git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-lib/examples/gb/sgb_pong/sgb_pong.c

      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 
      8 uint8_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
     17 void 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()
     24 inline 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 
     30 joypads_t joypads;
     31 
     32 // absolute Y coordinates of player 1 & 2
     33 uint8_t player1, player2;
     34 uint16_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
     43 uint8_t ballX, ballY;
     44 int8_t spd_ballX, spd_ballY;
     45 
     46 #define INITBALLX 80 + 4 
     47 #define INITBALLY 64 + 8
     48 
     49 const unsigned char HUD[] = " p1: %d   p2: %d";
     50 
     51 // main funxction
     52 void 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     // Wait 4 frames
     70     // For SGB on PAL SNES this delay is required on startup, otherwise borders don't show up
     71     for (uint8_t i = 4; i != 0; i--) vsync();
     72 
     73     // init 2 joypads
     74     if (joypad_init(2, &joypads) != 2) {
     75         printf(" This program must\n  be executed  on\n   Super GameBoy");
     76         return;
     77     }
     78  
     79     // init players
     80     player1 = 64, player2 = 64;
     81     player1_score = player2_score = 0;
     82     
     83     // draw score
     84     printf(HUD, player1_score, player2_score);
     85     
     86     // init ball
     87     ballX = INITBALLX, ballY = INITBALLY;
     88     spd_ballX = 1, spd_ballY = 1;
     89     
     90     while(1) {
     91         // poll joypads
     92         joypad_ex(&joypads);
     93         
     94         // player 1
     95         if (joypads.joy0 & J_UP) {
     96             player1 -= 2;
     97             if (player1 < YMIN) player1 = YMIN;
     98         } else if (joypads.joy0 & J_DOWN) {
     99             player1 += 2;
    100             if (player1 > YMAX) player1 = YMAX;            
    101         }
    102         draw_pad(0, PLAYER1_X, player1);
    103         
    104         // player 2
    105         if (joypads.joy1 & J_UP) {
    106             player2 -= 2;
    107             if (player2 < YMIN) player2 = YMIN;
    108         } else if (joypads.joy1 & J_DOWN) {
    109             player2 += 2;
    110             if (player2 > YMAX) player2 = YMAX;            
    111         }
    112         draw_pad(1, PLAYER2_X, player2);
    113 
    114         // move ball
    115         ballX += spd_ballX, ballY += spd_ballY;
    116         // check bounce from limits
    117         if ((ballY < YMIN) || (ballY > (YMAX + 24))) {
    118             spd_ballY = -spd_ballY; 
    119         }
    120         // check bounce from bats
    121         if (ballX < (PLAYER1_X + 8)) {
    122             if ((ballY > player1) && (ballY < (player1 + 24)) && (spd_ballX < 0)) 
    123                 spd_ballX = -spd_ballX;
    124         } else if (ballX > (PLAYER2_X - 8)) {
    125             if ((ballY > player2) && (ballY < (player2 + 24)) && (spd_ballX > 0)) 
    126                 spd_ballX = -spd_ballX;
    127         }
    128         // check player1 or 2 wins, update scores, start from center
    129         if (ballX < PLAYER1_X) {
    130             // player2 wins
    131             ballX = INITBALLX, ballY = INITBALLY;
    132             spd_ballX = -spd_ballX;
    133             player2_score++;
    134             gotoxy(0, 0); printf(HUD, player1_score, player2_score);
    135         } else if (ballX > PLAYER2_X) {
    136             // player1 wins
    137             ballX = INITBALLX, ballY = INITBALLY;
    138             spd_ballX = -spd_ballX;
    139             player1_score++;
    140             gotoxy(0, 0); printf(HUD, player1_score, player2_score);
    141         }
    142         // move ball sprite
    143         move_sprite(3, ballX, ballY);
    144 
    145         // wait for VBlank to slow down everything
    146         vsync();
    147     }
    148 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.