libretro, improve ps2 support, switchable renderers, 32X support w/ DRC
authorkub <derkub@gmail.com>
Sat, 12 Dec 2020 13:51:44 +0000 (14:51 +0100)
committerkub <derkub@gmail.com>
Sat, 12 Dec 2020 13:51:44 +0000 (14:51 +0100)
Makefile.libretro
cpu/sh2/compiler.c
platform/libretro/libretro.c
platform/libretro/libretro_core_options.h

index eb9c20c..6777576 100644 (file)
@@ -203,6 +203,7 @@ else ifeq ($(platform), ps2)
        STATIC_LINKING = 1
        NO_MMAP = 1
 
+       ARCH = mipsel
        asm_render = 1
        OBJS += platform/ps2/asm.o
 
index ba6e871..4ab4204 100644 (file)
@@ -380,7 +380,7 @@ static struct block_list *inactive_blocks[TCACHE_BUFFERS];
 // each array has len: sizeof(mem) / INVAL_PAGE_SIZE 
 static struct block_list **inval_lookup[TCACHE_BUFFERS];
 
-#define HASH_TABLE_SIZE(tcid)          ((tcid) ? 512 : 64*512)
+#define HASH_TABLE_SIZE(tcid)          ((tcid) ? 512 : 32*512)
 static struct block_entry **hash_tables[TCACHE_BUFFERS];
 
 #define HASH_FUNC(hash_tab, addr, mask) \
index e39f502..6de1034 100644 (file)
@@ -3,6 +3,7 @@
  * (C) notaz, 2013
  * (C) aliaspider, 2016
  * (C) Daniel De Matteis, 2013
+ * (C) kub, 2020
  *
  * This work is licensed under the terms of MAME license.
  * See COPYING file in the top-level directory.
@@ -80,12 +81,8 @@ static retro_input_state_t input_state_cb;
 static retro_environment_t environ_cb;
 static retro_audio_sample_batch_t audio_batch_cb;
 
-#if defined(RENDER_GSKIT_PS2)
-#define VOUT_MAX_WIDTH 328
-#else
 #define VOUT_MAX_WIDTH 320
 #define VOUT_32COL_WIDTH 256
-#endif
 #define VOUT_MAX_HEIGHT 240
 
 #define INITIAL_SND_RATE 44100
@@ -109,6 +106,8 @@ static int vout_width, vout_height, vout_offset;
 static float user_vout_width = 0.0;
 
 #if defined(RENDER_GSKIT_PS2)
+#define VOUT_8BIT_WIDTH 328
+#define VOUT_8BIT_HEIGHT 256
 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL;
 static void *retro_palette;
 static struct retro_hw_ps2_insets padding;
@@ -213,6 +212,28 @@ void cache_flush_d_inval_i(void *start, void *end)
 #endif
 }
 
+#ifdef RENDER_GSKIT_PS2
+/* ee-gcc is version 3.2, where these aren't yet defined */
+void __builtin___clear_cache(void *b, void *e)
+{
+#if 0 /* which of these is overall faster for lots of small cache updates? */
+   SyncDCache(b, e);
+#else
+   FlushCache(0); /* WRITEBACK_DCACHE */
+#endif
+   FlushCache(2); /* INVALIDATE_ICACHE */
+}
+
+int __builtin_parity(unsigned v)
+{
+   /* credits to bit twiddling hacks, https://graphics.stanford.edu/~seander/bithacks.html */
+   v ^= v >> 16;
+   v ^= v >> 8;
+   v ^= v >> 4;
+   return (0x6996 >> (v&0xf)) & 1;
+}
+#endif
+
 #ifdef __MACH__
 /* calls to this may be generated by the compiler, but it's missing in libc? */
 void __clear_cache(void *start, void *end)
@@ -604,17 +625,29 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols)
    vout_16bit = vout_format == PDF_RGB555 || (PicoIn.AHW & PAHW_32X);
 
 #if defined(RENDER_GSKIT_PS2)
