mirror of https://github.com/mgba-emu/mgba.git
OpenEmu: Convert to using mCore
This commit is contained in:
parent
c581764e23
commit
752b4faaff
|
@ -19,6 +19,7 @@ struct GBACore {
|
||||||
struct mCore d;
|
struct mCore d;
|
||||||
struct GBAVideoSoftwareRenderer renderer;
|
struct GBAVideoSoftwareRenderer renderer;
|
||||||
int keys;
|
int keys;
|
||||||
|
struct ARMComponent* components[GBA_COMPONENT_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool _GBACoreInit(struct mCore* core) {
|
static bool _GBACoreInit(struct mCore* core) {
|
||||||
|
@ -36,7 +37,8 @@ static bool _GBACoreInit(struct mCore* core) {
|
||||||
|
|
||||||
GBACreate(gba);
|
GBACreate(gba);
|
||||||
// TODO: Restore debugger and cheats
|
// TODO: Restore debugger and cheats
|
||||||
ARMSetComponents(cpu, &gba->d, 0, 0);
|
memset(gbacore->components, 0, sizeof(gbacore->components));
|
||||||
|
ARMSetComponents(cpu, &gba->d, GBA_COMPONENT_MAX, gbacore->components);
|
||||||
ARMInit(cpu);
|
ARMInit(cpu);
|
||||||
|
|
||||||
GBAVideoSoftwareRendererCreate(&gbacore->renderer);
|
GBAVideoSoftwareRendererCreate(&gbacore->renderer);
|
||||||
|
|
|
@ -26,11 +26,14 @@
|
||||||
|
|
||||||
#include "util/common.h"
|
#include "util/common.h"
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "gba/audio.h"
|
||||||
#include "gba/cheats.h"
|
#include "gba/cheats.h"
|
||||||
|
#include "gba/core.h"
|
||||||
#include "gba/cheats/gameshark.h"
|
#include "gba/cheats/gameshark.h"
|
||||||
#include "gba/renderers/video-software.h"
|
#include "gba/gba.h"
|
||||||
|
#include "gba/input.h"
|
||||||
#include "gba/serialize.h"
|
#include "gba/serialize.h"
|
||||||
#include "gba/context/context.h"
|
|
||||||
#include "util/circle-buffer.h"
|
#include "util/circle-buffer.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/vfs.h"
|
#include "util/vfs.h"
|
||||||
|
@ -43,11 +46,11 @@
|
||||||
|
|
||||||
@interface mGBAGameCore () <OEGBASystemResponderClient>
|
@interface mGBAGameCore () <OEGBASystemResponderClient>
|
||||||
{
|
{
|
||||||
struct GBAContext context;
|
struct mCore* core;
|
||||||
struct GBAVideoSoftwareRenderer renderer;
|
struct GBA* gba;
|
||||||
struct GBACheatDevice cheats;
|
struct GBACheatDevice cheats;
|
||||||
|
void* outputBuffer;
|
||||||
NSMutableDictionary *cheatSets;
|
NSMutableDictionary *cheatSets;
|
||||||
uint16_t keys;
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -57,21 +60,25 @@
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
// TODO: Add a log handler
|
core = GBACoreCreate();
|
||||||
GBAContextInit(&context, 0);
|
mCoreInitConfig(core, nil);
|
||||||
|
|
||||||
struct mCoreOptions opts = {
|
struct mCoreOptions opts = {
|
||||||
.useBios = true,
|
.useBios = true,
|
||||||
};
|
};
|
||||||
mCoreConfigLoadDefaults(&context.config, &opts);
|
mCoreConfigLoadDefaults(&core->config, &opts);
|
||||||
GBAVideoSoftwareRendererCreate(&renderer);
|
core->init(core);
|
||||||
renderer.outputBuffer = malloc(256 * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
|
|
||||||
renderer.outputBufferStride = 256;
|
unsigned width, height;
|
||||||
context.renderer = &renderer.d;
|
core->desiredVideoDimensions(core, &width, &height);
|
||||||
GBAAudioResizeBuffer(&context.gba->audio, SAMPLES);
|
outputBuffer = malloc(width * height * BYTES_PER_PIXEL);
|
||||||
|
core->setVideoBuffer(core, outputBuffer, width);
|
||||||
|
|
||||||
|
gba = core->board;
|
||||||
|
GBAAudioResizeBuffer(&gba->audio, SAMPLES);
|
||||||
GBACheatDeviceCreate(&cheats);
|
GBACheatDeviceCreate(&cheats);
|
||||||
GBACheatAttachDevice(context.gba, &cheats);
|
GBACheatAttachDevice(gba, &cheats);
|
||||||
cheatSets = [[NSMutableDictionary alloc] init];
|
cheatSets = [[NSMutableDictionary alloc] init];
|
||||||
keys = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -79,7 +86,7 @@
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
GBAContextDeinit(&context);
|
core->deinit(core);
|
||||||
[cheatSets enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
[cheatSets enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||||
UNUSED(key);
|
UNUSED(key);
|
||||||
UNUSED(stop);
|
UNUSED(stop);
|
||||||
|
@ -92,7 +99,7 @@
|
||||||
GBACheatSetDeinit([obj pointerValue]);
|
GBACheatSetDeinit([obj pointerValue]);
|
||||||
}];
|
}];
|
||||||
[cheatSets release];
|
[cheatSets release];
|
||||||
free(renderer.outputBuffer);
|
free(outputBuffer);
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -106,50 +113,42 @@
|
||||||
withIntermediateDirectories:YES
|
withIntermediateDirectories:YES
|
||||||
attributes:nil
|
attributes:nil
|
||||||
error:nil];
|
error:nil];
|
||||||
if (context.dirs.save) {
|
if (core->dirs.save) {
|
||||||
context.dirs.save->close(context.dirs.save);
|
core->dirs.save->close(core->dirs.save);
|
||||||
}
|
}
|
||||||
context.dirs.save = VDirOpen([batterySavesDirectory UTF8String]);
|
core->dirs.save = VDirOpen([batterySavesDirectory UTF8String]);
|
||||||
|
|
||||||
if (!GBAContextLoadROM(&context, [path UTF8String], true)) {
|
if (!mCoreLoadFile(core, [path UTF8String])) {
|
||||||
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:nil];
|
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:nil];
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
mCoreAutoloadSave(core);
|
||||||
|
|
||||||
if (!GBAContextStart(&context)) {
|
core->reset(core);
|
||||||
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotStartCoreError userInfo:nil];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)executeFrame
|
- (void)executeFrame
|
||||||
{
|
{
|
||||||
GBAContextFrame(&context, keys);
|
core->runFrame(core);
|
||||||
|
|
||||||
int16_t samples[SAMPLES * 2];
|
int16_t samples[SAMPLES * 2];
|
||||||
size_t available = 0;
|
size_t available = 0;
|
||||||
available = blip_samples_avail(context.gba->audio.psg.left);
|
available = blip_samples_avail(core->getAudioChannel(core, 0));
|
||||||
blip_read_samples(context.gba->audio.psg.left, samples, available, true);
|
blip_read_samples(core->getAudioChannel(core, 0), samples, available, true);
|
||||||
blip_read_samples(context.gba->audio.psg.right, samples + 1, available, true);
|
blip_read_samples(core->getAudioChannel(core, 1), samples + 1, available, true);
|
||||||
[[self ringBufferAtIndex:0] write:samples maxLength:available * 4];
|
[[self ringBufferAtIndex:0] write:samples maxLength:available * 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)resetEmulation
|
- (void)resetEmulation
|
||||||
{
|
{
|
||||||
ARMReset(context.cpu);
|
core->reset(core);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)stopEmulation
|
|
||||||
{
|
|
||||||
GBAContextStop(&context);
|
|
||||||
[super stopEmulation];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setupEmulation
|
- (void)setupEmulation
|
||||||
{
|
{
|
||||||
blip_set_rates(context.gba->audio.psg.left, GBA_ARM7TDMI_FREQUENCY, 32768);
|
blip_set_rates(core->getAudioChannel(core, 0), GBA_ARM7TDMI_FREQUENCY, 32768);
|
||||||
blip_set_rates(context.gba->audio.psg.right, GBA_ARM7TDMI_FREQUENCY, 32768);
|
blip_set_rates(core->getAudioChannel(core, 1), GBA_ARM7TDMI_FREQUENCY, 32768);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Video
|
#pragma mark - Video
|
||||||
|
@ -161,17 +160,21 @@
|
||||||
|
|
||||||
- (OEIntRect)screenRect
|
- (OEIntRect)screenRect
|
||||||
{
|
{
|
||||||
return OEIntRectMake(0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
|
unsigned width, height;
|
||||||
|
core->desiredVideoDimensions(core, &width, &height);
|
||||||
|
return OEIntRectMake(0, 0, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (OEIntSize)bufferSize
|
- (OEIntSize)bufferSize
|
||||||
{
|
{
|
||||||
return OEIntSizeMake(256, VIDEO_VERTICAL_PIXELS);
|
unsigned width, height;
|
||||||
|
core->desiredVideoDimensions(core, &width, &height);
|
||||||
|
return OEIntSizeMake(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (const void *)videoBuffer
|
- (const void *)videoBuffer
|
||||||
{
|
{
|
||||||
return renderer.outputBuffer;
|
return outputBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (GLenum)pixelFormat
|
- (GLenum)pixelFormat
|
||||||
|
@ -211,7 +214,7 @@
|
||||||
- (NSData *)serializeStateWithError:(NSError **)outError
|
- (NSData *)serializeStateWithError:(NSError **)outError
|
||||||
{
|
{
|
||||||
struct VFile* vf = VFileMemChunk(nil, 0);
|
struct VFile* vf = VFileMemChunk(nil, 0);
|
||||||
if (!GBASaveStateNamed(context.gba, vf, SAVESTATE_SAVEDATA)) {
|
if (!core->saveState(core, vf, SAVESTATE_SAVEDATA)) {
|
||||||
*outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil];
|
*outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil];
|
||||||
vf->close(vf);
|
vf->close(vf);
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -227,7 +230,7 @@
|
||||||
- (BOOL)deserializeState:(NSData *)state withError:(NSError **)outError
|
- (BOOL)deserializeState:(NSData *)state withError:(NSError **)outError
|
||||||
{
|
{
|
||||||
struct VFile* vf = VFileFromConstMemory(state.bytes, state.length);
|
struct VFile* vf = VFileFromConstMemory(state.bytes, state.length);
|
||||||
if (!GBALoadStateNamed(context.gba, vf, SAVESTATE_SAVEDATA)) {
|
if (!core->loadState(core, vf, SAVESTATE_SAVEDATA)) {
|
||||||
*outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil];
|
*outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil];
|
||||||
vf->close(vf);
|
vf->close(vf);
|
||||||
return NO;
|
return NO;
|
||||||
|
@ -239,14 +242,14 @@
|
||||||
- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
||||||
{
|
{
|
||||||
struct VFile* vf = VFileOpen([fileName UTF8String], O_CREAT | O_TRUNC | O_RDWR);
|
struct VFile* vf = VFileOpen([fileName UTF8String], O_CREAT | O_TRUNC | O_RDWR);
|
||||||
block(GBASaveStateNamed(context.gba, vf, 0), nil);
|
block(core->saveState(core, vf, 0), nil);
|
||||||
vf->close(vf);
|
vf->close(vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
|
||||||
{
|
{
|
||||||
struct VFile* vf = VFileOpen([fileName UTF8String], O_RDONLY);
|
struct VFile* vf = VFileOpen([fileName UTF8String], O_RDONLY);
|
||||||
block(GBALoadStateNamed(context.gba, vf, 0), nil);
|
block(core->loadState(core, vf, 0), nil);
|
||||||
vf->close(vf);
|
vf->close(vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,13 +271,13 @@ const int GBAMap[] = {
|
||||||
- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player
|
- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player
|
||||||
{
|
{
|
||||||
UNUSED(player);
|
UNUSED(player);
|
||||||
keys |= 1 << GBAMap[button];
|
core->addKeys(core, 1 << GBAMap[button]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player
|
- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player
|
||||||
{
|
{
|
||||||
UNUSED(player);
|
UNUSED(player);
|
||||||
keys &= ~(1 << GBAMap[button]);
|
core->clearKeys(core, 1 << GBAMap[button]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Cheats
|
#pragma mark - Cheats
|
||||||
|
|
Loading…
Reference in New Issue