diff options
author | Twinaphex | 2014-12-09 13:28:17 +0100 |
---|---|---|
committer | Twinaphex | 2014-12-09 13:28:17 +0100 |
commit | 988c2e2655c7c1f724ba727f008d84e3faa6cd24 (patch) | |
tree | da7bf131f33b9ae16d2a93a0a7615a3c0b9c7535 /libretro.c | |
parent | 7bb77f4fc090cadc23c3e05998ccebac7156e3cf (diff) | |
parent | e2d6ea9082a5ff977f834eda0bbb2362397422df (diff) | |
download | picogpsp-988c2e2655c7c1f724ba727f008d84e3faa6cd24.tar.gz picogpsp-988c2e2655c7c1f724ba727f008d84e3faa6cd24.tar.bz2 picogpsp-988c2e2655c7c1f724ba727f008d84e3faa6cd24.zip |
Merge pull request #2 from aliaspider/master
initial port of gpsp to libretro.
Diffstat (limited to 'libretro.c')
-rw-r--r-- | libretro.c | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/libretro.c b/libretro.c new file mode 100644 index 0000000..649a7b8 --- /dev/null +++ b/libretro.c @@ -0,0 +1,367 @@ + + +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include "common.h" +#include "libco.h" +#include "libretro.h" + +#ifndef MAX_PATH +#define MAX_PATH (512) +#endif + +static retro_log_printf_t log_cb; +static retro_video_refresh_t video_cb; +static retro_input_poll_t input_poll_cb; +static retro_environment_t environ_cb; + +struct retro_perf_callback perf_cb; + +static cothread_t main_thread; +static cothread_t cpu_thread; + +/* to be removed */ +u32 savestate_slot = 0; +void get_savestate_filename_noshot(u32 slot, char* name_buffer) +{ + (void) slot; + sprintf(name_buffer, "dummy.svs"); +} +/* ------------ */ + +void switch_to_main_thread(void) +{ + co_switch(main_thread); +} + +static inline void switch_to_cpu_thread(void) +{ + co_switch(cpu_thread); +} + +static void cpu_thread_entry(void) +{ + execute_arm_translate(execute_cycles); + execute_arm(execute_cycles); +} + +static inline void init_context_switch(void) +{ + main_thread = co_active(); + cpu_thread = co_create(0x20000, cpu_thread_entry); +} + +static inline void deinit_context_switch(void) +{ + co_delete(cpu_thread); +} + +#ifdef PERF_TEST + +extern struct retro_perf_callback perf_cb; + +#define RETRO_PERFORMANCE_INIT(X) \ + static struct retro_perf_counter X = {#X}; \ + do { \ + if (!(X).registered) \ + perf_cb.perf_register(&(X)); \ + } while(0) + +#define RETRO_PERFORMANCE_START(X) perf_cb.perf_start(&(X)) +#define RETRO_PERFORMANCE_STOP(X) perf_cb.perf_stop(&(X)) +#else +#define RETRO_PERFORMANCE_INIT(X) +#define RETRO_PERFORMANCE_START(X) +#define RETRO_PERFORMANCE_STOP(X) + +#endif + +void retro_get_system_info(struct retro_system_info* info) +{ + info->library_name = "gpSP"; + info->library_version = "v0.91"; + info->need_fullpath = true; + info->block_extract = false; + info->valid_extensions = "gba|bin|agb|gbz" ; +} + + +void retro_get_system_av_info(struct retro_system_av_info* info) +{ + info->geometry.base_width = GBA_SCREEN_WIDTH; + info->geometry.base_height = GBA_SCREEN_HEIGHT; + info->geometry.max_width = GBA_SCREEN_WIDTH; + info->geometry.max_height = GBA_SCREEN_HEIGHT; + info->geometry.aspect_ratio = 0; + // 59.72750057 hz + info->timing.fps = ((float)(16 * 1024 * 1024)) / (308 * 228 * 4); + info->timing.sample_rate = GBA_SOUND_FREQUENCY; +} + +#include <sys/mman.h> + +void retro_init() +{ + init_gamepak_buffer(); + init_sound(1); + + rom_translation_cache = mmap(NULL, ROM_TRANSLATION_CACHE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + ram_translation_cache = mmap(NULL, RAM_TRANSLATION_CACHE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + bios_translation_cache = mmap(NULL, BIOS_TRANSLATION_CACHE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + + rom_translation_ptr = rom_translation_cache; + ram_translation_ptr = ram_translation_cache; + bios_translation_ptr = bios_translation_cache; +} + +void retro_deinit() +{ + perf_cb.perf_log(); + memory_term(); + + munmap(rom_translation_cache, ROM_TRANSLATION_CACHE_SIZE); + munmap(ram_translation_cache, RAM_TRANSLATION_CACHE_SIZE); + munmap(bios_translation_cache, BIOS_TRANSLATION_CACHE_SIZE); +} + +void retro_set_environment(retro_environment_t cb) +{ + struct retro_log_callback log; + + environ_cb = cb; + + if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log)) + log_cb = log.log; + else + log_cb = NULL; + + environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb); + +} + +void retro_set_video_refresh(retro_video_refresh_t cb) +{ + video_cb = cb; +} +void retro_set_input_poll(retro_input_poll_t cb) +{ + input_poll_cb = cb; +} + +void retro_set_controller_port_device(unsigned port, unsigned device) {} + +void retro_reset() +{ + deinit_context_switch(); + + update_backup(); + reset_gba(); + + init_context_switch(); +} + + +size_t retro_serialize_size() +{ + // return SAVESTATE_SIZE; + return 0; +} + +bool retro_serialize(void* data, size_t size) +{ + // if (size < SAVESTATE_SIZE) + return false; + + // gba_save_state(data); + + // return true; +} + +bool retro_unserialize(const void* data, size_t size) +{ + // if (size < SAVESTATE_SIZE) + return false; + + // gba_load_state(data); + + // return true; +} + +void retro_cheat_reset() {} +void retro_cheat_set(unsigned index, bool enabled, const char* code) {} + +void error_msg(const char* text) +{ + if (log_cb) + log_cb(RETRO_LOG_ERROR, text); +} + +void info_msg(const char* text) +{ + if (log_cb) + log_cb(RETRO_LOG_INFO, text); +} + +static void extract_directory(char* buf, const char* path, size_t size) +{ + strncpy(buf, path, size - 1); + buf[size - 1] = '\0'; + + char* base = strrchr(buf, '/'); + + if (base) + *base = '\0'; + else + strncpy(buf, ".", size); +} + +bool retro_load_game(const struct retro_game_info* info) +{ + char filename_bios[MAX_PATH]; + const char* dir = NULL; + + enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_RGB565; + if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) + { + if (log_cb) + log_cb(RETRO_LOG_INFO, "[TempGBA]: 0RGB1555 is not supported.\n"); + return false; + } + + extract_directory(main_path, info->path, sizeof(main_path)); + + if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir) + strncpy(filename_bios, dir, sizeof(filename_bios)); + else + strncpy(filename_bios, main_path, sizeof(filename_bios)); + + strncat(filename_bios, "/gba_bios.bin", sizeof(filename_bios)); + + + // if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir) + // strncpy(dir_save, dir, sizeof(dir_save)); + // else + // strncpy(dir_save, main_path, sizeof(dir_save)); + + // strncat(dir_save, "/",sizeof(dir_save)); + + // strncat(main_path, "/",sizeof(main_path)); + + if (load_bios(filename_bios) != 0) + { + error_msg("Could not load BIOS image file.\n"); + return false; + } + + if (bios_rom[0] != 0x18) + { + info_msg("You have an incorrect BIOS image.\n"); + info_msg("While many games will work fine, some will not. It\n"); + info_msg("is strongly recommended that you obtain the\n"); + info_msg("correct BIOS file.\n"); + } + + gamepak_filename[0] = 0; + + if (load_gamepak(info->path) != 0) + { + error_msg("Could not load the game file.\n"); + return false; + } + + reset_gba(); + + init_context_switch(); + + return true; +} + + +bool retro_load_game_special(unsigned game_type, + const struct retro_game_info* info, size_t num_info) +{ + return false; +} + +void retro_unload_game() +{ + deinit_context_switch(); + update_backup(); +} + +unsigned retro_get_region() +{ + return RETRO_REGION_NTSC; +} + +void* retro_get_memory_data(unsigned id) +{ + // switch (id) + // { + // case RETRO_MEMORY_SAVE_RAM: + // return gamepak_backup; + // } + + return 0; +} + +size_t retro_get_memory_size(unsigned id) +{ + // switch (id) + // { + // case RETRO_MEMORY_SAVE_RAM: + // switch(backup_type) + // { + // case BACKUP_SRAM: + // return sram_size; + + // case BACKUP_FLASH: + // return flash_size; + + // case BACKUP_EEPROM: + // return eeprom_size; + + // case BACKUP_NONE: + // return 0x0; + + // default: + // return 0x8000; + // } + // } + + return 0; +} + +static void check_variables(void) +{ + +} + +void retro_run() +{ + bool updated = false; + + input_poll_cb(); + + switch_to_cpu_thread(); + + update_input(); + + render_audio(); + + video_cb(gba_screen_pixels, GBA_SCREEN_WIDTH, GBA_SCREEN_HEIGHT, + GBA_SCREEN_PITCH * 2); + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) + check_variables(); + +} + +unsigned retro_api_version() +{ + return RETRO_API_VERSION; +} |