Add PS2 Support for changing resolution and offset

This commit is contained in:
Francisco Javier Trujillo Mata 2021-09-07 19:09:56 +02:00
parent c8a46e6e69
commit 216675919b
7 changed files with 233 additions and 48 deletions

View File

@ -30,7 +30,7 @@ ASFLAGS = $(CFLAGS)
RARCH_DEFINES += -DPS2 -DHAVE_GRIFFIN=1 -DRARCH_INTERNAL -DHAVE_SCREENSHOTS -DHAVE_REWIND -DRARCH_CONSOLE -DHAVE_MENU -DHAVE_CONFIGFILE -DHAVE_PATCH -DHAVE_CHEATS
RARCH_DEFINES += -DHAVE_ZLIB -DHAVE_NO_BUILTINZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_FILTERS_BUILTIN -DHAVE_7ZIP -D_7ZIP_ST -DHAVE_CC_RESAMPLER -DHAVE_AUDIOMIXER
RARCH_DEFINES += -DHAVE_VIDEO_FILTER -DHAVE_RGUI
RARCH_DEFINES += -DHAVE_WINDOW_OFFSET -DHAVE_VIDEO_FILTER -DHAVE_RGUI
RARCH_DEFINES += -DHAVE_DSP_FILTER
LDFLAGS += -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ports/lib -L.
@ -58,7 +58,7 @@ EE_OBJS += $(IRX_DIR)/mcman_irx.o $(IRX_DIR)/mcserv_irx.o
EE_OBJS += $(IRX_DIR)/usbd_irx.o $(IRX_DIR)/bdm_irx.o $(IRX_DIR)/bdmfs_vfat_irx.o $(IRX_DIR)/usbmass_bd_irx.o
EE_OBJS += $(IRX_DIR)/libsd_irx.o $(IRX_DIR)/audsrv_irx.o
EE_OBJS += $(IRX_DIR)/cdfs_irx.o
EE_OBJS += $(IRX_DIR)/ps2dev9_irx.o $(IRX_DIR)/ps2atad_irx.o $(IRX_DIR)/ps2hdd_irx.o $(IRX_DIR)/ps2fs_irx.o $(IRX_DIR)/poweroff_irx.o
EE_OBJS += $(IRX_DIR)/ps2dev9_irx.o $(IRX_DIR)/ps2atad_irx.o $(IRX_DIR)/ps2hdd_irx.o $(IRX_DIR)/ps2fs_irx.o $(IRX_DIR)/poweroff_irx.o
EE_OBJS += $(IRX_DIR)/mtapman_irx.o $(IRX_DIR)/padman_irx.o
# Missing objecst on the PS2SDK

View File

@ -27,10 +27,54 @@
#define GS_TEXT GS_SETREG_RGBA(0x80,0x80,0x80,0x80)
/* turn black GS Screen */
#define GS_BLACK GS_SETREG_RGBA(0x00,0x00,0x00,0x80)
/* default alpha logic */
#define GS_DEFAULT_ALPHA GS_SETREG_ALPHA(0, 1, 0, 1, 0)
#define NTSC_WIDTH 640
#define NTSC_HEIGHT 448
#define NUM_RM_VMODES 8
#define PS2_RESOLUTION_LAST NUM_RM_VMODES - 1
#define RM_VMODE_AUTO 0
enum rm_aratio {
RM_ARATIO_4_3 = 0,
RM_ARATIO_16_9,
};
// RM Vmode -> GS Vmode conversion table
struct rm_mode
{
char mode;
char hsync; // In KHz
short int width;
short int height;
short int passes;
short int VCK;
short int interlace;
short int field;
short int aratio;
short int PAR1; // Pixel Aspect Ratio 1 (For video modes with non-square pixels, like PAL/NTSC)
short int PAR2; // Pixel Aspect Ratio 2 (For video modes with non-square pixels, like PAL/NTSC)
char desc[64];
};
static struct rm_mode rm_mode_table[NUM_RM_VMODES] = {
// 24 bit color mode with black borders
{-1, 16, 640, -1, 1, 4, GS_INTERLACED, GS_FIELD, RM_ARATIO_4_3, -1, 15, "AUTO"}, // AUTO
{GS_MODE_PAL, 16, 640, 512, 1, 4, GS_INTERLACED, GS_FIELD, RM_ARATIO_4_3, 16, 15, "PAL@50Hz"}, // PAL@50Hz
{GS_MODE_NTSC, 16, 640, 448, 1, 4, GS_INTERLACED, GS_FIELD, RM_ARATIO_4_3, 14, 15, "NTSC@60Hz"}, // NTSC@60Hz
{GS_MODE_PAL, 16, 640, 256, 1, 2, GS_NONINTERLACED, GS_FIELD, RM_ARATIO_4_3, 16, 15, "PAL@50Hz"}, // PAL@50Hz
{GS_MODE_NTSC, 16, 640, 224, 1, 2, GS_NONINTERLACED, GS_FIELD, RM_ARATIO_4_3, 14, 15, "NTSC@60Hz"}, // NTSC@60Hz
{GS_MODE_DTV_480P, 31, 640, 448, 1, 2, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_4_3, 14, 15, "DTV480P@60Hz"}, // DTV480P@60Hz
{GS_MODE_DTV_576P, 31, 640, 512, 1, 2, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_4_3, 16, 15, "DTV576P@50Hz"}, // DTV576P@50Hz
{GS_MODE_VGA_640_60, 31, 640, 480, 1, 2, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_4_3, 1, 1, "VGA640x480@60Hz"}, // VGA640x480@60Hz
// 24 bit color mode full screen, multi-pass (2 passes, HIRES)
// {GS_MODE_PAL, 16, 704, 576, 2, 4, GS_INTERLACED, GS_FIELD, RM_ARATIO_4_3, 12, 11, "PAL@50Hz"}, // PAL@50Hz
// {GS_MODE_NTSC, 16, 704, 480, 2, 4, GS_INTERLACED, GS_FIELD, RM_ARATIO_4_3, 10, 11, "NTSC@60Hz"}, // NTSC@60Hz
// {GS_MODE_DTV_480P, 31, 704, 480, 2, 2, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_4_3, 10, 11, "DTV480P@60Hz"}, // DTV480P@60Hz
// {GS_MODE_DTV_576P, 31, 704, 576, 2, 2, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_4_3, 12, 11, "DTV576P@50Hz"}, // DTV576P@50Hz
// 16 bit color mode full screen, multi-pass (3 passes, HIRES)
// {GS_MODE_DTV_720P, 31, 1280, 720, 3, 1, GS_NONINTERLACED, GS_FRAME, RM_ARATIO_16_9, 1, 1, "HDTV720P@60Hz"}, // HDTV720P@60Hz
// {GS_MODE_DTV_1080I, 31, 1920, 1080, 3, 1, GS_INTERLACED, GS_FRAME, RM_ARATIO_16_9, 1, 1, "HDTV1080I@60Hz"}, // HDTV1080I@60Hz
};
typedef struct ps2_video
{
/* I need to create this additional field
@ -41,6 +85,11 @@ typedef struct ps2_video
int vsync_callback_id;
bool force_aspect;
int8_t vmode;
bool hires;
int video_window_offset_x;
int video_window_offset_y;
int PSM;
int menu_filter;
int core_filter;
@ -66,7 +115,108 @@ static int vsync_handler()
return 0;
}
static GSGLOBAL *init_GSGlobal(void)
static void rmEnd(ps2_video_t *ps2)
{
if (!ps2->gsGlobal)
return;
if (ps2->hires)
{
gsKit_hires_deinit_global(ps2->gsGlobal);
}
else
{
gsKit_deinit_global(ps2->gsGlobal);
}
ps2->vmode = -1;
}
static void updateOffSetsIfNeeded(ps2_video_t *ps2)
{
bool shouldUpdate = false;
settings_t *settings = config_get_ptr();
int video_window_offset_x = settings->ints.video_window_offset_x;
int video_window_offset_y = settings->ints.video_window_offset_y;
if (video_window_offset_x != ps2->video_window_offset_x || video_window_offset_y != ps2->video_window_offset_y)
shouldUpdate = true;
if (!shouldUpdate)
return;
ps2->video_window_offset_x = video_window_offset_x;
ps2->video_window_offset_y = video_window_offset_y;
gsKit_set_display_offset(ps2->gsGlobal, ps2->video_window_offset_x * rm_mode_table[ps2->vmode].VCK, ps2->video_window_offset_y);
RARCH_LOG("RENDERMAN Change offset: %d, %d\n", ps2->video_window_offset_x, ps2->video_window_offset_y);
}
static int rmSetMode(ps2_video_t *ps2, int force)
{
global_t *global = global_get_ptr();
// we don't want to set the vmode without a reason...
int changed = (ps2->vmode != global->console.screen.resolutions.current.id || force);
if (changed) {
// Cleanup previous gsKit instance
if (ps2->vmode >= 0)
rmEnd(ps2);
ps2->vmode = global->console.screen.resolutions.current.id;
ps2->hires = (rm_mode_table[ps2->vmode].passes > 1) ? 1 : 0;
if (ps2->hires) {
ps2->gsGlobal = gsKit_hires_init_global();
} else {
ps2->gsGlobal = gsKit_init_global();
}
ps2->gsGlobal->Mode = rm_mode_table[ps2->vmode].mode;
ps2->gsGlobal->Width = rm_mode_table[ps2->vmode].width;
ps2->gsGlobal->Height = rm_mode_table[ps2->vmode].height;
ps2->gsGlobal->Interlace = rm_mode_table[ps2->vmode].interlace;
ps2->gsGlobal->Field = rm_mode_table[ps2->vmode].field;
ps2->gsGlobal->PSM = GS_PSM_CT16;
ps2->gsGlobal->PSMZ = GS_PSMZ_16S;
ps2->gsGlobal->DoubleBuffering = GS_SETTING_OFF;
ps2->gsGlobal->ZBuffering = GS_SETTING_OFF;
ps2->gsGlobal->PrimAlphaEnable = GS_SETTING_OFF;
if ((ps2->gsGlobal->Interlace == GS_INTERLACED) && (ps2->gsGlobal->Field == GS_FRAME))
ps2->gsGlobal->Height /= 2;
// Coordinate space ranges from 0 to 4096 pixels
// Center the buffer in the coordinate space
ps2->gsGlobal->OffsetX = ((4096 - ps2->gsGlobal->Width) / 2) * 16;
ps2->gsGlobal->OffsetY = ((4096 - ps2->gsGlobal->Height) / 2) * 16;
if (ps2->hires) {
gsKit_hires_init_screen(ps2->gsGlobal, rm_mode_table[ps2->vmode].passes);
} else {
gsKit_init_screen(ps2->gsGlobal);
gsKit_mode_switch(ps2->gsGlobal, GS_ONESHOT);
}
gsKit_set_test(ps2->gsGlobal, GS_ZTEST_OFF);
gsKit_set_primalpha(ps2->gsGlobal, GS_DEFAULT_ALPHA, 0);
// reset the contents of the screen to avoid garbage being displayed
if (ps2->hires) {
gsKit_hires_sync(ps2->gsGlobal);
gsKit_hires_flip(ps2->gsGlobal);
} else {
gsKit_clear(ps2->gsGlobal, GS_BLACK);
gsKit_sync_flip(ps2->gsGlobal);
}
RARCH_LOG("RENDERMAN New vmode: %d, %d x %d\n", ps2->vmode, ps2->gsGlobal->Width, ps2->gsGlobal->Height);
}
updateOffSetsIfNeeded(ps2);
return changed;
}
static void rmInit(ps2_video_t *ps2)
{
ee_sema_t sema;
sema.init_count = 0;
@ -74,42 +224,19 @@ static GSGLOBAL *init_GSGlobal(void)
sema.option = 0;
vsync_sema_id = CreateSema(&sema);
GSGLOBAL *gsGlobal = gsKit_init_global();
short int mode = gsKit_check_rom();
gsGlobal->Mode = GS_MODE_NTSC;
gsGlobal->Interlace = GS_INTERLACED;
gsGlobal->Field = GS_FIELD;
gsGlobal->Width = NTSC_WIDTH;
gsGlobal->Height = NTSC_HEIGHT;
rm_mode_table[RM_VMODE_AUTO].mode = mode;
rm_mode_table[RM_VMODE_AUTO].height = (mode == GS_MODE_PAL) ? 512 : 448;
rm_mode_table[RM_VMODE_AUTO].PAR1 = (mode == GS_MODE_PAL) ? 16 : 14;
gsGlobal->PSM = GS_PSM_CT16;
gsGlobal->PSMZ = GS_PSMZ_16;
gsGlobal->DoubleBuffering = GS_SETTING_OFF;
gsGlobal->ZBuffering = GS_SETTING_OFF;
gsGlobal->PrimAlphaEnable = GS_SETTING_OFF;
dmaKit_init(D_CTRL_RELE_OFF,D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC,
D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF);
/* Initialize the DMAC */
// Initialize the DMAC
dmaKit_chan_init(DMA_CHANNEL_GIF);
gsKit_init_screen(gsGlobal);
gsKit_mode_switch(gsGlobal, GS_ONESHOT);
gsKit_set_test(gsGlobal, GS_ZTEST_OFF);
gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0, 1, 0, 1, 0), 0);
gsKit_clear(gsGlobal, GS_BLACK);
return gsGlobal;
}
static void deinit_GSGlobal(GSGLOBAL *gsGlobal)
{
gsKit_clear(gsGlobal, GS_BLACK);
gsKit_vram_clear(gsGlobal);
gsKit_deinit_global(gsGlobal);
rmSetMode(ps2, 1);
}
/* Copy of gsKit_sync_flip, but without the 'flip' */
@ -148,7 +275,7 @@ static GSTEXTURE *prepare_new_texture(void)
static void init_ps2_video(ps2_video_t *ps2)
{
ps2->gsGlobal = init_GSGlobal();
rmInit(ps2);
gsKit_TexManager_init(ps2->gsGlobal);
ps2->vp.x = 0;
@ -162,6 +289,11 @@ static void init_ps2_video(ps2_video_t *ps2)
ps2->menuTexture = prepare_new_texture();
ps2->coreTexture = prepare_new_texture();
ps2->vmode = 0;
ps2->hires = false;
ps2->video_window_offset_x = 0;
ps2->video_window_offset_y = 0;
/* Used for cores that supports palette */
ps2->iface.interface_type = RETRO_HW_RENDER_INTERFACE_GSKIT_PS2;
ps2->iface.interface_version = RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION;
@ -300,6 +432,9 @@ static bool ps2_gfx_frame(void *data, const void *frame,
printf("ps2_gfx_frame %llu\n", frame_count);
#endif
// Check if user change offset values
updateOffSetsIfNeeded(ps2);
if (frame)
{
struct retro_hw_ps2_insets padding = empty_ps2_insets;
@ -382,7 +517,7 @@ static void ps2_gfx_free(void *data)
free(ps2->coreTexture);
gsKit_remove_vsync_handler(ps2->vsync_callback_id);
deinit_GSGlobal(ps2->gsGlobal);
rmEnd(ps2);
if (vsync_sema_id >= 0)
DeleteSema(vsync_sema_id);
@ -393,6 +528,13 @@ static void ps2_gfx_free(void *data)
static bool ps2_gfx_set_shader(void *data,
enum rarch_shader_type type, const char *path) { return false; }
static void ps2_set_video_mode(void *data, unsigned fbWidth, unsigned lines,
bool fullscreen)
{
ps2_video_t *ps2 = (ps2_video_t*)data;
rmSetMode(ps2, 0);
}
static void ps2_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling)
{
ps2_video_t *ps2 = (ps2_video_t*)data;
@ -400,6 +542,49 @@ static void ps2_set_filtering(void *data, unsigned index, bool smooth, bool ctx_
ps2->menu_filter = smooth ? GS_FILTER_LINEAR : GS_FILTER_NEAREST;
}
static void ps2_get_video_output_size(void *data,
unsigned *width, unsigned *height)
{
global_t *global = global_get_ptr();
if (!global)
return;
/* If the current index is out of bound default it to zero */
if (global->console.screen.resolutions.current.id > PS2_RESOLUTION_LAST)
global->console.screen.resolutions.current.id = 0;
*width = rm_mode_table[
global->console.screen.resolutions.current.id].width;
*height = rm_mode_table[
global->console.screen.resolutions.current.id].height;
}
static void ps2_get_video_output_prev(void *data)
{
global_t *global = global_get_ptr();
if (global->console.screen.resolutions.current.id == 0)
{
global->console.screen.resolutions.current.id = PS2_RESOLUTION_LAST;
return;
}
global->console.screen.resolutions.current.id--;
}
static void ps2_get_video_output_next(void *data)
{
global_t *global = global_get_ptr();
if (global->console.screen.resolutions.current.id >= PS2_RESOLUTION_LAST)
{
global->console.screen.resolutions.current.id = 0;
return;
}
global->console.screen.resolutions.current.id++;
}
static void ps2_set_texture_frame(void *data, const void *frame, bool rgb32,
unsigned width, unsigned height, float alpha)
{
@ -448,12 +633,12 @@ static const video_poke_interface_t ps2_poke_interface = {
NULL, /* get_flags */
NULL,
NULL,
NULL,
ps2_set_video_mode,
NULL, /* get_refresh_rate */
ps2_set_filtering,
NULL, /* get_video_output_size */
NULL, /* get_video_output_prev */
NULL, /* get_video_output_next */
ps2_get_video_output_size,
ps2_get_video_output_prev,
ps2_get_video_output_next,
NULL, /* get_current_framebuffer */
NULL, /* get_proc_address */
NULL, /* set_aspect_ratio */

View File

@ -6757,7 +6757,7 @@ static int generic_dropdown_box_list(size_t idx, unsigned lbl)
static int action_ok_video_resolution(const char *path,
const char *label, unsigned type, size_t idx, size_t entry_idx)
{
#if defined(GEKKO) || !defined(__PSL1GHT__) && defined(__PS3__)
#if defined(GEKKO) || defined(PS2) || !defined(__PSL1GHT__) && defined(__PS3__)
unsigned width = 0;
unsigned height = 0;

View File

@ -486,7 +486,7 @@ static int action_start_video_resolution(
const char *path, const char *label,
unsigned type, size_t idx, size_t entry_idx)
{
#if defined(GEKKO) || !defined(__PSL1GHT__) && !defined(__PS3__)
#if defined(GEKKO) || defined(PS2) || !defined(__PSL1GHT__) && !defined(__PS3__)
unsigned width = 0, height = 0;
global_t *global = global_get_ptr();

View File

@ -7893,7 +7893,7 @@ unsigned menu_displaylist_build_list(
PARSE_ONLY_UINT, false) == 0)
count++;
#if defined(GEKKO) || !defined(__PSL1GHT__) && defined(__PS3__)
#if defined(GEKKO) || defined(PS2) || !defined(__PSL1GHT__) && defined(__PS3__)
if (true)
#else
if (video_display_server_has_resolution_list())

View File

@ -11390,7 +11390,7 @@ static bool setting_append_list(
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_LAKKA_ADVANCED);
#if defined(GEKKO) || !defined(__PSL1GHT__) && defined(__PS3__)
#if defined(GEKKO) || defined(PS2) || !defined(__PSL1GHT__) && defined(__PS3__)
if (true)
#else
if (!string_is_equal(video_display_server_get_ident(), "null"))
@ -11417,7 +11417,7 @@ static bool setting_append_list(
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, -24, 24, 1, true, true);
menu_settings_list_current_add_range(list, list_info, -50, 50, 1, true, true);
CONFIG_INT(
list, list_info,
@ -11430,7 +11430,7 @@ static bool setting_append_list(
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, -24, 24, 1, true, true);
menu_settings_list_current_add_range(list, list_info, -50, 50, 1, true, true);
#endif
CONFIG_UINT(

View File

@ -7194,7 +7194,7 @@ bool command_event(enum event_command cmd, void *data)
}
break;
case CMD_EVENT_SET_PER_GAME_RESOLUTION:
#if defined(GEKKO)
#if defined(GEKKO) || defined(PS2)
{
unsigned width = 0, height = 0;