aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorm45t3r2020-05-27 20:43:50 -0300
committerm45t3r2020-05-27 20:43:50 -0300
commit435a5ef19ed64121a87df4d4e7b420ae8b5a1ea4 (patch)
treee55a22230676d97cdc4242e9fae78e77fab74a50
parentedeffb2aa9b74a4a6cfcdada0857ade94b1195dd (diff)
downloadsnesemu-435a5ef19ed64121a87df4d4e7b420ae8b5a1ea4.tar.gz
snesemu-435a5ef19ed64121a87df4d4e7b420ae8b5a1ea4.tar.bz2
snesemu-435a5ef19ed64121a87df4d4e7b420ae8b5a1ea4.zip
Port color operation code from Snes9x 1.60
-rw-r--r--source/gfx.c81
-rw-r--r--source/gfx.h60
-rw-r--r--source/pixform.h109
-rw-r--r--source/port.h4
4 files changed, 49 insertions, 205 deletions
diff --git a/source/gfx.c b/source/gfx.c
index 00fb4d1..3508011 100644
--- a/source/gfx.c
+++ b/source/gfx.c
@@ -226,81 +226,12 @@ bool S9xInitGFX(void)
GFX.PPLx2 = GFX.Pitch;
S9xFixColourBrightness();
- if (!(GFX.X2 = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000)))
- return false;
-
- if (!(GFX.ZERO_OR_X2 = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000)) || !(GFX.ZERO = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000)))
+ if (!(GFX.ZERO = (uint16_t*) malloc(sizeof(uint16_t) * 0x10000)))
{
- if (GFX.ZERO_OR_X2)
- {
- free(GFX.ZERO_OR_X2);
- GFX.ZERO_OR_X2 = NULL;
- }
- if (GFX.X2)
- {
- free(GFX.X2);
- GFX.X2 = NULL;
- }
return false;
}
- /* Build a lookup table that multiplies a packed RGB value by 2 with
- * saturation. */
- for (r = 0; r <= MAX_RED; r++)
- {
- uint32_t r2 = r << 1;
- if (r2 > MAX_RED)
- r2 = MAX_RED;
- for (g = 0; g <= MAX_GREEN; g++)
- {
- uint32_t g2 = g << 1;
- if (g2 > MAX_GREEN)
- g2 = MAX_GREEN;
- for (b = 0; b <= MAX_BLUE; b++)
- {
- uint32_t b2 = b << 1;
- if (b2 > MAX_BLUE)
- b2 = MAX_BLUE;
- GFX.X2 [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2);
- GFX.X2 [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(r2, g2, b2);
- }
- }
- }
memset(GFX.ZERO, 0, 0x10000 * sizeof(uint16_t));
- memset(GFX.ZERO_OR_X2, 0, 0x10000 * sizeof(uint16_t));
- /* Build a lookup table that if the top bit of the color value is zero
- * then the value is zero, otherwise multiply the value by 2. Used by
- * the color subtraction code. */
- for (r = 0; r <= MAX_RED; r++)
- {
- uint32_t r2 = r;
- if ((r2 & 0x10) == 0)
- r2 = 0;
- else
- r2 = (r2 << 1) & MAX_RED;
-
- for (g = 0; g <= MAX_GREEN; g++)
- {
- uint32_t g2 = g;
- if ((g2 & GREEN_HI_BIT) == 0)
- g2 = 0;
- else
- g2 = (g2 << 1) & MAX_GREEN;
-
- for (b = 0; b <= MAX_BLUE; b++)
- {
- uint32_t b2 = b;
- if ((b2 & 0x10) == 0)
- b2 = 0;
- else
- b2 = (b2 << 1) & MAX_BLUE;
-
- GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b)] = BUILD_PIXEL2(r2, g2, b2);
- GFX.ZERO_OR_X2 [BUILD_PIXEL2(r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2(MAX(1, r2), MAX(1, g2), MAX(1, b2));
- }
- }
- }
-
/* 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. */
for (r = 0; r <= MAX_RED; r++)
@@ -337,16 +268,6 @@ bool S9xInitGFX(void)
void S9xDeinitGFX(void)
{
/* Free any memory allocated in S9xInitGFX */
- if (GFX.X2)
- {
- free(GFX.X2);
- GFX.X2 = NULL;
- }
- if (GFX.ZERO_OR_X2)
- {
- free(GFX.ZERO_OR_X2);
- GFX.ZERO_OR_X2 = NULL;
- }
if (GFX.ZERO)
{
free(GFX.ZERO);
diff --git a/source/gfx.h b/source/gfx.h
index 582f7c2..fc4806b 100644
--- a/source/gfx.h
+++ b/source/gfx.h
@@ -33,8 +33,6 @@ typedef struct
uint32_t Pitch;
int32_t Delta;
- uint16_t* X2;
- uint16_t* ZERO_OR_X2;
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,28 +146,50 @@ extern uint8_t mul_brightness [16][32];
static INLINE uint16_t COLOR_ADD(uint16_t C1, uint16_t C2)
{
- 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);
+ 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);
+ rb += 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;
+}
+
+static INLINE uint16_t COLOR_ADD1_2(uint16_t C1, uint16_t C2)
+{
+ return ((((((C1)&RGB_REMOVE_LOW_BITS_MASK) + ((C2)&RGB_REMOVE_LOW_BITS_MASK)) >> 1) +
+ ((C1) & (C2)&RGB_LOW_BITS_MASK)) |
+ ALPHA_BITS_MASK);
}
-#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))
+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
-#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))
+ return retval;
+}
-#define COLOR_SUB1_2(C1, C2) \
-GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \
- ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1]
+static INLINE uint16_t COLOR_SUB1_2(uint16_t C1, uint16_t C2)
+{
+ return GFX.ZERO[(((C1) | RGB_HI_BITS_MASKx2) - ((C2)&RGB_REMOVE_LOW_BITS_MASK)) >> 1];
+}
typedef void (*NormalTileRenderer)(uint32_t Tile, int32_t Offset, uint32_t StartLine, uint32_t LineCount);
typedef void (*ClippedTileRenderer)(uint32_t Tile, int32_t Offset, uint32_t StartPixel, uint32_t Width, uint32_t StartLine, uint32_t LineCount);
diff --git a/source/pixform.h b/source/pixform.h
index f9c075c..4a61ae2 100644
--- a/source/pixform.h
+++ b/source/pixform.h
@@ -12,6 +12,8 @@
#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
@@ -32,6 +34,8 @@
#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
@@ -43,107 +47,6 @@
#define THIRD_COLOR_MASK_RGB555 0x001F
#define ALPHA_BITS_MASK_RGB555 0x0000
-/* BGR565 format */
-#define BUILD_PIXEL_BGR565(R,G,B) (((int32_t) (B) << 11) | ((int32_t) (G) << 6) | (int32_t) (R))
-#define BUILD_PIXEL2_BGR565(R,G,B) (((int32_t) (B) << 11) | ((int32_t) (G) << 5) | (int32_t) (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) (((int32_t) (B) << 10) | ((int32_t) (G) << 5) | (int32_t) (R))
-#define BUILD_PIXEL2_BGR555(R,G,B) (((int32_t) (B) << 10) | ((int32_t) (G) << 5) | (int32_t) (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) (((int32_t) (G) << 11) | ((int32_t) (B) << 6) | (int32_t) (R))
-#define BUILD_PIXEL2_GBR565(R,G,B) (((int32_t) (G) << 11) | ((int32_t) (B) << 5) | (int32_t) (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) (((int32_t) (G) << 10) | ((int32_t) (B) << 5) | (int32_t) (R))
-#define BUILD_PIXEL2_GBR555(R,G,B) (((int32_t) (G) << 10) | ((int32_t) (B) << 5) | (int32_t) (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) (((int32_t) (R) << 11) | ((int32_t) (G) << 6) | (int32_t) ((B) << 1) | 1)
-#define BUILD_PIXEL2_RGB5551(R,G,B) (((int32_t) (R) << 11) | ((int32_t) (G) << 6) | (int32_t) ((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
-
-
#define CONCAT(X,Y) X##Y
/* C pre-processor needs a two stage macro define to enable it to concat
@@ -159,6 +62,8 @@
#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)
@@ -173,6 +78,8 @@
#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)
diff --git a/source/port.h b/source/port.h
index 06c5f5e..6c3425c 100644
--- a/source/port.h
+++ b/source/port.h
@@ -14,11 +14,7 @@
#include <sys/types.h>
#include <retro_inline.h>
-#ifdef PSP
-#define PIXEL_FORMAT BGR555
-#else
#define PIXEL_FORMAT RGB565
-#endif
/* The above is used to disable the 16-bit graphics mode checks sprinkled
* throughout the code, if the pixel format is always 16-bit. */