Add support for native XBGR1555 format

This is the format used by PS2.
This requires fixing the palette conversion routines (and palette writes
in the MIPS dynarec) but also adding support for 555 mode blending
(currently only 565 modes are supported, regardless of whether they are
RGB or BGR).
This commit is contained in:
David Guillen Fandos 2021-07-07 00:51:29 +02:00
parent 3790b233f1
commit aded681de2
3 changed files with 46 additions and 15 deletions

View file

@ -78,6 +78,9 @@
#ifdef USE_BGR_FORMAT
#define convert_palette(value) \
value = ((value & 0x7FE0) << 1) | (value & 0x1F)
#elif defined(USE_XBGR1555_FORMAT)
#define convert_palette(value) \
value = (value & 0x7FFF)
#else
#define convert_palette(value) \
value = ((value & 0x1F) << 11) | ((value & 0x03E0) << 1) | (value >> 10)

View file

@ -2635,7 +2635,6 @@ u8 swi_hle_handle[256] =
extern u32 tmemld[11][16];
extern u32 tmemst[ 4][16];
extern u32 thnjal[15*16];
void mips_lookup_pc();
void smc_write();
cpu_alert_type write_io_register8 (u32 address, u32 value);
cpu_alert_type write_io_register16(u32 address, u32 value);
@ -2977,6 +2976,10 @@ static void emit_pmemst_stub(
mips_emit_sll(reg_temp, reg_a1, 1); \
mips_emit_andi(reg_temp, reg_temp, 0xFFC0); \
mips_emit_ins(reg_temp, reg_a1, 0, 5);
#elif defined(USE_XBGR1555_FORMAT)
/* PS2's native format */
#define palette_convert() \
mips_emit_andi(reg_temp, reg_temp, 0x7FFF);
#else
/* 0BGR to RGB565 (clobbers a0) */
#ifdef MIPS_HAS_R2_INSTS

53
video.c
View file

@ -3473,11 +3473,36 @@ fill_line_builder(color16);
fill_line_builder(color32);
// Blending is performed by separating an RGB value into 0G0R0B (32 bit)
// Since blending factors are at most 16, mult/add operations do not overflow
// to the neighbouring color and can be performed much faster than separatedly
// Here follow the mask value to separate/expand the color to 32 bit,
// the mask to detect overflows in the blend operation and
#define BLND_MSK (SATR_MSK | SATG_MSK | SATB_MSK)
#ifdef USE_XBGR1555_FORMAT
#define OVFG_MSK 0x04000000
#define OVFR_MSK 0x00008000
#define OVFB_MSK 0x00000020
#define SATG_MSK 0x03E00000
#define SATR_MSK 0x00007C00
#define SATB_MSK 0x0000001F
#else
#define OVFG_MSK 0x08000000
#define OVFR_MSK 0x00010000
#define OVFB_MSK 0x00000020
#define SATG_MSK 0x07E00000
#define SATR_MSK 0x0000F800
#define SATB_MSK 0x0000001F
#endif
// Alpha blend two pixels (pixel_top and pixel_bottom).
#define blend_pixel() \
pixel_bottom = palette_ram_converted[(pixel_pair >> 16) & 0x1FF]; \
pixel_bottom = (pixel_bottom | (pixel_bottom << 16)) & 0x07E0F81F; \
pixel_bottom = (pixel_bottom | (pixel_bottom << 16)) & BLND_MSK; \
pixel_top = ((pixel_top * blend_a) + (pixel_bottom * blend_b)) >> 4 \
@ -3486,18 +3511,18 @@ fill_line_builder(color32);
#define blend_saturate_pixel() \
pixel_bottom = palette_ram_converted[(pixel_pair >> 16) & 0x1FF]; \
pixel_bottom = (pixel_bottom | (pixel_bottom << 16)) & 0x07E0F81F; \
pixel_bottom = (pixel_bottom | (pixel_bottom << 16)) & BLND_MSK; \
pixel_top = ((pixel_top * blend_a) + (pixel_bottom * blend_b)) >> 4; \
if(pixel_top & 0x08010020) \
if(pixel_top & (OVFR_MSK | OVFG_MSK | OVFB_MSK)) \
{ \
if(pixel_top & 0x08000000) \
pixel_top |= 0x07E00000; \
if(pixel_top & OVFG_MSK) \
pixel_top |= SATG_MSK; \
\
if(pixel_top & 0x00010000) \
pixel_top |= 0x0000F800; \
if(pixel_top & OVFR_MSK) \
pixel_top |= SATR_MSK; \
\
if(pixel_top & 0x00000020) \
pixel_top |= 0x0000001F; \
if(pixel_top & OVFB_MSK) \
pixel_top |= SATB_MSK; \
} \
#define brighten_pixel() \
@ -3513,9 +3538,9 @@ fill_line_builder(color32);
((pixel_source & 0x00000200) == 0x00000200) \
#define expand_pixel_no_dest(expand_type, pixel_source) \
pixel_top = (pixel_top | (pixel_top << 16)) & 0x07E0F81F; \
pixel_top = (pixel_top | (pixel_top << 16)) & BLND_MSK; \
expand_type##_pixel(); \
pixel_top &= 0x07E0F81F; \
pixel_top &= BLND_MSK; \
pixel_top = (pixel_top >> 16) | pixel_top \
#define expand_pixel(expand_type, pixel_source) \
@ -3659,7 +3684,7 @@ static void expand_brighten(u16 *screen_src_ptr, u16 *screen_dest_ptr,
if(blend > 16)
blend = 16;
upper = ((0x07E0F81F * blend) >> 4) & 0x07E0F81F;
upper = ((BLND_MSK * blend) >> 4) & BLND_MSK;
blend = 16 - blend;
expand_loop(brighten, effect_condition_fade(pixel_top), pixel_top);
@ -3709,7 +3734,7 @@ static void expand_brighten_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_
if(blend > 16)
blend = 16;
upper = ((0x07E0F81F * blend) >> 4) & 0x07E0F81F;
upper = ((BLND_MSK * blend) >> 4) & BLND_MSK;
blend = 16 - blend;
if(blend_a > 16)
@ -3899,7 +3924,7 @@ static void expand_brighten_partial_alpha(u32 *screen_src_ptr, u16 *screen_dest_
if(blend > 16) \
blend = 16; \
\
upper = ((0x07E0F81F * blend) >> 4) & 0x07E0F81F; \
upper = ((BLND_MSK * blend) >> 4) & BLND_MSK; \
blend = 16 - blend; \
\
expand_pixel_no_dest(brighten, pixel_top); \