Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

#1 2015-05-25 04:05:06

Gonkalbell
New member
Registered: 2015-05-25
Posts: 2

GBDK multidimensional arrays aren't working

So while experimenting with GBDK, I noticed that 2d arrays don't seem to work correctly. Here is a simple example:

#include <gb/gb.h>
#include <stdio.h>

UBYTE a[4][3];
int i, j;

void main()
{
    for ( i = 0; i < 4; i++ )
    {
        for ( j = 0; j < 3; j++ )
        {
            a[i][j] = i + j;
        }
    }
    for ( i = 0; i < 4; i++ )
    {
        for ( j = 0; j < 3; j++ )
        {
            printf("a[%d][%d] = %d\n", i,j, (int)a[i][j] );
        }
    }
}


When I compile a ROM and run it on an emulator, it shows 0 for every value in the array. I used VBA's memory view to find the location where "a" is in memory, and all 12 bytes were 0. I guess I could use a single dimensional array, but that will make things more difficult.

Offline

 

#2 2015-05-25 10:11:03

nitro2k01
Administrator
Registered: 2008-02-22
Posts: 249

Re: GBDK multidimensional arrays aren't working

I would suggest learning asm and saving yourself the trouble of figuring out the broken mess  that is GBDK.

I don't know if this is the problem, but maybe you need to cast i+j to UBYTE for it the write to work.
(UBYTE)(i + j)

I would also recommend using BGB as your debugger instead of VBA. it's both much more accurate to the original hardware, and much mower powerful as a debugger. Maybe, for example, the writes do happen but end up in la-la land for some reason.


Blog: Gameboy Genius
"A journey of a thousand miles begins with one small step"
Old Chinese Proverb

Offline

 

#3 2015-05-25 13:39:45

Gonkalbell
New member
Registered: 2015-05-25
Posts: 2

Re: GBDK multidimensional arrays aren't working

I tried making those changes, and still no luck. There is enough space allocated for the array, but it doesn't seem to be updating those bytes. Also, switching to assembly isn't an option for me, since I am making a portfolio for a company that mainly cares about C and C++ code.

Offline

 

#4 2015-05-29 17:45:59

UraKn0x
New member
Registered: 2014-04-19
Posts: 7

Re: GBDK multidimensional arrays aren't working

I may suggest you to access the array directly with its memory address. I had a similar problem with my 2048 clone last year, and I solved it like that:

UINT8 array[4][4];
UINT8 *arrayAccess = &array;
#define array(i, j) (*(arrayAccess + (4 * i) + (j)))

Then you'd be able to read and write any cell of your array by using array(i, j) as if you were using array[i][j].
My full solution is implemented here if you want to take a look https://github.com/UraKn0x/gameboy-2048 … ter/main.c

Offline

 

#5 2015-05-29 18:20:05

a cat
Member
Registered: 2014-07-27
Posts: 98

Re: GBDK multidimensional arrays aren't working

just to add to this i am currently working on a snake game using gbdk and so so many times
rely rely illogical things happen(notably when using 2d arrays) and its driving me insane O.O

for example i once spent a day trying to work out why a variable was being set to -6000 and something when i did x = 1;
after i changed it from a char to a int it worked fine which makes no sense as the value was 1 and signed chars can goto 127

many many other things like this happen often and you just have to expect them when using the outdated gbdk compiler

but anyway i have recently discovered you can compile gameboy code using the modern sdcc compiler
so i hope to try to use this in the future

heres the post that has info on it:
http://sourceforge.net/p/sdcc/discussio … /e04ebcc5/


a cat in need of knowledge!!

Offline

 

#6 2015-05-31 06:28:00

a cat
Member
Registered: 2014-07-27
Posts: 98

Re: GBDK multidimensional arrays aren't working

when i try to use your method in my program:
UINT8 array[4][4];
UINT8 *arrayAccess = &array;
#define array(i, j) (*(arrayAccess + (4 * i) + (j)))

i get a error message:
main.c(32):error *** FATAL Compiler Internet Error in file 'gen.c' line number '3864' : code generator internel error
Contact Author with source code

