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.

Beginners > Pointer Confusion

#171806 - vladimirsan - Fri Dec 25, 2009 10:34 am

Hello While I'm not new to programming I'm not very familiar with "GBA Style" programming.

I'm using the Tonc tutorial to learn GBA programming (I cheeked the HAM book before using Tonc). I don't understand this piece of code...

Code:
#define fooSize ...
const u16 fooData[]= { ... };

// copy via u16 array (the de facto standard)
u16 *dst= (u16*)vid_mem, *src= (u16*)fooData;
for(ii=0; ii<fooSize/2; ii++)
    dst[ii]= src[ii];



It's located in http://www.coranac.com/tonc/text/bitmaps.htm#ssec-data-align

I don't understand why he used fooSize/2 if both fooData and dst elements are 16 bits long

In a previous chapter is this code


Code:

// An array representing a 240x160@16 bitmap, converted
// to an array by some graphics conversion tool.
const u8 fooBitmap[240*160*2]=
{
    // Maaaaany, many lines of data.
}

int main()
{
    REG_DISPCNT= DCNT_MODE3 | DCNT_BG2;

    u16 *src= (u16*)fooBitmap;  // Cast source to u16-array

    // Copy 240x160 pixels to VRAM (YARLY!)
    int ii;
    for(ii=0; ii<240*160; ii++)
        vid_mem[ii]= src[ii];

    return 0;
}

http://www.coranac.com/tonc/text/first.htm


I thought that there he didn't put the *2 because he is casting fooBitmap to a u16 which is bigger than u8.

I've looked everywhere and I think that I got more confused every minute hahahahah please help

#171807 - Pete_Lockwood - Fri Dec 25, 2009 12:42 pm

vladimirsan wrote:
I don't understand why he used fooSize/2 if both fooData and dst elements are 16 bits long

It's because fooSize is the size in bytes not in U16s, as noted in the text immediately below: "Both these routines copy fooSize bytes from fooData to..."

One could argue that this isn't excessively clear in the code but at the same time an experienced C programmer would probably just infer this from the fact that src and dst are being cast from "something" to 16 bit pointers and subsequently the loop's bounds are being halved.


Quote:
I thought that there he didn't put the *2 because he is casting fooBitmap to a u16 which is bigger than u8.

Correct. src there is a 16 bit pointer so although it's pointing to something that was originally allocated as a lump of 8 bit stuff, incrementing src will move 16 bits at a time.


You're basically heading in the right direction but you missed the fact that the first piece said fooSize was size in bytes.
_________________
It's not an illusion, it just looks like one.

#171808 - kusma - Fri Dec 25, 2009 1:00 pm

vladimirsan wrote:

In a previous chapter is this code


Code:

// An array representing a 240x160@16 bitmap, converted
// to an array by some graphics conversion tool.
const u8 fooBitmap[240*160*2]=
{
    // Maaaaany, many lines of data.
}

int main()
{
    REG_DISPCNT= DCNT_MODE3 | DCNT_BG2;

    u16 *src= (u16*)fooBitmap;  // Cast source to u16-array

    // Copy 240x160 pixels to VRAM (YARLY!)
    int ii;
    for(ii=0; ii<240*160; ii++)
        vid_mem[ii]= src[ii];

    return 0;
}

http://www.coranac.com/tonc/text/first.htm

This code is simply broken, as an u8 array might not be 16 bit aligned, so accessing it through a 16 bit pointer has a good chance of being misaligned. Even if alignment were forced by compiler directives, it would still violate the strict-aliasing rules of C99 and C++ (which are assumed on GCC even for pre-C99 when compiling with -O3).

#171809 - vladimirsan - Fri Dec 25, 2009 1:05 pm

Pete_Lockwood wrote:

It's because fooSize is the size in bytes not in U16s, as noted in the text immediately below: "Both these routines copy fooSize bytes from fooData to..."


Thanks a lot...It took me some time to figure that out (even after reading your explanation) ahahaha....I realize now that I really to study more C if I really want to do serious GBA programming.

#172007 - Erik Carrick - Fri Jan 08, 2010 9:24 am

kusma wrote:
vladimirsan wrote:

In a previous chapter is this code


Code:

// An array representing a 240x160@16 bitmap, converted
// to an array by some graphics conversion tool.
const u8 fooBitmap[240*160*2]=
{
    // Maaaaany, many lines of data.
}

int main()
{
    REG_DISPCNT= DCNT_MODE3 | DCNT_BG2;

    u16 *src= (u16*)fooBitmap;  // Cast source to u16-array

    // Copy 240x160 pixels to VRAM (YARLY!)
    int ii;
    for(ii=0; ii<240*160; ii++)
        vid_mem[ii]= src[ii];

    return 0;
}

http://www.coranac.com/tonc/text/first.htm

This code is simply broken, as an u8 array might not be 16 bit aligned, so accessing it through a 16 bit pointer has a good chance of being misaligned. Even if alignment were forced by compiler directives, it would still violate the strict-aliasing rules of C99 and C++ (which are assumed on GCC even for pre-C99 when compiling with -O3).


I too was assuming this only. The code is indeed incomplete
_________________
craft ideas | india news