cscg22-gearboy

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

main.c (2837B)


      1#include <gbdk/platform.h>
      2#include <gbdk/incbin.h>
      3#include <stdbool.h>
      4
      5#include <gbdk/rledecompress.h>
      6
      7// The Tile data is not compressed
      8INCBIN(map_tiles, "res/map_tiles.bin")
      9INCBIN_EXTERN(map_tiles)
     10
     11// The Map data is compressed using: gbcompress --alg=rle
     12// The map is ordered in sequential columns 18 tiles high
     13// so it's easy to load one entire screen column worth at a time.
     14#define MAP_DATA_HEIGHT 18
     15INCBIN(map_compressed, "res/map.bin.rle")
     16INCBIN_EXTERN(map_compressed)
     17
     18uint8_t data[32][MAP_DATA_HEIGHT];  // Collision map buffer
     19uint8_t scrollpos = 0;              // Scroll position in pixels
     20uint8_t datapos = 0;                // x position in tiles inside the collision map
     21
     22void main() {
     23
     24    SHOW_BKG;
     25
     26    // Load Tile data
     27    set_bkg_data(0, INCBIN_SIZE(map_tiles) >> 4, map_tiles);
     28
     29    // Initialize decompressor with Map data
     30    rle_init(map_compressed);
     31
     32    // To get started, decompress and display a whole screen worth,
     33    // + 1 additional column in the direction being scrolled (to
     34    // avoid screen tearing from drawing a column right as it scrolls into view)
     35    uint8_t * data_ptr = &data[0][0];
     36    for (uint8_t i = 0; (rle_decompress(data_ptr, MAP_DATA_HEIGHT)) && (i != DEVICE_SCREEN_WIDTH + 1); i++) {
     37        // pre-process column here
     38        // ...
     39
     40        // Draw current column starting at row 0
     41        set_bkg_tiles(i, 0, 1, MAP_DATA_HEIGHT, data_ptr);
     42    }
     43
     44    // main game loop
     45    datapos = scrollpos = 0;
     46    while(TRUE) {
     47
     48        wait_vbl_done();
     49
     50        // Scroll one pixel to the right
     51        // (This should be done as close to wait_vbl_done and before
     52        // the map drawing below to avoid tearing at the top of the screen)
     53        scrollpos++;
     54        move_bkg(scrollpos, 0);
     55
     56        // Once for every 8 pixels scrolled: draw a
     57        // new column of tiles on the right-most edge
     58        // ( == 1 is used here so it triggers on the very first pass)
     59        if ((scrollpos & 0x07u) == 1) {
     60
     61            // Get hardware map tile X column from scroll position / 8
     62            // Then + 1 since there's a 1 tile column buffer on the right edge
     63            datapos = (scrollpos >> 3) + 1;
     64            uint8_t map_x_column = (datapos + DEVICE_SCREEN_WIDTH) & 31;
     65
     66            // Decompress a column worth of data
     67            data_ptr = &data[map_x_column][0];
     68            // If the end of compressed data is reached, reset decompression
     69            // and resume at the start (to make infinite scrolling)
     70            if (!rle_decompress(data_ptr, MAP_DATA_HEIGHT)) {
     71                rle_init(map_compressed);
     72                rle_decompress(data_ptr, MAP_DATA_HEIGHT);
     73            }
     74            // pre-process column here
     75            // ...
     76
     77            // Display column
     78            set_bkg_tiles(map_x_column, 0, 1, MAP_DATA_HEIGHT, data_ptr);
     79        }
     80    }
     81}