Yes, it’s finally here, with comments and everything! Below is the code for the C file and I’ve included all the files with a readme.txt file for your perusal here. I hope this helps you to get started on your gameboy development journeys!
gbdkdemo .zip file, 6kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
//////////////////////////////////////////////////////////////////////////////// // DEMOGAME.C //------------------------------------------------------------------------------ // FAIRLY MINIMAL GAME DEMO FOR GETTING STARTED WITH GBDK // BY REFRESH GAMES //------------------------------------------------------------------------------ // THIS IS INTENDED TO BE A BASE POINT FOR ANYONE TO CUSTOMISE AND ADD TO SO // THEY CAN MAKE THEIR OWN GAMEBOY GAMES, HENCE THE COMMENTS! //------------------------------------------------------------------------------ // WEB: refreshgames.co.uk //////////////////////////////////////////////////////////////////////////////// #include // INCLUDE RANDOM FUNCTIONS #include ; // INCLUDE GBDK FUNCTION LIBRARY #include ; // INCLUDE HANDY HARDWARE REFERENCES // FUNCTION DECLARATIONS void initGame(); // INITIALISE OUR GAME void updatePlayer(); // UPDATE OUR PLAYER UINT8 collisionCheck(UINT8, UINT8, UINT8, UINT8, UINT8, UINT8, UINT8, UINT8); // SIMPLE RECT TO RECT CHECK // VARIABLE DECLARATIONS - STORED IN RAM UINT8 i, j; // GENERIC LOOPING VARIABLE UINT8 playerX, playerY; // PLAYER CO-ORDINATES UINT8 eX[10], eY[10]; // ENEMY CO-ORDINATES UINT8 lastKeys; // HOLDS KEYS FOR THE PREVIOUS FRAME UINT8 randomBkgTiles[20]; // CONTAINS RANDOM DATA FOR OUR BKG // SPRITE DATA - 14 SPRITES - STORED IN ROM const unsigned char sprites[] = {0x3C,0x3C,0x42,0x42,0xA9,0xA9,0xA9,0xA9,0x81,0x81,0x91,0x91,0x42,0x42,0x3C,0x3C,0x3C,0x3C,0x42,0x42,0x81,0x81,0xED,0xED,0x81,0x81,0x91,0x91,0x42,0x42,0x3C,0x3C,0x99,0x81,0x42,0x5A,0x24,0x3C,0x99,0x7E,0x99,0x7E,0x24,0x3C,0x42,0x5A,0x99,0x81,0x38,0x04,0x7C,0x02,0x5C,0x22,0x5C,0x22,0x5C,0x22,0x5C,0x22,0x7C,0x02,0x38,0x04,0x00,0x00,0x3E,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x3E,0x00,0x00,0x00,0x00,0x1C,0x1C,0x3C,0x3C,0x6C,0x6C,0x0C,0x0C,0x0C,0x0C,0x7F,0x7F,0x00,0x00,0x00,0x00,0x3E,0x3E,0x63,0x63,0x03,0x03,0x1E,0x1E,0x70,0x70,0x7F,0x7F,0x00,0x00,0x00,0x00,0x7F,0x7F,0x03,0x03,0x3E,0x3E,0x07,0x07,0x43,0x43,0x3E,0x3E,0x00,0x00,0x00,0x00,0x60,0x60,0x6C,0x6C,0x6C,0x6C,0x7F,0x7F,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,0x7F,0x7F,0x60,0x60,0x7E,0x7E,0x03,0x03,0x63,0x63,0x3E,0x3E,0x00,0x00,0x00,0x00,0x3F,0x3F,0x60,0x60,0x7E,0x7E,0x63,0x63,0x63,0x63,0x3E,0x3E,0x00,0x00,0x00,0x00,0x7F,0x7F,0x03,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x00,0x00,0x00,0x00,0x3E,0x3E,0x63,0x63,0x63,0x63,0x3E,0x3E,0x63,0x63,0x3E,0x3E,0x00,0x00,0x00,0x00,0x3E,0x3E,0x63,0x63,0x63,0x63,0x3F,0x3F,0x03,0x03,0x7E,0x7E,0x00,0x00}; //BACKGROUND DATA - 4 SPRITES - STORED IN ROM const unsigned char myBkgData[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x36,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x50,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0E,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x20,0x00,0x50,0x00,0x00,0x00}; //////////////////////////////////////////////////////////////////////////////// // MAIN FUNCTION void main(){ initGame(); // RAN ONCE AT STARTUP // GAME LOOP START while(1){ updatePlayer(); // UPDATE PLAYER HIDE_WIN; // SHOW WINDOW LAYER SHOW_SPRITES; // HIDE SPRITES LAYER SHOW_BKG; // SHOW BACKGROUND LAYER lastKeys = joypad(); // UPDATE OUR KEYPRESSES wait_vbl_done(); // WAIT FOR VBLANK TO FINISH - ENSURES 60 FRAMES PER SECOND MAXIMUM } // GAME LOOP END } //////////////////////////////////////////////////////////////////////////////// // INIT GAME void initGame(){ DISPLAY_ON; // TURNS ON THE GAMEBOY LCD NR52_REG = 0x8F; // TURN SOUND ON NR51_REG = 0x11; // ENABLE SOUND CHANNELS NR50_REG = 0x1F; // VOLUME MAX = 0x77, MIN = 0x00 initrand(DIV_REG); // SEED OUR RANDOMIZER set_sprite_data(0, 14, sprites); // STORE OUR SPRITE DATA AT THE START OF SPRITE VRAM set_bkg_data(0, 4, myBkgData); // STORE OUR BKG DATA AT THE START OF BKG VRAM - NOTE, THE WINDOW LAYER SHARED THE BKG VRAM BY DEFAULT playerX = 64; // PLAYERS INITAL X POSITION playerY = 64; // PLAYERS INITAL Y POSITION set_sprite_tile(0,0); //PLAYERS SPRITE TILE - 0 for (i=0; i !=10; i++){ // OUR ENEMY POSITION LOOP - NOTE, USE !=, NOT < TO SCRAPE BACK SOME CPU TIME eX[i] = 16+(rand() >> 1); // RANDOM X POSITION 16 - 144 eY[i] = 16+(rand() >> 1); // RANDOM Y POSITION 16 - 144 set_sprite_tile(i+1, 2); // ENEMIES SRITE TILE - SET TO SPRITE 2 move_sprite(i+1,eX[i], eY[i]); // POSITION ENEMIES } // GENERATE RANDOM BKG TILE DATA - SO STARRY! for (j=0; j != 18; j++){ for (i=0; i != 20; i++){ randomBkgTiles[i] = rand() % 4; } set_bkg_tiles(0,j,20,1,randomBkgTiles); // SET A LINE OF BKG DATA (X, Y, W, H, DATA) } } //////////////////////////////////////////////////////////////////////////////// // UPDATE PLAYER void updatePlayer(){ // MOTION VIA DPAD - LIMITED TO A CERTAIN AREA ON SCREEN // UP if (joypad() & J_UP){ playerY--; if (playerY == 15){ playerY = 16; } } // DOWN if (joypad() & J_DOWN){ playerY++; if (playerY == 153){ playerY = 152; } } // LEFT if (joypad() & J_LEFT){ playerX--; if (playerX == 7){ playerX = 8; } } // RIGHT if (joypad() & J_RIGHT){ playerX++; if (playerX == 161){ playerX = 160; } } // END MOTION VIA DPAD // TAP A - PLAYS A RANDOM BEEP THROUGH SOUND CHANNEL 1 - SQUARE WAVE CHANNEL if (joypad() & J_A){ NR11_REG = 0x7f; // SQUARE WAVE DUTY NR12_REG = 0x7f; // VOLUME 0 = quietest, 255 = loudest NR13_REG = DIV_REG; // LOWER BITS OF SOUND FREQ NR14_REG = 0x80 + (DIV_REG % 8); // LARGER SOUND FREQ - MINIMUM OF 128 - TOP 3 BYTES - ANY LESS = SOUND CHANNEL SWITCHES OFF } else { NR11_REG = 0x00; // NO A BUTTON - NO SOUND NR12_REG = 0x00; NR13_REG = 0x00; NR14_REG = 0x00; } //MOVE OUR SPRITE move_sprite(0,playerX,playerY); // POSITION OUR SPRITE ON THE SCREEN j=0; // RE-USE J AS A FLAG TO SEE IF WE HAVE COLLIDED WITH AN ENEMY for (i=0; i != 10; i++){ // LOOP THROUGH OUR 10 ENEMIES if (collisionCheck(playerX, playerY, 8, 8, eX[i], eY[i], 8, 8) == 1){ j= 1; // IF WE COLLIDED, SET OUR FLAG VARIABLE, J TO 1 } } // ADJUST OUR PLAYER SPRITES FRAME IF THEY HIT SOMETHING switch (j){ // NO HIT case 0: set_sprite_tile(0,0); break; // HIT ENEMY default: set_sprite_tile(0,1); break; } } //////////////////////////////////////////////////////////////////////////////// // COLLISION CHECKER - SIMPLE RECTANGLE COLLISION CHECKING // RETURNS 1 IF OVERLAPPING UINT8 collisionCheck(UINT8 x1, UINT8 y1, UINT8 w1, UINT8 h1, UINT8 x2, UINT8 y2, UINT8 w2, UINT8 h2){ if ((x1 < (x2+w2)) && ((x1+w1) > x2) && (y1 < (h2+y2)) && ((y1+h1) > y2)){ return 1; } else { return 0; } } |
1 thought on “Gameboy GBDK Tutorial ROM Code!”
Comments are closed.