all repos — mgba @ cd0a352a33d1613196ad5c3fa7e2af055e0fbecc

mGBA Game Boy Advance Emulator

3DS, Wii: GB support partially working
Jeffrey Pfau jeffrey@endrift.com
Sun, 14 Feb 2016 19:02:45 -0800
commit

cd0a352a33d1613196ad5c3fa7e2af055e0fbecc

parent

8615defda763c928eadb4c0919081a74b6bd28fc

M CMakeLists.txtCMakeLists.txt

@@ -473,24 +473,6 @@ foreach(FEATURE IN LISTS FEATURES)

list(APPEND FEATURE_DEFINES "USE_${FEATURE}") endforeach() -source_group("Virtual files" FILES ${CORE_VFS_SRC} ${VFS_SRC}) -source_group("Extra features" FILES ${FEATURE_SRC}) -source_group("Third-party code" FILES ${THIRD_PARTY_SRC}) - -# Platform binaries -if(3DS) - add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/3ds ${CMAKE_BINARY_DIR}/3ds) -endif() - -if(WII) - add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/wii ${CMAKE_BINARY_DIR}/wii) -endif() - -if(PSP2) - add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/psp2 ${CMAKE_BINARY_DIR}/psp2) -endif() - -# Binaries set(CORE_SRC) if(M_CORE_GB) add_definitions(-DM_CORE_GB)

@@ -514,6 +496,24 @@ list(APPEND CORE_SRC ${CMAKE_SOURCE_DIR}/src/gb/audio.c)

endif() endif() +source_group("Virtual files" FILES ${CORE_VFS_SRC} ${VFS_SRC}) +source_group("Extra features" FILES ${FEATURE_SRC}) +source_group("Third-party code" FILES ${THIRD_PARTY_SRC}) + +# Platform binaries +if(3DS) + add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/3ds ${CMAKE_BINARY_DIR}/3ds) +endif() + +if(WII) + add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/wii ${CMAKE_BINARY_DIR}/wii) +endif() + +if(PSP2) + add_subdirectory(${CMAKE_SOURCE_DIR}/src/platform/psp2 ${CMAKE_BINARY_DIR}/psp2) +endif() + +# Binaries list(APPEND CORE_SRC ${UTIL_SRC} ${CORE_VFS_SRC}
M src/gb/core.csrc/gb/core.c

@@ -153,7 +153,9 @@

static void _GBCoreReset(struct mCore* core) { struct GBCore* gbcore = (struct GBCore*) core; struct GB* gb = (struct GB*) core->board; - GBVideoAssociateRenderer(&gb->video, &gbcore->renderer.d); + if (gbcore->renderer.outputBuffer) { + GBVideoAssociateRenderer(&gb->video, &gbcore->renderer.d); + } LR35902Reset(core->cpu); }
M src/gba/core.csrc/gba/core.c

@@ -85,7 +85,7 @@ struct GBACore* gbacore = (struct GBACore*) core;

