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}