Improve display rendering accuracy for both Galaxian and Pac-Man
authorNick Downing <nick@ndcode.org>
Mon, 4 Jul 2022 05:50:54 +0000 (15:50 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 4 Jul 2022 05:50:54 +0000 (15:50 +1000)
emu_z80/emu_z80.c

index 9004d70..6a02f63 100644 (file)
@@ -15,8 +15,8 @@
 #include "stty_sane.h"
 #include "z80/z80.h"
 
-#define GALAXIAN 1
-#define PACMAN 0
+#define GALAXIAN 0
+#define PACMAN 1
 #define APPLE 0
 
 #if GALAXIAN
@@ -179,27 +179,9 @@ SDL_Texture *texture;
 SDL_Surface *surface;
 uint32_t frame[WINDOW_HEIGHT][WINDOW_WIDTH];
 
+#if APPLE
 // see palette.py
 uint32_t palette[0x10] = {
-#if GALAXIAN || PACMAN
-  // see https://www.lomont.org/software/games/pacman/PacmanEmulation.pdf
-  0xff000000,
-  0xffff0000,
-  0xffde9751,
-  0xffffb8ff,
-  0xff000000,
-  0xff00ffff,
-  0xff47b8ff,
-  0xffffb851,
-  0xff000000,
-  0xffffff00,
-  0xff000000,
-  0xff2121ff,
-  0xff00ff00,
-  0xff47b8ae,
-  0xffffb8ae,
-  0xffdedeff,
-#else // APPLE
   0xff000000,
   0xffbc0089,
   0xff0000bc,
@@ -216,8 +198,8 @@ uint32_t palette[0x10] = {
   0xffffffbc,
   0xffbcffe1,
   0xffffffff,
-#endif
 };
+#endif
 
 // can make this green or amber to be more realistic
 uint32_t mono_palette[2] = {0xff000000, 0xffffffff};
@@ -2081,7 +2063,7 @@ int main(int argc, char **argv) {
       //   spriteram[0x61] = vertical position of shell 0
       //   spriteram[0x63] = horizontal count until shell 0 starts rendering
       //   ...
-      for (int i = 0; i < 8; ++i) {
+      for (int i = 7; i >= 0; --i) {
         int data = mem[0x41 | (i << 2) | SPRITE_RAM];
         bool x_flip = (data >> 6) & 1;
         bool y_flip = (data >> 7) & 1;
@@ -2094,7 +2076,7 @@ int main(int argc, char **argv) {
         int palette_base =
           ((mem[0x42 | (i << 2) | SPRITE_RAM] & 7) << 2) |
           ROM_GALAXIAN_CLR_ADDR;
-        int x = mem[0x40 | (i << 2) | SPRITE_RAM] - 16;
+        int x = mem[0x40 | (i << 2) | SPRITE_RAM] - 16 - (i < 3);
         int y = mem[0x43 | (i << 2) | SPRITE_RAM];
         for (int j = 0; j < 16; ++j) {
           int y1 = y + j;
@@ -2119,6 +2101,7 @@ int main(int argc, char **argv) {
                       ((((colour & 0x38) * 0x49) & 0xff0) << 4) |
                       (((colour & 0xc0) * 0x55) >> 6) | // 0x3fc0 >> 6
                       0xff000000;
+ //rgb = 0xff808080 + i * 0x101010;
                     x1 *= WINDOW_X_SCALE;
                     for (int l = 0; l < WINDOW_Y_SCALE; ++l)
                       for (int m = 0; m < WINDOW_X_SCALE; ++m)
@@ -2141,6 +2124,7 @@ int main(int argc, char **argv) {
                       ((((colour & 0x38) * 0x49) & 0xff0) << 4) |
                       (((colour & 0xc0) * 0x55) >> 6) | // 0x3fc0 >> 6
                       0xff000000;
+ //rgb = 0xff808080 + i * 0x101010;
                     x1 *= WINDOW_X_SCALE;
                     for (int l = 0; l < WINDOW_Y_SCALE; ++l)
                       for (int m = 0; m < WINDOW_X_SCALE; ++m)
@@ -2155,7 +2139,7 @@ int main(int argc, char **argv) {
 
       // draw shells and missile
       for (int i = 0; i < 8; ++i) {
-        int x = mem[0x61 | (i << 2) | SPRITE_RAM] - 16;
+        int x = mem[0x61 | (i << 2) | SPRITE_RAM] - 16 - (i < 3);
         if (x < GALAXIAN_WIDTH) {
           x *= WINDOW_X_SCALE;
           uint32_t rgb = i < 7 ? 0xffffffff : 0xffffff00;
@@ -2195,11 +2179,20 @@ int main(int argc, char **argv) {
             int y = (k | (i << 3)) * WINDOW_Y_SCALE;
             for (int l = 0; l < 8; ++l) {
               int data = mem[l ^ ((k & 4) << 1) ^ tile_base] << (k & 3);
-              uint32_t rgb = palette[
-                mem[
-                  ((data & 8) >> 3) | ((data & 0x80) >> 6) | palette_base
-                ] & 0xf
-              ];
+              int colour = mem[
+                (
+                  mem[
+                    ((data & 8) >> 3) |
+                    ((data & 0x80) >> 6) |
+                    palette_base
+                  ] & 0x1f
+                ) | ROM_82S123_7F_ADDR
+              ]; // approximately bbgggrrr
+              uint32_t rgb =
+                ((((colour & 7) * 0x49) & 0x1fe) << 15) |
+                ((((colour & 0x38) * 0x49) & 0xff0) << 4) |
+                (((colour & 0xc0) * 0x55) >> 6) | // 0x3fc0 >> 6
+                0xff000000;
               int x = (l | (j << 3)) * WINDOW_X_SCALE;
               for (int m = 0; m < WINDOW_Y_SCALE; ++m)
                 for (int n = 0; n < WINDOW_X_SCALE; ++n)
@@ -2209,7 +2202,7 @@ int main(int argc, char **argv) {
         }
 
       // draw sprites
-      for (int i = 0; i < 8; ++i) {
+      for (int i = 7; i >= 0; --i) {
         int data = mem[(i << 1) | SPRITE_CONFIG];
         bool y_flip = data & 1;
         bool x_flip = (data >> 1) & 1;
@@ -2221,7 +2214,7 @@ int main(int argc, char **argv) {
         int palette_base =
           ((mem[1 | (i << 1) | SPRITE_CONFIG] & 0x3f) << 2) |
           ROM_82S126_4A_ADDR;
-        int x = PACMAN_WIDTH + 15 - mem[(i << 1) | SPRITE_COORDS];
+        int x = PACMAN_WIDTH + 15 - mem[(i << 1) | SPRITE_COORDS] - (i < 3);
         int y = PACMAN_HEIGHT - 16 - mem[1 | (i << 1) | SPRITE_COORDS];
         for (int j = 0; j < 16; ++j) {
           int y1 = y + j;
@@ -2237,14 +2230,21 @@ int main(int argc, char **argv) {
                     ((k & 8) << 2) ^
                     sprite_base
                   ] << (j & 3);
-                  if (data & 0x88) {
-                    uint32_t rgb = palette[
-                      mem[
-                        ((data & 8) >> 3) |
-                        ((data & 0x80) >> 6) |
-                        palette_base
-                      ] & 0xf
-                    ];
+                  int colour = mem[
+                    ((data & 8) >> 3) |
+                    ((data & 0x80) >> 6) |
+                    palette_base
+                  ] & 0x1f; // first stage lookup
+                  if (colour) {
+                    colour = mem[
+                      colour | ROM_82S123_7F_ADDR
+                    ]; // second stage lookup, approximately bbgggrrr
+                    uint32_t rgb =
+                      ((((colour & 7) * 0x49) & 0x1fe) << 15) |
+                      ((((colour & 0x38) * 0x49) & 0xff0) << 4) |
+                      (((colour & 0xc0) * 0x55) >> 6) | // 0x3fc0 >> 6
+                      0xff000000;
+ //rgb = 0xff808080 + i * 0x101010;
                     x1 *= WINDOW_X_SCALE;
                     for (int l = 0; l < WINDOW_Y_SCALE; ++l)
                       for (int m = 0; m < WINDOW_X_SCALE; ++m)
@@ -2258,14 +2258,21 @@ int main(int argc, char **argv) {
                     ((k & 8) << 2) ^
                     sprite_base
                   ] >> (j & 3);
-                  if (data & 0x11) {
-                    uint32_t rgb = palette[
-                      mem[
-                        (data & 1) |
-                        ((data & 0x10) >> 3) |
-                        palette_base
-                      ] & 0xf
-                    ];
+                  int colour = mem[
+                    (data & 1) |
+                    ((data & 0x10) >> 3) |
+                    palette_base
+                  ] & 0x1f; // first stage lookup
+                  if (colour) {
+                    colour = mem[
+                      colour | ROM_82S123_7F_ADDR
+                    ]; // second stage lookup, approximately bbgggrrr
+                    uint32_t rgb =
+                      ((((colour & 7) * 0x49) & 0x1fe) << 15) |
+                      ((((colour & 0x38) * 0x49) & 0xff0) << 4) |
+                      (((colour & 0xc0) * 0x55) >> 6) | // 0x3fc0 >> 6
+                      0xff000000;
+ //rgb = 0xff808080 + i * 0x101010;
                     x1 *= WINDOW_X_SCALE;
                     for (int l = 0; l < WINDOW_Y_SCALE; ++l)
                       for (int m = 0; m < WINDOW_X_SCALE; ++m)