X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=frontend%2Flibretro.c;h=4f6879ed5ea40c4fb4461199ad6dce2c2b57d859;hp=db13d7a29c824a4fbbf0e496034f8274a8da836b;hb=468072a17a20bf584df17f14e329441eebf66776;hpb=87e5b45fe1aa734289cf57531c89988cfafff524 diff --git a/frontend/libretro.c b/frontend/libretro.c index db13d7a2..4f6879ed 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -13,6 +13,7 @@ #include "../libpcsxcore/psxcounters.h" #include "../libpcsxcore/psxmem_map.h" #include "../libpcsxcore/new_dynarec/new_dynarec.h" +#include "../libpcsxcore/cheat.h" #include "../plugins/dfsound/out.h" #include "../plugins/gpulib/cspace.h" #include "main.h" @@ -28,9 +29,17 @@ static retro_environment_t environ_cb; static retro_audio_sample_batch_t audio_batch_cb; static void *vout_buf; +static int vout_width, vout_height; +static int vout_doffs_old, vout_fb_dirty; +static bool vout_can_dupe; + static int samples_sent, samples_to_send; static int plugins_opened; -static int native_rgb565; +static int is_pal_mode; + +/* memory card data */ +extern char Mcd1Data[MCD_SIZE]; +extern char McdDisable[2]; /* PCSX ReARMed core calls and stuff */ int in_type1, in_type2; @@ -38,6 +47,39 @@ int in_a1[2] = { 127, 127 }, in_a2[2] = { 127, 127 }; int in_keystate; int in_enable_vibration; +static void init_memcard(char *mcd_data) +{ + unsigned off = 0; + unsigned i; + + memset(mcd_data, 0, MCD_SIZE); + + mcd_data[off++] = 'M'; + mcd_data[off++] = 'C'; + off += 0x7d; + mcd_data[off++] = 0x0e; + + for (i = 0; i < 15; i++) { + mcd_data[off++] = 0xa0; + off += 0x07; + mcd_data[off++] = 0xff; + mcd_data[off++] = 0xff; + off += 0x75; + mcd_data[off++] = 0xa0; + } + + for (i = 0; i < 20; i++) { + mcd_data[off++] = 0xff; + mcd_data[off++] = 0xff; + mcd_data[off++] = 0xff; + mcd_data[off++] = 0xff; + off += 0x04; + mcd_data[off++] = 0xff; + mcd_data[off++] = 0xff; + off += 0x76; + } +} + static int vout_open(void) { return 0; @@ -45,8 +87,11 @@ static int vout_open(void) static void vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) { + vout_width = w; + vout_height = h; } +#ifndef FRONTEND_SUPPORTS_RGB565 static void convert(void *buf, size_t bytes) { unsigned int i, v, *p = buf; @@ -56,12 +101,14 @@ static void convert(void *buf, size_t bytes) p[i] = (v & 0x001f001f) | ((v >> 1) & 0x7fe07fe0); } } +#endif static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) { unsigned short *dest = vout_buf; const unsigned short *src = vram; - int dstride = w, h1 = h; + int dstride = vout_width, h1 = h; + int doffs; if (vram == NULL) { // blanking @@ -69,6 +116,15 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) goto out; } + doffs = (vout_height - h) * dstride; + doffs += (dstride - w) / 2 & ~1; + if (doffs != vout_doffs_old) { + // clear borders + memset(vout_buf, 0, dstride * h * 2); + vout_doffs_old = doffs; + } + dest += doffs; + if (bgr24) { // XXX: could we switch to RETRO_PIXEL_FORMAT_XRGB8888 here? @@ -86,9 +142,10 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) } out: - if (!native_rgb565) - convert(vout_buf, w * h * 2); - video_cb(vout_buf, w, h, w * 2); +#ifndef FRONTEND_SUPPORTS_RGB565 + convert(vout_buf, vout_width * vout_height * 2); +#endif + vout_fb_dirty = 1; pl_rearmed_cbs.flip_cnt++; } @@ -126,6 +183,7 @@ void pl_frame_limit(void) void pl_timing_prepare(int is_pal) { + is_pal_mode = is_pal; } void plat_trigger_vibrate(int is_strong) @@ -198,7 +256,7 @@ void retro_get_system_info(struct retro_system_info *info) void retro_get_system_av_info(struct retro_system_av_info *info) { memset(info, 0, sizeof(*info)); - info->timing.fps = 60; + info->timing.fps = is_pal_mode ? 50 : 60; info->timing.sample_rate = 44100; info->geometry.base_width = 320; info->geometry.base_height = 240; @@ -207,37 +265,137 @@ void retro_get_system_av_info(struct retro_system_av_info *info) info->geometry.aspect_ratio = 4.0 / 3.0; } -/* TODO */ +/* savestates */ size_t retro_serialize_size(void) { - return 0; + // it's currently 4380651 bytes, but have some reserved for future + return 0x430000; +} + +struct save_fp { + char *buf; + size_t pos; + int is_write; +}; + +static void *save_open(const char *name, const char *mode) +{ + struct save_fp *fp; + + if (name == NULL || mode == NULL) + return NULL; + + fp = malloc(sizeof(*fp)); + if (fp == NULL) + return NULL; + + fp->buf = (char *)name; + fp->pos = 0; + fp->is_write = (mode[0] == 'w' || mode[1] == 'w'); + + return fp; +} + +static int save_read(void *file, void *buf, u32 len) +{ + struct save_fp *fp = file; + if (fp == NULL || buf == NULL) + return -1; + + memcpy(buf, fp->buf + fp->pos, len); + fp->pos += len; + return len; +} + +static int save_write(void *file, const void *buf, u32 len) +{ + struct save_fp *fp = file; + if (fp == NULL || buf == NULL) + return -1; + + memcpy(fp->buf + fp->pos, buf, len); + fp->pos += len; + return len; +} + +static long save_seek(void *file, long offs, int whence) +{ + struct save_fp *fp = file; + if (fp == NULL) + return -1; + + switch (whence) { + case SEEK_CUR: + fp->pos += offs; + return fp->pos; + case SEEK_SET: + fp->pos = offs; + return fp->pos; + default: + return -1; + } +} + +static void save_close(void *file) +{ + struct save_fp *fp = file; + size_t r_size = retro_serialize_size(); + if (fp == NULL) + return; + + if (fp->pos > r_size) + SysPrintf("ERROR: save buffer overflow detected\n"); + else if (fp->is_write && fp->pos < r_size) + // make sure we don't save trash in leftover space + memset(fp->buf + fp->pos, 0, r_size - fp->pos); + free(fp); } bool retro_serialize(void *data, size_t size) { - return false; + int ret = SaveState(data); + return ret == 0 ? true : false; } bool retro_unserialize(const void *data, size_t size) { - return false; + int ret = LoadState(data); + return ret == 0 ? true : false; } void retro_cheat_reset(void) { + ClearAllCheats(); } void retro_cheat_set(unsigned index, bool enabled, const char *code) { + char buf[256]; + int ret; + + // cheat funcs are destructive, need a copy.. + strncpy(buf, code, sizeof(buf)); + buf[sizeof(buf) - 1] = 0; + + if (index < NumCheats) + ret = EditCheat(index, "", buf); + else + ret = AddCheat("", buf); + + if (ret != 0) + SysPrintf("Failed to set cheat %#u\n", index); + else if (index < NumCheats) + Cheats[index].Enabled = enabled; } bool retro_load_game(const struct retro_game_info *info) { +#ifdef FRONTEND_SUPPORTS_RGB565 enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; if (environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { - native_rgb565 = 1; - fprintf(stderr, "RGB565 supported, using it\n"); + SysPrintf("RGB565 supported, using it\n"); } +#endif if (plugins_opened) { ClosePlugins(); @@ -248,7 +406,7 @@ bool retro_load_game(const struct retro_game_info *info) /* have to reload after set_cd_image for correct cdr plugin */ if (LoadPlugins() == -1) { - printf("faled to load plugins\n"); + SysPrintf("failed to load plugins\n"); return false; } @@ -256,7 +414,7 @@ bool retro_load_game(const struct retro_game_info *info) NetOpened = 0; if (OpenPlugins() == -1) { - printf("faled to open plugins\n"); + SysPrintf("failed to open plugins\n"); return false; } @@ -264,14 +422,14 @@ bool retro_load_game(const struct retro_game_info *info) Config.PsxAuto = 1; if (CheckCdrom() == -1) { - printf("unsupported/invalid CD image: %s\n", info->path); + SysPrintf("unsupported/invalid CD image: %s\n", info->path); return false; } SysReset(); if (LoadCdrom() == -1) { - printf("could not load CD-ROM!\n"); + SysPrintf("could not load CD-ROM!\n"); return false; } emu_on_new_cd(0); @@ -290,17 +448,17 @@ void retro_unload_game(void) unsigned retro_get_region(void) { - return RETRO_REGION_NTSC; + return is_pal_mode ? RETRO_REGION_PAL : RETRO_REGION_NTSC; } void *retro_get_memory_data(unsigned id) { - return NULL; + return Mcd1Data; } size_t retro_get_memory_size(unsigned id) { - return 0; + return MCD_SIZE; } void retro_reset(void) @@ -345,7 +503,11 @@ void retro_run(void) stop = 0; psxCpu->Execute(); - samples_to_send += 44100 / 60; + samples_to_send += is_pal_mode ? 44100 / 50 : 44100 / 60; + + video_cb((vout_fb_dirty || !vout_can_dupe) ? vout_buf : NULL, + vout_width, vout_height, vout_width * 2); + vout_fb_dirty = 0; } void retro_init(void) @@ -359,7 +521,7 @@ void retro_init(void) ret = emu_core_preinit(); ret |= emu_core_init(); if (ret != 0) { - printf("PCSX init failed, sorry\n"); + SysPrintf("PCSX init failed.\n"); exit(1); } @@ -379,14 +541,35 @@ void retro_init(void) } } if (f != NULL) { - printf("found BIOS file: %s\n", Config.Bios); + SysPrintf("found BIOS file: %s\n", Config.Bios); fclose(f); } else - printf("no BIOS files found.\n"); + SysPrintf("no BIOS files found.\n"); level = 1; environ_cb(RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL, &level); + + environ_cb(RETRO_ENVIRONMENT_GET_CAN_DUPE, &vout_can_dupe); + + /* 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 + cycle_multiplier = 200; +#endif + + McdDisable[0] = 0; + McdDisable[1] = 1; + init_memcard(Mcd1Data); + + SaveFuncs.open = save_open; + SaveFuncs.read = save_read; + SaveFuncs.write = save_write; + SaveFuncs.seek = save_seek; + SaveFuncs.close = save_close; } void retro_deinit(void) @@ -395,4 +578,3 @@ void retro_deinit(void) free(vout_buf); vout_buf = NULL; } -