cscg22-gearboy

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

metasprites.c (4600B)


      1#include <stdint.h>
      2
      3#include <gbdk/platform.h>
      4#include <gbdk/metasprites.h>
      5
      6#include "sprite.h"
      7
      8const unsigned char pattern[] = {0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x01,0x01};
      9
     10joypads_t joypads;
     11
     12#define ACC_X 1
     13#define ACC_Y 2
     14
     15// The metasprite will be built starting with hardware sprite zero (the first)
     16#define SPR_NUM_START 0
     17
     18// Metasprite tiles are loaded into VRAM starting at tile number 0 
     19#define TILE_NUM_START 0
     20
     21// sprite coords
     22uint16_t PosX, PosY;
     23int16_t SpdX, SpdY;
     24uint8_t PosF;
     25uint8_t hide, jitter;
     26uint8_t idx, rot;
     27
     28// main funxction
     29void main(void) {
     30    // init palettes
     31    BGP_REG = OBP0_REG = 0xE4;
     32    OBP1_REG = 0xE0;
     33
     34	// Fill the screen background with a single tile pattern
     35    fill_bkg_rect(0, 0, 20, 18, 0);
     36    set_bkg_data(0, 1, pattern);
     37
     38    // Load metasprite tile data into VRAM
     39    set_sprite_data(TILE_NUM_START, sizeof(sprite_tiles) >> 4, sprite_tiles);
     40
     41    // show bkg and sprites
     42    SHOW_BKG; SHOW_SPRITES;
     43
     44	// Check what size hardware sprite the metasprite is using (from sprite.h)
     45	#if sprite_TILE_H == 16
     46		SPRITES_8x16;
     47	#else
     48		SPRITES_8x8;
     49	#endif
     50
     51    // init 1 joypad
     52    joypad_init(1, &joypads);
     53 
     54    // Set initial position, zero out speed
     55    PosX = PosY = 64 << 4;
     56    SpdX = SpdY = 0;
     57
     58    hide = 0; jitter = 0; idx = 0; rot = 0;
     59
     60    while(1) {        
     61        // poll joypads
     62        joypad_ex(&joypads);
     63        
     64        PosF = 0;
     65        // game object
     66        if (joypads.joy0 & J_UP) {
     67            SpdY -= 2;
     68            if (SpdY < -32) SpdY = -32;
     69            PosF |= ACC_Y;
     70        } else if (joypads.joy0 & J_DOWN) {
     71            SpdY += 2;
     72            if (SpdY > 32) SpdY = 32;
     73            PosF |= ACC_Y;
     74        }
     75
     76        if (joypads.joy0 & J_LEFT) {
     77            SpdX -= 2;
     78            if (SpdX < -32) SpdX = -32;
     79            PosF |= ACC_X;
     80        } else if (joypads.joy0 & J_RIGHT) {
     81            SpdX += 2;
     82            if (SpdX > 32) SpdX = 32;
     83            PosF |= ACC_X;
     84        }
     85
     86
     87        // Press A button to show/hide metasprite
     88        if ((joypads.joy0 & J_A) && (!jitter)) {
     89            hide = (!hide);
     90            jitter = 20;
     91        }
     92
     93        // Press B button to cycle through metasprite animations
     94        if ((joypads.joy0 & J_B) && (!jitter) && (!hide)) {
     95            idx++; if (idx >= (sizeof(sprite_metasprites) >> 1)) idx = 0;
     96            jitter = 10;
     97        }
     98
     99        // Press SELECT button to cycle metasprite through Normal/Flip-Y/Flip-XY/Flip-X
    100        if ((joypads.joy0 & J_SELECT) && (!jitter) && (!hide)) {
    101            rot++; rot &= 3;
    102            jitter = 20;
    103        }
    104
    105        // Hide/Animate/Flip input throttling
    106        if (jitter) jitter--;
    107
    108        PosX += SpdX, PosY += SpdY; 
    109
    110        uint8_t hiwater = 0;
    111	
    112		// NOTE: In a real game it would be better to only call the move_metasprite..()
    113        //       functions if something changed (such as movement or rotation). That
    114		//	     reduces CPU usage on frames that don't need updates.
    115		//
    116		// In this example they are called every frame to simplify the example code
    117
    118        // Hide the metasprite or move it & apply any rotation settings
    119        if (hide)
    120            hide_metasprite(sprite_metasprites[idx], SPR_NUM_START);
    121        else
    122            switch (rot) {
    123                case 0: hiwater = move_metasprite       (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break;
    124                case 1: hiwater = move_metasprite_hflip (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break;
    125                case 2: hiwater = move_metasprite_hvflip(sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break;
    126                case 3: hiwater = move_metasprite_vflip (sprite_metasprites[idx], TILE_NUM_START, SPR_NUM_START, (PosX >> 4), (PosY >> 4)); break;
    127            };
    128
    129        // Hide rest of the hardware sprites, because amount of sprites differ between animation frames.
    130	hide_sprites_range(hiwater, 40);        
    131
    132        // Y Axis: update velocity (reduce speed) if no U/D button pressed
    133        if (!(PosF & ACC_Y)) {
    134            if (SpdY != 0) {
    135                if (SpdY > 0) SpdY--;
    136                else SpdY ++;
    137            }
    138        }
    139
    140        // X Axis: update velocity (reduce speed) if no L/R button pressed
    141        if (!(PosF & ACC_X)) {
    142            if (SpdX != 0) {
    143                if (SpdX > 0) SpdX--;
    144                else SpdX ++;
    145            }
    146        }
    147
    148
    149        // wait for VBlank to slow down everything and reduce cpu use when idle
    150        wait_vbl_done();
    151    }
    152}
    153