X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=frontend%2Flibretro.c;h=59f1201509e764822c59b5ba5510880cbf9712fd;hb=138b161a28538ed55f1d2b721670095236bec411;hp=47b08c7ee0056e4029136a62dbc6adb16bace55e;hpb=8822aea7b69508c7ce2be72607657248d38771c1;p=pcsx_rearmed.git diff --git a/frontend/libretro.c b/frontend/libretro.c index 47b08c7e..59f12015 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -59,18 +59,6 @@ #define INTERNAL_FPS_SAMPLE_PERIOD 64 -#ifdef DRC_DISABLE -int stop; -u32 next_interupt; -u32 event_cycles[PSXINT_COUNT]; -int cycle_multiplier; -int new_dynarec_hacks; - -void new_dyna_before_save(void) {} -void new_dyna_after_save(void) {} -void new_dyna_freeze(void *f, int i) {} -#endif - //hack to prevent retroarch freezing when reseting in the menu but not while running with the hot key static int rebootemu = 0; @@ -83,6 +71,8 @@ static retro_set_rumble_state_t rumble_cb; static struct retro_log_callback logging; static retro_log_printf_t log_cb; +static unsigned msg_interface_version = 0; + static void *vout_buf; static void *vout_buf_ptr; static int vout_width, vout_height; @@ -100,6 +90,7 @@ static int show_advanced_gpu_peops_settings = -1; static int show_advanced_gpu_unai_settings = -1; #endif static int show_other_input_settings = -1; +static float mouse_sensitivity = 1.0f; static unsigned previous_width = 0; static unsigned previous_height = 0; @@ -122,9 +113,11 @@ int in_type[8] = { int in_analog_left[8][2] = { { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 } }; int in_analog_right[8][2] = { { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 }, { 127, 127 } }; unsigned short in_keystate[PORTS_NUMBER]; +int in_mouse[8][2]; int multitap1 = 0; int multitap2 = 0; int in_enable_vibration = 1; +static int input_changed = 0; // NegCon adjustment parameters // > The NegCon 'twist' action is somewhat awkward when mapped @@ -524,6 +517,41 @@ 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) + +static char *get_pse_pad_label[] = { + "none", "mouse", "negcon", "konami gun", "standard", "analog", "guncon", "dualshock" +}; + +static const struct retro_controller_description pads[7] = +{ + { "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 }, + { NULL, 0 }, +}; + +static const struct retro_controller_info ports[9] = +{ + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { pads, 7 }, + { NULL, 0 }, +}; + /* libretro */ void retro_set_environment(retro_environment_t cb) { @@ -532,6 +560,7 @@ void retro_set_environment(retro_environment_t cb) if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging)) log_cb = logging.log; + environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports); libretro_set_core_options(environ_cb); } @@ -546,105 +575,7 @@ unsigned retro_api_version(void) return RETRO_API_VERSION; } -static int controller_port_variable(unsigned port, struct retro_variable *var) -{ - if (port >= PORTS_NUMBER) - return 0; - - if (!environ_cb) - return 0; - - var->value = NULL; - switch (port) - { - case 0: - var->key = "pcsx_rearmed_pad1type"; - break; - case 1: - var->key = "pcsx_rearmed_pad2type"; - break; - case 2: - var->key = "pcsx_rearmed_pad3type"; - break; - case 3: - var->key = "pcsx_rearmed_pad4type"; - break; - case 4: - var->key = "pcsx_rearmed_pad5type"; - break; - case 5: - var->key = "pcsx_rearmed_pad6type"; - break; - case 6: - var->key = "pcsx_rearmed_pad7type"; - break; - case 7: - var->key = "pcsx_rearmed_pad8type"; - break; - } - - return environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, var) && var->value; -} - -static void update_controller_port_variable(unsigned port) -{ - if (port >= PORTS_NUMBER) - return; - - struct retro_variable var; - - if (controller_port_variable(port, &var)) - { - if (strcmp(var.value, "standard") == 0) - in_type[port] = PSE_PAD_TYPE_STANDARD; - else if (strcmp(var.value, "analog") == 0) - in_type[port] = PSE_PAD_TYPE_ANALOGJOY; - else if (strcmp(var.value, "dualshock") == 0) - 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 - } -} - -static void update_controller_port_device(unsigned port, unsigned device) -{ - if (port >= PORTS_NUMBER) - return; - - struct retro_variable var; - - if (!controller_port_variable(port, &var)) - return; - - if (strcmp(var.value, "default") != 0) - return; - - switch (device) - { - case RETRO_DEVICE_JOYPAD: - in_type[port] = PSE_PAD_TYPE_STANDARD; - break; - case RETRO_DEVICE_ANALOG: - in_type[port] = PSE_PAD_TYPE_ANALOGPAD; - break; - case RETRO_DEVICE_MOUSE: - in_type[port] = PSE_PAD_TYPE_MOUSE; - break; - case RETRO_DEVICE_LIGHTGUN: - in_type[port] = PSE_PAD_TYPE_GUN; - break; - case RETRO_DEVICE_NONE: - default: - in_type[port] = PSE_PAD_TYPE_NONE; - } -} - -static void update_multitap() +static void update_multitap(void) { struct retro_variable var; int auto_case, port; @@ -658,11 +589,11 @@ static void update_multitap() multitap1 = 1; else if (strcmp(var.value, "disabled") == 0) multitap1 = 0; - else // 'auto' case + else if (strcmp(var.value, "automatic") == 0) auto_case = 1; } else - auto_case = 1; + multitap1 = 0; if (auto_case) { @@ -681,11 +612,11 @@ static void update_multitap() multitap2 = 1; else if (strcmp(var.value, "disabled") == 0) multitap2 = 0; - else // 'auto' case + else if (strcmp(var.value, "automatic") == 0) auto_case = 1; } else - auto_case = 1; + multitap2 = 0; if (auto_case) { @@ -698,13 +629,37 @@ static void update_multitap() void retro_set_controller_port_device(unsigned port, unsigned device) { - SysPrintf("port %u device %u", port, device); - if (port >= PORTS_NUMBER) return; - update_controller_port_device(port, device); - update_multitap(); + switch (device) + { + case RETRO_DEVICE_JOYPAD: + case RETRO_DEVICE_PSE_STANDARD: + in_type[port] = PSE_PAD_TYPE_STANDARD; + break; + case RETRO_DEVICE_PSE_ANALOG: + in_type[port] = PSE_PAD_TYPE_ANALOGJOY; + break; + case RETRO_DEVICE_PSE_DUALSHOCK: + in_type[port] = PSE_PAD_TYPE_ANALOGPAD; + break; + case RETRO_DEVICE_PSE_MOUSE: + in_type[port] = PSE_PAD_TYPE_MOUSE; + break; + case RETRO_DEVICE_PSE_NEGCON: + in_type[port] = PSE_PAD_TYPE_NEGCON; + break; + case RETRO_DEVICE_PSE_GUNCON: + in_type[port] = PSE_PAD_TYPE_GUNCON; + break; + case RETRO_DEVICE_NONE: + default: + in_type[port] = PSE_PAD_TYPE_NONE; + break; + } + + SysPrintf("port: %u device: %s\n", port + 1, get_pse_pad_label[in_type[port]]); } void retro_get_system_info(struct retro_system_info *info) @@ -1242,6 +1197,7 @@ strcasestr(const char *s, const char *find) static void set_retro_memmap(void) { +#ifndef NDEBUG struct retro_memory_map retromap = { 0 }; struct retro_memory_descriptor mmap = { 0, psxM, 0, 0, 0, 0, 0x200000 @@ -1251,6 +1207,7 @@ static void set_retro_memmap(void) retromap.num_descriptors = 1; environ_cb(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, &retromap); +#endif } static void update_variables(bool in_flight); @@ -1444,7 +1401,7 @@ bool retro_load_game(const struct retro_game_info *info) } plugin_call_rearmed_cbs(); - dfinput_activate(); + /* dfinput_activate(); */ if (CheckCdrom() == -1) { @@ -1463,6 +1420,8 @@ bool retro_load_game(const struct retro_game_info *info) set_retro_memmap(); + input_changed = 1; + return true; } @@ -1529,7 +1488,6 @@ static float GunconAdjustRatioY = 1; static void update_variables(bool in_flight) { struct retro_variable var; - int i; #ifdef GPU_PEOPS int gpu_peops_fix = 0; #endif @@ -1552,8 +1510,8 @@ static void update_variables(bool in_flight) Config.PsxType = 1; } - for (i = 0; i < PORTS_NUMBER; i++) - update_controller_port_variable(i); + /*for (i = 0; i < PORTS_NUMBER; i++) + update_controller_port_variable(i);*/ update_multitap(); @@ -1786,9 +1744,20 @@ static void update_variables(bool in_flight) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (strcmp(var.value, "async") == 0) + { Config.AsyncCD = 1; - else + 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 @@ -1822,6 +1791,21 @@ static void update_variables(bool in_flight) Config.SpuIrq = 1; } +#ifdef THREAD_RENDERING + var.key = "pcsx_rearmed_gpu_thread_rendering"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.thread_rendering = THREAD_RENDERING_OFF; + else if (strcmp(var.value, "sync") == 0) + pl_rearmed_cbs.thread_rendering = THREAD_RENDERING_SYNC; + else if (strcmp(var.value, "async") == 0) + pl_rearmed_cbs.thread_rendering = THREAD_RENDERING_ASYNC; + } +#endif + #ifdef GPU_PEOPS var.value = NULL; var.key = "pcsx_rearmed_gpu_peops_odd_even_bit"; @@ -2003,6 +1987,17 @@ static void update_variables(bool in_flight) pl_rearmed_cbs.gpu_unai.blending = 1; } + var.key = "pcsx_rearmed_gpu_unai_scale_hires"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.gpu_unai.scale_hires = 0; + else if (strcmp(var.value, "enabled") == 0) + pl_rearmed_cbs.gpu_unai.scale_hires = 1; + } + var.key = "pcsx_rearmed_show_gpu_unai_settings"; var.value = NULL; @@ -2018,17 +2013,18 @@ static void update_variables(bool in_flight) { unsigned i; struct retro_core_option_display option_display; - char gpu_unai_option[5][40] = { + 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_pixel_skip", + "pcsx_rearmed_gpu_unai_scale_hires", }; option_display.visible = show_advanced_gpu_unai_settings; - for (i = 0; i < 5; i++) + for (i = 0; i < 6; i++) { option_display.key = gpu_unai_option[i]; environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); @@ -2113,6 +2109,13 @@ static void update_variables(bool in_flight) } #endif /* NEW_DYNAREC */ + var.value = NULL; + var.key = "pcsx_rearmed_input_sensitivity"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + mouse_sensitivity = atof(var.value); + } + var.key = "pcsx_rearmed_show_other_input_settings"; var.value = NULL; @@ -2129,14 +2132,6 @@ static void update_variables(bool in_flight) unsigned i; struct retro_core_option_display option_display; char gpu_peops_option[][50] = { - "pcsx_rearmed_multitap1", - "pcsx_rearmed_multitap2", - "pcsx_rearmed_pad3type", - "pcsx_rearmed_pad4type", - "pcsx_rearmed_pad5type", - "pcsx_rearmed_pad6type", - "pcsx_rearmed_pad7type", - "pcsx_rearmed_pad8type", "pcsx_rearmed_negcon_deadzone", "pcsx_rearmed_negcon_response", "pcsx_rearmed_analog_axis_modifier", @@ -2168,7 +2163,7 @@ static void update_variables(bool in_flight) GPU_open(&gpuDisp, "PCSX", NULL); } - dfinput_activate(); + /* dfinput_activate(); */ } else { @@ -2244,74 +2239,204 @@ unsigned char axis_range_modifier(int16_t axis_value, bool is_square) return modifier_axis_range; } -void retro_run(void) +static void update_input_guncon(int port, int ret) { - int i; - //SysReset must be run while core is running,Not in menu (Locks up Retroarch) - if (rebootemu != 0) + //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 + + //GUNCON has 3 controls, Trigger,A,B which equal Circle,Start,Cross + + // Trigger + //The 1 is hardcoded instead of port to prevent the overlay mouse button libretro crash bug + if (input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)) { - rebootemu = 0; - SysReset(); - if (!Config.HLE && !Config.SlowBoot) - { - // skip BIOS logos - psxRegs.pc = psxRegs.GPR.n.ra; - } + in_keystate[port] |= (1 << DKEY_CIRCLE); } - if (display_internal_fps) + // A + if (input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)) { - frame_count++; + in_keystate[port] |= (1 << DKEY_START); + } - 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 - }; + // B + if (input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)) + { + in_keystate[port] |= (1 << DKEY_CROSS); + } - str[0] = '\0'; + int gunx = input_state_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X); + int guny = input_state_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y); - snprintf(str, sizeof(str), "Internal FPS: %2d", internal_fps); + //Mouse range is -32767 -> 32767 + //1% is about 655 + //Use the left analog stick field to store the absolute coordinates + in_analog_left[port][0] = (gunx * GunconAdjustRatioX) + (GunconAdjustX * 655); + in_analog_left[port][1] = (guny * GunconAdjustRatioY) + (GunconAdjustY * 655); +} - pl_rearmed_cbs.flip_cnt = 0; +static void update_input_negcon(int port, int ret) +{ + int lsx; + int rsy; + int negcon_i_rs; + int negcon_ii_rs; + float negcon_twist_amplitude; - environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); - } + // Query digital inputs + // + // > Pad-Up + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) + in_keystate[port] |= (1 << DKEY_UP); + // > Pad-Right + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) + in_keystate[port] |= (1 << DKEY_RIGHT); + // > Pad-Down + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) + in_keystate[port] |= (1 << DKEY_DOWN); + // > Pad-Left + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) + in_keystate[port] |= (1 << DKEY_LEFT); + // > Start + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_START)) + in_keystate[port] |= (1 << DKEY_START); + // > neGcon A + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_A)) + in_keystate[port] |= (1 << DKEY_CIRCLE); + // > neGcon B + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_X)) + in_keystate[port] |= (1 << DKEY_TRIANGLE); + // > neGcon R shoulder (digital) + if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_R)) + in_keystate[port] |= (1 << DKEY_R1); + // Query analog inputs + // + // From studying 'libpcsxcore/plugins.c' and 'frontend/plugin.c': + // >> pad->leftJoyX == in_analog_left[port][0] == NeGcon II + // >> pad->leftJoyY == in_analog_left[port][1] == NeGcon L + // >> pad->rightJoyX == in_analog_right[port][0] == NeGcon twist + // >> pad->rightJoyY == in_analog_right[port][1] == NeGcon I + // So we just have to map in_analog_left/right to more + // appropriate inputs... + // + // > NeGcon twist + // >> Get raw analog stick value and account for deadzone + lsx = input_state_cb(port, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X); + if (lsx > negcon_deadzone) + lsx = lsx - negcon_deadzone; + else if (lsx < -negcon_deadzone) + lsx = lsx + negcon_deadzone; + 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) + negcon_twist_amplitude = -(negcon_twist_amplitude * negcon_twist_amplitude); + 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; + // >> Convert to final 'in_analog' integer value [0,255] + in_analog_right[port][0] = MAX(MIN((int)(negcon_twist_amplitude * 128.0f) + 128, 255), 0); + // > NeGcon I + II + // >> Handle right analog stick vertical axis mapping... + // - Up (-Y) == accelerate == neGcon I + // - Down (+Y) == brake == neGcon II + negcon_i_rs = 0; + negcon_ii_rs = 0; + rsy = input_state_cb(port, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y); + if (rsy >= 0) + { + // Account for deadzone + // (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) + rsy = rsy - negcon_deadzone; + 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 - frame_count = 0; + { + if (rsy < -negcon_deadzone) + rsy = -1 * (rsy + negcon_deadzone); + else + rsy = 0; + negcon_i_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255); + } + // >> NeGcon I + in_analog_right[port][1] = MAX( + MAX( + get_analog_button(ret, input_state_cb, port, RETRO_DEVICE_ID_JOYPAD_R2), + get_analog_button(ret, input_state_cb, port, RETRO_DEVICE_ID_JOYPAD_B)), + negcon_i_rs); + // >> NeGcon II + in_analog_left[port][0] = MAX( + MAX( + get_analog_button(ret, input_state_cb, port, RETRO_DEVICE_ID_JOYPAD_L2), + get_analog_button(ret, input_state_cb, port, RETRO_DEVICE_ID_JOYPAD_Y)), + negcon_ii_rs); + // > NeGcon L + in_analog_left[port][1] = get_analog_button(ret, input_state_cb, port, RETRO_DEVICE_ID_JOYPAD_L); +} - input_poll_cb(); +static void update_input_mouse(int port, int ret) +{ + float raw_x = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); + float raw_y = input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); - bool updated = false; - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) - update_variables(true); + int x = (int)roundf(raw_x * mouse_sensitivity); + int y = (int)roundf(raw_y * mouse_sensitivity); + + if (x > 127) x = 127; + else if (x < -128) x = -128; + + if (y > 127) y = 127; + else if (y < -128) y = -128; + in_mouse[port][0] = x; /* -128..+128 left/right movement, 0 = no movement */ + in_mouse[port][1] = y; /* -128..+128 down/up movement, 0 = no movement */ + + /* left mouse button state */ + if (input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT)) + in_keystate[port] |= 1 << 11; + + /* right mouse button state */ + if (input_state_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)) + in_keystate[port] |= 1 << 10; +} + +static void update_input(void) +{ // reset all keystate, query libretro for keystate + int i; int j; - int lsx; - int rsy; - float negcon_twist_amplitude; - int negcon_i_rs; - int negcon_ii_rs; for (i = 0; i < PORTS_NUMBER; i++) { int16_t ret = 0; + int type = in_type[i]; + in_keystate[i] = 0; - if (in_type[i] == PSE_PAD_TYPE_NONE) + if (type == 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)) @@ -2319,173 +2444,118 @@ void retro_run(void) } } - if (in_type[i] == PSE_PAD_TYPE_GUNCON) + switch (type) { - //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); - } + case PSE_PAD_TYPE_GUNCON: + update_input_guncon(i, ret); + break; + case PSE_PAD_TYPE_NEGCON: + update_input_negcon(i, ret); + break; + case PSE_PAD_TYPE_MOUSE: + update_input_mouse(i, ret); + break; + default: + // Query digital inputs + for (j = 0; j < RETRO_PSX_MAP_LEN; j++) + if (ret & (1 << j)) + in_keystate[i] |= retro_psx_map[j]; - // B - if (input_state_cb(1, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_MIDDLE)) + // Query analog inputs + if (type == PSE_PAD_TYPE_ANALOGJOY || type == PSE_PAD_TYPE_ANALOGPAD) { - in_keystate[i] |= (1 << DKEY_CROSS); + in_analog_left[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier); + in_analog_left[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier); + in_analog_right[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier); + in_analog_right[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier); } + } + } +} - //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); +static void print_internal_fps(void) +{ + if (display_internal_fps) + { + frame_count++; - //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) + if (frame_count % INTERNAL_FPS_SAMPLE_PERIOD == 0) { - // Query digital inputs - // - // > Pad-Up - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) - in_keystate[i] |= (1 << DKEY_UP); - // > Pad-Right - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) - in_keystate[i] |= (1 << DKEY_RIGHT); - // > Pad-Down - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) - in_keystate[i] |= (1 << DKEY_DOWN); - // > Pad-Left - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) - in_keystate[i] |= (1 << DKEY_LEFT); - // > Start - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - in_keystate[i] |= (1 << DKEY_START); - // > neGcon A - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_A)) - in_keystate[i] |= (1 << DKEY_CIRCLE); - // > neGcon B - if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_X)) - in_keystate[i] |= (1 << DKEY_TRIANGLE); - // > neGcon R shoulder (digital) - 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': - // >> pad->leftJoyX == in_analog_left[i][0] == NeGcon II - // >> pad->leftJoyY == in_analog_left[i][1] == NeGcon L - // >> pad->rightJoyX == in_analog_right[i][0] == NeGcon twist - // >> pad->rightJoyY == in_analog_right[i][1] == NeGcon I - // So we just have to map in_analog_left/right to more - // appropriate inputs... - // - // > 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) - lsx = lsx - negcon_deadzone; - else if (lsx < -negcon_deadzone) - lsx = lsx + negcon_deadzone; - 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) - negcon_twist_amplitude = -(negcon_twist_amplitude * negcon_twist_amplitude); - 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; - // >> 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 - // >> Handle right analog stick vertical axis mapping... - // - Up (-Y) == accelerate == neGcon I - // - Down (+Y) == brake == neGcon II - negcon_i_rs = 0; - negcon_ii_rs = 0; - rsy = input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y); - if (rsy >= 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; + + str[0] = '\0'; + + snprintf(str, sizeof(str), "Internal FPS: %2d", internal_fps); + + pl_rearmed_cbs.flip_cnt = 0; + + if (msg_interface_version >= 1) { - // Account for deadzone - // (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) - rsy = rsy - negcon_deadzone; - 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); + struct retro_message_ext msg = { + strc, + 3000, + 1, + RETRO_LOG_INFO, + RETRO_MESSAGE_TARGET_OSD, + RETRO_MESSAGE_TYPE_STATUS, + -1 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE_EXT, &msg); } else { - if (rsy < -negcon_deadzone) - rsy = -1 * (rsy + negcon_deadzone); - else - rsy = 0; - negcon_i_rs = MIN((int)(((float)rsy / (float)(NEGCON_RANGE - negcon_deadzone)) * 255.0f), 255); + struct retro_message msg = { + strc, + 180 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); } - // >> NeGcon I - in_analog_right[i][1] = MAX( - MAX( - 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(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(ret, input_state_cb, i, RETRO_DEVICE_ID_JOYPAD_L); } - 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 (ret & (1 << j)) - in_keystate[i] |= retro_psx_map[j]; + } + else + frame_count = 0; +} - // Query analog inputs - if (in_type[i] == PSE_PAD_TYPE_ANALOGJOY || in_type[i] == PSE_PAD_TYPE_ANALOGPAD) - { - in_analog_left[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier); - in_analog_left[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier); - in_analog_right[i][0] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X), axis_bounds_modifier); - in_analog_right[i][1] = axis_range_modifier(input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y), axis_bounds_modifier); - } +void retro_run(void) +{ + /* update multitap when inputs have changed */ + /* this is only applied on core restart */ + if (input_changed) + { + int i; + input_changed = 0; + update_multitap(); + for (i = 0; i < 8; i++) + SysDLog("Player %d: %s\n", i + 1, get_pse_pad_label[in_type[i]]); + SysDLog("Multiplayer 1: %s\n", multitap1 ? "enabled" : "disabled"); + SysDLog("Multiplayer 2: %s\n", multitap2 ? "enabled" : "disabled"); + } + + //SysReset must be run while core is running,Not in menu (Locks up Retroarch) + if (rebootemu != 0) + { + rebootemu = 0; + SysReset(); + if (!Config.HLE && !Config.SlowBoot) + { + // skip BIOS logos + psxRegs.pc = psxRegs.GPR.n.ra; } + return; } + print_internal_fps(); + + input_poll_cb(); + + update_input(); + + bool updated = false; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) + update_variables(true); + stop = 0; psxCpu->Execute(); @@ -2610,6 +2680,7 @@ static void loadPSXBios(void) unsigned useHLE = 0; const char *bios[] = { + "PS1_ROM", "ps1_rom", "PSXONPSP660", "psxonpsp660", "SCPH101", "scph101", "SCPH5501", "scph5501", @@ -2654,14 +2725,41 @@ static void loadPSXBios(void) } } - if (useHLE || !found_bios) + if (!found_bios) { - SysPrintf("no BIOS files found.\n"); - struct retro_message msg = { - "No PlayStation BIOS file found - add for better compatibility", - 180 - }; - environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void *)&msg); + const char *msg_str; + if (useHLE) + { + msg_str = "BIOS set to \'hle\' in core options - real BIOS will be ignored"; + SysPrintf("Using HLE BIOS.\n"); + } + else + { + msg_str = "No PlayStation BIOS file found - add for better compatibility"; + SysPrintf("No BIOS files found.\n"); + } + + 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); + } } } @@ -2671,6 +2769,9 @@ void retro_init(void) struct retro_rumble_interface rumble; int ret; + msg_interface_version = 0; + environ_cb(RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION, &msg_interface_version); + #ifdef __MACH__ // magic sauce to make the dynarec work on iOS syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0); @@ -2730,7 +2831,7 @@ void retro_init(void) * we have to do this because cache misses and some IO penalties * are not emulated. Warning: changing this may break compatibility. */ cycle_multiplier = 175; -#ifdef HAVE_PRE_ARMV7 +#if defined(HAVE_PRE_ARMV7) && !defined(_3DS) cycle_multiplier = 200; #endif pl_rearmed_cbs.gpu_peops.iUseDither = 1; @@ -2794,3 +2895,17 @@ void SysPrintf(const char *fmt, ...) if (log_cb) log_cb(RETRO_LOG_INFO, "%s", msg); } + +/* Prints debug-level logs */ +void SysDLog(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_DEBUG, "%s", msg); +}