X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Flibretro%2Flibretro.c;h=1b914d547201d1046497901e0ffbfbbe8bf2a689;hb=6cf45534d325cc4a2e93910e57f5f1eff7443a88;hp=7c271388bcb5b198aa4c77a98eea06a9f608d17e;hpb=f2d6bde9466285cfe5c01c6bca556a8933cdd88f;p=picodrive.git diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 7c27138..1b914d5 100644 --- a/platform/libretro/libretro.c +++ b/platform/libretro/libretro.c @@ -1,6 +1,8 @@ /* * libretro core glue for PicoDrive * (C) notaz, 2013 + * (C) aliaspider, 2016 + * (C) Daniel De Matteis, 2013 * * This work is licensed under the terms of MAME license. * See COPYING file in the top-level directory. @@ -38,10 +40,20 @@ void* linearMemAlign(size_t size, size_t alignment); void linearFree(void* mem); static int ctr_svchack_successful = 0; + +#elif defined(VITA) +#define TARGET_SIZE_2 24 // 2^24 = 16 megabytes + +#include +static int sceBlock; +int getVMBlock(); +int _newlib_vm_size_user = 1 << TARGET_SIZE_2; + #endif #include #include +#include #include "../common/input_pico.h" #include "../common/version.h" #include "libretro.h" @@ -55,8 +67,16 @@ static retro_audio_sample_batch_t audio_batch_cb; #define VOUT_MAX_WIDTH 320 #define VOUT_MAX_HEIGHT 240 + +static const float VOUT_PAR = 0.0; +static const float VOUT_4_3 = (224.0f * (4.0f / 3.0f)); +static const float VOUT_CRT = (224.0f * 1.29911f); + +bool show_overscan = false; + static void *vout_buf; static int vout_width, vout_height, vout_offset; +static float user_vout_width = 0.0; #ifdef _MSC_VER static short sndBuffer[2*44100/50]; @@ -77,14 +97,16 @@ static void snd_write(int len); void cache_flush_d_inval_i(void *start, void *end) { #ifdef __arm__ + size_t len = (char *)end - (char *)start; #if defined(__BLACKBERRY_QNX__) msync(start, end - start, MS_SYNC | MS_CACHE_ONLY | MS_INVALIDATE_ICACHE); #elif defined(__MACH__) - size_t len = (char *)end - (char *)start; sys_dcache_flush(start, len); sys_icache_invalidate(start, len); #elif defined(_3DS) ctr_flush_invalidate_cache(); +#elif defined(VITA) + sceKernelSyncVMDomain(sceBlock, start, len); #else __clear_cache(start, end); #endif @@ -438,7 +460,8 @@ int plat_mem_set_exec(void *ptr, size_t size) exit(1); } - +#elif defined(VITA) + int ret = sceKernelOpenVMDomain(); #else int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC); if (ret != 0 && log_cb) @@ -452,9 +475,16 @@ void emu_video_mode_change(int start_line, int line_count, int is_32cols) memset(vout_buf, 0, 320 * 240 * 2); vout_width = is_32cols ? 256 : 320; PicoDrawSetOutBuf(vout_buf, vout_width * 2); + if (show_overscan == true) line_count += 16; + if (show_overscan == true) start_line -= 8; vout_height = line_count; vout_offset = vout_width * start_line; + + // Update the geometry + struct retro_system_av_info av_info; + retro_get_system_av_info(&av_info); + environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info); } void emu_32x_startup(void) @@ -483,6 +513,8 @@ void retro_set_environment(retro_environment_t cb) { "picodrive_ramcart", "MegaCD RAM cart; disabled|enabled" }, { "picodrive_region", "Region; Auto|Japan NTSC|Japan PAL|US|Europe" }, { "picodrive_region_fps", "Region FPS; Auto|NTSC|PAL" }, + { "picodrive_aspect", "Core-provided aspect ratio; PAR|4/3|CRT" }, + { "picodrive_overscan", "Show Overscan; disabled|enabled" }, #ifdef DRC_SH2 { "picodrive_drc", "Dynamic recompilers; enabled|disabled" }, #endif @@ -513,7 +545,10 @@ void retro_get_system_info(struct retro_system_info *info) { memset(info, 0, sizeof(*info)); info->library_name = "PicoDrive"; - info->library_version = VERSION; +#ifndef GIT_VERSION +#define GIT_VERSION "" +#endif + info->library_version = VERSION GIT_VERSION; info->valid_extensions = "bin|gen|smd|md|32x|cue|iso|sms"; info->need_fullpath = true; } @@ -523,11 +558,16 @@ void retro_get_system_av_info(struct retro_system_av_info *info) memset(info, 0, sizeof(*info)); info->timing.fps = Pico.m.pal ? 50 : 60; info->timing.sample_rate = 44100; - info->geometry.base_width = 320; + info->geometry.base_width = vout_width; info->geometry.base_height = vout_height; - info->geometry.max_width = VOUT_MAX_WIDTH; - info->geometry.max_height = VOUT_MAX_HEIGHT; - info->geometry.aspect_ratio = 4.0f / 3.0f; + info->geometry.max_width = vout_width; + info->geometry.max_height = vout_height; + + float common_width = vout_width; + if (user_vout_width != 0) + common_width = user_vout_width; + + info->geometry.aspect_ratio = common_width / vout_height; } /* savestates */ @@ -653,12 +693,73 @@ bool retro_unserialize(const void *data, size_t size) } /* cheats - TODO */ + void retro_cheat_reset(void) { + int i=0; + unsigned int addr; + + for (i = 0; i < PicoPatchCount; i++) + { + addr = PicoPatches[i].addr; + if (addr < Pico.romsize) + if (PicoPatches[i].active) + *(unsigned short *)(Pico.rom + addr) = PicoPatches[i].data_old; + else + if (PicoPatches[i].active) + m68k_write16(PicoPatches[i].addr,PicoPatches[i].data_old); + } + + PicoPatchUnload(); } void retro_cheat_set(unsigned index, bool enabled, const char *code) { + struct patch + { + unsigned int addr; + unsigned short data; + } pt; + int array_len = 0; + char *buff; + + //TODO: Split multi-line codes properly + buff = strtok(code,"+"); + + while (buff) + { + decode(buff, &pt); + if (pt.addr == (unsigned int)-1 || pt.data == (unsigned short)-1) + { + log_cb(RETRO_LOG_ERROR,"CHEATS: Invalid code: %s\n",buff); + return; + } + + /* code was good, add it */ + if (array_len < PicoPatchCount + 1) + { + void *ptr; + array_len *= 2; + array_len++; + ptr = realloc(PicoPatches, array_len * sizeof(PicoPatches[0])); + if (ptr == NULL) { + log_cb(RETRO_LOG_ERROR,"CHEATS: Failed to allocate memory for: %s\n",buff); + return; + } + PicoPatches = ptr; + } + strcpy(PicoPatches[PicoPatchCount].code, buff); + + PicoPatches[PicoPatchCount].name[51] = ""; + PicoPatches[PicoPatchCount].active = enabled; + PicoPatches[PicoPatchCount].addr = pt.addr; + PicoPatches[PicoPatchCount].data = pt.data; + if (PicoPatches[PicoPatchCount].addr < Pico.romsize) + PicoPatches[PicoPatchCount].data_old = *(unsigned short *)(Pico.rom + PicoPatches[PicoPatchCount].addr); + else + PicoPatches[PicoPatchCount].data_old = (unsigned short) m68k_read16(PicoPatches[PicoPatchCount].addr); + PicoPatchCount++; + } } /* multidisk support */ @@ -848,6 +949,22 @@ static const char *find_bios(int *region, const char *cd_fname) return NULL; } +static void sram_reset() +{ + SRam.data = NULL; + SRam.start = 0; + SRam.end = 0; + SRam.flags = '\0'; + SRam.unused2 = '\0'; + SRam.changed = '\0' ; + SRam.eeprom_type = '\0'; + SRam.unused3 = '\0'; + SRam.eeprom_bit_cl = '\0'; + SRam.eeprom_bit_in = '\0'; + SRam.eeprom_bit_out = '\0'; + SRam.size = 0; +} + bool retro_load_game(const struct retro_game_info *info) { enum media_type_e media_type; @@ -904,6 +1021,8 @@ bool retro_load_game(const struct retro_game_info *info) { 0 }, }; + sram_reset(); + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { if (log_cb) @@ -983,38 +1102,64 @@ unsigned retro_get_region(void) return Pico.m.pal ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } -void *retro_get_memory_data(unsigned id) +void *retro_get_memory_data(unsigned type) { - if (id != RETRO_MEMORY_SAVE_RAM) - return NULL; + uint8_t* data; - if (PicoAHW & PAHW_MCD) - return Pico_mcd->bram; - else - return SRam.data; + switch(type) + { + case RETRO_MEMORY_SAVE_RAM: + if (PicoAHW & PAHW_MCD) + data = Pico_mcd->bram; + else + data = SRam.data; + break; + case RETRO_MEMORY_SYSTEM_RAM: + if (PicoAHW & PAHW_SMS) + data = Pico.vramb; + else + data = Pico.ram; + break; + default: + data = NULL; + break; + } + + return data; } -size_t retro_get_memory_size(unsigned id) +size_t retro_get_memory_size(unsigned type) { unsigned int i; int sum; - if (id != RETRO_MEMORY_SAVE_RAM) - return 0; + switch(type) + { + case RETRO_MEMORY_SAVE_RAM: + if (PicoAHW & PAHW_MCD) + // bram + return 0x2000; + + if (Pico.m.frame_count == 0) + return SRam.size; - if (PicoAHW & PAHW_MCD) - // bram - return 0x2000; + // if game doesn't write to sram, don't report it to + // libretro so that RA doesn't write out zeroed .srm + for (i = 0, sum = 0; i < SRam.size; i++) + sum |= SRam.data[i]; - if (Pico.m.frame_count == 0) - return SRam.size; + return (sum != 0) ? SRam.size : 0; - // if game doesn't write to sram, don't report it to - // libretro so that RA doesn't write out zeroed .srm - for (i = 0, sum = 0; i < SRam.size; i++) - sum |= SRam.data[i]; + case RETRO_MEMORY_SYSTEM_RAM: + if (PicoAHW & PAHW_SMS) + return sizeof(Pico.vramb); + else + return sizeof(Pico.ram); + + default: + return 0; + } - return (sum != 0) ? SRam.size : 0; } void retro_reset(void) @@ -1114,7 +1259,7 @@ static void update_variables(void) else if (strcmp(var.value, "NTSC") == 0) PicoRegionFPSOverride = 1; else if (strcmp(var.value, "PAL") == 0) - PicoRegionFPSOverride = 2; + PicoRegionFPSOverride = 2; } // Update region, fps and sound flags if needed @@ -1126,6 +1271,35 @@ static void update_variables(void) PsndRerate(1); } + float old_user_vout_width = user_vout_width; + var.value = NULL; + var.key = "picodrive_aspect"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + if (strcmp(var.value, "4/3") == 0) + user_vout_width = VOUT_4_3; + else if (strcmp(var.value, "CRT") == 0) + user_vout_width = VOUT_CRT; + else + user_vout_width = VOUT_PAR; + } + + var.value = NULL; + var.key = "picodrive_overscan"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { + if (strcmp(var.value, "enabled") == 0) + show_overscan = true; + else + show_overscan = false; + } + + if (user_vout_width != old_user_vout_width) + { + // Update the geometry + struct retro_system_av_info av_info; + retro_get_system_av_info(&av_info); + environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info); + } + #ifdef DRC_SH2 var.value = NULL; var.key = "picodrive_drc"; @@ -1158,6 +1332,7 @@ void retro_run(void) if (input_state_cb(pad, RETRO_DEVICE_JOYPAD, 0, i)) PicoPad[pad] |= retro_pico_map[i]; + PicoPatchApply(); PicoFrame(); video_cb((short *)vout_buf + vout_offset, @@ -1188,6 +1363,8 @@ void retro_init(void) #ifdef _3DS ctr_svchack_successful = ctr_svchack_init(); +#elif defined(VITA) + sceBlock = getVMBlock(); #endif PicoOpt = POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80