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 2020-05-03 12:40:38

Sin
Member
Registered: 2019-08-11
Posts: 16

Music and Bank Switching Problem

Hello all,

Thank you so much for previous help, I have stepped away for some time and tried to come back and finish my first project using GBDK. However, I am running into problems after trying to add music. I added the code listed in the tutorial/template to do bank switching. When compiling I am getting errors that mention addresses possibly being wrote to twice and my game becomes unuseable. This leads me to believe something went wrong with the bank switching.


Below is my code. My hope was to be able to have the game music and maybe some artwork in one bank, and the rest in another? I honestly don't know much about the bank switching part so I am running blind mostly off of old threats and tutorials I found. I still have some code to add to the game for a start and pause, as well as updating the health and score counts, but wanted to get this sorted out first as it seems the most difficult for me. The game compiles/plays fine without the added music.


Code:

// Include statements

    #include <gb/gb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "kappa.c"
    #include "drops.c"
    #include "dropitems.c"
    #include "backgroundtiles.c"
    #include "fujimap.c"
    #include "score.c"

extern const unsigned char * song_Data[];


void main(){


    // Variables
        int r = 0;                      // Counter for right movement
        int l = 0;                      // Counter for left movement
        int i = 0;                      // Game loop counter
        int score = 0;                  // Holds player's score
        int water = 100;                // Holds player's water (health) left

        int char_x = 55;                // Player X value
        int char_y = 135;               // Player Y value

        int seed[] = {5, 2, 9, 1, 8, 4, 7, 6, 3, 0, 9, 0, 3, 1, 6, 2, 4, 7, 5, 8, 5, 7, 2, 7, 3, 1, 8, 0, 4, 9};

        int ax = 151;
        int ay = -100;
        int aspeed = 4;
        int apoint = 20;
        int acount = 0;

        int bx = 103;
        int by = 0;
        int bspeed = 5;
        int bpoint = 20;
        int bcount = 0;

        int cx = 103;
        int cy = 0;
        int cspeed = 8;
        int cpoint = 50;
        int ccount = 0;
        int cflag = 0;

        int dx = 151;
        int dy = 0;
        int dspeed = 7;
        int dpoint = 100;
        int dcount = 0;
        int dflag = 0;

        int ex = 55;
        int ey = 0;
        int espeed = 9;
        int epoint = 250;
        int ecount = 0;
        int eflag = 0;

        int n_count = 0;    // Counter for Seed position
        int c_count = 0;    // Counter for C drop loops
        int d_count = 0;    // Counter for D drop loops
        int e_count = 0;    // Counter for E drop loops



// Generates Background and sprites
    SPRITES_8x16;
    set_sprite_data(26,16,kappa);           // Pulls in Kappa Character sprites and sets defaults
    set_sprite_tile(0,26);
    move_sprite(0,char_x,char_y);
    set_sprite_tile(1,28);
    move_sprite(1,char_x+8, char_y);

    set_sprite_data(42,34,drops);            // Pulls in drops sprites and sets defaults
    set_sprite_tile(2,42);
    move_sprite(2,bx, by);
    set_sprite_tile(3,44);
    move_sprite(3,bx + 8, by);

    set_sprite_tile(4,42);
    move_sprite(4,ax, ay);
    set_sprite_tile(5,44);
    move_sprite(5,ax + 8, ay);

    set_sprite_tile(6,46);
    move_sprite(6,cx, cy);
    set_sprite_tile(7,48);
    move_sprite(7,cx + 8, cy);

    set_sprite_tile(8,54);
    move_sprite(8,dx, dy);
    set_sprite_tile(9,56);
    move_sprite(9,dx + 8, dy);

    set_sprite_tile(10,50);
    move_sprite(10,ex, ey);
    set_sprite_tile(11,52);
    move_sprite(11,ex + 8, ey);

    set_sprite_tile(12,58);             // Scores
    move_sprite(12, 42, 152);

    set_sprite_tile(13,58);
    move_sprite(13, 50, 152);

    set_sprite_tile(14,58);
    move_sprite(14, 58, 152);

    set_sprite_tile(15,58);
    move_sprite(15, 66, 152);

    set_sprite_tile(16,58);
    move_sprite(16, 74, 152);

    set_sprite_tile(17,60);         // Water
    move_sprite(17, 138, 152);

    set_sprite_tile(18,58);
    move_sprite(18, 146, 152);

    set_sprite_tile(19,58);
    move_sprite(19, 154, 152);



    set_bkg_data(0,122, backgroundtiles);   // Pulls in background sprite and sets defaults
    set_bkg_tiles(0,0, 20, 18, fujimap);


    SHOW_BKG;                               // Turns on background sprites and display
    SHOW_SPRITES;
    DISPLAY_ON;


//Music

    disable_interrupts();

    gbt_play(song_Data, 2, 7);
    gbt_loop(1);

    set_interrupts(VBL_IFLAG);
    enable_interrupts();


// Start main game loop
    while(1)
    {
        wait_vbl_done();

        i++;
        c_count++;
        d_count++;
        e_count++;


        if (i == 100) //100 game cycles
        {
            i = 0;
              by += bspeed;
              ay += aspeed;
              if (cflag == 1)
              {
                  cy += cspeed;
                }

            if (dflag == 1)
              {
                  dy += dspeed;
                }
                
            if (eflag == 1)
              {
                  ey += espeed;
                }
              
        }

        if (c_count == 12000)
        {
            c_count = 0;
            cflag = 1;
        }

        if (d_count == 17500)
        {
            d_count = 0;
            dflag = 1;
        }
        
        if (e_count == 25000)
        {
            e_count = 0;
            eflag = 1;
        }
       

// Drop A configurations        

    // Move Sprites as x and y update
    move_sprite(4,ax, ay);
    move_sprite(5,ax + 8, ay);

    // IF drop A is caught by player
    if (ax == char_x && ay >= char_y -16 && ay <= 136)
        {
            score += apoint;
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
              ay = 0;
              ax = 151;
              ax -= (seed[n_count] * 16);
              move_sprite(4,ax, 0);
              move_sprite(5,ax + 8, 0);
        }

    // If drop A hits the ground   
    if (ay >= 136)
        {
        // Increments counter and resets for next drop
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
            ay = 0;
            ax = 151;
            ax -= (seed[n_count] * 16);
            move_sprite(4,ax, 0);
            move_sprite(5,ax + 8, 0);
        }


// Drop B configurations

    // Move Sprites as x and y update
        move_sprite(2,bx, by);
        move_sprite(3,bx + 8, by);

    // IF drop B is caught by player
        if (bx == char_x && by >= char_y - 16 && by <= 136)
        {
            score += bpoint;
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
              by = 0;
              bx = 151;
              bx -= (seed[n_count] * 16);
              move_sprite(2,bx, 0);
              move_sprite(3,bx + 8, 0);
        }

        // If drop B hits the ground
        if (by >= 136)
        {
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }

            by = 0;
            bx = 151;
            bx -= (seed[n_count] * 16);
            move_sprite(2,bx, 0);
            move_sprite(3,bx + 8, 0);
          }

// Drop C configurations     

    if (cflag == 1)
    {
        // Move Sprites as x and y update
        move_sprite(6,cx, cy);
        move_sprite(7,cx + 8, cy);

        // IF drop C is caught by player
        if (cx == char_x && cy >= char_y -16 && cy <= 136)
        {
            score += cpoint;
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
              cy = 0;
              cx = 151;
              cx -= (seed[n_count] * 16);
              move_sprite(6,cx, 0);
              move_sprite(7,cx + 8, 0);
              cflag = 0;
        }

        // If drop C hits the ground   
        if (cy >= 136)
        {
        // Increments counter and resets for next drop
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
            cflag = 0;
            cy = 0;
            cx = 151;
            cx -= (seed[n_count] * 16);
            move_sprite(6,cx, 0);
            move_sprite(7,cx + 8, 0);
        }

    }


// Drop D configurations     

    if (dflag == 1)
    {
        // Move Sprites as x and y update
        move_sprite(8,dx, dy);
        move_sprite(9,dx + 8, dy);

        // IF drop D is caught by player
        if (dx == char_x && dy >= char_y -16 && dy <= 136)
        {
            score += dpoint;
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
              dy = 0;
              dx = 151;
              dx -= (seed[n_count] * 16);
              move_sprite(8,dx, 0);
              move_sprite(9,dx + 8, 0);
              dflag = 0;
        }

        // If drop D hits the ground   
        if (dy >= 136)
        {
        // Increments counter and resets for next drop
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
            dflag = 0;
            dy = 0;
            dx = 151;
            dx -= (seed[n_count] * 16);
            move_sprite(8,dx, 0);
            move_sprite(9,dx + 8, 0);
        }

    }
         
// Drop E configurations     

    if (eflag == 1)
    {
        // Move Sprites as x and y update
        move_sprite(10,ex, ey);
        move_sprite(11,ex + 8, ey);

        // IF drop E is caught by player
        if (ex == char_x && ey >= char_y -16 && ey <= 136)
        {
            score += epoint;
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
              ey = 0;
              ex = 151;
              ex -= (seed[n_count] * 16);
              move_sprite(10,ex, 0);
              move_sprite(11,ex + 8, 0);
              eflag = 0;
        }

        // If drop E hits the ground   
        if (ey >= 136)
        {
        // Increments counter and resets for next drop
            if (n_count == 29)
            {
                n_count = 0;
            }
            else
            {
                 n_count++;
            }
            eflag = 0;
            ey = 0;
            ex = 151;
            ex -= (seed[n_count] * 16);
            move_sprite(10,ex, 0);
            move_sprite(11,ex + 8, 0);
        }

    }








//Begin Joypad Controls
    switch(joypad())
            {
            case J_LEFT:            // If user presses left
                if(char_x > 10)     // If user can move left
                {
                    l++;            // Increment left counter
                    if (l == 60)
                    {   water -= 1;
                        char_x -= 16;
                        move_sprite(0,char_x,char_y);
                        move_sprite(1,char_x+8,char_y); 
                        set_sprite_tile(1,28);
                        set_sprite_tile(0,26);
                    }

                    else if (l == 65)
                    {
                        set_sprite_tile(0,30);
                        set_sprite_tile(1,32);
                    }

                    else if (l==75)
                    {
                        set_sprite_tile(0,30);
                        set_sprite_tile(1,32);
                    }

                    else if (l==85)
                    {
                        set_sprite_tile(0,38);
                        set_sprite_tile(1,40);
                    }

                    else if (l==95)
                    {
                        l=0;
                        set_sprite_tile(0,26);
                        set_sprite_tile(1,28);
                    }
                    
                }
                break;

             case J_RIGHT:          // If user presses right
                if(char_x < 150)    // If user can move right
                {
                     r++;           // Increment right counter

                    if (r == 60)
                    {
                        water -= 1;
                        char_x += 16;
                        move_sprite(0,char_x,char_y);
                        move_sprite(1,char_x+8,char_y); 
                        set_sprite_tile(1,28);
                        set_sprite_tile(0,26);
                    }

                    else if (r == 65)
                    {
                        set_sprite_tile(0,30);
                        set_sprite_tile(1,32);
                    }

                    else if (r==75)
                    {
                        set_sprite_tile(0,30);
                        set_sprite_tile(1,32);
                    }

                    else if (r==85)
                    {
                        set_sprite_tile(0,38);
                        set_sprite_tile(1,40);
                    }

                    else if (r==95)
                    {
                        r=0;
                        set_sprite_tile(0,26);
                        set_sprite_tile(1,28);
                    }
                }
                break;  
            default:
                {
                    set_sprite_tile(1,28);
                    set_sprite_tile(0,26);
                }
             
            }// End Joypad Controls


    gbt_update(); // This will change to ROM bank 1.
}// End Game While Loop

}   // End Main

