gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Headache Array =/

#6234 - wiz - Tue May 20, 2003 10:02 am

Hi *again* I feel bad to keep bothering everyone, but I literally have an headache :(

What is it I'm doing wrong? (in function main, mode 3)
Code:

u16 TestArray[160][160];

int x,y;

for (x = 0; x<160; x++)
  for (y = 0; y<160; y++)
    TestArray[x][y] = RGB(31,31,31);

for (x=0; x<160; x++)
  for (y=0; y<160; y++)
    PlotPixel(x,y,TestArray[x][y]);


ok so this should display a white square.. (please ignore other methods of displaying a squre as this is only a test)

anything up to [80][80] in the 'first' (init) loop seems to work fine, but theres corruption when making that loop up to 160 (interestingly enough 80 is half of 160)

what on earth could be the reason for this problem?

I hate reloading the emulator every time I recompile and need to test a change it takes AGES to load :(

and incase you need to see pixel function its just:

void PlotPixel(int x,int y, u16 c)
{
videoBuffer[x + (y * 240)] = (c);
}

thanks

#6237 - niltsair - Tue May 20, 2003 2:18 pm

Mmm, that's a weird one.

Could we see your 'videoBuffer' Define or Declare?

#6240 - tom - Tue May 20, 2003 2:53 pm

u16 TestArray[160][160];

is this a local variable ?
if so, it will never fit into the stack, if it's in iwram...
(160 * 160 * 2 = 51200 bytes)

#6245 - Touchstone - Tue May 20, 2003 7:06 pm

Have you made sure you have enough memory to hold a 51kb buffer? IWRAM (where I assume you have your variables and stackframe) is only 32kb.
_________________
You can't beat our meat

#6254 - wiz - Wed May 21, 2003 1:01 am

I just declared this in main, I guess it is a local variable

u16 TestArray[160][160];

whats weird is that if I change it to

u16 TestArray[260][160];

I can access the 160x160.. but this obviously is not the solution (but still weird)

so as you say the array is too big for the memory, how do I change that to fix the problem? I cant recall reading about this in any of the tutorials I looked at.

Thanks kindy

PS the videobuffer is declared as: u16 *videoBuffer = (u16*)0x6000000;

#6271 - Quirky - Wed May 21, 2003 8:15 am

If you are testing this on VBA, there are some differences to real hardware regarding memory (VBA has more under certain circumstances and won't fall victim to all of your memory errors). On real hardware, going "out of bounds" on the stack has unpredictable results. But the most likely result is that it will crash.

The best thing to do is rethink why you need to do this and think of a better way to go about it. If you really must, you can place the array in ewram. It'll fit there.

Code:

__attribute__ ((section (".ewram"))) u16 TestArray[160][160];


But the lesson to be learned from your test is "placing a giant array in memory just for the hell of it is a silly idea!" :)

#6276 - wiz - Wed May 21, 2003 12:05 pm

Thank you for that, I shall try it :)

The reason for the 160x160 array is that Im porting a game over from the pc. I render the sprite in a function using pixels and there are 100 frames (at 16x16) for very smooth animation. I wanted the sprite frames to be on an offscreen buffer so it doesnt use 100 of what is available.

Then I plan to use one hardware sprite cell, and copy the 16x16 from the buffer according to which cell is needed. leaving all the other sprites for the rest of the game..

hopefully that makes sense ;)

thanks

#6281 - niltsair - Wed May 21, 2003 2:54 pm

Well, there's 1024 Tiles entry for sprites, if you can spare 400 of them, you could use it to compute your sprite's tiles. When your computation is done, just use DMA top copy it from their current spot to the area used to display them.

#6283 - Touchstone - Wed May 21, 2003 3:32 pm

niltsair wrote:
Well, there's 1024 Tiles entry for sprites, if you can spare 400 of them, you could use it to compute your sprite's tiles. When your computation is done, just use DMA top copy it from their current spot to the area used to display them.


Or more efficiently, tell the video hardware to use the tile index for your anim frame instead of copy the frame from one place in VRAM to another.
_________________
You can't beat our meat

#6284 - niltsair - Wed May 21, 2003 3:42 pm

Touchstone wrote:
niltsair wrote:
Well, there's 1024 Tiles entry for sprites, if you can spare 400 of them, you could use it to compute your sprite's tiles. When your computation is done, just use DMA top copy it from their current spot to the area used to display them.


Or more efficiently, tell the video hardware to use the tile index for your anim frame instead of copy the frame from one place in VRAM to another.


This is true of not too many Sprite's tiles index need to be changed, else it'll takes some time. I just don't know where exactly changing the indexs become slower than DMA the tiles.

But yeah, you probably only have a little amount fo indexs to change, so it would be faster.

#6286 - Touchstone - Wed May 21, 2003 5:31 pm

niltsair wrote:
This is true of not too many Sprite's tiles index need to be changed, else it'll takes some time. I just don't know where exactly changing the indexs become slower than DMA the tiles.


True.
_________________
You can't beat our meat

#6287 - Quirky - Wed May 21, 2003 5:50 pm

niltsair wrote:
Well, there's 1024 Tiles entry for sprites, if you can spare 400 of them, you could use it to compute your sprite's tiles. When your computation is done, just use DMA top copy it from their current spot to the area used to display them.


The only (minor) problem with that is that you can only access VRAM 16 bits at a time, so it would be slower than normal ram. Even more so if you want to use 16 coloured tiles - read four pixels at a time, mask three of them and change your one pixel, write all four back again. Ouch!

#6288 - niltsair - Wed May 21, 2003 6:01 pm

mmm, i suppose he'll want to change a whole tile, tile per tile.

A good way would be like this :

u8 WorkTile[8][4]; //work memory space for tile modification
DMA3 TileAdr(x), WorkTile, 8 | DMA_32 //Transfer the entire tile
...
work on WorkTile
...
DMA3 WorkTile, TileAdr(x), 8 | DMA_32 //Store the tile back

Take note that each item in WorkTile contain 2 pixels, since in 16colors, they each takes 4bits.