// -------- // INCLUDES // -------- //#include #include // --------- // FUNCTIONS // --------- void init(); void update60(); void update30(); void update15(); void drawCircles(); void drawEyeClosed(); void drawEyeOpen(); void drawMap(); void drawWallBackground(); void drawWallSprites(); UINT8 getRandom(); UINT8 rand(); void initrand(); // --------- // VARIABLES // --------- // Some generic variables used by methods // DO NOT call other methods that use these variables when in use! UINT8 i; UINT8 j; UINT8 k; UINT8 l; // Stores pressed key data UINT8 keysCurrent; UINT8 keysLast; // Whether the game has ended UINT8 gameover; // Counter for the different update intervals UINT8 ticker; // How many frames the eye stays closed UINT8 eyeClosed; // Which object slot should be used for the next ring UINT8 ringLoop; // How many frames until the next ring spawns UINT8 nextRing; // How many pixel the walls are away from the center UINT8 wallDistance; // How many pixel the rings are away from the center UINT8 ringDistance[8]; // From which way the rings are facing UINT8 ringDirection[8]; // On which side the ring has the hole UINT8 ringHole[8]; // -------- // GRAPHICS // -------- const unsigned char TilesSprites[] = { // 00: RING UP 0x6C,0x6C,0xEE,0xEE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xFE,0xFE,0x7C,0x7C,0x00,0x00, // 01: WALL HORIZONTAL 0/8 0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 02: WALL HORIZONTAL 1/8 0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 03: WALL HORIZONTAL 2/8 0xFF,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 04: WALL HORIZONTAL 3/8 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 05: WALL HORIZONTAL 4/8 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 06: WALL HORIZONTAL 5/8 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,0x00, // 07: WALL HORIZONTAL 6/8 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00, // 08: WALL HORIZONTAL 7/8 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7E,0x00, // 09: WALL VERTICAL 0/8 0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00, // 10: WALL VERTICAL 1/8 0x80,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0x80,0x80, // 11: WALL VERTICAL 2/8 0xC0,0xC0,0xE0,0xC0,0xE0,0xC0,0xE0,0xC0,0xE0,0xC0,0xE0,0xC0,0xE0,0xC0,0xC0,0xC0, // 12: WALL VERTICAL 3/8 0xE0,0xE0,0xF0,0xE0,0xF0,0xE0,0xF0,0xE0,0xF0,0xE0,0xF0,0xE0,0xF0,0xE0,0xE0,0xE0, // 13: WALL VERTICAL 4/8 0xF0,0xF0,0xF8,0xF0,0xF8,0xF0,0xF8,0xF0,0xF8,0xF0,0xF8,0xF0,0xF8,0xF0,0xF0,0xF0, // 14: WALL VERTICAL 5/8 0xF8,0xF8,0xFC,0xF8,0xFC,0xF8,0xFC,0xF8,0xFC,0xF8,0xFC,0xF8,0xFC,0xF8,0xF8,0xF8, // 15: WALL VERTICAL 6/8 0xFC,0xFC,0xFE,0xFC,0xFE,0xFC,0xFE,0xFC,0xFE,0xFC,0xFE,0xFC,0xFE,0xFC,0xFC,0xFC, // 16: WALL VERTICAL 7/8 0xFE,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFE,0xFE, // 17: RING LEFT 0x7C,0x7C,0xFE,0xFE,0xC6,0xC6,0x06,0x06,0xC6,0xC6,0xFE,0xFE,0x7C,0x7C,0x00,0x00, }; const unsigned char TilesBackground[] = { // 00: EMPTY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 01: WALL 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 02: LINE UP 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 03: LINE DOWN 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00, // 04: LINE LEFT 0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80, // 05: LINE RIGHT 0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02, // 06: CORNER UP LEFT 0x7F,0x7F,0xBF,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80, // 07: CORNER UP RIGHT 0xFC,0xFC,0xFA,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02, // 08: CORNER DOWN LEFT 0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xBF,0x80,0x7F,0x7F,0x00,0x00, // 09: CORNER DOWN RIGHT 0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0xFA,0x02,0xFC,0xFC,0x00,0x00, // 10: EYE OPEN UP LEFT 0xBF,0x00,0x40,0x00,0x80,0x00,0x80,0x00,0x87,0x00,0x8F,0x00,0x8C,0x00,0x8C,0x00, // 11: EYE OPEN UP RIGHT 0xFB,0x01,0x05,0x00,0x02,0x00,0x02,0x00,0xC2,0x00,0xE2,0x00,0x62,0x00,0x62,0x00, // 12: EYE OPEN DOWN LEFT 0x8C,0x00,0x8F,0x00,0x87,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0xBF,0x00,0xC0,0x80, // 13: EYE OPEN DOWN RIGHT 0x62,0x00,0xE2,0x00,0xC2,0x00,0x02,0x00,0x02,0x00,0x05,0x00,0xFB,0x01,0x06,0x02, // 14: EYE CLOSED UP LEFT 0xBF,0x00,0x40,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x00,0xFF,0x00, // 15: EYE CLOSED UP RIGHT 0xFB,0x01,0x05,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0xFE,0x00,0xFE,0x00, // 16: EYE CLOSED DOWN LEFT 0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0xBF,0x00,0xC0,0x80, // 17: EYE CLOSED DOWN RIGHT 0xFE,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x05,0x00,0xFB,0x01,0x06,0x02, // 18: LINE DOWN 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF, // 19: LINE CORNER DOWN LEFT 0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xC0,0x80,0xFF,0xFF, // 20: LINE CORNER DOWN RIGHT 0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0x06,0x02,0xFF,0xFF, // 21: LINE RIGHT 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, // 22: LINE CORNER RIGHT UP 0xFF,0xFF,0xFF,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, // 23: LINE CORNER RIGHT DOWN 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0x01,0xFF,0xFF,0x01,0x01, // 24: LINE DOWN RIGHT 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0xFF,0xFF, // 25: WALL DOWN 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00, // 26: WALL RIGHT 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, }; const unsigned char TilesEyeOpen[] = { 10,11, 12,13 }; const unsigned char TilesEyeClosed[] = { 14,15, 16,17 }; // ---- // MAPS // ---- const unsigned char MapGame[] = { 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,02,02,02,02,02,02,02,02,00,00,02,02,02,02,02,02,02,22,01, 01,03,03,03,03,03,03,03,03,00,00,03,03,03,03,03,03,03,23,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,00,00,00,00,00,00,00,00,04,05,00,00,00,00,00,00,00,21,01, 01,18,18,18,18,18,18,18,18,19,20,18,18,18,18,18,18,18,24,01 }; // Just a bunch of walls const unsigned char MapWallBlock[] = { 1,1,1,1,1,1,1,1 }; // Just a bunch of walls const unsigned char MapWallDown[] = { 25,25,25,25,25,25,25,25 }; // Just a bunch of walls const unsigned char MapWallRight[] = { 26,26,26,26,26,26,26,26 }; // ----- // LOGIC // ----- void main(){ init(); while (1) { keysCurrent=joypad(); if(ticker == 4) { ticker = 0; } if (gameover == 0) { update60(); if(ticker == 0) { update30(); update15(); } else if(ticker == 2) { update30(); } ticker++; } else { if ((keysCurrent & J_A) && !(keysLast & J_A)) { init(); } } keysLast=keysCurrent; wait_vbl_done(); } } void init(){ // Set layer visibility DISPLAY_ON; HIDE_WIN; SHOW_SPRITES; SHOW_BKG; // Enable Sound NR52_REG = 0x80; // Enable sound NR51_REG = 0xBB; // Use sound channel 1, 2 and 4 NR50_REG = 0x77; // Set volume to max //initrand(DIV_REG); initrand(); // Load Data set_sprite_data(0, 18, TilesSprites); set_bkg_data(0, 27, TilesBackground); // Set Sprite properties set_sprite_prop(0, 0); set_sprite_prop(1, 0); set_sprite_prop(2, S_FLIPY); set_sprite_prop(3, S_FLIPY); set_sprite_prop(4, 0); set_sprite_prop(5, 0); set_sprite_prop(6, S_FLIPX); set_sprite_prop(7, S_FLIPX); // Initialize default values eyeClosed = 0; ringLoop = 0; nextRing = 1; wallDistance = 63; ticker = 0; gameover = 0; for (i = 0; i != 8; i++) { ringDistance[i] = 0; } // Draw initial state drawMap(); drawEyeOpen(); drawWallBackground(); drawWallSprites(); } void update60(){ j = 5; // Check direction keys if ((keysCurrent & J_UP) && !(keysLast & J_UP)) { j = 0; } else if((keysCurrent & J_DOWN) && !(keysLast & J_DOWN)) { j = 1; } else if ((keysCurrent & J_LEFT) && !(keysLast & J_LEFT)) { j = 2; } else if ((keysCurrent & J_RIGHT) && !(keysLast & J_RIGHT)) { j = 3; } if (j != 5) { eyeClosed = 8; // Check if ring is hit for (i = 0; i != 8; i++) { // Assign this first because why not... D: k = ringHole[i]; // Check if ring is in range if ((k == j) && ringDistance[i] < 15 && ringDistance[i] > 0) { // Check if ring is in perfect range NR21_REG = 0x0F; NR22_REG = 0xFF; NR23_REG = 0xF0; NR24_REG = 0xC3; // Remove ring ringDistance[i] = 0; } } } if(eyeClosed){ eyeClosed--; drawEyeClosed(); } else { drawEyeOpen(); } } void update30(){ // Move circles closer for (i=0; i != 8; i++){ if(ringDistance[i] != 0) { ringDistance[i]--; if(ringDistance[i] == 0) { gameover = 1; NR41_REG = 0x3F; NR42_REG = 0xF7; NR43_REG = 0x8A; NR44_REG = 0xC0; } } } drawCircles(); } void update15() { nextRing--; if(nextRing == 0) { // Play sound NR10_REG = 0x1E; NR11_REG = 0x10; NR12_REG = 0x83; NR13_REG = 0x00; NR14_REG = 0x87; // Move walls closer if(wallDistance > 9) { wallDistance--; } // Generate next ring ringDistance[ringLoop] = 63; ringDirection[ringLoop] = getRandom(); ringHole[ringLoop] = getRandom(); if (ringHole[ringLoop] == 0){ set_sprite_tile(8 + ringLoop, 0); set_sprite_prop(8 + ringLoop, 0); } else if (ringHole[ringLoop]==1) { set_sprite_tile(8 + ringLoop, 0); set_sprite_prop(8 + ringLoop, S_FLIPY); } else if (ringHole[ringLoop]==2) { set_sprite_tile(8 + ringLoop, 17); set_sprite_prop(8 + ringLoop, 0); } else if (ringHole[ringLoop]==3) { set_sprite_tile(8 + ringLoop, 17); set_sprite_prop(8 + ringLoop, S_FLIPX); } ringLoop++; if(ringLoop == 8) { ringLoop = 0; } nextRing = 8; drawWallBackground(); drawWallSprites(); } } void drawMap(){ set_bkg_tiles(0, 0, 20, 18, MapGame); } void drawEyeClosed(){ set_bkg_tiles(9, 8, 2, 2, TilesEyeClosed); } void drawEyeOpen(){ set_bkg_tiles(9, 8, 2, 2, TilesEyeOpen); } // Draws all fully blacked out tiles into the background void drawWallBackground() { i = wallDistance / 8; // Up set_bkg_tiles( 9, 0, 1, 8 - i, MapWallBlock); set_bkg_tiles(10, 0, 1, 8 - i, MapWallRight); // Left set_bkg_tiles(1, 8, 8 - i, 1, MapWallBlock); set_bkg_tiles(1, 9, 8 - i, 1, MapWallDown); i = (wallDistance - 1) / 8; // Down set_bkg_tiles( 9, 10 + i, 1, 8 - i, MapWallBlock); set_bkg_tiles(10, 10 + i, 1, 8 - i, MapWallRight); // Right set_bkg_tiles(11 + i, 8, 8 - i, 1, MapWallBlock); set_bkg_tiles(11 + i, 9, 8 - i, 1, MapWallDown); } // Draws partially blacked out tiles as sprites void drawWallSprites() { // Calculate distance i = 8 - wallDistance % 8; // Set Sprite tiles set_sprite_tile(0, i); set_sprite_tile(1, i); set_sprite_tile(4, 8 + i); set_sprite_tile(5, 8 + i); wallDistance--; i = 8 - wallDistance % 8; set_sprite_tile(2, i); set_sprite_tile(3, i); set_sprite_tile(6, 8 + i); set_sprite_tile(7, 8 + i); wallDistance++; // Calculate position i = (8 * 8) - (wallDistance - wallDistance % 8); // Set Sprite position move_sprite(0, 80, 16 + i); // UpA move_sprite(1, 86, 16 + i); // UpB move_sprite(4, 16 + i, 81); // LeftA move_sprite(5, 16 + i, 87); // LeftB wallDistance--; i = (8 * 8) - (wallDistance - wallDistance % 8); move_sprite(2, 80, 152 - i); // DownA move_sprite(3, 86, 152 - i); // DownB move_sprite(6, 152 - i, 81); // RightA move_sprite(7, 152 - i, 87); // RightB wallDistance++; } void drawCircles() { if (gameover == 1) return; for (i=0; i != 8; i++){ // Calculate offset j = 0; k = 0; l = ringHole[i]; if (l == 3) { j = 1; } else if (l == 1) { k = 1; } // Set position if (ringDistance[i] == 0) { move_sprite(8 + i, 0, 0); } else if (ringDirection[i] == 0) { move_sprite(8 + i, 84 - j, 92 - ringDistance[i] - k); } else if (ringDirection[i] == 1) { move_sprite(8 + i, 84 - j, 76 + ringDistance[i] - k); } else if (ringDirection[i] == 2) { move_sprite(8 + i, 92 - ringDistance[i] - j, 84 - k); } else if (ringDirection[i] == 3) { move_sprite(8 + i, 76 + ringDistance[i] - j, 84 - k); } } } UINT8 getRandom() { // Do this, because reasons... D: //j = rand(); return rand() % 4; } UINT8 next; // Pseudo-random number generator UINT8 rand(void) { next = next * 49 + 13; return next / 64 % 32; } // Initializes the randomness void initrand() { next = DIV_REG; }