gbacore->overrides = mCoreConfigGetOverridesConst(config); struct VFile* bios = 0; - if (core->opts.useBios) { + if (core->opts.useBios && core->opts.bios) { bios = VFileOpen(core->opts.bios, O_RDONLY); } if (bios) {
M src/gba/gui/gui-runner.csrc/gba/gui/gui-runner.c

@@ -1,11 +1,11 @@

-/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2016 Jeffrey Pfau * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gui-runner.h" -#include "gba/core.h" +#include "core/core.h" #include "gba/gui/gui-config.h" #include "gba/input.h" #include "gba/interface.h"

@@ -63,7 +63,10 @@ if (gbaBackground->screenshot && gbaBackground->screenshotId == (int) id) {

gbaBackground->p->drawScreenshot(gbaBackground->p, gbaBackground->screenshot, true); return; } - struct VFile* vf = GBAGetState(gbaBackground->p->core->board, gbaBackground->p->core->dirs.state, stateId, false); + struct VFile* vf = NULL; + if (gbaBackground->p->core->platform(gbaBackground->p->core) == PLATFORM_GBA) { + vf = GBAGetState(gbaBackground->p->core->board, gbaBackground->p->core->dirs.state, stateId, false); + } uint32_t* pixels = gbaBackground->screenshot; if (!pixels) { pixels = anonymousMemoryMap(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4);

@@ -108,47 +111,24 @@ }

void mGUIInit(struct mGUIRunner* runner, const char* port) { GUIInit(&runner->params); - runner->core = GBACoreCreate(); - runner->core->init(runner->core); - mInputMapInit(&runner->core->inputMap, &GBAInputInfo); - mCoreInitConfig(runner->core, port); + runner->port = port; + runner->core = NULL; runner->luminanceSource.d.readLuminance = _readLux; runner->luminanceSource.d.sample = _updateLux; runner->luminanceSource.luxLevel = 0; - ((struct GBA*) runner->core->board)->luminanceSource = &runner->luminanceSource.d; runner->background.d.draw = _drawBackground; runner->background.p = runner; runner->fps = 0; runner->lastFpsCheck = 0; runner->totalDelta = 0; CircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); - if (runner->setup) { - runner->setup(runner); - } - - if (runner->core->config.port && runner->keySources) { - size_t i; - for (i = 0; runner->keySources[i].id; ++i) { - mInputMapLoad(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); - } - } } void mGUIDeinit(struct mGUIRunner* runner) { if (runner->teardown) { runner->teardown(runner); } - if (runner->core->config.port) { - if (runner->keySources) { - size_t i; - for (i = 0; runner->keySources[i].id; ++i) { - mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); - } - } - mCoreConfigSave(&runner->core->config); - } CircleBufferDeinit(&runner->fpsBuffer); - runner->core->deinit(runner->core); } void mGUIRun(struct mGUIRunner* runner, const char* path) {

@@ -218,7 +198,28 @@ runner->params.guiFinish();

} runner->params.drawEnd(); - if (!mCoreLoadFile(runner->core, path)) { + bool found = false; + runner->core = mCoreFind(path); + if (runner->core) { + runner->core->init(runner->core); + mInputMapInit(&runner->core->inputMap, &GBAInputInfo); + mCoreInitConfig(runner->core, runner->port); + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + ((struct GBA*) runner->core->board)->luminanceSource = &runner->luminanceSource.d; + } + if (runner->core->config.port && runner->keySources) { + size_t i; + for (i = 0; runner->keySources[i].id; ++i) { + mInputMapLoad(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); + } + } + found = mCoreLoadFile(runner->core, path); + if (!found) { + runner->core->deinit(runner->core); + } + } + + if (!found) { int i; for (i = 0; i < 240; ++i) { runner->params.drawStart();

@@ -234,6 +235,9 @@ }

return; } mCoreAutoloadSave(runner->core); + if (runner->setup) { + runner->setup(runner); + } runner->core->reset(runner->core); bool running = true; if (runner->gameLoaded) {

@@ -346,7 +350,7 @@ mCoreTakeScreenshot(runner->core);

break; case RUNNER_CONFIG: mGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra); - mCoreConfigGetIntValue(&runner->core->config, "frameskip", &((struct GBA*) runner->core->board)->video.frameskip); + mCoreLoadConfig(runner->core); break; case RUNNER_CONTINUE: break;

@@ -373,6 +377,18 @@ drawState.screenshotId = 0;

if (drawState.screenshot) { mappedMemoryFree(drawState.screenshot, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4); } + + if (runner->core->config.port) { + if (runner->keySources) { + size_t i; + for (i = 0; runner->keySources[i].id; ++i) { + mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->core->config)); + } + } + mCoreConfigSave(&runner->core->config); + } + runner->core->deinit(runner->core); + GUIMenuItemListDeinit(&pauseMenu.items); GUIMenuItemListDeinit(&stateSaveMenu.items); GUIMenuItemListDeinit(&stateLoadMenu.items);
M src/gba/gui/gui-runner.hsrc/gba/gui/gui-runner.h

@@ -45,6 +45,7 @@ size_t nConfigExtra;

struct GUIInputKeys* keySources; + const char* port; float fps; int64_t lastFpsCheck; int32_t totalDelta;
M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -249,9 +249,11 @@ screenCleanup |= SCREEN_CLEANUP_BOTTOM;

} static void _setup(struct mGUIRunner* runner) { - ((struct GBA*) runner->core->board)->rotationSource = &rotation.d; + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + ((struct GBA*) runner->core->board)->rotationSource = &rotation.d; + } if (hasSound != NO_SOUND) { - ((struct GBA*) runner->core->board)->stream = &stream; + runner->core->setAVStream(runner->core, &stream); } _map3DSKey(&runner->core->inputMap, KEY_A, GBA_KEY_A);

@@ -277,17 +279,19 @@ runner->core->setAudioBufferSize(runner->core, AUDIO_SAMPLES);

} static void _gameLoaded(struct mGUIRunner* runner) { - if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_TILT) { - HIDUSER_EnableAccelerometer(); - } - if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { - HIDUSER_EnableGyroscope(); + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_TILT) { + HIDUSER_EnableAccelerometer(); + } + if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { + HIDUSER_EnableGyroscope(); + } } osSetSpeedupEnable(true); double ratio = GBAAudioCalculateRatio(1, 59.8260982880808, 1); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), GBA_ARM7TDMI_FREQUENCY, 32768 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), GBA_ARM7TDMI_FREQUENCY, 32768 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768 * ratio); if (hasSound != NO_SOUND) { audioPos = 0; }

