From 4e51d019fd0c1d21aa8e965fd68dbacec39a2576 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 26 Apr 2021 12:14:45 +0200 Subject: Test screenblock entry demo --- src/common.h | 23 ++++++++++++++++++---- src/main.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- src/sprites.h | 1 + 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/src/common.h b/src/common.h index 35b4619..6047e5f 100644 --- a/src/common.h +++ b/src/common.h @@ -76,6 +76,20 @@ #define BG_V_SCROLL_2 *((vu16*)(0x04000012 + 0x0004 * 2)) #define BG_V_SCROLL_3 *((vu16*)(0x04000012 + 0x0004 * 3)) +// Screenblocks for BGs. +typedef u16 ScreenBlock[1024]; +#define SCREENBLOCK_MEM ((ScreenBlock*)MEM_VRAM) + +// Screenblock entry bits. +#define SCREENBLOCK_ENTRY_H_FLIP (1 << 0xA) +#define SCREENBLOCK_ENTRY_V_FLIP (1 << 0xB) +#define SCREENBLOCK_ENTRY_PAL(N) ((N) << 0xC) + +size_t se_index(size_t tile_x, size_t tile_y, size_t map_width) { + size_t sbb = ((tile_x >> 5) + (tile_y >> 5) * (map_width >> 5)); + return sbb * 1024 + ((tile_x & 31) + (tile_y & 31) * 32); +} + // Screen settings. #define SCREEN_WIDTH 240 #define SCREEN_HEIGHT 160 @@ -84,6 +98,9 @@ // (RGB) have a 0--31 range. For example, pure red would be rgb15(31, 0, 0). typedef u16 Color; +// A palette is composed of 16 colors, with color at index 0 being transparent. +typedef Color Palette[16]; + // // Tile memory access. // @@ -96,9 +113,6 @@ typedef struct Tile { typedef Tile TileBlock[512]; #define TILE_MEM ((TileBlock*) MEM_VRAM) -typedef u16 ScreenBlock[1024]; -#define SCREENBLOCK_MEM ((ScreenBlock*)MEM_VRAM) - // We can treat the screen as a HxW matrix. With the following macro we can // write a pixel to the screen at the (x, y) position using: // @@ -109,6 +123,8 @@ typedef Color Scanline[SCREEN_WIDTH]; #define SCREEN_BUFFER ((u16*) MEM_VRAM) #define PAL_BUFFER_BG ((u16*) MEM_PAL) #define PAL_BUFFER_SPRITES ((u16*) 0x05000200) +#define PAL_BANK_BG ((Palette*) MEM_PAL) +#define PAL_BANK_SPRITES ((Palette*) 0x05000200) // // Colors. @@ -277,5 +293,4 @@ key_hold(u32 key) { // Check if the given key/button is currently pressed. #define KEY_PRESSED(key) (~(KEY_INPUTS) & key) - #endif // GBAEXP_COMMON_H diff --git a/src/main.c b/src/main.c index b8f2334..793baa8 100644 --- a/src/main.c +++ b/src/main.c @@ -10,23 +10,58 @@ // // TODO: Cleanup OBJ/OAM memory copying and access. +// +#define CBB_0 0 +#define SBB_0 28 -int main(void) { - // Load background palette. - memcpy(&PAL_BUFFER_BG[0], &bg_palette, 512); - memcpy(&TILE_MEM[0][0], bg_data, 3168); - memcpy(&SCREENBLOCK_MEM[30][0], bg_map, 2048); - - // Configure BG0 to use 4bpp, 64x32 tile map in charblock 0 and screenblock - // 31. - BG_CTRL_0 = BG_CHARBLOCK(0) | BG_SCREENBLOCK(30) | BG_SIZE(0); +#define CROSS_TX 15 +#define CROSS_TY 10 + +u16 *bg0_map = SCREENBLOCK_MEM[SBB_0]; + +void +init_map() { + // initialize a background + BG_CTRL_0 = BG_CHARBLOCK(CBB_0) | BG_SCREENBLOCK(SBB_0) | BG_SIZE(3); BG_H_SCROLL_0 = 0; BG_V_SCROLL_0 = 0; + // (1) create the tiles: basic tile and a cross + const Tile tiles[2] = { + {{0x11111111, 0x01111111, 0x01111111, 0x01111111, + 0x01111111, 0x01111111, 0x01111111, 0x00000001}}, + {{0x00000000, 0x00100100, 0x01100110, 0x00011000, + 0x00011000, 0x01100110, 0x00100100, 0x00000000}}, + }; + TILE_MEM[CBB_0][0] = tiles[0]; + TILE_MEM[CBB_0][1] = tiles[1]; + + // (2) create a palette + PAL_BANK_BG[0][1] = rgb15(31, 0, 0); + PAL_BANK_BG[1][1] = rgb15( 0, 31, 0); + PAL_BANK_BG[2][1] = rgb15( 0, 0, 31); + PAL_BANK_BG[3][1] = rgb15(16, 16, 16); + + // (3) Create a map: four contingent blocks of + // 0x0000, 0x1000, 0x2000, 0x3000. + u16 *pse = bg0_map; + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 32 * 32; j++) { + *pse++ = SCREENBLOCK_ENTRY_PAL(i) | 0; + } + } +} + +int main(void) { + init_map(); // Configure the display in mode 0 to show OBJs, where tile memory is // sequential. DISP_CTRL = DISP_ENABLE_SPRITES | DISP_MODE_0 | DISP_BG_0; + u32 tx, ty, se_curr, se_prev= CROSS_TY * 32 + CROSS_TX; + + bg0_map[se_prev]++; // initial position of cross + // Initialize sprite button overlay. init_sprite_pal(0, COLOR_WHITE); init_sprites(0); @@ -51,6 +86,15 @@ int main(void) { if (key_hold(KEY_RIGHT)) { x += 3; } + tx = ((x >> 3) + CROSS_TX) & 0x3F; + ty = ((y >> 3) + CROSS_TY) & 0x3F; + + se_curr = se_index(tx, ty, 64); + if(se_curr != se_prev) { + bg0_map[se_prev]--; + bg0_map[se_curr]++; + se_prev= se_curr; + } frame_counter++; BG_H_SCROLL_0 = x; diff --git a/src/sprites.h b/src/sprites.h index e7439f1..e249e95 100644 --- a/src/sprites.h +++ b/src/sprites.h @@ -95,4 +95,5 @@ init_sprite_pal(size_t starting_index, Color col) { } } + #endif // GBAEXP_SPRITES_H -- cgit v1.2.1