cscg22-gearboy

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

sgb_border.c (2226B)


      1#include "sgb_border.h"
      2
      3#include <gb/gb.h>
      4#include <stdint.h>
      5#include <gb/sgb.h>
      6#include <string.h>
      7
      8#define SGB_CHR_BLOCK0 0
      9#define SGB_CHR_BLOCK1 1
     10
     11#define SGB_SCR_FREEZE 1
     12#define SGB_SCR_UNFREEZE 0
     13
     14#define SGB_TRANSFER(A,B) map_buf[0]=(A),map_buf[1]=(B),sgb_transfer(map_buf) 
     15
     16void set_sgb_border(unsigned char * tiledata, size_t tiledata_size,
     17                    unsigned char * tilemap, size_t tilemap_size,
     18                    unsigned char * palette, size_t palette_size) {
     19    if (sgb_check()) {
     20        unsigned char map_buf[20];
     21        memset(map_buf, 0, sizeof(map_buf));
     22
     23        SGB_TRANSFER((SGB_MASK_EN << 3) | 1, SGB_SCR_FREEZE); 
     24
     25        BGP_REG = OBP0_REG = OBP1_REG = 0xE4U;
     26        SCX_REG = SCY_REG = 0U;
     27
     28        uint8_t tmp_lcdc = LCDC_REG;
     29
     30        HIDE_SPRITES, HIDE_WIN, SHOW_BKG;
     31        DISPLAY_ON;
     32        // prepare tilemap for SGB_BORDER_CHR_TRN (should display all 256 tiles)
     33        uint8_t i = 0U;
     34        for (uint8_t y = 0; y != 14U; ++y) {
     35            uint8_t * dout = map_buf;
     36            for (uint8_t x = 0U; x != 20U; ++x) {
     37                *dout++ = i++;
     38            }
     39            set_bkg_tiles(0, y, 20, 1, map_buf);
     40        }
     41        memset(map_buf, 0, sizeof(map_buf));
     42
     43        // transfer tile data
     44        uint8_t ntiles = (tiledata_size > 256 * 32) ? 0 : tiledata_size >> 5;
     45        if ((!ntiles) || (ntiles > 128U)) { 
     46            set_bkg_data(0, 0, tiledata); 
     47            SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK0);
     48            if (ntiles) ntiles -= 128U; 
     49            tiledata += (128 * 32);
     50            set_bkg_data(0, ntiles << 1, tiledata); 
     51            SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK1);
     52        } else { 
     53            set_bkg_data(0, ntiles << 1, tiledata); 
     54            SGB_TRANSFER((SGB_CHR_TRN << 3) | 1, SGB_CHR_BLOCK0);
     55        }
     56
     57        // transfer map and palettes
     58        set_bkg_data(0, (uint8_t)(tilemap_size >> 4), tilemap);
     59        set_bkg_data(128, (uint8_t)(palette_size >> 4), palette);
     60        SGB_TRANSFER((SGB_PCT_TRN << 3) | 1, 0);
     61
     62        LCDC_REG = tmp_lcdc;
     63
     64        // clear SCREEN
     65        fill_bkg_rect(0, 0, 20, 18, 0);
     66        
     67        SGB_TRANSFER((SGB_MASK_EN << 3) | 1, SGB_SCR_UNFREEZE); 
     68    }
     69}