From b790dd8e7518d9ab8edfd5e18bfd1a0eecf35482 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Oct 2018 14:41:01 -0700 Subject: [PATCH 01/50] Python: Minor API improvements --- CHANGES | 1 + src/platform/python/mgba/core.py | 15 +++++++++++++++ src/platform/python/mgba/gamedata.py | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 5e922cdf6..c6be2b40d 100644 --- a/CHANGES +++ b/CHANGES @@ -136,6 +136,7 @@ Misc: - Debugger: Minor text fixes - Qt: Debugger console history - Qt: Detect presence of GL_ARB_framebuffer_object + - Python: Minor API improvements 0.7 beta 1: (2018-09-24) - Initial beta for 0.7 diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 6c91af213..94b685328 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -167,51 +167,65 @@ class Core(object): def _load(self): self._was_reset = True + @protected def load_file(self, path): return bool(lib.mCoreLoadFile(self._core, path.encode('UTF-8'))) def is_rom(self, vfile): return bool(self._core.isROM(vfile.handle)) + @protected def load_rom(self, vfile): return bool(self._core.loadROM(self._core, vfile.handle)) + @protected def load_bios(self, vfile, id=0): return bool(self._core.loadBIOS(self._core, vfile.handle, id)) + @protected def load_save(self, vfile): return bool(self._core.loadSave(self._core, vfile.handle)) + @protected def load_temporary_save(self, vfile): return bool(self._core.loadTemporarySave(self._core, vfile.handle)) + @protected def load_patch(self, vfile): return bool(self._core.loadPatch(self._core, vfile.handle)) + @protected def load_config(self, config): lib.mCoreLoadForeignConfig(self._core, config._native) + @protected def autoload_save(self): return bool(lib.mCoreAutoloadSave(self._core)) + @protected def autoload_patch(self): return bool(lib.mCoreAutoloadPatch(self._core)) + @protected def autoload_cheats(self): return bool(lib.mCoreAutoloadCheats(self._core)) + @property def platform(self): return self._core.platform(self._core) + @protected def desired_video_dimensions(self): width = ffi.new("unsigned*") height = ffi.new("unsigned*") self._core.desiredVideoDimensions(self._core, width, height) return width[0], height[0] + @protected def set_video_buffer(self, image): self._core.setVideoBuffer(self._core, image.buffer, image.stride) + @protected def reset(self): self._core.reset(self._core) self._load() @@ -227,6 +241,7 @@ class Core(object): self._core.runLoop(self._core) @needs_reset + @protected def step(self): self._core.step(self._core) diff --git a/src/platform/python/mgba/gamedata.py b/src/platform/python/mgba/gamedata.py index 301da4812..6151326e1 100644 --- a/src/platform/python/mgba/gamedata.py +++ b/src/platform/python/mgba/gamedata.py @@ -11,10 +11,10 @@ except ImportError: def search(core): crc32 = None - if hasattr(core, 'PLATFORM_GBA') and core.platform() == core.PLATFORM_GBA: + if hasattr(core, 'PLATFORM_GBA') and core.platform == core.PLATFORM_GBA: platform = 'GBA' crc32 = core.crc32 - if hasattr(core, 'PLATFORM_GB') and core.platform() == core.PLATFORM_GB: + if hasattr(core, 'PLATFORM_GB') and core.platform == core.PLATFORM_GB: platform = 'GB' crc32 = core.crc32 cls = mgba_gamedata.registry.search(platform, {'crc32': crc32}) From 4346c5db1b931df3bde87631d628f398e10e4461 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Oct 2018 15:21:52 -0700 Subject: [PATCH 02/50] Python: Experimental audio API --- CHANGES | 1 + src/platform/python/_builder.h | 1 + src/platform/python/_builder.py | 1 + src/platform/python/mgba/audio.py | 57 +++++++++++++++++++++++++++++++ src/platform/python/mgba/core.py | 18 +++++++++- 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/platform/python/mgba/audio.py diff --git a/CHANGES b/CHANGES index c6be2b40d..6bacf4db9 100644 --- a/CHANGES +++ b/CHANGES @@ -111,6 +111,7 @@ Features: - Qt: State file load/save menu options - Windows installer - Tile viewer now has adjustable width + - Python: Experimental audio API Bugfixes: - PSP2: Fix audio crackling after fast forward - PSP2: Fix audio crackling when buffer is full diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index bc1ee9d40..9a0d2b624 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -35,6 +35,7 @@ void free(void*); #include "flags.h" +#include #include #include #include diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 707703c5b..45518fa4f 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -20,6 +20,7 @@ ffi.set_source("mgba._pylib", """ #define inline #include "flags.h" #define OPAQUE_THREADING +#include #include #include #include diff --git a/src/platform/python/mgba/audio.py b/src/platform/python/mgba/audio.py new file mode 100644 index 000000000..a833d0827 --- /dev/null +++ b/src/platform/python/mgba/audio.py @@ -0,0 +1,57 @@ +# Copyright (c) 2013-2018 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/. +from ._pylib import ffi, lib # pylint: disable=no-name-in-module + + +class Buffer(object): + def __init__(self, native, internal_rate): + self._native = native + self._internal_rate = internal_rate + + @property + def available(self): + return lib.blip_samples_avail(self._native) + + def set_rate(self, rate): + lib.blip_set_rates(self._native, self._internal_rate, rate) + + def read(self, samples): + buffer = ffi.new("short[%i]" % samples) + count = self.read_into(buffer, samples, 1, 0) + return buffer[:count] + + def read_into(self, buffer, samples, channels=1, interleave=0): + return lib.blip_read_samples(self._native, ffi.addressof(buffer, interleave), samples, channels == 2) + + def clear(self): + lib.blip_clear(self._native) + + +class StereoBuffer(object): + def __init__(self, left, right): + self._left = left + self._right = right + + @property + def available(self): + return min(self._left.available, self._right.available) + + def set_rate(self, rate): + self._left.set_rate(rate) + self._right.set_rate(rate) + + def read(self, samples): + buffer = ffi.new("short[%i]" % (2 * samples)) + count = self.read_into(buffer, samples) + return buffer[0:2 * count] + + def read_into(self, buffer, samples): + samples = self._left.read_into(buffer, samples, 2, 0) + return self._right.read_into(buffer, samples, 2, 1) + + def clear(self): + self._left.clear() + self._right.clear() diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 94b685328..1399b1ad6 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -4,7 +4,7 @@ # 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/. from ._pylib import ffi, lib # pylint: disable=no-name-in-module -from . import tile +from . import tile, audio from cached_property import cached_property from functools import wraps @@ -225,6 +225,22 @@ class Core(object): def set_video_buffer(self, image): self._core.setVideoBuffer(self._core, image.buffer, image.stride) + @protected + def set_audio_buffer_size(self, size) + self._core.setAudioBufferSize(self._core, size) + + @property + def audio_buffer_size(self): + return self._core.getAudioBufferSize(self._core) + + @protected + def get_audio_channels(self): + return audio.StereoBuffer(self.get_audio_channel(0), self.get_audio_channel(1)); + + @protected + def get_audio_channel(self, channel): + return audio.Buffer(self._core.getAudioChannel(self._core, channel), self.frequency) + @protected def reset(self): self._core.reset(self._core) From 357e2e2d6be4c31d25404e29421468a2c8e6d6ac Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Oct 2018 15:39:42 -0700 Subject: [PATCH 03/50] Python: Fix syntax error --- src/platform/python/mgba/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 1399b1ad6..7a0672322 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -226,7 +226,7 @@ class Core(object): self._core.setVideoBuffer(self._core, image.buffer, image.stride) @protected - def set_audio_buffer_size(self, size) + def set_audio_buffer_size(self, size): self._core.setAudioBufferSize(self._core, size) @property From 8fd76bc9f53f208c511c776e8406eb05d50e0443 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Oct 2018 20:02:32 -0700 Subject: [PATCH 04/50] PSP2: Simplify frame limiter code --- src/platform/psp2/main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index c33c7228c..31540b89b 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -25,18 +25,17 @@ #include static void _drawStart(void) { - vita2d_set_vblank_wait(false); + static int vcount = 0; + extern bool frameLimiter; + int oldVCount = vcount; + vcount = sceDisplayGetVcount(); + vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount); vita2d_start_drawing(); vita2d_clear_screen(); } static void _drawEnd(void) { - static int vcount = 0; - extern bool frameLimiter; - int oldVCount = vcount; vita2d_end_drawing(); - vcount = sceDisplayGetVcount(); - vita2d_set_vblank_wait(frameLimiter && vcount + 1 >= oldVCount); vita2d_swap_buffers(); } From c1a8e32fc1851d5daf719689453531f26b212cc1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Oct 2018 20:18:00 -0700 Subject: [PATCH 05/50] PSP2: Fix tearing issues (fixes #1211) --- CHANGES | 1 + src/platform/psp2/main.c | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 6bacf4db9..de70636d3 100644 --- a/CHANGES +++ b/CHANGES @@ -125,6 +125,7 @@ Bugfixes: - GB, GBA Savedata: Fix leaks when loading masked save (fixes mgba.io/i/1197) - Qt: Fix focus issues with load/save state overlay - GB Video: Fix SGB border hole size + - PSP2: Fix tearing issues (fixes mgba.io/i/1211) Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index 31540b89b..8060d26ae 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -36,6 +36,7 @@ static void _drawStart(void) { static void _drawEnd(void) { vita2d_end_drawing(); + vita2d_wait_rendering_done(); vita2d_swap_buffers(); } From 76ccf41c25d89de5448883d77b95ef69a341ae78 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Tue, 9 Oct 2018 19:05:09 +0200 Subject: [PATCH 06/50] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index ec6ce7f87..5f2748367 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -4624,20 +4624,30 @@ wenn vorhanden Tiles - + 256 colors 256 Farben - + × × - + Magnification Vergrößerung + + + Tiles per row + Tiles pro Zeile + + + + Fit to window + An Fenster anpassen + VideoView From af1d114f49450c39e0253500952a94fe490e6734 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 10:15:59 -0700 Subject: [PATCH 07/50] 3DS: Reuse screenshot buffer, cleanup --- src/platform/3ds/main.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index f08290edc..1f3d496a5 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -84,7 +84,8 @@ static enum { } hasSound; // TODO: Move into context -static void* outputBuffer; +static color_t* outputBuffer = NULL; +static color_t* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; @@ -135,6 +136,11 @@ static void _cleanup(void) { if (outputBuffer) { linearFree(outputBuffer); + outputBuffer = NULL; + } + if (screenshotBuffer) { + linearFree(screenshotBuffer); + screenshotBuffer = NULL; } C3D_RenderTargetDelete(topScreen[0]); @@ -276,7 +282,7 @@ static void _setup(struct mGUIRunner* runner) { _map3DSKey(&runner->core->inputMap, KEY_L, GBA_KEY_L); _map3DSKey(&runner->core->inputMap, KEY_R, GBA_KEY_R); - outputBuffer = linearMemAlign(256 * 224 * 2, 0x80); + outputBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); runner->core->setVideoBuffer(runner->core, outputBuffer, 256); unsigned mode; @@ -547,7 +553,7 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { GSPGPU_FlushDataCache(outputBuffer, 256 * VIDEO_VERTICAL_PIXELS * 2); C3D_SyncDisplayTransfer( - outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), + (u32*) outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), tex->data, GX_BUFFER_DIM(256, 256), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) | @@ -564,22 +570,22 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { C3D_Tex* tex = &outputTexture; - color_t* newPixels = linearMemAlign(256 * height * sizeof(color_t), 0x100); - + if (!screenshotBuffer) { + screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); + } unsigned y; for (y = 0; y < height; ++y) { - memcpy(&newPixels[y * 256], &pixels[y * width], width * sizeof(color_t)); - memset(&newPixels[y * 256 + width], 0, (256 - width) * sizeof(color_t)); + memcpy(&screenshotBuffer[y * 256], &pixels[y * width], width * sizeof(color_t)); + memset(&screenshotBuffer[y * 256 + width], 0, (256 - width) * sizeof(color_t)); } - GSPGPU_FlushDataCache(newPixels, 256 * height * sizeof(u32)); + GSPGPU_FlushDataCache(screenshotBuffer, 256 * height * sizeof(color_t)); C3D_SyncDisplayTransfer( - (u32*) newPixels, GX_BUFFER_DIM(256, height), + (u32*) screenshotBuffer, GX_BUFFER_DIM(256, height), tex->data, GX_BUFFER_DIM(256, 256), GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1)); - linearFree(newPixels); _drawTex(runner->core, faded); } From 50d735b99b0dbb6e24eda5c40176f1519dc651ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 11:11:48 -0700 Subject: [PATCH 08/50] GBA Savedata: EEPROM performance fixes --- CHANGES | 2 ++ include/mgba/internal/gba/savedata.h | 3 ++- src/gba/dma.c | 6 +----- src/gba/memory.c | 2 +- src/gba/savedata.c | 28 ++++++++++++++++++++++------ 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index de70636d3..58af4992b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 0.8.0: (Future) Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) +Misc: + - GBA Savedata: EEPROM performance fixes 0.7.0: (Future) Features: diff --git a/include/mgba/internal/gba/savedata.h b/include/mgba/internal/gba/savedata.h index ecf17eecf..05cd65963 100644 --- a/include/mgba/internal/gba/savedata.h +++ b/include/mgba/internal/gba/savedata.h @@ -23,7 +23,8 @@ enum SavedataType { SAVEDATA_SRAM = 1, SAVEDATA_FLASH512 = 2, SAVEDATA_FLASH1M = 3, - SAVEDATA_EEPROM = 4 + SAVEDATA_EEPROM = 4, + SAVEDATA_EEPROM512 = 5 }; enum SavedataCommand { diff --git a/src/gba/dma.c b/src/gba/dma.c index cf5174fdb..2a33eae94 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -266,11 +266,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { memory->dmaTransferRegister &= 0xFFFF0000; memory->dmaTransferRegister |= memory->dmaTransferRegister >> 16; } else { - if (sourceRegion == REGION_CART2_EX && memory->savedata.type == SAVEDATA_EEPROM) { - if (memory->savedata.type == SAVEDATA_AUTODETECT) { - mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); - GBASavedataInitEEPROM(&memory->savedata); - } + if (sourceRegion == REGION_CART2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) { memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); } else { if (source) { diff --git a/src/gba/memory.c b/src/gba/memory.c index 384fd81cc..5c7efd104 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -558,7 +558,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { break; case REGION_CART2_EX: wait = memory->waitstatesNonseq16[address >> BASE_OFFSET]; - if (memory->savedata.type == SAVEDATA_EEPROM) { + if (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512) { value = GBASavedataReadEEPROM(&memory->savedata); } else if ((address & (SIZE_CART0 - 1)) < memory->romSize) { LOAD_16(value, address & (SIZE_CART0 - 2), memory->rom); diff --git a/src/gba/savedata.c b/src/gba/savedata.c index ba702e36b..08d0b1367 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -77,6 +77,9 @@ void GBASavedataDeinit(struct GBASavedata* savedata) { case SAVEDATA_EEPROM: mappedMemoryFree(savedata->data, SIZE_CART_EEPROM); break; + case SAVEDATA_EEPROM512: + mappedMemoryFree(savedata->data, SIZE_CART_EEPROM512); + break; case SAVEDATA_FORCE_NONE: case SAVEDATA_AUTODETECT: break; @@ -127,6 +130,8 @@ bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) { return out->write(out, savedata->data, SIZE_CART_FLASH1M) == SIZE_CART_FLASH1M; case SAVEDATA_EEPROM: return out->write(out, savedata->data, SIZE_CART_EEPROM) == SIZE_CART_EEPROM; + case SAVEDATA_EEPROM512: + return out->write(out, savedata->data, SIZE_CART_EEPROM512) == SIZE_CART_EEPROM512; case SAVEDATA_AUTODETECT: case SAVEDATA_FORCE_NONE: return true; @@ -152,7 +157,9 @@ size_t GBASavedataSize(const struct GBASavedata* savedata) { case SAVEDATA_FLASH1M: return SIZE_CART_FLASH1M; case SAVEDATA_EEPROM: - return (savedata->vf && savedata->vf->size(savedata->vf) == SIZE_CART_EEPROM512) ? SIZE_CART_EEPROM512 : SIZE_CART_EEPROM; + return SIZE_CART_EEPROM; + case SAVEDATA_EEPROM512: + return SIZE_CART_EEPROM512; case SAVEDATA_FORCE_NONE: return 0; case SAVEDATA_AUTODETECT: @@ -218,6 +225,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) GBASavedataInitFlash(savedata); break; case SAVEDATA_EEPROM: + case SAVEDATA_EEPROM512: GBASavedataInitEEPROM(savedata); break; case SAVEDATA_SRAM: @@ -263,22 +271,26 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { void GBASavedataInitEEPROM(struct GBASavedata* savedata) { if (savedata->type == SAVEDATA_AUTODETECT) { - savedata->type = SAVEDATA_EEPROM; - } else { + savedata->type = SAVEDATA_EEPROM512; + } else if (savedata->type != SAVEDATA_EEPROM512 && savedata->type != SAVEDATA_EEPROM) { mLOG(GBA_SAVE, WARN, "Can't re-initialize savedata"); return; } int32_t eepromSize = SIZE_CART_EEPROM512; + if (savedata->type == SAVEDATA_EEPROM) { + eepromSize = SIZE_CART_EEPROM; + } off_t end; if (!savedata->vf) { end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); } else { end = savedata->vf->size(savedata->vf); - if (end < SIZE_CART_EEPROM512) { - savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM512); - } else if (end > SIZE_CART_EEPROM512) { + if (end < eepromSize) { + savedata->vf->truncate(savedata->vf, eepromSize); + } else if (end >= SIZE_CART_EEPROM) { eepromSize = SIZE_CART_EEPROM; + savedata->type = SAVEDATA_EEPROM; } savedata->data = savedata->vf->map(savedata->vf, eepromSize, savedata->mapMode); } @@ -420,6 +432,10 @@ static void _ensureEeprom(struct GBASavedata* savedata, uint32_t size) { if (size < SIZE_CART_EEPROM512) { return; } + if (savedata->type == SAVEDATA_EEPROM) { + return; + } + savedata->type = SAVEDATA_EEPROM; if (!savedata->vf || savedata->vf->size(savedata->vf) > SIZE_CART_EEPROM512) { return; } From 830cad3e7bc24281d8d9da31672c020693a17c5b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 11:13:55 -0700 Subject: [PATCH 09/50] GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash --- CHANGES | 1 + src/gba/savedata.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 58af4992b..db4c41e89 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) Misc: - GBA Savedata: EEPROM performance fixes + - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash 0.7.0: (Future) Features: diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 08d0b1367..8cf291f24 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -259,6 +259,9 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { end = savedata->vf->size(savedata->vf); if (end < flashSize) { savedata->vf->truncate(savedata->vf, flashSize); + } else if (end >= SIZE_CART_FLASH1M) { + flashSize = SIZE_CART_FLASH1M; + savedata->type = SAVEDATA_FLASH1M; } savedata->data = savedata->vf->map(savedata->vf, flashSize, savedata->mapMode); } From 4d383b129dd51083a917f5c82ec9f3314c577a65 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Oct 2018 21:09:49 -0700 Subject: [PATCH 10/50] ARM: De-macro-ize ARM/Thumb PC write routines --- include/mgba/internal/arm/isa-inlines.h | 30 +++++++++++++------------ src/arm/arm.c | 16 ++++--------- src/arm/debugger/debugger.c | 10 ++++----- src/arm/isa-arm.c | 18 +++++++-------- src/arm/isa-thumb.c | 16 ++++++------- src/debugger/gdb-stub.c | 10 ++++----- src/gba/bios.c | 3 +-- src/gba/gba.c | 3 +-- 8 files changed, 47 insertions(+), 59 deletions(-) diff --git a/include/mgba/internal/arm/isa-inlines.h b/include/mgba/internal/arm/isa-inlines.h index 5850dab69..a73c157b4 100644 --- a/include/mgba/internal/arm/isa-inlines.h +++ b/include/mgba/internal/arm/isa-inlines.h @@ -55,21 +55,23 @@ #define ARM_STUB cpu->irqh.hitStub(cpu, opcode) #define ARM_ILL cpu->irqh.hitIllegal(cpu, opcode) -#define ARM_WRITE_PC \ - cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); \ - cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - cpu->gprs[ARM_PC] += WORD_SIZE_ARM; \ - LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - currentCycles += 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; +static inline int32_t ARMWritePC(struct ARMCore* cpu) { + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM); + cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); + LOAD_32(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + cpu->gprs[ARM_PC] += WORD_SIZE_ARM; + LOAD_32(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + return 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; +} -#define THUMB_WRITE_PC \ - cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); \ - cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); \ - LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; \ - LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); \ - currentCycles += 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; +static inline int32_t ThumbWritePC(struct ARMCore* cpu) { + cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB); + cpu->memory.setActiveRegion(cpu, cpu->gprs[ARM_PC]); + LOAD_16(cpu->prefetch[0], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + cpu->gprs[ARM_PC] += WORD_SIZE_THUMB; + LOAD_16(cpu->prefetch[1], cpu->gprs[ARM_PC] & cpu->memory.activeMask, cpu->memory.activeRegion); + return 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; +} static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) { return mode != MODE_SYSTEM && mode != MODE_USER; diff --git a/src/arm/arm.c b/src/arm/arm.c index d0325dc05..bd8c3b565 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -135,9 +135,7 @@ void ARMReset(struct ARMCore* cpu) { cpu->executionMode = MODE_THUMB; _ARMSetMode(cpu, MODE_ARM); - - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); cpu->cycles = 0; cpu->nextEvent = 0; @@ -161,12 +159,10 @@ void ARMRaiseIRQ(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_IRQ; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_PC] = BASE_IRQ; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; cpu->halted = 0; } @@ -182,12 +178,10 @@ void ARMRaiseSWI(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_SUPERVISOR; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_SWI; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; } void ARMRaiseUndefined(struct ARMCore* cpu) { @@ -202,12 +196,10 @@ void ARMRaiseUndefined(struct ARMCore* cpu) { cpu->cpsr.priv = MODE_UNDEFINED; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_UNDEF; - int currentCycles = 0; - ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); + cpu->cycles += ARMWritePC(cpu); cpu->spsr = cpsr; cpu->cpsr.i = 1; - cpu->cycles += currentCycles; } static inline void ARMStep(struct ARMCore* cpu) { diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index 55105a17d..292b98c87 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -347,11 +347,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32 } if (strcmp(name, "pc") == 0) { cpu->gprs[ARM_PC] = value; - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } return true; } @@ -363,11 +362,10 @@ bool ARMDebuggerSetRegister(struct mDebuggerPlatform* d, const char* name, int32 } cpu->gprs[reg] = value; if (reg == ARM_PC) { - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } } return true; diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index e9ed19a2d..901174b75 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -253,7 +253,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { #define ADDR_MODE_2_WRITEBACK(ADDR) \ cpu->gprs[rn] = ADDR; \ if (UNLIKELY(rn == ARM_PC)) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } #define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I) @@ -278,7 +278,7 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { #define ARM_LOAD_POST_BODY \ currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; \ if (rd == ARM_PC) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } #define ARM_STORE_POST_BODY \ @@ -301,9 +301,9 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) { S_BODY; \ if (rd == ARM_PC) { \ if (cpu->executionMode == MODE_ARM) { \ - ARM_WRITE_PC; \ + currentCycles += ARMWritePC(cpu); \ } else { \ - THUMB_WRITE_PC; \ + currentCycles += ThumbWritePC(cpu); \ } \ }) @@ -594,7 +594,7 @@ DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(LDM, load, currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32; if (rs & 0x8000) { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) DEFINE_LOAD_STORE_MULTIPLE_INSTRUCTION_ARM(STM, @@ -625,22 +625,22 @@ DEFINE_INSTRUCTION_ARM(B, int32_t offset = opcode << 8; offset >>= 6; cpu->gprs[ARM_PC] += offset; - ARM_WRITE_PC;) + currentCycles += ARMWritePC(cpu);) DEFINE_INSTRUCTION_ARM(BL, int32_t immediate = (opcode & 0x00FFFFFF) << 8; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - WORD_SIZE_ARM; cpu->gprs[ARM_PC] += immediate >> 6; - ARM_WRITE_PC;) + currentCycles += ARMWritePC(cpu);) DEFINE_INSTRUCTION_ARM(BX, int rm = opcode & 0x0000000F; _ARMSetMode(cpu, cpu->gprs[rm] & 0x00000001); cpu->gprs[ARM_PC] = cpu->gprs[rm] & 0xFFFFFFFE; if (cpu->executionMode == MODE_THUMB) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); } else { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) // End branch definitions diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 54faf6ddc..ad72bffb9 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -238,14 +238,14 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MVN, cpu->gprs[rd] = ~cpu->gprs[rn]; THUMB_ DEFINE_INSTRUCTION_WITH_HIGH_THUMB(ADD4, cpu->gprs[rd] += cpu->gprs[rm]; if (rd == ARM_PC) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); }) DEFINE_INSTRUCTION_WITH_HIGH_THUMB(CMP3, int32_t aluOut = cpu->gprs[rd] - cpu->gprs[rm]; THUMB_SUBTRACTION_S(cpu->gprs[rd], cpu->gprs[rm], aluOut)) DEFINE_INSTRUCTION_WITH_HIGH_THUMB(MOV3, cpu->gprs[rd] = cpu->gprs[rm]; if (rd == ARM_PC) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); }) #define DEFINE_IMMEDIATE_WITH_REGISTER_THUMB(NAME, BODY) \ @@ -310,7 +310,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(STMIA, if (ARM_COND_ ## COND) { \ int8_t immediate = opcode; \ cpu->gprs[ARM_PC] += (int32_t) immediate << 1; \ - THUMB_WRITE_PC; \ + currentCycles += ThumbWritePC(cpu); \ }) DEFINE_CONDITIONAL_BRANCH_THUMB(EQ) @@ -346,7 +346,7 @@ DEFINE_LOAD_STORE_MULTIPLE_THUMB(POPR, rs |= 1 << ARM_PC, THUMB_LOAD_POST_BODY; cpu->gprs[ARM_SP] = address; - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_LOAD_STORE_MULTIPLE_THUMB(PUSH, ARM_SP, @@ -369,7 +369,7 @@ DEFINE_INSTRUCTION_THUMB(BKPT, cpu->irqh.bkpt16(cpu, opcode & 0xFF);) DEFINE_INSTRUCTION_THUMB(B, int16_t immediate = (opcode & 0x07FF) << 5; cpu->gprs[ARM_PC] += (((int32_t) immediate) >> 4); - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_INSTRUCTION_THUMB(BL1, int16_t immediate = (opcode & 0x07FF) << 5; @@ -380,7 +380,7 @@ DEFINE_INSTRUCTION_THUMB(BL2, uint32_t pc = cpu->gprs[ARM_PC]; cpu->gprs[ARM_PC] = cpu->gprs[ARM_LR] + immediate; cpu->gprs[ARM_LR] = pc - 1; - THUMB_WRITE_PC;) + currentCycles += ThumbWritePC(cpu);) DEFINE_INSTRUCTION_THUMB(BX, int rm = (opcode >> 3) & 0xF; @@ -391,9 +391,9 @@ DEFINE_INSTRUCTION_THUMB(BX, } cpu->gprs[ARM_PC] = (cpu->gprs[rm] & 0xFFFFFFFE) - misalign; if (cpu->executionMode == MODE_THUMB) { - THUMB_WRITE_PC; + currentCycles += ThumbWritePC(cpu); } else { - ARM_WRITE_PC; + currentCycles += ARMWritePC(cpu); }) DEFINE_INSTRUCTION_THUMB(SWI, cpu->irqh.swi16(cpu, opcode & 0xFF)) diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 73dd978d6..f5b5218d5 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -305,11 +305,10 @@ static void _writeGPRs(struct GDBStub* stub, const char* message) { cpu->gprs[r] = _hex2int(readAddress, 8); readAddress += 8; } - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } strncpy(stub->outgoing, "OK", GDB_STUB_MAX_LINE - 4); @@ -369,11 +368,10 @@ static void _writeRegister(struct GDBStub* stub, const char* message) { if (reg <= ARM_PC) { cpu->gprs[reg] = value; if (reg == ARM_PC) { - int32_t currentCycles = 0; if (cpu->executionMode == MODE_ARM) { - ARM_WRITE_PC; + ARMWritePC(cpu); } else { - THUMB_WRITE_PC; + ThumbWritePC(cpu); } } } else if (reg == 0x19) { diff --git a/src/gba/bios.c b/src/gba/bios.c index ead5332c2..286c00a7f 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -43,8 +43,7 @@ static void _SoftReset(struct GBA* gba) { cpu->gprs[ARM_PC] = BASE_CART0; } _ARMSetMode(cpu, MODE_ARM); - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); } static void _RegisterRamReset(struct GBA* gba) { diff --git a/src/gba/gba.c b/src/gba/gba.c index eab779158..0e58f1618 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -242,8 +242,7 @@ void GBASkipBIOS(struct GBA* gba) { } gba->memory.io[REG_VCOUNT >> 1] = 0x7E; gba->memory.io[REG_POSTFLG >> 1] = 1; - int currentCycles = 0; - ARM_WRITE_PC; + ARMWritePC(cpu); } } From a751cd51841f7f00dfd148df13f13c877a5d7074 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Oct 2018 14:17:43 -0700 Subject: [PATCH 11/50] Qt: Fix mapping analog triggers (fixes #495) --- CHANGES | 1 + src/platform/qt/GBAKeyEditor.cpp | 12 ++---------- src/platform/qt/GBAKeyEditor.h | 1 - src/platform/qt/KeyEditor.cpp | 4 ++-- src/platform/qt/KeyEditor.h | 2 +- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index db4c41e89..1dcb44d03 100644 --- a/CHANGES +++ b/CHANGES @@ -129,6 +129,7 @@ Bugfixes: - Qt: Fix focus issues with load/save state overlay - GB Video: Fix SGB border hole size - PSP2: Fix tearing issues (fixes mgba.io/i/1211) + - Qt: Fix mapping analog triggers (fixes mgba.io/i/495) Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/platform/qt/GBAKeyEditor.cpp b/src/platform/qt/GBAKeyEditor.cpp index 064bd0f58..03d0769e2 100644 --- a/src/platform/qt/GBAKeyEditor.cpp +++ b/src/platform/qt/GBAKeyEditor.cpp @@ -278,13 +278,13 @@ void GBAKeyEditor::lookupAxes(const mInputMap* map) { if (description->highDirection != GBA_KEY_NONE) { KeyEditor* key = self->keyById(static_cast(description->highDirection)); if (key) { - key->setValueAxis(axis, description->deadHigh); + key->setValueAxis(axis, GamepadAxisEvent::POSITIVE); } } if (description->lowDirection != GBA_KEY_NONE) { KeyEditor* key = self->keyById(static_cast(description->lowDirection)); if (key) { - key->setValueAxis(axis, description->deadLow); + key->setValueAxis(axis, GamepadAxisEvent::NEGATIVE); } } }, this); @@ -350,14 +350,6 @@ bool GBAKeyEditor::findFocus(KeyEditor* needle) { } #ifdef BUILD_SDL -void GBAKeyEditor::setAxisValue(int axis, int32_t value) { - if (!findFocus()) { - return; - } - KeyEditor* focused = *m_currentKey; - focused->setValueAxis(axis, value); -} - void GBAKeyEditor::selectGamepad(int index) { m_controller->setGamepad(m_type, index); m_profile = m_profileSelect->currentText(); diff --git a/src/platform/qt/GBAKeyEditor.h b/src/platform/qt/GBAKeyEditor.h index 22720ab3c..24b1e5c4a 100644 --- a/src/platform/qt/GBAKeyEditor.h +++ b/src/platform/qt/GBAKeyEditor.h @@ -42,7 +42,6 @@ private slots: void setNext(); void refresh(); #ifdef BUILD_SDL - void setAxisValue(int axis, int32_t value); void selectGamepad(int index); void updateJoysticks(); #endif diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 002ba490f..f77dceb9b 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -48,10 +48,10 @@ void KeyEditor::setValueButton(int button) { setValue(button); } -void KeyEditor::setValueAxis(int axis, int32_t value) { +void KeyEditor::setValueAxis(int axis, GamepadAxisEvent::Direction direction) { m_button = true; m_axis = axis; - m_direction = value < 0 ? GamepadAxisEvent::NEGATIVE : GamepadAxisEvent::POSITIVE; + m_direction = direction; updateButtonText(); emit axisChanged(axis, m_direction); } diff --git a/src/platform/qt/KeyEditor.h b/src/platform/qt/KeyEditor.h index 00798c56f..e74df7f27 100644 --- a/src/platform/qt/KeyEditor.h +++ b/src/platform/qt/KeyEditor.h @@ -33,7 +33,7 @@ public slots: void setValue(int key); void setValueKey(int key); void setValueButton(int button); - void setValueAxis(int axis, int32_t value); + void setValueAxis(int axis, GamepadAxisEvent::Direction value); void setValueHat(int hat, GamepadHatEvent::Direction value); void clearButton(); void clearAxis(); From ae633d9c86f8a42051a135ffa9e17488936f1144 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Oct 2018 08:51:10 -0700 Subject: [PATCH 12/50] Qt: Grab focus when game starts (fixes #804) --- CHANGES | 1 + src/platform/qt/Window.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 1dcb44d03..a28ae16c2 100644 --- a/CHANGES +++ b/CHANGES @@ -130,6 +130,7 @@ Bugfixes: - GB Video: Fix SGB border hole size - PSP2: Fix tearing issues (fixes mgba.io/i/1211) - Qt: Fix mapping analog triggers (fixes mgba.io/i/495) + - Qt: Grab focus when game starts (fixes mgba.io/i/804) Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ea03858f0..f876892e0 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -707,6 +707,7 @@ void Window::gameStarted() { } attachWidget(m_display.get()); m_display->setMinimumSize(size); + setFocus(); #ifndef Q_OS_MAC if (isFullScreen()) { From 29675e354f0e6001403bcd7d12141f9599f4356e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 17 Oct 2018 09:10:50 -0700 Subject: [PATCH 13/50] Qt: Minor memory view tweaks --- CHANGES | 1 + src/platform/qt/MemoryView.ui | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index a28ae16c2..bcbd5353f 100644 --- a/CHANGES +++ b/CHANGES @@ -144,6 +144,7 @@ Misc: - Qt: Debugger console history - Qt: Detect presence of GL_ARB_framebuffer_object - Python: Minor API improvements + - Qt: Minor memory view tweaks 0.7 beta 1: (2018-09-24) - Initial beta for 0.7 diff --git a/src/platform/qt/MemoryView.ui b/src/platform/qt/MemoryView.ui index acbd04da7..b00c710f8 100644 --- a/src/platform/qt/MemoryView.ui +++ b/src/platform/qt/MemoryView.ui @@ -6,8 +6,8 @@ 0 0 - 565 - 658 + 822 + 886 @@ -98,7 +98,7 @@ - 1 Byte + &1 Byte true @@ -121,7 +121,7 @@ - 2 Bytes + &2 Bytes @@ -141,7 +141,7 @@ - 4 Bytes + &4 Bytes @@ -168,7 +168,6 @@ 0 - From a748e0c795a4ab7117eaac78349cecb303873ddf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 17 Oct 2018 09:21:16 -0700 Subject: [PATCH 14/50] All: Partial warnings burndown --- src/core/log.c | 4 ++-- src/core/tile-cache.c | 2 +- src/gb/memory.c | 4 +++- src/gb/timer.c | 3 +-- src/gba/gba.c | 2 +- src/gba/renderers/cache-set.c | 8 ++++---- src/platform/python/engine.c | 5 ++--- src/platform/sdl/sdl-events.c | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/core/log.c b/src/core/log.c index 6af5724b9..118d6fff3 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -128,13 +128,13 @@ void mLogFilterSet(struct mLogFilter* filter, const char* category, int levels) } bool mLogFilterTest(struct mLogFilter* filter, int category, enum mLogLevel level) { - int value = (int) TableLookup(&filter->levels, category); + int value = (intptr_t) TableLookup(&filter->levels, category); if (value) { return value & level; } const char* cat = mLogCategoryId(category); if (cat) { - value = (int) HashTableLookup(&filter->categories, cat); + value = (intptr_t) HashTableLookup(&filter->categories, cat); if (value) { TableInsert(&filter->levels, category, (void*)(intptr_t) value); return value & level; diff --git a/src/core/tile-cache.c b/src/core/tile-cache.c index 2a7c8cf3a..d1e1b9e25 100644 --- a/src/core/tile-cache.c +++ b/src/core/tile-cache.c @@ -198,7 +198,7 @@ static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, un if (tileId >= tiles) { abort(); } - if (paletteId >= 1 << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)) { + if (paletteId >= 1U << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)) { abort(); } #endif diff --git a/src/gb/memory.c b/src/gb/memory.c index 688d43676..1761bcb39 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -178,6 +178,7 @@ void GBMemoryReset(struct GB* gb) { memset(&gb->memory.hram, 0, sizeof(gb->memory.hram)); GBMBCInit(gb); + memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); switch (gb->memory.mbcType) { case GB_MBC1: gb->memory.mbcState.mbc1.mode = 0; @@ -192,8 +193,9 @@ void GBMemoryReset(struct GB* gb) { case GB_MMM01: GBMBCSwitchBank0(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 2); GBMBCSwitchBank(gb, gb->memory.romSize / GB_SIZE_CART_BANK0 - 1); + break; default: - memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); + break; } gb->memory.sramBank = gb->memory.sram; diff --git a/src/gb/timer.c b/src/gb/timer.c index ca2fe46d6..32c9efdc5 100644 --- a/src/gb/timer.c +++ b/src/gb/timer.c @@ -30,7 +30,7 @@ static void _GBTimerDivIncrement(struct GBTimer* timer, uint32_t cyclesLate) { mTimingSchedule(&timer->p->timing, &timer->irq, 7 - ((timer->p->cpu->executionState - cyclesLate) & 3)); } } - int timingFactor = 0x3FF >> !timer->p->doubleSpeed; + unsigned timingFactor = 0x3FF >> !timer->p->doubleSpeed; if ((timer->internalDiv & timingFactor) == timingFactor) { GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing); } @@ -80,7 +80,6 @@ void GBTimerDivReset(struct GBTimer* timer) { mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3)); } } - int timingFactor = 0x200 >> !timer->p->doubleSpeed; if (timer->internalDiv & 0x200) { GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing); } diff --git a/src/gba/gba.c b/src/gba/gba.c index 0e58f1618..d68a03c2e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -512,7 +512,7 @@ void GBADebug(struct GBA* gba, uint16_t flags) { int level = 1 << GBADebugFlagsGetLevel(gba->debugFlags); level &= 0x1F; char oolBuf[0x101]; - strncpy(oolBuf, gba->debugString, sizeof(gba->debugString)); + strncpy(oolBuf, gba->debugString, sizeof(oolBuf) - 1); memset(gba->debugString, 0, sizeof(gba->debugString)); oolBuf[0x100] = '\0'; mLog(_mLOG_CAT_GBA_DEBUG(), level, "%s", oolBuf); diff --git a/src/gba/renderers/cache-set.c b/src/gba/renderers/cache-set.c index 343cdcb8e..dae92b675 100644 --- a/src/gba/renderers/cache-set.c +++ b/src/gba/renderers/cache-set.c @@ -158,10 +158,10 @@ void GBAVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint32_t address, switch (address) { case REG_DISPCNT: GBAVideoCacheWriteDISPCNT(cache, value); - GBAVideoCacheWriteBGCNT(cache, 0, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 0)->context); - GBAVideoCacheWriteBGCNT(cache, 1, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 1)->context); - GBAVideoCacheWriteBGCNT(cache, 2, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 2)->context); - GBAVideoCacheWriteBGCNT(cache, 3, (uint16_t) mMapCacheSetGetPointer(&cache->maps, 3)->context); + GBAVideoCacheWriteBGCNT(cache, 0, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 0)->context); + GBAVideoCacheWriteBGCNT(cache, 1, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 1)->context); + GBAVideoCacheWriteBGCNT(cache, 2, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 2)->context); + GBAVideoCacheWriteBGCNT(cache, 3, (uintptr_t) mMapCacheSetGetPointer(&cache->maps, 3)->context); break; case REG_BG0CNT: GBAVideoCacheWriteBGCNT(cache, 0, value); diff --git a/src/platform/python/engine.c b/src/platform/python/engine.c index e6b2c0cf6..67d1d7b49 100644 --- a/src/platform/python/engine.c +++ b/src/platform/python/engine.c @@ -65,7 +65,6 @@ bool mPythonScriptEngineInit(struct mScriptEngine* se, struct mScriptBridge* sb) } void mPythonScriptEngineDeinit(struct mScriptEngine* se) { - struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; free(se); } @@ -76,7 +75,7 @@ bool mPythonScriptEngineIsScript(struct mScriptEngine* se, const char* name, str } bool mPythonScriptEngineLoadScript(struct mScriptEngine* se, const char* name, struct VFile* vf) { - struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; + UNUSED(se); return mPythonLoadScript(name, vf); } @@ -94,7 +93,7 @@ void mPythonScriptEngineRun(struct mScriptEngine* se) { } bool mPythonScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, int32_t* out) { - struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; + UNUSED(se); return mPythonLookupSymbol(name, out); } diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 97f58f229..00d6df378 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -304,7 +304,7 @@ void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration #else const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); #endif - char value[12]; + char value[16]; snprintf(value, sizeof(value), "%i", context->rotation.axisX); mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name); snprintf(value, sizeof(value), "%i", context->rotation.axisY); From 0dc7da9a74cb6821a579ef5bba6a928937cfe0a3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 17 Oct 2018 09:55:38 -0700 Subject: [PATCH 15/50] GB MBC: Fix MBC1 initialization --- src/gb/mbc.c | 10 +++++----- src/gb/memory.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 817b3dc9d..65ba791e3 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -188,11 +188,6 @@ void GBMBCInit(struct GB* gb) { case 2: case 3: gb->memory.mbcType = GB_MBC1; - if (gb->memory.romSize >= GB_SIZE_CART_BANK0 * 0x31 && _isMulticart(gb->memory.rom)) { - gb->memory.mbcState.mbc1.multicartStride = 4; - } else { - gb->memory.mbcState.mbc1.multicartStride = 5; - } break; case 5: case 6: @@ -255,6 +250,11 @@ void GBMBCInit(struct GB* gb) { break; case GB_MBC1: gb->memory.mbcWrite = _GBMBC1; + if (gb->memory.romSize >= GB_SIZE_CART_BANK0 * 0x31 && _isMulticart(gb->memory.rom)) { + gb->memory.mbcState.mbc1.multicartStride = 4; + } else { + gb->memory.mbcState.mbc1.multicartStride = 5; + } break; case GB_MBC2: gb->memory.mbcWrite = _GBMBC2; diff --git a/src/gb/memory.c b/src/gb/memory.c index 1761bcb39..b2e229c4d 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -177,8 +177,8 @@ void GBMemoryReset(struct GB* gb) { memset(&gb->memory.hram, 0, sizeof(gb->memory.hram)); - GBMBCInit(gb); memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); + GBMBCInit(gb); switch (gb->memory.mbcType) { case GB_MBC1: gb->memory.mbcState.mbc1.mode = 0; From b913419069b360ac1b2a51ef836e9a44c75bf966 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Oct 2018 11:25:02 -0700 Subject: [PATCH 16/50] Core: Expose timing --- include/mgba/core/core.h | 1 + src/gb/core.c | 1 + src/gba/core.c | 1 + 3 files changed, 3 insertions(+) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 96a9324f2..569b55f82 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -44,6 +44,7 @@ struct mVideoLogContext; struct mCore { void* cpu; void* board; + struct mTiming* timing; struct mDebugger* debugger; struct mDebuggerSymbols* symbolTable; diff --git a/src/gb/core.c b/src/gb/core.c index 5185e9a69..c0c4f50da 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -99,6 +99,7 @@ static bool _GBCoreInit(struct mCore* core) { } core->cpu = cpu; core->board = gb; + core->timing = &gb->timing; gbcore->overrides = NULL; gbcore->debuggerPlatform = NULL; gbcore->cheatDevice = NULL; diff --git a/src/gba/core.c b/src/gba/core.c index 05225bc56..93dc98d84 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -148,6 +148,7 @@ static bool _GBACoreInit(struct mCore* core) { } core->cpu = cpu; core->board = gba; + core->timing = &gba->timing; core->debugger = NULL; core->symbolTable = NULL; gbacore->overrides = NULL; From 01502ad7d4a50fc46c5e3665eab7595133465c5d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Oct 2018 11:37:45 -0700 Subject: [PATCH 17/50] Core: Remember to deinit proxy ring FIFO --- CHANGES | 1 + src/feature/thread-proxy.c | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index bcbd5353f..8dd985d92 100644 --- a/CHANGES +++ b/CHANGES @@ -131,6 +131,7 @@ Bugfixes: - PSP2: Fix tearing issues (fixes mgba.io/i/1211) - Qt: Fix mapping analog triggers (fixes mgba.io/i/495) - Qt: Grab focus when game starts (fixes mgba.io/i/804) + - Core: Remember to deinit proxy ring FIFO Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index 196877002..d00da8cd8 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -78,6 +78,7 @@ void mVideoThreadProxyDeinit(struct mVideoLogger* logger) { if (waiting) { ThreadJoin(proxyRenderer->thread); } + RingFIFODeinit(&proxyRenderer->dirtyQueue); ConditionDeinit(&proxyRenderer->fromThreadCond); ConditionDeinit(&proxyRenderer->toThreadCond); MutexDeinit(&proxyRenderer->mutex); From f92059bee1892a5358b3e9a9d0b5065cae1d1cc0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Oct 2018 11:46:21 -0700 Subject: [PATCH 18/50] All: Update .gitignore --- .gitignore | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6fe2e703a..3e6aea460 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,17 @@ -/build -/build-* *.user* *~ *.swp *.pyc + +/build +/build-* + +*.a +*.dylib +*.dll +*.exe +*.o +*.so +CMakeCache.txt +CMakeFiles +version.c From 27a58187051352f01b5b7f876ea6d7e6612edb11 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 3 Nov 2018 15:15:02 -0700 Subject: [PATCH 19/50] GBA Hardware: Fix RTC handshake transition (fixes #1134) --- CHANGES | 1 + src/gba/hardware.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8dd985d92..f9e151f54 100644 --- a/CHANGES +++ b/CHANGES @@ -70,6 +70,7 @@ Bugfixes: - GB, GBA Video: Don't call finishFrame twice in thread proxy - GB Audio: Fix channel 1, 2 and 4 reset timing - Util: Fix wrapping edge cases in RingFIFO + - GBA Hardware: Fix RTC handshake transition (fixes mgba.io/i/1134) Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/src/gba/hardware.c b/src/gba/hardware.c index 20d342012..70704a5d2 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -171,7 +171,7 @@ void _rtcReadPins(struct GBACartridgeHardware* hw) { case 1: if ((hw->pinState & 5) == 5) { hw->rtc.transferStep = 2; - } else { + } else if ((hw->pinState & 5) != 1) { hw->rtc.transferStep = 0; } break; From ed0a7c68eab07e4dca5b2744b2a45ef7b00917b1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 3 Nov 2018 15:39:00 -0700 Subject: [PATCH 20/50] README: Update --- README.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2fa2b691d..bacb81b10 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,31 @@ Controls are configurable in the settings menu. Many game controllers should be Compiling --------- -Compiling requires using CMake 2.8.11 or newer. GCC and Clang are both known to work to compile mGBA, but Visual Studio 2013 and older are known not to work. Support for Visual Studio 2015 and newer is coming soon. To use CMake to build on a Unix-based system, the recommended commands are as follows: +Compiling requires using CMake 3.1 or newer. GCC and Clang are both known to work to compile mGBA, but Visual Studio 2013 and older are known not to work. Support for Visual Studio 2015 and newer is coming soon. + +#### Docker building + +The recommended way to build for most platforms is to use Docker. Several Docker images are provided that contain the requisite toolchain and dependencies for building mGBA across several platforms. + +To use a Docker image to build mGBA, simply run the following command while in the root of an mGBA checkout: + + docker run --rm -t -v $PWD:/home/mgba/src mgba/windows:w32 + +This will produce a `build-win32` directory with the build products. Replace `mgba/windows:w32` with another Docker image for other platforms, which will produce a corresponding other directory. The following Docker images available on Docker Hub: + +- mgba/3ds +- mgba/switch +- mgba/ubuntu:xenial +- mgba/ubuntu:bionic +- mgba/ubuntu:cosmic +- mgba/vita +- mgba/wii +- mgba/windows:w32 +- mgba/windows:w64 + +#### *nix building + +To use CMake to build on a Unix-based system, the recommended commands are as follows: mkdir build cd build @@ -153,6 +177,22 @@ Then finally build it by running these commands: Please note that this build of mGBA for Windows is not suitable for distribution, due to the scattering of DLLs it needs to run, but is perfect for development. However, if distributing such a build is desired (e.g. for testing on machines that don't have the MSYS2 environment installed), running `cpack -G ZIP` will prepare a zip file with all of the necessary DLLs. +#### Toolchain building + +If you have devkitARM (for 3DS), devkitPPC (for Wii), devkitA64 (for Switch), or vitasdk (for PS Vita), you can use the following commands for building: + + mkdir build + cd build + cmake -DCMAKE_TOOLCHAIN_FILE=../src/platform/3ds/CMakeToolchain.txt .. + make + +Replace the `-DCMAKE_TOOLCHAIN_FILE` parameter for the following platforms: + +- 3DS: `../src/platform/3ds/CMakeToolchain.txt` +- Switch: `../src/platform/switch/CMakeToolchain.txt` +- Vita: `../src/platform/psp2/CMakeToolchain.vitasdk` +- Wii: `../src/platform/wii/CMakeToolchain.txt` + ### Dependencies mGBA has no hard dependencies, however, the following optional dependencies are required for specific features. The features will be disabled if the dependencies can't be found. From f6b88660d248f643319ae430b4ecda7c3e3dcbbe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 4 Nov 2018 15:54:00 -0800 Subject: [PATCH 21/50] GBA: Reset now reloads multiboot ROMs --- CHANGES | 1 + src/gba/gba.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index f9e151f54..5b6203f48 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ 0.8.0: (Future) Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) + - GBA: Reset now reloads multiboot ROMs Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/gba.c b/src/gba/gba.c index d68a03c2e..7cb3faafe 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -216,6 +216,20 @@ void GBAReset(struct ARMCore* cpu) { GBASIOReset(&gba->sio); + bool isELF = false; +#ifdef USE_ELF + struct ELF* elf = ELFOpen(gba->romVf); + if (elf) { + isELF = true; + ELFClose(elf); + } +#endif + + if (GBAIsMB(gba->romVf) && !isELF) { + gba->romVf->seek(gba->romVf, 0, SEEK_SET); + gba->romVf->read(gba->romVf, gba->memory.wram, gba->pristineRomSize); + } + gba->lastJump = 0; gba->haltPending = false; gba->idleDetectionStep = 0; @@ -343,11 +357,6 @@ bool GBALoadMB(struct GBA* gba, struct VFile* vf) { } gba->isPristine = true; memset(gba->memory.wram, 0, SIZE_WORKING_RAM); - vf->read(vf, gba->memory.wram, gba->pristineRomSize); - if (!gba->memory.wram) { - mLOG(GBA, WARN, "Couldn't map ROM"); - return false; - } gba->yankedRomSize = 0; gba->memory.romSize = 0; gba->memory.romMask = 0; From b33c5076ad31a3a08c77d35fc490d0f1771811f8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 4 Nov 2018 15:56:13 -0800 Subject: [PATCH 22/50] GBA BIOS: Fix multiboot entry point (fixes Magic Floor) --- CHANGES | 1 + src/gba/hle-bios.c | 4 ++-- src/gba/hle-bios.s | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 5b6203f48..7272b5c48 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs + - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/hle-bios.c b/src/gba/hle-bios.c index be450acd4..a6a5382e9 100644 --- a/src/gba/hle-bios.c +++ b/src/gba/hle-bios.c @@ -6,7 +6,7 @@ const uint8_t hleBios[SIZE_BIOS] = { 0x06, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x0b, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe1, 0x2c, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x03, 0xa0, 0xe3, - 0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0x02, 0x04, 0xa0, 0x13, + 0x03, 0x10, 0xd0, 0xe5, 0xea, 0x00, 0x51, 0xe3, 0xec, 0x01, 0x9f, 0x15, 0x10, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x29, 0xe1, 0x00, 0x00, 0x5d, 0xe3, 0x01, 0xd3, 0xa0, 0x03, 0x20, 0xd0, 0x4d, 0x02, 0x00, 0x58, 0x2d, 0xe9, 0x02, 0xb0, 0x5e, 0xe5, 0x9c, 0xc0, 0xa0, 0xe3, @@ -48,5 +48,5 @@ const uint8_t hleBios[SIZE_BIOS] = { 0x03, 0xa0, 0xa0, 0xe1, 0x02, 0x00, 0x51, 0xe1, 0xf8, 0x07, 0xa1, 0xb8, 0xfc, 0xff, 0xff, 0xba, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x51, 0xe1, 0xf8, 0x07, 0xb0, 0xb8, 0xf8, 0x07, 0xa1, 0xb8, 0xfb, 0xff, 0xff, 0xba, - 0xf0, 0x87, 0xbd, 0xe8 + 0xf0, 0x87, 0xbd, 0xe8, 0xc0, 0x00, 0x00, 0x02 }; diff --git a/src/gba/hle-bios.s b/src/gba/hle-bios.s index 19e00127d..e10947c96 100644 --- a/src/gba/hle-bios.s +++ b/src/gba/hle-bios.s @@ -20,7 +20,7 @@ resetBase: mov r0, #0x8000000 ldrb r1, [r0, #3] cmp r1, #0xEA -movne r0, #0x2000000 +ldrne r0, =0x20000C0 bx r0 .word 0 .word 0xE129F000 @@ -183,3 +183,5 @@ stmltia r1!, {r3-r10} blt 0b 2: ldmfd sp!, {r4-r10, pc} + +.ltorg From 32279c37b1512f579208ee6d700045ad6031f6c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 4 Nov 2018 15:59:57 -0800 Subject: [PATCH 23/50] GBA: Add EEPROM512 to overrides --- src/gba/overrides.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gba/overrides.c b/src/gba/overrides.c index 7227404b7..675b2d471 100644 --- a/src/gba/overrides.c +++ b/src/gba/overrides.c @@ -223,6 +223,9 @@ bool GBAOverrideFind(const struct Configuration* config, struct GBACartridgeOver } else if (strcasecmp(savetype, "EEPROM") == 0) { found = true; override->savetype = SAVEDATA_EEPROM; + } else if (strcasecmp(savetype, "EEPROM512") == 0) { + found = true; + override->savetype = SAVEDATA_EEPROM512; } else if (strcasecmp(savetype, "FLASH512") == 0) { found = true; override->savetype = SAVEDATA_FLASH512; @@ -267,6 +270,9 @@ void GBAOverrideSave(struct Configuration* config, const struct GBACartridgeOver case SAVEDATA_EEPROM: savetype = "EEPROM"; break; + case SAVEDATA_EEPROM512: + savetype = "EEPROM512"; + break; case SAVEDATA_FLASH512: savetype = "FLASH512"; break; From 9262475cb47c1bbfd4422591394b789ce18f6b6b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 9 Nov 2018 20:31:30 -0800 Subject: [PATCH 24/50] GBA Savedata: Fix various filesize edge cases (fixes #1221) --- src/gba/savedata.c | 20 +++++++++----------- src/platform/libretro/libretro.c | 1 + 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 8cf291f24..10f9499fa 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -259,9 +259,6 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { end = savedata->vf->size(savedata->vf); if (end < flashSize) { savedata->vf->truncate(savedata->vf, flashSize); - } else if (end >= SIZE_CART_FLASH1M) { - flashSize = SIZE_CART_FLASH1M; - savedata->type = SAVEDATA_FLASH1M; } savedata->data = savedata->vf->map(savedata->vf, flashSize, savedata->mapMode); } @@ -291,9 +288,6 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) { end = savedata->vf->size(savedata->vf); if (end < eepromSize) { savedata->vf->truncate(savedata->vf, eepromSize); - } else if (end >= SIZE_CART_EEPROM) { - eepromSize = SIZE_CART_EEPROM; - savedata->type = SAVEDATA_EEPROM; } savedata->data = savedata->vf->map(savedata->vf, eepromSize, savedata->mapMode); } @@ -439,13 +433,17 @@ static void _ensureEeprom(struct GBASavedata* savedata, uint32_t size) { return; } savedata->type = SAVEDATA_EEPROM; - if (!savedata->vf || savedata->vf->size(savedata->vf) > SIZE_CART_EEPROM512) { + if (!savedata->vf) { return; } savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_EEPROM512); - savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM); - savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, savedata->mapMode); - memset(&savedata->data[SIZE_CART_EEPROM512], 0xFF, SIZE_CART_EEPROM - SIZE_CART_EEPROM512); + if (savedata->vf->size(savedata->vf) < SIZE_CART_EEPROM) { + savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM); + savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, savedata->mapMode); + memset(&savedata->data[SIZE_CART_EEPROM512], 0xFF, SIZE_CART_EEPROM - SIZE_CART_EEPROM512); + } else { + savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, savedata->mapMode); + } } void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value, uint32_t writeSize) { @@ -605,7 +603,7 @@ void _flashSwitchBank(struct GBASavedata* savedata, int bank) { savedata->type = SAVEDATA_FLASH1M; if (savedata->vf) { savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_FLASH512); - if (savedata->vf->size(savedata->vf) == SIZE_CART_FLASH512) { + if (savedata->vf->size(savedata->vf) < SIZE_CART_FLASH1M) { savedata->vf->truncate(savedata->vf, SIZE_CART_FLASH1M); savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_FLASH1M, MAP_WRITE); memset(&savedata->data[SIZE_CART_FLASH512], 0xFF, SIZE_CART_FLASH512); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 06a9638b1..57bd74296 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -489,6 +489,7 @@ bool retro_load_game(const struct retro_game_info* game) { core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); savedata = anonymousMemoryMap(SIZE_CART_FLASH1M); + memset(savedata, 0xFF, SIZE_CART_FLASH1M); struct VFile* save = VFileFromMemory(savedata, SIZE_CART_FLASH1M); _reloadSettings(); From e4c38de1fcbdf2765c7ad2430467ff6d6eebcd3f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 11 Nov 2018 12:16:59 -0800 Subject: [PATCH 25/50] CMake: Fix libswresample version dependencies (fixes #1229) --- CHANGES | 1 + CMakeLists.txt | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 7272b5c48..18bb402f1 100644 --- a/CHANGES +++ b/CHANGES @@ -149,6 +149,7 @@ Misc: - Qt: Detect presence of GL_ARB_framebuffer_object - Python: Minor API improvements - Qt: Minor memory view tweaks + - CMake: Fix libswresample version dependencies (fixes mgba.io/i/1229) 0.7 beta 1: (2018-09-24) - Initial beta for 0.7 diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ba995484..fa01e3a50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -535,12 +535,7 @@ if(USE_FFMPEG) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavformat${LIBAVFORMAT_VERSION_MAJOR}|libavformat-ffmpeg${LIBAVFORMAT_VERSION_MAJOR}") if(USE_LIBSWRESAMPLE) string(REGEX MATCH "^[0-9]+" LIBSWRESAMPLE_VERSION_MAJOR ${libswresample_VERSION}) - if(${libswresample_VERSION} EQUAL "3.1.100") - set(LIBSWRESAMPLE_VERSION_DEBIAN 3) - else() - math(EXPR LIBSWRESAMPLE_VERSION_DEBIAN "${LIBSWRESAMPLE_VERSION_MAJOR} - 1") - endif() - set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libswresample${LIBSWRESAMPLE_VERSION_DEBIAN}|libswresample-ffmpeg${LIBSWRESAMPLE_VERSION_DEBIAN}") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libswresample${LIBSWRESAMPLE_VERSION_MAJOR}|libswresample-ffmpeg${LIBSWRESAMPLE_VERSION_MAJOR}") else() string(REGEX MATCH "^[0-9]+" LIBAVRESAMPLE_VERSION_MAJOR ${libavresample_VERSION}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavresample${LIBAVRESAMPLE_VERSION_MAJOR}|libavresample-ffmpeg${LIBAVRESAMPLE_VERSION_MAJOR}") From dd7e422bde762063efded268abc8f14b06821e03 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 17 Nov 2018 14:48:03 -0800 Subject: [PATCH 26/50] Switch: Screen stretching options --- CHANGES | 1 + src/platform/switch/main.c | 64 +++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 18bb402f1..21b1e3f51 100644 --- a/CHANGES +++ b/CHANGES @@ -114,6 +114,7 @@ Features: - Qt: Separate fast forward volume control (fixes mgba.io/i/846, mgba.io/i/1143) - Switch: Rumble support - Switch: Rotation support + - Switch: Screen stretching options - Qt: State file load/save menu options - Windows installer - Tile viewer now has adjustable width diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 6c1018712..c8d2fbd3d 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -92,6 +92,13 @@ static unsigned framecap = 10; static u32 vibrationDeviceHandles[4]; static HidVibrationValue vibrationStop = { .freq_low = 160.f, .freq_high = 320.f }; +static enum ScreenMode { + SM_PA, + SM_AF, + SM_SF, + SM_MAX +} screenMode = SM_PA; + static bool initEgl() { s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!s_display) { @@ -238,6 +245,11 @@ static void _setup(struct mGUIRunner* runner) { runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); + + unsigned mode; + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { + screenMode = mode; + } } static void _gameLoaded(struct mGUIRunner* runner) { @@ -249,6 +261,11 @@ static void _gameLoaded(struct mGUIRunner* runner) { mCoreConfigGetUIntValue(&runner->config, "fastForwardCap", &framecap); + unsigned mode; + if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { + screenMode = mode; + } + rumble.up = 0; rumble.down = 0; } @@ -270,11 +287,26 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glBindVertexArray(vao); float aspectX = width / (float) runner->params.width; float aspectY = height / (float) runner->params.height; - float max; - if (aspectX > aspectY) { - max = floor(1.0 / aspectX); - } else { - max = floor(1.0 / aspectY); + float max = 1.f; + switch (screenMode) { + case SM_PA: + if (aspectX > aspectY) { + max = floor(1.0 / aspectX); + } else { + max = floor(1.0 / aspectY); + } + break; + case SM_AF: + if (aspectX > aspectY) { + max = 1.0 / aspectX; + } else { + max = 1.0 / aspectY; + } + break; + case SM_SF: + aspectX = 1.0; + aspectY = 1.0; + break; } aspectX *= max; @@ -354,6 +386,12 @@ static uint16_t _pollGameInput(struct mGUIRunner* runner) { return _pollInput(&runner->core->inputMap); } +static void _incrementScreenMode(struct mGUIRunner* runner) { + UNUSED(runner); + screenMode = (screenMode + 1) % SM_MAX; + mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode); +} + static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); if (!frameLimiter && limit) { @@ -607,6 +645,18 @@ int main(int argc, char* argv[]) { { .id = 0 } }, .configExtra = (struct GUIMenuItem[]) { + { + .title = "Screen mode", + .data = "screenMode", + .submenu = 0, + .state = SM_PA, + .validStates = (const char*[]) { + "Pixel-Accurate", + "Aspect-Ratio Fit", + "Stretched", + }, + .nStates = 3 + }, { .title = "Fast forward cap", .data = "fastForwardCap", @@ -637,7 +687,7 @@ int main(int argc, char* argv[]) { .nStates = 15 }, }, - .nConfigExtra = 1, + .nConfigExtra = 2, .setup = _setup, .teardown = NULL, .gameLoaded = _gameLoaded, @@ -647,7 +697,7 @@ int main(int argc, char* argv[]) { .drawScreenshot = _drawScreenshot, .paused = _gameUnloaded, .unpaused = _gameLoaded, - .incrementScreenMode = NULL, + .incrementScreenMode = _incrementScreenMode, .setFrameLimiter = _setFrameLimiter, .pollGameInput = _pollGameInput, .running = _running From 034353e843ee2ffec8235f4f0b09ea06f1909eb7 Mon Sep 17 00:00:00 2001 From: lotharsm Date: Sun, 18 Nov 2018 09:49:08 +0100 Subject: [PATCH 27/50] Doc: Update MSYS2 build instructions in the README file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bacb81b10..f07dc310d 100644 --- a/README.md +++ b/README.md @@ -157,11 +157,11 @@ To build on Windows for development, using MSYS2 is recommended. Follow the inst For x86 (32 bit) builds: - pacman -Sy base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} + pacman -Sy --needed base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} For x86_64 (64 bit) builds: - pacman -Sy base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} + pacman -Sy --needed base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} Check out the source code by running this command: From 27feb3ed1f84796e8291eddb156312b469383ff7 Mon Sep 17 00:00:00 2001 From: lotharsm Date: Sun, 18 Nov 2018 09:53:35 +0100 Subject: [PATCH 28/50] Doc: Update German README translation --- README_DE.md | 65 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/README_DE.md b/README_DE.md index 2f1088e12..a41d5fbcd 100644 --- a/README_DE.md +++ b/README_DE.md @@ -52,21 +52,18 @@ Die folgenden Mapper werden vollständig unterstützt: Die folgenden Mapper werden teilweise unterstützt: +- MBC6 +- MMM01 - Pocket Cam - TAMA5 -- HuC-3 - -Die folgenden Mapper werden derzeit nicht unterstützt: - -- MBC6 - HuC-1 -- MMM01 +- HuC-3 ### Geplante Features - Unterstützung für Link-Kabel-Multiplayer über ein Netzwerk. - Unterstützung für Link-Kabel über Dolphin/JOY-Bus. -- M4A-Audio-Abmischung für höhere Audio-Qualität. +- M4A-Audio-Abmischung für höhere Audio-Qualität als echte Hardware. - Unterstützung für Tool-Assisted Speedruns. - Lua-Unterstützung für Scripting. - Eine umfangreiche Debugging-Suite. @@ -93,7 +90,7 @@ Die Systemvoraussetzungen sind minimal. Jeder Computer, der mit Windows Vista od Downloads --------- -Download-Links befinden sich in der [Downloads][downloads]-Sektion auf der offizielle Website. Der Quellcode befindet sich auf [GitHub][source]. +Download-Links befinden sich in der [Downloads][downloads]-Sektion auf der offiziellen Website. Der Quellcode befindet sich auf [GitHub][source]. Steuerung --------- @@ -110,7 +107,31 @@ Die Steuerung kann im Einstellungs-Menü konfiguriert werden. Viele Spiele-Contr Kompilieren ----------- -Um mGBA kompilieren zu können, wird CMake 2.8.11 oder neuer benötigt. GCC und Clang sind beide dafür bekannt, mGBA kompilieren zu können. Visual Studio 2013 und älter funktionieren nicht. Unterstützung für Visual Studio 2015 und neuer wird bald hinzugefügt. Um CMake auf einem Unix-basierten System zu verwenden, werden folgende Kommandos empfohlen: +Um mGBA kompilieren zu können, wird CMake 3.1 oder neuer benötigt. GCC und Clang sind beide dafür bekannt, mGBA kompilieren zu können. Visual Studio 2013 und älter funktionieren nicht. Unterstützung für Visual Studio 2015 und neuer wird bald hinzugefügt. + +#### Kompilieren mit Docker + +Der empfohlene Weg, um mGBA für die meisten Plattformen zu kompilieren, ist Docker. Mehrere Docker-Images sind verfügbar, welche die benötigte Compiler-Umgebung und alle benötigten Abhängigkeiten beinhaltet, um mGBA für verschiedene Plattformen zu bauen. + +Um ein Docker-Image zum Bau von mGBA zu verwenden, führe einfach folgenden Befehl in dem Verzeichnis aus, in welches Du den mGBA-Quellcode ausgecheckt hast: + + docker run --rm -t -v $PWD:/home/mgba/src mgba/windows:w32 + +Dieser Befehl erzeugt ein Verzeichnis `build-win32` mit den erzeugten Programmdateien. Ersetze `mgba/windows:32` durch ein Docker-Image für eine andere Plattform, wodurch dann das entsprechende Verzeichnis erzeugt wird. Die folgenden Docker-Images sind im Docker Hub verfügbar: + +- mgba/3ds +- mgba/switch +- mgba/ubuntu:xenial +- mgba/ubuntu:bionic +- mgba/ubuntu:cosmic +- mgba/vita +- mgba/wii +- mgba/windows:w32 +- mgba/windows:w64 + +#### Unter *nix kompilieren + +Verwende folgende Befehle, um mGBA mithilfe von CMake auf einem Unix-basierten System zu bauen: mkdir build cd build @@ -118,9 +139,9 @@ Um mGBA kompilieren zu können, wird CMake 2.8.11 oder neuer benötigt. GCC und make sudo make install -Damit wird mGBA gebaut und in `/usr/bin` und `/usr/lib` installiert. Installierte Abhängigkeiten werden automatisch erkannt. Features, die aufgrund fehlender Abhängigkeiten deaktiviert werden, werden nach dem `cmake`-Kommando aufgelistet. +Damit wird mGBA gebaut und in `/usr/bin` und `/usr/lib` installiert. Installierte Abhängigkeiten werden automatisch erkannt. Features, die aufgrund fehlender Abhängigkeiten deaktiviert wurden, werden nach dem `cmake`-Kommando angezeigt. -Wenn Du macOS verwendest, sind die einzelnen Schritte etwas anders. Angenommen, dass Du eine Homebrew-Paketverwaltung verwendest, werden folgende Schritte zum installieren der Abhängigkeiten und anschließenden bauen von mGBA empfohlen: +Wenn Du macOS verwendest, sind die einzelnen Schritte etwas anders. Angenommen, dass Du den Homebrew-Paketmanager verwendest, werden folgende Schritte zum installieren der Abhängigkeiten und anschließenden bauen von mGBA empfohlen: brew install cmake ffmpeg imagemagick libzip qt5 sdl2 libedit pkg-config mkdir build @@ -136,11 +157,11 @@ Um mGBA auf Windows zu kompilieren, wird MSYS2 empfohlen. Befolge die Installati Für x86 (32 Bit): - pacman -Sy base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} + pacman -Sy --needed base-devel git mingw-w64-i686-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} Für x86_64 (64 Bit): - pacman -Sy base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} + pacman -Sy --needed base-devel git mingw-w64-x86_64-{cmake,ffmpeg,gcc,gdb,imagemagick,libelf,libepoxy,libzip,pkg-config,qt5,SDL2,ntldd-git} Lade den aktuellen mGBA-Quellcode mithilfe des folgenden Kommandos herunter: @@ -154,7 +175,23 @@ Abschließend wird mGBA über folgende Kommandos kompiliert: cmake .. -G "MSYS Makefiles" make -Bitte beachte, dass mGBA für Windows aufgrund der Vielzahl an benötigten DLLs nicht für die weitere Verteilung geeignet ist, wenn es auf diese Weise gebaut wurde. Es ist jedoch perfekt für Entwickler geeignet. Soll mGBA dennoch weiter verteilt werden (beispielsweise zu Testzwecken auf Systemen, auf denen keine MSYS2-Umgebung installiert ist), kann mithilfe des Befehls 'cpack -G ZIP' ein ZIP-Archiv mit allen benötigten DLLs erstellt werden. +Bitte beachte, dass mGBA für Windows aufgrund der Vielzahl an benötigten DLLs nicht für die weitere Verteilung geeignet ist, wenn es auf diese Weise gebaut wurde. Es ist jedoch perfekt für Entwickler geeignet. Soll mGBA dennoch weiter verteilt werden (beispielsweise zu Testzwecken auf Systemen, auf denen keine MSYS2-Umgebung installiert ist), kann mithilfe des Befehls `cpack -G ZIP` ein ZIP-Archiv mit allen benötigten DLLs erstellt werden. + +#### Kompilieren mithilfe einer Toolchain + +Wenn Du devkitARM (für 3DS), devkitPPC (für Wii), devkitA64 (für Switch) oder vitasdk (für PS Vita) installiert hast, kannst Du die folgenden Befehle zum Kompilieren verwenden: + + mkdir build + cd build + cmake -DCMAKE_TOOLCHAIN_FILE=../src/platform/3ds/CMakeToolchain.txt .. + make + +Ersetze den Parameter `-DCMAKE_TOOLCHAIN_FILE` dabei folgendermaßen: + +- 3DS: `../src/platform/3ds/CMakeToolchain.txt` +- Switch: `../src/platform/switch/CMakeToolchain.txt` +- Vita: `../src/platform/psp2/CMakeToolchain.vitasdk` +- Wii: `../src/platform/wii/CMakeToolchain.txt` ### Abhängigkeiten From 00cbb6156ba020772fb44d6678d3b9142695c854 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 19 Nov 2018 21:16:57 -0800 Subject: [PATCH 29/50] GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM --- CHANGES | 1 + src/gba/dma.c | 4 +++- src/gba/memory.c | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 21b1e3f51..df60cbddf 100644 --- a/CHANGES +++ b/CHANGES @@ -136,6 +136,7 @@ Bugfixes: - Qt: Fix mapping analog triggers (fixes mgba.io/i/495) - Qt: Grab focus when game starts (fixes mgba.io/i/804) - Core: Remember to deinit proxy ring FIFO + - GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/gba/dma.c b/src/gba/dma.c index 2a33eae94..d3ad66c8a 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -278,7 +278,9 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata); } - GBASavedataWriteEEPROM(&memory->savedata, memory->dmaTransferRegister, wordsRemaining); + if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { + GBASavedataWriteEEPROM(&memory->savedata, memory->dmaTransferRegister, wordsRemaining); + } } else { cpu->memory.store16(cpu, dest, memory->dmaTransferRegister, 0); diff --git a/src/gba/memory.c b/src/gba/memory.c index 5c7efd104..58dca916f 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -892,7 +892,11 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle mLOG(GBA_MEM, INFO, "Detected EEPROM savegame"); GBASavedataInitEEPROM(&memory->savedata); } - GBASavedataWriteEEPROM(&memory->savedata, value, 1); + if (memory->savedata.type == SAVEDATA_EEPROM512 || memory->savedata.type == SAVEDATA_EEPROM) { + GBASavedataWriteEEPROM(&memory->savedata, value, 1); + break; + } + mLOG(GBA_MEM, GAME_ERROR, "Bad memory Store16: 0x%08X", address); break; case REGION_CART_SRAM: case REGION_CART_SRAM_MIRROR: From ff2a0f8519c89870e681171a1703ab91ade318b8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 21 Nov 2018 17:21:43 -0500 Subject: [PATCH 30/50] Debugger: Readability improvements (fixes #1238) --- CHANGES | 1 + src/arm/debugger/cli-debugger.c | 13 +++++++------ src/lr35902/debugger/cli-debugger.c | 14 +++++++------- src/lr35902/debugger/debugger.c | 4 ++-- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index df60cbddf..d1025d971 100644 --- a/CHANGES +++ b/CHANGES @@ -152,6 +152,7 @@ Misc: - Python: Minor API improvements - Qt: Minor memory view tweaks - CMake: Fix libswresample version dependencies (fixes mgba.io/i/1229) + - Debugger: Readability improvements (fixes mgba.io/i/1238) 0.7 beta 1: (2018-09-24) - Initial beta for 0.7 diff --git a/src/arm/debugger/cli-debugger.c b/src/arm/debugger/cli-debugger.c index 881b99e11..fe1265a11 100644 --- a/src/arm/debugger/cli-debugger.c +++ b/src/arm/debugger/cli-debugger.c @@ -125,13 +125,14 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { struct CLIDebuggerBackend* be = debugger->p->backend; struct ARMCore* cpu = debugger->p->d.core->cpu; int r; - for (r = 0; r < 4; ++r) { - be->printf(be, "%08X %08X %08X %08X\n", - cpu->gprs[r << 2], - cpu->gprs[(r << 2) + 1], - cpu->gprs[(r << 2) + 2], - cpu->gprs[(r << 2) + 3]); + for (r = 0; r < 16; r += 4) { + be->printf(be, "%sr%i: %08X %sr%i: %08X %sr%i: %08X %sr%i: %08X\n", + r < 10 ? " " : "", r, cpu->gprs[r], + r < 9 ? " " : "", r + 1, cpu->gprs[r + 1], + r < 8 ? " " : "", r + 2, cpu->gprs[r + 2], + r < 7 ? " " : "", r + 3, cpu->gprs[r + 3]); } + be->printf(be, "cpsr: "); _printPSR(be, cpu->cpsr); int instructionLength; enum ExecutionMode mode = cpu->cpsr.t; diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index 7df1ea726..fe85bca27 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -21,7 +21,7 @@ static struct CLIDebuggerCommandSummary _lr35902Commands[] = { }; static inline void _printFlags(struct CLIDebuggerBackend* be, union FlagRegister f) { - be->printf(be, "[%c%c%c%c]\n", + be->printf(be, "F: [%c%c%c%c]\n", f.z ? 'Z' : '-', f.n ? 'N' : '-', f.h ? 'H' : '-', @@ -82,16 +82,16 @@ static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address static void _printStatus(struct CLIDebuggerSystem* debugger) { struct CLIDebuggerBackend* be = debugger->p->backend; struct LR35902Core* cpu = debugger->p->d.core->cpu; - be->printf(be, "A: %02X F: %02X (AF: %04X)\n", cpu->a, cpu->f.packed, cpu->af); - be->printf(be, "B: %02X C: %02X (BC: %04X)\n", cpu->b, cpu->c, cpu->bc); - be->printf(be, "D: %02X E: %02X (DE: %04X)\n", cpu->d, cpu->e, cpu->de); - be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl); - be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp); + be->printf(be, "A: %02X F: %02X (AF: %04X)\n", cpu->a, cpu->f.packed, cpu->af); + be->printf(be, "B: %02X C: %02X (BC: %04X)\n", cpu->b, cpu->c, cpu->bc); + be->printf(be, "D: %02X E: %02X (DE: %04X)\n", cpu->d, cpu->e, cpu->de); + be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl); + be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp); struct LR35902Debugger* platDebugger = (struct LR35902Debugger*) debugger->p->d.platform; size_t i; for (i = 0; platDebugger->segments[i].name; ++i) { - be->printf(be, "%s%s: %02X", i ? " " : "", platDebugger->segments[i].name, cpu->memory.currentSegment(cpu, platDebugger->segments[i].start)); + be->printf(be, "%s%s: %02X", i ? " " : "", platDebugger->segments[i].name, cpu->memory.currentSegment(cpu, platDebugger->segments[i].start)); } if (i) { be->printf(be, "\n"); diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 04337f463..02f19138d 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -213,10 +213,10 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* disPtr += 2; LR35902Disassemble(&info, disPtr, sizeof(disassembly) - (disPtr - disassembly)); - *length = snprintf(out, *length, "A: %02X F: %02X B: %02X C: %02X D: %02X E: %02X H: %02X L: %02X SP: %04X PC: %04X | %s", + *length = snprintf(out, *length, "A: %02X F: %02X B: %02X C: %02X D: %02X E: %02X H: %02X L: %02X SP: %04X PC: %02X:%04X | %s", cpu->a, cpu->f.packed, cpu->b, cpu->c, cpu->d, cpu->e, cpu->h, cpu->l, - cpu->sp, cpu->pc, disassembly); + cpu->sp, cpu->memory.currentSegment(cpu, cpu->pc), cpu->pc, disassembly); } bool LR35902DebuggerGetRegister(struct mDebuggerPlatform* d, const char* name, int32_t* value) { From 741ac61baac7bec7101e7c24b35a13ad3e69d058 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 21 Nov 2018 23:07:25 -0500 Subject: [PATCH 31/50] Core: Reroot timing list when (de)scheduling --- CHANGES | 1 + src/core/timing.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index d1025d971..91c46f86d 100644 --- a/CHANGES +++ b/CHANGES @@ -137,6 +137,7 @@ Bugfixes: - Qt: Grab focus when game starts (fixes mgba.io/i/804) - Core: Remember to deinit proxy ring FIFO - GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM + - Core: Reroot timing list when (de)scheduling Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/core/timing.c b/src/core/timing.c index be63c1029..7059659ea 100644 --- a/src/core/timing.c +++ b/src/core/timing.c @@ -28,6 +28,10 @@ void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t if (nextEvent < *timing->nextEvent) { *timing->nextEvent = nextEvent; } + if (timing->reroot) { + timing->root = timing->reroot; + timing->reroot = NULL; + } struct mTimingEvent** previous = &timing->root; struct mTimingEvent* next = timing->root; unsigned priority = event->priority; @@ -44,6 +48,10 @@ void mTimingSchedule(struct mTiming* timing, struct mTimingEvent* event, int32_t } void mTimingDeschedule(struct mTiming* timing, struct mTimingEvent* event) { + if (timing->reroot) { + timing->root = timing->reroot; + timing->reroot = NULL; + } struct mTimingEvent** previous = &timing->root; struct mTimingEvent* next = timing->root; while (next) { From 38bad71e119aa71f9c89d066fdfe589d3cdfd2e6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 23 Nov 2018 16:29:52 -0500 Subject: [PATCH 32/50] GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes #1224) --- CHANGES | 1 + src/gb/video.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 91c46f86d..4cb831613 100644 --- a/CHANGES +++ b/CHANGES @@ -138,6 +138,7 @@ Bugfixes: - Core: Remember to deinit proxy ring FIFO - GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM - Core: Reroot timing list when (de)scheduling + - GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224) Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/gb/video.c b/src/gb/video.c index dcb49523c..d63460088 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -449,10 +449,12 @@ void GBVideoWriteSTAT(struct GBVideo* video, GBRegisterSTAT value) { void GBVideoWriteLYC(struct GBVideo* video, uint8_t value) { GBRegisterSTAT oldStat = video->stat; - video->stat = GBRegisterSTATSetLYC(video->stat, value == video->ly); - if (!_statIRQAsserted(video, oldStat) && _statIRQAsserted(video, video->stat)) { - video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT); - GBUpdateIRQs(video->p); + if (GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC])) { + video->stat = GBRegisterSTATSetLYC(video->stat, value == video->ly); + if (!_statIRQAsserted(video, oldStat) && _statIRQAsserted(video, video->stat)) { + video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT); + GBUpdateIRQs(video->p); + } } video->p->memory.io[REG_STAT] = video->stat; } From df497cf336fb542a49b2a0b45c3262f175c53c50 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Wed, 28 Nov 2018 18:01:20 +0000 Subject: [PATCH 33/50] SDL: Split sw-sdl.c into separate files --- src/platform/sdl/CMakeLists.txt | 6 +- src/platform/sdl/{sw-sdl.c => sw-sdl1.c} | 35 ------------ src/platform/sdl/sw-sdl2.c | 72 ++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 36 deletions(-) rename src/platform/sdl/{sw-sdl.c => sw-sdl1.c} (68%) create mode 100644 src/platform/sdl/sw-sdl2.c diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 0c2fc771b..bed74eea8 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -85,7 +85,11 @@ else() include_directories(${OPENGLES2_INCLUDE_DIR}) endif() if(NOT BUILD_GL AND NOT BUILD_GLES2) - list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c) + if(SDL_VERSION EQUAL "2") + list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl2.c) + else() + list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl1.c) + endif() endif() endif() diff --git a/src/platform/sdl/sw-sdl.c b/src/platform/sdl/sw-sdl1.c similarity index 68% rename from src/platform/sdl/sw-sdl.c rename to src/platform/sdl/sw-sdl1.c index 2451eb2c6..374d11bdf 100644 --- a/src/platform/sdl/sw-sdl.c +++ b/src/platform/sdl/sw-sdl1.c @@ -21,35 +21,14 @@ void mSDLSWCreate(struct mSDLRenderer* renderer) { } bool mSDLSWInit(struct mSDLRenderer* renderer) { -#if !SDL_VERSION_ATLEAST(2, 0, 0) #ifdef COLOR_16_BIT SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE); #else SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); -#endif #endif unsigned width, height; renderer->core->desiredVideoDimensions(renderer->core, &width, &height); -#if SDL_VERSION_ATLEAST(2, 0, 0) - renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); - SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); - renderer->player.window = renderer->window; - renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); -#ifdef COLOR_16_BIT -#ifdef COLOR_5_6_5 - renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); -#else - renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height); -#endif -#else - renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height); -#endif - - int stride; - SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); - renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); -#else SDL_Surface* surface = SDL_GetVideoSurface(); SDL_LockSurface(surface); @@ -81,7 +60,6 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) { return false; #endif } -#endif return true; } @@ -89,9 +67,7 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) { void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) { struct mCoreThread* context = user; SDL_Event event; -#if !SDL_VERSION_ATLEAST(2, 0, 0) SDL_Surface* surface = SDL_GetVideoSurface(); -#endif while (mCoreThreadIsActive(context)) { while (SDL_PollEvent(&event)) { @@ -99,14 +75,6 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) { } if (mCoreSyncWaitFrameStart(&context->impl->sync)) { -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_UnlockTexture(renderer->sdlTex); - SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0); - SDL_RenderPresent(renderer->sdlRenderer); - int stride; - SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); - renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); -#else #ifdef USE_PIXMAN if (renderer->ratio > 1) { pixman_image_composite32(PIXMAN_OP_SRC, renderer->pix, 0, renderer->screenpix, @@ -132,7 +100,6 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) { SDL_UnlockSurface(surface); SDL_Flip(surface); SDL_LockSurface(surface); -#endif } mCoreSyncWaitFrameEnd(&context->impl->sync); } @@ -142,12 +109,10 @@ void mSDLSWDeinit(struct mSDLRenderer* renderer) { if (renderer->ratio > 1) { free(renderer->outputBuffer); } -#if !SDL_VERSION_ATLEAST(2, 0, 0) SDL_Surface* surface = SDL_GetVideoSurface(); SDL_UnlockSurface(surface); #ifdef USE_PIXMAN pixman_image_unref(renderer->pix); pixman_image_unref(renderer->screenpix); #endif -#endif } diff --git a/src/platform/sdl/sw-sdl2.c b/src/platform/sdl/sw-sdl2.c new file mode 100644 index 000000000..fb5a3f0b9 --- /dev/null +++ b/src/platform/sdl/sw-sdl2.c @@ -0,0 +1,72 @@ +/* Copyright (c) 2013-2015 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 "main.h" + +#include +#include +#include +#include + +static bool mSDLSWInit(struct mSDLRenderer* renderer); +static void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user); +static void mSDLSWDeinit(struct mSDLRenderer* renderer); + +void mSDLSWCreate(struct mSDLRenderer* renderer) { + renderer->init = mSDLSWInit; + renderer->deinit = mSDLSWDeinit; + renderer->runloop = mSDLSWRunloop; +} + +bool mSDLSWInit(struct mSDLRenderer* renderer) { + unsigned width, height; + renderer->core->desiredVideoDimensions(renderer->core, &width, &height); + renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); + SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); + renderer->player.window = renderer->window; + renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); +#else + renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height); +#endif +#else + renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height); +#endif + + int stride; + SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); + renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); + + return true; +} + +void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) { + struct mCoreThread* context = user; + SDL_Event event; + + while (mCoreThreadIsActive(context)) { + while (SDL_PollEvent(&event)) { + mSDLHandleEvent(context, &renderer->player, &event); + } + + if (mCoreSyncWaitFrameStart(&context->impl->sync)) { + SDL_UnlockTexture(renderer->sdlTex); + SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0); + SDL_RenderPresent(renderer->sdlRenderer); + int stride; + SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); + renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); + } + mCoreSyncWaitFrameEnd(&context->impl->sync); + } +} + +void mSDLSWDeinit(struct mSDLRenderer* renderer) { + if (renderer->ratio > 1) { + free(renderer->outputBuffer); + } +} From d8c3236c857abed3abe5e0db396515bcf3efd2c7 Mon Sep 17 00:00:00 2001 From: RidgeX Date: Tue, 27 Nov 2018 12:34:00 +0000 Subject: [PATCH 34/50] GBA I/O: SOUNDCNT_HI is readable when sound is off --- CHANGES | 1 + src/gba/io.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4cb831613..1753ee27a 100644 --- a/CHANGES +++ b/CHANGES @@ -139,6 +139,7 @@ Bugfixes: - GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM - Core: Reroot timing list when (de)scheduling - GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224) + - GBA I/O: SOUNDCNT_HI is readable when sound is off Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/gba/io.c b/src/gba/io.c index a4dd110f9..b06e950fc 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -841,7 +841,6 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { case REG_SOUND4CNT_LO: case REG_SOUND4CNT_HI: case REG_SOUNDCNT_LO: - case REG_SOUNDCNT_HI: if (!GBAudioEnableIsEnable(gba->memory.io[REG_SOUNDCNT_X >> 1])) { // TODO: Is writing allowed when the circuit is disabled? return 0; @@ -858,6 +857,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { case REG_WINOUT: case REG_BLDCNT: case REG_BLDALPHA: + case REG_SOUNDCNT_HI: case REG_SOUNDCNT_X: case REG_WAVE_RAM0_LO: case REG_WAVE_RAM0_HI: From bc9dff00da64b899662dc4433ff750a1f1fd715e Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Thu, 29 Nov 2018 21:45:11 +0000 Subject: [PATCH 35/50] SDL: Only unreference pixman buffers when necessary --- src/platform/sdl/sw-sdl1.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/sdl/sw-sdl1.c b/src/platform/sdl/sw-sdl1.c index 374d11bdf..29e9b15e8 100644 --- a/src/platform/sdl/sw-sdl1.c +++ b/src/platform/sdl/sw-sdl1.c @@ -108,11 +108,11 @@ void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) { void mSDLSWDeinit(struct mSDLRenderer* renderer) { if (renderer->ratio > 1) { free(renderer->outputBuffer); +#ifdef USE_PIXMAN + pixman_image_unref(renderer->pix); + pixman_image_unref(renderer->screenpix); +#endif } SDL_Surface* surface = SDL_GetVideoSurface(); SDL_UnlockSurface(surface); -#ifdef USE_PIXMAN - pixman_image_unref(renderer->pix); - pixman_image_unref(renderer->screenpix); -#endif } From 11559cb2a9e9fc044954559140f301296af06bb8 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Fri, 30 Nov 2018 18:11:35 +0000 Subject: [PATCH 36/50] SDL: Set the window name when using SDL 1.2 --- src/platform/sdl/gl-common.c | 1 + src/platform/sdl/sw-sdl1.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 0b73cc519..2ec8227ca 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -55,5 +55,6 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) { #else SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | (SDL_FULLSCREEN * renderer->fullscreen)); #endif + SDL_WM_SetCaption(projectName, ""); #endif } diff --git a/src/platform/sdl/sw-sdl1.c b/src/platform/sdl/sw-sdl1.c index 29e9b15e8..776984fe2 100644 --- a/src/platform/sdl/sw-sdl1.c +++ b/src/platform/sdl/sw-sdl1.c @@ -26,6 +26,7 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) { #else SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); #endif + SDL_WM_SetCaption(projectName, ""); unsigned width, height; renderer->core->desiredVideoDimensions(renderer->core, &width, &height); From b55fac0a8a09ec34b9ac273eeba182537db6cfe6 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Fri, 30 Nov 2018 18:45:08 +0000 Subject: [PATCH 37/50] SDL: Support fullscreen mode when using the SDL1 software renderer --- src/platform/sdl/sw-sdl1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/sdl/sw-sdl1.c b/src/platform/sdl/sw-sdl1.c index 776984fe2..c8002fd24 100644 --- a/src/platform/sdl/sw-sdl1.c +++ b/src/platform/sdl/sw-sdl1.c @@ -22,9 +22,9 @@ void mSDLSWCreate(struct mSDLRenderer* renderer) { bool mSDLSWInit(struct mSDLRenderer* renderer) { #ifdef COLOR_16_BIT - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->fullscreen)); #else - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->fullscreen)); #endif SDL_WM_SetCaption(projectName, ""); From 42f65db3960834394438017cea28547f41560d25 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Fri, 30 Nov 2018 13:28:18 +0000 Subject: [PATCH 38/50] SDL: Fix auto-detection of SDL version --- src/platform/sdl/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index bed74eea8..b2f9df308 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -15,7 +15,7 @@ endif() if(SDL_VERSION EQUAL "1.2" OR NOT SDL2_FOUND) find_package(SDL 1.2) if(SDL_FOUND) - set(SDL_VERSION "1.2" PARENT_SCOPE) + set(SDL_VERSION "1.2") set(SDL_VERSION_DEBIAN "1.2debian") set(USE_PIXMAN ON) endif() @@ -26,6 +26,7 @@ if (NOT SDL2_FOUND AND NOT SDL_FOUND) return() endif() +set(SDL_VERSION "${SDL_VERSION}" PARENT_SCOPE) add_definitions(-DBUILD_SDL) find_feature(USE_PIXMAN "pixman-1") From 0332db8961ef1b11b4f9e0326d3683b8e5d17730 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 5 Dec 2018 19:39:29 -0800 Subject: [PATCH 39/50] GB Memory: Support running from blocked memory --- CHANGES | 1 + src/gb/memory.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index 1753ee27a..d9fc51a9f 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Bugfixes: Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash + - GB Memory: Support running from blocked memory 0.7.0: (Future) Features: diff --git a/src/gb/memory.c b/src/gb/memory.c index b2e229c4d..15ef917ad 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -45,6 +45,8 @@ static const enum GBBus _oamBlockCGB[] = { GB_BUS_CPU // 0xE000 }; +static const uint8_t _blockedRegion[1] = { 0xFF }; + static void _pristineCow(struct GB* gba); static uint8_t GBFastLoad8(struct LR35902Core* cpu, uint16_t address) { @@ -92,6 +94,15 @@ static void GBSetActiveRegion(struct LR35902Core* cpu, uint16_t address) { cpu->memory.cpuLoad8 = GBLoad8; break; } + if (gb->memory.dmaRemaining) { + const enum GBBus* block = gb->model < GB_MODEL_CGB ? _oamBlockDMG : _oamBlockCGB; + enum GBBus dmaBus = block[memory->dmaSource >> 13]; + enum GBBus accessBus = block[address >> 13]; + if ((dmaBus != GB_BUS_CPU && dmaBus == accessBus) || (address >= GB_BASE_OAM && address < GB_BASE_UNUSABLE)) { + cpu->memory.activeRegion = _blockedRegion; + cpu->memory.activeMask = 0; + } + } } static void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate); From 6158a4fb8d6bc8e7df42504bad7e18d9b5c667a3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 5 Dec 2018 19:47:57 -0800 Subject: [PATCH 40/50] GB Audio: Skip frame if enabled when clock is high --- include/mgba/internal/gb/audio.h | 1 + include/mgba/internal/gb/serialize.h | 1 + src/gb/audio.c | 17 +++++++++++++++++ src/gb/timer.c | 3 ++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/mgba/internal/gb/audio.h b/include/mgba/internal/gb/audio.h index 837e0a1b3..ed3a76325 100644 --- a/include/mgba/internal/gb/audio.h +++ b/include/mgba/internal/gb/audio.h @@ -187,6 +187,7 @@ struct GBAudio { uint8_t* nr52; int frame; + bool skipFrame; int32_t sampleInterval; enum GBAudioStyle style; diff --git a/include/mgba/internal/gb/serialize.h b/include/mgba/internal/gb/serialize.h index 14cfd12d4..7b1feb93e 100644 --- a/include/mgba/internal/gb/serialize.h +++ b/include/mgba/internal/gb/serialize.h @@ -195,6 +195,7 @@ DECL_BITS(GBSerializedAudioFlags, Frame, 22, 3); DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25); DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26); DECL_BIT(GBSerializedAudioFlags, Ch3Readable, 27); +DECL_BIT(GBSerializedAudioFlags, SkipFrame, 28); DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t); DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7); diff --git a/src/gb/audio.c b/src/gb/audio.c index ee5ec9ed8..08ba1fa9e 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -470,7 +470,15 @@ void GBAudioWriteNR52(struct GBAudio* audio, uint8_t value) { } *audio->nr52 &= ~0x000F; } else if (!wasEnable) { + audio->skipFrame = false; audio->frame = 7; + + if (audio->p) { + unsigned timingFactor = 0x400 >> !audio->p->doubleSpeed; + if (audio->p->timer.internalDiv & timingFactor) { + audio->skipFrame = true; + } + } } } @@ -483,6 +491,13 @@ void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate) { } void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) { + if (!audio->enable) { + return; + } + if (audio->skipFrame) { + audio->skipFrame = false; + return; + } int frame = (audio->frame + 1) & 7; audio->frame = frame; @@ -929,6 +944,7 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat uint32_t ch4Flags = 0; flags = GBSerializedAudioFlagsSetFrame(flags, audio->frame); + flags = GBSerializedAudioFlagsSetSkipFrame(flags, audio->skipFrame); STORE_32LE(audio->frameEvent.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextFrame); flags = GBSerializedAudioFlagsSetCh1Volume(flags, audio->ch1.envelope.currentVolume); @@ -987,6 +1003,7 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt LOAD_32LE(flags, 0, flagsIn); audio->frame = GBSerializedAudioFlagsGetFrame(flags); + audio->skipFrame = GBSerializedAudioFlagsGetSkipFrame(flags); LOAD_32LE(ch1Flags, 0, &state->ch1.envelope); audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags); diff --git a/src/gb/timer.c b/src/gb/timer.c index 32c9efdc5..e990b3534 100644 --- a/src/gb/timer.c +++ b/src/gb/timer.c @@ -80,7 +80,8 @@ void GBTimerDivReset(struct GBTimer* timer) { mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3)); } } - if (timer->internalDiv & 0x200) { + unsigned timingFactor = 0x400 >> !timer->p->doubleSpeed; + if (timer->internalDiv & timingFactor) { GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing); } timer->p->memory.io[REG_DIV] = 0; From 7bc50b90cd38b72105d876e3e53df623f1694aa8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 8 Dec 2018 16:40:43 -0800 Subject: [PATCH 41/50] CHANGES: Update --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index d9fc51a9f..2c44da5b5 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - GB Memory: Support running from blocked memory + - GB Audio: Skip frame if enabled when clock is high 0.7.0: (Future) Features: From 759a1d27491332da7a051859e783abb33c492544 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 8 Dec 2018 16:41:19 -0800 Subject: [PATCH 42/50] Qt: Fix non-SQLite build (fixes #1254) --- src/platform/qt/GBAApp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index 823f3f773..c331c11f3 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -75,9 +75,11 @@ void GBAApp::cleanup() { finishJob(m_workerJobs.firstKey()); } +#ifdef USE_SQLITE3 if (m_db) { NoIntroDBDestroy(m_db); } +#endif } bool GBAApp::event(QEvent* event) { From 062ba0767c25aaf647f3caf967f86bb860037066 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Dec 2018 18:33:52 -0800 Subject: [PATCH 43/50] SDL: Fix handling of invalid gamepads (fixes #1239) --- CHANGES | 1 + src/platform/sdl/sdl-events.c | 43 +++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 2c44da5b5..1cb1e28ce 100644 --- a/CHANGES +++ b/CHANGES @@ -142,6 +142,7 @@ Bugfixes: - Core: Reroot timing list when (de)scheduling - GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224) - GBA I/O: SOUNDCNT_HI is readable when sound is off + - SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239) Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 00d6df378..9f4b218b2 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -64,8 +64,12 @@ bool mSDLInitEvents(struct mSDLEvents* context) { if (!SDL_JoystickListSize(&context->joysticks)) { int i; for (i = 0; i < nJoysticks; ++i) { + SDL_Joystick* sdlJoystick = SDL_JoystickOpen(i); + if (!sdlJoystick) { + continue; + } struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&context->joysticks); - joystick->joystick = SDL_JoystickOpen(i); + joystick->joystick = sdlJoystick; joystick->index = SDL_JoystickListSize(&context->joysticks) - 1; #if SDL_VERSION_ATLEAST(2, 0, 0) joystick->id = SDL_JoystickInstanceID(joystick->joystick); @@ -203,6 +207,9 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { #else joystickName = SDL_JoystickName(SDL_JoystickIndex(SDL_JoystickListGetPointer(&events->joysticks, i)->joystick)); #endif + if (!joystickName) { + continue; + } if (events->preferredJoysticks[player->playerId] && strcmp(events->preferredJoysticks[player->playerId], joystickName) == 0) { index = i; break; @@ -253,6 +260,9 @@ void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration #else const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); #endif + if (!name) { + return; + } mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name); const char* value; @@ -304,6 +314,9 @@ void mSDLPlayerSaveConfig(const struct mSDLPlayer* context, struct Configuration #else const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick)); #endif + if (!name) { + return; + } char value[16]; snprintf(value, sizeof(value), "%i", context->rotation.axisX); mInputSetCustomValue(config, "gba", SDL_BINDING_BUTTON, "tiltAxisX", value, name); @@ -332,8 +345,12 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration* SDL_Event event; while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED) > 0) { if (event.type == SDL_JOYDEVICEADDED) { + SDL_Joystick* sdlJoystick = SDL_JoystickOpen(event.jdevice.which); + if (!sdlJoystick) { + continue; + } struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&events->joysticks); - joystick->joystick = SDL_JoystickOpen(event.jdevice.which); + joystick->joystick = sdlJoystick; joystick->id = SDL_JoystickInstanceID(joystick->joystick); joystick->index = SDL_JoystickListSize(&events->joysticks) - 1; #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -347,16 +364,18 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration* joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick)); #endif size_t i; - for (i = 0; (int) i < events->playersAttached; ++i) { - if (events->players[i]->joystick) { - continue; - } - if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) { - events->players[i]->joystick = joystick; - if (config) { - mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); + if (joystickName) { + for (i = 0; (int) i < events->playersAttached; ++i) { + if (events->players[i]->joystick) { + continue; + } + if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) { + events->players[i]->joystick = joystick; + if (config) { + mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); + } + return; } - return; } } for (i = 0; (int) i < events->playersAttached; ++i) { @@ -364,7 +383,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration* continue; } events->players[i]->joystick = joystick; - if (config) { + if (config && joystickName) { mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName); } break; From 6442d17b4c0012a68683b052a0c1bbafd2318722 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 26 Dec 2018 13:28:08 -0800 Subject: [PATCH 44/50] Libretro: Fix adding codes with hooks --- CHANGES | 1 + src/gba/cheats.c | 3 +++ src/platform/libretro/libretro.c | 1 + 3 files changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 1cb1e28ce..b8e12c52b 100644 --- a/CHANGES +++ b/CHANGES @@ -143,6 +143,7 @@ Bugfixes: - GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224) - GBA I/O: SOUNDCNT_HI is readable when sound is off - SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239) + - Libretro: Fix adding codes with hooks Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/gba/cheats.c b/src/gba/cheats.c index 19e80b0b1..8999abc23 100644 --- a/src/gba/cheats.c +++ b/src/gba/cheats.c @@ -276,6 +276,9 @@ static void GBACheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* devic struct GBACheatSet* gbaset = (struct GBACheatSet*) cheats; if (cheats->enabled) { _patchROM(device, gbaset); + if (gbaset->hook && !gbaset->hook->reentries) { + _addBreakpoint(device, gbaset); + } } else { _unpatchROM(device, gbaset); } diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 57bd74296..6caa5d866 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -657,6 +657,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char* code) { } } #endif + cheatSet->refresh(cheatSet, device); } unsigned retro_get_region(void) { From 3fb46a2a8832c383429fd65c00ba3e642c750bcf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 29 Dec 2018 23:08:09 -0800 Subject: [PATCH 45/50] GBA Savedata: Fix 4 kiB EEPROM overrides (fixes #1251) --- src/gba/savedata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 10f9499fa..0c8207b3a 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -226,6 +226,7 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) break; case SAVEDATA_EEPROM: case SAVEDATA_EEPROM512: + savedata->type = type; GBASavedataInitEEPROM(savedata); break; case SAVEDATA_SRAM: From 6617a9dccdf693c25b8f2cd19214fd988bad6ffe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 2 Jan 2019 20:55:37 -0800 Subject: [PATCH 46/50] Switch: Adapt to egl changes --- src/platform/switch/main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index c8d2fbd3d..a6e8d9941 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -120,7 +120,7 @@ static bool initEgl() { goto _fail1; } - s_surface = eglCreateWindowSurface(s_display, config, "", NULL); + s_surface = eglCreateWindowSurface(s_display, config, nwindowGetDefault(), NULL); if (!s_surface) { goto _fail1; } @@ -403,6 +403,7 @@ static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { } } frameLimiter = limit; + eglSwapInterval(s_surface, limit); } static bool _running(struct mGUIRunner* runner) { @@ -663,11 +664,12 @@ int main(int argc, char* argv[]) { .submenu = 0, .state = 7, .validStates = (const char*[]) { - "3", "4", "5", "6", "7", "8", "9", + "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "20", "30" }, .stateMappings = (const struct GUIVariant[]) { + GUI_V_U(2), GUI_V_U(3), GUI_V_U(4), GUI_V_U(5), @@ -684,7 +686,7 @@ int main(int argc, char* argv[]) { GUI_V_U(20), GUI_V_U(30), }, - .nStates = 15 + .nStates = 16 }, }, .nConfigExtra = 2, From aa90dbbc92aca9c864e52c89005d9241121a1dc0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 4 Jan 2019 21:48:21 -0800 Subject: [PATCH 47/50] Res: Improve modeling of AGB/AGS screen in shaders --- CHANGES | 3 ++- res/shaders/agb001.shader/agb001.fs | 9 ++++----- res/shaders/agb001.shader/manifest.ini | 2 +- res/shaders/ags001.shader/ags001.fs | 9 ++++----- res/shaders/ags001.shader/manifest.ini | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index b8e12c52b..749b79b95 100644 --- a/CHANGES +++ b/CHANGES @@ -7,7 +7,6 @@ Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - GB Memory: Support running from blocked memory - - GB Audio: Skip frame if enabled when clock is high 0.7.0: (Future) Features: @@ -160,6 +159,8 @@ Misc: - Qt: Minor memory view tweaks - CMake: Fix libswresample version dependencies (fixes mgba.io/i/1229) - Debugger: Readability improvements (fixes mgba.io/i/1238) + - GB Audio: Skip frame if enabled when clock is high + - Res: Improve modeling of AGB/AGS screen in shaders 0.7 beta 1: (2018-09-24) - Initial beta for 0.7 diff --git a/res/shaders/agb001.shader/agb001.fs b/res/shaders/agb001.shader/agb001.fs index 79a036ff7..732b941b2 100644 --- a/res/shaders/agb001.shader/agb001.fs +++ b/res/shaders/agb001.shader/agb001.fs @@ -4,18 +4,17 @@ uniform vec2 texSize; void main() { vec4 color = texture2D(tex, texCoord); - vec3 arrayX[4]; - arrayX[0] = vec3(1.0, 0.2, 0.2); + vec3 arrayX[3]; + arrayX[0] = vec3(0.2, 0.2, 1.0); arrayX[1] = vec3(0.2, 1.0, 0.2); - arrayX[2] = vec3(0.2, 0.2, 1.0); - arrayX[3] = vec3(0.4, 0.4, 0.4); + arrayX[2] = vec3(1.0, 0.2, 0.2); vec3 arrayY[4]; arrayY[0] = vec3(1.0, 1.0, 1.0); arrayY[1] = vec3(1.0, 1.0, 1.0); arrayY[2] = vec3(1.0, 1.0, 1.0); arrayY[3] = vec3(0.8, 0.8, 0.8); color.rgb = pow(color.rgb * vec3(0.8, 0.8, 0.8), vec3(1.8, 1.8, 1.8)) + vec3(0.16, 0.16, 0.16); - color.rgb *= arrayX[int(mod(texCoord.s * texSize.x * 4.0, 4.0))]; + color.rgb *= arrayX[int(mod(texCoord.s * texSize.x * 3.0, 3.0))]; color.rgb *= arrayY[int(mod(texCoord.t * texSize.y * 4.0, 4.0))]; color.a = 0.5; gl_FragColor = color; diff --git a/res/shaders/agb001.shader/manifest.ini b/res/shaders/agb001.shader/manifest.ini index 4c1a8f5b3..8196fd5b5 100644 --- a/res/shaders/agb001.shader/manifest.ini +++ b/res/shaders/agb001.shader/manifest.ini @@ -7,5 +7,5 @@ passes=1 [pass.0] fragmentShader=agb001.fs blend=1 -width=-4 +width=-3 height=-4 diff --git a/res/shaders/ags001.shader/ags001.fs b/res/shaders/ags001.shader/ags001.fs index 8b7265bd3..1f70cef07 100644 --- a/res/shaders/ags001.shader/ags001.fs +++ b/res/shaders/ags001.shader/ags001.fs @@ -4,18 +4,17 @@ uniform vec2 texSize; void main() { vec4 color = texture2D(tex, texCoord); - vec3 arrayX[4]; - arrayX[0] = vec3(1.0, 0.2, 0.2); + vec3 arrayX[3]; + arrayX[0] = vec3(0.2, 0.2, 1.0); arrayX[1] = vec3(0.2, 1.0, 0.2); - arrayX[2] = vec3(0.2, 0.2, 1.0); - arrayX[3] = vec3(0.4, 0.4, 0.4); + arrayX[2] = vec3(1.0, 0.2, 0.2); vec3 arrayY[4]; arrayY[0] = vec3(1.0, 1.0, 1.0); arrayY[1] = vec3(1.0, 1.0, 1.0); arrayY[2] = vec3(1.0, 1.0, 1.0); arrayY[3] = vec3(0.9, 0.9, 0.9); color.rgb = pow(color.rgb, vec3(1.6, 1.6, 1.6)); - color.rgb *= arrayX[int(mod(texCoord.s * texSize.x * 4.0, 4.0))]; + color.rgb *= arrayX[int(mod(texCoord.s * texSize.x * 3.0, 3.0))]; color.rgb *= arrayY[int(mod(texCoord.t * texSize.y * 4.0, 4.0))]; color.a = 0.8; gl_FragColor = color; diff --git a/res/shaders/ags001.shader/manifest.ini b/res/shaders/ags001.shader/manifest.ini index 2d5b7c491..1d7d95dcc 100644 --- a/res/shaders/ags001.shader/manifest.ini +++ b/res/shaders/ags001.shader/manifest.ini @@ -7,12 +7,12 @@ passes=2 [pass.0] fragmentShader=ags001.fs blend=1 -width=-4 +width=-3 height=-4 [pass.1] fragmentShader=ags001-light.fs -width=-4 +width=-3 height=-4 [pass.1.uniform.lightBrightness] From 3dc30a13d19fb536c1f348bc8c227bb40cbfc962 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 7 Jan 2019 22:15:23 -0800 Subject: [PATCH 48/50] GBA BIOS: BitUnPack improvements --- CHANGES | 1 + src/gba/bios.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 749b79b95..72f2c6aac 100644 --- a/CHANGES +++ b/CHANGES @@ -74,6 +74,7 @@ Bugfixes: - GB Audio: Fix channel 1, 2 and 4 reset timing - Util: Fix wrapping edge cases in RingFIFO - GBA Hardware: Fix RTC handshake transition (fixes mgba.io/i/1134) + - GBA BIOS: Fix BitUnPack narrowing Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/src/gba/bios.c b/src/gba/bios.c index 286c00a7f..186c1d1b6 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -819,7 +819,6 @@ static void _unBitPack(struct GBA* gba) { in >>= sourceWidth; if (scaled || bias & 0x80000000) { scaled += bias & 0x7FFFFFFF; - scaled &= (1 << destWidth) - 1; } bitsRemaining -= sourceWidth; out |= scaled << bitsEaten; @@ -831,4 +830,6 @@ static void _unBitPack(struct GBA* gba) { dest += 4; } } + cpu->gprs[0] = source; + cpu->gprs[1] = dest; } From 69014400db6b8c299ab5ca6770e5a4e19ae78c0a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 8 Jan 2019 23:19:33 -0800 Subject: [PATCH 49/50] GBA: Fix GB Player features --- CHANGES | 1 + src/gba/hardware.c | 4 ++-- src/gba/io.c | 22 +++++++++++----------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 72f2c6aac..242f4427c 100644 --- a/CHANGES +++ b/CHANGES @@ -144,6 +144,7 @@ Bugfixes: - GBA I/O: SOUNDCNT_HI is readable when sound is off - SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239) - Libretro: Fix adding codes with hooks + - GBA: Fix GB Player features Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/gba/hardware.c b/src/gba/hardware.c index 70704a5d2..e981a9649 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -539,9 +539,9 @@ void GBAHardwarePlayerUpdate(struct GBA* gba) { uint16_t _gbpRead(struct mKeyCallback* callback) { struct GBAGBPKeyCallback* gbpCallback = (struct GBAGBPKeyCallback*) callback; if (gbpCallback->p->gbpInputsPosted == 2) { - return 0x30F; + return 0xF0; } - return 0x3FF; + return 0; } uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { diff --git a/src/gba/io.c b/src/gba/io.c index b06e950fc..c3561dd50 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -728,7 +728,7 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { if (gba->rr && gba->rr->isPlaying(gba->rr)) { return 0x3FF ^ gba->rr->queryInput(gba->rr); } else { - uint16_t input = 0x3FF; + uint16_t input = 0; if (gba->keyCallback) { input = gba->keyCallback->readKeys(gba->keyCallback); if (gba->keySource) { @@ -736,16 +736,16 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { } } else if (gba->keySource) { input = *gba->keySource; - } - if (!gba->allowOpposingDirections) { - unsigned rl = input & 0x030; - unsigned ud = input & 0x0C0; - input &= 0x30F; - if (rl != 0x030) { - input |= rl; - } - if (ud != 0x0C0) { - input |= ud; + if (!gba->allowOpposingDirections) { + unsigned rl = input & 0x030; + unsigned ud = input & 0x0C0; + input &= 0x30F; + if (rl != 0x030) { + input |= rl; + } + if (ud != 0x0C0) { + input |= ud; + } } } if (gba->rr && gba->rr->isRecording(gba->rr)) { From c1eb1e5ae1843b4d4781fc39c8edaf362943c78e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 12 Jan 2019 15:56:29 -0800 Subject: [PATCH 50/50] Qt: Ensure FATAL logs reach log view --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 242f4427c..82d01ed78 100644 --- a/CHANGES +++ b/CHANGES @@ -145,6 +145,7 @@ Bugfixes: - SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239) - Libretro: Fix adding codes with hooks - GBA: Fix GB Player features + - Qt: Ensure FATAL logs reach log view Misc: - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index e16e1c5da..1c848ab4b 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -185,12 +185,12 @@ CoreController::CoreController(mCore* core, QObject* parent) message = QString().vsprintf(format, args); QMetaObject::invokeMethod(controller, "statusPosted", Q_ARG(const QString&, message)); } + message = QString().vsprintf(format, args); + QMetaObject::invokeMethod(controller, "logPosted", Q_ARG(int, level), Q_ARG(int, category), Q_ARG(const QString&, message)); if (level == mLOG_FATAL) { mCoreThreadMarkCrashed(controller->thread()); QMetaObject::invokeMethod(controller, "crashed", Q_ARG(const QString&, QString().vsprintf(format, args))); } - message = QString().vsprintf(format, args); - QMetaObject::invokeMethod(controller, "logPosted", Q_ARG(int, level), Q_ARG(int, category), Q_ARG(const QString&, message)); }; }