Added initial LibRetro support.

This commit is contained in:
Cody Brocious 2016-06-04 16:50:30 -06:00
parent 6c9c929cc1
commit b27f4bd17a
6 changed files with 2281 additions and 67 deletions

View file

@ -26,6 +26,7 @@ public:
map<uint32_t, Device *> pci;
uint32_t xbebase;
uint32_t kernel_entry;
bool frame_rendered = false; // Trigger return from cpu
};

View file

@ -13,10 +13,10 @@ endif
OBJ_FILES := $(CPP_FILES:.cpp=.o)
all: NightBeliever zookeeper
all: NightBeliever zookeeper_libretro.dylib
zookeeper: $(OBJ_FILES)
clang++ -g $(CC_FLAGS) -lboost_regex-mt -framework Hypervisor -o zookeeper $(OBJ_FILES)
zookeeper_libretro.dylib: $(OBJ_FILES)
clang++ -g $(CC_FLAGS) -dynamiclib -lboost_regex-mt -framework Hypervisor -o zookeeper_libretro.dylib $(OBJ_FILES)
.PHONY: NightBeliever

168
RetroAPI.cpp Normal file
View file

@ -0,0 +1,168 @@
#include "Zookeeper.hpp"
#include <libgen.h>
retro_environment_t env;
uint32_t load_multiboot(uint32_t *header) {
assert(header[1] & 0x10000);
uint8_t *rel = (uint8_t *) header;
uint32_t memsize = header[6] - KBASE;
if(memsize & PAGE_MASK)
memsize = (memsize & ~PAGE_MASK) + PAGE_SIZE;
assert(memsize <= KRAM_SIZE);
memcpy(box->cpu->kmem + (header[4] - KBASE), rel + (header[4] - header[3]), memsize);
memset(box->cpu->kmem + (header[5] - KBASE), 0, header[6] - header[5]);
box->cpu->map_pages(KBASE, KBASE, memsize / PAGE_SIZE);
return header[7];
}
uint32_t load_kernel() {
char *path;
env(RETRO_ENVIRONMENT_GET_LIBRETRO_PATH, &path);
auto temp = strdup(path);
string full = dirname(temp);
full += "/nightbeliever.krnl";
FILE *fp = fopen(full.c_str(), "r");
delete temp;
fseek(fp, 0, SEEK_END);
uint32_t size = ftell(fp);
uint8_t *buf = new uint8_t[size];
fseek(fp, 0, SEEK_SET);
fread(buf, 1, size, fp);
uint32_t *seek = (uint32_t *) buf;
uint32_t *end = (uint32_t *) (buf + size);
uint32_t entry;
do {
if(*seek == 0x1BADB002 && seek[2] == -(seek[0] + seek[1])) {
if((entry = load_multiboot(seek)) != -1)
break;
}
} while(++seek != end);
if(seek == end) {
cout << "Reached EOF before finding Multiboot header!" << endl;
}
delete[] buf;
return entry;
}
RETRO_API unsigned retro_api_version() {
return RETRO_API_VERSION;
}
void intHandler(int _) {
break_in();
}
RETRO_API void retro_init() {
// signal(SIGINT, intHandler);
}
RETRO_API void retro_deinit() {
}
RETRO_API void retro_get_system_info(struct retro_system_info *info) {
info->library_name = "Zookeeper";
info->library_version = "Pre-Alpha 1";
info->valid_extensions = "xbe|iso";
info->need_fullpath = true;
info->block_extract = false;
}
RETRO_API bool retro_load_game(const struct retro_game_info *game) {
new Box;
box->kernel_entry = load_kernel();
auto xbe = new Xbe((char *) game->path);
xbe->LoadImage();
return true;
}
RETRO_API bool retro_load_game_special(
unsigned game_type,
const struct retro_game_info *info, size_t num_info
) {
return false;
}
RETRO_API void retro_unload_game() {
delete box;
}
RETRO_API void retro_run() {
box->cpu->run(box->kernel_entry);
box->kernel_entry = -1; // Ensure we don't just keep going back here
}
RETRO_API void retro_get_system_av_info(struct retro_system_av_info *info) {
info->geometry.base_width = 1280;
info->geometry.base_height = 720;
info->timing.fps = 30;
info->timing.sample_rate = 44100;
}
RETRO_API void retro_set_environment(retro_environment_t cb) {
env = cb;
}
RETRO_API void retro_set_video_refresh(retro_video_refresh_t cb) {
}
RETRO_API void retro_set_audio_sample(retro_audio_sample_t cb) {
}
RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) {
}
RETRO_API void retro_set_input_poll(retro_input_poll_t cb) {
}
RETRO_API void retro_set_input_state(retro_input_state_t cb) {
}
RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device) {
}
RETRO_API void retro_reset() {
}
RETRO_API size_t retro_serialize_size(void) {
return 0;
}
RETRO_API bool retro_serialize(void *data, size_t size) {
return false;
}
RETRO_API bool retro_unserialize(const void *data, size_t size) {
return false;
}
RETRO_API void retro_cheat_reset() {
}
RETRO_API void retro_cheat_set(unsigned index, bool enabled, const char *code) {
}
/* Gets region of game. */
RETRO_API unsigned retro_get_region(void) {
return 0;
}
/* Gets region of memory. */
RETRO_API void *retro_get_memory_data(unsigned id) {
return NULL;
}
RETRO_API size_t retro_get_memory_size(unsigned id) {
return 0;
}

View file

@ -22,6 +22,8 @@ using boost::format;
#define KBASE 0xC0000000
#include "libretro.h"
#include "HV.hpp"
#ifdef MAC
#include "Mac/HVMac.hpp"

2107
libretro.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,64 +0,0 @@
#include "Zookeeper.hpp"
uint32_t load_multiboot(uint32_t *header) {
assert(header[1] & 0x10000);
uint8_t *rel = (uint8_t *) header;
uint32_t memsize = header[6] - KBASE;
if(memsize & PAGE_MASK)
memsize = (memsize & ~PAGE_MASK) + PAGE_SIZE;
assert(memsize <= KRAM_SIZE);
memcpy(box->cpu->kmem + (header[4] - KBASE), rel + (header[4] - header[3]), memsize);
memset(box->cpu->kmem + (header[5] - KBASE), 0, header[6] - header[5]);
box->cpu->map_pages(KBASE, KBASE, memsize / PAGE_SIZE);
return header[7];
}
uint32_t load_kernel() {
FILE *fp = fopen("nightbeliever.krnl", "r");
fseek(fp, 0, SEEK_END);
uint32_t size = ftell(fp);
uint8_t *buf = new uint8_t[size];
fseek(fp, 0, SEEK_SET);
fread(buf, 1, size, fp);
uint32_t *seek = (uint32_t *) buf;
uint32_t *end = (uint32_t *) (buf + size);
uint32_t entry;
do {
if(*seek == 0x1BADB002 && seek[2] == -(seek[0] + seek[1])) {
if((entry = load_multiboot(seek)) != -1)
break;
}
} while(++seek != end);
if(seek == end) {
cout << "Reached EOF before finding Multiboot header!" << endl;
}
delete[] buf;
return entry;
}
void intHandler(int _) {
break_in();
}
int main(int argc, char **argv) {
new Box;
uint32_t entry = load_kernel();
auto xbe = new Xbe((char *) "test1.xbe");
xbe->LoadImage();
signal(SIGINT, intHandler);
box->cpu->run(entry);
delete box;
return 0;
}