+   // calculate the borders of the real image inside the picodrive image
+   vout_width = (vout_16bit ? VOUT_MAX_WIDTH : VOUT_8BIT_WIDTH);
+   vout_height = (vout_16bit ? VOUT_MAX_HEIGHT : VOUT_8BIT_HEIGHT);
+   vout_offset = (vout_16bit ? 0 : 8); // 8bit has 8 px overlap area on the left
    if (is_32cols) {
-      padding = (struct retro_hw_ps2_insets){start_line, 16.0f, VOUT_MAX_HEIGHT - line_count - start_line, 64.0f};
+      // 256x240, with or w/o overlap on the left and 64 px on the right
+      padding = (struct retro_hw_ps2_insets){start_line, vout_offset, vout_height - line_count - start_line, vout_width - 256.0f - vout_offset};
    } else {
-      padding = (struct retro_hw_ps2_insets){start_line, 16.0f, VOUT_MAX_HEIGHT - line_count - start_line, 0.0f};
+      // 320x240, with or w/o overlap on the left and none on the right
+      padding = (struct retro_hw_ps2_insets){start_line, vout_offset, vout_height - line_count - start_line, vout_width - 320.0f - vout_offset};
    }
 
-   vout_width = VOUT_MAX_WIDTH;
-   vout_height = VOUT_MAX_HEIGHT;
-   memset(vout_buf, 0, vout_width * VOUT_MAX_HEIGHT);
+   int pxsz = (vout_16bit ? 2 : 1); // pixel size: RGB = 16 bits, CLUT = 8 bits
+   memset(vout_buf, 0, pxsz * vout_width * vout_height);
    memset(retro_palette, 0, gsKit_texture_size_ee(16, 16, GS_PSM_CT16));
-   PicoDrawSetOutBuf(vout_buf, vout_width);
+   PicoDrawSetOutBuf(vout_buf, pxsz * vout_width);
+   if (ps2) {
+      // prepare image as texture for rendering
+      ps2->coreTexture->Width = vout_width;
+      ps2->coreTexture->Height = vout_height;
+      ps2->coreTexture->PSM = (vout_16bit ? GS_PSM_CT16 : GS_PSM_T8);
+      ps2->padding = padding;
+   }
 #else
    vout_width = is_32cols ? VOUT_32COL_WIDTH : VOUT_MAX_WIDTH;
    memset(vout_buf, 0, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);  
@@ -1653,10 +1686,11 @@ void retro_run(void)
    buff = (uint32_t *)RETRO_HW_FRAME_BUFFER_VALID;
 
    if (!ps2) {
+      // get access to the graphics hardware
       if (!environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&ps2) || !ps2) {
          printf("Failed to get HW rendering interface!\n");
          return;
-          }
+      }
 
       if (ps2->interface_version != RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION) {
          printf("HW render interface mismatch, expected %u, got %u!\n", 
@@ -1664,72 +1698,32 @@ void retro_run(void)
          return;
       }
 
-      ps2->coreTexture->Width = vout_width;
-      ps2->coreTexture->Height = vout_height;
-      ps2->coreTexture->PSM = GS_PSM_T8;
       ps2->coreTexture->ClutPSM = GS_PSM_CT16;
       ps2->coreTexture->Filter = GS_FILTER_LINEAR;
       ps2->coreTexture->Clut = retro_palette;
-   }
 
