X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Flibretro%2Flibretro.c;h=a4bc0a1bbf44caa49993de1d8e738c0189c8e9a6;hb=e5326b1a0e5fe59e95db275c52acffd4bd50e7da;hp=1260f4833ceac1be916e7fbefb75b8ac5b8e2150;hpb=c3e69f81d86410bce18d0335d2c879bda71285db;p=picodrive.git diff --git a/platform/libretro/libretro.c b/platform/libretro/libretro.c index 1260f48..a4bc0a1 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 */ @@ -652,13 +692,91 @@ bool retro_unserialize(const void *data, size_t size) return ret == 0; } -/* cheats - TODO */ +typedef struct patch +{ + unsigned int addr; + unsigned short data; +} patch; + +extern void decode(char *buff, patch *dest); +extern uint16_t m68k_read16(uint32_t a); +extern void m68k_write16(uint32_t a, uint16_t d); + 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) { + patch pt; + int array_len = PicoPatchCount; + char codeCopy[256]; + char *buff; + bool multiline=0; + + strcpy(codeCopy,code); + + if (strstr(code,"+")){ + multiline=1; + buff = strtok(codeCopy,"+"); + } else { + buff=codeCopy; + } + + while (buff != NULL) + { + log_cb(RETRO_LOG_INFO,"Buff: %s\n",buff); + decode(buff, &pt); + if (pt.addr == (uint32_t) -1 || pt.data == (uint16_t) -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].active = enabled; + PicoPatches[PicoPatchCount].addr = pt.addr; + PicoPatches[PicoPatchCount].data = pt.data; + if (PicoPatches[PicoPatchCount].addr < Pico.romsize) + PicoPatches[PicoPatchCount].data_old = *(uint16_t *)(Pico.rom + PicoPatches[PicoPatchCount].addr); + else + PicoPatches[PicoPatchCount].data_old = (uint16_t) m68k_read16(PicoPatches[PicoPatchCount].addr); + PicoPatchCount++; + + if (!multiline) + break; + buff = strtok(NULL,"+"); + } } /* multidisk support */ @@ -848,6 +966,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 +1038,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) @@ -1005,7 +1141,7 @@ void *retro_get_memory_data(unsigned type) data = NULL; break; } - + return data; } @@ -1013,7 +1149,7 @@ size_t retro_get_memory_size(unsigned type) { unsigned int i; int sum; - + switch(type) { case RETRO_MEMORY_SAVE_RAM: @@ -1030,17 +1166,17 @@ size_t retro_get_memory_size(unsigned type) sum |= SRam.data[i]; return (sum != 0) ? SRam.size : 0; - + case RETRO_MEMORY_SYSTEM_RAM: if (PicoAHW & PAHW_SMS) return sizeof(Pico.vramb); else return sizeof(Pico.ram); - + default: return 0; } - + } void retro_reset(void) @@ -1140,7 +1276,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 @@ -1152,6 +1288,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"; @@ -1184,6 +1349,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, @@ -1214,6 +1380,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