#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
-
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
#define ISHEXDEC ((buf[cursor] >= '0') && (buf[cursor] <= '9')) || ((buf[cursor] >= 'a') && (buf[cursor] <= 'f')) || ((buf[cursor] >= 'A') && (buf[cursor] <= 'F'))
static int vout_fb_dirty;
static int psx_w, psx_h;
static bool vout_can_dupe;
-static bool found_bios;
static int display_internal_fps;
static bool libretro_supports_bitmasks = false;
static bool libretro_supports_option_categories = false;
}
static void show_notification(const char *msg_str,
- unsigned duration_ms, unsigned priority)
+ unsigned duration_ms, unsigned priority, enum retro_log_level level)
{
if (msg_interface_version >= 1)
{
struct retro_message_ext msg = {
msg_str,
duration_ms,
- 3,
- RETRO_LOG_WARN,
+ priority,
+ level,
RETRO_MESSAGE_TARGET_ALL,
RETRO_MESSAGE_TYPE_NOTIFICATION,
-1
#if !defined(HAVE_CDROM) && !defined(USE_LIBRETRO_VFS)
ReleasePlugins();
LogErr("%s\n", "Physical CD-ROM support is not compiled in.");
- show_notification("Physical CD-ROM support is not compiled in.", 6000, 3);
+ show_notification("Physical CD-ROM support is not compiled in.",
+ 6000, 3, RETRO_LOG_ERROR);
return false;
#endif
}
for (i = 0; i < 8; ++i)
in_type[i] = PSE_PAD_TYPE_STANDARD;
- if (!is_exe && CheckCdrom() == -1)
+ if (!is_exe)
{
- LogErr("unsupported/invalid CD image: %s\n", info->path);
- return false;
+ if (CheckCdrom() == -1)
+ {
+ LogErr("unsupported/invalid CD image: %s\n", info->path);
+ return false;
+ }
+ }
+ else
+ {
+ Config.PsxRegion = PSX_REGION_US;
+ Config.PsxType = PSX_TYPE_NTSC;
}
plugin_call_rearmed_cbs();
#endif
log_mem_usage(0);
- if (check_unsatisfied_libcrypt())
- show_notification("LibCrypt protected game with missing SBI detected", 3000, 3);
+ if (check_unsatisfied_libcrypt()) {
+ show_notification("LibCrypt protected game with missing SBI detected",
+ 3000, 3, RETRO_LOG_WARN);
+ }
+ if (Config.SlowBoot)
+ {
+ char buf[16+64];
+ if (Config.PsxRegion < ARRAY_SIZE(Config.Bios) && Config.Bios[Config.PsxRegion][0]) {
+ snprintf(buf, sizeof(buf), "Booting BIOS: %s", Config.Bios[Config.PsxRegion]);
+ show_notification(buf, 1000, 2, RETRO_LOG_INFO);
+ }
+ }
if (Config.TurboCD)
- show_notification("TurboCD is ON", 700, 2);
+ show_notification("TurboCD is ON", 700, 2, RETRO_LOG_INFO);
return true;
}
}
#endif
- if (found_bios)
- {
- var.value = NULL;
- var.key = "pcsx_rearmed_show_bios_bootlogo";
- if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
- {
- Config.SlowBoot = 0;
- if (strcmp(var.value, "enabled") == 0)
- Config.SlowBoot = 1;
- else if (strcmp(var.value, "enabled_no_pcsx") == 0)
- Config.SlowBoot = 2;
- }
- }
-
if (in_flight)
{
// inform core things about possible config changes
int state = padToggleAnalog(i);
char msg[32];
snprintf(msg, sizeof(msg), "ANALOG %s", state ? "ON" : "OFF");
- show_notification(msg, 800, 1);
+ show_notification(msg, 800, 1, RETRO_LOG_INFO);
in_dualshock_toggling = true;
}
return;
}
}
+static bool get_bios_config_hle(void);
+static void prepare_bios(bool use_hle);
+
void retro_run(void)
{
//SysReset must be run while core is running,Not in menu (Locks up Retroarch)
if (rebootemu != 0)
{
rebootemu = 0;
+ prepare_bios(get_bios_config_hle());
SysReset();
if (Config.HLE)
LoadCdrom();
#endif
}
-static bool try_use_bios(const char *path, bool preferred_only)
+// see Config.Bios
+static char *bios_saved[PSX_REGION_COUNT];
+
+static bool try_use_bios(char *path, size_t path_size, bool preferred_only)
{
+ const char *guessed_region_name = "US";
+ u8 guessed_region = PSX_REGION_US;
long size;
const char *name;
FILE *fp = fopen(path, "rb");
return false;
if (strstr(name, "unirom"))
return false;
- // jp bios have an addidional region check
- if (preferred_only && (strcasestr(name, "00.") || strcasestr(name, "j.bin")))
- return false;
+ if (strstr(name, "00.") || strcasestr(name, "j.bin")) {
+ guessed_region = PSX_REGION_JP;
+ guessed_region_name = "JP";
+ }
+ else if (strstr(name, "02.") || strstr(name, "52.") || strcasestr(name, "e.bin")) {
+ guessed_region = PSX_REGION_EU;
+ guessed_region_name = "EU";
+ }
- snprintf(Config.Bios, sizeof(Config.Bios), "%s", name);
+ if (bios_saved[guessed_region] == NULL) {
+ bios_saved[guessed_region] = strdup(name);
+ if (bios_saved[guessed_region])
+ SysPrintf("found %s BIOS file: %s\n", guessed_region_name, path);
+ }
return true;
}
#include <sys/types.h>
#include <dirent.h>
-static bool find_any_bios(const char *dirpath, char *path, size_t path_size)
+static void find_any_bios(const char *dirpath, char *path, size_t path_size)
{
static const char *substr_pref[] = { "scph", "ps" };
static const char *substr_alt[] = { "scph", "ps", "openbios" };
DIR *dir;
struct dirent *ent;
- bool ret = false;
size_t i;
dir = opendir(dirpath);
if (dir == NULL)
- return false;
+ return;
// try to find a "better" bios
while ((ent = readdir(dir)))
if ((strncasecmp(ent->d_name, substr, strlen(substr)) != 0))
continue;
snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
- ret = try_use_bios(path, true);
- if (ret)
+ try_use_bios(path, path_size, true);
+ if (bios_saved[0] && bios_saved[1] && bios_saved[2])
goto finish;
}
}
if ((strncasecmp(ent->d_name, substr, strlen(substr)) != 0))
continue;
snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name);
- ret = try_use_bios(path, false);
- if (ret)
+ try_use_bios(path, path_size, false);
+ if (bios_saved[0] && bios_saved[1] && bios_saved[2])
goto finish;
}
}
-
finish:
closedir(dir);
- return ret;
}
#else
-#define find_any_bios(...) false
+#define find_any_bios(...)
#endif
static void check_system_specs(void)
return ret;
}
-static void loadPSXBios(void)
+static bool get_bios_config_hle(void)
{
- const char *dir;
- char path[PATH_MAX];
- unsigned useHLE = 0;
-
- const char *bios[] = {
- "PSXONPSP660", "psxonpsp660",
- "SCPH101", "scph101",
- "SCPH5501", "scph5501",
- "SCPH7001", "scph7001",
- "SCPH1001", "scph1001"
- };
-
- struct retro_variable var = {
- .key = "pcsx_rearmed_bios",
- .value = NULL
- };
-
- found_bios = 0;
+ struct retro_variable var = { NULL, };
+ bool use_hle = false;
+ var.key = "pcsx_rearmed_bios";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "HLE"))
- useHLE = 1;
+ use_hle = true;
}
- if (!useHLE)
+ Config.SlowBoot = 0;
+ if (!use_hle)
{
- if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
+ var.value = NULL;
+ var.key = "pcsx_rearmed_show_bios_bootlogo";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
- unsigned i;
- snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+ if (strcmp(var.value, "enabled") == 0)
+ Config.SlowBoot = 1;
+ else if (strcmp(var.value, "enabled_no_pcsx") == 0)
+ Config.SlowBoot = 2;
+ }
+ }
+ return use_hle;
+}
- for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++)
- {
- snprintf(path, sizeof(path), "%s%c%s.bin", dir, SLASH, bios[i]);
- found_bios = try_use_bios(path, true);
- if (found_bios)
- break;
+static void prepare_bios(bool use_hle)
+{
+ size_t i, count = sizeof(bios_saved) / sizeof(bios_saved[0]);
+ assert(count == sizeof(Config.Bios) / sizeof(Config.Bios[0]));
+ for (i = 0; i < count; i++) {
+ Config.Bios[i][0] = 0;
+ if (bios_saved[i] && !use_hle) {
+ int r = snprintf(Config.Bios[i], sizeof(Config.Bios[i]), "%s", bios_saved[i]);
+ if (r >= sizeof(Config.Bios[i])) {
+ LogErr("BIOS '%s' name is too long, discarding\n", bios_saved[i]);
+ Config.Bios[i][0] = 0;
}
-
- if (!found_bios)
- found_bios = find_any_bios(dir, path, sizeof(path));
- }
- if (found_bios)
- {
- SysPrintf("found BIOS file: %s\n", Config.Bios);
}
}
+}
+
+static void loadPSXBios(void)
+{
+ char path[PATH_MAX];
+ const char *dir;
+ const char *msg_str = NULL;
+ unsigned duration = 0;
+ const char * const us_bios[] = {
+ "PSXONPSP660", "psxonpsp660",
+ "SCPH101", "scph101",
+ "SCPH5501", "scph5501",
+ "SCPH7001", "scph7001",
+ "SCPH1001", "scph1001"
+ };
+ bool use_hle = get_bios_config_hle();
+ enum retro_log_level level = RETRO_LOG_INFO;
- if (!found_bios)
+ if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
{
- const char *msg_str;
- unsigned duration;
- if (useHLE)
- {
- msg_str = "BIOS set to \'hle\'";
- SysPrintf("Using HLE BIOS.\n");
- // shorter as the user probably intentionally wants to use HLE
- duration = 700;
- }
- else
+ unsigned i;
+ snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir);
+
+ for (i = 0; i < sizeof(us_bios) / sizeof(us_bios[0]); i++)
{
- msg_str = "No PlayStation BIOS file found - add for better compatibility";
- SysPrintf("No BIOS files found.\n");
- duration = 3000;
+ bool found_bios;
+ snprintf(path, sizeof(path), "%s%c%s.bin", dir, SLASH, us_bios[i]);
+ found_bios = try_use_bios(path, sizeof(path), true);
+ if (found_bios)
+ break;
}
- show_notification(msg_str, duration, 2);
+
+ find_any_bios(dir, path, sizeof(path));
+ }
+
+ prepare_bios(use_hle);
+
+ if (use_hle)
+ {
+ msg_str = "BIOS set to \'hle\'";
+ SysPrintf("Using HLE BIOS.\n");
+ // shorter as the user probably intentionally wants to use HLE
+ duration = 700;
}
+ else if (!bios_saved[0] && !bios_saved[1] && !bios_saved[2])
+ {
+ msg_str = "No PlayStation BIOS file found - add for better compatibility";
+ SysPrintf("No BIOS files found.\n");
+ duration = 3000;
+ level = RETRO_LOG_WARN;
+ }
+ if (msg_str)
+ show_notification(msg_str, duration, 2, level);
}
void retro_init(void)
void retro_deinit(void)
{
+ size_t i;
+
if (plugins_opened)
{
ClosePlugins();
#ifdef GPU_UNAI
show_advanced_gpu_unai_settings = true;
#endif
+ for (i = 0; i < ARRAY_SIZE(bios_saved); i++) {
+ free(bios_saved[i]);
+ bios_saved[i] = NULL;
+ }
/* Have to reset disks struct, otherwise
* fnames/flabels will leak memory */
}
#define CE_CONFIG_STR(val) \
- { #val, 0, Config.val }
+ { #val, sizeof(Config.val), Config.val }
#define CE_CONFIG_VAL(val) \
{ #val, sizeof(Config.val), &Config.val }
-#define CE_STR(val) \
- { #val, 0, val }
-
#define CE_INTVAL(val) \
{ #val, sizeof(val), &val }
// 'versioned' var, used when defaults change
#define CE_CONFIG_STR_V(val, ver) \
- { #val #ver, 0, Config.val }
+ { #val #ver, sizeof(Config.val), Config.val }
#define CE_INTVAL_V(val, ver) \
{ #val #ver, sizeof(val), &val }
size_t len;
void *val;
} config_data[] = {
- CE_CONFIG_STR(Bios),
+ { "Bios", sizeof(Config.Bios[0]), Config.Bios[0] },
CE_CONFIG_STR_V(Gpu, 3),
CE_CONFIG_STR(Spu),
// CE_CONFIG_STR(Cdr),
for (i = 0; i < ARRAY_SIZE(config_data); i++) {
fprintf(f, "%s = ", config_data[i].name);
- switch (config_data[i].len) {
- case 0:
+ if (config_data[i].len > 8) { // string
fprintf(f, "%s\n", (char *)config_data[i].val);
- break;
+ continue;
+ }
+ switch (config_data[i].len) {
case 1:
write_u32_value(f, *(u8 *)config_data[i].val);
break;
return 0;
}
-static void parse_str_val(char *cval, const char *src)
+static void parse_str_val(char *cval, size_t len, const char *src)
{
- char *tmp;
- strncpy(cval, src, MAXPATHLEN);
- cval[MAXPATHLEN - 1] = 0;
- tmp = strchr(cval, '\n');
+ const char *tmp;
+ len--;
+ tmp = strchr(src, '\n');
if (tmp == NULL)
- tmp = strchr(cval, '\r');
- if (tmp != NULL)
- *tmp = 0;
+ tmp = strchr(src, '\r');
+ if (tmp != NULL) {
+ size_t l1 = tmp - src;
+ if (len > l1)
+ len = l1;
+ }
+ memcpy(cval, src, len);
+ cval[len] = 0;
}
static void keys_load_all(const char *cfg);
continue;
tmp += 3;
- if (config_data[i].len == 0) {
- parse_str_val(config_data[i].val, tmp);
+ if (config_data[i].len > 8) {
+ parse_str_val(config_data[i].val, config_data[i].len, tmp);
continue;
}
char *tmp = strstr(cfg, "lastcdimg = ");
if (tmp != NULL) {
tmp += 12;
- parse_str_val(last_selected_fname, tmp);
+ parse_str_val(last_selected_fname, sizeof(last_selected_fname), tmp);
}
}
// sync plugins
for (i = bios_sel = 0; bioses[i] != NULL; i++)
- if (strcmp(Config.Bios, bioses[i]) == 0)
+ if (strcmp(Config.Bios[0], bioses[i]) == 0)
{ bios_sel = i; break; }
for (i = gpu_plugsel = 0; gpu_plugins[i] != NULL; i++)
Config.SlowBoot = slowboot_sel;
// sync BIOS/plugins
- snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[bios_sel]);
+ snprintf(Config.Bios[0], sizeof(Config.Bios[0]), "%s", bioses[bios_sel]);
snprintf(Config.Gpu, sizeof(Config.Gpu), "%s", gpu_plugins[gpu_plugsel]);
snprintf(Config.Spu, sizeof(Config.Spu), "%s", spu_plugins[spu_plugsel]);
me_enable(e_menu_main2, MA_MAIN_RUN_BIOS, bios_sel != 0);
if (fname == NULL)
return -1;
+ Config.PsxRegion = PSX_REGION_US;
+ Config.PsxType = PSX_TYPE_NTSC;
+
ready_to_go = 0;
if (reload_plugins(NULL) != 0)
return -1;
// assume first run
if (bioses[1] != NULL) {
// autoselect BIOS to make user's life easier
- snprintf(Config.Bios, sizeof(Config.Bios), "%s", bioses[1]);
+ snprintf(Config.Bios[0], sizeof(Config.Bios[0]), "%s", bioses[1]);
bios_sel = 1;
}
else if (!warned_about_bios) {
char *buf;
unsigned char mdir[4096];
char exename[256];
- int lic_region_detected = -1;
- int i, len, c;
+ int psxtype_from_lic = -1;
+ struct { u8 region; const char *str; } lic_strings[] = {
+ { PSX_REGION_JP, "Inc." },
+ { PSX_REGION_US, "Amer ica" },
+ { PSX_REGION_EU, "Euro pe" }
+ };
+ size_t i, len, c;
FreePPFCache();
memset(CdromLabel, 0, sizeof(CdromLabel));
memset(CdromId, 0, sizeof(CdromId));
memset(exename, 0, sizeof(exename));
+ Config.PsxRegion = PSX_REGION_US;
if (!Config.HLE && Config.SlowBoot) {
// boot to BIOS in case of CDDA or lid is open
if ((stat.Status & 0x10) || stat.Type == 2 || cdra_readTrack(time))
return 0;
}
- if (Config.PsxAuto) {
- time[0] = 0;
- time[1] = 2;
- time[2] = 4;
- READTRACK();
- if (strcmp((char *)buf + 12 + 46, "Entertainment Euro pe ") == 0)
- lic_region_detected = PSX_TYPE_PAL;
- // else it'll default to NTSC anyway
+ time[0] = 0;
+ time[1] = 2;
+ time[2] = 4;
+ READTRACK();
+ for (i = 0; i < sizeof(lic_strings) / sizeof(lic_strings[0]); i++) {
+ len = strlen(lic_strings[i].str);
+ if (strncmp((char *)buf + 12 + 60, lic_strings[i].str, len) == 0) {
+ Config.PsxRegion = lic_strings[i].region;
+ psxtype_from_lic = Config.PsxRegion == PSX_REGION_EU
+ ? PSX_TYPE_PAL : PSX_TYPE_NTSC;
+ break;
+ }
}
+ if (psxtype_from_lic < 0)
+ SysPrintf("CheckCdrom: missing lic sector?\n");
time[0] = 0;
time[1] = 2;
/* Workaround for Wild Arms EU/US which has non-standard string causing incorrect region detection */
if (exename[0] == 'E' && exename[1] == 'X' && exename[2] == 'E' && exename[3] == '\\') {
size_t offset = 4;
- size_t i, len = strlen(exename) - offset;
+ len = strlen(exename) - offset;
for (i = 0; i < len; i++)
exename[i] = exename[i + offset];
exename[i] = '\0';
strcpy(CdromId, "SLUS99999");
if (Config.PsxAuto) { // autodetect system (pal or ntsc)
- if (lic_region_detected >= 0)
- Config.PsxType = lic_region_detected;
+ if (psxtype_from_lic >= 0)
+ Config.PsxType = psxtype_from_lic;
else if (
/* Make sure Wild Arms SCUS-94608 is not detected as a PAL game. */
((CdromId[0] == 's' || CdromId[0] == 'S') && (CdromId[2] == 'e' || CdromId[2] == 'E')) ||