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.

DS development > BMP Problem

#162779 - hacker013 - Fri Sep 12, 2008 7:40 pm

Hey everybody,

I've have some problems with my code to load a bmp and to draw it. (it is modifyd version of mighty maxs bmp load code for his os.

Code:

#include <hax_fat.h>
#include <hax_bmp.h>
#include <malloc.h>
#include <string.h>

/*-----------------------------------------------------------------------------------------------------------
   hax_load_bmp
   
   const char* name = filename
   bool custom = custom memory adres
   unsigned long adress = if custom is true, custom memory adress, else 0
  -----------------------------------------------------------------------------------------------------------*/
unsigned short *hax_load_bmp(const char* name,bool custom,unsigned long adress)
{
   FILE *bmp = fopen(name,"rb") ;
   if (!bmp) return NULL;
   unsigned short *screen = NULL;
   if (custom==true) {
      screen = (unsigned short *)adress ;
   } else {
      screen = (unsigned short *)malloc(flength(bmp));
   }
   fseek(bmp,54,SEEK_SET) ;
   int x,y ;
   for (y=191;y>=0;y--) {
      for (x=0;x<256;x++) {
         unsigned char color[3] ;
         fread(&color[0],1,3,bmp) ;
         color[0]/=8 ;
         color[1]/=8 ;
         color[2]/=8 ;
         screen[y*256+x] = 0x8000 | (color[0] & 0x1F) | ((color[1] & 0x1F) << 5) | ((color[2] & 0x1F) << 10) ;
      } ;
   } ;
   fclose(bmp) ;
   return screen;
}

void hax_draw_bmp(bool screen,int x, int y, int w, int h, unsigned long adress)
{
   unsigned short *scr = NULL;
   if (screen==0) {
      scr = (u16 *)0x06008000;
   } else {
      scr = (u16 *)0x06208000;
   }
   unsigned short *mem = (unsigned short *)adress ;
   for (y=y;h>=y;h--) {
      for (x=x;x<w;x++) {
         scr[h*256+x] = *mem;
         mem++;
      } ;
   } ;
}

void hax_remove_bmp(unsigned long adress)
{
   free((unsigned short *)adress);
}


I get when is use hax_draw_bmp a black screen. Can you see the problem?

gr,

hacker013
_________________
Website / Blog

Let the nds be with you.

#162780 - ingramb - Fri Sep 12, 2008 7:55 pm

Code:
for (y=y;h>=y;h--) {
      for (x=x;x<w;x++) {
         scr[h*256+x] = *mem;
         mem++;
      } ;
   } ;

This is messed up. Try
Code:
for (int y0 = y; y0 < y + h; y0++) {
      for (int x0 = x; x0 < x + w; x0++) {
         scr[y0*256+x0] = *mem;
         mem++;
      }
   }

#162805 - hacker013 - Sat Sep 13, 2008 10:44 am

ingramb wrote:
Code:
for (y=y;h>=y;h--) {
      for (x=x;x<w;x++) {
         scr[h*256+x] = *mem;
         mem++;
      } ;
   } ;

This is messed up. Try
Code:
for (int y0 = y; y0 < y + h; y0++) {
      for (int x0 = x; x0 < x + w; x0++) {
         scr[y0*256+x0] = *mem;
         mem++;
      }
   }


it doesn't work, i get a black screen again.

EDIT:

i'm using to code like this:

Code:
u16 bmp_desktop;

bmp_desktop=hax_load_bmp("/xsystem/desktop.bmp",0,0);
hax_draw_bmp(0,0,0,256,192,*bmp_desktop); //hanging here

_________________
Website / Blog

Let the nds be with you.

#162827 - koryspansel - Sat Sep 13, 2008 7:19 pm

Your example code has some serious problems and shouldn't even compile (ie. illegal indirection):

Code:

u16 bmp_desktop;

bmp_desktop=hax_load_bmp("/xsystem/desktop.bmp",0,0);
hax_draw_bmp(0,0,0,256,192,*bmp_desktop); //hanging here


Or did you mean for bmp_desktop to be pointer to u16? If that IS the case, then you have the problem of de-referencing the pointer, which just returns the value at the start of that address, which you then cast back to a pointer (not good!)

The best solution would be to have your draw_bmp & remove_bmp functions take the actual pointer, instead of casting it to an integer then back again. Assuming it was a typo in your example code, doing this would have also highlighted the real problem in the first place. Since you can't pass an integer value as pointer without a cast.

EDIT: Clarity

--
Kory

#162828 - hacker013 - Sat Sep 13, 2008 7:24 pm

koryspansel wrote:
Your example code has some serious problems and shouldn't even compile (ie. illegal indirection):

Code:

u16 bmp_desktop;

bmp_desktop=hax_load_bmp("/xsystem/desktop.bmp",0,0);
hax_draw_bmp(0,0,0,256,192,*bmp_desktop); //hanging here


Or did you mean for bmp_desktop to be pointer to u16? If that IS the case, then you have the problem of de-referencing the pointer, which just returns the value at the start of that address, which you then cast back to a pointer (not good!)

The best solution would be to have your draw_bmp & remove_bmp functions take the actual pointer, instead of casting it to an integer then back again. Assuming it was a typo in your example code, doing this would have also highlighted the real problem in the first place. Since you can't pass an integer value as pointer without a cast.

EDIT: Clarity

--
Kory


Can you give an example because i don't understand somethinf about pointers.
_________________
Website / Blog

Let the nds be with you.

#162831 - koryspansel - Sat Sep 13, 2008 7:45 pm

Sure. Be aware, however, that I haven't really looked at the bitmap code too in-depth so you may have bugs elsewhere too.

Assuming the code should really look like this (to compile):

Code:

u16* bmp_desktop;

bmp_desktop=hax_load_bmp("/xsystem/desktop.bmp",0,0);
hax_draw_bmp(0,0,0,256,192,*bmp_desktop); //hanging here


Note how your hax_load_bmp returns a pointer to the memory where your bmp has been loaded. The easiest way to think about pointers is to remember that their value is just a memory address. So now bmp_desktop contains the memory address for the start of your bitmap. And as you've already noticed this causes the problem:

Code:

hax_draw_bmp(0,0,0,256,192,*bmp_desktop); //hanging here


The de-reference operator (*) returns the value at the memory location pointed to by the pointer. The type & size of the value is determined by the type pointed to. So *bmp_desktop just returns the first u16 of your bitmap.

Assuming this is a direct color bitmap:

Code:

*bmp_desktop             // returns first pixel
*(bmp_desktop + 1)    // returns second pixel
*(bmp_desktop + 2)    // returns third pixel
...


So what you end up doing is reading the color value for the first pixel of the bitmap and casting that to a memory address, which is almost certainly going to be bogus.

To sum it up, change:

Code:

void hax_draw_bmp(bool screen,int x, int y, int w, int h, unsigned long adress)


to

Code:

void hax_draw_bmp(bool screen,int x, int y, int w, int h, unsigned short* mem)


Remove this line in hax_draw_bmp:

Code:

unsigned short *mem = (unsigned short *)adress ;


And change the example code to:

Code:

u16* bmp_desktop;

bmp_desktop=hax_load_bmp("/xsystem/desktop.bmp",0,0);
hax_draw_bmp(0,0,0,256,192,bmp_desktop); //hanging here


Well, that was quite long. Hopefully, it makes sense.

--
Kory