From e6eb0a17dcf50e0ff8ff5843362e96020a6de094 Mon Sep 17 00:00:00 2001 From: lif <> Date: Tue, 2 Jan 2024 03:55:24 -0800 Subject: [PATCH] start fixing swizzle-mode graphics rendering, starting with tilemap pointers and OAM --- video.cc | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/video.cc b/video.cc index 567b200..d1521b8 100644 --- a/video.cc +++ b/video.cc @@ -28,6 +28,26 @@ u32 gba_screen_pitch = GBA_SCREEN_WIDTH; #define get_screen_pixels() gba_screen_pixels #define get_screen_pitch() gba_screen_pitch +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +typedef struct { + u16 attr1, attr0, attr3, attr2; +} t_oam; + +typedef struct { + u16 pad0[2]; + u16 dx; + u16 pad1[3]; + u16 dmx; + u16 pad2[3]; + u16 dy; + u16 pad3[3]; + u16 dmy; + u16 pad4; +} t_affp; + +#else // BIG_ENDIAN + typedef struct { u16 attr0, attr1, attr2, attr3; } t_oam; @@ -43,6 +63,8 @@ typedef struct { u16 dmy; } t_affp; +#endif // BIG_ENDIAN + typedef void (* bitmap_render_function)( u32 start, u32 end, void *dest_ptr, const u16 *pal); typedef void (* tile_render_function)( @@ -285,6 +307,16 @@ static inline void render_tile_Nbpp( } } +inline u16 swizzle_u16ptr(u16 *ptr) { + u16* swizptr = (u16*)((uintptr_t)(ptr) ^ 2); + return *swizptr; +} + +inline u16 swizzle_u16ptr_inc(u16 **pptr) { + u16* swizptr = (u16*)((uintptr_t)(*pptr) ^ 2); + (*pptr)++; + return *swizptr; +} template static void render_scanline_text_fast(u32 layer, @@ -360,7 +392,10 @@ static void render_scanline_text_fast(u32 layer, u32 todraw = MIN(end, partial_hcnt); // [1..7] u32 stop = tile_hoff + todraw; // Usually 8, unless short run. - u16 tile = eswap16(*map_ptr++); +// map_ptr = (u16*)((uintptr_t)(map_ptr) ^ 2); + u16 tile = swizzle_u16ptr_inc(&map_ptr); //eswap16(*map_ptr); +// map_ptr = (u16*)((uintptr_t)(map_ptr) ^ 2); +// map_ptr++; if (tile & 0x400) // Tile horizontal flip rend_part_tile_Nbpp( bg_comb, px_comb, dest_ptr, tile_hoff, stop, tile, tile_base, vflip_off, paltbl); @@ -380,7 +415,7 @@ static void render_scanline_text_fast(u32 layer, u32 todraw = MIN(end, pixel_run) / 8; for (u32 i = 0; i < todraw; i++, dest_ptr += 8) { - u16 tile = eswap16(*map_ptr++); + u16 tile = swizzle_u16ptr_inc(&map_ptr); if (tile & 0x400) // Tile horizontal flip render_tile_Nbpp( bg_comb, px_comb, dest_ptr, tile, tile_base, vflip_off, paltbl); @@ -401,7 +436,7 @@ static void render_scanline_text_fast(u32 layer, todraw = end / 8; for (u32 i = 0; i < todraw; i++, dest_ptr += 8) { - u16 tile = eswap16(*map_ptr++); + u16 tile = swizzle_u16ptr_inc(&map_ptr);//eswap16(*map_ptr++); if (tile & 0x400) // Tile horizontal flip render_tile_Nbpp( bg_comb, px_comb, dest_ptr, tile, tile_base, vflip_off, paltbl); @@ -414,7 +449,7 @@ static void render_scanline_text_fast(u32 layer, // Finalize the tile rendering the left side of it (from 0 up to "end"). if (end) { - u16 tile = eswap16(*map_ptr++); + u16 tile = swizzle_u16ptr_inc(&map_ptr);//eswap16(*map_ptr++); if (tile & 0x400) // Tile horizontal flip rend_part_tile_Nbpp( bg_comb, px_comb, dest_ptr, 0, end, tile, tile_base, vflip_off, paltbl); @@ -488,7 +523,7 @@ static void render_scanline_text_mosaic(u32 layer, // Iterate pixel by pixel, loading data every N pixels to honor mosaic effect u8 pval = 0; for (u32 i = 0; start < end; start++, i++, dest_ptr++) { - u16 tile = eswap16(*map_ptr); + u16 tile = swizzle_u16ptr(map_ptr);//eswap16(*map_ptr); if (!(i % mosh)) { const u8 *tile_ptr = &tile_base[(tile & 0x3FF) * (is8bpp ? 64 : 32)]; @@ -1431,7 +1466,7 @@ void render_scanline_objs( for (objn = objcnt-1; objn >= 0; objn--) { // Objects in the list are pre-filtered and sorted in the appropriate order u32 objoff = objlist[objn]; - const t_oam *oamentry = &((t_oam*)oam_ram)[objoff]; + const t_oam *oamentry = &((t_oam*)oam_ram)[objoff ^ (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)]; u16 obj_attr0 = eswap16(oamentry->attr0); u16 obj_attr1 = eswap16(oamentry->attr1);