From d7f7709a37419d5b626aeec119a985bda162f2d8 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Mon, 21 Jan 2019 22:19:46 +0100 Subject: [PATCH] Add palette into FCEumm for PS2 --- Makefile.libretro | 12 ++++ ps2/inttypes.h | 8 +++ ps2/stdint.h | 33 +++++++++ .../include/libretro_gskit_ps2.h | 56 +++++++++++++++ src/drivers/libretro/libretro.c | 72 ++++++++++++++++++- 5 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 ps2/inttypes.h create mode 100644 ps2/stdint.h create mode 100644 src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h diff --git a/Makefile.libretro b/Makefile.libretro index 2222307..ba86af4 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -155,6 +155,18 @@ else ifeq ($(platform), sncps3) STATIC_LINKING=1 EXTERNAL_ZLIB=1 +# PS2 +else ifeq ($(platform), ps2) + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = ee-gcc$(EXE_EXT) + AR = ee-ar$(EXE_EXT) + FCEU_DEFINES := -DPATH_MAX=1024 -DINLINE=inline -DPSS_STYLE=1 -DFCEU_VERSION_NUMERIC=9813 -DHAVE_ASPRINTF + ENDIANNESS_DEFINES := -DLSB_FIRST -DLOCAL_LE=1 + PLATFORM_DEFINES := -DPS2 -G0 -DFRONTEND_SUPPORTS_ABGR1555 -DRENDER_GSKIT_PS2 + PLATFORM_DEFINES += -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -Ips2/ -I$(PS2DEV)/gsKit/include + STATIC_LINKING=1 + EXTERNAL_ZLIB=1 + # PSP else ifeq ($(platform), psp1) TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/ps2/inttypes.h b/ps2/inttypes.h new file mode 100644 index 0000000..3049fbd --- /dev/null +++ b/ps2/inttypes.h @@ -0,0 +1,8 @@ +#ifndef INTTYPES_H +#define INTTYPES_H + +#define PRId64 "ld" +#define PRIu64 "lu" +#define PRIuPTR "lu" + +#endif //INTTYPES_H diff --git a/ps2/stdint.h b/ps2/stdint.h new file mode 100644 index 0000000..ae9a75b --- /dev/null +++ b/ps2/stdint.h @@ -0,0 +1,33 @@ +#ifndef STDINT_H +#define STDINT_H + +typedef unsigned long uintptr_t; +typedef signed long intptr_t; + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long int64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long uint64_t; + +typedef unsigned long uint_least32_t; +typedef unsigned short uint_least16_t; + +#define STDIN_FILENO 0 /* standard input file descriptor */ +#define STDOUT_FILENO 1 /* standard output file descriptor */ +#define STDERR_FILENO 2 /* standard error file descriptor */ + +#define INT8_C(val) val##c +#define INT16_C(val) val##h +#define INT32_C(val) val##i +#define INT64_C(val) val##l + +#define UINT8_C(val) val##uc +#define UINT16_C(val) val##uh +#define UINT32_C(val) val##ui +#define UINT64_C(val) val##ul + +#endif //STDINT_H diff --git a/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h b/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h new file mode 100644 index 0000000..e1e978d --- /dev/null +++ b/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h @@ -0,0 +1,56 @@ +/* Copyright (C) 2010-2018 The RetroArch team + * + * --------------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro API header (libretro_d3d.h) + * --------------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the + * "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_GSKIT_PS2_H_ +#define LIBRETRO_GSKIT_PS2_H_ + +#include "libretro.h" + +#if defined(PS2) + +#include + +#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 1 + +struct retro_hw_render_interface_gskit_ps2 +{ + /* Must be set to RETRO_HW_RENDER_INTERFACE_GSKIT_PS2. */ + enum retro_hw_render_interface_type interface_type; + /* Must be set to RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION. */ + unsigned interface_version; + + /* Opaque handle to the GSKit_PS2 backend in the frontend + * which must be passed along to all function pointers + * in this interface. + */ + GSTEXTURE *coreTexture; + bool clearTexture; +}; +typedef struct retro_hw_render_interface_gskit_ps2 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2; + +#endif + +#endif /* LIBRETRO_GSKIT_PS2_H_ */ diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 89ed88a..cc6cfb0 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -24,6 +24,10 @@ #include "../../vsuni.h" #include "../../video.h" +#if defined(RENDER_GSKIT_PS2) +#include "libretro-common/include/libretro_gskit_ps2.h" +#endif + #include "libretro-common/include/streams/memory_stream.h" #define MAX_PLAYERS 4 /* max supported players */ @@ -95,7 +99,11 @@ static __attribute__((aligned(16))) uint16_t retro_palette[256]; #else static uint16_t retro_palette[256]; #endif +#if defined(RENDER_GSKIT_PS2) +static uint8_t* fceu_video_out; +#else static uint16_t* fceu_video_out; +#endif /* Some timing-related variables. */ static unsigned sndsamplerate; @@ -145,6 +153,16 @@ int FCEUD_SendData(void *data, uint32 len) #define RED_EXPAND 3 #define GREEN_EXPAND 2 #define BLUE_EXPAND 3 +#elif defined (FRONTEND_SUPPORTS_ABGR1555) +#define RED_SHIFT 0 +#define GREEN_SHIFT 5 +#define BLUE_SHIFT 10 +#define RED_EXPAND 3 +#define GREEN_EXPAND 3 +#define BLUE_EXPAND 3 +#define RED_MASK 0x1F +#define GREEN_MASK 0x3E0 +#define BLUE_MASK 0x7C00 #elif defined (FRONTEND_SUPPORTS_RGB565) #define RED_SHIFT 11 #define GREEN_SHIFT 5 @@ -166,10 +184,21 @@ int FCEUD_SendData(void *data, uint32 len) void FCEUD_SetPalette(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { + unsigned char index_to_write = index; +#if defined(RENDER_GSKIT_PS2) + /* Index correction for PS2 GS */ + int modi = index & 63; + if ((modi >= 8 && modi < 16) || (modi >= 40 && modi < 48)) { + index_to_write += 8; + } else if ((modi >= 16 && modi < 24) || (modi >= 48 && modi < 56)) { + index_to_write -= 8; + } +#endif + #ifdef FRONTEND_SUPPORTS_RGB565 - retro_palette[index] = BUILD_PIXEL_RGB565(r >> RED_EXPAND, g >> GREEN_EXPAND, b >> BLUE_EXPAND); + retro_palette[index_to_write] = BUILD_PIXEL_RGB565(r >> RED_EXPAND, g >> GREEN_EXPAND, b >> BLUE_EXPAND); #else - retro_palette[index] = + retro_palette[index_to_write] = ((r >> RED_EXPAND) << RED_SHIFT) | ((g >> GREEN_EXPAND) << GREEN_SHIFT) | ((b >> BLUE_EXPAND) << BLUE_SHIFT); #endif } @@ -1534,6 +1563,45 @@ static void retro_run_blit(uint8_t *gfx) sceGuFinish(); video_cb(texture_vram_p, width, height, 256); +#elif defined(RENDER_GSKIT_PS2) + + RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL; + uint32_t *buf = (uint32_t *)RETRO_HW_FRAME_BUFFER_VALID; + + incr += (overscan_h ? 16 : 0); + width -= (overscan_h ? 16 : 0); + height -= (overscan_v ? 16 : 0); + pitch -= (overscan_h ? 32 : 0); + gfx += (overscan_v ? ((overscan_h ? 8 : 0) + 256 * 8) : (overscan_h ? 8 : 0)); + + 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", + RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION, ps2->interface_version); + return; + } + + if (ps2->clearTexture || !ps2->coreTexture->Clut || !ps2->coreTexture->Mem ) { + /* If it is empty we need to create it */ + ps2->coreTexture->Width = width; + ps2->coreTexture->Height = height; + ps2->coreTexture->PSM = GS_PSM_T8; + ps2->coreTexture->ClutPSM = GS_PSM_CT16; + ps2->coreTexture->Filter = GS_FILTER_LINEAR; + } + + for (y = 0; y < height; y++, gfx += incr) + for ( x = 0; x < width; x++, gfx++) + fceu_video_out[y * width + x] = *gfx; + + ps2->coreTexture->Clut = (u32*)retro_palette; + ps2->coreTexture->Mem = (u32*)fceu_video_out; + + video_cb(buf, width, height, pitch); #else incr += (overscan_h ? 16 : 0); width -= (overscan_h ? 16 : 0);