X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=frontend%2Flibretro.c;h=361695ce9bc73fbc1bebe9ff1a89ad3e82bd1485;hb=29f3675b9b2f24b8a16db73588b8b04d628eabd8;hp=413098d13d4af46fc39120cdf14c0a84e2614624;hpb=5948832fca5e81cc263bb57d784b6a81c19d1d71;p=pcsx_rearmed.git diff --git a/frontend/libretro.c b/frontend/libretro.c index 413098d1..361695ce 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -1,5 +1,5 @@ /* - * (C) notaz, 2012 + * (C) notaz, 2012,2014,2015 * * This work is licensed under the terms of the GNU GPLv2 or later. * See the COPYING file in the top-level directory. @@ -9,6 +9,7 @@ #include #include #include +#include #include "../libpcsxcore/misc.h" #include "../libpcsxcore/psxcounters.h" @@ -18,26 +19,33 @@ #include "../libpcsxcore/cdriso.h" #include "../libpcsxcore/cheat.h" #include "../plugins/dfsound/out.h" +#include "../plugins/dfsound/spu_config.h" #include "../plugins/dfinput/externals.h" #include "cspace.h" #include "main.h" #include "plugin.h" #include "plugin_lib.h" +#include "arm_features.h" #include "revision.h" #include "libretro.h" +#ifdef _3DS +#include "3ds/3ds_utils.h" +#endif + static retro_video_refresh_t video_cb; static retro_input_poll_t input_poll_cb; static retro_input_state_t input_state_cb; static retro_environment_t environ_cb; static retro_audio_sample_batch_t audio_batch_cb; +static struct retro_rumble_interface rumble; static void *vout_buf; static int vout_width, vout_height; static int vout_doffs_old, vout_fb_dirty; static bool vout_can_dupe; +static bool duping_enable; -static int samples_sent, samples_to_send; static int plugins_opened; static int is_pal_mode; @@ -46,10 +54,13 @@ extern char Mcd1Data[MCD_SIZE]; extern char McdDisable[2]; /* PCSX ReARMed core calls and stuff */ -int in_type1, in_type2; -int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; -int in_keystate; -int in_enable_vibration; +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[8]; +int multitap1 = 0; +int multitap2 = 0; +int in_enable_vibration = 1; /* PSX max resolution is 640x512, but with enhancement it's 1024x512 */ #define VOUT_MAX_WIDTH 1024 @@ -161,6 +172,85 @@ static void vout_close(void) { } +#ifdef _3DS +typedef struct +{ + void* buffer; + uint32_t target_map; + size_t size; + enum psxMapTag tag; +}psx_map_t; + +psx_map_t custom_psx_maps[] = { + {NULL, 0x13000000, 0x210000, MAP_TAG_RAM}, // 0x80000000 + {NULL, 0x12800000, 0x010000, MAP_TAG_OTHER}, // 0x1f800000 + {NULL, 0x12c00000, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000 + {NULL, 0x11000000, 0x800000, MAP_TAG_LUTS}, // 0x08000000 + {NULL, 0x12000000, 0x200000, MAP_TAG_VRAM}, // 0x00000000 +}; + +void* pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed, + enum psxMapTag tag) +{ + (void)is_fixed; + (void)addr; + + if (__ctr_svchax) + { + psx_map_t* custom_map = custom_psx_maps; + + for (; custom_map->size; custom_map++) + { + if ((custom_map->size == size) && (custom_map->tag == tag)) + { + uint32_t ptr_aligned, tmp; + + custom_map->buffer = malloc(size + 0x1000); + ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF; + + if(svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_MAP, 0x3) < 0) + { + SysPrintf("could not map memory @0x%08X\n", custom_map->target_map); + exit(1); + } + + return (void*)custom_map->target_map; + } + } + } + + return malloc(size); +} + +void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag) +{ + (void)tag; + + if (__ctr_svchax) + { + psx_map_t* custom_map = custom_psx_maps; + + for (; custom_map->size; custom_map++) + { + if ((custom_map->target_map == (uint32_t)ptr)) + { + uint32_t ptr_aligned, tmp; + + ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF; + + svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0x3); + + free(custom_map->buffer); + custom_map->buffer = NULL; + return; + } + } + } + + free(ptr); +} +#endif + static void *pl_mmap(unsigned int size) { return psxMap(0, size, 0, MAP_TAG_VRAM); @@ -194,8 +284,10 @@ void pl_timing_prepare(int is_pal) is_pal_mode = is_pal; } -void plat_trigger_vibrate(int is_strong) +void plat_trigger_vibrate(int pad, int low, int high) { + rumble.set_rumble_state(pad, RETRO_RUMBLE_STRONG, high << 8); + rumble.set_rumble_state(pad, RETRO_RUMBLE_WEAK, low ? 0xffff : 0x0); } void pl_update_gun(int *xn, int *yn, int *xres, int *yres, int *in) @@ -214,16 +306,13 @@ static void snd_finish(void) static int snd_busy(void) { - if (samples_to_send > samples_sent) - return 0; /* give more samples */ - else - return 1; + return 0; } static void snd_feed(void *buf, int bytes) { - audio_batch_cb(buf, bytes / 4); - samples_sent += bytes / 4; + if (audio_batch_cb != NULL) + audio_batch_cb(buf, bytes / 4); } void out_register_libretro(struct out_driver *drv) @@ -239,12 +328,31 @@ void out_register_libretro(struct out_driver *drv) void retro_set_environment(retro_environment_t cb) { static const struct retro_variable vars[] = { - { "frameskip", "Frameskip; 0|1|2|3" }, - { "region", "Region; Auto|NTSC|PAL" }, + { "pcsx_rearmed_frameskip", "Frameskip; 0|1|2|3" }, + { "pcsx_rearmed_region", "Region; Auto|NTSC|PAL" }, + { "pcsx_rearmed_pad1type", "Pad 1 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad2type", "Pad 2 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad3type", "Pad 3 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad4type", "Pad 4 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad5type", "Pad 5 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad6type", "Pad 6 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad7type", "Pad 7 Type; standard|analog|negcon" }, + { "pcsx_rearmed_pad8type", "Pad 8 Type; standard|analog|negcon" }, + { "pcsx_rearmed_multitap1", "Multitap 1; disabled|enabled" }, + { "pcsx_rearmed_multitap2", "Multitap 2; disabled|enabled" }, +#ifndef DRC_DISABLE + { "pcsx_rearmed_drc", "Dynamic recompiler; enabled|disabled" }, +#endif #ifdef __ARM_NEON__ - { "neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" }, - { "neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" }, + { "pcsx_rearmed_neon_interlace_enable", "Enable interlacing mode(s); disabled|enabled" }, + { "pcsx_rearmed_neon_enhancement_enable", "Enhanced resolution (slow); disabled|enabled" }, + { "pcsx_rearmed_neon_enhancement_no_main", "Enhanced resolution speed hack; disabled|enabled" }, #endif + { "pcsx_rearmed_duping_enable", "Frame duping; on|off" }, + { "pcsx_rearmed_spu_reverb", "Sound: Reverb; on|off" }, + { "pcsx_rearmed_spu_interpolation", "Sound: Interpolation; simple|gaussian|cubic|off" }, + { "pcsx_rearmed_pe2_fix", "Parasite Eve 2/Vandal Hearts 1/2 Fix; disabled|enabled" }, + { "pcsx_rearmed_inuyasha_fix", "InuYasha Sengoku Battle Fix; disabled|enabled" }, { NULL, NULL }, }; @@ -266,13 +374,14 @@ unsigned retro_api_version(void) void retro_set_controller_port_device(unsigned port, unsigned device) { + SysPrintf("port %u device %u",port,device); } void retro_get_system_info(struct retro_system_info *info) { memset(info, 0, sizeof(*info)); info->library_name = "PCSX-ReARMed"; - info->library_version = "r19"; + info->library_version = "r22"; info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u"; info->need_fullpath = true; } @@ -290,10 +399,11 @@ void retro_get_system_av_info(struct retro_system_av_info *info) } /* savestates */ -size_t retro_serialize_size(void) -{ - // it's currently 4380651 bytes, but have some reserved for future - return 0x430000; +size_t retro_serialize_size(void) +{ + // it's currently 4380651-4397047 bytes, + // but have some reserved for future + return 0x440000; } struct save_fp { @@ -376,7 +486,7 @@ static void save_close(void *file) } bool retro_serialize(void *data, size_t size) -{ +{ int ret = SaveState(data); return ret == 0 ? true : false; } @@ -590,11 +700,213 @@ static void extract_directory(char *buf, const char *path, size_t size) } } +#if defined(__QNX__) || defined(_WIN32) +/* Blackberry QNX doesn't have strcasestr */ + +/* + * Find the first occurrence of find in s, ignore case. + */ +char * +strcasestr(const char *s, const char*find) +{ + char c, sc; + size_t len; + + if ((c = *find++) != 0) { + c = tolower((unsigned char)c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + } while ((char)tolower((unsigned char)sc) != c); + } while (strncasecmp(s, find, len) != 0); + s--; + } + return ((char *)s); +} +#endif + bool retro_load_game(const struct retro_game_info *info) { size_t i; bool is_m3u = (strcasestr(info->path, ".m3u") != NULL); + struct retro_input_descriptor desc[] = { + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 2, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 3, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 4, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 4, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 4, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 4, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 5, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 5, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 6, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 6, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "Cross" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "Circle" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "Triangle" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Square" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L1" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L2, "L2" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L3, "L3" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R1" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2, "R2" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R3, "R3" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" }, + { 7, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" }, + { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X, "Left Analog X" }, + { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y, "Left Analog Y" }, + { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X, "Right Analog X" }, + { 7, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y, "Right Analog Y" }, + + { 0 }, + }; + + environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, desc); + #ifdef FRONTEND_SUPPORTS_RGB565 enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { @@ -683,7 +995,7 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info *i return false; } -void retro_unload_game(void) +void retro_unload_game(void) { } @@ -736,16 +1048,14 @@ static const unsigned short retro_psx_map[] = { static void update_variables(bool in_flight) { struct retro_variable var; - - var.value = NULL; - var.key = "frameskip"; + var.value = NULL; + var.key = "pcsx_rearmed_frameskip"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) pl_rearmed_cbs.frameskip = atoi(var.value); var.value = NULL; - var.key = "region"; - + var.key = "pcsx_rearmed_region"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) { Config.PsxAuto = 0; @@ -756,9 +1066,116 @@ static void update_variables(bool in_flight) else if (strcmp(var.value, "PAL") == 0) Config.PsxType = 1; } + + var.value = NULL; + var.key = "pcsx_rearmed_pad1type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[0] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[0] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[0] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad2type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[1] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[1] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[1] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad3type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[2] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[2] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[2] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad4type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[3] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[3] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[3] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad5type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[4] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[4] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[4] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad6type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[5] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[5] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[5] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad7type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[6] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[6] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[6] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_pad8type"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + in_type[7] = PSE_PAD_TYPE_STANDARD; + if (strcmp(var.value, "analog") == 0) + in_type[7] = PSE_PAD_TYPE_ANALOGPAD; + else if (strcmp(var.value, "negcon") == 0) + in_type[7] = PSE_PAD_TYPE_NEGCON; + } + + var.value = NULL; + var.key = "pcsx_rearmed_multitap1"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "enabled") == 0) + multitap1 = 1; + else multitap1 = 0; + } + + var.value = NULL; + var.key = "pcsx_rearmed_multitap2"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "enabled") == 0) + multitap2 = 1; + else multitap2 = 0; + } + #ifdef __ARM_NEON__ var.value = "NULL"; - var.key = "neon_interlace_enable"; + var.key = "pcsx_rearmed_neon_interlace_enable"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) { @@ -769,7 +1186,7 @@ static void update_variables(bool in_flight) } var.value = NULL; - var.key = "neon_enhancement_enable"; + var.key = "pcsx_rearmed_neon_enhancement_enable"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) { @@ -778,24 +1195,122 @@ static void update_variables(bool in_flight) else if (strcmp(var.value, "enabled") == 0) pl_rearmed_cbs.gpu_neon.enhancement_enable = 1; } + + var.value = NULL; + var.key = "pcsx_rearmed_neon_enhancement_no_main"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "disabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_no_main = 0; + else if (strcmp(var.value, "enabled") == 0) + pl_rearmed_cbs.gpu_neon.enhancement_no_main = 1; + } #endif - if (in_flight) { - // inform core things about possible config changes - plugin_call_rearmed_cbs(); + var.value = "NULL"; + var.key = "pcsx_rearmed_duping_enable"; - if (GPU_open != NULL && GPU_close != NULL) { - GPU_close(); - GPU_open(&gpuDisp, "PCSX", NULL); - } + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "off") == 0) + duping_enable = false; + else if (strcmp(var.value, "on") == 0) + duping_enable = true; + } - dfinput_activate(); - } +#ifndef DRC_DISABLE + var.value = NULL; + var.key = "pcsx_rearmed_drc"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + R3000Acpu *prev_cpu = psxCpu; + +#ifdef _3DS + if(!__ctr_svchax) + Config.Cpu = CPU_INTERPRETER; + else +#endif + if (strcmp(var.value, "disabled") == 0) + Config.Cpu = CPU_INTERPRETER; + else if (strcmp(var.value, "enabled") == 0) + Config.Cpu = CPU_DYNAREC; + + psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec; + if (psxCpu != prev_cpu) { + prev_cpu->Shutdown(); + psxCpu->Init(); + psxCpu->Reset(); // not really a reset.. + } + } +#endif + + var.value = "NULL"; + var.key = "pcsx_rearmed_spu_reverb"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "off") == 0) + spu_config.iUseReverb = false; + else if (strcmp(var.value, "on") == 0) + spu_config.iUseReverb = true; + } + + var.value = "NULL"; + var.key = "pcsx_rearmed_spu_interpolation"; + + 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; + } + + var.value = "NULL"; + var.key = "pcsx_rearmed_pe2_fix"; + + 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; + } + + var.value = "NULL"; + var.key = "pcsx_rearmed_inuyasha_fix"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) || var.value) + { + if (strcmp(var.value, "disabled") == 0) + Config.VSyncWA = 0; + else if (strcmp(var.value, "enabled") == 0) + Config.VSyncWA = 1; + } + + if (in_flight) { + // inform core things about possible config changes + plugin_call_rearmed_cbs(); + + if (GPU_open != NULL && GPU_close != NULL) { + GPU_close(); + GPU_open(&gpuDisp, "PCSX", NULL); + } + + dfinput_activate(); + } } -void retro_run(void) +void retro_run(void) { - int i; + + int i; input_poll_cb(); @@ -803,84 +1318,174 @@ void retro_run(void) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) update_variables(true); - in_keystate = 0; - for (i = 0; i < RETRO_PSX_MAP_LEN; i++) - if (input_state_cb(1, RETRO_DEVICE_JOYPAD, 0, i)) - in_keystate |= retro_psx_map[i]; - in_keystate <<= 16; - for (i = 0; i < RETRO_PSX_MAP_LEN; i++) - if (input_state_cb(0, RETRO_DEVICE_JOYPAD, 0, i)) - in_keystate |= retro_psx_map[i]; + // reset all keystate, query from libretro for keystate + int j; + for(i=0;i<8;i++){ + in_keystate[i] = 0; + // query from libretro for keystate + for (j = 0; j < RETRO_PSX_MAP_LEN; j++){ + if (input_state_cb(i, RETRO_DEVICE_JOYPAD, 0, j)) + in_keystate[i] |= retro_psx_map[j]; + } + } + + if (in_type[0] == PSE_PAD_TYPE_ANALOGPAD) + { + in_analog_left[0][0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_analog_left[0][1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + in_analog_right[0][0] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_analog_right[0][1] = (input_state_cb(0, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + } + + if (in_type[1] == PSE_PAD_TYPE_ANALOGPAD) + { + in_analog_left[1][0] = (input_state_cb(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_analog_left[1][1] = (input_state_cb(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + in_analog_right[1][0] = (input_state_cb(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; + in_analog_right[1][1] = (input_state_cb(1, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + } stop = 0; psxCpu->Execute(); - samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60; - - video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL, + video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf : NULL, vout_width, vout_height, vout_width * 2); vout_fb_dirty = 0; } +static bool try_use_bios(const char *path) +{ + FILE *f; + long size; + const char *name; + + f = fopen(path, "rb"); + if (f == NULL) + return false; + + fseek(f, 0, SEEK_END); + size = ftell(f); + fclose(f); + + if (size != 512 * 1024) + return false; + + name = strrchr(path, SLASH); + if (name++ == NULL) + name = path; + snprintf(Config.Bios, sizeof(Config.Bios), "%s", name); + return true; +} + +#ifndef VITA +#include +#include + +static bool find_any_bios(const char *dirpath, char *path, size_t path_size) +{ + DIR *dir; + struct dirent *ent; + bool ret = false; + + dir = opendir(dirpath); + if (dir == NULL) + return false; + + while ((ent = readdir(dir))) { + if (strncasecmp(ent->d_name, "scph", 4) != 0) + continue; + + snprintf(path, path_size, "%s/%s", dirpath, ent->d_name); + ret = try_use_bios(path); + if (ret) + break; + } + closedir(dir); + return ret; +} +#else +#define find_any_bios(...) false +#endif + +static void check_system_specs(void) +{ + unsigned level = 6; + environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); +} + void retro_init(void) { const char *bios[] = { "scph1001", "scph5501", "scph7001" }; const char *dir; char path[256]; - FILE *f = NULL; - int i, ret, level; + int i, ret; + bool found_bios = false; +#ifdef _3DS + psxMapHook = pl_3ds_mmap; + psxUnmapHook = pl_3ds_munmap; +#endif ret = emu_core_preinit(); +#ifdef _3DS + /* emu_core_preinit sets the cpu to dynarec */ + if(!__ctr_svchax) + Config.Cpu = CPU_INTERPRETER; +#endif ret |= emu_core_init(); if (ret != 0) { SysPrintf("PCSX init failed.\n"); exit(1); } +#ifdef _3DS + vout_buf = linearMemAlign(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2, 0x80); +#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) && !defined(VITA) + posix_memalign(&vout_buf, 16, VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); +#else vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); +#endif if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir) { - snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s/", dir); + snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir); for (i = 0; i < sizeof(bios) / sizeof(bios[0]); i++) { snprintf(path, sizeof(path), "%s/%s.bin", dir, bios[i]); - f = fopen(path, "r"); - if (f != NULL) { - snprintf(Config.Bios, sizeof(Config.Bios), "%s.bin", bios[i]); + found_bios = try_use_bios(path); + if (found_bios) break; - } } + + if (!found_bios) + found_bios = find_any_bios(dir, path, sizeof(path)); } - if (f != NULL) { + if (found_bios) { SysPrintf("found BIOS file: %s\n", Config.Bios); - fclose(f); } else - { + { SysPrintf("no BIOS files found.\n"); - struct retro_message msg = - { - "no BIOS found, expect bugs!", - 180 - }; - environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); - } - - level = 1; - environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); + struct retro_message msg = + { + "no BIOS found, expect bugs!", + 180 + }; + environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg); + } environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe); environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control); + environ_cb(RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE, &rumble); /* 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. */ -#ifdef __ARM_ARCH_7A__ cycle_multiplier = 175; -#else +#ifdef HAVE_PRE_ARMV7 cycle_multiplier = 200; #endif + pl_rearmed_cbs.gpu_peops.iUseDither = 1; + spu_config.iUseFixedUpdates = 1; McdDisable[0] = 0; McdDisable[1] = 1; @@ -893,11 +1498,24 @@ void retro_init(void) SaveFuncs.close = save_close; update_variables(false); + check_system_specs(); } void retro_deinit(void) { SysClose(); +#ifdef _3DS + linearFree(vout_buf); +#else free(vout_buf); +#endif vout_buf = NULL; } + +#ifdef VITA +#include +int usleep (unsigned long us) +{ + sceKernelDelayThread(us); +} +#endif