Offline

 

#2 2020-05-03 16:43:21

toxa
Member
Registered: 2020-02-13
Posts: 309

Re: Music and Bank Switching Problem

Sin wrote:

I added the code listed in the tutorial/template to do bank switching. When compiling I am getting errors that mention addresses possibly being wrote to twice and my game becomes unuseable.

something is wrong not with your code, but with the scripts you are using to build a rom. describe what gbdk do you use and post your scripts here.

don't try to make all work together from the beginning. write a small test with an almost empty main and music only. make it work.

ps: your manipulations with interrupts do nothing, they are useless. you might copy this from some program that has an interrupt-driven function for gbt_player, but you don't have your own interrupt routine with a gbt_update() call.

Offline

 

#3 2020-05-03 19:18:33

Sin
Member
Registered: 2019-08-11
Posts: 16

Re: Music and Bank Switching Problem

Thanks for the quick response!

I managed to get just the music playing for a .gb file fine, it was when I tried to merge the code with my current game work that I ran into the problems.

I did use the code (and interrupts) from a tutorial that used GBT_Player.


This is my make.bat, using version 2.95-3.

Code:

mod2gbt kappadrop.mod song -c 2

C:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o main.o main.c
C:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o output.o output.c
C:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o gbt_player.o gbt_player.s
C:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o gbt_player_bank1.o gbt_player_bank1.s