any ideas?

heres my code:
include <gb/gb.h>
#include <gb/drawing.h>
#include <stdio.h>
#include <stdlib.h>

void print_map(void);//i commented these functions out for testing
void print_map_array(void);

#define MAP(x, y) (*(pMAP + (4 * x) + (y)))

UINT32 MAP[12][12]={
                           {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                           {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};

UINT32 *pMAP = &MAP;

UINT32 x = 5;
UINT32 y = 5;

void main(void){
MAP(x,y) = 1;
}

Last edited by a cat (2015-05-31 06:28:45)


a cat in need of knowledge!!

Offline

 

#7 2015-06-01 17:43:29

bokny
New member
Registered: 2015-06-01
Posts: 4

Re: GBDK multidimensional arrays aren't working

mr cat i don't quite understand your code as i am still learning but could the problem be that you are initialising the array before main starts?
as it says on this page: http://gbdk.sourceforge.net/guidelines.html
"Do not declare initialised variables at the file level, except when they are read-only, because they will be located in ROM"

Offline

 

#8 2015-06-02 11:52:42

a cat
Member
Registered: 2014-07-27
Posts: 98

Re: GBDK multidimensional arrays aren't working

thanks alot!

this explains so many things now!


a cat in need of knowledge!!

Offline

 

#9 2017-08-22 22:09:55

drludos
Member
Registered: 2017-05-11
Posts: 52

Re: GBDK multidimensional arrays aren't working

Sorry to Necrobump this post, but today I've encountered the same problem while accessing a large dynamic 2D array (22*22 elements).

Sadly, the solution presented here didn't work for me.

After many hours of research, I found another workaround, that I'm sharing here because I guess it could be helpful to other people :

For whatever reason, if the total array size exceed 256 elements, you can't access elements using UINT8 / INT8 indexes, even if the "local" array that you are currently accessing have less than 256 or 128 elements.
BTW, the official GBDK doc states that a single array can't have more than 128 elements anyway.

So, the workaround I've found is to simply use UINT16 variables for the index to access both dimensions of the array.

For example, this code won't work:

UINT8 i,j;
UINT8 myArray[22][22];
//Let's say that the array was filled with 1 during a loop

i=15;
j=20;
if( myArray[i][j] == 1 ){
   //this will never be true, while it should: the program can't read the myArray content correctly
}


While this one will work as intended:

UINT16 i,j;
UINT8 myArray[22][22];
//Let's say that the array was filled with 1 during a loop

i=15;
j=20;
if( myArray[i][j] == 1 ){
   //this will be true, as it should be!
}

I hope it'll save somebody else several hours of research if you encounter the same issue!

Last edited by drludos (2017-08-22 22:23:53)


Download ROMs of my games: https://drludos.itch.io/
Support my work and get access to beta and prototypes: https://www.patreon.com/drludos

Offline

 

#10 2019-08-03 03:51:45

26F
Member
Registered: 2018-07-25
Posts: 13
Website

Re: GBDK multidimensional arrays aren't working

If you're having trouble indexing an array that is more than 255 items long you can use UINT16 and casting as follows:

#include <gb/gb.h>

unsigned char cmap[] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

unsigned char cells[] =
{
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};


void main() {
    UINT16 c = 0; // here
    set_bkg_data(0,2,cells);
    set_bkg_tiles(0,0, 20, 18, cmap);
    SHOW_BKG;
    while (1) {
            for (c = (UINT16)(0); (UINT16)c < (UINT16)(360); c++) { // here
                cmap[(UINT16)(c)] = 0x01;                           // here
            }
            set_bkg_tiles(0,0, 20, 18, cmap);
            wait_vbl_done();
            wait_vbl_done();
            wait_vbl_done();
            for (c = (UINT16)(0); (UINT16)c < (UINT16)(360); c++) {
                cmap[(UINT16)(c)] = 0x00;
            }
            set_bkg_tiles(0,0, 20, 18, cmap);
            wait_vbl_done();
            wait_vbl_done();
            wait_vbl_done();
        }
}

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson