From aac31071fe29122c2a118c8ee50c7fca4e76a4f7 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Mon, 19 Oct 2020 16:07:23 +0100 Subject: Backport colour operations from Snes9x 1.60 --- Makefile | 10 ++-- Makefile.common | 4 ++ src/gfx.c | 9 ++++ src/gfx.h | 45 +++++++++++++++++ src/gfx16.c | 11 ++++- src/pixform.h | 146 +++++++++++--------------------------------------------- 6 files changed, 100 insertions(+), 125 deletions(-) diff --git a/Makefile b/Makefile index 97f340e..57ed00f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -DEBUG=0 -LAGFIX=1 +DEBUG = 0 +LAGFIX = 1 +USE_OLD_COLOUR_OPS = 0 TARGET_NAME = snes9x2002 ifeq ($(platform),) @@ -219,10 +220,9 @@ else ifeq ($(platform), gcw0) AR = /opt/gcw0-toolchain/usr/bin/mipsel-linux-ar fpic := -fPIC SHARED := -shared -Wl,--version-script=libretro/link.T -Wl,--no-undefined - DEFINES += -DFRAME_SKIP - CFLAGS += -std=c99 -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float + CFLAGS += -std=c99 -fomit-frame-pointer -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float CFLAGS += -fno-builtin -fno-exceptions - CFLAGS += -DPATH_MAX=256 + CFLAGS += -DPATH_MAX=256 -DFAST_LSB_WORD_ACCESS # Windows MSVC 2010 x86 else ifeq ($(platform), windows_msvc2010_x86) diff --git a/Makefile.common b/Makefile.common index b7078e2..5bde095 100644 --- a/Makefile.common +++ b/Makefile.common @@ -124,4 +124,8 @@ DEFINES += -DLAGFIX endif endif +ifeq ($(USE_OLD_COLOUR_OPS),1) + FLAGS += -DUSE_OLD_COLOUR_OPS +endif + COMMON_DEFINES += $(CODE_DEFINES) $(WARNINGS_DEFINES) $(fpic) diff --git a/src/gfx.c b/src/gfx.c index 3842d1d..fa12da8 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -362,6 +362,8 @@ bool8_32 S9xGraphicsInit(void) DrawHiResClippedTilePtr = DrawHiResClippedTile16; S9xFixColourBrightness(); +#if defined(USE_OLD_COLOUR_OPS) + /* Pre-1.60 colour operations */ if (!(GFX.X2 = (uint16*) malloc(sizeof(uint16) * 0x10000))) return (FALSE); @@ -476,6 +478,10 @@ bool8_32 S9xGraphicsInit(void) } } #endif +#else + if (!(GFX.ZERO = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000))) + return false; +#endif // Build a lookup table that if the top bit of the color value is zero // then the value is zero, otherwise its just the value. @@ -514,6 +520,8 @@ bool8_32 S9xGraphicsInit(void) void S9xGraphicsDeinit(void) { // Free any memory allocated in S9xGraphicsInit +#if defined(USE_OLD_COLOUR_OPS) + /* Pre-1.60 colour operations */ if (GFX.X2) { free((char*) GFX.X2); @@ -524,6 +532,7 @@ void S9xGraphicsDeinit(void) free((char*) GFX.ZERO_OR_X2); GFX.ZERO_OR_X2 = NULL; } +#endif if (GFX.ZERO) { free((char*) GFX.ZERO); diff --git a/src/gfx.h b/src/gfx.h index f873531..362da1d 100644 --- a/src/gfx.h +++ b/src/gfx.h @@ -64,8 +64,11 @@ typedef struct // Setup in call to S9xGraphicsInit() int Delta; +#if defined(USE_OLD_COLOUR_OPS) + /* Pre-1.60 colour operations */ uint16* X2; uint16* ZERO_OR_X2; +#endif uint16* ZERO; uint8* S; uint8* DB; @@ -202,6 +205,8 @@ extern uint8 mul_brightness [16][32]; #define SUB_SCREEN_DEPTH 0 #define MAIN_SCREEN_DEPTH 32 +#if defined(USE_OLD_COLOUR_OPS) +/* Pre-1.60 colour operations */ #if defined(OLD_COLOUR_BLENDING) #define COLOR_ADD(C1, C2) \ GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ @@ -214,12 +219,34 @@ GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ ((C1) & (C2) & RGB_LOW_BITS_MASK)] | \ (((C1) ^ (C2)) & RGB_LOW_BITS_MASK)) #endif +#else +static INLINE uint16_t COLOR_ADD(uint16_t C1, uint16_t C2) +{ + 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) \ (((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ ((C1) & (C2) & RGB_LOW_BITS_MASK) | ALPHA_BITS_MASK) +#if defined(USE_OLD_COLOUR_OPS) +/* Pre-1.60 colour operations */ #if defined(OLD_COLOUR_BLENDING) #define COLOR_SUB(C1, C2) \ GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ @@ -230,6 +257,24 @@ 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)) #endif +#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) - \ diff --git a/src/gfx16.c b/src/gfx16.c index 51d1240..db35e6a 100644 --- a/src/gfx16.c +++ b/src/gfx16.c @@ -249,6 +249,7 @@ void DrawHiResTile16(uint32 Tile, uint32 Offset, bool8_32 S9xGraphicsInit() { + uint32 r, g, b; uint32 PixelOdd = 1; uint32 PixelEven = 2; @@ -366,6 +367,8 @@ bool8_32 S9xGraphicsInit() DrawHiResClippedTilePtr = DrawHiResClippedTile16; S9xFixColourBrightness(); +#if defined(USE_OLD_COLOUR_OPS) + /* Pre-1.60 colour operations */ if (!(GFX.X2 = (uint16*) malloc(sizeof(uint16) * 0x10000))) return (FALSE); @@ -384,7 +387,6 @@ bool8_32 S9xGraphicsInit() } return (FALSE); } - uint32 r, g, b; // Build a lookup table that multiplies a packed RGB value by 2 with // saturation. @@ -481,6 +483,10 @@ bool8_32 S9xGraphicsInit() } } #endif +#else + if (!(GFX.ZERO = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000))) + return false; +#endif // Build a lookup table that if the top bit of the color value is zero // then the value is zero, otherwise its just the value. @@ -519,6 +525,8 @@ bool8_32 S9xGraphicsInit() void S9xGraphicsDeinit(void) { // Free any memory allocated in S9xGraphicsInit +#if defined(USE_OLD_COLOUR_OPS) + /* Pre-1.60 colour operations */ if (GFX.X2) { free((char*) GFX.X2); @@ -529,6 +537,7 @@ void S9xGraphicsDeinit(void) free((char*) GFX.ZERO_OR_X2); GFX.ZERO_OR_X2 = NULL; } +#endif if (GFX.ZERO) { free((char*) GFX.ZERO); diff --git a/src/pixform.h b/src/pixform.h index f7e5e7a..1edd9c5 100644 --- a/src/pixform.h +++ b/src/pixform.h @@ -83,9 +83,11 @@ extern uint32 HIGH_BITS_SHIFTED_TWO_MASK; #define DECOMPOSE_PIXEL_RGB565(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_RGB565 (1 << 5) -#define MAX_RED_RGB565 31 -#define MAX_GREEN_RGB565 63 -#define MAX_BLUE_RGB565 31 +#define MAX_RED_RGB565 31 +#define MAX_GREEN_RGB565 63 +#define MAX_BLUE_RGB565 31 +#define RED_SHIFT_BITS_RGB565 11 +#define GREEN_SHIFT_BITS_RGB565 6 #define RED_LOW_BIT_MASK_RGB565 0x0800 #define GREEN_LOW_BIT_MASK_RGB565 0x0020 #define BLUE_LOW_BIT_MASK_RGB565 0x0001 @@ -103,9 +105,11 @@ extern uint32 HIGH_BITS_SHIFTED_TWO_MASK; #define DECOMPOSE_PIXEL_RGB555(PIX,R,G,B) {(R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; } #define SPARE_RGB_BIT_MASK_RGB555 (1 << 15) -#define MAX_RED_RGB555 31 -#define MAX_GREEN_RGB555 31 -#define MAX_BLUE_RGB555 31 +#define MAX_RED_RGB555 31 +#define MAX_GREEN_RGB555 31 +#define MAX_BLUE_RGB555 31 +#define RED_SHIFT_BITS_RGB555 10 +#define GREEN_SHIFT_BITS_RGB555 5 #define RED_LOW_BIT_MASK_RGB555 0x0400 #define GREEN_LOW_BIT_MASK_RGB555 0x0020 #define BLUE_LOW_BIT_MASK_RGB555 0x0001 @@ -117,106 +121,6 @@ extern uint32 HIGH_BITS_SHIFTED_TWO_MASK; #define THIRD_COLOR_MASK_RGB555 0x001F #define ALPHA_BITS_MASK_RGB555 0x0000 -// BGR565 format -#define BUILD_PIXEL_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 6) | (int) (R)) -#define BUILD_PIXEL2_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 5) | (int) (R)) -#define DECOMPOSE_PIXEL_BGR565(PIX,R,G,B) {(B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; } -#define SPARE_RGB_BIT_MASK_BGR565 (1 << 5) - -#define MAX_RED_BGR565 31 -#define MAX_GREEN_BGR565 63 -#define MAX_BLUE_BGR565 31 -#define RED_LOW_BIT_MASK_BGR565 0x0001 -#define GREEN_LOW_BIT_MASK_BGR565 0x0040 -#define BLUE_LOW_BIT_MASK_BGR565 0x0800 -#define RED_HI_BIT_MASK_BGR565 0x0010 -#define GREEN_HI_BIT_MASK_BGR565 0x0400 -#define BLUE_HI_BIT_MASK_BGR565 0x8000 -#define FIRST_COLOR_MASK_BGR565 0xF800 -#define SECOND_COLOR_MASK_BGR565 0x07E0 -#define THIRD_COLOR_MASK_BGR565 0x001F -#define ALPHA_BITS_MASK_BGR565 0x0000 - -// BGR555 format -#define BUILD_PIXEL_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R)) -#define BUILD_PIXEL2_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R)) -#define DECOMPOSE_PIXEL_BGR555(PIX,R,G,B) {(B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; } -#define SPARE_RGB_BIT_MASK_BGR555 (1 << 15) - -#define MAX_RED_BGR555 31 -#define MAX_GREEN_BGR555 31 -#define MAX_BLUE_BGR555 31 -#define RED_LOW_BIT_MASK_BGR555 0x0001 -#define GREEN_LOW_BIT_MASK_BGR555 0x0020 -#define BLUE_LOW_BIT_MASK_BGR555 0x0400 -#define RED_HI_BIT_MASK_BGR555 0x0010 -#define GREEN_HI_BIT_MASK_BGR555 0x0200 -#define BLUE_HI_BIT_MASK_BGR555 0x4000 -#define FIRST_COLOR_MASK_BGR555 0x7C00 -#define SECOND_COLOR_MASK_BGR555 0x03E0 -#define THIRD_COLOR_MASK_BGR555 0x001F -#define ALPHA_BITS_MASK_BGR555 0x0000 - -// GBR565 format -#define BUILD_PIXEL_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 6) | (int) (R)) -#define BUILD_PIXEL2_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 5) | (int) (R)) -#define DECOMPOSE_PIXEL_GBR565(PIX,R,G,B) {(G) = (PIX) >> 11; (B) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; } -#define SPARE_RGB_BIT_MASK_GBR565 (1 << 5) - -#define MAX_RED_GBR565 31 -#define MAX_BLUE_GBR565 63 -#define MAX_GREEN_GBR565 31 -#define RED_LOW_BIT_MASK_GBR565 0x0001 -#define BLUE_LOW_BIT_MASK_GBR565 0x0040 -#define GREEN_LOW_BIT_MASK_GBR565 0x0800 -#define RED_HI_BIT_MASK_GBR565 0x0010 -#define BLUE_HI_BIT_MASK_GBR565 0x0400 -#define GREEN_HI_BIT_MASK_GBR565 0x8000 -#define FIRST_COLOR_MASK_GBR565 0xF800 -#define SECOND_COLOR_MASK_GBR565 0x07E0 -#define THIRD_COLOR_MASK_GBR565 0x001F -#define ALPHA_BITS_MASK_GBR565 0x0000 - -// GBR555 format -#define BUILD_PIXEL_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R)) -#define BUILD_PIXEL2_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R)) -#define DECOMPOSE_PIXEL_GBR555(PIX,R,G,B) {(G) = (PIX) >> 10; (B) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; } -#define SPARE_RGB_BIT_MASK_GBR555 (1 << 15) - -#define MAX_RED_GBR555 31 -#define MAX_BLUE_GBR555 31 -#define MAX_GREEN_GBR555 31 -#define RED_LOW_BIT_MASK_GBR555 0x0001 -#define BLUE_LOW_BIT_MASK_GBR555 0x0020 -#define GREEN_LOW_BIT_MASK_GBR555 0x0400 -#define RED_HI_BIT_MASK_GBR555 0x0010 -#define BLUE_HI_BIT_MASK_GBR555 0x0200 -#define GREEN_HI_BIT_MASK_GBR555 0x4000 -#define FIRST_COLOR_MASK_GBR555 0x7C00 -#define SECOND_COLOR_MASK_GBR555 0x03E0 -#define THIRD_COLOR_MASK_GBR555 0x001F -#define ALPHA_BITS_MASK_GBR555 0x0000 - -// RGB5551 format -#define BUILD_PIXEL_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1) -#define BUILD_PIXEL2_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1) -#define DECOMPOSE_PIXEL_RGB5551(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; } -#define SPARE_RGB_BIT_MASK_RGB5551 (1) - -#define MAX_RED_RGB5551 31 -#define MAX_GREEN_RGB5551 31 -#define MAX_BLUE_RGB5551 31 -#define RED_LOW_BIT_MASK_RGB5551 0x0800 -#define GREEN_LOW_BIT_MASK_RGB5551 0x0040 -#define BLUE_LOW_BIT_MASK_RGB5551 0x0002 -#define RED_HI_BIT_MASK_RGB5551 0x8000 -#define GREEN_HI_BIT_MASK_RGB5551 0x0400 -#define BLUE_HI_BIT_MASK_RGB5551 0x0020 -#define FIRST_COLOR_MASK_RGB5551 0xf800 -#define SECOND_COLOR_MASK_RGB5551 0x07c0 -#define THIRD_COLOR_MASK_RGB5551 0x003e -#define ALPHA_BITS_MASK_RGB5551 0x0001 - #ifndef GFX_MULTI_FORMAT #define CONCAT(X,Y) X##Y @@ -230,24 +134,28 @@ extern uint32 HIGH_BITS_SHIFTED_TWO_MASK; #define BUILD_PIXEL2(R,G,B) BUILD_PIXEL2_D(PIXEL_FORMAT,R,G,B) #define DECOMPOSE_PIXEL(PIX,R,G,B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT,PIX,R,G,B) -#define MAX_RED_D(F) CONCAT(MAX_RED_,F) -#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F) -#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F) -#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F) -#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F) -#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F) -#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F) -#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F) -#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F) +#define MAX_RED_D(F) CONCAT(MAX_RED_,F) +#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F) +#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F) +#define RED_SHIFT_BITS_D(F) CONCAT(RED_SHIFT_BITS_, F) +#define GREEN_SHIFT_BITS_D(F) CONCAT(GREEN_SHIFT_BITS_, F) +#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F) +#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F) +#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F) +#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F) +#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F) +#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F) #define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_,F) #define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_,F) #define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_,F) #define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_,F) -#define MAX_RED MAX_RED_D(PIXEL_FORMAT) -#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT) -#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT) -#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT) +#define MAX_RED MAX_RED_D(PIXEL_FORMAT) +#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT) +#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT) +#define RED_SHIFT_BITS RED_SHIFT_BITS_D(PIXEL_FORMAT) +#define GREEN_SHIFT_BITS GREEN_SHIFT_BITS_D(PIXEL_FORMAT) +#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT) #define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT) #define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT) #define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT) -- cgit v1.2.3