Don't have an account? Register now to chat, post, use our tools, and much more.
Latest Headlines
Online Users
There are 141 users online: 9 members, 101 guests and 31 bots. Members: adrfcs, Ashbad, ElectronicsGeek, Hemenia, HOMER-16, ordelore, superamon. Bots: VoilaBot (1), Spinn3r (2), Magpie Crawler (4), VoilaBot (6), Googlebot (18).
RSS & Social Media
SAX
You must log in to view the SAX chat widget
|
| Author |
Message |
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 17 Apr 2011 11:18:10 am Post subject: Useful Prizm Routines |
|
|
I'll start us off.
XORSprite and CopySprite
The former XORs a sprite of specified width and height to the screen. Do it twice, and the screen will return to its original state. The latter routine overwrites the data on the screen, but is (potentially) faster because it memcpys each row. Note that these routines expect the sort of data that SourceCoder outputs.
Code: #define LCD_WIDTH_PX 384
#define LCD_HEIGHT_PX 216
void XORSprite(char* data, int x, int y, int width, int height) {
char* VRAM = (char*)0xA8000000;
VRAM += 2*(LCD_WIDTH_PX*y + x);
for(int j=y; j<y+height; j++) {
for(int i=x; i<x+width; i++) {
*(VRAM++) ^= *(data++);
*(VRAM++) ^= *(data++);
}
VRAM += 2*(LCD_WIDTH_PX-width);
}
}
void CopySprite(char* data, int x, int y, int width, int height) {
char* VRAM = (char*)0xA8000000;
VRAM += 2*(LCD_WIDTH_PX*y + x);
for(int j=y; j<y+height; j++) {
memcpy(VRAM,data,2*width);
VRAM += 2*LCD_WIDTH_PX;
data += 2*width;
}
}
_________________

Last edited by KermMartian on 13 May 2011 03:32:56 pm; edited 2 times in total |
|
| Back to top |
|
|
_player1537

Guru-in-Training

Joined: 25 Nov 2009 Posts: 2958
|
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
|
| Back to top |
|
|
merthsoft
File Archiver

Joined: 09 May 2010 Posts: 2735
|
Posted: 17 Apr 2011 02:01:42 pm Post subject: |
|
|
Until I find a better way to do it, this is how I do non-blocking key input:
Code: if (PRGM_GetKey()) {
GetKey(&key);
} else {
key = 0;
}
It only kind of works, though. _________________ Shaun |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
|
| Back to top |
|
|
merthsoft
File Archiver

Joined: 09 May 2010 Posts: 2735
|
Posted: 17 Apr 2011 02:40:28 pm Post subject: |
|
|
I assume that's what PRGM_GetKey() is in keyboard.hpp. Here's what I'm doing:
Code:
int lastKey, key;
while(1) {
lastKey = key;
key = PRGM_GetKey();
switch (key) {
/* ... */
case KEY_PRGM_MENU:
GetKey(&key);
break;
}
}
Last key is for stuff like my function keys, which shouldn't repeat if you hold down the button. _________________ Shaun |
|
| Back to top |
|
|
ephan
Super-Expert

Joined: 12 Nov 2010 Posts: 819
|
Posted: 17 Apr 2011 02:41:51 pm Post subject: |
|
|
| Based on the first post I think a routine to flip the screen horizontally and vertically would be possible. Am I right? |
|
| Back to top |
|
|
merthsoft
File Archiver

Joined: 09 May 2010 Posts: 2735
|
Posted: 17 Apr 2011 03:26:40 pm Post subject: |
|
|
String concatenation:
Code: char* concat(char* str1, char* str2) {
int len1 = 0;
int len2 = 0;
for (;str1[len1] != '\0'; len1++);
for (;str2[len2] != '\0'; len2++);
char* str3 = (char*)malloc(len1 + len2 + 1);
int i;
for (i = 0; i < len1; str3[i] = str1[i], i++);
for (i = 0; i < len2; str3[len1+i] = str2[i], i++);
str3[len1 + len2] = 0;
return str3;
}
_________________ Shaun |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 17 Apr 2011 03:43:29 pm Post subject: |
|
|
Depending on the size of the strings, a pair of memcpy()s instead of those two for() loops at the end might be faster, but it's almost definitely a trivial difference. Therefore, I'd call that good enough. _________________
 |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 18 Apr 2011 12:04:28 am Post subject: |