-   if (Pico.m.dirtyPal) {
-      int i;
-      unsigned short int *pal=(void *)ps2->coreTexture->Clut;
-
-      if (PicoIn.AHW & PAHW_SMS) {
-         // SMS
-         unsigned int *spal=(void *)PicoMem.cram;
-         unsigned int *dpal=(void *)pal;
-         unsigned int t;
-
-         /* cram is always stored as shorts, even though real hardware probably uses bytes */
-         for (i = 0x20/2; i > 0; i--, spal++, dpal++) {
-            t = *spal;
-            t = ((t & 0x00030003)<< 3) | ((t & 0x000c000c)<<6) | ((t & 0x00300030)<<9);
-            t |= t >> 2;
-            t |= (t >> 4) & 0x08610861;
-            *dpal = t;
-         }
-         pal[0xe0] = 0;
-
-
-      } else if (PicoIn.AHW & PAHW_32X) {
-         // MCD+32X
-      } else if (PicoIn.AHW & PAHW_MCD) {
-         // MCD
-      } else {
-         // MD
-         if(Pico.video.reg[0xC]&8){
-            do_pal_convert_with_shadows(pal, PicoMem.cram);
-         } else {
-            do_pal_convert(pal, PicoMem.cram);
-            if (Pico.est.rendstatus & PDRAW_SONIC_MODE) {
-               memcpy(&pal[0x80], pal, 0x40*2);
-            }
-         }
-      }
-
-
-          //Rotate CLUT.
-      for (i = 0; i < 256; i++) {
-         if ((i&0x18) == 8) {
-            unsigned short int tmp = pal[i];
-            pal[i] = pal[i+8];
-            pal[i+8] = tmp;
-         }
-      }
-
-      Pico.m.dirtyPal = 0;
-   }
-
-   if (PicoIn.AHW & PAHW_SMS) {
       ps2->coreTexture->Mem = vout_buf;
-   } else {
-      ps2->coreTexture->Mem = Pico.est.Draw2FB;
+      ps2->coreTexture->Width = vout_width;
+      ps2->coreTexture->Height = vout_height;
+      ps2->coreTexture->PSM = (vout_16bit ? GS_PSM_CT16 : GS_PSM_T8);
+      ps2->padding = padding;
    }
 
-   ps2->padding = padding;
-
+   // CLUT update needed?
+   if (!vout_16bit && Pico.m.dirtyPal) {
+      PicoDrawUpdateHighPal();
+
+      // Rotate CLUT. PS2 is special since entries in CLUT are not in sequence.
+      unsigned short int *pal=(void *)retro_palette;
+      for (i = 0; i < 256; i+=8) {
+         if ((i&0x18) == 0x08)
+            memcpy(pal+i,Pico.est.HighPal+i+8,16);
+         else if ((i&0x18) == 0x10)
+            memcpy(pal+i,Pico.est.HighPal+i-8,16);
+         else
+            memcpy(pal+i,Pico.est.HighPal+i,16);
+      }
+   }
 #else
    if (!vout_16bit) {
       /* The 8 bit renderers write a CLUT image in Pico.est.Draw2FB, while libretro wants RGB in vout_buf.
@@ -1809,21 +1803,13 @@ void retro_init(void)
 #ifdef _3DS
    vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80);
 #elif defined(RENDER_GSKIT_PS2)
-   vout_buf = memalign(128, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT);
+   vout_buf = memalign(4096, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
    retro_palette = memalign(128, gsKit_texture_size_ee(16, 16, GS_PSM_CT16));
 #else
    vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
 #endif
 
    PicoInit();
-#if defined(RENDER_GSKIT_PS2)
-   PicoDrawSetOutFormat(PDF_NONE, 0);
-       PicoDrawSetOutBuf(vout_buf, vout_width);
-   PicoDrawSetOutputMode4(PDF_8BIT);
-#else
-   PicoDrawSetOutFormat(PDF_RGB555, 0);
-   PicoDrawSetOutBuf(vout_buf, vout_width * 2);
-#endif
 
    //PicoIn.osdMessage = plat_status_msg_busy_next;
    PicoIn.mcdTrayOpen = disk_tray_open;
index a28de56..23ca416 100644 (file)
@@ -237,7 +237,6 @@ struct retro_core_option_definition option_defs_us[] = {
       },
       "33"
    },
-#if !defined(RENDER_GSKIT_PS2)
    {
       "picodrive_renderer",
       "Renderer",
@@ -250,7 +249,6 @@ struct retro_core_option_definition option_defs_us[] = {
       },
       "accurate"
    },
-#endif
    {
       "picodrive_sound_rate",
       "Sound quality",