@@ -314,28 +318,33 @@ csndExecCmds(false);

} osSetSpeedupEnable(false); - if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_TILT) { - HIDUSER_DisableAccelerometer(); - } - if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { - HIDUSER_DisableGyroscope(); + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_TILT) { + HIDUSER_DisableAccelerometer(); + } + if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { + HIDUSER_DisableGyroscope(); + } } } -static void _drawTex(bool faded) { +static void _drawTex(struct mCore* core, bool faded) { u32 color = faded ? 0x3FFFFFFF : 0xFFFFFFFF; int screen_w = screenMode < SM_PA_TOP ? 320 : 400; int screen_h = 240; + unsigned corew, coreh; + core->desiredVideoDimensions(core, &corew, &coreh); + int w, h; switch (screenMode) { case SM_PA_TOP: case SM_PA_BOTTOM: default: - w = VIDEO_HORIZONTAL_PIXELS; - h = VIDEO_VERTICAL_PIXELS; + w = corew; + h = coreh; break; case SM_AF_TOP: w = 360;

@@ -356,7 +365,7 @@

int x = (screen_w - w) / 2; int y = (screen_h - h) / 2; - ctrAddRectScaled(color, x, y, w, h, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + ctrAddRectScaled(color, x, y, w, h, 0, 0, corew, coreh); } static void _drawFrame(struct mGUIRunner* runner, bool faded) {

@@ -379,7 +388,7 @@ }

gspWaitForPPF(); ctrActivateTexture(tex); - _drawTex(faded); + _drawTex(runner->core, faded); } static void _drawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, bool faded) {

@@ -413,7 +422,7 @@ gspWaitForPPF();

linearFree(newPixels); ctrActivateTexture(tex); - _drawTex(faded); + _drawTex(runner->core, faded); } static uint16_t _pollGameInput(struct mGUIRunner* runner) {
M src/platform/wii/main.csrc/platform/wii/main.c

@@ -88,6 +88,7 @@ static int32_t gyroZ;

static uint32_t retraceCount; static uint32_t referenceRetraceCount; static int scaleFactor; +static unsigned corew, coreh; static void* framebuffer[2] = { 0, 0 }; static int whichFb = 0;

@@ -125,11 +126,9 @@ GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);

GX_SetFieldMode(vmode->field_rendering, ((vmode->viHeight == 2 * vmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); if (core) { - unsigned width = VIDEO_HORIZONTAL_PIXELS; - unsigned height = VIDEO_VERTICAL_PIXELS; - core->desiredVideoDimensions(core, &width, &height); - int hfactor = vmode->fbWidth / width; - int vfactor = vmode->efbHeight / height; + core->desiredVideoDimensions(core, &corew, &coreh); + int hfactor = vmode->fbWidth / corew; + int vfactor = vmode->efbHeight / coreh; if (hfactor > vfactor) { scaleFactor = vfactor; } else {

@@ -515,15 +514,17 @@ }

void _guiFinish(void) { if (screenMode == SM_PA) { - _reproj(VIDEO_HORIZONTAL_PIXELS * scaleFactor, VIDEO_VERTICAL_PIXELS * scaleFactor); + _reproj(corew * scaleFactor, coreh * scaleFactor); } else { - _reproj2(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + _reproj2(corew, coreh); } } void _setup(struct mGUIRunner* runner) { - ((struct GBA*) runner->core->board)->rumble = &rumble; - ((struct GBA*) runner->core->board)->rotationSource = &rotation; + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + ((struct GBA*) runner->core->board)->rumble = &rumble; + ((struct GBA*) runner->core->board)->rotationSource = &rotation; + } _mapKey(&runner->core->inputMap, GCN1_INPUT, PAD_BUTTON_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, GCN1_INPUT, PAD_BUTTON_B, GBA_KEY_B);

@@ -572,8 +573,8 @@

runner->core->setAudioBufferSize(runner->core, SAMPLES); double ratio = GBAAudioCalculateRatio(1, 60 / 1.001, 1); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), GBA_ARM7TDMI_FREQUENCY, 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), GBA_ARM7TDMI_FREQUENCY, 48000 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); } void _gameUnloaded(struct mGUIRunner* runner) {

@@ -583,7 +584,7 @@ }

void _gameLoaded(struct mGUIRunner* runner) { reconfigureScreen(runner->core, vmode); - if (((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { + if (runner->core->platform(runner->core) == PLATFORM_GBA && ((struct GBA*) runner->core->board)->memory.hw.devices & HW_GYRO) { int i; for (i = 0; i < 6; ++i) { u32 result = WPAD_SetMotionPlus(0, 1);

@@ -644,8 +645,8 @@ }

size_t x, y; uint64_t* texdest = (uint64_t*) texmem; uint64_t* texsrc = (uint64_t*) outputBuffer; - for (y = 0; y < VIDEO_VERTICAL_PIXELS; y += 4) { - for (x = 0; x < VIDEO_HORIZONTAL_PIXELS >> 2; ++x) { + for (y = 0; y < coreh; y += 4) { + for (x = 0; x < corew >> 2; ++x) { texdest[0 + x * 4 + y * 64] = texsrc[0 + x + y * 64]; texdest[1 + x * 4 + y * 64] = texsrc[64 + x + y * 64]; texdest[2 + x * 4 + y * 64] = texsrc[128 + x + y * 64];