#6314 - Foz - Thu May 22, 2003 11:08 pm
Hi all,
I'm having a problem with memset. I'm using gcc and the program is in mode 4.
I have a few files:Header
Implementation
Main
The following are fragments but contain all the pertinent info.
In the header I have: Code: |
extern u16* videoBuffer; |
In the implementation I have: Code: |
u16* videoBuffer;
memset((u16*)videoBuffer[y*(HALF_SCREEN_WIDTH)+x1>>1],color, x2-x1); |
I know assembly, or DMA is faster, but I am not there yet. I'm trying to get it all to work first. I will then go back and optimize.
Anyway I get a warning that says:"cast to pointer of different size" and besides the warning it flat out doesn't work.
#6322 - tepples - Fri May 23, 2003 3:44 am
[quote="Foz"] Code: |
u16* videoBuffer;
memset((u16*)videoBuffer[y*(HALF_SCREEN_WIDTH)+x1>>1],color, x2-x1); |
You're probably missing an ampersand. The value of 'videoBuffer' is a pointer to an array. The value of 'videoBuffer[x]' is the value of element x. The value of '&videoBuffer[x]' is a pointer to element x.
Try this: Code: |
u16* videoBuffer;
memset((u16*)&videoBuffer[y*(HALF_SCREEN_WIDTH)+x1>>1],color, x2-x1); |
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#6335 - funkeejeffou - Fri May 23, 2003 12:51 pm
This should also do it :
memset(videoBuffer + y*(HALF_SCREEN_WIDTH)+ x1>>1,color, x2-x1);
videoBuffer + y*(HALF_SCREEN_WIDTH)+ x1>>1 is the adress of the element you want to reach in your videobuffer array.
and
*(videoBuffer + y*(HALF_SCREEN_WIDTH)+ x1>>1) = videoBuffer[y*(HALF_SCREEN_WIDTH)+ x1>>1], wich is the u16 value stored at this adress.
I know this does it when coding on PC, but it should work on devkit as it's the fundemantal notion and definition of an array, wich is in fact a pointer.
Also, your cast should not be needed, even if the compiler generates a warning, don't care about it, as long as you know what you're doing:)
Hope this helps
#6362 - Maddox - Fri May 23, 2003 8:12 pm
funkeejeffou:
Uhhh, yeah. You pretty much ALWAYS want to pay attention to warnings, swifty, that's kinda why they're there.
Foz:
Try putting parentheses in like this like you're supposed to:
Code: |
memset(((u16*)videoBuffer)[y*(HALF_SCREEN_WIDTH)+x1>>1],color, x2-x1); |
See how I put those parentheses around ?
Now good grab a good C book that describes operator precedence.
MADDOX!!
_________________
You probably suck. I hope you're is not a game programmer.
#6402 - funkeejeffou - Sat May 24, 2003 11:37 am
maddox :
Code: |
memset(((u16*)videoBuffer)[y*(HALF_SCREEN_WIDTH)+x1>>1],color, x2-x1); |
won't work.
you're casting a u16 variable to a u16*
so if videoBuffer)[y*(HALF_SCREEN_WIDTH)+x1>>1] = 158;
then memset will copy the data at the adress 158=0x9E
hummm...guess it's not the VRAM starting adress...
Foz :
The general form of the memset functiun is:
Code: |
void *memset(void *s, int c, size_t n); |
where s is the adress pointing at your destination variable.
c is the value you want to write.
n is the number of bytes you want to write starting from the pointer s.
if you have
Code: |
extern u16 *videobuffer; |
then
is the value stored at the adress (videobuffer + x)
videobuffer[x] is equivalent to *(videobuffer + x)
You can put as an argument in the memset functiun for s :
&videobuffer[x] as Tepples said
or (videobuffer + x)
wich is the adress of the x element of the videobuffer array in both cases.
Besides, as you may may have guessed, memset copies blocs of bytes(unsigned char = 8bits), and the bus accessing the VRAM on the GBA is 16bit wide.
You really should use DMA in 16 or 32 bit for speed improvement, or even better, a little asm routine(DMA rereads the source for each 16/32bits transfer, making it inaccurate when copying a constant value on a large destination).
But memset works fine on devkit, so we can use it.
Hope this helps Foz
#6403 - funkeejeffou - Sat May 24, 2003 11:45 am
Just written something wrong up there, I've read too quickly,
Maddox, your code cast a u16* to a u16*...
useless...
but you still give the value of the array as an adress to the memset functiun, so memset will cast by itself a u16 (videobuffer[x...]) to a u16*.
So for the example above, you still write at the adress 0x9E...
And it is still not the VRAM starting adress...
#6417 - Maddox - Sun May 25, 2003 2:35 am
Oh, yeah. Put an ampersand in front of mine, too.
_________________
You probably suck. I hope you're is not a game programmer.
#6440 - Foz - Sun May 25, 2003 6:19 pm
Sorry, I was away for awhile. Thank you for all the posts.
funkeejeffou:
I was thinking of using DMA but I'm worried about losing input from the player as the CPU will ignore him during the copy (perhaps, I'm wrong on this, but I do know that DMA will take up the CPU cycles).
I'm going to give the ampersand a try.(I should have tried that) Maybe I'll get a book on C as Maddox suggested. ;)
As for assembly, once I get this routine working I can start to see the fruits of my labor as all of my drawing functions are based on it. Clearly assembly is the way to go here, so when it works I'll only need to plug in an inline assembly routine in order to see a significant speed increase. What was said about accuracy concerns me though. I'll fiddle around and get back to you. Thanks again.
-Foz