From d01190bf90b52cf974e5072a5edc1e7eb6d784bd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 00:43:19 -0800 Subject: [PATCH 01/20] CMake: Replace desktop file installing code with just the file --- src/platform/qt/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index aacd13a50..fff70e247 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -322,10 +322,7 @@ install(TARGETS ${BINARY_NAME}-qt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-qt BUNDLE DESTINATION Applications COMPONENT ${BINARY_NAME}-qt) if(UNIX AND NOT APPLE) - find_program(DESKTOP_FILE_INSTALL desktop-file-install) - if(DESKTOP_FILE_INSTALL) - install(CODE "execute_process(COMMAND ${DESKTOP_FILE_INSTALL} \"${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop\" --dir \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/applications/\")" COMPONENT ${BINARY_NAME}-qt) - endif() + install(FILES ${CMAKE_SOURCE_DIR}/res/mgba-qt.desktop DESTINATION share/applications COMPONENT ${BINARY_NAME}-qt) endif() if(UNIX) install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba-qt.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-qt) From 6ca62fae8324536a6748f6d576ae7ce671a6b400 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 01:25:38 -0800 Subject: [PATCH 02/20] CMake: Link with correct OpenGL library (fixes #1872) --- CHANGES | 1 + CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 5cb6fe228..9f708cbe1 100644 --- a/CHANGES +++ b/CHANGES @@ -53,6 +53,7 @@ Other fixes: - 3DS: Fix thread cleanup - All: Improve export headers (fixes mgba.io/i/1738) - CMake: Fix build with downstream minizip that exports incompatible symbols + - CMake: Link with correct OpenGL library (fixes mgba.io/i/1872) - Core: Ensure ELF regions can be written before trying - Core: Fix threading improperly setting paused state while interrupted - Debugger: Don't skip undefined instructions when debugger attached diff --git a/CMakeLists.txt b/CMakeLists.txt index aa3300e18..428c8bc2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ if(POLICY CMP0025) endif() if(POLICY CMP0072) cmake_policy(SET CMP0072 NEW) + set(OpenGL_GL_PREFERENCE LEGACY) endif() project(mGBA) set(BINARY_NAME mgba CACHE INTERNAL "Name of output binaries") @@ -436,6 +437,8 @@ if(BUILD_GL) find_package(OpenGL QUIET) if(NOT OPENGL_FOUND) set(BUILD_GL OFF CACHE BOOL "OpenGL not found" FORCE) + elseif(TARGET OpenGL::GL) + set(OPENGL_LIBRARY OpenGL::GL) endif() endif() if(NOT BUILD_GL) From f7749b31de8611caa04c1fe1f281fc37a9e758b5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 01:37:54 -0800 Subject: [PATCH 03/20] Core: Fix loading ELF files that have unexpected empty program headers --- CHANGES | 1 + src/core/core.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 9f708cbe1..a989b93fb 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,7 @@ Other fixes: - CMake: Link with correct OpenGL library (fixes mgba.io/i/1872) - Core: Ensure ELF regions can be written before trying - Core: Fix threading improperly setting paused state while interrupted + - Core: Fix loading ELF files that have unexpected empty program headers - Debugger: Don't skip undefined instructions when debugger attached - Debugger: Close trace log when done tracing - Debugger: Fix change watchpoints (fixes mgba.io/i/1947) diff --git a/src/core/core.c b/src/core/core.c index 4df6636a0..5afdc8667 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -382,6 +382,9 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { for (i = 0; i < ELFProgramHeadersSize(&ph); ++i) { size_t bsize, esize; Elf32_Phdr* phdr = ELFProgramHeadersGetPointer(&ph, i); + if (!phdr->p_filesz) { + continue; + } void* block = mCoreGetMemoryBlockMasked(core, phdr->p_paddr, &bsize, mCORE_MEMORY_WRITE | mCORE_MEMORY_WORM); char* bytes = ELFBytes(elf, &esize); if (block && bsize >= phdr->p_filesz && esize > phdr->p_offset && esize >= phdr->p_filesz + phdr->p_offset) { From b8e5b47c80d1780ddb22508fa7a8bb2c5870cec9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 01:38:41 -0800 Subject: [PATCH 04/20] GBA: Fix loading multiboot ELF files (fixes #1949) --- CHANGES | 1 + src/gba/core.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index a989b93fb..9236918f0 100644 --- a/CHANGES +++ b/CHANGES @@ -63,6 +63,7 @@ Other fixes: - FFmpeg: Fix some small memory leaks - FFmpeg: Fix encoding of time base - GB Video: Fix SGB video logs + - GBA: Fix loading multiboot ELF files (fixes mgba.io/i/1949) - mGUI: Don't attempt to preload files larger than can fit in RAM - Qt: Force OpenGL paint engine creation thread (fixes mgba.io/i/1642) - Qt: Fix static compilation in MinGW (fixes mgba.io/i/1769) diff --git a/src/gba/core.c b/src/gba/core.c index 6e5a5bd30..1df7286ff 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -487,9 +487,14 @@ static bool _GBACoreLoadROM(struct mCore* core, struct VFile* vf) { #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { - GBALoadNull(core->board); + if (ELFEntry(elf) == BASE_CART0) { + GBALoadNull(core->board); + } bool success = mCoreLoadELF(core, elf); ELFClose(elf); + if (success) { + vf->close(vf); + } return success; } #endif From 30a67d5496e3d0586654b93e41836bca07da32f7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 01:57:09 -0800 Subject: [PATCH 05/20] CMake: Fix build on Windows --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 428c8bc2b..a0912d7f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -437,7 +437,7 @@ if(BUILD_GL) find_package(OpenGL QUIET) if(NOT OPENGL_FOUND) set(BUILD_GL OFF CACHE BOOL "OpenGL not found" FORCE) - elseif(TARGET OpenGL::GL) + elseif(UNIX AND NOT APPLE AND TARGET OpenGL::GL) set(OPENGL_LIBRARY OpenGL::GL) endif() endif() From 42879afb9cb9f31c27c02e9c0d42836bcaf26121 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 18:58:22 -0800 Subject: [PATCH 06/20] Qt: Pre-attach GDB stub when launching with -g (fixes #1950) --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 9236918f0..40acf4c1a 100644 --- a/CHANGES +++ b/CHANGES @@ -73,6 +73,7 @@ Other fixes: - Qt: Fix game display sometimes disappearing after closing load/save state screen - Qt: Fix cancelling pausing before the frame ends - Qt: Fix gamepad event dispatching (fixes mgba.io/i/1922) + - Qt: Pre-attach GDB stub when launching with -g (fixes mgba.io/i/1950) - SM83: Simplify register pair access on big endian - SM83: Disassemble STOP as one byte - Wii: Fix crash on unloading irregularly sized GBA ROMs From 87d87b200fc3c792faf8bc1af8ffe640b60e1029 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 22:18:15 -0800 Subject: [PATCH 07/20] Qt: Pre-attach GDB stub when launching with -g (fixes #1950) --- src/platform/qt/Window.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 78688b4a5..13210bdac 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -181,10 +181,6 @@ void Window::argumentsPassed(mArguments* args) { m_pendingState = args->savestate; } - if (args->fname) { - setController(m_manager->loadGame(args->fname), args->fname); - } - #ifdef USE_GDB_STUB if (args->debuggerType == DEBUGGER_GDB) { if (!m_gdbController) { @@ -192,10 +188,15 @@ void Window::argumentsPassed(mArguments* args) { if (m_controller) { m_gdbController->setController(m_controller); } + m_gdbController->attach(); m_gdbController->listen(); } } #endif + + if (args->fname) { + setController(m_manager->loadGame(args->fname), args->fname); + } } void Window::resizeFrame(const QSize& size) { From a1c0318290b52302d919c33ce71763fc90353e4f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 24 Nov 2020 22:26:45 -0800 Subject: [PATCH 08/20] CMake: Move gl.c and gles2.c to FEATURE_SRC --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0912d7f8..16c44c14c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -423,6 +423,7 @@ endif() # Feature dependencies set(FEATURE_DEFINES) set(FEATURE_FLAGS) +set(FEATURE_SRC) set(FEATURES) set(ENABLES) if(CMAKE_SYSTEM_NAME MATCHES ".*BSD|DragonFly") @@ -455,12 +456,12 @@ if(NOT BUILD_GLES2) set(OPENGLES2_LIBRARY "" CACHE PATH "" FORCE) endif() if(BUILD_GL) - list(APPEND OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c) + list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c) list(APPEND DEPENDENCY_LIB ${OPENGL_LIBRARY}) include_directories(${OPENGL_INCLUDE_DIR}) endif() if(BUILD_GLES2) - list(APPEND OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gles2.c) + list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gles2.c) list(APPEND DEPENDENCY_LIB ${OPENGLES2_LIBRARY}) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() @@ -515,7 +516,6 @@ endif() add_subdirectory(src/debugger) add_subdirectory(src/feature) -set(FEATURE_SRC) set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") if(USE_EDITLINE) @@ -715,7 +715,7 @@ if (USE_LZMA) endif() if(USE_EPOXY) - list(APPEND OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gles2.c) + list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gles2.c) add_definitions(-DBUILD_GL -DBUILD_GLES2) list(APPEND FEATURES EPOXY) include_directories(AFTER ${EPOXY_INCLUDE_DIRS}) From b50d8e35e98906e446701dbf3973e799306f13ed Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 25 Nov 2020 20:09:54 -0800 Subject: [PATCH 09/20] GB I/O: Implement preliminary support for PCM12/PCM34 (#1468) --- CHANGES | 1 + src/gb/io.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 40acf4c1a..400c429fd 100644 --- a/CHANGES +++ b/CHANGES @@ -84,6 +84,7 @@ Misc: - Core: Rework thread state synchronization - GB: Allow pausing event loop while CPU is blocked - GB: Add support for sleep and shutdown callbacks + - GB I/O: Implement preliminary support for PCM12/PCM34 (closes mgba.io/i/1468) - GBA: Allow pausing event loop while CPU is blocked - GBA BIOS: Division by zero should emit a FATAL error - GBA Video: Convert OpenGL VRAM texture to integer diff --git a/src/gb/io.c b/src/gb/io.c index c0a2d36cc..0e3a70eca 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -216,7 +216,7 @@ void GBIOReset(struct GB* gb) { GBIOWrite(gb, GB_REG_HDMA4, 0xFF); gb->memory.io[GB_REG_HDMA5] = 0xFF; } else { - memset(&gb->memory.io[GB_REG_KEY0], 0xFF, GB_REG_PCM34 - GB_REG_KEY0); + memset(&gb->memory.io[GB_REG_KEY0], 0xFF, GB_REG_PCM34 - GB_REG_KEY0 + 1); } if (gb->model & GB_MODEL_SGB) { @@ -622,6 +622,20 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { return gb->audio.ch3.wavedata8[address - GB_REG_WAVE_0]; } break; + case GB_REG_PCM12: + if (gb->model < GB_MODEL_CGB) { + mLOG(GB_IO, GAME_ERROR, "Reading from CGB register FF%02X in DMG mode", address); + } else if (gb->audio.enable) { + return (gb->audio.ch1.sample) | (gb->audio.ch2.sample << 4); + } + break; + case GB_REG_PCM34: + if (gb->model < GB_MODEL_CGB) { + mLOG(GB_IO, GAME_ERROR, "Reading from CGB register FF%02X in DMG mode", address); + } else if (gb->audio.enable) { + return (gb->audio.ch3.sample) | (gb->audio.ch4.sample << 4); + } + break; case GB_REG_SB: case GB_REG_SC: case GB_REG_IF: From 1baa6fefbb49bea6c72cdffeda1f5f3ce50a1779 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 25 Nov 2020 20:12:21 -0800 Subject: [PATCH 10/20] CInema: Add xbaselines for mooneye-gb --- .../acceptance/boot_div-S/xbaseline_0000.png | Bin 0 -> 1381 bytes .../acceptance/boot_div-dmg0/xbaseline_0000.png | Bin 0 -> 1449 bytes .../boot_div-dmgABCmgb/xbaseline_0000.png | Bin 0 -> 1414 bytes .../acceptance/boot_div2-S/baseline_0000.png | Bin 0 -> 1244 bytes .../mooneye-gb/acceptance/boot_div2-S/config.ini | 3 --- .../hblank_ly_scx_timing-GS/xbaseline_0000.png | Bin 0 -> 1103 bytes .../xbaseline_0000.png | Bin 0 -> 621 bytes .../ppu/lcdon_timing-GS/xbaseline_0000.png | Bin 0 -> 1105 bytes .../ppu/lcdon_write_timing-GS/xbaseline_0000.png | Bin 0 -> 1090 bytes .../boot_sclk_align-dmgABCmgb/xbaseline_0000.png | Bin 0 -> 1402 bytes .../misc/boot_div-A/xbaseline_0000.png | Bin 0 -> 1441 bytes .../misc/boot_div-cgb0/xbaseline_0000.png | Bin 0 -> 1444 bytes .../misc/boot_div-cgbABCDE/xbaseline_0000.png | Bin 0 -> 1438 bytes cinema/gb/mooneye-gb/misc/boot_hwio-C/config.ini | 3 --- .../misc/boot_hwio-C/xbaseline_0000.png | Bin 853 -> 0 bytes .../ppu/vblank_stat_intr-C/xbaseline_0000.png | Bin 0 -> 1329 bytes 16 files changed, 6 deletions(-) create mode 100644 cinema/gb/mooneye-gb/acceptance/boot_div-S/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/boot_div-dmg0/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/boot_div-dmgABCmgb/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/boot_div2-S/baseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/ppu/hblank_ly_scx_timing-GS/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/ppu/intr_2_mode0_timing_sprites/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/ppu/lcdon_timing-GS/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/ppu/lcdon_write_timing-GS/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/acceptance/serial/boot_sclk_align-dmgABCmgb/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/misc/boot_div-A/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/misc/boot_div-cgb0/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/misc/boot_div-cgbABCDE/xbaseline_0000.png delete mode 100644 cinema/gb/mooneye-gb/misc/boot_hwio-C/xbaseline_0000.png create mode 100644 cinema/gb/mooneye-gb/misc/ppu/vblank_stat_intr-C/xbaseline_0000.png diff --git a/cinema/gb/mooneye-gb/acceptance/boot_div-S/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/boot_div-S/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..7cd244f25fcbda3706553f45d58ff0aab6829ecb GIT binary patch literal 1381 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Tp$r;B4q#hkZuFHT#nz~lOH z-M|0()$((WT1YWXT5|01P5sLk&6de9I&0{>-X+#_djD=&g^d9T1sVnxA`&uOJbbKd z?M%&|HJ9p~4*Flt**!fqv0`q^`ESc#6<$d5tNu9m>XnCUD$IRiwx|Ao3N&Jy*Jqt? z|LktuyE7@><>)1Wp#6EJ5rtDj>aq*AtG(sVdoOant7BEn-giG=eQnnL{UkWPGj;9s z>kGfVo)h|VU!=Y2u2ZXO9&G;qd_m#ruk%*uRk2qFxV|)f_GZ82>%ZruCeQKzuPe01 z(7*93zf50BqjTfIg$EuWx%b=?2ltz*Q+mYA&fQ#oZKdUJG3)B=wR=2nJ#49Lj1>rO z@!C~zYoDND>r$EXhf{?2*3J(z%d|PFvT5d83F*$>Yd0O0lbGB*&pbJJ%cc8=n!%&2 zf^$~SPy6t$yBfaoh)2(rTU&ffJmhWuW5xw3tir$)?p(;RKMx?6Vr@{FTtTK3MIGdCsc`&OT|@PG1pAN!;U zQghV#t{Kj%b?M;vJ)uPUXHHj&;MK0T@t3}zZSaT z^1L}ds=3!DiQ|Lj9h(rzyGKgrKklh}mcJ;{@<5^t&$$$tH&f58UavgMZvDC6y@eaZ z@7iQfQeSiZ=)o$UM~UMSNMBc%xHhhmpdY+3V_`FL+b<>*IqQ z-j6#z-CVl&eqgPwk*43w7{z58_a=P2`g85Uq-u>-i)6y3LO;qyN&i-RDfXqF-`w$2 zXu+bNH+KhU?zpDUbL6p?dwn%{n7)k-(2EuUTUBC|EX+2qMd}? zv4hBo1(LYo4#ehel~{eND$YaRKI^mRCMrc7`?^S0Jc|44XTdY?<@a3NRh%1VX<&5s z^1J7Y-YuTf*z;ShcI}=!;#NK$K$YFcowD0CzY6+hZ`VF~VTO9F{;j8qt9RcE`*Jv{ zjqi6IzlTOo^TD0Qe0CAioHL*4$iI_+j9r^pbvkjO>14O_>B<)cBPM29r@lFG zMEcOiRi(9u!?wR*TK~4TYtJ*+^7Yl4Z|mn7sQ$9g{okoz?=b0*g@hce0K;%2wy2-; YUnE!KSMJQ*E>Q95>FVdQ&MBb@0GQ*LEdT%j literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/boot_div-dmg0/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/boot_div-dmg0/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b1b859cc09f010708119b26e8d4d49fd4e98d9 GIT binary patch literal 1449 zcmb7^do&XY9LINcj2o@1Th}lnwA1t+Cz#f+Ya}pov2w4*3(P)AvO2lcu@|dEoLI`qS?oUaSkqVZ;wP zLL2Wh?tb7{J?;k>-%c<1b9H?3%NrUgN3L>;pGb~{;dbqVZ3R;UJSSjeHQVdd6^K^H zq-opxquBFG6k_vOmit0TGXmNt+0>VqMO7YDm>*8s@vn1mGhYbMPWf#(BwP6 zkSWkSBfS^9C|rwlt4$cZD`|Vq^mx!Ur7>v&qxNXr{Et#z8aXcTnBn5VM(HnEF$EU0 z4j6s`5Is7sPk{0joM=?2EHwDJt`kNyk+<6MF=@JwdfC(Y+fz`ev)p zxT&I+Vc~fTMmo@0gBa3Ua!-_v8P#AtG92XZPMjljFH;8YGinfv79?}z>q#FjjI89@E~Qq)a44F@0Cvk`p?gsA z&D>NEm2&qMTaXV)+H$&m*zLID>Y5H4(#4T1YF{ymj^n?A>NnC8^R$eAbhcHe!JSwz zo1hFPeP@FKJ}KgIpVHLJ=|J|&_*G>EJgVo0y!3Iuvb>mYcOWNsN8P02RDoVyM&Zv0 zNQA-n(9&E5DtA^tXFhXU0k~tnlDKQ?2DsmP#PykZKJ4%}d_gwqf;55aVJ=wADOW0; zdey?L`QS!}O_kM)GC{RLg>Nv!Pa4(iQ#N>6ZxACLXk*Qs`< zbs-?7sSS-k;Z78v_3y-%pK}(sD{DSwkVuI zWVrvk!fBN;25WDTFtj!gg5jOP&~-n)p#N3cw-@oRbyZSm-1#0_KhMz$>vrIE4ANeu zw}mt4VzWX?olwm2quxh9%sD5rQg^D%%g#;U>?dea67;VnR1o`8_F1)^Ohz0-95suU z)8Np?c%JxX%TTV>Y%=Qlm}>@~5@QgN=GdTI2~=}qG6lqgjHm0c72$E8^RgHNByzZx z_bPWmy%TXO#Tajeo}PJeC9XBk43$3)lViw&Cc1*L-z9T7S-VQ?i0mkf6wz*}4A?;T zTPY7yZLq15v6YJF5Og!Cbp9wk7rN9}2Qk-c4BsBQ4+M;owIl!3ywh7t)TwCV?+tmf zV{mgl;_?Qv&om5XMNg@c?^&X}@LL|D;UUs67bZ2Z?b4edh*a|6x>3Zt$XbVsU@>AY zR^E<821Q*C?rsto0ax3ECP)yq`;X0B|EKo7&-A~9|EzLd#@_do4;J&y1!#siCTNY+?##O{~46}9s3p3;MDdm)_*2M(jiTA=VC3-?M(?9bl zM!J6qWyr?xy#UrGoKU`7iRpvw0~2*7S%gEdlT9U;hCZ7ACP9grTr8_u$?{I9h4&>Q o)*esKYR?0*cXV;){vQZxEo0$Y?3xd^@1GZpboD{h91gqoH#(}=DF6Tf literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/boot_div-dmgABCmgb/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/boot_div-dmgABCmgb/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..7da91f958676b82f1f8d6f1904e70dc5d58d9164 GIT binary patch literal 1414 zcmZ`(dsNZ~6lR**eB_~%&q$qE&FKj(6Ve*9&_;=t)3oq~k5n|$JclVLEcKLz!y2La zNn5#}U4A-P(QP0bBO%4Av zN`_kN#XL`hHteL$hbf<3a z0L+rEA5u5s_-g~DBhy@OX|BrIRqDvM;8Mpj-7FyHmK#33wbXcv_VN+O*&q132olHb z@M?TnwQ1;?AroRiu+{E%WKYwJ(?3<>&S(5e5Wu)Icz=ujXrj=8MnMMp$5KL)+e&Op zvTKD}8Hbo~Yv}&qBT`(_HRRUltkvf78>P`K?82ULhZj@9?G5Q#MZWZ6MNH>k?$Hh(@i~Dz4g%J=#Auxh1NAseF`Df zYeRc>vjA5cw--k81y&t3feZi#`J5+%rZ(9d=#w2B`-N{@zsQHqCq8}d#Vrr;SVIoj z$LcW(s)jW+AdeLc+6m!e@}zDHbB(;MC+%S!z^Ubv-{#?4$}93`b&{a^??w)ky?YH* zPiL(CEuVgw0(1pQ(-uRr$n_98dugG0$WBN-6(PW!LRPrM5xEuoElb3sP}K zttlTU# zIoSaaq~;Dq8T2Oh0gZ+6(RaCK z&h9xQRNe#X_KvQ6zZxv_w|K3#}Ys;(lQ5GxQ3FIi*)y0nsE=k;5 zDM+<78ov%m>M4Vfi!(huW8qqudQ9gYT{Sts<7s%&8?gZa^W&0&PtD{%;tj9Xqzs(X z(fgp$Vs!!7bdyGZNcAY>lp=nkaAkr!BYIWduIG&IXEQTyHoU3qiwhcIxI1hoc!#b_ zT^`jc-_ADQ4ZBpWbKiFxH**7BOlb*0|U!qPZ!6KiaBrR-rlxEfybpV z?Eim#YyNXL^ja27FiDO4{dCK8;mgxvoH8P>mHIYKx8E!)u+bx-NX5WXXod`@Palh# zJJaOPo|?L+H|6hcIeL1N#vZnZoB!VYdSc7V%lj&x0PKb>ru>2Wg&G@9vz_k<$$ddHSyOeE9wU8`I)zzWE=m z&b_~W&6nGALNn*($ZPFdwP?;q%e)k+>sjyn9wnJin5pHq`eOS3vpsh2wG1EB+*&>* zptF)otNuxbN;lkv%8e%{9(V$DxD~tACB=m%8HtbQ)UJ|!wb?%DdB)ml;*GL?FT`)O zCUsr#5HGtezhuTCqi>HdM7rkRUp~!u*Sw^zw4eTOU$`nCW$BqX<6z>JEAGbj{z}Qo>umoi8+hw`=~lo++Q}WE|#O zKWu#jbj0lke~pV|=DhNCm_Kom><6t~n|aqAU87gF$EvW+SKMCSv0i4+#W`-pJb&9Kd<3vw60-lsS|3+hb1_o|1Z8SYXC#u_){B!HNSGikr0@A3aF+6?md< z*TFxxz@^Z@azSCirw;wSpAH^duYbJPy;*|Y`cdlUXXt^}qqU#UaHEGE_(cn`{e>P{0_Rj|g^|n-(pO;WM zzJ~kabJylC8)g+6=q#SQ=GMiDiHqmobv$}7^i7G}o9$-{dYTg(U#Fzrtou-6W!Ld} z(d^1Q(eq@?&&OJ}>?zd{h?Njzj}g_afkX;wY68a9Pp+Ijy=h_@|7<3Hi}g{*Qh2TK4Vy^*&w3YT+WmA_|{b)jsJSJo;>t|^VZzVYeCy3hO87TPa< zxiW6n+%?f#uO0Cd>ziNLuuF9h!`ely;%5psy#GB%KFZbj_`#F!)jijDH|G{SI&B-b zURHL?{0&!qH@sG>WR=^dZc%rP@z%*h{rct~{?6Hx7xZy2_sziR7CSQJkDs@2xGNOb z5O(oUw_M|9we$_FR^=sok4>nZeayn%dFGzHOTmv$FaJ@=mUmYrUfF&J%cfnNWp`Dc zHt%J4oAU7Zbm<>;esSh6rx$+sDFm|S)wB;xTe`&JFiHes0}N7r;8p#H^`u8N3(xj* Rz~YL5!PC{xWt~$(699U}S3dv% literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/boot_div2-S/config.ini b/cinema/gb/mooneye-gb/acceptance/boot_div2-S/config.ini index be43e382a..cc5f28f4f 100644 --- a/cinema/gb/mooneye-gb/acceptance/boot_div2-S/config.ini +++ b/cinema/gb/mooneye-gb/acceptance/boot_div2-S/config.ini @@ -1,6 +1,3 @@ -[testinfo] -fail=1 - [ports.cinema] gb.model=SGB diff --git a/cinema/gb/mooneye-gb/acceptance/ppu/hblank_ly_scx_timing-GS/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/ppu/hblank_ly_scx_timing-GS/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd601395ec15a355dff144e37dd94c587e99974 GIT binary patch literal 1103 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|Segr;B4q#hkZuZ%FA&OtEu`vXwrcN zKMdymj_>>WcuVLV@uVv!t5*A*)Li~#?MK7&w|?Aj{;q4We;xnC`8`b!H6;2_iF2QS zO=yTS{v9~y_s7XcUs@MV+ibcnQ=R2DYkA`ApuTJ6`Fc!cn%^@XR=%A6+(K&hi|fxj zr{!^7FaFlLiC@(A{pq_u^3*a{_H5?LgVA62?)(=O zl&!9LEyMgsPNke=5x?I5Ef>vt{%^KjY;gX`hM(If`c&QZ)R$pDoSC`k^Iwx(M*Z*4 z&D`s3C8nf*U-ZK7vF(n>YER;lXI$oR{_NxC`}u+$U!CC9J)bP5SKqmfznD458=n2L&A#T`%r(=jN^Wjmv3AzQ z@YqS)HTvhUtUUGE2uf2u9S=Z z!I^r#j`5T)$Y(O_FL@WJl@i!kQhEO-p*NOkeo;YoQ6(Is4F`qOxC? z{Cao9H3sNmO6mk#V=`PF0z{-5&ialgj$F z2In&#?S0(x$Ku&ppIr&UyzU1JM0n7M=Q~+GuP{De;2K>sYx>gke;dpz^hM&{e@s*3Ls`*VG_V6^PD`v06k ypT&I^{h9svzsm_(k4PEz$AJbitcQmI@ssx=qn?JT$5Ay# literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/ppu/intr_2_mode0_timing_sprites/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/ppu/intr_2_mode0_timing_sprites/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..74348ef729197e62756947002249e4b37612ada4 GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|S$Zr;B4q#hka-F6J$AU~mY$ z`Q?B8%vyuF7hWw0^te5{SZ`}yxKzP)c~_pGKux$=i#`Stq09XId3 z{`<4OzyI%H>+s^3xzm~Z_g3FKUz2{zdDWjEvOgBGTUVqlsZAF?Q}&_kobj#xx78=q z{ymj@^Wf&^LyFs9%$40!TrFYWVO)0pTYKqD8}qZrw!g0Y|48O(yF8=C?e6Uv|F{|- mv-AmD_&u-~We^t#JO00|J|!QtH$)tij67ZaT-G@yGywpCTO|ho literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/ppu/lcdon_timing-GS/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/ppu/lcdon_timing-GS/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..cdd28042c5b13ff7e8da58954b5b386728bca024 GIT binary patch literal 1105 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|SeMr;B4q#hkZuyr-=)5Mfy8 z|Gxh8o<_SRpLeP>aJgRf5d6Ga<%v_toMo9Z#}$)jE&KDpQ{uRxe%!|g&#oB!;p3iO z89M!4w*1rMyKlXo=vTe(sB+<>z4w(qO4m$V5w&k^WQ|G2#Yl%W8*aRf66!yF|KCw> zVNSVMyoUa7Je_U&zV~gYcy`0taBfUZ5!11E8?-D|yn4KN?%cgM6mPXhdH?#z>Hc-e zWg$+#Yw<_p;%Be;9<4u3QSIdRuzy#-cm|s+R||Ub{5I=^@1JHZ`W$KA*Z^;^8GQx|TbKm}%xk#ElwV?e)?UiS57uq#7b3U*GiaozBf7-54 zI6YQ7rN;c(v+gyszrFsQAj9K+us{Tzc&=IT=lnkr{Vk_ghF!V$IQ?1qjW2VyP8WXX zzwYe^)tjK8n@WT22RdOQcJ99OE^G)O5|9S5IqwD7^iT}1~-|9~jYA0_z zbbkBYJLf<23)W9koNB+{dWqt){W*Tm9j2Y{*&jR2{L+@0YctG$(Ct3Yzj%R7 z;oeV=)zkN;9-J((Bg;6DH-Dda)4>_>E$fm>{{QH%|5DcGeX=gDdJ~^#p7S2*_y_zt z(T3embwu;k_PmICvvu{Sk4ozvZc^;p-;$BJ;7>x4F2|+L=$*AKsybJzAiu`lPh>#FWcvh7aL5-NE8{9wiI z!$mChueTi&Zx2kC*^_Siy);ZLk})<(@1xC*ZC!jx`#(>1V{%-c7umDrjcmu^rw`6B zuUtF7vU|;;cnh7Ez46&O-C6gp&x$Q9`1m%|WBZ#Y`P(PjBb*0|N`Er;B4q#hkaZZ=xBlClR+x8T(dLGT#ErMNrpQg-|F?U) znvl&E>7h!}&2aMU2PZZP2t>@#@d|=DB-sDBfz1^8WXcHT~<7 z(?Xnn_x5+~-DegkzdcUJ*{A4!)KBxz>b@7}%<`Bx-(TDz?sV{nAMQo2^CI><6Ky?g zuWIyt#(UbJz&aAc5KwX<$OWWB~YnWOK;*2i;2>b#o1 zSx}8Pdf|tU4>zS;niTzZnb+EjJ13c5PAU)Fq|@`{pigz)!Ps5Ra%?%t-`{K2NG`wBdD4Gsn)vbK@gHmJe%7?QpDdi0zRB<8I^}zRuUI~};mhOU ze(!44bo=q4KdP&h^Yrdnolu{bbIU!#kZ;}8<;wqG3-mrH6+Y4%CmgV6Us?B)UuS(j zW#5Y4FY)hgmE+=L-`+QOuaDX~YyMRw-S^*)=Lbq3S6MWD&6A%~YR;{fKcx9?$_~rO zDHcYq^F#l2U%p&v7%LY%v0?o^{$sagKiy~FUi17;+0TR@A9a5ptbH@<{vG~*BIku= zKim1=^E_@p>Bzz>E3>78U$0&At?@AJ04QFyEMU$mm{!L$p-iTNcLuWPKA z);?+>aq|2IseRS%5e`OErl0A5UL$sz!_R5`&*IY=`&id<%R1k_bhj#T$&G@o%N;ge zjk`X}H1XgeKf}Mj?yRw&clvExGW#E?I?MRI7e4Z8Nc1&594W*(`|zo@QTozOuR&#l Mr>mdKI;Vst0F{m&7XSbN literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/acceptance/serial/boot_sclk_align-dmgABCmgb/xbaseline_0000.png b/cinema/gb/mooneye-gb/acceptance/serial/boot_sclk_align-dmgABCmgb/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..ed7bd71b0a0ea8a103895e25b8999a7f9ee2fb48 GIT binary patch literal 1402 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/misc/boot_div-cgb0/xbaseline_0000.png b/cinema/gb/mooneye-gb/misc/boot_div-cgb0/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d24cc3a6b7aa103cba20524a151a49314d4cec GIT binary patch literal 1444 zcmZuxe>4*a9G7B6^xmZ=W|lL`IrPg-Xh%ca+A3q2UmNQ}q7>1_Tuo)E&5uNd9Y@-k z)unAhSZ)^49*Kt78I24{tjRdNyY9W~`s4fkzW4d#`@Zk{`N24d^)WIqGtkk|F+%P` z_%6?1mMe3$?sC`ZQTOQR=tUzD9)3v$6NP=(xsbJpY3||@an23aRGpa?6zNI$_!Fgz z8HLWwydybVbWZ;61b^ib2NP3}!CGTI{Y$#^z2`*5jq+sA)snbBmN1Wp6fo0J*FR5d z85HZ@_fhOu+i#+}k4i5xwWvAbv$&%2_?_(VK`A|&j4U$SK!=pp502g&vSTdp<>BZW z$2vh9uRYtpETKXANaBc^Yq6!Zf}^!b&`P3`gNh@k_;>p|kEBVpYy_F3o{V&u*V}%` z>*2BYveX^FDqVxFoZd5nIdxC0((SW^6}0I7d*DIR$t_MW6Vrlc4CYDn79$Eown@lt z%SpV|sl*i8y3Ff2Z@y*bdtDfw(4WECFT@E7W5?j!cRhG8canU#Euib;4L*59>E~TL zYEPp@Y>Jzk@pLPepZfOtcAc`$uEwK8;UIye^ni0wPqmI`G& zpJ4`wV5S8{4!r^`sZSYX^|VHr6_tq93%*c-?b7JDY& z>TOc8rf{Q5B0bBsm&r=3tW=7K>*BbR9rX_k*Sk`YF93^<$u3vuqA_lZ?_$jT^;z9> z1aQ3lIAe&Vl#PiKI(*$?ve!8y7$4m$%$os(&fctWLB!Fh>}G{mVi<(1weXI(?}=4W z+`I7z)sS*E7(fW>GM{=p&uJZRDy5L!ElHhT#ESl+bnGiDe3Gh!vH5>O`FFo*CVqaL}Gh85+X5fFb&JD?TqZF?ZTbA9C?%n*d zRq1tjk9h?ZD6I(zf(uC_)STO3{>@X;IQTmC6fSUSpfm!g<|}rMDpMW?)zuBThb?$S zBavFtx(D+(Tm+vqZ7@WAQk&Dnj`!D%jp*J-`Np@f&HY(rR zso2K&%+pr2&5Kp_I2J@f%9@T3eK!jQJaJmahdl7y^mKIg@l-)Yzy^SDvWLF#UAbM^ zhfX_|IZ6SsJv+|fs(;>pA?}lLzxq}9)bS+VTel{ET+6OVql*U)qE}{I7?X`C2xciv z;Xr-Z)y3P9E&9-o%E3+jH&=8)+ltOuY_MP~<Gp>+5UQuCGr#1-%QyNVavbeIM;AqIZ5e!5RMl@go+{K@cz}P*ZiJbF|C@rJ ess8G%%h|K^1FHJ928a**l)gwWEQ04rI{z2Qy2V)l literal 0 HcmV?d00001 diff --git a/cinema/gb/mooneye-gb/misc/boot_div-cgbABCDE/xbaseline_0000.png b/cinema/gb/mooneye-gb/misc/boot_div-cgbABCDE/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..38e760ea82252416696d38b2bd9fc2a4e5ac83ba GIT binary patch literal 1438 zcmZvcc~BB~6vxeUb?|D`L@kdt*EFwcJSfOKB9HQDMf0FMGYAc|k@5&kH#Kq9^*{oT zG}H3R#6;6HLINwuv~;jcQ1gruaXnCQZFgp8oA!_2`^~(WH}jeIzVo^1>+Pln&4woEJ5_(*Rr8|2L zELh#>SaNUG8|=P1=?`0s68n--eg!)uCk>uZi>gX;QvMH<|fCS3w5c?_d&*Jcf2>ARH zB{BixWLl?u=Xv1TSk7|N1wtJ6jbpV!$Sdn+>2*f2CC2OkNLzRJe|YuaGs?8of~h4J z;m0YTH__^YcpNfjUHJ-~3Wiv|F4&roePs+l#_t+hA{CF4KYZy_)|o3QR$lS41-SsuiSKcbBdAt&(5 z&K$$dTPEHQz!8elFw9RZ{`{j0$5zjARl#Cp4dV+2quSH~$Ri1rfCd4sU>Yenk92+} zRA-aftMTQbGqSd(beJ@dCS9c;N&=^&6BvsgL$%mwnD6-erD-(qK5rI2+T2FaF*W~s zs-*}kIpff;k&%fz0Ak}7R7CtMM3`L+U+Fc$G+{BVOdO~ebMIYlcr!h!;8Q5{y1BfC z^yP4H^8i=eH%hG!yw#$$jND-dMom04%9rw|OkUnB^W)vw_DA@PQaaUf-+WS;c9qYK zgS+_@Q5emjlGTMkD`UwGN~fUf%9$fH&&|cM7^oIl90{*H+Xt9?wQ~>mNOZ`tj5t)Q zP7Ks1?YGRw;xLA;p|~p6s-uT99p?#_UU}1bj#RBBp??e04>#M&*al#C0^aClaSx#nG&4a@O*hSNT8mctXaQl_7Szw#*e@U z!l0}085m)>KZxhxVeO2gz!fBKD;n2$oxbT_Apnygl?gzA3d4g#Oy7!7#fd$H#6_7~r<8W)#$c1G7 z);I@GBS)DFRU7LT`fG+moN8Q->6S8a7_&dCGQM!6jl~u*m!@F>5_+Y-nxf8}}P%si&AopjX4~zrFIqj@Nk9J)6(OfD&P2mZ6UJbezJ$z92TT&WhpK z_#mR_1o!To&6vF#-mN+;9g`g8#aw@!g1_-XQ+=O2d-=*p8~90QlS%0~&eJD^^x-nX zj993Gj<>F`RnV!P>v~5G>i*zV{AjFIEo9VKC1uFy^Z`3{a&OSO9eWUwy{u8vvzM*q nt~sN`_}6?t5dI^?@7rQvJFuOn+hK9?n|D2+-p89b*0|T>+r;B4q#hkad?iQ^wU|>ir zsQ4egOnhFasKF z@lx&5!OI^npH1b>-EJ9@I_L02v+2|2UfrBr7k$GaHTi7O()+J(>&=y1%DCRh{Kw}4 zzUAI8U*3E=-{x2X_wBkowLfd@b@#n{JXgC{_`c99_TmUd+l_2|c`3VXAE)?#`Bj%@ z9woW_%aqJ$n|BxD6~9>9EHycoG5eC6JNurj-4D6e&8a{8^d-m3U)SR<^q;$H#gVyr zdiA$Dxhwx4wTqs6B6%w>ct`Bq`%8^?8)mJxm${!j{r~^(SKd3N?3q$rBgdc3J)IbLx%Fl8$2|d=VoTG@mYRHzoGFld?$Vd@-_pPTUzK^} z{r6cP>i6|2ABFudDp`_kzVgAG-bd{bKgT_%H9mf8WoaT|K`_y!d{!T4n8Op~^FH2m62U z9=>n+W`A<@s`tVBKWLwl`t)}Fq>@SRn_+&HlsJd({gEbA$KY_-=Ww9%>o!n!@pScb JS?83{1OOp9n-l;5 diff --git a/cinema/gb/mooneye-gb/misc/ppu/vblank_stat_intr-C/xbaseline_0000.png b/cinema/gb/mooneye-gb/misc/ppu/vblank_stat_intr-C/xbaseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..57a392a972c2763c9a4579df08036f46c0cc5b92 GIT binary patch literal 1329 zcmeAS@N?(olHy`uVBq!ia0vp^3xIe62NRHFxc>b*0|UzsPZ!6KiaBrR-kr8Yfv2U= zfB%2&&En^b?0*nj5bz>zSg^xJAbDxl6&%&)b-fh;#Aqv9h%@H9I#RTzKF? zKth3?=F-O&r_v{H_+i1^!Rp8~tL&RH9d zyt63n zSBn2SBQQAVe5LBFf}=~>j_;X1|IMT4T=`|2VjiD}o*K0>&UUL=j_S|Wv*2h}_?f`qfK z`kL0ndHJi}R%GOlJJ&spOEn}h*POj3^{Xh~rF$1^k~6;?*vi6d>=v|P_NEP1lcr`R zeUE>&+qA;uYw&h~%})F8xV&$wb9R6BbWcY9mw&g8EPj&Za&mf~vxsVka8ENdU4i3F z1}VAy6pc7(SJR#G?~O;bPF03meo{`Dq`+r&`O)ZLd>guP#=vu5^^=nMAu@|qs(|M&S>`dg=^50-qH z@~Uj9%=$&Qe(2p;pZEXPsyh{I{I(6tpSxRo*B|;f-M&HidGo_W8T8bT;YvuRfC>9e z`R=N&D0=DD)QboIeo;R4d(rA;F}=q>UY=@x-8XCAA+JeWw&h*A(78ykf|lu#grBFMZF}B#Vy2vJ z_CB4c=7*E7sHCg@^@==~xMI(&)!WyoY`*#I#ruwFW~fws`KFQvEb@)Wl?{aQrw z-@7pT_W{3tf8NR)`hWS`_Z&s+lT?l!`~WP5kX(e3^N~{#Fn<29?hk(UW|^MdUQki! M>FVdQ&MBb@0Nl`z!vFvP literal 0 HcmV?d00001 From b169e6b0dfa177ca6390d7f9e025e7412a22afe8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 25 Nov 2020 20:40:20 -0800 Subject: [PATCH 11/20] ARM: Fix non-debugger build --- include/mgba/internal/arm/decoder.h | 7 +++++-- src/arm/decoder.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/mgba/internal/arm/decoder.h b/include/mgba/internal/arm/decoder.h index f29c15aad..61226f8c4 100644 --- a/include/mgba/internal/arm/decoder.h +++ b/include/mgba/internal/arm/decoder.h @@ -215,14 +215,17 @@ struct ARMInstructionInfo { unsigned nDataCycles : 10; }; -struct mDebuggerSymbols; void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info); void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info); bool ARMDecodeThumbCombine(struct ARMInstructionInfo* info1, struct ARMInstructionInfo* info2, struct ARMInstructionInfo* out); -int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen); uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegisterFile* regs, uint32_t pc); +#ifdef USE_DEBUGGERS +struct mDebuggerSymbols; +int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen); +#endif + CXX_GUARD_END #endif diff --git a/src/arm/decoder.c b/src/arm/decoder.c index 59b3b7f1c..86583fa2d 100644 --- a/src/arm/decoder.c +++ b/src/arm/decoder.c @@ -9,6 +9,7 @@ #include #include +#ifdef USE_DEBUGGERS #define ADVANCE(AMOUNT) \ if (AMOUNT >= blen) { \ buffer[blen - 1] = '\0'; \ @@ -543,6 +544,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* cpu, const s buffer[blen - 1] = '\0'; return total; } +#endif uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegisterFile* regs, uint32_t pc) { uint32_t address = 0; From 2e2ad705500f0f52769c14b6f9722def9057633c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 25 Nov 2020 21:16:30 -0800 Subject: [PATCH 12/20] CMake: Move BUILD_GL flags to FEATURE_DEFINES --- CMakeLists.txt | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16c44c14c..49ca879d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,17 +457,20 @@ if(NOT BUILD_GLES2) endif() if(BUILD_GL) list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c) + list(APPEND FEATURE_DEFINES BUILD_GL) list(APPEND DEPENDENCY_LIB ${OPENGL_LIBRARY}) include_directories(${OPENGL_INCLUDE_DIR}) endif() if(BUILD_GLES2) list(APPEND FEATURE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gles2.c) + list(APPEND FEATURE_DEFINES BUILD_GLES2) list(APPEND DEPENDENCY_LIB ${OPENGLES2_LIBRARY}) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() if(BUILD_GLES3) find_path(OPENGLES3_INCLUDE_DIR NAMES GLES3/gl3.h) find_library(OPENGLES3_LIBRARY NAMES GLESv3 GLESv2) + list(APPEND FEATURE_DEFINES BUILD_GLES3) if(NOT OPENGLES3_INCLUDE_DIR OR NOT OPENGLES3_LIBRARY) set(BUILD_GLES3 OFF CACHE BOOL "OpenGL|ES 3 not found" FORCE) endif() @@ -912,18 +915,6 @@ else() endif() endif() -if(BUILD_GL) - add_definitions(-DBUILD_GL) -endif() - -if(BUILD_GLES2) - add_definitions(-DBUILD_GLES2) -endif() - -if(BUILD_GLES3) - add_definitions(-DBUILD_GLES3) -endif() - if(DISABLE_FRONTENDS) set(BUILD_SDL OFF) set(BUILD_QT OFF) From 0d96ba4f8fab5af32ea2491c7ecc8d958cdf50de Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 26 Nov 2020 22:09:01 -0800 Subject: [PATCH 13/20] Wii: Add libwiidrc support --- CHANGES | 1 + src/platform/wii/CMakeLists.txt | 8 +++ src/platform/wii/main.c | 110 ++++++++++++++++++++++++++++++-- 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 400c429fd..2969ec110 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Features: - ARM disassembler now resolves addresses to symbol names - Add Game Boy Player feature support to ports - Individual window types can now be toggled in debugging views + - Support for the Wii U GamePad when running as an injected VC title Emulation fixes: - ARM: Fix ALU reading PC after shifting - ARM: Fix STR storing PC after address calculation diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index 8d1a60e87..ed27fae90 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -3,6 +3,11 @@ find_program(GXTEXCONV gxtexconv) find_program(RAW2C raw2c) find_program(WIILOAD wiiload) +find_library(WIIDRC_LIBRARY wiidrc) +if(WIIDRC_LIBRARY) + add_definitions(-DWIIDRC) +endif() + set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 USE_VFS_FILE IOAPI_NO_64 FIXED_ROM_BUFFER) list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-file.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) @@ -20,6 +25,9 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/font.c PROPERTIES GENERA add_executable(${BINARY_NAME}.elf ${GUI_SRC} main.c) set_target_properties(${BINARY_NAME}.elf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}") target_link_libraries(${BINARY_NAME}.elf ${BINARY_NAME} ${OS_LIB}) +if(WIIDRC_LIBRARY) + target_link_libraries(${BINARY_NAME}.elf ${WIIDRC_LIBRARY}) +endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/font.tpl COMMAND ${GXTEXCONV} -i ${CMAKE_SOURCE_DIR}/res/font2x.png -o font.tpl colfmt=5 mipmap=no diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index dd9311de9..4a3c8b871 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -28,10 +28,15 @@ #include #include +#ifdef WIIDRC +#include +#endif + #define GCN1_INPUT 0x47434E31 #define GCN2_INPUT 0x47434E32 #define WIIMOTE_INPUT 0x5749494D #define CLASSIC_INPUT 0x57494943 +#define DRC_INPUT 0x44524355 #define TEX_W 256 #define TEX_H 224 @@ -254,6 +259,9 @@ int main(int argc, char* argv[]) { PAD_Init(); WPAD_Init(); WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR); +#ifdef WIIDRC + WiiDRC_Init(); +#endif AUDIO_Init(0); AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback(_audioDMA); @@ -452,6 +460,31 @@ int main(int argc, char* argv[]) { }, .nKeys = 32 }, +#ifdef WIIDRC + { + .name = "Wii U GamePad Input", + .id = DRC_INPUT, + .keyNames = (const char*[]) { + 0, // Sync + "\1\xE", + "-", + "+", + "R", + "L", + "ZR", + "ZL", + "Down", + "Up", + "Right", + "Left", + "Y", + "X", + "B", + "A", + }, + .nKeys = 16 + }, +#endif { .id = 0 } }, .configExtra = (struct GUIMenuItem[]) { @@ -576,6 +609,15 @@ int main(int argc, char* argv[]) { _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_LEFT, GUI_INPUT_LEFT); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_RIGHT, GUI_INPUT_RIGHT); +#ifdef WIIDRC + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_A, GUI_INPUT_SELECT); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_B, GUI_INPUT_BACK); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_X, GUI_INPUT_CANCEL); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_UP, GUI_INPUT_UP); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_DOWN, GUI_INPUT_DOWN); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_LEFT, GUI_INPUT_LEFT); + _mapKey(&runner.params.keyMap, DRC_INPUT, WIIDRC_BUTTON_RIGHT, GUI_INPUT_RIGHT); +#endif float stretch = 0; if (mCoreConfigGetFloatValue(&runner.config, "stretchWidth", &stretch)) { @@ -701,29 +743,48 @@ static uint32_t _pollInput(const struct mInputMap* map) { u32 ext = 0; WPAD_Probe(0, &ext); +#ifdef WIIDRC + u32 drckeys = 0; + if (WiiDRC_ScanPads()) { + drckeys = WiiDRC_ButtonsHeld(); + } +#endif + int keys = 0; keys |= mInputMapKeyBits(map, GCN1_INPUT, padkeys, 0); keys |= mInputMapKeyBits(map, GCN2_INPUT, padkeys, 0); keys |= mInputMapKeyBits(map, WIIMOTE_INPUT, wiiPad, 0); +#ifdef WIIDRC + keys |= mInputMapKeyBits(map, DRC_INPUT, drckeys, 0); +#endif if (ext == WPAD_EXP_CLASSIC) { keys |= mInputMapKeyBits(map, CLASSIC_INPUT, wiiPad, 0); } int x = PAD_StickX(0); int y = PAD_StickY(0); - int w_x = WPAD_StickX(0, 0); - int w_y = WPAD_StickY(0, 0); - if (x < -ANALOG_DEADZONE || w_x < -ANALOG_DEADZONE) { + int wX = WPAD_StickX(0, 0); + int wY = WPAD_StickY(0, 0); + ATTRIBUTE_UNUSED int drcX = 0; + ATTRIBUTE_UNUSED int drcY = 0; +#ifdef WIIDRC + if (WiiDRC_Connected()) { + drcX = WiiDRC_lStickX(); + drcY = WiiDRC_lStickY(); + } +#endif + if (x < -ANALOG_DEADZONE || wX < -ANALOG_DEADZONE || drcX < -ANALOG_DEADZONE) { keys |= 1 << GUI_INPUT_LEFT; } - if (x > ANALOG_DEADZONE || w_x > ANALOG_DEADZONE) { + if (x > ANALOG_DEADZONE || wX > ANALOG_DEADZONE || drcX > ANALOG_DEADZONE) { keys |= 1 << GUI_INPUT_RIGHT; } - if (y < -ANALOG_DEADZONE || w_y < -ANALOG_DEADZONE) { + if (y < -ANALOG_DEADZONE || wY < -ANALOG_DEADZONE || drcY < -ANALOG_DEADZONE) { keys |= 1 << GUI_INPUT_DOWN; } - if (y > ANALOG_DEADZONE || w_y > ANALOG_DEADZONE) { + if (y > ANALOG_DEADZONE || wY > ANALOG_DEADZONE || drcY > ANALOG_DEADZONE) { keys |= 1 << GUI_INPUT_UP; } + return keys; } @@ -803,12 +864,27 @@ void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_FULL_L, GBA_KEY_L); _mapKey(&runner->core->inputMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_FULL_R, GBA_KEY_R); +#ifdef WIIDRC + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_A, GBA_KEY_A); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_B, GBA_KEY_B); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_PLUS, GBA_KEY_START); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_MINUS, GBA_KEY_SELECT); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_UP, GBA_KEY_UP); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_DOWN, GBA_KEY_DOWN); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_LEFT, GBA_KEY_LEFT); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_RIGHT, GBA_KEY_RIGHT); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_L, GBA_KEY_L); + _mapKey(&runner->core->inputMap, DRC_INPUT, WIIDRC_BUTTON_R, GBA_KEY_R); +#endif + struct mInputAxis desc = { GBA_KEY_RIGHT, GBA_KEY_LEFT, ANALOG_DEADZONE, -ANALOG_DEADZONE }; mInputBindAxis(&runner->core->inputMap, GCN1_INPUT, 0, &desc); mInputBindAxis(&runner->core->inputMap, CLASSIC_INPUT, 0, &desc); + mInputBindAxis(&runner->core->inputMap, DRC_INPUT, 0, &desc); desc = (struct mInputAxis) { GBA_KEY_UP, GBA_KEY_DOWN, ANALOG_DEADZONE, -ANALOG_DEADZONE }; mInputBindAxis(&runner->core->inputMap, GCN1_INPUT, 1, &desc); mInputBindAxis(&runner->core->inputMap, CLASSIC_INPUT, 1, &desc); + mInputBindAxis(&runner->core->inputMap, DRC_INPUT, 1, &desc); outputBuffer = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL); runner->core->setVideoBuffer(runner->core, outputBuffer, TEX_W); @@ -1033,9 +1109,18 @@ uint16_t _pollGameInput(struct mGUIRunner* runner) { u32 wiiPad = WPAD_ButtonsHeld(0); u32 ext = 0; WPAD_Probe(0, &ext); +#ifdef WIIDRC + u32 drckeys = 0; + if (WiiDRC_ScanPads()) { + drckeys = WiiDRC_ButtonsHeld(); + } +#endif uint16_t keys = mInputMapKeyBits(&runner->core->inputMap, GCN1_INPUT, padkeys, 0); keys |= mInputMapKeyBits(&runner->core->inputMap, GCN2_INPUT, padkeys, 0); keys |= mInputMapKeyBits(&runner->core->inputMap, WIIMOTE_INPUT, wiiPad, 0); +#ifdef WIIDRC + keys |= mInputMapKeyBits(&runner->core->inputMap, DRC_INPUT, drckeys, 0); +#endif enum GBAKey angles = mInputMapAxis(&runner->core->inputMap, GCN1_INPUT, 0, PAD_StickX(0)); if (angles != GBA_KEY_NONE) { @@ -1056,6 +1141,19 @@ uint16_t _pollGameInput(struct mGUIRunner* runner) { keys |= 1 << angles; } } +#ifdef WIIDRC + if (WiiDRC_Connected()) { + keys |= mInputMapKeyBits(&runner->core->inputMap, DRC_INPUT, drckeys, 0); + angles = mInputMapAxis(&runner->core->inputMap, DRC_INPUT, 0, WiiDRC_lStickX()); + if (angles != GBA_KEY_NONE) { + keys |= 1 << angles; + } + angles = mInputMapAxis(&runner->core->inputMap, DRC_INPUT, 1, WiiDRC_lStickY()); + if (angles != GBA_KEY_NONE) { + keys |= 1 << angles; + } + } +#endif return keys; } From 7640c386847d5fc32b1adce76ee0afe2934e233e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 26 Nov 2020 22:33:05 -0800 Subject: [PATCH 14/20] mGUI: Skip second scan loop when possible --- CHANGES | 1 + src/util/gui/file-select.c | 101 +++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/CHANGES b/CHANGES index 2969ec110..06cec7817 100644 --- a/CHANGES +++ b/CHANGES @@ -92,6 +92,7 @@ Misc: - Debugger: Keep track of global cycle count - FFmpeg: Add looping option for GIF/APNG - mGUI: Show battery percentage + - mGUI: Skip second scan loop when possible - Qt: Renderer can be changed while a game is running - Qt: Add hex index to palette view - Qt: Add transformation matrix info to sprite view diff --git a/src/util/gui/file-select.c b/src/util/gui/file-select.c index 1d75e88b9..b8802d8cc 100644 --- a/src/util/gui/file-select.c +++ b/src/util/gui/file-select.c @@ -89,6 +89,8 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, char* n2 = malloc(len); snprintf(n2, len, "%s/", name); name = n2; + } else if (filterName && !filterName(name)) { + continue; } else { name = strdup(name); } @@ -96,59 +98,58 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, ++items; } qsort(GUIMenuItemListGetPointer(currentFiles, 1), GUIMenuItemListSize(currentFiles) - 1, sizeof(struct GUIMenuItem), _strpcmp); - i = 0; - size_t item = 0; - while (item < GUIMenuItemListSize(currentFiles)) { - ++i; - if (!(i % SCANNING_THRESHOLD_2)) { - uint32_t input = 0; - GUIPollInput(params, &input, 0); - if (input & (1 << GUI_INPUT_CANCEL)) { - dir->close(dir); - return false; - } - - params->drawStart(); - if (params->guiPrepare) { - params->guiPrepare(); - } - GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_ALIGN_LEFT, 0xFFFFFFFF, "(scanning item %"PRIz"u of %"PRIz"u)", i, items); - GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_ALIGN_LEFT, 0xFFFFFFFF, "%s", currentPath); - if (params->guiFinish) { - params->guiFinish(); - } - params->drawEnd(); - } - struct GUIMenuItem* testItem = GUIMenuItemListGetPointer(currentFiles, item); - if (testItem->data != (void*) VFS_FILE) { - ++item; - continue; - } - bool failed = false; - if (filterName && !filterName(testItem->title)) { - failed = true; - } - - if (!failed && filterContents) { - struct VFile* vf = dir->openFile(dir, testItem->title, O_RDONLY); - if (!vf) { - failed = true; - } else { - if (!filterContents(vf)) { - failed = true; + if (preselect || filterContents) { + i = 0; + size_t item = 0; + while (item < GUIMenuItemListSize(currentFiles)) { + ++i; + // If we're not filtering the contents, this loop is fast, so there's no need to show updates + if (filterContents && !(i % SCANNING_THRESHOLD_2)) { + uint32_t input = 0; + GUIPollInput(params, &input, 0); + if (input & (1 << GUI_INPUT_CANCEL)) { + dir->close(dir); + return false; } - vf->close(vf); - } - } - if (failed) { - free((char*) testItem->title); - GUIMenuItemListShift(currentFiles, item, 1); - } else { - if (preselect && strncmp(testItem->title, preselect, PATH_MAX) == 0) { - params->fileIndex = item; + params->drawStart(); + if (params->guiPrepare) { + params->guiPrepare(); + } + GUIFontPrintf(params->font, 0, GUIFontHeight(params->font), GUI_ALIGN_LEFT, 0xFFFFFFFF, "(scanning item %"PRIz"u of %"PRIz"u)", i, items); + GUIFontPrintf(params->font, 0, GUIFontHeight(params->font) * 2, GUI_ALIGN_LEFT, 0xFFFFFFFF, "%s", currentPath); + if (params->guiFinish) { + params->guiFinish(); + } + params->drawEnd(); + } + struct GUIMenuItem* testItem = GUIMenuItemListGetPointer(currentFiles, item); + if (testItem->data != (void*) VFS_FILE) { + ++item; + continue; + } + bool failed = false; + if (filterContents) { + struct VFile* vf = dir->openFile(dir, testItem->title, O_RDONLY); + if (!vf) { + failed = true; + } else { + if (!filterContents(vf)) { + failed = true; + } + vf->close(vf); + } + } + + if (failed) { + free((char*) testItem->title); + GUIMenuItemListShift(currentFiles, item, 1); + } else { + if (preselect && strncmp(testItem->title, preselect, PATH_MAX) == 0) { + params->fileIndex = item; + } + ++item; } - ++item; } } dir->close(dir); From 99e622eb43b7f218e24f91493a27473a640da388 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 13:53:33 -0800 Subject: [PATCH 15/20] GBA Video: Skip attempting to render offscreen sprites in OpenGL --- CHANGES | 1 + src/gba/renderers/gl.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index 06cec7817..a419da5b0 100644 --- a/CHANGES +++ b/CHANGES @@ -89,6 +89,7 @@ Misc: - GBA: Allow pausing event loop while CPU is blocked - GBA BIOS: Division by zero should emit a FATAL error - GBA Video: Convert OpenGL VRAM texture to integer + - GBA Video: Skip attempting to render offscreen sprites in OpenGL - Debugger: Keep track of global cycle count - FFmpeg: Add looping option for GIF/APNG - mGUI: Show battery percentage diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 8d2742eb8..46b5b60fa 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1669,6 +1669,11 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB spriteY -= 256; } + if (x + totalWidth <= 0 || x >= GBA_VIDEO_HORIZONTAL_PIXELS) { + // These sprites aren't displayed but affect cycle counting + return; + } + const struct GBAVideoGLShader* shader = &renderer->objShader[GBAObjAttributesAGet256Color(sprite->a)]; const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); From 39324749f2e22c5c081cfca79502f90c8cd853e7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 15:18:23 -0800 Subject: [PATCH 16/20] 3DS: Batch directory reads --- CHANGES | 1 + src/platform/3ds/3ds-vfs.c | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index a419da5b0..843d9e530 100644 --- a/CHANGES +++ b/CHANGES @@ -80,6 +80,7 @@ Other fixes: - Wii: Fix crash on unloading irregularly sized GBA ROMs Misc: - 3DS: Use "wide mode" where applicable for slightly better filtering + - 3DS: Batch directory reads - Core: Add savedataUpdated callback - Core: Add shutdown callback - Core: Rework thread state synchronization diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index 508b9fac3..587ac5944 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -9,6 +9,8 @@ #include #include +#define MAX_ENT 4 + struct VFile3DS { struct VFile d; @@ -18,7 +20,9 @@ struct VFile3DS { struct VDirEntry3DS { struct VDirEntry d; - FS_DirectoryEntry ent; + FS_DirectoryEntry ent[MAX_ENT]; + u32 entCount; + u32 currentEnt; char utf8Name[256]; }; @@ -198,6 +202,7 @@ struct VDir* VDirOpen(const char* path) { vd3d->vde.d.name = _vd3deName; vd3d->vde.d.type = _vd3deType; + vd3d->vde.entCount = 0; return &vd3d->d; } @@ -222,12 +227,16 @@ static void _vd3dRewind(struct VDir* vd) { static struct VDirEntry* _vd3dListNext(struct VDir* vd) { struct VDir3DS* vd3d = (struct VDir3DS*) vd; - u32 n = 0; - memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent)); memset(vd3d->vde.utf8Name, 0, sizeof(vd3d->vde.utf8Name)); - FSDIR_Read(vd3d->handle, &n, 1, &vd3d->vde.ent); - if (!n) { - return 0; + if (!vd3d->vde.entCount || vd3d->vde.currentEnt + 1 >= vd3d->vde.entCount) { + memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent)); + FSDIR_Read(vd3d->handle, &vd3d->vde.entCount, MAX_ENT, vd3d->vde.ent); + vd3d->vde.currentEnt = 0; + } else { + ++vd3d->vde.currentEnt; + } + if (!vd3d->vde.entCount) { + return NULL; } return &vd3d->vde.d; } @@ -296,14 +305,14 @@ static bool _vd3dDeleteFile(struct VDir* vd, const char* path) { static const char* _vd3deName(struct VDirEntry* vde) { struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde; if (!vd3de->utf8Name[0]) { - utf16_to_utf8((uint8_t*) vd3de->utf8Name, vd3de->ent.name, sizeof(vd3de->utf8Name)); + utf16_to_utf8((uint8_t*) vd3de->utf8Name, vd3de->ent[vd3de->currentEnt].name, sizeof(vd3de->utf8Name)); } return vd3de->utf8Name; } static enum VFSType _vd3deType(struct VDirEntry* vde) { struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde; - if (vd3de->ent.attributes & FS_ATTRIBUTE_DIRECTORY) { + if (vd3de->ent[vd3de->currentEnt].attributes & FS_ATTRIBUTE_DIRECTORY) { return VFS_DIRECTORY; } return VFS_FILE; From bb74b60cd9033fe1dd4cf0607b379033902dfc4d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 17:38:31 -0800 Subject: [PATCH 17/20] Core: Fix possible video sync deadlock --- src/core/sync.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/sync.c b/src/core/sync.c index 492572534..b2a65493b 100644 --- a/src/core/sync.c +++ b/src/core/sync.c @@ -49,11 +49,11 @@ bool mCoreSyncWaitFrameStart(struct mCoreSync* sync) { } MutexLock(&sync->videoFrameMutex); - ConditionWake(&sync->videoFrameRequiredCond); if (!sync->videoFrameWait && !sync->videoFramePending) { return false; } if (sync->videoFrameWait) { + ConditionWake(&sync->videoFrameRequiredCond); if (ConditionWaitTimed(&sync->videoFrameAvailableCond, &sync->videoFrameMutex, 50)) { return false; } @@ -67,6 +67,7 @@ void mCoreSyncWaitFrameEnd(struct mCoreSync* sync) { return; } + ConditionWake(&sync->videoFrameRequiredCond); MutexUnlock(&sync->videoFrameMutex); } From fc3e47a4bab1465b91e7368c6396b222f65f51cb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 18:24:02 -0800 Subject: [PATCH 18/20] Feature: Allow configuring waiting on frame flushing in proxy --- include/mgba/feature/video-logger.h | 1 + src/feature/video-logger.c | 6 ++++-- src/platform/qt/DisplayGL.cpp | 4 ++++ src/platform/qt/VideoProxy.cpp | 1 + src/platform/qt/VideoProxy.h | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index 2530d3fa2..cf50dd58e 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -57,6 +57,7 @@ struct mVideoLogger { void* dataContext; bool block; + bool waitOnFlush; void (*init)(struct mVideoLogger*); void (*deinit)(struct mVideoLogger*); void (*reset)(struct mVideoLogger*); diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 5c2a98f5c..508517c65 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -119,7 +119,6 @@ static inline size_t _roundUp(size_t value, int shift) { void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly) { if (readonly) { logger->writeData = _writeNull; - logger->block = true; } else { logger->writeData = _writeData; } @@ -134,6 +133,9 @@ void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly) { logger->unlock = NULL; logger->wait = NULL; logger->wake = NULL; + + logger->block = readonly; + logger->waitOnFlush = !readonly; } void mVideoLoggerRendererInit(struct mVideoLogger* logger) { @@ -263,7 +265,7 @@ void mVideoLoggerRendererFlush(struct mVideoLogger* logger) { 0xDEADBEEF, }; logger->writeData(logger, &dirty, sizeof(dirty)); - if (logger->wait) { + if (logger->waitOnFlush && logger->wait) { logger->wait(logger); } } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index e2685c8db..17e1ea360 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -435,6 +435,10 @@ void PainterGL::draw() { mCoreSync* sync = &m_context->thread()->impl->sync; mCoreSyncWaitFrameStart(sync); dequeue(); + if (m_videoProxy) { + // Only block on the next frame if we're trying to run at roughly 60fps via audio + m_videoProxy->setBlocking(sync->audioWait && std::abs(60.f - sync->fpsTarget) < 0.1f); + } if (!m_delayTimer.isValid()) { m_delayTimer.start(); } else if (sync->audioWait || sync->videoFrameWait) { diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index aee19deb4..c188f5b78 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -14,6 +14,7 @@ using namespace QGBA; VideoProxy::VideoProxy() { mVideoLoggerRendererCreate(&m_logger.d, false); m_logger.d.block = true; + m_logger.d.waitOnFlush = false; m_logger.d.init = &cbind<&VideoProxy::init>; m_logger.d.reset = &cbind<&VideoProxy::reset>; diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h index 0e0f4bd5b..9376515f4 100644 --- a/src/platform/qt/VideoProxy.h +++ b/src/platform/qt/VideoProxy.h @@ -24,6 +24,7 @@ public: void attach(CoreController*); void detach(CoreController*); + void setBlocking(bool block) { m_logger.d.waitOnFlush = block; } signals: void dataAvailable(); From 8e096916b1dc1aacc17236e8d2bf6eda4edb5edf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 18:31:13 -0800 Subject: [PATCH 19/20] Qt: Discard additional frame draws if waiting fails --- CHANGES | 1 + src/platform/qt/DisplayGL.cpp | 24 +++++++++++++++++++----- src/platform/qt/DisplayGL.h | 2 ++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 843d9e530..dc94b316d 100644 --- a/CHANGES +++ b/CHANGES @@ -102,6 +102,7 @@ Misc: - Qt: Add copy button to GB printer dialog - Qt: Window title updates can be disabled (closes mgba.io/i/1912) - Qt: Redo OpenGL context thread handling (fixes mgba.io/i/1724) + - Qt: Discard additional frame draws if waiting fails - Util: Reset vector size on deinit - VFS: Change semantics of VFile.sync on mapped files (fixes mgba.io/i/1730) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 17e1ea360..350aec1f1 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -432,8 +432,18 @@ void PainterGL::draw() { if (!m_active || m_queue.isEmpty()) { return; } + if (m_lagging >= 1) { + return; + } mCoreSync* sync = &m_context->thread()->impl->sync; - mCoreSyncWaitFrameStart(sync); + if (!mCoreSyncWaitFrameStart(sync)) { + mCoreSyncWaitFrameEnd(sync); + ++m_lagging; + if (m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) { + QTimer::singleShot(1, this, &PainterGL::draw); + } + return; + } dequeue(); if (m_videoProxy) { // Only block on the next frame if we're trying to run at roughly 60fps via audio @@ -445,17 +455,16 @@ void PainterGL::draw() { while (m_delayTimer.nsecsElapsed() + 2000000 < 1000000000 / sync->fpsTarget) { QThread::usleep(500); } - m_delayTimer.restart(); } mCoreSyncWaitFrameEnd(sync); - forceDraw(); + performDraw(); + m_backend->swap(m_backend); + m_delayTimer.restart(); } void PainterGL::forceDraw() { - m_painter.begin(m_window.get()); performDraw(); - m_painter.end(); if (!m_context->thread()->impl->sync.audioWait && !m_context->thread()->impl->sync.videoFrameWait) { if (m_delayTimer.elapsed() < 1000 / m_surface->screen()->refreshRate()) { return; @@ -486,10 +495,12 @@ void PainterGL::pause() { } void PainterGL::unpause() { + m_lagging = 0; m_active = true; } void PainterGL::performDraw() { + m_painter.begin(m_window.get()); m_painter.beginNativePainting(); float r = m_surface->devicePixelRatio(); m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); @@ -501,6 +512,7 @@ void PainterGL::performDraw() { if (m_showOSD && m_messagePainter) { m_messagePainter->paint(&m_painter); } + m_painter.end(); } void PainterGL::enqueue(const uint32_t* backing) { @@ -517,6 +529,7 @@ void PainterGL::enqueue(const uint32_t* backing) { memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); } } + m_lagging = 0; m_queue.enqueue(buffer); } @@ -531,6 +544,7 @@ void PainterGL::dequeue() { m_buffer = nullptr; } m_buffer = buffer; + return; } void PainterGL::dequeueAll() { diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index be982b006..5af24e478 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -16,6 +16,7 @@ #endif #endif +#include #include #include #include @@ -130,6 +131,7 @@ private: std::array, 3> m_buffers; QList m_free; QQueue m_queue; + QAtomicInt m_lagging = 0; uint32_t* m_buffer; QPainter m_painter; QMutex m_mutex; From 5bcf243139275654fe879b05c3d931a337c0fe90 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 27 Nov 2020 19:47:47 -0800 Subject: [PATCH 20/20] Qt: Fix build on clang --- src/platform/qt/DisplayGL.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 350aec1f1..9c0da14d5 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include #include #ifdef BUILD_GL