cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

pong.c (4236B)


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