X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=frontend%2Flibretro.c;h=d74a7b415dccf3d72d6056c0517b19d9c7d7eccd;hb=ec92465a82173aafd1d1c529d526007ff29d3608;hp=fb7c1492718eda191ffbea5a1c616fd910ff8528;hpb=37d9bf8315be570a350cd44876ae14f9b0eff20b;p=pcsx_rearmed.git diff --git a/frontend/libretro.c b/frontend/libretro.c index fb7c1492..d74a7b41 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -27,9 +27,10 @@ #include "../libpcsxcore/cdriso.h" #include "../libpcsxcore/cheat.h" #include "../libpcsxcore/r3000a.h" +#include "../libpcsxcore/gpu.h" +#include "../libpcsxcore/database.h" #include "../plugins/dfsound/out.h" #include "../plugins/dfsound/spu_config.h" -#include "../plugins/dfinput/externals.h" #include "cspace.h" #include "main.h" #include "menu.h" @@ -80,21 +81,24 @@ static unsigned msg_interface_version = 0; static void *vout_buf; static void *vout_buf_ptr; static int vout_width, vout_height; -static int vout_doffs_old, vout_fb_dirty; +static int vout_fb_dirty; +static int psx_w, psx_h; 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 bool libretro_supports_option_categories = false; +static bool show_input_settings = true; #ifdef GPU_PEOPS -static int show_advanced_gpu_peops_settings = -1; +static bool show_advanced_gpu_peops_settings = true; #endif #ifdef GPU_UNAI -static int show_advanced_gpu_unai_settings = -1; +static bool show_advanced_gpu_unai_settings = true; #endif -static int show_other_input_settings = -1; static float mouse_sensitivity = 1.0f; +static unsigned int disk_current_index; typedef enum { @@ -141,6 +145,7 @@ int in_mouse[8][2]; int multitap1 = 0; int multitap2 = 0; int in_enable_vibration = 1; +int in_enable_crosshair[2] = { 0, 0 }; // NegCon adjustment parameters // > The NegCon 'twist' action is somewhat awkward when mapped @@ -239,6 +244,8 @@ static void vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) { vout_width = w; vout_height = h; + psx_w = raw_w; + psx_h = raw_h; if (previous_width != vout_width || previous_height != vout_height) { @@ -266,29 +273,62 @@ static void convert(void *buf, size_t bytes) } #endif -static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) +// Function to add crosshairs +static void addCrosshair(int port, int crosshair_color, unsigned short *buffer, int bufferStride, int pos_x, int pos_y, int thickness, int size_x, int size_y) { + for (port = 0; port < 2; port++) { + // Draw the horizontal line of the crosshair + for (int i = pos_y - thickness / 2; i <= pos_y + thickness / 2; i++) { + for (int j = pos_x - size_x / 2; j <= pos_x + size_x / 2; j++) { + if ((i + vout_height) >= 0 && (i + vout_height) < bufferStride && j >= 0 && j < bufferStride && in_enable_crosshair[port] > 0) + buffer[i * bufferStride + j] = crosshair_color; + } + } + + // Draw the vertical line of the crosshair + for (int i = pos_x - thickness / 2; i <= pos_x + thickness / 2; i++) { + for (int j = pos_y - size_y / 2; j <= pos_y + size_y / 2; j++) { + if (i >= 0 && i < bufferStride && (j + vout_height) >= 0 && (j + vout_height) < bufferStride && in_enable_crosshair[port] > 0) + buffer[j * bufferStride + i] = crosshair_color; + } + } + } +} + +struct CrosshairInfo { + int pos_x, pos_y, thickness, size_x, size_y; +}; + +// Calculate size and position of crosshairs +static void CrosshairDimensions(int port, struct CrosshairInfo *info) { + int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X); + int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y); + if (gunx == 32767) // Prevent crosshairs from wrapping around right side of screen to left + info->pos_x = (gunx + 32767.0f) * vout_width / 65534.0f - 0.5f; + else + info->pos_x = (gunx + 32767.0f) * vout_width / 65534.0f; + info->pos_y = (guny + 32767.0f) * vout_height / 65534.0f - vout_height; + info->thickness = pl_rearmed_cbs.gpu_neon.enhancement_enable ? 4 : 2; + info->size_x = psx_w * (pl_rearmed_cbs.gpu_neon.enhancement_enable ? 2 : 1) / 40.0f; + info->size_y = psx_h * (pl_rearmed_cbs.gpu_neon.enhancement_enable ? 2 : 1) * (4.0f / 3.0f) / 40.0f; +} + +static void vout_flip(const void *vram, int stride, int bgr24, + int x, int y, int w, int h, int dims_changed) { unsigned short *dest = vout_buf_ptr; const unsigned short *src = vram; int dstride = vout_width, h1 = h; - int doffs; + int port = 0; - if (vram == NULL) + if (vram == NULL || dims_changed || (in_enable_crosshair[0] + in_enable_crosshair[1]) > 0) { + memset(vout_buf_ptr, 0, dstride * vout_height * 2); // blanking - memset(vout_buf_ptr, 0, dstride * h * 2); - goto out; + if (vram == NULL) + goto out; } - doffs = (vout_height - h) * dstride; - doffs += (dstride - w) / 2 & ~1; - if (doffs != vout_doffs_old) - { - // clear borders - memset(vout_buf_ptr, 0, dstride * h * 2); - vout_doffs_old = doffs; - } - dest += doffs; + dest += x + y * dstride; if (bgr24) { @@ -306,6 +346,15 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) } } + for (port = 0; port < 2; port++) { + if (in_enable_crosshair[port] > 0 && (in_type[port] == PSE_PAD_TYPE_GUNCON || in_type[port] == PSE_PAD_TYPE_GUN)) + { + struct CrosshairInfo crosshairInfo; + CrosshairDimensions(port, &crosshairInfo); + addCrosshair(port, in_enable_crosshair[port], dest, dstride, crosshairInfo.pos_x, crosshairInfo.pos_y, crosshairInfo.thickness, crosshairInfo.size_x, crosshairInfo.size_y); + } + } + out: #ifndef FRONTEND_SUPPORTS_RGB565 convert(vout_buf_ptr, vout_width * vout_height * 2); @@ -492,6 +541,7 @@ struct rearmed_cbs pl_rearmed_cbs = { .pl_vout_close = vout_close, .mmap = pl_mmap, .munmap = pl_munmap, + .gpu_state_change = gpu_state_change, /* from psxcounters */ .gpu_hcnt = &hSyncCount, .gpu_frame_count = &frame_counter, @@ -500,7 +550,7 @@ struct rearmed_cbs pl_rearmed_cbs = { void pl_frame_limit(void) { /* called once per frame, make psxCpu->Execute() above return */ - stop = 1; + stop++; } void pl_timing_prepare(int is_pal) @@ -520,8 +570,41 @@ void plat_trigger_vibrate(int pad, int low, int high) } } -void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in) +//Percentage distance of screen to adjust for Konami Gun +static float KonamiGunAdjustX = 0; +static float KonamiGunAdjustY = 0; + +void pl_gun_byte2(int port, unsigned char byte) { + int irq_count = 4; + float justifier_multiplier = 0; + int justifier_width = psx_w; + int justifier_height = psx_h; + int justifier_offscreen = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN); + int justifier_reload = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD); + + if (justifier_width == 256) + justifier_multiplier = is_pal_mode ? .157086f : .158532f; + else if (justifier_width == 320) + justifier_multiplier = is_pal_mode ? .196358f : .198166f; + else if (justifier_width == 384) + justifier_multiplier = is_pal_mode ? .224409f : .226475f; + else if (justifier_width == 512) + justifier_multiplier = is_pal_mode ? .314173f : .317065f; + else // (justifier_width == 640) + justifier_multiplier = is_pal_mode ? .392717f : .396332f; + + int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X); + int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y); + + //Default offset of +105 for X and -12 for Y is chosen to obtain alignment in Die Hard Trilogy, which has no calibration feature + int gunx_scaled = ((gunx + 32767.0f) / 65534.0f + KonamiGunAdjustX) * justifier_width / justifier_multiplier + 105.0f; + int guny_scaled = ((guny + 32767.0f) / 65534.0f + KonamiGunAdjustY) * justifier_height - 12.0f; + + if ((byte & 0x10) && !justifier_offscreen && !justifier_reload) + { + psxScheduleIrq10(irq_count, gunx_scaled, guny_scaled); + } } /* sound calls */ @@ -540,25 +623,27 @@ void out_register_libretro(struct out_driver *drv) drv->feed = snd_feed; } -#define RETRO_DEVICE_PSE_STANDARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) -#define RETRO_DEVICE_PSE_ANALOG RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 0) -#define RETRO_DEVICE_PSE_DUALSHOCK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 1) -#define RETRO_DEVICE_PSE_NEGCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 2) -#define RETRO_DEVICE_PSE_GUNCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0) -#define RETRO_DEVICE_PSE_MOUSE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 0) +#define RETRO_DEVICE_PSE_STANDARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 0) +#define RETRO_DEVICE_PSE_ANALOG RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 0) +#define RETRO_DEVICE_PSE_DUALSHOCK RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 1) +#define RETRO_DEVICE_PSE_NEGCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_ANALOG, 2) +#define RETRO_DEVICE_PSE_GUNCON RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 0) +#define RETRO_DEVICE_PSE_JUSTIFIER RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 1) +#define RETRO_DEVICE_PSE_MOUSE RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 0) static char *get_pse_pad_label[] = { "none", "mouse", "negcon", "konami gun", "standard", "analog", "guncon", "dualshock" }; -static const struct retro_controller_description pads[7] = +static const struct retro_controller_description pads[8] = { - { "standard", RETRO_DEVICE_JOYPAD }, - { "analog", RETRO_DEVICE_PSE_ANALOG }, - { "dualshock", RETRO_DEVICE_PSE_DUALSHOCK }, - { "negcon", RETRO_DEVICE_PSE_NEGCON }, - { "guncon", RETRO_DEVICE_PSE_GUNCON }, - { "mouse", RETRO_DEVICE_PSE_MOUSE }, + { "standard", RETRO_DEVICE_JOYPAD }, + { "analog", RETRO_DEVICE_PSE_ANALOG }, + { "dualshock", RETRO_DEVICE_PSE_DUALSHOCK }, + { "negcon", RETRO_DEVICE_PSE_NEGCON }, + { "guncon", RETRO_DEVICE_PSE_GUNCON }, + { "konami gun", RETRO_DEVICE_PSE_JUSTIFIER }, + { "mouse", RETRO_DEVICE_PSE_MOUSE }, { NULL, 0 }, }; @@ -576,8 +661,159 @@ static const struct retro_controller_info ports[9] = }; /* libretro */ + +static bool update_option_visibility(void) +{ + struct retro_variable var = {0}; + struct retro_core_option_display option_display = {0}; + bool updated = false; + unsigned i; + + /* If frontend supports core option categories + * then show/hide core option entries are ignored + * and no options should be hidden */ + if (libretro_supports_option_categories) + return false; + + var.key = "pcsx_rearmed_show_input_settings"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool show_input_settings_prev = + show_input_settings; + + show_input_settings = true; + if (strcmp(var.value, "disabled") == 0) + show_input_settings = false; + + if (show_input_settings != + show_input_settings_prev) + { + char input_option[][50] = { + "pcsx_rearmed_analog_axis_modifier", + "pcsx_rearmed_vibration", + "pcsx_rearmed_multitap", + "pcsx_rearmed_negcon_deadzone", + "pcsx_rearmed_negcon_response", + "pcsx_rearmed_input_sensitivity", + "pcsx_rearmed_crosshair1", + "pcsx_rearmed_crosshair2", + "pcsx_rearmed_konamigunadjustx", + "pcsx_rearmed_konamigunadjusty", + "pcsx_rearmed_gunconadjustx", + "pcsx_rearmed_gunconadjusty", + "pcsx_rearmed_gunconadjustratiox", + "pcsx_rearmed_gunconadjustratioy" + }; + + option_display.visible = show_input_settings; + + for (i = 0; + i < (sizeof(input_option) / + sizeof(input_option[0])); + i++) + { + option_display.key = input_option[i]; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + + updated = true; + } + } +#ifdef GPU_PEOPS + var.key = "pcsx_rearmed_show_gpu_peops_settings"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool show_advanced_gpu_peops_settings_prev = + show_advanced_gpu_peops_settings; + + show_advanced_gpu_peops_settings = true; + if (strcmp(var.value, "disabled") == 0) + show_advanced_gpu_peops_settings = false; + + 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[][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_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 < (sizeof(gpu_peops_option) / + sizeof(gpu_peops_option[0])); + i++) + { + option_display.key = gpu_peops_option[i]; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + + updated = true; + } + } +#endif +#ifdef GPU_UNAI + var.key = "pcsx_rearmed_show_gpu_unai_settings"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool show_advanced_gpu_unai_settings_prev = + show_advanced_gpu_unai_settings; + + show_advanced_gpu_unai_settings = true; + if (strcmp(var.value, "disabled") == 0) + show_advanced_gpu_unai_settings = false; + + 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[][40] = { + "pcsx_rearmed_gpu_unai_blending", + "pcsx_rearmed_gpu_unai_lighting", + "pcsx_rearmed_gpu_unai_fast_lighting", + "pcsx_rearmed_gpu_unai_scale_hires", + }; + + option_display.visible = show_advanced_gpu_unai_settings; + + for (i = 0; + i < (sizeof(gpu_unai_option) / + sizeof(gpu_unai_option[0])); + i++) + { + option_display.key = gpu_unai_option[i]; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + + updated = true; + } + } +#endif + return updated; +} + void retro_set_environment(retro_environment_t cb) { + bool option_categories = false; #ifdef USE_LIBRETRO_VFS struct retro_vfs_interface_info vfs_iface_info; #endif @@ -588,7 +824,54 @@ void retro_set_environment(retro_environment_t cb) log_cb = logging.log; environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports); - libretro_set_core_options(environ_cb); + + /* Set core options + * An annoyance: retro_set_environment() can be called + * multiple times, and depending upon the current frontend + * state various environment callbacks may be disabled. + * This means the reported 'categories_supported' status + * may change on subsequent iterations. We therefore have + * to record whether 'categories_supported' is true on any + * iteration, and latch the result */ + libretro_set_core_options(environ_cb, &option_categories); + libretro_supports_option_categories |= option_categories; + + /* If frontend supports core option categories, + * any show/hide core option entries are unused + * and should be hidden */ + if (libretro_supports_option_categories) + { + struct retro_core_option_display option_display; + option_display.visible = false; + + option_display.key = "pcsx_rearmed_show_input_settings"; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + +#ifdef GPU_PEOPS + option_display.key = "pcsx_rearmed_show_gpu_peops_settings"; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); +#endif +#ifdef GPU_UNAI + option_display.key = "pcsx_rearmed_show_gpu_unai_settings"; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); +#endif + } + /* If frontend does not support core option + * categories, core options may be shown/hidden + * at runtime. In this case, register 'update + * display' callback, so frontend can update + * core options menu without calling retro_run() */ + else + { + struct retro_core_options_update_display_callback update_display_cb; + update_display_cb.callback = update_option_visibility; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK, + &update_display_cb); + } #ifdef USE_LIBRETRO_VFS vfs_iface_info.required_interface_version = 1; @@ -658,6 +941,9 @@ void retro_set_controller_port_device(unsigned port, unsigned device) case RETRO_DEVICE_PSE_GUNCON: in_type[port] = PSE_PAD_TYPE_GUNCON; break; + case RETRO_DEVICE_PSE_JUSTIFIER: + in_type[port] = PSE_PAD_TYPE_GUN; + break; case RETRO_DEVICE_NONE: default: in_type[port] = PSE_PAD_TYPE_NONE; @@ -675,7 +961,7 @@ void retro_get_system_info(struct retro_system_info *info) memset(info, 0, sizeof(*info)); info->library_name = "PCSX-ReARMed"; info->library_version = "r23l" GIT_VERSION; - info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u|chd"; + info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u|chd|iso|exe"; info->need_fullpath = true; } @@ -785,14 +1071,24 @@ static void save_close(void *file) bool retro_serialize(void *data, size_t size) { - int ret = SaveState(data); + int ret; + CdromFrontendId = disk_current_index; + ret = SaveState(data); return ret == 0 ? true : false; } +static bool disk_set_image_index(unsigned int index); + bool retro_unserialize(const void *data, size_t size) { - int ret = LoadState(data); - return ret == 0 ? true : false; + int ret; + CdromFrontendId = -1; + ret = LoadState(data); + if (ret) + return false; + if (CdromFrontendId != -1 && CdromFrontendId != disk_current_index) + disk_set_image_index(CdromFrontendId); + return true; } /* cheats */ @@ -803,12 +1099,13 @@ void retro_cheat_reset(void) void retro_cheat_set(unsigned index, bool enabled, const char *code) { - char buf[256]; - int ret; + int ret = -1; + char *buf; - // cheat funcs are destructive, need a copy.. - strncpy(buf, code, sizeof(buf)); - buf[sizeof(buf) - 1] = 0; + // cheat funcs are destructive, need a copy... + buf = strdup(code); + if (buf == NULL) + goto finish; //Prepare buffered cheat for PCSX's AddCheat fucntion. int cursor = 0; @@ -834,10 +1131,12 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) else ret = AddCheat("", buf); +finish: if (ret != 0) SysPrintf("Failed to set cheat %#u\n", index); else if (index < NumCheats) Cheats[index].Enabled = enabled; + free(buf); } // just in case, maybe a win-rt port in the future? @@ -855,7 +1154,6 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) 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 { @@ -1215,6 +1513,32 @@ static void set_retro_memmap(void) #endif } +static void show_notification(const char *msg_str, + unsigned duration_ms, unsigned priority) +{ + if (msg_interface_version >= 1) + { + struct retro_message_ext msg = { + msg_str, + duration_ms, + 3, + RETRO_LOG_WARN, + RETRO_MESSAGE_TARGET_ALL, + RETRO_MESSAGE_TYPE_NOTIFICATION, + -1 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg); + } + else + { + struct retro_message msg = { + msg_str, + 180 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); + } +} + static void retro_audio_buff_status_cb( bool active, unsigned occupancy, bool underrun_likely) { @@ -1276,6 +1600,8 @@ 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); + bool is_exe = (strcasestr(info->path, ".exe") != NULL); + int ret; struct retro_input_descriptor desc[] = { #define JOYP(port) \ @@ -1302,7 +1628,8 @@ bool retro_load_game(const struct retro_game_info *info) { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER, "Gun Trigger" }, \ { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD, "Gun Reload" }, \ { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A, "Gun Aux A" }, \ - { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_B, "Gun Aux B" }, + { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_B, "Gun Aux B" }, \ + { port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START, "Gun Start" }, JOYP(0) JOYP(1) @@ -1469,7 +1796,7 @@ bool retro_load_game(const struct retro_game_info *info) plugin_call_rearmed_cbs(); /* dfinput_activate(); */ - if (CheckCdrom() == -1) + if (!is_exe && CheckCdrom() == -1) { log_cb(RETRO_LOG_INFO, "unsupported/invalid CD image: %s\n", info->path); return false; @@ -1477,9 +1804,13 @@ bool retro_load_game(const struct retro_game_info *info) SysReset(); - if (LoadCdrom() == -1) + if (is_exe) + ret = Load(info->path); + else + ret = LoadCdrom(); + if (ret != 0) { - log_cb(RETRO_LOG_INFO, "could not load CD\n"); + log_cb(RETRO_LOG_INFO, "could not load %s (%d)\n", is_exe ? "exe" : "CD", ret); return false; } emu_on_new_cd(0); @@ -1487,6 +1818,9 @@ bool retro_load_game(const struct retro_game_info *info) set_retro_memmap(); retro_set_audio_buff_status_cb(); + if (check_unsatisfied_libcrypt()) + show_notification("LibCrypt protected game with missing SBI detected", 3000, 3); + return true; } @@ -1542,11 +1876,11 @@ static const unsigned short retro_psx_map[] = { }; #define RETRO_PSX_MAP_LEN (sizeof(retro_psx_map) / sizeof(retro_psx_map[0])) -//Percentage distance of screen to adjust +//Percentage distance of screen to adjust for Guncon static int GunconAdjustX = 0; static int GunconAdjustY = 0; -//Used when out by a percentage +//Used when out by a percentage with Guncon static float GunconAdjustRatioX = 1; static float GunconAdjustRatioY = 1; @@ -1554,7 +1888,10 @@ static void update_variables(bool in_flight) { struct retro_variable var; #ifdef GPU_PEOPS - int gpu_peops_fix = 0; + // Always enable GPU_PEOPS_OLD_FRAME_SKIP flag + // (this is set in standalone, with no option + // to change it) + int gpu_peops_fix = GPU_PEOPS_OLD_FRAME_SKIP; #endif frameskip_type_t prev_frameskip_type; @@ -1666,7 +2003,7 @@ static void update_variables(bool in_flight) pl_rearmed_cbs.gpu_peops.iUseDither = 0; pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 0; pl_rearmed_cbs.gpu_unai.dithering = 0; -#ifdef __ARM_NEON__ +#ifdef GPU_NEON pl_rearmed_cbs.gpu_neon.allow_dithering = 0; #endif } @@ -1675,7 +2012,7 @@ static void update_variables(bool in_flight) pl_rearmed_cbs.gpu_peops.iUseDither = 1; pl_rearmed_cbs.gpu_peopsgl.bDrawDither = 1; pl_rearmed_cbs.gpu_unai.dithering = 1; -#ifdef __ARM_NEON__ +#ifdef GPU_NEON pl_rearmed_cbs.gpu_neon.allow_dithering = 1; #endif } @@ -1683,7 +2020,7 @@ static void update_variables(bool in_flight) #ifdef GPU_NEON var.value = NULL; - var.key = "pcsx_rearmed_neon_interlace_enable"; + var.key = "pcsx_rearmed_neon_interlace_enable_v2"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { @@ -1691,6 +2028,8 @@ static void update_variables(bool in_flight) pl_rearmed_cbs.gpu_neon.allow_interlace = 0; else if (strcmp(var.value, "enabled") == 0) pl_rearmed_cbs.gpu_neon.allow_interlace = 1; + else // auto + pl_rearmed_cbs.gpu_neon.allow_interlace = 2; } var.value = NULL; @@ -1738,6 +2077,8 @@ static void update_variables(bool in_flight) display_internal_fps = true; } + // + // CPU emulation related config #ifndef DRC_DISABLE var.value = NULL; var.key = "pcsx_rearmed_drc"; @@ -1747,18 +2088,13 @@ static void update_variables(bool in_flight) { R3000Acpu *prev_cpu = psxCpu; -#if defined(LIGHTREC) - bool can_use_dynarec = found_bios; -#else - bool can_use_dynarec = 1; -#endif #ifdef _3DS if (!__ctr_svchax) Config.Cpu = CPU_INTERPRETER; else #endif - if (strcmp(var.value, "disabled") == 0 || !can_use_dynarec) + if (strcmp(var.value, "disabled") == 0) Config.Cpu = CPU_INTERPRETER; else if (strcmp(var.value, "enabled") == 0) Config.Cpu = CPU_DYNAREC; @@ -1766,54 +2102,77 @@ static void update_variables(bool in_flight) psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec; if (psxCpu != prev_cpu) { + prev_cpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL); prev_cpu->Shutdown(); psxCpu->Init(); - psxCpu->Reset(); // not really a reset.. + psxCpu->Reset(); + psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); } } #endif /* !DRC_DISABLE */ - psxCpu->ApplyConfig(); var.value = NULL; - var.key = "pcsx_rearmed_spu_reverb"; + var.key = "pcsx_rearmed_psxclock"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + int psxclock = atoi(var.value); + Config.cycle_multiplier = 10000 / psxclock; + } +#if !defined(DRC_DISABLE) && !defined(LIGHTREC) + var.value = NULL; + var.key = "pcsx_rearmed_nosmccheck"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (strcmp(var.value, "disabled") == 0) - spu_config.iUseReverb = false; - else if (strcmp(var.value, "enabled") == 0) - spu_config.iUseReverb = true; + 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_spu_interpolation"; + 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, "simple") == 0) - spu_config.iUseInterpolation = 1; - else if (strcmp(var.value, "gaussian") == 0) - spu_config.iUseInterpolation = 2; - else if (strcmp(var.value, "cubic") == 0) - spu_config.iUseInterpolation = 3; - else if (strcmp(var.value, "off") == 0) - spu_config.iUseInterpolation = 0; + if (strcmp(var.value, "enabled") == 0) + new_dynarec_hacks |= NDHACK_GTE_NO_FLAGS; + else + new_dynarec_hacks &= ~NDHACK_GTE_NO_FLAGS; } var.value = NULL; - var.key = "pcsx_rearmed_pe2_fix"; + var.key = "pcsx_rearmed_nocompathacks"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + new_dynarec_hacks |= NDHACK_NO_COMPAT_HACKS; + else + new_dynarec_hacks &= ~NDHACK_NO_COMPAT_HACKS; + } +#endif /* !DRC_DISABLE && !LIGHTREC */ + var.value = NULL; + var.key = "pcsx_rearmed_nostalls"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (strcmp(var.value, "disabled") == 0) - Config.RCntFix = 0; - else if (strcmp(var.value, "enabled") == 0) - Config.RCntFix = 1; + if (strcmp(var.value, "enabled") == 0) + Config.DisableStalls = 1; + else + Config.DisableStalls = 0; } - + var.value = NULL; var.key = "pcsx_rearmed_icache_emulation"; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "disabled") == 0) @@ -1823,38 +2182,78 @@ static void update_variables(bool in_flight) } var.value = NULL; - var.key = "pcsx_rearmed_inuyasha_fix"; + var.key = "pcsx_rearmed_exception_emulation"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + Config.PreciseExceptions = 1; + else + Config.PreciseExceptions = 0; + } + + psxCpu->ApplyConfig(); + + // end of CPU emu config + // + + var.value = NULL; + var.key = "pcsx_rearmed_spu_reverb"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "disabled") == 0) - Config.VSyncWA = 0; + spu_config.iUseReverb = false; else if (strcmp(var.value, "enabled") == 0) - Config.VSyncWA = 1; + spu_config.iUseReverb = true; } -#ifndef _WIN32 var.value = NULL; - var.key = "pcsx_rearmed_async_cd"; + var.key = "pcsx_rearmed_spu_interpolation"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (strcmp(var.value, "async") == 0) - { - Config.AsyncCD = 1; - Config.CHD_Precache = 0; - } - else if (strcmp(var.value, "sync") == 0) - { - Config.AsyncCD = 0; - Config.CHD_Precache = 0; - } - else if (strcmp(var.value, "precache") == 0) - { - Config.AsyncCD = 0; - Config.CHD_Precache = 1; - } + if (strcmp(var.value, "simple") == 0) + spu_config.iUseInterpolation = 1; + else if (strcmp(var.value, "gaussian") == 0) + spu_config.iUseInterpolation = 2; + else if (strcmp(var.value, "cubic") == 0) + spu_config.iUseInterpolation = 3; + else if (strcmp(var.value, "off") == 0) + spu_config.iUseInterpolation = 0; + } + + var.value = NULL; + var.key = "pcsx_rearmed_spu_thread"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "enabled") == 0) + spu_config.iUseThread = 1; + else + spu_config.iUseThread = 0; + } + + if (P_HAVE_PTHREAD) { + var.value = NULL; + var.key = "pcsx_rearmed_async_cd"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "async") == 0) + { + Config.AsyncCD = 1; + Config.CHD_Precache = 0; + } + else if (strcmp(var.value, "sync") == 0) + { + Config.AsyncCD = 0; + Config.CHD_Precache = 0; + } + else if (strcmp(var.value, "precache") == 0) + { + Config.AsyncCD = 0; + Config.CHD_Precache = 1; + } + } } -#endif var.value = NULL; var.key = "pcsx_rearmed_noxadecoding"; @@ -1877,13 +2276,41 @@ static void update_variables(bool in_flight) } var.value = NULL; - var.key = "pcsx_rearmed_spuirq"; + var.key = "pcsx_rearmed_gpu_slow_llists"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "disabled") == 0) - Config.SpuIrq = 0; - else - Config.SpuIrq = 1; + Config.GpuListWalking = 0; + else if (strcmp(var.value, "enabled") == 0) + Config.GpuListWalking = 1; + else // auto + Config.GpuListWalking = -1; + } + + var.value = NULL; + var.key = "pcsx_rearmed_screen_centering"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "game") == 0) + pl_rearmed_cbs.screen_centering_type = 1; + else if (strcmp(var.value, "manual") == 0) + pl_rearmed_cbs.screen_centering_type = 2; + else // auto + pl_rearmed_cbs.screen_centering_type = 0; + } + + var.value = NULL; + var.key = "pcsx_rearmed_screen_centering_x"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + pl_rearmed_cbs.screen_centering_x = atoi(var.value); + } + + var.value = NULL; + var.key = "pcsx_rearmed_screen_centering_y"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + pl_rearmed_cbs.screen_centering_y = atoi(var.value); } #ifdef THREAD_RENDERING @@ -1947,15 +2374,6 @@ static void update_variables(bool in_flight) 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"; @@ -1985,69 +2403,18 @@ static void update_variables(bool in_flight) 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; - } + /* Note: This used to be an option, but it only works + * (correctly) when running high resolution games + * (480i, 512i) and has been obsoleted by + * pcsx_rearmed_gpu_unai_scale_hires */ + pl_rearmed_cbs.gpu_unai.ilace_force = 0; + /* Note: This used to be an option, but it has no + * discernable effect and has been obsoleted by + * pcsx_rearmed_gpu_unai_scale_hires */ + pl_rearmed_cbs.gpu_unai.pixel_skip = 0; var.key = "pcsx_rearmed_gpu_unai_lighting"; var.value = NULL; @@ -2092,136 +2459,91 @@ static void update_variables(bool in_flight) else if (strcmp(var.value, "enabled") == 0) pl_rearmed_cbs.gpu_unai.scale_hires = 1; } +#endif // GPU_UNAI - var.key = "pcsx_rearmed_show_gpu_unai_settings"; var.value = NULL; + var.key = "pcsx_rearmed_crosshair1"; 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[6][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", - "pcsx_rearmed_gpu_unai_scale_hires", - }; - - option_display.visible = show_advanced_gpu_unai_settings; - - for (i = 0; i < 6; i++) - { - option_display.key = gpu_unai_option[i]; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - } - } + in_enable_crosshair[0] = 0; + else if (strcmp(var.value, "blue") == 0) + in_enable_crosshair[0] = 0x1F; + else if (strcmp(var.value, "green") == 0) + in_enable_crosshair[0] = 0x7E0; + else if (strcmp(var.value, "red") == 0) + in_enable_crosshair[0] = 0xF800; + else if (strcmp(var.value, "white") == 0) + in_enable_crosshair[0] = 0xFFFF; } -#endif // GPU_UNAI - - //This adjustment process gives the user the ability to manually align the mouse up better - //with where the shots are in the emulator. var.value = NULL; - var.key = "pcsx_rearmed_gunconadjustx"; + var.key = "pcsx_rearmed_crosshair2"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - GunconAdjustX = atoi(var.value); + if (strcmp(var.value, "disabled") == 0) + in_enable_crosshair[1] = 0; + else if (strcmp(var.value, "blue") == 0) + in_enable_crosshair[1] = 0x1F; + else if (strcmp(var.value, "green") == 0) + in_enable_crosshair[1] = 0x7E0; + else if (strcmp(var.value, "red") == 0) + in_enable_crosshair[1] = 0xF800; + else if (strcmp(var.value, "white") == 0) + in_enable_crosshair[1] = 0xFFFF; } + //This adjustment process gives the user the ability to manually align the mouse up better + //with where the shots are in the emulator. + var.value = NULL; - var.key = "pcsx_rearmed_gunconadjusty"; + var.key = "pcsx_rearmed_konamigunadjustx"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - GunconAdjustY = atoi(var.value); + KonamiGunAdjustX = atof(var.value) / 100.0f; } var.value = NULL; - var.key = "pcsx_rearmed_gunconadjustratiox"; + var.key = "pcsx_rearmed_konamigunadjusty"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - GunconAdjustRatioX = atof(var.value); + KonamiGunAdjustY = atof(var.value) / 100.0f; } var.value = NULL; - var.key = "pcsx_rearmed_gunconadjustratioy"; + var.key = "pcsx_rearmed_gunconadjustx"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - GunconAdjustRatioY = atof(var.value); + GunconAdjustX = atoi(var.value); } -#if !defined(DRC_DISABLE) && !defined(LIGHTREC) 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.key = "pcsx_rearmed_gunconadjusty"; - 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; + GunconAdjustY = atoi(var.value); } 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; - } + var.key = "pcsx_rearmed_gunconadjustratiox"; - /* this probably is safe to change in real-time */ - var.value = NULL; - var.key = "pcsx_rearmed_psxclock"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - int psxclock = atoi(var.value); - cycle_multiplier = 10000 / psxclock; + GunconAdjustRatioX = atof(var.value); } var.value = NULL; - var.key = "pcsx_rearmed_nocompathacks"; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - if (strcmp(var.value, "enabled") == 0) - new_dynarec_hacks |= NDHACK_NO_COMPAT_HACKS; - else - new_dynarec_hacks &= ~NDHACK_NO_COMPAT_HACKS; - } -#endif /* !DRC_DISABLE && !LIGHTREC */ + var.key = "pcsx_rearmed_gunconadjustratioy"; - var.value = NULL; - var.key = "pcsx_rearmed_nostalls"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (strcmp(var.value, "enabled") == 0) - Config.DisableStalls = 1; - else - Config.DisableStalls = 0; + GunconAdjustRatioY = atof(var.value); } var.value = NULL; @@ -2231,42 +2553,6 @@ static void update_variables(bool in_flight) mouse_sensitivity = atof(var.value); } - var.key = "pcsx_rearmed_show_other_input_settings"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - int previous_settings = show_other_input_settings; - - show_other_input_settings = 1; - if (strcmp(var.value, "disabled") == 0) - show_other_input_settings = 0; - - if (show_other_input_settings != previous_settings) - { - unsigned i; - struct retro_core_option_display option_display; - char gpu_peops_option[][50] = { - "pcsx_rearmed_negcon_deadzone", - "pcsx_rearmed_negcon_response", - "pcsx_rearmed_analog_axis_modifier", - "pcsx_rearmed_gunconadjustx", - "pcsx_rearmed_gunconadjusty", - "pcsx_rearmed_gunconadjustratiox", - "pcsx_rearmed_gunconadjustratioy" - }; - #define INPUT_LIST (sizeof(gpu_peops_option) / sizeof(gpu_peops_option[0])) - - option_display.visible = show_other_input_settings; - - for (i = 0; i < INPUT_LIST; i++) - { - option_display.key = gpu_peops_option[i]; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - } - } - } - if (in_flight) { // inform core things about possible config changes @@ -2305,6 +2591,8 @@ static void update_variables(bool in_flight) } } } + + update_option_visibility(); } // Taken from beetle-psx-libretro @@ -2361,25 +2649,26 @@ unsigned char axis_range_modifier(int16_t axis_value, bool is_square) static void update_input_guncon(int port, int ret) { //ToDo: - //Core option for cursors for both players //Separate pointer and lightgun control types //Mouse range is -32767 -> 32767 //1% is about 655 //Use the left analog stick field to store the absolute coordinates - //Fix cursor to top-left when gun is detected as "offscreen" + + int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X); + int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y); + + //Have the Libretro API let /libpcsxcore/plugins.c know when the lightgun is pointed offscreen + //Offscreen value is chosen to be well out of range of any possible scaling done via core options if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN) || input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD)) { - in_analog_left[port][0] = -32767; - in_analog_left[port][1] = -32767; + in_analog_left[port][0] = 65536; + in_analog_left[port][1] = 65536; } else { - int gunx = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X); - int guny = input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y); - - in_analog_left[port][0] = (gunx * GunconAdjustRatioX) + (GunconAdjustX * 655); - in_analog_left[port][1] = (guny * GunconAdjustRatioY) + (GunconAdjustY * 655); + in_analog_left[port][0] = ((gunx * GunconAdjustRatioX) + (GunconAdjustX * 655)) / 64 + 512; + in_analog_left[port][1] = ((guny * GunconAdjustRatioY) + (GunconAdjustY * 655)) / 64 + 512; } //GUNCON has 3 controls, Trigger,A,B which equal Circle,Start,Cross @@ -2398,6 +2687,29 @@ static void update_input_guncon(int port, int ret) } +static void update_input_justifier(int port, int ret) +{ + //ToDo: + //Separate pointer and lightgun control types + + //RetroArch lightgun range is -32767 -> 32767 on both axes (positive Y is down) + + //JUSTIFIER has 3 controls, Trigger,Special,Start which equal Square,Cross,Start + + // Trigger + if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_TRIGGER) || input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_RELOAD)) + in_keystate[port] |= (1 << DKEY_SQUARE); + + // Special + if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_AUX_A)) + in_keystate[port] |= (1 << DKEY_CROSS); + + // Start + if (input_state_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_START)) + in_keystate[port] |= (1 << DKEY_START); + +} + static void update_input_negcon(int port, int ret) { int lsx; @@ -2566,6 +2878,9 @@ static void update_input(void) case PSE_PAD_TYPE_GUNCON: update_input_guncon(i, ret); break; + case PSE_PAD_TYPE_GUN: + update_input_justifier(i, ret); + break; case PSE_PAD_TYPE_NEGCON: update_input_negcon(i, ret); break; @@ -2642,12 +2957,8 @@ void retro_run(void) { rebootemu = 0; SysReset(); - if (!Config.HLE && !Config.SlowBoot) - { - // skip BIOS logos - psxRegs.pc = psxRegs.GPR.n.ra; - } - return; + if (Config.HLE) + LoadCdrom(); } print_internal_fps(); @@ -2717,7 +3028,7 @@ void retro_run(void) set_vout_fb(); } -static bool try_use_bios(const char *path) +static bool try_use_bios(const char *path, bool preferred_only) { long size; const char *name; @@ -2729,12 +3040,20 @@ static bool try_use_bios(const char *path) size = ftell(fp); fclose(fp); - if (size != 512 * 1024) - return false; - name = strrchr(path, SLASH); if (name++ == NULL) name = path; + + if (preferred_only && size != 512 * 1024) + return false; + if (size != 512 * 1024 && size != 4 * 1024 * 1024) + 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; + snprintf(Config.Bios, sizeof(Config.Bios), "%s", name); return true; } @@ -2745,24 +3064,50 @@ static bool try_use_bios(const char *path) static bool 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; + // try to find a "better" bios while ((ent = readdir(dir))) { - if ((strncasecmp(ent->d_name, "scph", 4) != 0) && (strncasecmp(ent->d_name, "psx", 3) != 0)) - continue; + for (i = 0; i < sizeof(substr_pref) / sizeof(substr_pref[0]); i++) + { + const char *substr = substr_pref[i]; + 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) + goto finish; + } + } - snprintf(path, path_size, "%s%c%s", dirpath, SLASH, ent->d_name); - ret = try_use_bios(path); - if (ret) - break; + // another pass to look for anything fitting, even ps2 bios + rewinddir(dir); + while ((ent = readdir(dir))) + { + for (i = 0; i < sizeof(substr_alt) / sizeof(substr_alt[0]); i++) + { + const char *substr = substr_alt[i]; + 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) + goto finish; + } } + + +finish: closedir(dir); return ret; } @@ -2859,7 +3204,7 @@ static void loadPSXBios(void) 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); + found_bios = try_use_bios(path, true); if (found_bios) break; } @@ -2876,38 +3221,21 @@ static void loadPSXBios(void) if (!found_bios) { const char *msg_str; + unsigned duration; if (useHLE) { - msg_str = "BIOS set to \'hle\' in core options - real BIOS will be ignored"; + msg_str = "BIOS set to \'hle\'"; SysPrintf("Using HLE BIOS.\n"); + // shorter as the user probably intentionally wants to use HLE + duration = 700; } else { msg_str = "No PlayStation BIOS file found - add for better compatibility"; SysPrintf("No BIOS files found.\n"); + duration = 3000; } - - if (msg_interface_version >= 1) - { - struct retro_message_ext msg = { - msg_str, - 3000, - 3, - RETRO_LOG_WARN, - RETRO_MESSAGE_TARGET_ALL, - RETRO_MESSAGE_TYPE_NOTIFICATION, - -1 - }; - environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg); - } - else - { - struct retro_message msg = { - msg_str, - 180 - }; - environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); - } + show_notification(msg_str, duration, 2); } } @@ -2952,7 +3280,7 @@ void retro_init(void) #ifdef _3DS vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80); -#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && !defined(VITA) && !defined(__SWITCH__) +#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && P_HAVE_POSIX_MEMALIGN if (posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2) != 0) vout_buf = (void *) 0; #else @@ -2979,13 +3307,12 @@ void retro_init(void) /* Set how much slower PSX CPU runs * 100 (so that 200 is 2 times) * we have to do this because cache misses and some IO penalties * are not emulated. Warning: changing this may break compatibility. */ - cycle_multiplier = 175; + Config.cycle_multiplier = CYCLE_MULT_DEFAULT; #if defined(HAVE_PRE_ARMV7) && !defined(_3DS) - cycle_multiplier = 200; + Config.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.read = save_read; @@ -3018,6 +3345,15 @@ void retro_deinit(void) deinit_vita_mmap(); #endif libretro_supports_bitmasks = false; + libretro_supports_option_categories = false; + + show_input_settings = true; +#ifdef GPU_PEOPS + show_advanced_gpu_peops_settings = true; +#endif +#ifdef GPU_UNAI + show_advanced_gpu_unai_settings = true; +#endif /* Have to reset disks struct, otherwise * fnames/flabels will leak memory */ @@ -3067,3 +3403,5 @@ void SysDLog(const char *fmt, ...) if (log_cb) log_cb(RETRO_LOG_DEBUG, "%s", msg); } + +// vim:sw=3:ts=3:expandtab