C:\gbdk\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -Wl-yt1 -Wl-yo4 -Wl-ya0 -o music.gb main.o output.o gbt_player.o gbt_player_bank1.o

del *.o *.lst

pause

Looking at the make.bat, do I need to modify that?

Offline

 

#4 2020-05-04 14:51:44

toxa
Member
Registered: 2020-02-13
Posts: 309

Re: Music and Bank Switching Problem

where is your song_Data defined? is it supposed to be in in bank2, are you sure you compile that file with #pragma bank 2 or -bo2 switch? it seems that you simply put that array to bank0 and it overflows, that results in thar "addresses possibly being wrote to twice" messages.

Last edited by toxa (2020-05-04 14:57:44)

Offline

 

#5 2020-05-04 17:58:31

Sin
Member
Registered: 2019-08-11
Posts: 16

Re: Music and Bank Switching Problem

This is my output.c file that contains my music code.

Code:

// File created by mod2gbt

#pragma bank=2

const unsigned char song0[] = {
  0x9d,0x04, 0x00, 0x8d,0x14, 0x89,0x01,
  0x21, 0x00, 0x22, 0x25,
  0x20, 0x00, 0x20, 0x24,
  0x00, 0x00, 0x8c,0x14, 0x20,
  0x00, 0x00, 0x21, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8d,0x24, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8e,0x14, 0x8d,0x01,
  0x00, 0x00, 0x21, 0x28,
  0x00, 0x00, 0x8f,0x14, 0x34,
  0x00, 0x00, 0x21, 0x20,
  0x00, 0x00, 0x8e,0x14, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8f,0x14, 0x00,
  0x00, 0x00, 0x22, 0x00,
  0x9d,0x04, 0x00, 0x8d,0x14, 0x89,0x01,
  0x21, 0x00, 0x22, 0x25,
  0x20, 0x00, 0x20, 0x24,
  0x00, 0x00, 0x8c,0x14, 0x20,
  0x00, 0x00, 0x21, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8d,0x24, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8e,0x14, 0x8d,0x01,
  0x00, 0x00, 0x21, 0x28,
  0x00, 0x00, 0x8f,0x14, 0x34,
  0x00, 0x00, 0x21, 0x20,
  0x00, 0x00, 0x8e,0x14, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8f,0x14, 0x00,
  0x00, 0x00, 0x22, 0x00,
  0x9d,0x04, 0x00, 0x8d,0x14, 0x89,0x01,
  0x21, 0x00, 0x22, 0x25,
  0x20, 0x00, 0x20, 0x24,
  0x00, 0x00, 0x8c,0x14, 0x20,
  0x00, 0x00, 0x21, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8d,0x24, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8e,0x14, 0x8d,0x01,
  0x00, 0x00, 0x21, 0x28,
  0x00, 0x00, 0x8f,0x14, 0x34,
  0x00, 0x00, 0x21, 0x20,
  0x00, 0x00, 0x8e,0x14, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8f,0x14, 0x00,
  0x00, 0x00, 0x22, 0x00,
  0x9d,0x04, 0x00, 0x8d,0x14, 0x89,0x01,
  0x21, 0x00, 0x22, 0x25,
  0x20, 0x00, 0x20, 0x24,
  0x00, 0x00, 0x8c,0x14, 0x20,
  0x00, 0x00, 0x21, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8d,0x24, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8e,0x14, 0x8d,0x01,
  0x00, 0x00, 0x21, 0x28,
  0x00, 0x00, 0x8f,0x14, 0x34,
  0x00, 0x00, 0x21, 0x20,
  0x00, 0x00, 0x8e,0x14, 0x00,
  0x00, 0x00, 0x20, 0x00,
  0x00, 0x00, 0x8f,0x14, 0x00,
  0x00, 0x00, 0x22, 0x00
};

