From 9bbdd2ba350aac319ca9b24eba042ce81070df9f Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 4 Oct 2020 18:10:47 -0700 Subject: [PATCH 01/10] Qt: Fix drawing on macOS break when using OpenGL (fixes #1899) --- CHANGES | 1 + src/platform/qt/DisplayGL.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index dabd10d1c..79fea85f4 100644 --- a/CHANGES +++ b/CHANGES @@ -69,6 +69,7 @@ Other fixes: - Qt: Add dummy English translation file (fixes mgba.io/i/1469) - Qt: Fix Battle Chip view not displaying chips on some DPI settings - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) + - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) - mGUI: Fix closing down a game if an exit is signalled - mVL: Fix injecting accidentally draining non-injection buffer - SM83: Simplify register pair access on big endian diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index d1e619c09..be545fe78 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -145,7 +145,9 @@ void DisplayGL::pauseDrawing() { m_isDrawing = false; CoreController::Interrupter interrupter(m_context); QMetaObject::invokeMethod(m_painter, "pause", Qt::BlockingQueuedConnection); +#ifndef Q_OS_MAC setUpdatesEnabled(true); +#endif } } @@ -154,7 +156,9 @@ void DisplayGL::unpauseDrawing() { m_isDrawing = true; CoreController::Interrupter interrupter(m_context); QMetaObject::invokeMethod(m_painter, "unpause", Qt::BlockingQueuedConnection); +#ifndef Q_OS_MAC setUpdatesEnabled(false); +#endif } } From 830aea2f57c37a69c23b7e3c2ece59c4a4c36567 Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 4 Oct 2020 22:06:14 -0700 Subject: [PATCH 02/10] Qt: Load/save bytes from memory viewer in the order visible (fixes #1900) --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 79fea85f4..08ad44c08 100644 --- a/CHANGES +++ b/CHANGES @@ -70,6 +70,7 @@ Other fixes: - Qt: Fix Battle Chip view not displaying chips on some DPI settings - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) + - Qt: Load/save bytes from memory viewer in the order visible (fixes mgba.io/i/1900) - mGUI: Fix closing down a game if an exit is signalled - mVL: Fix injecting accidentally draining non-injection buffer - SM83: Simplify register pair access on big endian From 3f10823ef560e2c492a6ae5aa885155e35b92d0c Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Mon, 5 Oct 2020 00:25:00 -0700 Subject: [PATCH 03/10] GBA Video: Fix deferred blending when OBJWIN matches window (fixes #1905) --- CHANGES | 1 + src/gba/renderers/video-software.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 08ad44c08..8974a0317 100644 --- a/CHANGES +++ b/CHANGES @@ -48,6 +48,7 @@ Emulation fixes: - GBA Video: Fix rare regression blending semitransparent sprites (fixes mgba.io/i/1876) - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) + - GBA Video: Fix deferred blending when OBJWIN matches window (fixes mgba.io/i/1905) - SM83: Emulate HALT bug Other fixes: - 3DS: Redo video sync to be more precise diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 9df7983e7..1a746e2a5 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -644,17 +644,18 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render } if (softwareRenderer->forceTarget1 && (softwareRenderer->blendEffect == BLEND_DARKEN || softwareRenderer->blendEffect == BLEND_BRIGHTEN)) { x = 0; - uint32_t mask = FLAG_REBLEND | FLAG_IS_BACKGROUND; - uint32_t match = FLAG_REBLEND; - if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { - mask |= FLAG_OBJWIN; - if (GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed)) { - match |= FLAG_OBJWIN; - } - } for (w = 0; w < softwareRenderer->nWindows; ++w) { int end = softwareRenderer->windows[w].endX; - if (!GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed)) { + uint32_t mask = FLAG_REBLEND | FLAG_IS_BACKGROUND; + uint32_t match = FLAG_REBLEND; + bool objBlend = GBAWindowControlIsBlendEnable(softwareRenderer->objwin.packed); + bool winBlend = GBAWindowControlIsBlendEnable(softwareRenderer->windows[w].control.packed); + if (GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt) && objBlend != winBlend) { + mask |= FLAG_OBJWIN; + if (objBlend) { + match |= FLAG_OBJWIN; + } + } else if (!winBlend) { x = end; continue; } From 78343663c443cb936296e4b705832d46bc6d4387 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari <mail@serra.me> Date: Mon, 5 Oct 2020 18:27:06 +0200 Subject: [PATCH 04/10] Win32: Fix supressing start menu item creation --- src/platform/windows/setup/setup.iss.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/windows/setup/setup.iss.in b/src/platform/windows/setup/setup.iss.in index fb164136a..1771aed4f 100644 --- a/src/platform/windows/setup/setup.iss.in +++ b/src/platform/windows/setup/setup.iss.in @@ -89,7 +89,7 @@ Source: "{#ResDir}\shaders\*"; DestDir: "{app}\shaders\"; Flags: ignoreversion r Source: "{#ResDir}\licenses\*"; DestDir: "{app}\licenses\"; Flags: ignoreversion recursesubdirs [Icons] -Name: "{commonstartmenu}\{#AppName}"; Filename: "{app}\{#AppName}.exe" +Name: "{commonstartmenu}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; Check: not WizardNoIcons Name: "{commondesktop}\{#AppName}"; Filename: "{app}\{#AppName}.exe"; Tasks: desktopicon [Run] From 22950a679673274f5b857d6c8570a7ac22c5120b Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari <mail@serra.me> Date: Mon, 5 Oct 2020 18:39:50 +0200 Subject: [PATCH 05/10] Win32: Add more language options to the installer NOTE: Requires the content of the directory https://github.com/jrsoftware/issrc/tree/main/Files/Languages/Unofficial to be present in the "Languages/" directory on the build host! --- src/platform/windows/setup/setup.iss.in | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/platform/windows/setup/setup.iss.in b/src/platform/windows/setup/setup.iss.in index 1771aed4f..9421d8fa9 100644 --- a/src/platform/windows/setup/setup.iss.in +++ b/src/platform/windows/setup/setup.iss.in @@ -64,11 +64,17 @@ ArchitecturesInstallIn64BitMode=x64 ArchitecturesAllowed=x86 x64 [Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" -Name: "french"; MessagesFile: "compiler:Languages\French.isl" Name: "german"; MessagesFile: "compiler:Languages\German.isl" -Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "english"; MessagesFile: "compiler:Default.isl" Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" +Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" +Name: "korean"; MessagesFile: "compiler:Languages\Korean.isl" +Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" +Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl" +Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" @@ -83,7 +89,7 @@ Source: "{#BinDir}\{#AppName2}-sdl.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#BinDir}\CHANGES.txt"; DestDir: "{app}\"; Flags: ignoreversion isreadme Source: "{#BinDir}\LICENSE.txt"; DestDir: "{app}\"; Flags: ignoreversion Source: "{#ResDir}\nointro.dat"; DestDir: "{app}\"; Flags: ignoreversion -Source: "{#BinDir}\README.html"; DestDir: "{app}\"; Flags: ignoreversion isreadme; Languages: english italian spanish +Source: "{#BinDir}\README.html"; DestDir: "{app}\"; Flags: ignoreversion isreadme; Languages: not german Source: "{#BinDir}\README_DE.html"; DestDir: "{app}\"; DestName: "LIESMICH.html"; Flags: ignoreversion isreadme; Languages: german Source: "{#ResDir}\shaders\*"; DestDir: "{app}\shaders\"; Flags: ignoreversion recursesubdirs Source: "{#ResDir}\licenses\*"; DestDir: "{app}\licenses\"; Flags: ignoreversion recursesubdirs @@ -129,9 +135,15 @@ procedure InitializeWizard(); begin if ExpandConstant('{language}') = 'english' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; if ExpandConstant('{language}') = 'french' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; - if ExpandConstant('{language}') = 'italian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'german' then noReleaseWarning := 'Sie m�chten eine Entwicklerversion von {#AppName} installieren.' + #13#10#13#10 + 'Entwicklerversionen k�nnen bislang noch nicht endeckte Fehler beinhalten. Bitte melden Sie alle Fehler, die Sie finden k�nnen, auf der GitHub-Projektseite.'; if ExpandConstant('{language}') = 'spanish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; if ExpandConstant('{language}') = 'spanish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; - if ExpandConstant('{language}') = 'german' then noReleaseWarning := 'Sie m�chten eine Entwicklerversion von {#AppName} installieren.' + #13#10#13#10 + 'Entwicklerversionen k�nnen bislang noch nicht endeckte Fehler beinhalten. Bitte melden Sie alle Fehler, die Sie finden k�nnen, auf der GitHub-Projektseite.'; + if ExpandConstant('{language}') = 'italian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'japanese' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'korean' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'dutch' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'russian' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'turkish' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; + if ExpandConstant('{language}') = 'chinesesimplified' then noReleaseWarning := 'You are about to install a development build of {#AppName}.' + #13#10#13#10 + 'Development builds may contain bugs that are not yet discovered. Please report any issues you can find to the GitHub project page.'; MsgBox(noReleaseWarning, mbInformation, MB_OK); end; end; From 7b3900ff937341eafac2e2ef3f05a0e17e2c4e94 Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Tue, 6 Oct 2020 01:11:34 -0700 Subject: [PATCH 06/10] Qt: Load/save bytes from memory viewer in the order visible (fixes #1900) --- src/platform/qt/MemoryModel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 856592a30..67b09e05e 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -246,7 +246,7 @@ QByteArray MemoryModel::serialize() { for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) { quint16 datum = m_core->rawRead16(m_core, i, m_currentBank); char leDatum[2]; - STORE_16LE(datum, 0, (uint16_t*) leDatum); + STORE_16BE(datum, 0, (uint16_t*) leDatum); bytes.append(leDatum, 2); } break; @@ -254,7 +254,7 @@ QByteArray MemoryModel::serialize() { for (uint32_t i = m_selection.first; i < m_selection.second; i += m_align) { quint32 datum = m_core->rawRead32(m_core, i, m_currentBank); char leDatum[4]; - STORE_32LE(datum, 0, (uint16_t*) leDatum); + STORE_32BE(datum, 0, (uint32_t*) leDatum); bytes.append(leDatum, 4); } break; @@ -275,7 +275,7 @@ void MemoryModel::deserialize(const QByteArray& bytes) { for (int i = 0; i < bytes.size(); i += m_align, addr += m_align) { char leDatum[2]{ bytes[i], bytes[i + 1] }; uint16_t datum; - LOAD_16LE(datum, 0, leDatum); + LOAD_16BE(datum, 0, leDatum); m_core->rawWrite16(m_core, addr, m_currentBank, datum); } break; @@ -283,7 +283,7 @@ void MemoryModel::deserialize(const QByteArray& bytes) { for (int i = 0; i < bytes.size(); i += m_align, addr += m_align) { char leDatum[4]{ bytes[i], bytes[i + 1], bytes[i + 2], bytes[i + 3] }; uint32_t datum; - LOAD_32LE(datum, 0, leDatum); + LOAD_32BE(datum, 0, leDatum); m_core->rawWrite32(m_core, addr, m_currentBank, datum); } break; From 8b8ff65821357ba2e436ce799b17c86be8d45730 Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 11 Oct 2020 16:37:49 -0700 Subject: [PATCH 07/10] GBA Video: Fix mode 4 transparency in OpenGL (fixes #1907) --- CHANGES | 1 + src/gba/renderers/gl.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8974a0317..9cc50fabc 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Emulation fixes: - GBA Video: Emulate sprite cycle limits in OpenGL renderer (fixes mgba.io/i/1635) - GBA Video: Do not affect OBJ pixel priority when writing OBJWIN (fixes mgba.io/i/1890) - GBA Video: Fix deferred blending when OBJWIN matches window (fixes mgba.io/i/1905) + - GBA Video: Fix mode 4 transparency in OpenGL (fixes mgba.io/i/1907) - SM83: Emulate HALT bug Other fixes: - 3DS: Redo video sync to be more precise diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 8856ec4ef..31c16f5cd 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -391,7 +391,11 @@ static const char* const _renderMode4 = " }\n" " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" " int twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0).r;\n" - " int paletteEntry = palette[(twoEntries >> (8 * (address & 1)) & 255)];\n" + " int entry = (twoEntries >> (8 * (address & 1))) & 255;\n" + " if (entry == 0) {\n" + " discard;\n" + " }\n" + " int paletteEntry = palette[entry];\n" " color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" "}"; From ba566f334d4b7d34d7572a9fde8d7510d07ff162 Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 11 Oct 2020 22:42:23 -0700 Subject: [PATCH 08/10] GB Core: Add reload config option for SGB borders --- src/gb/core.c | 6 ++++++ src/gb/serialize.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gb/core.c b/src/gb/core.c index 61cedc774..23ebb294d 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -292,6 +292,12 @@ static void _GBCoreReloadConfigOption(struct mCore* core, const char* option, co } return; } + if (strcmp("sgb.borders", option) == 0) { + if (mCoreConfigGetIntValue(config, "sgb.borders", &fakeBool)) { + gb->video.sgbBorders = fakeBool; + gb->video.renderer->enableSGBBorder(gb->video.renderer, fakeBool); + } + } } static void _GBCoreDesiredVideoDimensions(const struct mCore* core, unsigned* width, unsigned* height) { diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 002b5a650..35a54c752 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -256,7 +256,6 @@ void GBSGBSerialize(struct GB* gb, struct GBSerializedState* state) { if (gb->video.renderer->sgbAttributes) { memcpy(state->sgb.attributes, gb->video.renderer->sgbAttributes, sizeof(state->sgb.attributes)); } - gb->video.renderer->enableSGBBorder(gb->video.renderer, gb->video.sgbBorders); } void GBSGBDeserialize(struct GB* gb, const struct GBSerializedState* state) { From 7a9e1e4600f0bba80a7734c6d0c3504b4495485d Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 11 Oct 2020 22:44:26 -0700 Subject: [PATCH 09/10] Qt: Fix stride changing when toggling SGB borders (fixes #1898) --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGES b/CHANGES index 9cc50fabc..31599e7ce 100644 --- a/CHANGES +++ b/CHANGES @@ -73,6 +73,7 @@ Other fixes: - Qt: Fix camera image being upside-down sometimes (fixes mgba.io/i/829 again) - Qt: Fix drawing on macOS break when using OpenGL (fixes mgba.io/i/1899) - Qt: Load/save bytes from memory viewer in the order visible (fixes mgba.io/i/1900) + - Qt: Fix stride changing when toggling SGB borders (fixes mgba.io/i/1898) - mGUI: Fix closing down a game if an exit is signalled - mVL: Fix injecting accidentally draining non-injection buffer - SM83: Simplify register pair access on big endian diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 99fc0299d..2f4edb6f5 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -263,11 +263,23 @@ void CoreController::loadConfig(ConfigController* config) { m_fastForwardMute = config->getOption("fastForwardMute", -1).toInt(); mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "volume"); mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "mute"); + + QSize sizeBefore = screenDimensions(); mCoreLoadForeignConfig(m_threadContext.core, config->config()); + QSize sizeAfter = screenDimensions(); if (hasStarted()) { updateFastForward(); mCoreThreadRewindParamsChanged(&m_threadContext); } + if (sizeBefore != sizeAfter) { + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast<color_t*>(m_activeBuffer.data()), sizeAfter.width()); +#ifdef M_CORE_GB + mCoreConfigSetIntValue(&m_threadContext.core->config, "sgb.borders", 0); + m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); + mCoreConfigCopyValue(&m_threadContext.core->config, config->config(), "sgb.borders"); + m_threadContext.core->reloadConfigOption(m_threadContext.core, "sgb.borders", nullptr); +#endif + } } #ifdef USE_DEBUGGERS From 3b93e762ae248f80d2a19b7e3e39721304e7adad Mon Sep 17 00:00:00 2001 From: Vicki Pfau <vi@endrift.com> Date: Sun, 11 Oct 2020 23:56:51 -0700 Subject: [PATCH 10/10] GB Video: Clean up OBJ parsing outside of renderer --- include/mgba/internal/gb/renderers/proxy.h | 3 -- include/mgba/internal/gb/renderers/software.h | 3 ++ include/mgba/internal/gb/video.h | 3 +- src/gb/extra/proxy.c | 18 ++++----- src/gb/renderers/software.c | 37 ++++++++++++++++--- src/gb/video.c | 12 +----- 6 files changed, 45 insertions(+), 31 deletions(-) diff --git a/include/mgba/internal/gb/renderers/proxy.h b/include/mgba/internal/gb/renderers/proxy.h index 244c5e39b..bde4e2ddb 100644 --- a/include/mgba/internal/gb/renderers/proxy.h +++ b/include/mgba/internal/gb/renderers/proxy.h @@ -17,9 +17,6 @@ struct GBVideoProxyRenderer { struct GBVideoRenderer d; struct GBVideoRenderer* backend; struct mVideoLogger* logger; - - struct GBObj objThisLine[40]; - size_t oamMax; }; void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend); diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index fe4b1ff98..11e107f6d 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -40,6 +40,9 @@ struct GBVideoSoftwareRenderer { GBRegisterLCDC lcdc; enum GBModel model; + struct GBObj obj[10]; + int objMax; + int16_t objOffsetX; int16_t objOffsetY; int16_t offsetScx; diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index 13473776a..cd5a1e8d1 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -77,7 +77,7 @@ struct GBVideoRenderer { void (*writeVRAM)(struct GBVideoRenderer* renderer, uint16_t address); void (*writePalette)(struct GBVideoRenderer* renderer, int index, uint16_t value); void (*writeOAM)(struct GBVideoRenderer* renderer, uint16_t oam); - void (*drawRange)(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* objOnLine, size_t nObj); + void (*drawRange)(struct GBVideoRenderer* renderer, int startX, int endX, int y); void (*finishScanline)(struct GBVideoRenderer* renderer, int y); void (*finishFrame)(struct GBVideoRenderer* renderer); void (*enableSGBBorder)(struct GBVideoRenderer* renderer, bool enable); @@ -139,7 +139,6 @@ struct GBVideo { int vramCurrentBank; union GBOAM oam; - struct GBObj objThisLine[10]; int objMax; int bcpIndex; diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index f7b21cbda..24758cd2a 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -19,7 +19,7 @@ static void GBVideoProxyRendererWriteSGBPacket(struct GBVideoRenderer* renderer, static void GBVideoProxyRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address); static void GBVideoProxyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam); static void GBVideoProxyRendererWritePalette(struct GBVideoRenderer* renderer, int address, uint16_t value); -static void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); +static void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y); static void GBVideoProxyRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer); static void GBVideoProxyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); @@ -68,8 +68,6 @@ static void _reset(struct GBVideoProxyRenderer* proxyRenderer) { memcpy(proxyRenderer->logger->oam, &proxyRenderer->d.oam->raw, GB_SIZE_OAM); memcpy(proxyRenderer->logger->vram, proxyRenderer->d.vram, GB_SIZE_VRAM); - proxyRenderer->oamMax = 0; - mVideoLoggerRendererReset(proxyRenderer->logger); } @@ -117,6 +115,7 @@ void GBVideoProxyRendererDeinit(struct GBVideoRenderer* renderer) { static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* item) { struct GBVideoProxyRenderer* proxyRenderer = logger->context; uint8_t sgbPacket[16]; + struct GBObj legacyBuffer[40]; switch (item->type) { case DIRTY_REGISTER: proxyRenderer->backend->writeVideoRegister(proxyRenderer->backend, item->address, item->value); @@ -145,7 +144,7 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD break; case DIRTY_RANGE: if (item->value < item->value2 && item->value2 <= GB_VIDEO_HORIZONTAL_PIXELS && item->address < GB_VIDEO_VERTICAL_PIXELS) { - proxyRenderer->backend->drawRange(proxyRenderer->backend, item->value, item->value2, item->address, proxyRenderer->objThisLine, proxyRenderer->oamMax); + proxyRenderer->backend->drawRange(proxyRenderer->backend, item->value, item->value2, item->address); } break; case DIRTY_FRAME: @@ -154,12 +153,10 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD case DIRTY_BUFFER: switch (item->address) { case BUFFER_OAM: - proxyRenderer->oamMax = item->value2 / sizeof(struct GBObj); - if (proxyRenderer->oamMax > 40) { - proxyRenderer->oamMax = 0; + if (item->value2 / sizeof(struct GBObj) > 40) { return false; } - logger->readData(logger, &proxyRenderer->objThisLine, item->value2, true); + logger->readData(logger, legacyBuffer, item->value2, true); break; case BUFFER_SGB: logger->readData(logger, sgbPacket, 16, true); @@ -228,12 +225,11 @@ void GBVideoProxyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam mVideoLoggerRendererWriteOAM(proxyRenderer->logger, oam, ((uint8_t*) proxyRenderer->d.oam->raw)[oam]); } -void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { +void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (!proxyRenderer->logger->block) { - proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y, obj, oamMax); + proxyRenderer->backend->drawRange(proxyRenderer->backend, startX, endX, y); } - mVideoLoggerWriteBuffer(proxyRenderer->logger, BUFFER_OAM, 0, oamMax * sizeof(*obj), obj); mVideoLoggerRendererDrawRange(proxyRenderer->logger, startX, endX, y); } diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 637bae496..f6c4f9818 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -18,7 +18,7 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value); static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address); static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam); -static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); +static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y); static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer); static void GBVideoSoftwareRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); @@ -499,7 +499,31 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, ui // Nothing to do } -static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { +static void _cleanOAM(struct GBVideoSoftwareRenderer* renderer, int y) { + // TODO: GBC differences + // TODO: Optimize + int spriteHeight = 8; + if (GBRegisterLCDCIsObjSize(renderer->lcdc)) { + spriteHeight = 16; + } + int o = 0; + int i; + for (i = 0; i < 40 && o < 10; ++i) { + uint8_t oy = renderer->d.oam->obj[i].y; + if (y < oy - 16 || y >= oy - 16 + spriteHeight) { + continue; + } + // TODO: Sort + renderer->obj[o] = renderer->d.oam->obj[i]; + ++o; + if (o == 10) { + break; + } + } + renderer->objMax = o; +} + +static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; softwareRenderer->lastY = y; softwareRenderer->lastX = endX; @@ -536,9 +560,12 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i } if (GBRegisterLCDCIsObjEnable(softwareRenderer->lcdc) && !softwareRenderer->d.disableOBJ) { - size_t i; - for (i = 0; i < oamMax; ++i) { - GBVideoSoftwareRendererDrawObj(softwareRenderer, &obj[i], startX, endX, y); + if (startX == 0) { + _cleanOAM(softwareRenderer, y); + } + int i; + for (i = 0; i < softwareRenderer->objMax; ++i) { + GBVideoSoftwareRendererDrawObj(softwareRenderer, &softwareRenderer->obj[i], startX, endX, y); } } diff --git a/src/gb/video.c b/src/gb/video.c index 6c207297d..8bf173797 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -403,26 +403,18 @@ void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLat } static void _cleanOAM(struct GBVideo* video, int y) { - // TODO: GBC differences - // TODO: Optimize - video->objMax = 0; int spriteHeight = 8; if (GBRegisterLCDCIsObjSize(video->p->memory.io[REG_LCDC])) { spriteHeight = 16; } int o = 0; int i; - for (i = 0; i < 40; ++i) { + for (i = 0; i < 40 && o < 10; ++i) { uint8_t oy = video->oam.obj[i].y; if (y < oy - 16 || y >= oy - 16 + spriteHeight) { continue; } - // TODO: Sort - video->objThisLine[o] = video->oam.obj[i]; ++o; - if (o == 10) { - break; - } } video->objMax = o; } @@ -442,7 +434,7 @@ void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate) { oldX = 0; } if (video->frameskipCounter <= 0) { - video->renderer->drawRange(video->renderer, oldX, video->x, video->ly, video->objThisLine, video->objMax); + video->renderer->drawRange(video->renderer, oldX, video->x, video->ly); } }