X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Flibretro.c;h=49038471e8a7040e2221df77ad9a75f7d249db07;hb=b08a2950f1f213508c653c6289bf0c006082c6c5;hp=d46cc4a2c180320ae324c128eb11728902d8e683;hpb=86b38dc46d93354418faf5aecd430f8661adb4b3;p=picodrive.git diff --git a/platform/libretro.c b/platform/libretro.c index d46cc4a..4903847 100644 --- a/platform/libretro.c +++ b/platform/libretro.c @@ -10,7 +10,13 @@ #include #include #include +#ifndef _WIN32 #include +#else +#include +#include +#include +#endif #include #ifdef __MACH__ #include @@ -22,10 +28,6 @@ #include "common/version.h" #include "libretro.h" -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - static retro_video_refresh_t video_cb; static retro_input_poll_t input_poll_cb; static retro_input_state_t input_state_cb; @@ -66,27 +68,127 @@ void cache_flush_d_inval_i(void *start, void *end) #endif } +#ifdef _WIN32 +/* mmap() replacement for Windows + * + * Author: Mike Frysinger + * Placed into the public domain + */ + +/* References: + * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx + * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx + * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx + * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx + */ + +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +/* This flag is only available in WinXP+ */ +#ifdef FILE_MAP_EXECUTE +#define PROT_EXEC 0x4 +#else +#define PROT_EXEC 0x0 +#define FILE_MAP_EXECUTE 0 +#endif + +#define MAP_SHARED 0x01 +#define MAP_PRIVATE 0x02 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FAILED ((void *) -1) + +#ifdef __USE_FILE_OFFSET64 +# define DWORD_HI(x) (x >> 32) +# define DWORD_LO(x) ((x) & 0xffffffff) +#else +# define DWORD_HI(x) (0) +# define DWORD_LO(x) (x) +#endif + +static void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) + return MAP_FAILED; + if (fd == -1) { + if (!(flags & MAP_ANON) || offset) + return MAP_FAILED; + } else if (flags & MAP_ANON) + return MAP_FAILED; + + DWORD flProtect; + if (prot & PROT_WRITE) { + if (prot & PROT_EXEC) + flProtect = PAGE_EXECUTE_READWRITE; + else + flProtect = PAGE_READWRITE; + } else if (prot & PROT_EXEC) { + if (prot & PROT_READ) + flProtect = PAGE_EXECUTE_READ; + else if (prot & PROT_EXEC) + flProtect = PAGE_EXECUTE; + } else + flProtect = PAGE_READONLY; + + off_t end = length + offset; + HANDLE mmap_fd, h; + if (fd == -1) + mmap_fd = INVALID_HANDLE_VALUE; + else + mmap_fd = (HANDLE)_get_osfhandle(fd); + h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL); + if (h == NULL) + return MAP_FAILED; + + DWORD dwDesiredAccess; + if (prot & PROT_WRITE) + dwDesiredAccess = FILE_MAP_WRITE; + else + dwDesiredAccess = FILE_MAP_READ; + if (prot & PROT_EXEC) + dwDesiredAccess |= FILE_MAP_EXECUTE; + if (flags & MAP_PRIVATE) + dwDesiredAccess |= FILE_MAP_COPY; + void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length); + if (ret == NULL) { + CloseHandle(h); + ret = MAP_FAILED; + } + return ret; +} + +static void munmap(void *addr, size_t length) +{ + UnmapViewOfFile(addr); + /* ruh-ro, we leaked handle from CreateFileMapping() ... */ +} +#endif + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed) { - int flags = MAP_PRIVATE | MAP_ANONYMOUS; - void *req, *ret; + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + void *req, *ret; - req = (void *)addr; - ret = mmap(req, size, PROT_READ | PROT_WRITE, flags, -1, 0); - if (ret == MAP_FAILED) { - lprintf("mmap(%08lx, %zd) failed: %d\n", addr, size, errno); - return NULL; - } + req = (void *)addr; + ret = mmap(req, size, PROT_READ | PROT_WRITE, flags, -1, 0); + if (ret == MAP_FAILED) { + lprintf("mmap(%08lx, %zd) failed: %d\n", addr, size, errno); + return NULL; + } - if (addr != 0 && ret != (void *)addr) { - lprintf("warning: wanted to map @%08lx, got %p\n", - addr, ret); + if (addr != 0 && ret != (void *)addr) { + lprintf("warning: wanted to map @%08lx, got %p\n", + addr, ret); - if (is_fixed) { - munmap(ret, size); - return NULL; - } - } + if (is_fixed) { + munmap(ret, size); + return NULL; + } + } return ret; } @@ -132,10 +234,15 @@ void plat_munmap(void *ptr, size_t size) int plat_mem_set_exec(void *ptr, size_t size) { - int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC); - if (ret != 0) - lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, errno); - +#ifdef _WIN32 + int ret = VirtualProtect(ptr,size,PAGE_EXECUTE_READWRITE,0); + if (ret == 0) + lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, 0); +#else + int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC); + if (ret != 0) + lprintf("mprotect(%p, %zd) failed: %d\n", ptr, size, errno); +#endif return ret; } @@ -183,6 +290,11 @@ void retro_set_environment(retro_environment_t cb) { static const struct retro_variable vars[] = { //{ "region", "Region; Auto|NTSC|PAL" }, + { "picodrive_input1", "Input device 1; 3 button pad|6 button pad|None" }, + { "picodrive_input2", "Input device 2; 3 button pad|6 button pad|None" }, +#ifdef DRC_SH2 + { "picodrive_drc", "Dynamic recompilers; enabled|disabled" }, +#endif { NULL, NULL }, }; @@ -473,13 +585,13 @@ static void disk_tray_close(void) static const char * const biosfiles_us[] = { - "us_scd1_9210", "us_scd2_9306", "SegaCDBIOS9303", "bios_CD_U" + "us_scd2_9306", "SegaCDBIOS9303", "us_scd1_9210", "bios_CD_U" }; static const char * const biosfiles_eu[] = { - "eu_mcd1_9210", "eu_mcd2_9306", "eu_mcd2_9303", "bios_CD_E" + "eu_mcd2_9306", "eu_mcd2_9303", "eu_mcd1_9210", "bios_CD_E" }; static const char * const biosfiles_jp[] = { - "jp_mcd1_9112", "jp_mcd1_9111", "bios_CD_J" + "jp_mcd2_921222", "jp_mcd1_9112", "jp_mcd1_9111", "bios_CD_J" }; static void make_system_path(char *buf, size_t buf_size, @@ -545,7 +657,7 @@ bool retro_load_game(const struct retro_game_info *info) enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { - lprintf("RGB565 suppot required, sorry\n"); + lprintf("RGB565 support required, sorry\n"); return false; } @@ -660,13 +772,52 @@ static void snd_write(int len) audio_batch_cb(PsndOut, len / 4); } +static enum input_device input_name_to_val(const char *name) +{ + if (strcmp(name, "3 button pad") == 0) + return PICO_INPUT_PAD_3BTN; + if (strcmp(name, "6 button pad") == 0) + return PICO_INPUT_PAD_6BTN; + if (strcmp(name, "None") == 0) + return PICO_INPUT_NOTHING; + + lprintf("invalid picodrive_input: '%s'\n", name); + return PICO_INPUT_PAD_3BTN; +} + +static void update_variables(void) +{ + struct retro_variable var; + + var.value = NULL; + var.key = "picodrive_input1"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + PicoSetInputDevice(0, input_name_to_val(var.value)); + + var.value = NULL; + var.key = "picodrive_input2"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + PicoSetInputDevice(1, input_name_to_val(var.value)); + +#ifdef DRC_SH2 + var.value = NULL; + var.key = "picodrive_drc"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + if (strcmp(var.value, "enabled") == 0) + PicoOpt |= POPT_EN_DRC; + else + PicoOpt &= ~POPT_EN_DRC; + } +#endif +} + void retro_run(void) { bool updated = false; int pad, i; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) - ; //update_variables(true); + update_variables(); input_poll_cb(); @@ -703,7 +854,7 @@ void retro_init(void) | POPT_EN_32X|POPT_EN_PWM | POPT_ACC_SPRITES|POPT_DIS_32C_BORDER; #ifdef __arm__ - PicoOpt |= POPT_EN_SVP_DRC; + PicoOpt |= POPT_EN_DRC; #endif PsndRate = 44100; PicoAutoRgnOrder = 0x184; // US, EU, JP @@ -720,6 +871,8 @@ void retro_init(void) //PicoMessage = plat_status_msg_busy_next; PicoMCDopenTray = disk_tray_open; PicoMCDcloseTray = disk_tray_close; + + update_variables(); } void retro_deinit(void)