From 8c24c86a49b23086941814e3ae1d58a2993dac7a Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 15 Oct 2020 14:37:46 +0100 Subject: Backports: Colour operations from Snes9x 1.60 + MIPS optimisations from PocketSNES --- source/gfx.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source/gfx.h') diff --git a/source/gfx.h b/source/gfx.h index 582f7c2..096ea98 100644 --- a/source/gfx.h +++ b/source/gfx.h @@ -33,8 +33,11 @@ typedef struct uint32_t Pitch; int32_t Delta; +#if defined(PSP) + /* PSP uses pre-1.60 colour operations */ uint16_t* X2; uint16_t* ZERO_OR_X2; +#endif uint16_t* ZERO; uint32_t RealPitch; /* True pitch of Screen buffer. */ uint32_t Pitch2; /* Same as RealPitch except while using speed up hack for Glide. */ @@ -148,12 +151,31 @@ extern uint8_t mul_brightness [16][32]; static INLINE uint16_t COLOR_ADD(uint16_t C1, uint16_t C2) { +#if defined(PSP) + /* PSP uses pre-1.60 colour operations */ if (C1 == 0) return C2; else if (C2 == 0) return C1; else return GFX.X2[(((C1 & RGB_REMOVE_LOW_BITS_MASK) + (C2 & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + (C1 & C2 & RGB_LOW_BITS_MASK)] | ((C1 ^ C2) & RGB_LOW_BITS_MASK); +#else + const int RED_MASK = 0x1F << RED_SHIFT_BITS; + const int GREEN_MASK = 0x1F << GREEN_SHIFT_BITS; + const int BLUE_MASK = 0x1F; + + int rb = (C1 & (RED_MASK | BLUE_MASK)) + (C2 & (RED_MASK | BLUE_MASK)); + int rbcarry = rb & ((0x20 << RED_SHIFT_BITS) | (0x20 << 0)); + int g = (C1 & (GREEN_MASK)) + (C2 & (GREEN_MASK)); + int rgbsaturate = (((g & (0x20 << GREEN_SHIFT_BITS)) | rbcarry) >> 5) * 0x1f; + uint16_t retval = (rb & (RED_MASK | BLUE_MASK)) | (g & GREEN_MASK) | rgbsaturate; + +#if GREEN_SHIFT_BITS == 6 + retval |= (retval & 0x0400) >> 5; +#endif + + return retval; +#endif } #define COLOR_ADD1_2(C1, C2) \ @@ -161,11 +183,31 @@ static INLINE uint16_t COLOR_ADD(uint16_t C1, uint16_t C2) ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ (((C1) & (C2) & RGB_LOW_BITS_MASK) | ALPHA_BITS_MASK)) +#if defined(PSP) +/* PSP uses pre-1.60 colour operations */ #define COLOR_SUB(C1, C2) \ (GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + \ ((C1) & RGB_LOW_BITS_MASK) - \ ((C2) & RGB_LOW_BITS_MASK)) +#else +static INLINE uint16_t COLOR_SUB(uint16_t C1, uint16_t C2) +{ + int rb1 = (C1 & (THIRD_COLOR_MASK | FIRST_COLOR_MASK)) | ((0x20 << 0) | (0x20 << RED_SHIFT_BITS)); + int rb2 = C2 & (THIRD_COLOR_MASK | FIRST_COLOR_MASK); + int rb = rb1 - rb2; + int rbcarry = rb & ((0x20 << RED_SHIFT_BITS) | (0x20 << 0)); + int g = ((C1 & (SECOND_COLOR_MASK)) | (0x20 << GREEN_SHIFT_BITS)) - (C2 & (SECOND_COLOR_MASK)); + int rgbsaturate = (((g & (0x20 << GREEN_SHIFT_BITS)) | rbcarry) >> 5) * 0x1f; + uint16_t retval = ((rb & (THIRD_COLOR_MASK | FIRST_COLOR_MASK)) | (g & SECOND_COLOR_MASK)) & rgbsaturate; + +#if GREEN_SHIFT_BITS == 6 + retval |= (retval & 0x0400) >> 5; +#endif + + return retval; +} +#endif #define COLOR_SUB1_2(C1, C2) \ GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \ -- cgit v1.2.3