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.
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.
// 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
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
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.
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
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
This is my output.c file that contains my music 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
please, put it all together to github, because it's hard to help you other way.
Offline
I've dumped the files from that version of the build here:
Last edited by Sin (2020-05-10 14:06:26)
Offline
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:
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:
const unsigned char const fujimap[] = {};
that save you a lot of space in ROM and RAM.
Offline
Looks like that did the trick! Appreciate it!
Now to debug all the other issues. Haha!
Offline
To confirm, I put two const in each declaration?
Offline
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
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