|
|
| ScoutDavid wrote: | | Based on the first post I think a routine to flip the screen horizontally and vertically would be possible. Am I right? | Not only possible, but trivial. If someone wants it, I would be happy to write such a routine. Anywhere, here's a few useful routines:
DrawDialog
Code: //Draws a DCS SmallWindow-style dialog box. Can fit in
//text from (x,y)=(4,3) through (x,y)=(8,17)
void drawDialog(char* title) {
#define DIALOG_WIDTH 256
#define DIALOG_HEIGHT 152
#define DIALOG_X 50
#define DIALOG_Y 39
fillArea(DIALOG_X,DIALOG_Y,DIALOG_WIDTH,DIALOG_HEIGHT,0x0000FFFF); //fill with white
drawLine(DIALOG_X,DIALOG_Y,DIALOG_X+DIALOG_WIDTH,DIALOG_Y,0x00000000);
drawLine(DIALOG_X,DIALOG_Y,DIALOG_X,DIALOG_Y+DIALOG_HEIGHT,0x00000000);
drawLine(DIALOG_X+DIALOG_WIDTH,DIALOG_Y+DIALOG_HEIGHT,DIALOG_X+DIALOG_WIDTH,DIALOG_Y,0x00000000);
drawLine(DIALOG_X+DIALOG_WIDTH,DIALOG_Y+DIALOG_HEIGHT,DIALOG_X,DIALOG_Y+DIALOG_HEIGHT,0x00000000);
for(int i=DIALOG_Y+1;i<DIALOG_Y+32;i++) {
drawLine(DIALOG_X+1, i, DIALOG_X+DIALOG_WIDTH-1, i, makeGray((i-DIALOG_Y)/2));
}
PrintXY(4, 2, title, 0x20, 7);
CopySprite(closebutton,DIALOG_X+DIALOG_WIDTH-30,DIALOG_Y+3,27,26);
}
MakeGray
Code: //shade can be between 0 (black) and 31 (white)
//creates a two-byte 5/6/5 color code
int makeGray(int shade) {
return (((shade<<11)&0x0000F800) | ((shade << 6)&0x000007C0) | ((shade)&0x0000001F));
}
DrawLine
Code: //Uses the Bresenham line algorithm
void drawLine(int x1, int y1, int x2, int y2, int color) {
signed char ix;
signed char iy;
// if x1 == x2 or y1 == y2, then it does not matter what we set here
int delta_x = (x2 > x1?(ix = 1, x2 - x1):(ix = -1, x1 - x2)) << 1;
int delta_y = (y2 > y1?(iy = 1, y2 - y1):(iy = -1, y1 - y2)) << 1;
plot(x1, y1, color);
if (delta_x >= delta_y) {
int error = delta_y - (delta_x >> 1); // error may go below zero
while (x1 != x2) {
if (error >= 0) {
if (error || (ix > 0)) {
y1 += iy;
error -= delta_x;
} // else do nothing
} // else do nothing
x1 += ix;
error += delta_y;
plot(x1, y1, color);
}
} else {
int error = delta_x - (delta_y >> 1); // error may go below zero
while (y1 != y2) {
if (error >= 0) {
if (error || (iy > 0)) {
x1 += ix;
error -= delta_y;
} // else do nothing
} // else do nothing
y1 += iy;
error += delta_x;
plot(x1, y1, color);
}
}
}
Plot
Code: //draws a point of color color at (x0, y0)
void plot(int x0, int y0, int color) {
char* VRAM = (char*)0xA8000000;
VRAM += 2*(y0*LCD_WIDTH_PX + x0);
*(VRAM++) = (color&0x0000FF00)>>8;
*(VRAM++) = (color&0x000000FF);
return;
}
FillArea
Code: //fills a rectangular area of (width,height) with upper-left
//corner at (x,y) with color color
void fillArea(int x, int y, int width, int height, int color) {
//only use lower two bytes of color
char* VRAM = (char*)0xA8000000;
VRAM += 2*(LCD_WIDTH_PX*y + x);
for(int j=y; j<y+height; j++) {
for(int i=x; i<x+width; i++) {
*(VRAM++) = (color&0x0000FF00)>>8;
*(VRAM++) = (color&0x000000FF);
}
VRAM += 2*(LCD_WIDTH_PX-width);
}
}
_________________
 |
|
| Back to top |
|
|
TheStorm

NOU!

Joined: 26 Mar 2007 Posts: 2375
|
Posted: 18 Apr 2011 12:07:49 am Post subject: |
|
|
We could really put a lot of these into a libfxgc or sorts so that users can easily compile them into the main program. In fact I'd suggest we start just that. My thought would be have sets of statically linkable libs with related routines. One main one for syscalls and helper functions, another for a GUI library, maybe another with Floating point stuff etc. Thoughts? _________________
"Always code as if the person who will maintain your code is a maniac serial killer that knows where you live" -Unknown
"If you've done something right no one will know that you've done anything at all" -Futurama
"Have a nice day, or not, the choice is yours." Tom Steiner
<Michael_V> or create a Borg collective and call it The 83+
<Michael_V> Lower your slide cases and prepare to be silent linked. Memory clears are futile. |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 18 Apr 2011 10:25:53 am Post subject: |
|
|
I think that's an awesome idea. I'm also thinking strongly that if I do indeed make some kind of Doors CS port, that it will have a version of the DCS GUI system, because it would be much much easier on this. Is there a such library that will only link in the routines that the user uses? _________________
 |