const unsigned char * song_Data[] = {
    song0,
    0x0000
};

Offline

 

#6 2020-05-05 09:13:39

toxa
Member
Registered: 2020-02-13
Posts: 309

Re: Music and Bank Switching Problem

please, put it all together to github, because it's hard to help you other way.

Offline

 

#7 2020-05-05 13:44:31

Sin
Member
Registered: 2019-08-11
Posts: 16

Re: Music and Bank Switching Problem

I've dumped the files from that version of the build here:

Last edited by Sin (2020-05-10 14:06:26)

Offline

 

#8 2020-05-05 18:26:29

toxa
Member
Registered: 2020-02-13
Posts: 309

Re: Music and Bank Switching Problem

everything is ok, you just simply run out of rom. that's not because you have too much graphics, but you simply declare arrays like:

Code:

unsigned char fujimap[] = {...};

that means, that this is a array variable in RAM, initialized with some values. so, sdcc generates loads of code to init that array in RAM with constant data.

you must declare your constants as:

Code:

const unsigned char const fujimap[] = {};

that save you a lot of space in ROM and RAM.

Offline

 

#9 2020-05-05 19:07:58

Sin
Member
Registered: 2019-08-11
Posts: 16

Re: Music and Bank Switching Problem

Looks like that did the trick! Appreciate it!

Now to debug all the other issues. Haha!

Offline

 

#10 2020-05-05 19:59:15

Sin
Member
Registered: 2019-08-11
Posts: 16

Re: Music and Bank Switching Problem

To confirm, I put two const in each declaration?

Offline

 

#11 2020-05-06 04:44:29

toxa
Member
Registered: 2020-02-13
Posts: 309

Re: Music and Bank Switching Problem

put as many const as you can.
this is a nice tool to visualize rom usage: https://github.com/pinobatch/240p-test- … omusage.py

Last edited by toxa (2020-05-06 06:29:39)

Offline

 

#12 2020-05-07 19:34:20

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

Re: Music and Bank Switching Problem

If you are using Linux then you can also use this shell script to get a readout of your bank usage:
https://gbdev.gg8.se/forums/viewtopic.php?id=632

Example output:
GroupBy(Seg),sum(Size)
CABS,0
CODE,11364
CODE_1,15043
CODE_2,14780
CODE_3,15263
DABS,0
DATA,1545
GSFINAL,0
GSINIT,1038
HOME,0

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson