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
Cheats[index].Enabled = enabled;
}
+// just in case, maybe a win-rt port in the future?
+#ifdef _WIN32
+#define SLASH '\\'
+#else
+#define SLASH '/'
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
/* multidisk support */
+static unsigned int disk_initial_index;
+static char disk_initial_path[PATH_MAX];
static bool disk_ejected;
static unsigned int disk_current_index;
static unsigned int disk_count;
static struct disks_state {
char *fname;
+ char *flabel;
int internal_index; // for multidisk eboots
} disks[8];
+static void get_disk_label(char *disk_label, const char *disk_path, size_t len)
+{
+ const char *base = NULL;
+
+ if (!disk_path || (*disk_path == '\0'))
+ return;
+
+ base = strrchr(disk_path, SLASH);
+ if (!base)
+ base = disk_path;
+
+ if (*base == SLASH)
+ base++;
+
+ strncpy(disk_label, base, len - 1);
+ disk_label[len - 1] = '\0';
+
+ char *ext = strrchr(disk_label, '.');
+ if (ext)
+ *ext = '\0';
+}
+
+static void disk_init(void)
+{
+ size_t i;
+
+ disk_ejected = false;
+ disk_current_index = 0;
+ disk_count = 0;
+
+ for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) {
+ if (disks[i].fname != NULL) {
+ free(disks[i].fname);
+ disks[i].fname = NULL;
+ }
+ if (disks[i].flabel != NULL) {
+ free(disks[i].flabel);
+ disks[i].flabel = NULL;
+ }
+ disks[i].internal_index = 0;
+ }
+}
+
static bool disk_set_eject_state(bool ejected)
{
// weird PCSX API..
static bool disk_replace_image_index(unsigned index,
const struct retro_game_info *info)
{
- char *old_fname;
- bool ret = true;
+ char *old_fname = NULL;
+ char *old_flabel = NULL;
+ bool ret = true;
if (index >= sizeof(disks) / sizeof(disks[0]))
return false;
- old_fname = disks[index].fname;
- disks[index].fname = NULL;
+ old_fname = disks[index].fname;
+ old_flabel = disks[index].flabel;
+
+ disks[index].fname = NULL;
+ disks[index].flabel = NULL;
disks[index].internal_index = 0;
if (info != NULL) {
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
disks[index].fname = strdup(info->path);
+
+ get_disk_label(disk_label, info->path, PATH_MAX);
+ disks[index].flabel = strdup(disk_label);
+
if (index == disk_current_index)
ret = disk_set_image_index(index);
}
if (old_fname != NULL)
free(old_fname);
+ if (old_flabel != NULL)
+ free(old_flabel);
+
return ret;
}
return true;
}
+static bool disk_set_initial_image(unsigned index, const char *path)
+{
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ if (!path || (*path == '\0'))
+ return false;
+
+ disk_initial_index = index;
+
+ strncpy(disk_initial_path, path, sizeof(disk_initial_path) - 1);
+ disk_initial_path[sizeof(disk_initial_path) - 1] = '\0';
+
+ return true;
+}
+
+static bool disk_get_image_path(unsigned index, char *path, size_t len)
+{
+ const char *fname = NULL;
+
+ if (len < 1)
+ return false;
+
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ fname = disks[index].fname;
+
+ if (!fname || (*fname == '\0'))
+ return false;
+
+ strncpy(path, fname, len - 1);
+ path[len - 1] = '\0';
+
+ return true;
+}
+
+static bool disk_get_image_label(unsigned index, char *label, size_t len)
+{
+ const char *flabel = NULL;
+
+ if (len < 1)
+ return false;
+
+ if (index >= sizeof(disks) / sizeof(disks[0]))
+ return false;
+
+ flabel = disks[index].flabel;
+
+ if (!flabel || (*flabel == '\0'))
+ return false;
+
+ strncpy(label, flabel, len - 1);
+ label[len - 1] = '\0';
+
+ return true;
+}
+
static struct retro_disk_control_callback disk_control = {
.set_eject_state = disk_set_eject_state,
.get_eject_state = disk_get_eject_state,
.add_image_index = disk_add_image_index,
};
-// just in case, maybe a win-rt port in the future?
-#ifdef _WIN32
-#define SLASH '\\'
-#else
-#define SLASH '/'
-#endif
-
-#ifndef PATH_MAX
-#define PATH_MAX 4096
-#endif
+static struct retro_disk_control_ext_callback disk_control_ext = {
+ .set_eject_state = disk_set_eject_state,
+ .get_eject_state = disk_get_eject_state,
+ .get_image_index = disk_get_image_index,
+ .set_image_index = disk_set_image_index,
+ .get_num_images = disk_get_num_images,
+ .replace_image_index = disk_replace_image_index,
+ .add_image_index = disk_add_image_index,
+ .set_initial_image = disk_set_initial_image,
+ .get_image_path = disk_get_image_path,
+ .get_image_label = disk_get_image_label,
+};
static char base_dir[1024];
if (line[0] != '\0')
{
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
snprintf(name, sizeof(name), "%s%c%s", base_dir, SLASH, line);
- disks[disk_count++].fname = strdup(name);
+ disks[disk_count].fname = strdup(name);
+
+ get_disk_label(disk_label, name, PATH_MAX);
+ disks[disk_count].flabel = strdup(disk_label);
+
+ disk_count++;
}
}
}
#endif
+static void set_retro_memmap(void)
+{
+ struct retro_memory_map retromap = { 0 };
+ struct retro_memory_descriptor mmap =
+ {
+ 0, psxM, 0, 0, 0, 0, 0x200000
+ };
+
+ retromap.descriptors = &mmap;
+ retromap.num_descriptors = 1;
+
+ environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap);
+}
+
bool retro_load_game(const struct retro_game_info *info)
{
size_t i;
+ unsigned int cd_index = 0;
bool is_m3u = (strcasestr(info->path, ".m3u") != NULL);
struct retro_input_descriptor desc[] = {
plugins_opened = 0;
}
- for (i = 0; i < sizeof(disks) / sizeof(disks[0]); i++) {
- if (disks[i].fname != NULL) {
- free(disks[i].fname);
- disks[i].fname = NULL;
- }
- disks[i].internal_index = 0;
- }
+ disk_init();
- disk_current_index = 0;
extract_directory(base_dir, info->path, sizeof(base_dir));
if (is_m3u) {
return false;
}
} else {
+ char disk_label[PATH_MAX];
+ disk_label[0] = '\0';
+
disk_count = 1;
disks[0].fname = strdup(info->path);
+
+ get_disk_label(disk_label, info->path, PATH_MAX);
+ disks[0].flabel = strdup(disk_label);
}
- set_cd_image(disks[0].fname);
+ /* If this is an M3U file, attempt to set the
+ * initial disk image */
+ if (is_m3u &&
+ (disk_initial_index > 0) &&
+ (disk_initial_index < disk_count)) {
+ const char *fname = disks[disk_initial_index].fname;
+
+ if (fname && (*fname != '\0'))
+ if (strcmp(disk_initial_path, fname) == 0)
+ cd_index = disk_initial_index;
+ }
+
+ set_cd_image(disks[cd_index].fname);
+ disk_current_index = cd_index;
/* have to reload after set_cd_image for correct cdr plugin */
if (LoadPlugins() == -1) {
return false;
}
+ /* Handle multi-disk images (i.e. PBP)
+ * > Cannot do this until after OpenPlugins() is
+ * called (since this sets the value of
+ * cdrIsoMultidiskCount) */
+ if (!is_m3u && (cdrIsoMultidiskCount > 1)) {
+ disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8;
+
+ /* Small annoyance: We need to change the label
+ * of disk 0, so have to clear existing entries */
+ if (disks[0].fname != NULL)
+ free(disks[0].fname);
+ disks[0].fname = NULL;
+
+ if (disks[0].flabel != NULL)
+ free(disks[0].flabel);
+ disks[0].flabel = NULL;
+
+ for (i = 0; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) {
+ char disk_name[PATH_MAX];
+ char disk_label[PATH_MAX];
+ disk_name[0] = '\0';
+ disk_label[0] = '\0';
+
+ disks[i].fname = strdup(info->path);
+
+ get_disk_label(disk_name, info->path, PATH_MAX);
+ snprintf(disk_label, sizeof(disk_label), "%s #%u", disk_name, (unsigned)i + 1);
+ disks[i].flabel = strdup(disk_label);
+
+ disks[i].internal_index = i;
+ }
+
+ /* This is not an M3U file, so initial disk
+ * image has not yet been set - attempt to
+ * do so now */
+ if ((disk_initial_index > 0) &&
+ (disk_initial_index < disk_count)) {
+ const char *fname = disks[disk_initial_index].fname;
+
+ if (fname && (*fname != '\0'))
+ if (strcmp(disk_initial_path, fname) == 0)
+ cd_index = disk_initial_index;
+ }
+
+ if (cd_index > 0) {
+ CdromId[0] = '\0';
+ CdromLabel[0] = '\0';
+
+ cdrIsoMultidiskSelect = disks[cd_index].internal_index;
+ disk_current_index = cd_index;
+ set_cd_image(disks[cd_index].fname);
+
+ if (ReloadCdromPlugin() < 0) {
+ log_cb(RETRO_LOG_INFO, "failed to reload cdr plugins\n");
+ return false;
+ }
+ if (CDR_open() < 0) {
+ log_cb(RETRO_LOG_INFO, "failed to open cdr plugin\n");
+ return false;
+ }
+ }
+ }
+
plugin_call_rearmed_cbs();
dfinput_activate();
}
emu_on_new_cd(0);
- // multidisk images
- if (!is_m3u) {
- disk_count = cdrIsoMultidiskCount < 8 ? cdrIsoMultidiskCount : 8;
- for (i = 1; i < sizeof(disks) / sizeof(disks[0]) && i < cdrIsoMultidiskCount; i++) {
- disks[i].fname = strdup(info->path);
- disks[i].internal_index = i;
- }
- }
+ set_retro_memmap();
return true;
}
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 (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
// > NeGcon 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++)
void retro_init(void)
{
+ unsigned dci_version = 0;
struct retro_rumble_interface rumble;
int ret;
loadPSXBios();
environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe);
- environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
+
+ disk_initial_index = 0;
+ disk_initial_path[0] = '\0';
+ if (environ_cb(RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION, &dci_version) && (dci_version >= 1))
+ environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE, &disk_control_ext);
+ else
+ environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
rumble_cb = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble))
deinit_vita_mmap();
#endif
libretro_supports_bitmasks = false;
+
+ /* Have to reset disks struct, otherwise
+ * fnames/flabels will leak memory */
+ disk_init();
}
#ifdef VITA