diff options
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/libretro.c | 160 | ||||
-rwxr-xr-x | frontend/libretro.h | 215 | ||||
-rw-r--r-- | frontend/vita/pthread.h | 200 | ||||
-rw-r--r-- | frontend/vita/sys/mman.h | 29 |
4 files changed, 341 insertions, 263 deletions
diff --git a/frontend/libretro.c b/frontend/libretro.c index b13f9c7..589f07c 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -10,6 +10,10 @@ #include <stdlib.h> #include <string.h> #include <strings.h> +#ifdef __MACH__ +#include <unistd.h> +#include <sys/syscall.h> +#endif #include "../libpcsxcore/misc.h" #include "../libpcsxcore/psxcounters.h" @@ -43,6 +47,7 @@ static retro_audio_sample_batch_t audio_batch_cb; static struct retro_rumble_interface rumble; static void *vout_buf; +static void * vout_buf_ptr; static int vout_width, vout_height; static int vout_doffs_old, vout_fb_dirty; static bool vout_can_dupe; @@ -113,6 +118,20 @@ static void vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) { vout_width = w; vout_height = h; + + struct retro_framebuffer fb = {0}; + + fb.width = vout_width; + fb.height = vout_height; + fb.access_flags = RETRO_MEMORY_ACCESS_WRITE; + + vout_buf_ptr = vout_buf; + + if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_RGB565) + { + vout_buf_ptr = (uint16_t*)fb.data; + } + } #ifndef FRONTEND_SUPPORTS_RGB565 @@ -129,14 +148,14 @@ static void convert(void *buf, size_t bytes) static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) { - unsigned short *dest = vout_buf; + unsigned short *dest = vout_buf_ptr; const unsigned short *src = vram; int dstride = vout_width, h1 = h; int doffs; if (vram == NULL) { // blanking - memset(vout_buf, 0, dstride * h * 2); + memset(vout_buf_ptr, 0, dstride * h * 2); goto out; } @@ -144,7 +163,7 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) doffs += (dstride - w) / 2 & ~1; if (doffs != vout_doffs_old) { // clear borders - memset(vout_buf, 0, dstride * h * 2); + memset(vout_buf_ptr, 0, dstride * h * 2); vout_doffs_old = doffs; } dest += doffs; @@ -167,7 +186,7 @@ static void vout_flip(const void *vram, int stride, int bgr24, int w, int h) out: #ifndef FRONTEND_SUPPORTS_RGB565 - convert(vout_buf, vout_width * vout_height * 2); + convert(vout_buf_ptr, vout_width * vout_height * 2); #endif vout_fb_dirty = 1; pl_rearmed_cbs.flip_cnt++; @@ -256,6 +275,88 @@ void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag) } #endif +#ifdef VITA +typedef struct +{ + void* buffer; + uint32_t target_map; + size_t size; + enum psxMapTag tag; +}psx_map_t; + +void* addr = NULL; + +psx_map_t custom_psx_maps[] = { + {NULL, NULL, 0x210000, MAP_TAG_RAM}, // 0x80000000 + {NULL, NULL, 0x010000, MAP_TAG_OTHER}, // 0x1f800000 + {NULL, NULL, 0x080000, MAP_TAG_OTHER}, // 0x1fc00000 + {NULL, NULL, 0x800000, MAP_TAG_LUTS}, // 0x08000000 + {NULL, NULL, 0x200000, MAP_TAG_VRAM}, // 0x00000000 +}; + +int init_vita_mmap(){ + int n; + void * tmpaddr; + addr = malloc(64*1024*1024); + if(addr==NULL) + return -1; + tmpaddr = ((u32)(addr+0xFFFFFF))&~0xFFFFFF; + custom_psx_maps[0].buffer=tmpaddr+0x2000000; + custom_psx_maps[1].buffer=tmpaddr+0x1800000; + custom_psx_maps[2].buffer=tmpaddr+0x1c00000; + custom_psx_maps[3].buffer=tmpaddr+0x0000000; + custom_psx_maps[4].buffer=tmpaddr+0x1000000; +#if 0 + for(n = 0; n < 5; n++){ + sceClibPrintf("addr reserved %x\n",custom_psx_maps[n].buffer); + } +#endif + return 0; +} + +void deinit_vita_mmap(){ + free(addr); +} + +void* pl_vita_mmap(unsigned long addr, size_t size, int is_fixed, + enum psxMapTag tag) +{ + (void)is_fixed; + (void)addr; + + + psx_map_t* custom_map = custom_psx_maps; + + for (; custom_map->size; custom_map++) + { + if ((custom_map->size == size) && (custom_map->tag == tag)) + { + return custom_map->buffer; + } + } + + + return malloc(size); +} + +void pl_vita_munmap(void *ptr, size_t size, enum psxMapTag tag) +{ + (void)tag; + + psx_map_t* custom_map = custom_psx_maps; + + for (; custom_map->size; custom_map++) + { + if ((custom_map->buffer == ptr)) + { + return; + } + } + + free(ptr); +} +#endif + static void *pl_mmap(unsigned int size) { return psxMap(0, size, 0, MAP_TAG_VRAM); @@ -473,7 +574,7 @@ static void update_controller_port_device(unsigned port, unsigned device) static void update_multitap() { struct retro_variable var; - int auto_case; + int auto_case, port; var.value = NULL; var.key = "pcsx_rearmed_multitap1"; @@ -494,7 +595,7 @@ static void update_multitap() { // If a gamepad is plugged after port 2, we need a first multitap. multitap1 = 0; - for (int port = 2; port < PORTS_NUMBER; port++) + for (port = 2; port < PORTS_NUMBER; port++) multitap1 |= in_type[port] != PSE_PAD_TYPE_NONE; } @@ -517,7 +618,7 @@ static void update_multitap() { // If a gamepad is plugged after port 4, we need a second multitap. multitap2 = 0; - for (int port = 4; port < PORTS_NUMBER; port++) + for (port = 4; port < PORTS_NUMBER; port++) multitap2 |= in_type[port] != PSE_PAD_TYPE_NONE; } } @@ -537,7 +638,10 @@ void retro_get_system_info(struct retro_system_info *info) { memset(info, 0, sizeof(*info)); info->library_name = "PCSX-ReARMed"; - info->library_version = "r22"; +#ifndef GIT_VERSION +#define GIT_VERSION "" +#endif + info->library_version = "r22" GIT_VERSION; info->valid_extensions = "bin|cue|img|mdf|pbp|toc|cbn|m3u"; info->need_fullpath = true; } @@ -1204,6 +1308,7 @@ static const unsigned short retro_psx_map[] = { static void update_variables(bool in_flight) { struct retro_variable var; + int i; var.value = NULL; var.key = "pcsx_rearmed_frameskip"; @@ -1223,7 +1328,7 @@ static void update_variables(bool in_flight) Config.PsxType = 1; } - for (int i = 0; i < PORTS_NUMBER; i++) + for (i = 0; i < PORTS_NUMBER; i++) update_controller_port_variable(i); update_multitap(); @@ -1362,6 +1467,11 @@ static void update_variables(bool in_flight) } } +static int min(int a, int b) +{ + return a < b ? a : b; +} + void retro_run(void) { int i; @@ -1387,17 +1497,17 @@ void retro_run(void) if (in_type[i] == PSE_PAD_TYPE_ANALOGPAD) { - in_analog_left[i][0] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; - in_analog_left[i][1] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; - in_analog_right[i][0] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 256) + 128; - in_analog_right[i][1] = (input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 256) + 128; + in_analog_left[i][0] = min((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_X) / 255) + 128, 255); + in_analog_left[i][1] = min((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_LEFT, RETRO_DEVICE_ID_ANALOG_Y) / 255) + 128, 255); + in_analog_right[i][0] = min((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_X) / 255) + 128, 255); + in_analog_right[i][1] = min((input_state_cb(i, RETRO_DEVICE_ANALOG, RETRO_DEVICE_INDEX_ANALOG_RIGHT, RETRO_DEVICE_ID_ANALOG_Y) / 255) + 128, 255); } } stop = 0; psxCpu->Execute(); - video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf : NULL, + video_cb((vout_fb_dirty || !vout_can_dupe || !duping_enable) ? vout_buf_ptr : NULL, vout_width, vout_height, vout_width * 2); vout_fb_dirty = 0; } @@ -1470,16 +1580,28 @@ void retro_init(void) int i, ret; bool found_bios = false; +#ifdef __MACH__ + // magic sauce to make the dynarec work on iOS + syscall(SYS_ptrace, 0 /*PTRACE_TRACEME*/, 0, 0, 0); +#endif + #ifdef _3DS psxMapHook = pl_3ds_mmap; psxUnmapHook = pl_3ds_munmap; #endif +#ifdef VITA + if(init_vita_mmap()<0) + abort(); + psxMapHook = pl_vita_mmap; + psxUnmapHook = pl_vita_munmap; +#endif ret = emu_core_preinit(); -#ifdef _3DS +#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"); @@ -1493,7 +1615,9 @@ void retro_init(void) #else vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2); #endif - + + vout_buf_ptr = vout_buf; + if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir) { snprintf(Config.BiosDir, sizeof(Config.BiosDir), "%s", dir); @@ -1559,6 +1683,10 @@ void retro_deinit(void) free(vout_buf); #endif vout_buf = NULL; + +#ifdef VITA + deinit_vita_mmap(); +#endif } #ifdef VITA diff --git a/frontend/libretro.h b/frontend/libretro.h index 16c274a..a231548 100755 --- a/frontend/libretro.h +++ b/frontend/libretro.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2014 The RetroArch team +/* Copyright (C) 2010-2016 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). @@ -43,6 +43,40 @@ extern "C" { #endif #endif +#ifndef RETRO_CALLCONV +# if defined(__GNUC__) && defined(__i386__) && !defined(__x86_64__) +# define RETRO_CALLCONV __attribute__((cdecl)) +# elif defined(_MSC_VER) && defined(_M_X86) && !defined(_M_X64) +# define RETRO_CALLCONV __cdecl +# else +# define RETRO_CALLCONV /* all other platforms only have one calling convention each */ +# endif +#endif + +#ifndef RETRO_API +# if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) +# ifdef RETRO_IMPORT_SYMBOLS +# ifdef __GNUC__ +# define RETRO_API RETRO_CALLCONV __attribute__((__dllimport__)) +# else +# define RETRO_API RETRO_CALLCONV __declspec(dllimport) +# endif +# else +# ifdef __GNUC__ +# define RETRO_API RETRO_CALLCONV __attribute__((__dllexport__)) +# else +# define RETRO_API RETRO_CALLCONV __declspec(dllexport) +# endif +# endif +# else +# if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__CELLOS_LV2__) +# define RETRO_API RETRO_CALLCONV __attribute__((__visibility__("default"))) +# else +# define RETRO_API RETRO_CALLCONV +# endif +# endif +#endif + /* Used for checking API/ABI mismatches that can break libretro * implementations. * It is not incremented for compatible changes to the API. @@ -165,13 +199,15 @@ extern "C" { #define RETRO_DEVICE_ID_ANALOG_Y 1 /* Id values for MOUSE. */ -#define RETRO_DEVICE_ID_MOUSE_X 0 -#define RETRO_DEVICE_ID_MOUSE_Y 1 -#define RETRO_DEVICE_ID_MOUSE_LEFT 2 -#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 -#define RETRO_DEVICE_ID_MOUSE_WHEELUP 4 -#define RETRO_DEVICE_ID_MOUSE_WHEELDOWN 5 -#define RETRO_DEVICE_ID_MOUSE_MIDDLE 6 +#define RETRO_DEVICE_ID_MOUSE_X 0 +#define RETRO_DEVICE_ID_MOUSE_Y 1 +#define RETRO_DEVICE_ID_MOUSE_LEFT 2 +#define RETRO_DEVICE_ID_MOUSE_RIGHT 3 +#define RETRO_DEVICE_ID_MOUSE_WHEELUP 4 +#define RETRO_DEVICE_ID_MOUSE_WHEELDOWN 5 +#define RETRO_DEVICE_ID_MOUSE_MIDDLE 6 +#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP 7 +#define RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN 8 /* Id values for LIGHTGUN types. */ #define RETRO_DEVICE_ID_LIGHTGUN_X 0 @@ -206,6 +242,8 @@ enum retro_language RETRO_LANGUAGE_KOREAN = 9, RETRO_LANGUAGE_CHINESE_TRADITIONAL = 10, RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11, + RETRO_LANGUAGE_ESPERANTO = 12, + RETRO_LANGUAGE_POLISH = 13, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -693,9 +731,10 @@ enum retro_mod * location-based information from the host device, * such as current latitude / longitude. */ -#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 +#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30 /* Old name, kept for compatibility. */ +#define RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY 30 /* const char ** -- - * Returns the "content" directory of the frontend. + * Returns the "core assets" directory of the frontend. * This directory can be used to store specific assets that the * core relies upon, such as art assets, * input data, etc etc. @@ -851,6 +890,61 @@ enum retro_mod * Returns the specified language of the frontend, if specified by the user. * It can be used by the core for localization purposes. */ +#define RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER (40 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_framebuffer * -- + * Returns a preallocated framebuffer which the core can use for rendering + * the frame into when not using SET_HW_RENDER. + * The framebuffer returned from this call must not be used + * after the current call to retro_run() returns. + * + * The goal of this call is to allow zero-copy behavior where a core + * can render directly into video memory, avoiding extra bandwidth cost by copying + * memory from core to video memory. + * + * If this call succeeds and the core renders into it, + * the framebuffer pointer and pitch can be passed to retro_video_refresh_t. + * If the buffer from GET_CURRENT_SOFTWARE_FRAMEBUFFER is to be used, + * the core must pass the exact + * same pointer as returned by GET_CURRENT_SOFTWARE_FRAMEBUFFER; + * i.e. passing a pointer which is offset from the + * buffer is undefined. The width, height and pitch parameters + * must also match exactly to the values obtained from GET_CURRENT_SOFTWARE_FRAMEBUFFER. + * + * It is possible for a frontend to return a different pixel format + * than the one used in SET_PIXEL_FORMAT. This can happen if the frontend + * needs to perform conversion. + * + * It is still valid for a core to render to a different buffer + * even if GET_CURRENT_SOFTWARE_FRAMEBUFFER succeeds. + * + * A frontend must make sure that the pointer obtained from this function is + * writeable (and readable). + */ + +enum retro_hw_render_interface_type +{ + RETRO_HW_RENDER_INTERFACE_VULKAN = 0, + RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX +}; + +/* Base struct. All retro_hw_render_interface_* types + * contain at least these fields. */ +struct retro_hw_render_interface +{ + enum retro_hw_render_interface_type interface_type; + unsigned interface_version; +}; +#define RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE (41 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* const struct retro_hw_render_interface ** -- + * Returns an API specific rendering interface for accessing API specific data. + * Not all HW rendering APIs support or need this. + * The contents of the returned pointer is specific to the rendering API + * being used. See the various headers like libretro_vulkan.h, etc. + * + * GET_HW_RENDER_INTERFACE cannot be called before context_reset has been called. + * Similarly, after context_destroyed callback returns, + * the contents of the HW_RENDER_INTERFACE are invalidated. + */ #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ @@ -1125,6 +1219,10 @@ struct retro_log_callback #define RETRO_SIMD_VFPU (1 << 13) #define RETRO_SIMD_PS (1 << 14) #define RETRO_SIMD_AES (1 << 15) +#define RETRO_SIMD_VFPV3 (1 << 16) +#define RETRO_SIMD_VFPV4 (1 << 17) +#define RETRO_SIMD_POPCNT (1 << 18) +#define RETRO_SIMD_MOVBE (1 << 19) typedef uint64_t retro_perf_tick_t; typedef int64_t retro_time_t; @@ -1464,6 +1562,9 @@ enum retro_hw_context_type * use the corresponding enums directly. */ RETRO_HW_CONTEXT_OPENGLES_VERSION = 5, + /* Vulkan, see RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE. */ + RETRO_HW_CONTEXT_VULKAN = 6, + RETRO_HW_CONTEXT_DUMMY = INT_MAX }; @@ -1486,23 +1587,28 @@ struct retro_hw_render_callback */ retro_hw_context_reset_t context_reset; - /* Set by frontend. */ + /* Set by frontend. + * TODO: This is rather obsolete. The frontend should not + * be providing preallocated framebuffers. */ retro_hw_get_current_framebuffer_t get_current_framebuffer; /* Set by frontend. */ retro_hw_get_proc_address_t get_proc_address; - /* Set if render buffers should have depth component attached. */ + /* Set if render buffers should have depth component attached. + * TODO: Obsolete. */ bool depth; - /* Set if stencil buffers should be attached. */ + /* Set if stencil buffers should be attached. + * TODO: Obsolete. */ bool stencil; /* If depth and stencil are true, a packed 24/8 buffer will be added. * Only attaching stencil is invalid and will be ignored. */ /* Use conventional bottom-left origin convention. If false, - * standard libretro top-left origin semantics are used. */ + * standard libretro top-left origin semantics are used. + * TODO: Move to GL specific interface. */ bool bottom_left_origin; /* Major version number for core GL context or GLES 3.1+. */ @@ -1513,6 +1619,7 @@ struct retro_hw_render_callback /* If this is true, the frontend will go very far to avoid * resetting context in scenarios like toggling fullscreen, etc. + * TODO: Obsolete? Maybe frontend should just always assume this ... */ bool cache_context; @@ -1779,6 +1886,36 @@ struct retro_game_info const char *meta; /* String of implementation specific meta-data. */ }; +#define RETRO_MEMORY_ACCESS_WRITE (1 << 0) + /* The core will write to the buffer provided by retro_framebuffer::data. */ +#define RETRO_MEMORY_ACCESS_READ (1 << 1) + /* The core will read from retro_framebuffer::data. */ +#define RETRO_MEMORY_TYPE_CACHED (1 << 0) + /* The memory in data is cached. + * If not cached, random writes and/or reading from the buffer is expected to be very slow. */ +struct retro_framebuffer +{ + void *data; /* The framebuffer which the core can render into. + Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. + The initial contents of data are unspecified. */ + unsigned width; /* The framebuffer width used by the core. Set by core. */ + unsigned height; /* The framebuffer height used by the core. Set by core. */ + size_t pitch; /* The number of bytes between the beginning of a scanline, + and beginning of the next scanline. + Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */ + enum retro_pixel_format format; /* The pixel format the core must use to render into data. + This format could differ from the format used in + SET_PIXEL_FORMAT. + Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */ + + unsigned access_flags; /* How the core will access the memory in the framebuffer. + RETRO_MEMORY_ACCESS_* flags. + Set by core. */ + unsigned memory_flags; /* Flags telling core how the memory has been mapped. + RETRO_MEMORY_TYPE_* flags. + Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */ +}; + /* Callbacks */ /* Environment callback. Gives implementations a way of performing @@ -1832,25 +1969,25 @@ typedef int16_t (*retro_input_state_t)(unsigned port, unsigned device, * * The rest of the set_* functions are guaranteed to have been called * before the first call to retro_run() is made. */ -void retro_set_environment(retro_environment_t); -void retro_set_video_refresh(retro_video_refresh_t); -void retro_set_audio_sample(retro_audio_sample_t); -void retro_set_audio_sample_batch(retro_audio_sample_batch_t); -void retro_set_input_poll(retro_input_poll_t); -void retro_set_input_state(retro_input_state_t); +RETRO_API void retro_set_environment(retro_environment_t); +RETRO_API void retro_set_video_refresh(retro_video_refresh_t); +RETRO_API void retro_set_audio_sample(retro_audio_sample_t); +RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t); +RETRO_API void retro_set_input_poll(retro_input_poll_t); +RETRO_API void retro_set_input_state(retro_input_state_t); /* Library global initialization/deinitialization. */ -void retro_init(void); -void retro_deinit(void); +RETRO_API void retro_init(void); +RETRO_API void retro_deinit(void); /* Must return RETRO_API_VERSION. Used to validate ABI compatibility * when the API is revised. */ -unsigned retro_api_version(void); +RETRO_API unsigned retro_api_version(void); /* Gets statically known system info. Pointers provided in *info * must be statically allocated. * Can be called at any time, even before retro_init(). */ -void retro_get_system_info(struct retro_system_info *info); +RETRO_API void retro_get_system_info(struct retro_system_info *info); /* Gets information about system audio/video timings and geometry. * Can be called only after retro_load_game() has successfully completed. @@ -1858,7 +1995,7 @@ void retro_get_system_info(struct retro_system_info *info); * variable if needed. * E.g. geom.aspect_ratio might not be initialized if core doesn't * desire a particular aspect ratio. */ -void retro_get_system_av_info(struct retro_system_av_info *info); +RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info); /* Sets device to be used for player 'port'. * By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all @@ -1868,10 +2005,10 @@ void retro_get_system_av_info(struct retro_system_av_info *info); * hint to the libretro core when a core cannot automatically detect the * appropriate input device type on its own. It is also relevant when a * core can change its behavior depending on device type. */ -void retro_set_controller_port_device(unsigned port, unsigned device); +RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device); /* Resets the current game. */ -void retro_reset(void); +RETRO_API void retro_reset(void); /* Runs the game for one video frame. * During retro_run(), input_poll callback must be called at least once. @@ -1881,7 +2018,7 @@ void retro_reset(void); * a frame if GET_CAN_DUPE returns true. * In this case, the video callback can take a NULL argument for data. */ -void retro_run(void); +RETRO_API void retro_run(void); /* Returns the amount of data the implementation requires to serialize * internal state (save states). @@ -1889,35 +2026,35 @@ void retro_run(void); * returned size is never allowed to be larger than a previous returned * value, to ensure that the frontend can allocate a save state buffer once. */ -size_t retro_serialize_size(void); +RETRO_API size_t retro_serialize_size(void); /* Serializes internal state. If failed, or size is lower than * retro_serialize_size(), it should return false, true otherwise. */ -bool retro_serialize(void *data, size_t size); -bool retro_unserialize(const void *data, size_t size); +RETRO_API bool retro_serialize(void *data, size_t size); +RETRO_API bool retro_unserialize(const void *data, size_t size); -void retro_cheat_reset(void); -void retro_cheat_set(unsigned index, bool enabled, const char *code); +RETRO_API void retro_cheat_reset(void); +RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code); /* Loads a game. */ -bool retro_load_game(const struct retro_game_info *game); +RETRO_API bool retro_load_game(const struct retro_game_info *game); /* Loads a "special" kind of game. Should not be used, * except in extreme cases. */ -bool retro_load_game_special( +RETRO_API bool retro_load_game_special( unsigned game_type, const struct retro_game_info *info, size_t num_info ); /* Unloads a currently loaded game. */ -void retro_unload_game(void); +RETRO_API void retro_unload_game(void); /* Gets region of game. */ -unsigned retro_get_region(void); +RETRO_API unsigned retro_get_region(void); /* Gets region of memory. */ -void *retro_get_memory_data(unsigned id); -size_t retro_get_memory_size(unsigned id); +RETRO_API void *retro_get_memory_data(unsigned id); +RETRO_API size_t retro_get_memory_size(unsigned id); #ifdef __cplusplus } diff --git a/frontend/vita/pthread.h b/frontend/vita/pthread.h deleted file mode 100644 index c18b20b..0000000 --- a/frontend/vita/pthread.h +++ /dev/null @@ -1,200 +0,0 @@ -/* Copyright (C) 2010-2015 The RetroArch team - * - * --------------------------------------------------------------------------------------- - * The following license statement only applies to this file (psp_pthread.h). - * --------------------------------------------------------------------------------------- - * - * Permission is hereby granted, free of charge, - * to any person obtaining a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* FIXME: unfinished on PSP, mutexes and condition variables basically a stub. */ -#ifndef _PSP_PTHREAD_WRAP__ -#define _PSP_PTHREAD_WRAP__ - -#ifdef VITA -#include <psp2/kernel/threadmgr.h> -#else -#include <pspkernel.h> -#include <pspthreadman.h> -#include <pspthreadman_kernel.h> -#endif -#include <stdio.h> -#include <retro_inline.h> - -#define STACKSIZE (64 * 1024) - -typedef SceUID pthread_t; -typedef SceUID pthread_mutex_t; -typedef void* pthread_mutexattr_t; -typedef int pthread_attr_t; -typedef SceUID pthread_cond_t; -typedef SceUID pthread_condattr_t; - -/* Use pointer values to create unique names for threads/mutexes */ -char name_buffer[256]; - -typedef void* (*sthreadEntry)(void *argp); - -typedef struct -{ - void* arg; - sthreadEntry start_routine; -} sthread_args_struct; - - -static int psp_thread_wrap(SceSize args, void *argp) -{ - sthread_args_struct* sthread_args = (sthread_args_struct*)argp; - - return (int)sthread_args->start_routine(sthread_args->arg); -} - -static INLINE int pthread_create(pthread_t *thread, - const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) -{ - sprintf(name_buffer, "0x%08X", (uint32_t) thread); - - *thread = sceKernelCreateThread(name_buffer, - psp_thread_wrap, 0x20, STACKSIZE, 0, -#ifdef VITA - 0, -#endif - NULL); - - sthread_args_struct sthread_args; - sthread_args.arg = arg; - sthread_args.start_routine = start_routine; - - return sceKernelStartThread(*thread, sizeof(sthread_args), &sthread_args); -} - -static INLINE int pthread_mutex_init(pthread_mutex_t *mutex, - const pthread_mutexattr_t *attr) -{ - sprintf(name_buffer, "0x%08X", (uint32_t) mutex); - -#ifdef VITA - return *mutex = sceKernelCreateMutex(name_buffer, 0, 0, 0); -#else - return *mutex = sceKernelCreateSema(name_buffer, 0, 1, 1, NULL); -#endif -} - -static INLINE int pthread_mutex_destroy(pthread_mutex_t *mutex) -{ -#ifdef VITA - return sceKernelDeleteMutex(*mutex); -#else - return sceKernelDeleteSema(*mutex); -#endif -} - -static INLINE int pthread_mutex_lock(pthread_mutex_t *mutex) -{ -#ifdef VITA - return sceKernelLockMutex(*mutex, 1, 0); -#else - /* FIXME: stub */ - return 1; -#endif -} - -static INLINE int pthread_mutex_unlock(pthread_mutex_t *mutex) -{ -#ifdef VITA - return sceKernelUnlockMutex(*mutex, 1); -#else - /* FIXME: stub */ - return 1; -#endif -} - - -static INLINE int pthread_join(pthread_t thread, void **retval) -{ - int exit_status; - SceUInt timeout = (SceUInt)-1; -#ifdef VITA - sceKernelWaitThreadEnd(thread, &exit_status, &timeout); -#else - sceKernelWaitThreadEnd(thread, &timeout); - exit_status = sceKernelGetThreadExitStatus(thread); -#endif - sceKernelDeleteThread(thread); - return exit_status; -} - -static INLINE int pthread_mutex_trylock(pthread_mutex_t *mutex) -{ -#ifdef VITA - return sceKernelTryLockMutex(*mutex, 1 /* not sure about this last param */); -#else - /* FIXME: stub */ - return 1; -#endif -} - -static INLINE int pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) -{ - sceKernelDelayThread(10000); - return 1; -} - -static INLINE int pthread_cond_timedwait(pthread_cond_t *cond, - pthread_mutex_t *mutex, const struct timespec *abstime) -{ - //FIXME: stub - return 1; -} - -static INLINE int pthread_cond_init(pthread_cond_t *cond, - const pthread_condattr_t *attr) -{ - //FIXME: stub - return 1; -} - -static INLINE int pthread_cond_signal(pthread_cond_t *cond) -{ - //FIXME: stub - return 1; -} - -static INLINE int pthread_cond_broadcast(pthread_cond_t *cond) -{ - //FIXME: stub - return 1; -} - -static INLINE int pthread_cond_destroy(pthread_cond_t *cond) -{ - //FIXME: stub - return 1; -} - - -static INLINE int pthread_detach(pthread_t thread) -{ - return 1; -} - -static INLINE void pthread_exit(void *retval) -{ - (void)retval; -} - -#endif //_PSP_PTHREAD_WRAP__ diff --git a/frontend/vita/sys/mman.h b/frontend/vita/sys/mman.h index 66467f4..89da513 100644 --- a/frontend/vita/sys/mman.h +++ b/frontend/vita/sys/mman.h @@ -18,19 +18,32 @@ extern "C" { static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { - (void)addr; (void)prot; (void)flags; (void)fd; (void)offset; - void* addr_out; + int block, ret; + + block = sceKernelAllocMemBlockForVM("code", len); + if(block<=0){ + sceClibPrintf("could not alloc mem block @0x%08X 0x%08X \n", block, len); + exit(1); + } + + // get base address + ret = sceKernelGetMemBlockBase(block, &addr); + if (ret < 0) + { + sceClibPrintf("could get address @0x%08X 0x%08X \n", block, addr); + exit(1); + } + - addr_out = malloc(len); - if(!addr_out) + if(!addr) return MAP_FAILED; - return addr_out; + return addr; } static inline int mprotect(void *addr, size_t len, int prot) @@ -43,8 +56,9 @@ static inline int mprotect(void *addr, size_t len, int prot) static inline int munmap(void *addr, size_t len) { - free(addr); - return 0; + int uid = sceKernelFindMemBlockByAddr(addr, len); + + return sceKernelFreeMemBlock(uid); } @@ -53,4 +67,3 @@ static inline int munmap(void *addr, size_t len) #endif #endif // MMAN_H - |