fix most(?) rendering issues i have seen so far in swizzled mode. tiles at screen edges are still being drawn backwards

This commit is contained in:
lif 2024-01-03 03:04:44 -08:00
parent e6eb0a17dc
commit 6928b667ae
2 changed files with 40 additions and 25 deletions

View File

@ -1023,9 +1023,9 @@ cpu_alert_type function_cc write_io_register32(u32 address, u32 value)
u32 value_low = value & 0xFFFF; \
address32(palette_ram, palette_address) = eswap32(value); \
value_high = convert_palette(value_high); \
address16(palette_ram_converted, palette_address + 2) = value_high; \
address16(palette_ram_converted, palette_address) = value_high; \
value_low = convert_palette(value_low); \
address16(palette_ram_converted, palette_address) = value_low; \
address16(palette_ram_converted, palette_address + 2) = value_low; \
} \

View File

@ -28,6 +28,7 @@ u32 gba_screen_pitch = GBA_SCREEN_WIDTH;
#define get_screen_pixels() gba_screen_pixels
#define get_screen_pitch() gba_screen_pitch
// swap halfwords in structures
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
typedef struct {
@ -65,6 +66,34 @@ typedef struct {
#endif // BIG_ENDIAN
inline u8 swizzle_u8ptr(u8 *ptr) {
u8* swizptr = (u8*)swizzle_b((uintptr_t)(ptr));
return *swizptr;
}
inline u16 swizzle_u16ptr(u16 *ptr) {
u16* swizptr = (u16*)swizzle_h((uintptr_t)(ptr));
return *swizptr;
}
inline u16 swizzle_u16ptr_inc(u16 **pptr) {
u16* swizptr = (u16*)swizzle_h((uintptr_t)(*pptr));
(*pptr)++;
return *swizptr;
}
template<typename pixfmt> pixfmt swizzle_pixptr(pixfmt *ptr) {
pixfmt* swizptr;
if (sizeof(pixfmt) == 2) {
swizptr = (pixfmt*)swizzle_h((uintptr_t)(ptr));
} else if (sizeof(pixfmt) == 1) {
swizptr = (pixfmt*)swizzle_b((uintptr_t)(ptr));
} else {
swizptr = ptr;
}
return *swizptr;
}
typedef void (* bitmap_render_function)(
u32 start, u32 end, void *dest_ptr, const u16 *pal);
typedef void (* tile_render_function)(
@ -192,7 +221,7 @@ static inline void rend_part_tile_Nbpp(u32 bg_comb, u32 px_comb,
for (u32 i = start; i < end; i++, dest_ptr++) {
// Honor hflip by selecting bytes in the correct order
u32 sel = hflip ? (7-i) : i;
u8 pval = tile_ptr[sel];
u8 pval = tile_ptr[swizzle_b(sel)];
// Alhpa mode stacks previous value (unless rendering the first layer)
if (pval) {
if (rdtype == FULLCOLOR)
@ -307,17 +336,6 @@ 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<typename stype, rendtype rdtype, bool isbase, bool is8bpp>
static void render_scanline_text_fast(u32 layer,
u32 start, u32 end, void *scanline, const u16 * paltbl)
@ -392,10 +410,7 @@ 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.
// 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<stype, rdtype, is8bpp, isbase, true>(
bg_comb, px_comb, dest_ptr, tile_hoff, stop, tile, tile_base, vflip_off, paltbl);
@ -621,9 +636,9 @@ static inline u8 lookup_pix_8bpp(
// Given coords (px,py) in the background space, find the tile.
u32 mapoff = (px / 8) + ((py / 8) << map_pitch);
// Each tile is 8x8, so 64 bytes each.
const u8 *tile_ptr = &tile_base[map_base[mapoff] * tile_size_8bpp];
const u8 *tile_ptr = &tile_base[map_base[swizzle_b(mapoff)] * tile_size_8bpp];
// Read the 8bit color within the tile.
return tile_ptr[(px % 8) + ((py % 8) * 8)];
return tile_ptr[swizzle_b((px % 8) + ((py % 8) * 8))];
}
@ -918,7 +933,7 @@ static inline void render_scanline_bitmap(
for (u32 i = 0; pixcnt; i++, pixcnt--, valptr++) {
// Pretty much pixel copier
if (!mosaic || !(i % mosh))
val = sizeof(pixfmt) == 2 ? eswap16(*valptr) : *valptr;
val = swizzle_pixptr(valptr);
bitmap_pixel_write<rdtype, dsttype, mode, pixfmt>(dst_ptr++, val, palptr, px_attr);
}
}
@ -945,7 +960,7 @@ static inline void render_scanline_bitmap(
if (!mosaic || !(i % mosh)) {
pixfmt *valptr = &src_ptr[pixel_x + (pixel_y * width)];
val = sizeof(pixfmt) == 2 ? eswap16(*valptr) : *valptr;
val = swizzle_pixptr(valptr);
}
bitmap_pixel_write<rdtype, dsttype, mode, pixfmt>(dst_ptr++, val, palptr, px_attr);
@ -973,7 +988,7 @@ static inline void render_scanline_bitmap(
// Lookup pixel and draw it.
if (!mosaic || !(i % mosh)) {
pixfmt *valptr = &src_ptr[pixel_x + (pixel_y * width)];
val = sizeof(pixfmt) == 2 ? eswap16(*valptr) : *valptr;
val = swizzle_pixptr(valptr);
}
bitmap_pixel_write<rdtype, dsttype, mode, pixfmt>(dst_ptr++, val, palptr, px_attr);
@ -1324,7 +1339,7 @@ static void render_affine_object(
((pixel_y & 0x7) * tile_bwidth) + // Skip vertical rows to the pixel
(pixel_x & 0x7); // Skip the horizontal offset
pixval = vram[0x10000 + (tile_off & 0x7FFF)]; // Read pixel value!
pixval = vram[swizzle_b(0x10000 + (tile_off & 0x7FFF))]; // Read pixel value!
} else {
const u32 tile_off =
base_tile + // Character base
@ -1333,7 +1348,7 @@ static void render_affine_object(
((pixel_y & 0x7) * tile_bwidth) + // Skip vertical rows to the pixel
((pixel_x >> 1) & 0x3); // Skip the horizontal offset
u8 pixpair = vram[0x10000 + (tile_off & 0x7FFF)]; // Read 2 pixels @4bpp
u8 pixpair = vram[swizzle_b(0x10000 + (tile_off & 0x7FFF))]; // Read 2 pixels @4bpp
pixval = ((pixel_x & 1) ? pixpair >> 4 : pixpair & 0xF);
}
}
@ -1466,7 +1481,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 ^ (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)];
const t_oam *oamentry = &((t_oam*)oam_ram)[objoff];
u16 obj_attr0 = eswap16(oamentry->attr0);
u16 obj_attr1 = eswap16(oamentry->attr1);