#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <strings.h>
#include "../libpcsxcore/misc.h"
#include "../libpcsxcore/psxcounters.h"
static int vout_width, vout_height;
static int vout_doffs_old, vout_fb_dirty;
static bool vout_can_dupe;
+static bool duping_enable;
static int samples_sent, samples_to_send;
static int plugins_opened;
static const struct retro_variable vars[] = {
{ "frameskip", "Frameskip; 0|1|2|3" },
{ "region", "Region; Auto|NTSC|PAL" },
-#ifdef __ARM_NEON__
+ { "pad1type", "Pad 1 Type; standard|analog" },
+#ifndef DRC_DISABLE
+ { "rearmed_drc", "Dynamic recompiler; enabled|disabled" },
+#endif
+#if defined(__ARM_NEON__) || defined(NEON_PC)
{ "neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" },
{ "neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" },
{ "neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" },
#endif
+ { "pcsx_rearmed_duping_enable", "Frame duping; on|off" },
{ NULL, NULL },
};
else if (strcmp(var.value, "PAL") == 0)
Config.PsxType = 1;
}
-#ifdef __ARM_NEON__
+
+ var.value = NULL;
+ var.key = "pad1type";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ in_type1 = PSE_PAD_TYPE_STANDARD;
+ if (strcmp(var.value, "analog") == 0)
+ in_type1 = PSE_PAD_TYPE_ANALOGPAD;
+ }
+
+#if defined(__ARM_NEON__) || defined(NEON_PC)
var.value = "NULL";
var.key = "neon_interlace_enable";
}
#endif
+ var.value = "NULL";
+ var.key = "pcsx_rearmed_duping_enable";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ if (strcmp(var.value, "off") == 0)
+ duping_enable = false;
+ else if (strcmp(var.value, "on") == 0)
+ duping_enable = true;
+ }
+
+#ifndef DRC_DISABLE
+ var.value = NULL;
+ var.key = "rearmed_drc";
+
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value)
+ {
+ R3000Acpu *prev_cpu = psxCpu;
+
+ if (strcmp(var.value, "disabled") == 0)
+ Config.Cpu = CPU_INTERPRETER;
+ else if (strcmp(var.value, "enabled") == 0)
+ Config.Cpu = CPU_DYNAREC;
+
+ psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
+ if (psxCpu != prev_cpu) {
+ prev_cpu->Shutdown();
+ psxCpu->Init();
+ psxCpu->Reset(); // not really a reset..
+ }
+ }
+#endif
+
if (in_flight) {
// inform core things about possible config changes
plugin_call_rearmed_cbs();
if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i))
in_keystate |= retro_psx_map[i];
+ if (in_type1 == PSE_PAD_TYPE_ANALOGPAD)
+ {
+ in_a1[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
+ in_a1[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
+ in_a2[0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128;
+ in_a2[1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128;
+ }
+
stop = 0;
psxCpu->Execute();
samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60;
- video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL,
+ video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf : NULL,
vout_width, vout_height, vout_width * 2);
vout_fb_dirty = 0;
}
+static bool try_use_bios(const char *path)
+{
+ FILE *f;
+ long size;
+ const char *name;
+
+ f = fopen(path, "rb");
+ if (f == NULL)
+ return false;
+
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fclose(f);
+
+ if (size != 512 * 1024)
+ return false;
+
+ name = strrchr(path, SLASH);
+ if (name++ == NULL)
+ name = path;
+ snprintf(Config.Bios, sizeof(Config.Bios), "%s", name);
+ return true;
+}
+
+#if 1
+#include <sys/types.h>
+#include <dirent.h>
+
+static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
+{
+ DIR *dir;
+ struct dirent *ent;
+ bool ret = false;
+
+ dir = opendir(dirpath);
+ if (dir == NULL)
+ return false;
+
+ while ((ent = readdir(dir))) {
+ if (strncasecmp(ent->d_name, "scph", 4) != 0)
+ continue;
+
+ snprintf(path, path_size, "%s/%s", dirpath, ent->d_name);
+ ret = try_use_bios(path);
+ if (ret)
+ break;
+ }
+ closedir(dir);
+ return ret;
+}
+#else
+#define find_any_bios(...) false
+#endif
+
+static void check_system_specs(void)
+{
+ unsigned level = 6;
+ environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
+}
+
void retro_init(void)
{
const char *bios[] = { "scph1001", "scph5501", "scph7001" };
const char *dir;
char path[256];
- FILE *f = NULL;
int i, ret, level;
+ bool found_bios = false;
ret = emu_core_preinit();
ret |= emu_core_init();
exit(1);
}
+#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)
+ posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
+#else
vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
+#endif
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
{
for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) {
snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]);
- f = fopen(path, "r");
- if (f != NULL) {
- snprintf(Config.Bios, sizeof(Config.Bios), "%s.bin", bios[i]);
+ found_bios = try_use_bios(path);
+ if (found_bios)
break;
- }
}
+
+ if (!found_bios)
+ found_bios = find_any_bios(dir, path, sizeof(path));
}
- if (f != NULL) {
+ if (found_bios) {
SysPrintf("found BIOS file: %s\n", Config.Bios);
- fclose(f);
}
else
- {
+ {
SysPrintf("no BIOS files found.\n");
- struct retro_message msg =
- {
- "no BIOS found, expect bugs!",
- 180
- };
- environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
- }
+ struct retro_message msg =
+ {
+ "no BIOS found, expect bugs!",
+ 180
+ };
+ environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
+ }
level = 1;
environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level);
SaveFuncs.close = save_close;
update_variables(false);
+ check_system_specs();
}
void retro_deinit(void)