sgb_pong.c (4194B)
1#include <gb/gb.h> 2#include <gb/sgb.h> 3#include <gbdk/console.h> 4 5#include <stdint.h> 6#include <stdio.h> 7 8uint8_t sprite_data[] = { 9 0x3C,0x3C,0x42,0x7E,0x99,0xFF,0xA9,0xFF,0x89,0xFF,0x89,0xFF,0x42,0x7E,0x3C,0x3C, 10 0x3C,0x3C,0x42,0x7E,0xB9,0xFF,0x89,0xFF,0x91,0xFF,0xB9,0xFF,0x42,0x7E,0x3C,0x3C, 11 0x3C,0x3C,0x42,0x7E,0x99,0xFF,0x89,0xFF,0x99,0xFF,0x89,0xFF,0x5A,0x7E,0x3C,0x3C, 12 0x3C,0x3C,0x42,0x7E,0xA9,0xFF,0xA9,0xFF,0xB9,0xFF,0x89,0xFF,0x42,0x7E,0x3C,0x3C 13 14}; 15 16// initializes sprites for pad. every pad uses 3 sprites which id's are aligned by 4 17void init_pad(uint8_t n) { 18 set_sprite_tile(n << 2, n); 19 set_sprite_tile((n << 2) + 1, n); 20 set_sprite_tile((n << 2) + 2, n); 21} 22 23// inline function for moving pads; code of this function will be inlined with the code of main() 24inline void draw_pad(uint8_t n, uint8_t x, uint8_t y) { 25 move_sprite(n << 2, x, y); 26 move_sprite((n << 2) + 1, x, y + 8); 27 move_sprite((n << 2) + 2, x, y + 16); 28} 29 30joypads_t joypads; 31 32// absolute Y coordinates of player 1 & 2 33uint8_t player1, player2; 34uint16_t player1_score, player2_score; 35 36// player constraints 37#define YMIN 28 38#define YMAX 100 39#define PLAYER1_X 16 40#define PLAYER2_X (uint8_t)((20 * 8) - 8) 41 42// coordinates and speeds of ball 43uint8_t ballX, ballY; 44int8_t spd_ballX, spd_ballY; 45 46#define INITBALLX 80 + 4 47#define INITBALLY 64 + 8 48 49const unsigned char HUD[] = " p1: %d p2: %d"; 50 51// main funxction 52void main(void) { 53 // init palettes 54 BGP_REG = OBP0_REG = OBP1_REG = 0xE4; 55 56 // load tile data into VRAM 57 set_sprite_data(0, 4, sprite_data); 58 59 // init pad sprites 60 init_pad(0); 61 init_pad(1); 62 63 // init ball sprite 64 set_sprite_tile(3, 2); 65 66 // show bkg and sprites 67 SHOW_BKG; SHOW_SPRITES; 68 69 // init 2 joypads 70 if (joypad_init(2, &joypads) != 2) { 71 printf(" This program must\n be executed on\n Super GameBoy"); 72 return; 73 } 74 75 // init players 76 player1 = 64, player2 = 64; 77 player1_score = player2_score = 0; 78 79 // draw score 80 printf(HUD, player1_score, player2_score); 81 82 // init ball 83 ballX = INITBALLX, ballY = INITBALLY; 84 spd_ballX = 1, spd_ballY = 1; 85 86 while(1) { 87 // poll joypads 88 joypad_ex(&joypads); 89 90 // player 1 91 if (joypads.joy0 & J_UP) { 92 player1 -= 2; 93 if (player1 < YMIN) player1 = YMIN; 94 } else if (joypads.joy0 & J_DOWN) { 95 player1 += 2; 96 if (player1 > YMAX) player1 = YMAX; 97 } 98 draw_pad(0, PLAYER1_X, player1); 99 100 // player 2 101 if (joypads.joy1 & J_UP) { 102 player2 -= 2; 103 if (player2 < YMIN) player2 = YMIN; 104 } else if (joypads.joy1 & J_DOWN) { 105 player2 += 2; 106 if (player2 > YMAX) player2 = YMAX; 107 } 108 draw_pad(1, PLAYER2_X, player2); 109 110 // move ball 111 ballX += spd_ballX, ballY += spd_ballY; 112 // check bounce from limits 113 if ((ballY < YMIN) || (ballY > (YMAX + 24))) { 114 spd_ballY = -spd_ballY; 115 } 116 // check bounce from bats 117 if (ballX < (PLAYER1_X + 8)) { 118 if ((ballY > player1) && (ballY < (player1 + 24)) && (spd_ballX < 0)) 119 spd_ballX = -spd_ballX; 120 } else if (ballX > (PLAYER2_X - 8)) { 121 if ((ballY > player2) && (ballY < (player2 + 24)) && (spd_ballX > 0)) 122 spd_ballX = -spd_ballX; 123 } 124 // check player1 or 2 wins, update scores, start from center 125 if (ballX < PLAYER1_X) { 126 // player2 wins 127 ballX = INITBALLX, ballY = INITBALLY; 128 spd_ballX = -spd_ballX; 129 player2_score++; 130 gotoxy(0, 0); printf(HUD, player1_score, player2_score); 131 } else if (ballX > PLAYER2_X) { 132 // player1 wins 133 ballX = INITBALLX, ballY = INITBALLY; 134 spd_ballX = -spd_ballX; 135 player1_score++; 136 gotoxy(0, 0); printf(HUD, player1_score, player2_score); 137 } 138 // move ball sprite 139 move_sprite(3, ballX, ballY); 140 141 // wait for VBlank to slow down everything 142 wait_vbl_done(); 143 } 144}