|
| Back to top |
|
|
TheStorm

NOU!

Joined: 26 Mar 2007 Posts: 2375
|
Posted: 18 Apr 2011 10:33:03 am Post subject: |
|
|
I would think GCC would be smart enough to figure that out but I'm not sure one that. _________________
"Always code as if the person who will maintain your code is a maniac serial killer that knows where you live" -Unknown
"If you've done something right no one will know that you've done anything at all" -Futurama
"Have a nice day, or not, the choice is yours." Tom Steiner
<Michael_V> or create a Borg collective and call it The 83+
<Michael_V> Lower your slide cases and prepare to be silent linked. Memory clears are futile. |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 18 Apr 2011 10:37:04 am Post subject: |
|
|
| TheStorm wrote: | | I would think GCC would be smart enough to figure that out but I'm not sure one that. | To optimize out routines that aren't called from anywhere, you mean? That's a good point, I didn't even think of that. I'm so used to working with z80 assembly where you'd have to come up with some sort of mechanism to only include the routines in a linked library that you need. _________________
 |
|
| Back to top |
|
|
Ashbad

I am governor Jerry Brown

Joined: 01 Dec 2010 Posts: 2423 Location: There lived a certain man in Russia long ago
|
Posted: 01 May 2011 06:50:19 pm Post subject: |
|
|
Does anyone know a routine to copy the contents of VRAM to the actual LCD? _________________ -Ashbad |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 01 May 2011 06:54:49 pm Post subject: |
|
|
| Ashbad wrote: | | Does anyone know a routine to copy the contents of VRAM to the actual LCD? | Just call Bdisp_PutDisp_DD();. For example, the code below clears the screen, copies on the Obliterate titlescreen, draws the select-item menu sprite, and copies everything to the screen. The z80 analog is iPutSprite.
Code: Bdisp_AllCr_VRAM();
memcpy(VRAM,oblit_prizm_title,(384*216*2));
CopySprite(menubullet,264,131+21*menuitem,16,16);
Bdisp_PutDisp_DD();
_________________
 |
|
| Back to top |
|
|
calc84maniac

Epic z80 roflpwner

Joined: 01 Aug 2006 Posts: 1503 Location: The ex-planet Pluto
|
Posted: 01 May 2011 07:05:54 pm Post subject: |
|
|
This might actually be a better way to do the MakeGray routine:
Code: //shade can be between 0 (black) and 31 (white)
//creates a two-byte 5/6/5 color code
int makeGray(int shade) {
return shade * 0x0841;
}
since a multiplication is probably more optimized than a bunch of shifting and masking on the SuperH. If there was a way to optimize this to a 16-bit x 16-bit multiplication, that would be even better (inline assembly?) _________________ ~calc84maniac has spoken.
Projects:
TI-Boy SE
F-Zero
Super Mario (aka Project M) |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 01 May 2011 07:19:13 pm Post subject: |
|
|
Close, but not quite. 31 yields FFDF, for instance, rather than FFFF. Using 0x0842 instead of 0x0841 yields FFFF, which is closer, but of course it doesn't do the intermediate values properly. I suppose that's not bad if it gets decent speed, and I suppose getting the least significant bit of the green wrong is not the total end of the world. _________________
 |
|
| Back to top |
|
|
calc84maniac

Epic z80 roflpwner

Joined: 01 Aug 2006 Posts: 1503 Location: The ex-planet Pluto
|
Posted: 01 May 2011 07:22:59 pm Post subject: |
|
|
| KermMartian wrote: | | Close, but not quite. 31 yields FFDF, for instance, rather than FFFF. Using 0x0842 instead of 0x0841 yields FFFF, which is closer, but of course it doesn't do the intermediate values properly. I suppose that's not bad if it gets decent speed, and I suppose getting the least significant bit of the green wrong is not the total end of the world. |
I just did exactly what your routine did, so...  _________________ ~calc84maniac has spoken.
Projects:
TI-Boy SE
F-Zero
Super Mario (aka Project M) |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55882 Location: Earth, Sol, Milky Way
|
Posted: 01 May 2011 07:25:20 pm Post subject: |
|
|
| calc84maniac wrote: | I just did exactly what your routine did, so...  | So you did, and I now see why that wasn't looking right to me, and also why I'm stupid. Of course the LSB of green will always be zero for gray values 0-31. :S _________________
 |
|
| Back to top |
|
|
|
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.
» Go to Registration page
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
© Copyright 2000-2013 Cemetech & Kerm Martian :: Page Execution Time: 0.050628 seconds.
|