98 lines
3.3 KiB
C
98 lines
3.3 KiB
C
#include <mgba/flags.h>
|
|
#include <mgba/core/core.h>
|
|
#include <mgba/core/thread.h>
|
|
#include <mgba/core/interface.h>
|
|
|
|
#ifdef M_CORE_GBA
|
|
#include <mgba/internal/gba/sio/lockstep.h>
|
|
#endif
|
|
#ifdef M_CORE_GB
|
|
#include <mgba/internal/gb/sio/lockstep.h>
|
|
#endif
|
|
#include <mgba/core/serialize.h>
|
|
#include <mgba-util/vfs.h>
|
|
|
|
#include <msgba/global.h>
|
|
#include <msgba/core_controller.h>
|
|
|
|
|
|
struct msCoreController *
|
|
msCoreControllerLoadGame (const unsigned char *rom, size_t rom_len,
|
|
const unsigned char *state, size_t state_len,
|
|
struct msClientConnectionData *const data) {
|
|
struct VFile* file_rom = VFileMemChunk (NULL, rom_len);
|
|
struct VFile* file_state = VFileMemChunk (NULL, state_len);
|
|
file_rom->seek (file_rom, 0, SEEK_SET);
|
|
file_state->seek (file_state, 0, SEEK_SET);
|
|
file_rom->write (file_rom, rom, rom_len);
|
|
file_state->write (file_state, state, state_len);
|
|
struct mCore *core = mCoreFindVF (file_rom);
|
|
struct msCoreController *controller = NULL;
|
|
if (!core) {
|
|
ms_last_error = "This rom does not appear to be a GBA or GB/C one";
|
|
file_rom->close(file_rom);
|
|
file_state->close(file_rom);
|
|
goto loadGameReturn;
|
|
}
|
|
core->init(core);
|
|
unsigned int width;
|
|
unsigned int height;
|
|
mCoreInitConfig(core, NULL);
|
|
mCoreConfigSetIntValue(&core->config, "logLevel", mLOG_FATAL);
|
|
|
|
core->desiredVideoDimensions(core, &width, &height);
|
|
color_t *outputBuffer = malloc((sizeof *outputBuffer) * width * height);
|
|
printf("controller->outputBuffer width: %u\n", width);
|
|
core->setVideoBuffer(core, outputBuffer, width);
|
|
core->loadROM (core, file_rom);
|
|
mCoreLoadStateNamed (core, file_state, SAVESTATE_SAVEDATA & SAVESTATE_RTC);
|
|
|
|
controller = msCoreControllerNew (core, data);
|
|
controller->outputBuffer = outputBuffer;
|
|
controller->stride = width;
|
|
loadGameReturn:
|
|
return controller;
|
|
}
|
|
|
|
void
|
|
msCoreControllerSetFrameCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *)) {
|
|
self->threadContext.frameCallback = callback;
|
|
}
|
|
void
|
|
msCoreControllerSetStartCallback(struct msCoreController *const self, void(*callback)(struct mCoreThread *)) {
|
|
self->threadContext.startCallback = callback;
|
|
}
|
|
|
|
void
|
|
msCoreControllerThreadStart (struct msCoreController *const core_controller) {
|
|
struct mCoreThread *thread = &core_controller->threadContext;
|
|
mCoreThreadStart(thread);
|
|
}
|
|
|
|
void
|
|
msCoreControllerDestroy(struct msCoreController **controller_ptr) {
|
|
if (controller_ptr && *controller_ptr) {
|
|
struct msCoreController *controller = *controller_ptr;
|
|
|
|
if (mCoreThreadHasStarted(&controller->threadContext)
|
|
&& !mCoreThreadHasExited(&controller->threadContext)) {
|
|
mCoreThreadEnd(&controller->threadContext);
|
|
}
|
|
if (controller->threadContext.core) {
|
|
struct mCore *core = controller->threadContext.core;
|
|
core->deinit(core);
|
|
}
|
|
free(controller->outputBuffer);
|
|
free(controller);
|
|
*controller_ptr = NULL;
|
|
}
|
|
}
|
|
struct msCoreController *
|
|
msCoreControllerNew (struct mCore *core, struct msClientConnectionData *const data) {
|
|
struct msCoreController *controller = malloc (sizeof *controller);
|
|
controller->multiplayer = NULL;
|
|
controller->threadContext.core = core;
|
|
controller->threadContext.userData = data;
|
|
return controller;
|
|
}
|