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++ > prob: faulty blit/drawing func's in mode 4

#7283 - Vector - Fri Jun 13, 2003 7:04 pm

Hey all,

maybe i just missed something really stupid but i have a question. i have C code that compiles for devkitadv and runs when i use literals in the functions, but when i added a "bitmap" structure, and pass it by pointer to the functions, i don't get anything on screen.

here is the structure:
Code:

typedef struct {
  (u16*) bmp;
  int w;
  int h;
} bitmap;

i used malloc() to get memory for the bmp, but the problem lies elsewhere because it even breaks when i just set the bmp ptr to video memory.

i modified putpixel() from
Code:

void putpixel(int x, y, u16 color)
{
  videobuffer[y*120 + x] = color;
}

to:
Code:

void putpixel(bitmap* bmp, int x, y, u16 color)
{
  bmp->bmp[bmp->w*y + x] = color;
}


now when I do:
Code:

bitmap* videobuffer;
videobuffer->bmp = (16*)0x6000000;
videobuffer->w = 120;   // mode 4, so write 2 pixels at once :-(
videobuffer->h = 160;
putpixel(videobuffer, 10, 10,  0xf0f);


the bitmap implementation was the only thing i changed. mode 4 is already set up, with the palette loaded (vba shows the palette loaded in memory, but still only a blank screen.

anyone know whats wrong?

#7285 - niltsair - Fri Jun 13, 2003 7:59 pm

You're most probably busting the available IWRAM (32k).

If you really need to use an array this big(37.5k), put it in EWRAM(256k) or like it was discussed elsewhere, possibly in sprite tile memory (better access speed) haven't tested it but should work.

And about your function it's so simple that you should use a #define instead, to save on function calling overhead (which mean speed gain).

#define putpixel(bitmap* bmp, int x, y, u16 color) bmp->bmp[bmp->w*y + x] = color;

#7292 - Cyberman - Sat Jun 14, 2003 2:56 am

Code:

bitmap* videobuffer;
videobuffer->bmp = (16*)0x6000000;
videobuffer->w = 120;   // mode 4, so write 2 pixels at once :-(
videobuffer->h = 160;
putpixel(videobuffer, 10, 10,  0xf0f);


Umm...
Code:
videobuffer->bmp = (u16 *) 0x06000000;


The compilor might be thinking you are doing this with your code.

16 * 0x06000000 is the same thing as assigning
0x60000000; You are addressing way out of the GBA's memory range. :)

Other small details, in Mode four your pixels are byte sized.. your put method will not work properly or the way you will think they will. You can access this in a per byte mode or word or long but 1 pixel = 1 byte.. you can access IRAM and WRAM as this, and for 8 bits per pixel mode you really shouldn't access it any other way. unless you are drawing a line or something (even then because of endianess one should take that into account).'


Cyb

#7381 - Vector - Mon Jun 16, 2003 5:15 pm

niltsair wrote:
You're most probably busting the available IWRAM....If you really need an array this big(37.5k)

There is no array! videobuffer, as declared later, was simply a pointer to 0x6000000. Perhaps my choice to use dovoto's variable name instead of "videoptr" was misleading. Sorry :-)
But thanks for the idea about using a #define for putpixel(), thats inline, so it replaces function calls with the actual code right?

Cyb, I don't understand. doesn't
Code:
 (u16*) 0x6000000
evaluate to "u16 pointer to memory address 0x6000000" which is the same as "unsigned short int pointer to 0x6000000" ? So if the compiler replaces u16 with unsigned short int, it can't interpret (u16*) 0x6000000 as "16 * 0x6000000" right?

#7388 - niltsair - Mon Jun 16, 2003 8:12 pm

[quote="Vector"]
niltsair wrote:
You're most probably busting the available IWRAM....If you really need an array this big(37.5k)

There is no array! videobuffer, as declared later, was simply a pointer to 0x6000000. Perhaps my choice to use dovoto's variable name instead of "videoptr" was misleading. Sorry :-)
But thanks for the idea about using a #define for putpixel(), thats inline, so it replaces function calls with the actual code right?[/code]
It works like macro. It'll replace the macro call with the actual code like you said.

Quote:
Cyb, I don't understand. doesn't
Code:
 (u16*) 0x6000000
evaluate to "u16 pointer to memory address 0x6000000" which is the same as "unsigned short int pointer to 0x6000000" ? So if the compiler replaces u16 with unsigned short int, it can't interpret (u16*) 0x6000000 as "16 * 0x6000000" right?


Yes, but in your code you wrote (16*) instead of (u16*)