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.

Ads

#1 2023-05-11 18:50:44

mattu82
New member
Registered: 2023-05-11
Posts: 7

Need help using more than 150 sprites with GBDK

I am just getting my feet wet using gbdk, and am having an issue when trying to include a lot of sprites.

Below is my code (minus sprite data), which is just a simple program to cycle through sprites and show them to the screen. I am compiling using:

    C:\gbdk\bin\lcc.exe spritetest.c -c -o spritetest.o

Things work fine when I have up to 150 sprites (2400 bytes) in sprite_data[], but if I have more than that then compiling fails. I don't get any errors, but no output is produced.

As I understand it, you can have up to 256 sprites, with the latter 128 sprites sharing VRAM with background tiles. So I am not sure why this is failing. Without any compiler errors, I am not sure where to go from here. Can anybody help me see what I'm missing?



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

void load_sprites()
{
    unsigned char sprite_data[] = {
        /* SPRITE DATA GOES HERE */
    };

    int sprite_count = sizeof(sprite_data)/16;
    set_sprite_data(0,sprite_count,sprite_data);
}

void main ()
{
    load_sprites();
    SHOW_SPRITES;

    //header
    gotoxy(5,5);
    printf("0123456789\n   0\n   1\n   2\n   3");

    //set 40 sprites and move them to center screen
    for (int i = 0; i < 40; i++)
    {
        set_sprite_tile (i, i);
        move_sprite(i, 48 + (i*8)%80, 64 + 8*(i/10) );
    }

    int line = 0;
    int last_joypad = 0;

    while (1)
    {
        int change_sprites = 0;

        //scroll up or down
        int this_joypad = joypad();
        if ((this_joypad-last_joypad) > 0)
        {
            if ((this_joypad-last_joypad) & J_UP && line > 0) { line--; change_sprites = 1; };
            if ((this_joypad-last_joypad) & J_DOWN && line < 22) { line++; change_sprites = 1; };
        }
        last_joypad = this_joypad;

        //change sprites
        if (change_sprites)
        {
            //line numbers
            for (int i = 0; i < 4; i++)
            {
                gotoxy(3,6+i);
                printf("%d  ",line+i);
            }

            //sprites
            for (int i = 0; i < 40; i++)
                set_sprite_tile (i, 10*line+i);
        }

        wait_vbl_done();
    }
}

Offline

 

#2 2023-05-11 23:17:08

mattu82
New member
Registered: 2023-05-11
Posts: 7

Re: Need help using more than 150 sprites with GBDK

Turns out there is a limit on function size, and 151 sprites is where I was hitting it. I got this to work by breaking up load_sprites into 2 functions like so:

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

void load_sprites1()
{
    unsigned char sprite_data[] = {
        /* SPRITE DATA 0-127 GOES HERE */
    };
    int sprite_count = sizeof(sprite_data)/16;
    set_sprite_data(0,sprite_count,sprite_data);
}

void load_sprites2()
{
    unsigned char sprite_data[] = {
        /* SPRITE DATA 128-255 GOES HERE */
    };
    int sprite_count = sizeof(sprite_data)/16;
    set_sprite_data(128,sprite_count,sprite_data);
}

void main ()
{
    load_sprites1();
    load_sprites2();
    SHOW_SPRITES;
    ...

Offline

 

#3 2023-05-14 22:04:33

bbbbbr
Member
Registered: 2019-03-04
Posts: 126

Re: Need help using more than 150 sprites with GBDK

Code:

void load_sprites1()
{
    unsigned char sprite_data[] = {
        /* SPRITE DATA 0-127 GOES HERE */
    };
    int sprite_count = sizeof(sprite_data)/16;
    set_sprite_data(0,sprite_count,sprite_data);
}

When that sprite data variable is declared inside the function (and without "static") that makes it a local variable, which goes on the Stack general memory region (of which there is not that much of in the GB)  Having it like that will also cause it to take up ROM for the variable init data, and then RAM as well for the memory it gets loaded into.

Since you don't seem to be modifying the data, it would be better to do 2 things:
1) Declare it outside the scope of a function so that it's global instead of stack-local
2) Make it "const" so that it's stored in ROM and doesn't use up the limited RAM available.

Code:

const  unsigned char sprite_data[] = {
        /* SPRITE DATA 0-127 GOES HERE */
    };

void load_sprites1()
{
    int sprite_count = sizeof(sprite_data)/16;
    set_sprite_data(0,sprite_count,sprite_data);
}

And even better, put it in a separate C source file and use a extern reference to allow access to it. That way large data arrays don't clutter up the source code.

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson