#include "../plugins/dfinput/externals.h"
#include "cspace.h"
#include "main.h"
+#include "menu.h"
#include "plugin.h"
#include "plugin_lib.h"
#include "arm_features.h"
#include "revision.h"
-#include "libretro.h"
+
+#include <libretro.h>
+#include "libretro_core_options.h"
#ifdef _3DS
#include "3ds/3ds_utils.h"
#define ISHEXDEC ((buf[cursor]>='0') && (buf[cursor]<='9')) || ((buf[cursor]>='a') && (buf[cursor]<='f')) || ((buf[cursor]>='A') && (buf[cursor]<='F'))
+#define INTERNAL_FPS_SAMPLE_PERIOD 64
+
//hack to prevent retroarch freezing when reseting in the menu but not while running with the hot key
static int rebootemu = 0;
static bool vout_can_dupe;
static bool duping_enable;
static bool found_bios;
+static bool display_internal_fps = false;
+static unsigned frame_count = 0;
+static bool libretro_supports_bitmasks = false;
+static int show_advanced_gpu_peops_settings = -1;
+static int show_advanced_gpu_unai_settings = -1;
+
+static unsigned previous_width = 0;
+static unsigned previous_height = 0;
static int plugins_opened;
static int is_pal_mode;
static void snd_finish(void){}
static int snd_busy(void){return 0;}
+#define GPU_PEOPS_ODD_EVEN_BIT (1 << 0)
+#define GPU_PEOPS_EXPAND_SCREEN_WIDTH (1 << 1)
+#define GPU_PEOPS_IGNORE_BRIGHTNESS (1 << 2)
+#define GPU_PEOPS_DISABLE_COORD_CHECK (1 << 3)
+#define GPU_PEOPS_LAZY_SCREEN_UPDATE (1 << 6)
+#define GPU_PEOPS_OLD_FRAME_SKIP (1 << 7)
+#define GPU_PEOPS_REPEATED_TRIANGLES (1 << 8)
+#define GPU_PEOPS_QUADS_WITH_TRIANGLES (1 << 9)
+#define GPU_PEOPS_FAKE_BUSY_STATE (1 << 10)
+
static void init_memcard(char *mcd_data)
{
unsigned off = 0;
vout_width = w;
vout_height = h;
+ if (previous_width != vout_width || previous_height != vout_height)
+ {
+ previous_width = vout_width;
+ previous_height = vout_height;
+
+ struct retro_system_av_info info;
+ retro_get_system_av_info(&info);
+ environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &info.geometry);
+ }
+
set_vout_fb();
}
/* libretro */
void retro_set_environment(retro_environment_t cb)
{
- static const struct retro_variable vars[] = {
- { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" },
- { "pcsx_rearmed_bios", "Use BIOS; auto|HLE" },
- { "pcsx_rearmed_region", "Region; auto|NTSC|PAL" },
- { "pcsx_rearmed_memcard2", "Enable second memory card; disabled|enabled" },
- { "pcsx_rearmed_pad1type", "Pad 1 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad2type", "Pad 2 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad3type", "Pad 3 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad4type", "Pad 4 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad5type", "Pad 5 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad6type", "Pad 6 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad7type", "Pad 7 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_pad8type", "Pad 8 Type; default|none|standard|analog|dualshock|negcon" },
- { "pcsx_rearmed_multitap1", "Multitap 1; auto|disabled|enabled" },
- { "pcsx_rearmed_multitap2", "Multitap 2; auto|disabled|enabled" },
- { "pcsx_rearmed_negcon_deadzone", "NegCon Twist Deadzone (percent); 0|5|10|15|20|25|30" },
- { "pcsx_rearmed_negcon_response", "NegCon Twist Response; linear|quadratic|cubic" },
- { "pcsx_rearmed_vibration", "Enable Vibration; enabled|disabled" },
- { "pcsx_rearmed_dithering", "Enable Dithering; enabled|disabled" },
-#ifndef DRC_DISABLE
- { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" },
-#ifdef HAVE_PRE_ARMV7
- { "pcsx_rearmed_psxclock", "PSX cpu clock (default 50); 50|51|52|53|54|55|5657|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49" },
-#else
- { "pcsx_rearmed_psxclock", "PSX cpu clock (default 57); 57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99|100|30|31|32|33|34|35|36|37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56" },
-#endif
-#endif
-#ifdef __ARM_NEON__
- { "pcsx_rearmed_neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
- { "pcsx_rearmed_neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" },
- { "pcsx_rearmed_neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" },
-#endif
- { "pcsx_rearmed_duping_enable", "Frame duping; enabled|disabled" },
- { "pcsx_rearmed_show_bios_bootlogo", "Show Bios Bootlogo(Breaks some games); disabled|enabled" },
- { "pcsx_rearmed_spu_reverb", "Sound: Reverb; enabled|disabled" },
- { "pcsx_rearmed_spu_interpolation", "Sound: Interpolation; simple|gaussian|cubic|off" },
- { "pcsx_rearmed_pe2_fix", "Parasite Eve 2/Vandal Hearts 1/2 Fix; disabled|enabled" },
- { "pcsx_rearmed_inuyasha_fix", "InuYasha Sengoku Battle Fix; disabled|enabled" },
- { NULL, NULL },
- };
-
- if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
- log_cb = logging.log;
-
environ_cb = cb;
- cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
+ if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
+ log_cb = logging.log;
+
+ libretro_set_core_options(environ_cb);
}
void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }
in_type[port] = PSE_PAD_TYPE_ANALOGPAD;
else if (strcmp(var.value, "negcon") == 0)
in_type[port] = PSE_PAD_TYPE_NEGCON;
+ else if (strcmp(var.value, "guncon") == 0)
+ in_type[port] = PSE_PAD_TYPE_GUNCON;
else if (strcmp(var.value, "none") == 0)
in_type[port] = PSE_PAD_TYPE_NONE;
// else 'default' case, do nothing
#define GIT_VERSION ""
#endif
info->library_version = "r22" GIT_VERSION;
- info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u";
+ info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u|chd";
info->need_fullpath = true;
}
void retro_get_system_av_info(struct retro_system_av_info *info)
{
+
+ unsigned geom_height = vout_height > 0 ? vout_height : 240;
+ unsigned geom_width = vout_width > 0 ? vout_width : 320;
+
memset(info, 0, sizeof(*info));
info->timing.fps = is_pal_mode ? 50 : 60;
info->timing.sample_rate = 44100;
- info->geometry.base_width = 320;
- info->geometry.base_height = 240;
+ info->geometry.base_width = geom_width;
+ info->geometry.base_height = geom_height;
info->geometry.max_width = VOUT_MAX_WIDTH;
info->geometry.max_height = VOUT_MAX_HEIGHT;
info->geometry.aspect_ratio = 4.0 / 3.0;
#define PATH_MAX 4096
#endif
-static char base_dir[PATH_MAX];
+static char base_dir[1024];
static bool read_m3u(const char *file)
{
- char line[PATH_MAX];
+ char line[1024];
char name[PATH_MAX];
FILE *f = fopen(file, "r");
if (!f)
{ 0 },
};
+ frame_count = 0;
+
environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc);
#ifdef FRONTEND_SUPPORTS_RGB565
return false;
}
- /* TODO: Calling SysReset() outside retro_run for some system
- * causes RetroArch to freeze, e.g Ludo */
- //SysReset();
- rebootemu = 1;
+ SysReset();
if (LoadCdrom() == -1) {
log_cb(RETRO_LOG_INFO, "could not load CD\n");
{
if (id == RETRO_MEMORY_SAVE_RAM)
return Mcd1Data;
+ else if (id == RETRO_MEMORY_SYSTEM_RAM)
+ return psxM;
else
return NULL;
}
{
if (id == RETRO_MEMORY_SAVE_RAM)
return MCD_SIZE;
+ else if (id == RETRO_MEMORY_SYSTEM_RAM)
+ return 0x200000;
else
return 0;
}
{
struct retro_variable var;
int i;
+ int gpu_peops_fix = 0;
var.value = NULL;
var.key = "pcsx_rearmed_frameskip";
if (strcmp(var.value, "disabled") == 0) {
pl_rearmed_cbs.gpu_peops.iUseDither = 0;
pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 0;
+ pl_rearmed_cbs.gpu_unai.dithering = 0;
#ifdef __ARM_NEON__
pl_rearmed_cbs.gpu_neon.allow_dithering = 0;
#endif
else if (strcmp(var.value, "enabled") == 0) {
pl_rearmed_cbs.gpu_peops.iUseDither = 1;
pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 1;
+ pl_rearmed_cbs.gpu_unai.dithering = 1;
#ifdef __ARM_NEON__
pl_rearmed_cbs.gpu_neon.allow_dithering = 1;
#endif
duping_enable = true;
}
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_display_internal_fps";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ display_internal_fps = false;
+ else if (strcmp(var.value, "enabled") == 0)
+ display_internal_fps = true;
+ }
+
#ifndef DRC_DISABLE
var.value = NULL;
var.key = "pcsx_rearmed_drc";
Config.RCntFix = 1;
}
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_idiablofix";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ spu_config.idiablofix = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ spu_config.idiablofix = 1;
+ }
+
var.value = "NULL";
var.key = "pcsx_rearmed_inuyasha_fix";
Config.VSyncWA = 1;
}
+ var.value = NULL;
+ var.key = "pcsx_rearmed_noxadecoding";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.Xa = 1;
+ else
+ Config.Xa = 0;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nocdaudio";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.Cdda = 1;
+ else
+ Config.Cdda = 0;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_spuirq";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ Config.SpuIrq = 0;
+ else
+ Config.SpuIrq = 1;
+ }
+
+#ifndef DRC_DISABLE
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nosmccheck";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_NO_SMC_CHECK;
+ else
+ new_dynarec_hacks &= ~NDHACK_NO_SMC_CHECK;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gteregsunneeded";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_GTE_UNNEEDED;
+ else
+ new_dynarec_hacks &= ~NDHACK_GTE_UNNEEDED;
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_nogteflags";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ new_dynarec_hacks |= NDHACK_GTE_NO_FLAGS;
+ else
+ new_dynarec_hacks &= ~NDHACK_GTE_NO_FLAGS;
+ }
+#endif
+
+#ifdef GPU_PEOPS
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_odd_even_bit";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_ODD_EVEN_BIT;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_expand_screen_width";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_EXPAND_SCREEN_WIDTH;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_ignore_brightness";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_IGNORE_BRIGHTNESS;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_disable_coord_check";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_DISABLE_COORD_CHECK;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_lazy_screen_update";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_LAZY_SCREEN_UPDATE;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_old_frame_skip";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_OLD_FRAME_SKIP;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_repeated_triangles";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_REPEATED_TRIANGLES;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_quads_with_triangles";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_QUADS_WITH_TRIANGLES;
+ }
+
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_gpu_peops_fake_busy_state";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ if (strcmp(var.value, "enabled") == 0)
+ gpu_peops_fix |= GPU_PEOPS_FAKE_BUSY_STATE;
+ }
+
+ if (pl_rearmed_cbs.gpu_peops.dwActFixes != gpu_peops_fix)
+ pl_rearmed_cbs.gpu_peops.dwActFixes = gpu_peops_fix;
+
+
+ /* Show/hide core options */
+
+ var.key = "pcsx_rearmed_show_gpu_peops_settings";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ int show_advanced_gpu_peops_settings_prev = show_advanced_gpu_peops_settings;
+
+ show_advanced_gpu_peops_settings = 1;
+ if (strcmp(var.value, "disabled") == 0)
+ show_advanced_gpu_peops_settings = 0;
+
+ if (show_advanced_gpu_peops_settings != show_advanced_gpu_peops_settings_prev)
+ {
+ unsigned i;
+ struct retro_core_option_display option_display;
+ char gpu_peops_option[9][45] = {
+ "pcsx_rearmed_gpu_peops_odd_even_bit",
+ "pcsx_rearmed_gpu_peops_expand_screen_width",
+ "pcsx_rearmed_gpu_peops_ignore_brightness",
+ "pcsx_rearmed_gpu_peops_disable_coord_check",
+ "pcsx_rearmed_gpu_peops_lazy_screen_update",
+ "pcsx_rearmed_gpu_peops_old_frame_skip",
+ "pcsx_rearmed_gpu_peops_repeated_triangles",
+ "pcsx_rearmed_gpu_peops_quads_with_triangles",
+ "pcsx_rearmed_gpu_peops_fake_busy_state",
+ };
+
+ option_display.visible = show_advanced_gpu_peops_settings;
+
+ for (i = 0; i < 9; i++)
+ {
+ option_display.key = gpu_peops_option[i];
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+ }
+ }
+ }
+#endif
+
+#ifdef GPU_UNAI
+ var.key = "pcsx_rearmed_gpu_unai_ilace_force";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.ilace_force = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.ilace_force = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_pixel_skip";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.pixel_skip = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.pixel_skip = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_lighting";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.lighting = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.lighting = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_fast_lighting";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.fast_lighting = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.fast_lighting = 1;
+ }
+
+ var.key = "pcsx_rearmed_gpu_unai_blending";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "disabled") == 0)
+ pl_rearmed_cbs.gpu_unai.blending = 0;
+ else if (strcmp(var.value, "enabled") == 0)
+ pl_rearmed_cbs.gpu_unai.blending = 1;
+ }
+
+ var.key = "pcsx_rearmed_show_gpu_unai_settings";
+ var.value = NULL;
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+ {
+ int show_advanced_gpu_unai_settings_prev = show_advanced_gpu_unai_settings;
+
+ show_advanced_gpu_unai_settings = 1;
+ if (strcmp(var.value, "disabled") == 0)
+ show_advanced_gpu_unai_settings = 0;
+
+ if (show_advanced_gpu_unai_settings != show_advanced_gpu_unai_settings_prev)
+ {
+ unsigned i;
+ struct retro_core_option_display option_display;
+ char gpu_unai_option[5][40] = {
+ "pcsx_rearmed_gpu_unai_blending",
+ "pcsx_rearmed_gpu_unai_lighting",
+ "pcsx_rearmed_gpu_unai_fast_lighting",
+ "pcsx_rearmed_gpu_unai_ilace_force",
+ "pcsx_rearmed_gpu_unai_pixel_skip",
+ };
+
+ option_display.visible = show_advanced_gpu_unai_settings;
+
+ for (i = 0; i < 5; i++)
+ {
+ option_display.key = gpu_unai_option[i];
+ environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display);
+ }
+ }
+ }
+#endif // GPU_UNAI
+
if (in_flight) {
// inform core things about possible config changes
plugin_call_rearmed_cbs();
dfinput_activate();
}
- else{
+ else
+ {
//not yet running
//bootlogo display hack
var.key = "pcsx_rearmed_show_bios_bootlogo";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
{
+ Config.SlowBoot = 0;
+ rebootemu = 0;
if (strcmp(var.value, "enabled") == 0)
+ {
Config.SlowBoot = 1;
- else
- Config.SlowBoot = 0;
+ rebootemu = 1;
+ }
}
}
#ifndef DRC_DISABLE
}
// Taken from beetle-psx-libretro
-static uint16_t get_analog_button(retro_input_state_t input_state_cb, int player_index, int id)
+static uint16_t get_analog_button(int16_t ret, retro_input_state_t input_state_cb, int player_index, int id)
{
- uint16_t button;
-
// NOTE: Analog buttons were added Nov 2017. Not all front-ends support this
// feature (or pre-date it) so we need to handle this in a graceful way.
// First, try and get an analog value using the new libretro API constant
- button = input_state_cb(player_index,
+ uint16_t button = input_state_cb(player_index,
RETRO_DEVICE_ANALOG,
RETRO_DEVICE_INDEX_ANALOG_BUTTON,
id);
// NOTE: If we're really just not holding the button, we're still going to get zero.
- button = input_state_cb(player_index,
- RETRO_DEVICE_JOYPAD,
- 0,
- id) ? 255 : 0;
+ button = (ret & (1 << id)) ? 255 : 0;
}
return button;
}
}
+ if (display_internal_fps) {
+ frame_count++;
+
+ if (frame_count % INTERNAL_FPS_SAMPLE_PERIOD == 0) {
+ unsigned internal_fps = pl_rearmed_cbs.flip_cnt * (is_pal_mode ? 50 : 60) / INTERNAL_FPS_SAMPLE_PERIOD;
+ char str[64];
+ const char *strc = (const char*)str;
+ struct retro_message msg =
+ {
+ strc,
+ 180
+ };
+
+ str[0] = '\0';
+
+ snprintf(str, sizeof(str), "Internal FPS: %2d", internal_fps);
+
+ pl_rearmed_cbs.flip_cnt = 0;
+
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
+ }
+ }
+ else
+ frame_count = 0;
+
input_poll_cb();
bool updated = false;
float negcon_twist_amplitude;
int negcon_i_rs;
int negcon_ii_rs;
- for(i = 0; i < PORTS_NUMBER; i++) {
+ for(i = 0; i < PORTS_NUMBER; i++)
+ {
+ int16_t ret = 0;
in_keystate[i] = 0;
if (in_type[i] == PSE_PAD_TYPE_NONE)
continue;
+ if (libretro_supports_bitmasks)
+ ret = input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
+ else
+ {
+ unsigned j;
+ for (j = 0; j < (RETRO_DEVICE_ID_JOYPAD_R3+1); j++)
+ {
+ if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, j))
+ ret |= (1 << j);
+ }
+ }
+
+ if (in_type[i] == PSE_PAD_TYPE_GUNCON)
+ {
+ //ToDo move across to:
+ //RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X
+ //RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y
+ //RETRO_DEVICE_ID_LIGHTGUN_TRIGGER
+ //RETRO_DEVICE_ID_LIGHTGUN_RELOAD
+ //RETRO_DEVICE_ID_LIGHTGUN_AUX_A
+ //RETRO_DEVICE_ID_LIGHTGUN_AUX_B
+ //Though not sure these are hooked up properly on the Pi
+
+ //ToDo
+ //Put the controller index back to i instead of hardcoding to 1 when the libretro overlay crash bug is fixed
+ //This is required for 2 player
+
+ //GUNCON has 3 controls, Trigger,A,B which equal Circle,Start,Cross
+
+ // Trigger
+ //The 1 is hardcoded instead of i to prevent the overlay mouse button libretro crash bug
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)){
+ in_keystate[i] |= (1 << DKEY_CIRCLE);
+ }
+
+ // A
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)){
+ in_keystate[i] |= (1 << DKEY_START);
+ }
+
+ // B
+ if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)){
+ in_keystate[i] |= (1 << DKEY_CROSS);
+ }
+
+ //The 1 is hardcoded instead of i to prevent the overlay mouse button libretro crash bug
+ int gunx = input_state_cb(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
+ int guny = input_state_cb(1, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
+
+ //This adjustment process gives the user the ability to manually align the mouse up better
+ //with where the shots are in the emulator.
+
+ //Percentage distance of screen to adjust
+ int GunconAdjustX = 0;
+ int GunconAdjustY = 0;
+
+ //Used when out by a percentage
+ float GunconAdjustRatioX = 1;
+ float GunconAdjustRatioY = 1;
+
+ struct retro_variable var;
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustx";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustX = atoi(var.value);
+ }
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjusty";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustY = atoi(var.value);
+ }
+
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustratiox";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustRatioX = atof(var.value);
+ }
+
+
+ var.value = NULL;
+ var.key = "pcsx_rearmed_gunconadjustratioy";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ GunconAdjustRatioY = atof(var.value);
+ }
+
+ //Mouse range is -32767 -> 32767
+ //1% is about 655
+ //Use the left analog stick field to store the absolute coordinates
+ in_analog_left[0][0] = (gunx*GunconAdjustRatioX) + (GunconAdjustX * 655);
+ in_analog_left[0][1] = (guny*GunconAdjustRatioY) + (GunconAdjustY * 655);
+
+
+ }
if (in_type[i] == PSE_PAD_TYPE_NEGCON)
{
// Query digital inputs
//
// > Pad-Up
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
in_keystate[i] |= (1 << DKEY_UP);
- }
// > Pad-Right
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
in_keystate[i] |= (1 << DKEY_RIGHT);
- }
// > Pad-Down
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
in_keystate[i] |= (1 << DKEY_DOWN);
- }
// > Pad-Left
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
in_keystate[i] |= (1 << DKEY_LEFT);
- }
// > Start
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_START))
in_keystate[i] |= (1 << DKEY_START);
- }
// > neGcon A
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_A))
in_keystate[i] |= (1 << DKEY_CIRCLE);
- }
// > neGcon B
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_X))
in_keystate[i] |= (1 << DKEY_TRIANGLE);
- }
// > neGcon R shoulder (digital)
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R)){
+ if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_R))
in_keystate[i] |= (1 << DKEY_R1);
- }
// Query analog inputs
//
// From studying 'libpcsxcore/plugins.c' and 'frontend/plugin.c':
// > NeGcon twist
// >> Get raw analog stick value and account for deadzone
lsx = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X);
- if (lsx > negcon_deadzone){
+ if (lsx > negcon_deadzone)
lsx = lsx - negcon_deadzone;
- } else if (lsx < -negcon_deadzone){
+ else if (lsx < -negcon_deadzone)
lsx = lsx + negcon_deadzone;
- } else {
+ else
lsx = 0;
- }
// >> Convert to an 'amplitude' [-1.0,1.0] and adjust response
negcon_twist_amplitude = (float)lsx / (float)(NEGCON_RANGE - negcon_deadzone);
- if (negcon_linearity == 2){
- if (negcon_twist_amplitude < 0.0){
+ if (negcon_linearity == 2)
+ {
+ if (negcon_twist_amplitude < 0.0)
negcon_twist_amplitude = -(negcon_twist_amplitude * negcon_twist_amplitude);
- } else {
+ else
negcon_twist_amplitude = negcon_twist_amplitude * negcon_twist_amplitude;
- }
- } else if (negcon_linearity == 3){
- negcon_twist_amplitude = negcon_twist_amplitude * negcon_twist_amplitude * negcon_twist_amplitude;
}
+ else if (negcon_linearity == 3)
+ negcon_twist_amplitude = negcon_twist_amplitude * negcon_twist_amplitude * negcon_twist_amplitude;
// >> Convert to final 'in_analog' integer value [0,255]
in_analog_right[i][0] = MAX(MIN((int)(negcon_twist_amplitude * 128.0f) + 128, 255), 0);
// > NeGcon I + II
// (Note: have never encountered a gamepad with significant differences
// in deadzone between left/right analog sticks, so use the regular 'twist'
// deadzone here)
- if (rsy > negcon_deadzone){
+ if (rsy > negcon_deadzone)
rsy = rsy - negcon_deadzone;
- } else {
+ else
rsy = 0;
- }
// Convert to 'in_analog' integer value [0,255]
negcon_ii_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
} else {
- if (rsy < -negcon_deadzone){
+ if (rsy < -negcon_deadzone)
rsy = -1 * (rsy + negcon_deadzone);
- } else {
+ else
rsy = 0;
- }
negcon_i_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255);
}
// >> NeGcon I
in_analog_right[i][1] = MAX(
MAX(
- get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_R2),
- get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_B)
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_R2),
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_B)
),
negcon_i_rs
);
// >> NeGcon II
in_analog_left[i][0] = MAX(
MAX(
- get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L2),
- get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_Y)
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L2),
+ get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_Y)
),
negcon_ii_rs
);
// > NeGcon L
- in_analog_left[i][1] = get_analog_button(input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L);
+ in_analog_left[i][1] = get_analog_button(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L);
}
- else
+ if (in_type[i] != PSE_PAD_TYPE_NEGCON && in_type[i] != PSE_PAD_TYPE_GUNCON)
{
// Query digital inputs
- for (j = 0; j < RETRO_PSX_MAP_LEN; j++){
- if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, j)){
+ for (j = 0; j < RETRO_PSX_MAP_LEN; j++)
+ if (ret & (1 << j))
in_keystate[i] |= retro_psx_map[j];
- }
- }
+
// Query analog inputs
if (in_type[i] == PSE_PAD_TYPE_ANALOGJOY || in_type[i] == PSE_PAD_TYPE_ANALOGPAD)
{
return false;
while ((ent = readdir(dir))) {
- if (strncasecmp(ent->d_name, "scph", 4) != 0)
+ if ((strncasecmp(ent->d_name, "scph", 4) != 0) && (strncasecmp(ent->d_name, "psx", 3) != 0))
continue;
snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
static void loadPSXBios(void)
{
const char *dir;
- char path[256];
+ char path[PATH_MAX];
unsigned useHLE = 0;
const char *bios[] = {
- "SCPH101", "SCPH7001", "SCPH5501", "SCPH1001",
- "scph101", "scph7001", "scph5501", "scph1001"
+ "PSXONPSP660", "psxonpsp660",
+ "SCPH101", "scph101",
+ "SCPH5501", "scph5501",
+ "SCPH7001", "scph7001",
+ "SCPH1001", "scph1001"
};
struct retro_variable var = {
cycle_multiplier = 200;
#endif
pl_rearmed_cbs.gpu_peops.iUseDither = 1;
+ pl_rearmed_cbs.gpu_peops.dwActFixes = GPU_PEOPS_OLD_FRAME_SKIP;
spu_config.iUseFixedUpdates = 1;
SaveFuncs.open = save_open;
SaveFuncs.seek = save_seek;
SaveFuncs.close = save_close;
+ if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
+ libretro_supports_bitmasks = true;
+
update_variables(false);
check_system_specs();
}
void retro_deinit(void)
{
+ ClosePlugins();
SysClose();
#ifdef _3DS
linearFree(vout_buf);
#ifdef VITA
deinit_vita_mmap();
#endif
+ libretro_supports_bitmasks = false;
}
#ifdef VITA
sceKernelDelayThread(us);
}
#endif
+
+void SysPrintf(const char *fmt, ...) {
+ va_list list;
+ char msg[512];
+
+ va_start(list, fmt);
+ vsprintf(msg, fmt, list);
+ va_end(list);
+
+ if (log_cb)
+ log_cb(RETRO_LOG_INFO, "%s", msg);
+}