From 2f54fc732e1a89172ad9f6629268a34a58f730d0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 26 Jan 2019 09:45:02 -0800 Subject: [PATCH 001/429] Qt: Fix crash when closing window while game running --- src/platform/qt/Window.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 404bdd5dd..f5df80bd6 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -782,11 +782,13 @@ void Window::gameStopped() { m_screenWidget->setLockAspectRatio(true); m_screenWidget->setPixmap(m_logo); m_screenWidget->unsetCursor(); + if (m_display) { #ifdef M_CORE_GB - m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); + m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); #elif defined(M_CORE_GBA) - m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); #endif + } m_videoLayers->clear(); m_audioChannels->clear(); From 8106c99c2ecd0bdc1d3afc25279f5c6d17511547 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 26 Jan 2019 16:06:06 -0800 Subject: [PATCH 002/429] CHANGES: Update for 0.7.0 --- CHANGES | 192 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/CHANGES b/CHANGES index 4a166e445..c36c57eaf 100644 --- a/CHANGES +++ b/CHANGES @@ -12,7 +12,7 @@ Misc: - Qt: Don't unload ROM immediately if it crashes - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) -0.7.0: (Future) +0.7.0: (2019-01-26) Features: - ELF support - Game Boy Camera support @@ -33,87 +33,87 @@ Features: - GBA: ARMIPS/A22i-style and ELF symbol table support - Initial Switch port Bugfixes: - - GB Audio: Make audio unsigned with bias (fixes mgba.io/i/749) - - GB Serialize: Fix audio state loading - - GB Video: Fix dot clock timing being slightly wrong - - Qt: Fix GL display when loading a game from CLI (fixes mgba.io/i/843) - ARM: Fix MSR when T bit is set - - GB Serialize: Fix game title check - - GB: Revamp IRQ handling based on new information - - GBA Video: Don't mask out high bits of BLDY (fixes mgba.io/i/899) - - GB Video: Fix loading states while in mode 3 - - GBA DMA: Fix invalid DMA reads (fixes mgba.io/i/142) - - GBA Video: Add delay when enabling BGs (fixes mgba.io/i/744, mgba.io/i/752) - - GB Timer: Minor accuracy improvements - - GB Audio: Clock frame events on DIV - - GBA Timer: Fix timers sometimes being late (fixes mgba.io/i/1012) - - GBA Hardware: Fix RTC overriding light sensor (fixes mgba.io/i/1069) - - GBA Savedata: Fix savedata modified time updating when read-only - - GB Video: Fix enabling window when LY > WY (fixes mgba.io/i/409) - - GBA Video: Start timing mid-scanline when skipping BIOS - Core: Fix audio sync breaking when interrupted - - Qt: Improve FPS timer stability - - GBA Serialize: Fix loading channel 3 volume (fixes mgba.io/i/1107) - - GBA SIO: Fix unconnected SIOCNT for multi mode (fixes mgba.io/i/1105) - - GBA BIOS: Fix BitUnPack final byte - - GB I/O: DMA register is R/W - - GB Video: Fix SCX timing - - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1126) - - GB, GBA Savedata: Fix savestate loading overwriting saves on reset - - GBA Video: Make layer disabling work consistently - - GB: Fix IRQ disabling on the same T-cycle as an assert - Core: Fix ordering events when scheduling during events - - GBA: Reset WAITCNT properly - - GBA Serialize: Fix loading states in Hblank - - PSP2: Fix more issues causing poor audio - - GBA Memory: Fix Vast Fame support (taizou) (fixes mgba.io/i/1170) - - GB, GBA Savedata: Fix unmasking savedata crash - - GBA DMA: Fix temporal sorting of DMAs of different priorities - FFmpeg: Fix encoding audio/video queue issues - - GB Serialize: Fix IRQ pending/EI pending confusion - - GB MBC: Improve multicart detection heuristic (fixes mgba.io/i/1177) + - GB: Revamp IRQ handling based on new information + - GB: Fix IRQ disabling on the same T-cycle as an assert + - GB Audio: Make audio unsigned with bias (fixes mgba.io/i/749) + - GB Audio: Clock frame events on DIV - GB Audio: Fix channel 3 reset value - GB Audio: Fix channel 4 initial LFSR - - 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) + - GB I/O: DMA register is R/W + - GB MBC: Improve multicart detection heuristic (fixes mgba.io/i/1177) + - GB, GBA Savedata: Fix savestate loading overwriting saves on reset + - GB, GBA Savedata: Fix unmasking savedata crash + - GB Serialize: Fix audio state loading + - GB Serialize: Fix game title check + - GB Serialize: Fix IRQ pending/EI pending confusion + - GB Timer: Minor accuracy improvements + - GB Video: Fix dot clock timing being slightly wrong + - GB Video: Fix loading states while in mode 3 + - GB Video: Fix enabling window when LY > WY (fixes mgba.io/i/409) + - GB Video: Fix SCX timing + - GB, GBA Video: Don't call finishFrame twice in thread proxy + - GBA: Reset WAITCNT properly + - GBA BIOS: Fix BitUnPack final byte - GBA BIOS: Fix BitUnPack narrowing + - GBA DMA: Fix invalid DMA reads (fixes mgba.io/i/142) + - GBA DMA: Fix temporal sorting of DMAs of different priorities + - GBA Hardware: Fix RTC overriding light sensor (fixes mgba.io/i/1069) + - GBA Hardware: Fix RTC handshake transition (fixes mgba.io/i/1134) + - GBA Memory: Fix Vast Fame support (taizou) (fixes mgba.io/i/1170) + - GBA Savedata: Fix savedata modified time updating when read-only + - GBA Serialize: Fix loading channel 3 volume (fixes mgba.io/i/1107) + - GBA Serialize: Fix loading states in Hblank + - GBA SIO: Fix unconnected SIOCNT for multi mode (fixes mgba.io/i/1105) + - GBA Timer: Fix timers sometimes being late (fixes mgba.io/i/1012) + - GBA Video: Don't mask out high bits of BLDY (fixes mgba.io/i/899) + - GBA Video: Add delay when enabling BGs (fixes mgba.io/i/744, mgba.io/i/752) + - GBA Video: Start timing mid-scanline when skipping BIOS + - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1126) + - GBA Video: Make layer disabling work consistently + - PSP2: Fix more issues causing poor audio + - Qt: Fix GL display when loading a game from CLI (fixes mgba.io/i/843) + - Qt: Improve FPS timer stability + - Util: Fix wrapping edge cases in RingFIFO Misc: - - GBA Timer: Use global cycles for timers - - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) - - All: Make FIXED_ROM_BUFFER an option instead of 3DS-only - - Qt: Redo GameController into multiple classes - - Test: Restructure test suite into multiple executables - - Python: Integrate tests from cinema test suite - - Util: Don't build crc32 if the function already exists - - GBA: Implement display start DMAs - - Qt: Prevent window from being created off-screen - - Qt: Add option to disable FPS display - - GBA: Improve multiboot image detection - - GB MBC: Remove erroneous bank 0 wrapping - - GBA Cheats: Allow multiple ROM patches in the same slot - - GB: Skip BIOS option now works - - Libretro: Add frameskip option - - GBA Memory: 64 MiB GBA Video cartridge support - - PSP2: Use system enter key by default - 3DS: Remove deprecated CSND interface - - Qt: Options to mess around with layer placement - - GBA Savedata: Remove ability to disable realistic timing - - Qt: Add load alternate save option - - GB Audio: Improved audio quality - - GB, GBA Audio: Increase max audio volume - - GB: Fix VRAM/palette locking (fixes mgba.io/i/1109) - - GB Video: Darken colors in GBA mode + - All: Make FIXED_ROM_BUFFER an option instead of 3DS-only + - Core: Remove broken option for whether rewinding restores save games + - Feature: Added loading savestates from command line - FFmpeg: Support libswresample (fixes mgba.io/i/1120, mgba.io/b/123) - FFmpeg: Support lossless h.264 encoding - - Feature: Added loading savestates from command line - - Qt: Allow pausing game at load (fixes mgba.io/i/1129) - - Wii: Move audio handling to callbacks (fixes mgba.io/i/803) - - Qt: Clean up FPS target UI (fixes mgba.io/i/436) - - Core: Remove broken option for whether rewinding restores save games - FFmpeg: Support lossless VP9 encoding + - GBA Cheats: Allow multiple ROM patches in the same slot + - GB: Skip BIOS option now works + - GB: Fix VRAM/palette locking (fixes mgba.io/i/1109) + - GB Audio: Improved audio quality + - GB, GBA Audio: Increase max audio volume + - GB MBC: Remove erroneous bank 0 wrapping + - GB Video: Darken colors in GBA mode + - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) + - GBA: Implement display start DMAs + - GBA: Improve multiboot image detection + - GBA Memory: 64 MiB GBA Video cartridge support + - GBA Savedata: Remove ability to disable realistic timing + - GBA Timer: Use global cycles for timers + - Libretro: Add frameskip option - mGUI: Add fast forward toggle + - PSP2: Use system enter key by default + - Python: Integrate tests from cinema test suite + - Qt: Redo GameController into multiple classes + - Qt: Prevent window from being created off-screen + - Qt: Add option to disable FPS display + - Qt: Options to mess around with layer placement + - Qt: Add load alternate save option + - Qt: Allow pausing game at load (fixes mgba.io/i/1129) + - Qt: Clean up FPS target UI (fixes mgba.io/i/436) + - Test: Restructure test suite into multiple executables + - Util: Don't build crc32 if the function already exists + - Wii: Move audio handling to callbacks (fixes mgba.io/i/803) Changes from beta 1: Features: - Libretro: Add Game Boy cheat support @@ -126,49 +126,49 @@ Features: - Tile viewer now has adjustable width - Python: Experimental audio API Bugfixes: + - 3DS: Fix unused screens not clearing (fixes mgba.io/i/1184) + - Core: Remember to deinit proxy ring FIFO + - Core: Reroot timing list when (de)scheduling + - GB, GBA: Fix broken opposing button filter (fixes mgba.io/i/1191) + - GB MBC: Fix MBC30 SRAM + - GB, GBA Savedata: Fix leaks when loading masked save (fixes mgba.io/i/1197) + - GB Video: Fix SGB border hole size + - GB Video: Changing LYC while LCDC off doesn't affect STAT (fixes mgba.io/i/1224) + - GBA: Fix GB Player features + - GBA I/O: SOUNDCNT_HI is readable when sound is off + - GBA Savedata: Fix EEPROM writing codepath when savetype is not EEPROM + - GBA Video: Fix caching with background toggling (fixes mgba.io/i/1118) + - Libretro: Fix adding codes with hooks - PSP2: Fix audio crackling after fast forward - PSP2: Fix audio crackling when buffer is full - - 3DS: Fix unused screens not clearing (fixes mgba.io/i/1184) - - GBA Video: Fix caching with background toggling (fixes mgba.io/i/1118) - - Wii: Fix drawing caching regression (fixes mgba.io/i/1185) - - Switch: Fix incorrect mapping for fast forward cap - - GB, GBA: Fix broken opposing button filter (fixes mgba.io/i/1191) - Qt: Fix jumbled background when paused - Qt: Fix FPS counter on Windows - - 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 + - Switch: Fix incorrect mapping for fast forward cap + - Wii: Fix drawing caching regression (fixes mgba.io/i/1185) - 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 - - 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 - - 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 - - GB MBC: Fix MBC30 SRAM + - SDL: Fix handling of invalid gamepads (fixes mgba.io/i/1239) Misc: + - CMake: Fix libswresample version dependencies (fixes mgba.io/i/1229) + - Debugger: Minor text fixes + - Debugger: Readability improvements (fixes mgba.io/i/1238) + - GB: Improved SGB2 support + - GB Audio: Skip frame if enabled when clock is high + - Libretro: Reduce rumble callbacks - mGUI: Add SGB border configuration option - mGUI: Add support for different settings types + - Python: Minor API improvements + - Qt: Ensure camera image is valid + - Qt: Debugger console history + - Qt: Detect presence of GL_ARB_framebuffer_object + - Qt: Minor memory view tweaks + - Res: Improve modeling of AGB/AGS screen in shaders - Wii: Define _GNU_SOURCE (fixes mgba.io/i/1106) - Wii: Expose stretch configuration in settings - Wii: Stretch now sets pixel-accurate mode size cap - - Qt: Ensure camera image is valid - - GB: Improved SGB2 support - - Libretro: Reduce rumble callbacks - - Debugger: Minor text fixes - - Qt: Debugger console history - - 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) - - 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 From 2d303cdda314c48a9534fef04782f8ad2bf2ca6a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 26 Jan 2019 22:38:47 -0800 Subject: [PATCH 003/429] GBA Video: Remove redundant checks --- src/gba/renderers/software-obj.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 722df8d83..ad846ace0 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -27,9 +27,6 @@ } \ } \ for (; outX < condition; ++outX, inX += xOffset) { \ - if (!(renderer->row[outX] & FLAG_UNWRITTEN)) { \ - continue; \ - } \ int localX = inX - xOffset * (outX % mosaicH); \ if (localX < 0 || localX > width - 1) { \ continue; \ @@ -43,9 +40,6 @@ unsigned widthMask = ~(width - 1); \ unsigned heightMask = ~(height - 1); \ for (; outX < condition; ++outX, ++inX) { \ - if (!(renderer->row[outX] & FLAG_UNWRITTEN)) { \ - continue; \ - } \ renderer->spriteCyclesRemaining -= 2; \ xAccum += mat.a; \ yAccum += mat.c; \ From 0eaa9e487f94216ea1763cb62b803c43a71141ca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 29 Jan 2019 14:03:09 -0800 Subject: [PATCH 004/429] Switch: Fix final cleanup (fixes #1283) --- CHANGES | 1 + src/platform/switch/main.c | 89 ++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/CHANGES b/CHANGES index c36c57eaf..6bf25a7a1 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,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) + - Switch: Fix final cleanup (fixes mgba.io/i/1283) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index a6e8d9941..e344ff44d 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -100,63 +100,64 @@ static enum ScreenMode { } screenMode = SM_PA; static bool initEgl() { - s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (!s_display) { - goto _fail0; - } + s_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!s_display) { + goto _fail0; + } - eglInitialize(s_display, NULL, NULL); + eglInitialize(s_display, NULL, NULL); - EGLConfig config; - EGLint numConfigs; - static const EGLint attributeList[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, - EGL_NONE - }; - eglChooseConfig(s_display, attributeList, &config, 1, &numConfigs); - if (!numConfigs) { - goto _fail1; - } + EGLConfig config; + EGLint numConfigs; + static const EGLint attributeList[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_NONE + }; + eglChooseConfig(s_display, attributeList, &config, 1, &numConfigs); + if (!numConfigs) { + goto _fail1; + } - s_surface = eglCreateWindowSurface(s_display, config, nwindowGetDefault(), NULL); - if (!s_surface) { - goto _fail1; - } + s_surface = eglCreateWindowSurface(s_display, config, nwindowGetDefault(), NULL); + if (!s_surface) { + goto _fail1; + } EGLint contextAttributeList[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; - s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, contextAttributeList); - if (!s_context) { - goto _fail2; - } + s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, contextAttributeList); + if (!s_context) { + goto _fail2; + } - eglMakeCurrent(s_display, s_surface, s_surface, s_context); - return true; + eglMakeCurrent(s_display, s_surface, s_surface, s_context); + return true; _fail2: - eglDestroySurface(s_display, s_surface); - s_surface = NULL; + eglDestroySurface(s_display, s_surface); + s_surface = NULL; _fail1: - eglTerminate(s_display); - s_display = NULL; + eglTerminate(s_display); + s_display = NULL; _fail0: - return false; + return false; } static void deinitEgl() { - if (s_display) { - if (s_context) { - eglDestroyContext(s_display, s_context); - } - if (s_surface) { - eglDestroySurface(s_display, s_surface); - } - eglTerminate(s_display); - } + if (s_display) { + eglMakeCurrent(s_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (s_context) { + eglDestroyContext(s_display, s_context); + } + if (s_surface) { + eglDestroySurface(s_display, s_surface); + } + eglTerminate(s_display); + } } static void _mapKey(struct mInputMap* map, uint32_t binding, int nativeKey, enum GBAKey key) { @@ -726,8 +727,14 @@ int main(int argc, char* argv[]) { mGUIRunloop(&runner); } + mGUIDeinit(&runner); + + audoutStopAudioOut(); + GUIFontDestroy(font); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteBuffers(1, &pbo); glDeleteTextures(1, &tex); From 0c9802e4da83f8f82bfba7576eaf644aa1b1f25f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 31 Jan 2019 22:52:27 -0800 Subject: [PATCH 005/429] Debugger: Revamp breakpoint/watchpoint API, add listing --- CHANGES | 1 + include/mgba/debugger/debugger.h | 39 +++- include/mgba/internal/arm/debugger/debugger.h | 22 +- .../mgba/internal/lr35902/debugger/debugger.h | 24 +- src/arm/debugger/debugger.c | 212 ++++++++++-------- src/arm/debugger/memory-debugger.c | 6 +- src/debugger/cli-debugger.c | 128 ++++++----- src/debugger/debugger.c | 3 + src/debugger/gdb-stub.c | 47 +++- src/lr35902/debugger/debugger.c | 148 ++++++------ src/lr35902/debugger/memory-debugger.c | 6 +- 11 files changed, 361 insertions(+), 275 deletions(-) diff --git a/CHANGES b/CHANGES index 6bf25a7a1..036e2bf4b 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Misc: - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) + - Debugger: Add breakpoint and watchpoint listing 0.7.0: (2019-01-26) Features: diff --git a/include/mgba/debugger/debugger.h b/include/mgba/debugger/debugger.h index 8de7d4c00..108df77e7 100644 --- a/include/mgba/debugger/debugger.h +++ b/include/mgba/debugger/debugger.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017 Jeffrey Pfau +/* Copyright (c) 2013-2019 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 @@ -12,6 +12,7 @@ CXX_GUARD_START #include #include +#include mLOG_DECLARE_CATEGORY(DEBUGGER); @@ -36,7 +37,8 @@ enum mDebuggerState { enum mWatchpointType { WATCHPOINT_WRITE = 1, WATCHPOINT_READ = 2, - WATCHPOINT_RW = 3 + WATCHPOINT_RW = 3, + WATCHPOINT_WRITE_CHANGE = 4, }; enum mBreakpointType { @@ -69,6 +71,25 @@ struct mDebuggerEntryInfo { } type; }; +struct mBreakpoint { + ssize_t id; + uint32_t address; + int segment; + enum mBreakpointType type; + struct ParseTree* condition; +}; + +struct mWatchpoint { + ssize_t id; + uint32_t address; + int segment; + enum mWatchpointType type; + struct ParseTree* condition; +}; + +DECLARE_VECTOR(mBreakpointList, struct mBreakpoint); +DECLARE_VECTOR(mWatchpointList, struct mWatchpoint); + struct mDebugger; struct ParseTree; struct mDebuggerPlatform { @@ -79,13 +100,15 @@ struct mDebuggerPlatform { void (*entered)(struct mDebuggerPlatform*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); bool (*hasBreakpoints)(struct mDebuggerPlatform*); - void (*setBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment); - void (*setConditionalBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment, struct ParseTree* condition); - void (*clearBreakpoint)(struct mDebuggerPlatform*, uint32_t address, int segment); - void (*setWatchpoint)(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type); - void (*setConditionalWatchpoint)(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type, struct ParseTree* condition); - void (*clearWatchpoint)(struct mDebuggerPlatform*, uint32_t address, int segment); void (*checkBreakpoints)(struct mDebuggerPlatform*); + bool (*clearBreakpoint)(struct mDebuggerPlatform*, ssize_t id); + + ssize_t (*setBreakpoint)(struct mDebuggerPlatform*, const struct mBreakpoint*); + void (*listBreakpoints)(struct mDebuggerPlatform*, struct mBreakpointList*); + + ssize_t (*setWatchpoint)(struct mDebuggerPlatform*, const struct mWatchpoint*); + void (*listWatchpoints)(struct mDebuggerPlatform*, struct mWatchpointList*); + void (*trace)(struct mDebuggerPlatform*, char* out, size_t* length); bool (*getRegister)(struct mDebuggerPlatform*, const char* name, int32_t* value); diff --git a/include/mgba/internal/arm/debugger/debugger.h b/include/mgba/internal/arm/debugger/debugger.h index 5c1852243..5dc73485c 100644 --- a/include/mgba/internal/arm/debugger/debugger.h +++ b/include/mgba/internal/arm/debugger/debugger.h @@ -17,23 +17,14 @@ CXX_GUARD_START struct ParseTree; struct ARMDebugBreakpoint { - uint32_t address; - struct ParseTree* condition; - bool isSw; + struct mBreakpoint d; struct { uint32_t opcode; enum ExecutionMode mode; } sw; }; -struct ARMDebugWatchpoint { - uint32_t address; - enum mWatchpointType type; - struct ParseTree* condition; -}; - DECLARE_VECTOR(ARMDebugBreakpointList, struct ARMDebugBreakpoint); -DECLARE_VECTOR(ARMDebugWatchpointList, struct ARMDebugWatchpoint); struct ARMDebugger { struct mDebuggerPlatform d; @@ -41,18 +32,19 @@ struct ARMDebugger { struct ARMDebugBreakpointList breakpoints; struct ARMDebugBreakpointList swBreakpoints; - struct ARMDebugWatchpointList watchpoints; + struct mWatchpointList watchpoints; struct ARMMemory originalMemory; + ssize_t nextId; + void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); - bool (*setSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); - bool (*clearSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t opcode); + ssize_t (*setSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); + void (*clearSoftwareBreakpoint)(struct ARMDebugger*, const struct ARMDebugBreakpoint*); }; struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void); -bool ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* debugger, uint32_t address, enum ExecutionMode mode); -void ARMDebuggerClearSoftwareBreakpoint(struct mDebuggerPlatform* debugger, uint32_t address); +ssize_t ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* debugger, uint32_t address, enum ExecutionMode mode); CXX_GUARD_END diff --git a/include/mgba/internal/lr35902/debugger/debugger.h b/include/mgba/internal/lr35902/debugger/debugger.h index 6b66c715a..1114c5c1a 100644 --- a/include/mgba/internal/lr35902/debugger/debugger.h +++ b/include/mgba/internal/lr35902/debugger/debugger.h @@ -13,21 +13,6 @@ CXX_GUARD_START #include #include -#include - -struct ParseTree; -struct LR35902DebugBreakpoint { - uint16_t address; - int segment; - struct ParseTree* condition; -}; - -struct LR35902DebugWatchpoint { - uint16_t address; - int segment; - enum mWatchpointType type; - struct ParseTree* condition; -}; struct LR35902Segment { uint16_t start; @@ -35,17 +20,16 @@ struct LR35902Segment { const char* name; }; -DECLARE_VECTOR(LR35902DebugBreakpointList, struct LR35902DebugBreakpoint); -DECLARE_VECTOR(LR35902DebugWatchpointList, struct LR35902DebugWatchpoint); - struct LR35902Debugger { struct mDebuggerPlatform d; struct LR35902Core* cpu; - struct LR35902DebugBreakpointList breakpoints; - struct LR35902DebugWatchpointList watchpoints; + struct mBreakpointList breakpoints; + struct mWatchpointList watchpoints; struct LR35902Memory originalMemory; + ssize_t nextId; + const struct LR35902Segment* segments; }; diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index 292b98c87..1feaa2df6 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -13,12 +13,11 @@ #include DEFINE_VECTOR(ARMDebugBreakpointList, struct ARMDebugBreakpoint); -DEFINE_VECTOR(ARMDebugWatchpointList, struct ARMDebugWatchpoint); static struct ARMDebugBreakpoint* _lookupBreakpoint(struct ARMDebugBreakpointList* breakpoints, uint32_t address) { size_t i; for (i = 0; i < ARMDebugBreakpointListSize(breakpoints); ++i) { - if (ARMDebugBreakpointListGetPointer(breakpoints, i)->address == address) { + if (ARMDebugBreakpointListGetPointer(breakpoints, i)->d.address == address) { return ARMDebugBreakpointListGetPointer(breakpoints, i); } } @@ -26,13 +25,13 @@ static struct ARMDebugBreakpoint* _lookupBreakpoint(struct ARMDebugBreakpointLis } static void _destroyBreakpoint(struct ARMDebugBreakpoint* breakpoint) { - if (breakpoint->condition) { - parseFree(breakpoint->condition); - free(breakpoint->condition); + if (breakpoint->d.condition) { + parseFree(breakpoint->d.condition); + free(breakpoint->d.condition); } } -static void _destroyWatchpoint(struct ARMDebugWatchpoint* watchpoint) { +static void _destroyWatchpoint(struct mWatchpoint* watchpoint) { if (watchpoint->condition) { parseFree(watchpoint->condition); free(watchpoint->condition); @@ -52,15 +51,15 @@ static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { if (!breakpoint) { return; } - if (breakpoint->condition) { + if (breakpoint->d.condition) { int32_t value; int segment; - if (!mDebuggerEvaluateParseTree(d->p, breakpoint->condition, &value, &segment) || !(value || segment >= 0)) { + if (!mDebuggerEvaluateParseTree(d->p, breakpoint->d.condition, &value, &segment) || !(value || segment >= 0)) { return; } } struct mDebuggerEntryInfo info = { - .address = breakpoint->address, + .address = breakpoint->d.address, .type.bp.breakType = BREAKPOINT_HARDWARE }; mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info); @@ -71,12 +70,11 @@ static void ARMDebuggerDeinit(struct mDebuggerPlatform* platform); static void ARMDebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info); -static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment); -static void ARMDebuggerSetConditionalBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment, struct ParseTree* condition); -static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment); -static void ARMDebuggerSetWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type); -static void ARMDebuggerSetConditionalWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type, struct ParseTree* condition); -static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment); +static ssize_t ARMDebuggerSetBreakpoint(struct mDebuggerPlatform*, const struct mBreakpoint*); +static bool ARMDebuggerClearBreakpoint(struct mDebuggerPlatform*, ssize_t id); +static void ARMDebuggerListBreakpoints(struct mDebuggerPlatform*, struct mBreakpointList*); +static ssize_t ARMDebuggerSetWatchpoint(struct mDebuggerPlatform*, const struct mWatchpoint*); +static void ARMDebuggerListWatchpoints(struct mDebuggerPlatform*, struct mWatchpointList*); static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform*); static bool ARMDebuggerHasBreakpoints(struct mDebuggerPlatform*); static void ARMDebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length); @@ -89,11 +87,10 @@ struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void) { platform->init = ARMDebuggerInit; platform->deinit = ARMDebuggerDeinit; platform->setBreakpoint = ARMDebuggerSetBreakpoint; - platform->setConditionalBreakpoint = ARMDebuggerSetConditionalBreakpoint; + platform->listBreakpoints = ARMDebuggerListBreakpoints; platform->clearBreakpoint = ARMDebuggerClearBreakpoint; platform->setWatchpoint = ARMDebuggerSetWatchpoint; - platform->setConditionalWatchpoint = ARMDebuggerSetConditionalWatchpoint; - platform->clearWatchpoint = ARMDebuggerClearWatchpoint; + platform->listWatchpoints = ARMDebuggerListWatchpoints; platform->checkBreakpoints = ARMDebuggerCheckBreakpoints; platform->hasBreakpoints = ARMDebuggerHasBreakpoints; platform->trace = ARMDebuggerTrace; @@ -106,9 +103,10 @@ void ARMDebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { struct ARMDebugger* debugger = (struct ARMDebugger*) platform; debugger->cpu = cpu; debugger->originalMemory = debugger->cpu->memory; + debugger->nextId = 1; ARMDebugBreakpointListInit(&debugger->breakpoints, 0); ARMDebugBreakpointListInit(&debugger->swBreakpoints, 0); - ARMDebugWatchpointListInit(&debugger->watchpoints, 0); + mWatchpointListInit(&debugger->watchpoints, 0); } void ARMDebuggerDeinit(struct mDebuggerPlatform* platform) { @@ -118,7 +116,7 @@ void ARMDebuggerDeinit(struct mDebuggerPlatform* platform) { size_t b; for (b = ARMDebugBreakpointListSize(&debugger->swBreakpoints); b; --b) { struct ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListGetPointer(&debugger->swBreakpoints, b - 1); - debugger->clearSoftwareBreakpoint(debugger, breakpoint->address, breakpoint->sw.mode, breakpoint->sw.opcode); + debugger->clearSoftwareBreakpoint(debugger, breakpoint); } } ARMDebuggerRemoveMemoryShim(debugger); @@ -129,11 +127,11 @@ void ARMDebuggerDeinit(struct mDebuggerPlatform* platform) { } ARMDebugBreakpointListDeinit(&debugger->breakpoints); - for (i = 0; i < ARMDebugWatchpointListSize(&debugger->watchpoints); ++i) { - _destroyWatchpoint(ARMDebugWatchpointListGetPointer(&debugger->watchpoints, i)); + for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { + _destroyWatchpoint(mWatchpointListGetPointer(&debugger->watchpoints, i)); } ARMDebugBreakpointListDeinit(&debugger->swBreakpoints); - ARMDebugWatchpointListDeinit(&debugger->watchpoints); + mWatchpointListDeinit(&debugger->watchpoints); } static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { @@ -142,16 +140,16 @@ static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerE cpu->nextEvent = cpu->cycles; if (reason == DEBUGGER_ENTER_BREAKPOINT) { struct ARMDebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->swBreakpoints, _ARMPCAddress(cpu)); - if (breakpoint && breakpoint->isSw) { - info->address = breakpoint->address; + if (breakpoint && breakpoint->d.type == BREAKPOINT_SOFTWARE) { + info->address = breakpoint->d.address; if (debugger->clearSoftwareBreakpoint) { - debugger->clearSoftwareBreakpoint(debugger, breakpoint->address, breakpoint->sw.mode, breakpoint->sw.opcode); + debugger->clearSoftwareBreakpoint(debugger, breakpoint); } ARMRunFake(cpu, breakpoint->sw.opcode); if (debugger->setSoftwareBreakpoint) { - debugger->setSoftwareBreakpoint(debugger, breakpoint->address, breakpoint->sw.mode, &breakpoint->sw.opcode); + debugger->setSoftwareBreakpoint(debugger, breakpoint->d.address, breakpoint->sw.mode, &breakpoint->sw.opcode); } } } @@ -160,105 +158,135 @@ static void ARMDebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerE } } -bool ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* d, uint32_t address, enum ExecutionMode mode) { +ssize_t ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* d, uint32_t address, enum ExecutionMode mode) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; uint32_t opcode; if (!debugger->setSoftwareBreakpoint || !debugger->setSoftwareBreakpoint(debugger, address, mode, &opcode)) { - return false; + return -1; } struct ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListAppend(&debugger->swBreakpoints); - breakpoint->address = address; - breakpoint->isSw = true; + ssize_t id = debugger->nextId; + ++debugger->nextId; + breakpoint->d.id = id; + breakpoint->d.address = address; + breakpoint->d.segment = -1; + breakpoint->d.condition = NULL; + breakpoint->d.type = BREAKPOINT_SOFTWARE; breakpoint->sw.opcode = opcode; breakpoint->sw.mode = mode; - return true; + return id; } -void ARMDebuggerClearSoftwareBreakpoint(struct mDebuggerPlatform* d, uint32_t address) { - struct ARMDebugger* debugger = (struct ARMDebugger*) d; - if (!debugger->clearSoftwareBreakpoint) { - return; - } - - struct ARMDebugBreakpoint* breakpoint = NULL; - // Clear the stack backwards in case any overlap - size_t b; - for (b = ARMDebugBreakpointListSize(&debugger->swBreakpoints); b; --b) { - breakpoint = ARMDebugBreakpointListGetPointer(&debugger->swBreakpoints, b - 1); - if (breakpoint->address == address) { - break; - } - breakpoint = NULL; - } - - if (breakpoint) { - debugger->clearSoftwareBreakpoint(debugger, address, breakpoint->sw.mode, breakpoint->sw.opcode); - } -} - -static void ARMDebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { - ARMDebuggerSetConditionalBreakpoint(d, address, segment, NULL); -} - -static void ARMDebuggerSetConditionalBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, struct ParseTree* condition) { - UNUSED(segment); +static ssize_t ARMDebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struct mBreakpoint* info) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; struct ARMDebugBreakpoint* breakpoint = ARMDebugBreakpointListAppend(&debugger->breakpoints); - breakpoint->condition = condition; - breakpoint->address = address; - breakpoint->isSw = false; + ssize_t id = debugger->nextId; + ++debugger->nextId; + breakpoint->d = *info; + breakpoint->d.id = id; + if (info->type == BREAKPOINT_SOFTWARE) { + // TODO + abort(); + } + return id; } -static void ARMDebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { - UNUSED(segment); +static bool ARMDebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; - struct ARMDebugBreakpointList* breakpoints = &debugger->breakpoints; size_t i; + + struct ARMDebugBreakpointList* breakpoints = &debugger->breakpoints; for (i = 0; i < ARMDebugBreakpointListSize(breakpoints); ++i) { - if (ARMDebugBreakpointListGetPointer(breakpoints, i)->address == address) { + if (ARMDebugBreakpointListGetPointer(breakpoints, i)->d.id == id) { _destroyBreakpoint(ARMDebugBreakpointListGetPointer(breakpoints, i)); ARMDebugBreakpointListShift(breakpoints, i, 1); + return true; + } + } + + struct ARMDebugBreakpointList* swBreakpoints = &debugger->swBreakpoints; + if (debugger->clearSoftwareBreakpoint) { + for (i = 0; i < ARMDebugBreakpointListSize(swBreakpoints); ++i) { + if (ARMDebugBreakpointListGetPointer(swBreakpoints, i)->d.id == id) { + debugger->clearSoftwareBreakpoint(debugger, ARMDebugBreakpointListGetPointer(swBreakpoints, i)); + ARMDebugBreakpointListShift(swBreakpoints, i, 1); + return true; + } + } + } + + struct mWatchpointList* watchpoints = &debugger->watchpoints; + for (i = 0; i < mWatchpointListSize(watchpoints); ++i) { + if (mWatchpointListGetPointer(watchpoints, i)->id == id) { + _destroyWatchpoint(mWatchpointListGetPointer(watchpoints, i)); + mWatchpointListShift(watchpoints, i, 1); + if (!mWatchpointListSize(&debugger->watchpoints)) { + ARMDebuggerRemoveMemoryShim(debugger); + } + return true; + } + } + return false; +} + +static void ARMDebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) { + struct ARMDebugger* debugger = (struct ARMDebugger*) d; + mBreakpointListClear(list); + size_t i, s; + for (i = 0, s = 0; i < ARMDebugBreakpointListSize(&debugger->breakpoints) || s < ARMDebugBreakpointListSize(&debugger->swBreakpoints);) { + struct ARMDebugBreakpoint* hw = NULL; + struct ARMDebugBreakpoint* sw = NULL; + if (i < ARMDebugBreakpointListSize(&debugger->breakpoints)) { + hw = ARMDebugBreakpointListGetPointer(&debugger->breakpoints, i); + } + if (s < ARMDebugBreakpointListSize(&debugger->swBreakpoints)) { + sw = ARMDebugBreakpointListGetPointer(&debugger->swBreakpoints, s); + } + struct mBreakpoint* b = mBreakpointListAppend(list); + if (hw && sw) { + if (hw->d.id < sw->d.id) { + *b = hw->d; + ++i; + } else { + *b = sw->d; + ++s; + } + } else if (hw) { + *b = hw->d; + ++i; + } else if (sw) { + *b = sw->d; + ++s; + } else { + abort(); // Should be unreachable } } } static bool ARMDebuggerHasBreakpoints(struct mDebuggerPlatform* d) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; - return ARMDebugBreakpointListSize(&debugger->breakpoints) || ARMDebugWatchpointListSize(&debugger->watchpoints); + return ARMDebugBreakpointListSize(&debugger->breakpoints) || mWatchpointListSize(&debugger->watchpoints); } -static void ARMDebuggerSetWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, enum mWatchpointType type) { - ARMDebuggerSetConditionalWatchpoint(d, address, segment, type, NULL); -} - -static void ARMDebuggerSetConditionalWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, enum mWatchpointType type, struct ParseTree* condition) { - UNUSED(segment); +static ssize_t ARMDebuggerSetWatchpoint(struct mDebuggerPlatform* d, const struct mWatchpoint* info) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; - if (!ARMDebugWatchpointListSize(&debugger->watchpoints)) { + if (!mWatchpointListSize(&debugger->watchpoints)) { ARMDebuggerInstallMemoryShim(debugger); } - struct ARMDebugWatchpoint* watchpoint = ARMDebugWatchpointListAppend(&debugger->watchpoints); - watchpoint->address = address; - watchpoint->type = type; - watchpoint->condition = condition; + struct mWatchpoint* watchpoint = mWatchpointListAppend(&debugger->watchpoints); + ssize_t id = debugger->nextId; + ++debugger->nextId; + *watchpoint = *info; + watchpoint->id = id; + return id; } -static void ARMDebuggerClearWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { - UNUSED(segment); +static void ARMDebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) { struct ARMDebugger* debugger = (struct ARMDebugger*) d; - struct ARMDebugWatchpointList* watchpoints = &debugger->watchpoints; - size_t i; - for (i = 0; i < ARMDebugWatchpointListSize(watchpoints); ++i) { - if (ARMDebugWatchpointListGetPointer(watchpoints, i)->address == address) { - _destroyWatchpoint(ARMDebugWatchpointListGetPointer(watchpoints, i)); - ARMDebugWatchpointListShift(watchpoints, i, 1); - } - } - if (!ARMDebugWatchpointListSize(&debugger->watchpoints)) { - ARMDebuggerRemoveMemoryShim(debugger); - } + mWatchpointListClear(list); + mWatchpointListCopy(list, &debugger->watchpoints); } static void ARMDebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* length) { diff --git a/src/arm/debugger/memory-debugger.c b/src/arm/debugger/memory-debugger.c index 2faca99a6..db3e4f8a6 100644 --- a/src/arm/debugger/memory-debugger.c +++ b/src/arm/debugger/memory-debugger.c @@ -93,10 +93,10 @@ CREATE_SHIM(setActiveRegion, void, (struct ARMCore* cpu, uint32_t address), addr static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint32_t newValue, int width) { --width; - struct ARMDebugWatchpoint* watchpoint; + struct mWatchpoint* watchpoint; size_t i; - for (i = 0; i < ARMDebugWatchpointListSize(&debugger->watchpoints); ++i) { - watchpoint = ARMDebugWatchpointListGetPointer(&debugger->watchpoints, i); + for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { + watchpoint = mWatchpointListGetPointer(&debugger->watchpoints, i); if (!((watchpoint->address ^ address) & ~width) && watchpoint->type & type) { if (watchpoint->condition) { int32_t value; diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index e4ff8ab5b..e77e317ce 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -46,9 +46,12 @@ static void _readHalfword(struct CLIDebugger*, struct CLIDebugVector*); static void _readWord(struct CLIDebugger*, struct CLIDebugVector*); static void _setBreakpoint(struct CLIDebugger*, struct CLIDebugVector*); static void _clearBreakpoint(struct CLIDebugger*, struct CLIDebugVector*); -static void _setWatchpoint(struct CLIDebugger*, struct CLIDebugVector*); +static void _listBreakpoints(struct CLIDebugger*, struct CLIDebugVector*); +static void _setReadWriteWatchpoint(struct CLIDebugger*, struct CLIDebugVector*); static void _setReadWatchpoint(struct CLIDebugger*, struct CLIDebugVector*); static void _setWriteWatchpoint(struct CLIDebugger*, struct CLIDebugVector*); +static void _setWriteChangedWatchpoint(struct CLIDebugger*, struct CLIDebugVector*); +static void _listWatchpoints(struct CLIDebugger*, struct CLIDebugVector*); static void _trace(struct CLIDebugger*, struct CLIDebugVector*); static void _writeByte(struct CLIDebugger*, struct CLIDebugVector*); static void _writeHalfword(struct CLIDebugger*, struct CLIDebugVector*); @@ -75,6 +78,10 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "help", _printHelp, "S", "Print help" }, { "i", _printStatus, "", "Print the current status" }, { "info", _printStatus, "", "Print the current status" }, + { "lb", _listBreakpoints, "", "List breakpoints" }, + { "listb", _listBreakpoints, "", "List breakpoints" }, + { "lw", _listWatchpoints, "", "List watchpoints" }, + { "listw", _listWatchpoints, "", "List watchpoints" }, { "n", _next, "", "Execute next instruction" }, { "next", _next, "", "Execute next instruction" }, { "p", _print, "I", "Print a value" }, @@ -91,12 +98,13 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "r/4", _readWord, "I", "Read a word from a specified offset" }, { "status", _printStatus, "", "Print the current status" }, { "trace", _trace, "I", "Trace a fixed number of instructions" }, - { "w", _setWatchpoint, "Is", "Set a watchpoint" }, + { "w", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, { "w/r", _writeRegister, "SI", "Write a register" }, { "w/4", _writeWord, "II", "Write a word at a specified offset" }, - { "watch", _setWatchpoint, "Is", "Set a watchpoint" }, + { "watch", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, + { "watch/c", _setWriteChangedWatchpoint, "Is", "Set a change watchpoint" }, { "watch/r", _setReadWatchpoint, "Is", "Set a read watchpoint" }, { "watch/w", _setWriteWatchpoint, "Is", "Set a write watchpoint" }, { "x/1", _dumpByte, "Ii", "Examine bytes at a specified offset" }, @@ -488,20 +496,24 @@ static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS); return; } - uint32_t address = dv->intValue; + struct mBreakpoint breakpoint = { + .address = dv->intValue, + .segment = dv->segmentValue, + .type = BREAKPOINT_HARDWARE + }; if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { struct ParseTree* tree = _parseTree(dv->next->charValue); if (tree) { - debugger->d.platform->setConditionalBreakpoint(debugger->d.platform, address, dv->segmentValue, tree); + breakpoint.condition = tree; } else { debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS); + return; } - } else { - debugger->d.platform->setBreakpoint(debugger->d.platform, address, dv->segmentValue); } + debugger->d.platform->setBreakpoint(debugger->d.platform, &breakpoint); } -static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { +static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv, enum mWatchpointType type) { if (!dv || dv->type != CLIDV_INT_TYPE) { debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS); return; @@ -510,72 +522,80 @@ static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* debugger->backend->printf(debugger->backend, "Watchpoints are not supported by this platform.\n"); return; } - uint32_t address = dv->intValue; + struct mWatchpoint watchpoint = { + .address = dv->intValue, + .segment = dv->segmentValue, + .type = type + }; if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { struct ParseTree* tree = _parseTree(dv->next->charValue); if (tree) { - debugger->d.platform->setConditionalWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_RW, tree); + watchpoint.condition = tree; } else { debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS); + return; } - } else { - debugger->d.platform->setWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_RW); } + debugger->d.platform->setWatchpoint(debugger->d.platform, &watchpoint); +} + +static void _setReadWriteWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + _setWatchpoint(debugger, dv, WATCHPOINT_RW); } static void _setReadWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { - if (!dv || dv->type != CLIDV_INT_TYPE) { - debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS); - return; - } - if (!debugger->d.platform->setWatchpoint) { - debugger->backend->printf(debugger->backend, "Watchpoints are not supported by this platform.\n"); - return; - } - uint32_t address = dv->intValue; - if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { - struct ParseTree* tree = _parseTree(dv->next->charValue); - if (tree) { - debugger->d.platform->setConditionalWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_READ, tree); - } else { - debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS); - } - } else { - debugger->d.platform->setWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_READ); - } + _setWatchpoint(debugger, dv, WATCHPOINT_READ); } static void _setWriteWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { - if (!dv || dv->type != CLIDV_INT_TYPE) { - debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS); - return; - } - if (!debugger->d.platform->setWatchpoint) { - debugger->backend->printf(debugger->backend, "Watchpoints are not supported by this platform.\n"); - return; - } - uint32_t address = dv->intValue; - if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { - struct ParseTree* tree = _parseTree(dv->next->charValue); - if (tree) { - debugger->d.platform->setConditionalWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_WRITE, tree); - } else { - debugger->backend->printf(debugger->backend, "%s\n", ERROR_INVALID_ARGS); - } - } else { - debugger->d.platform->setWatchpoint(debugger->d.platform, address, dv->segmentValue, WATCHPOINT_WRITE); - }} + _setWatchpoint(debugger, dv, WATCHPOINT_WRITE); +} + +static void _setWriteChangedWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + _setWatchpoint(debugger, dv, WATCHPOINT_WRITE_CHANGE); +} static void _clearBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { if (!dv || dv->type != CLIDV_INT_TYPE) { debugger->backend->printf(debugger->backend, "%s\n", ERROR_MISSING_ARGS); return; } - uint32_t address = dv->intValue; - debugger->d.platform->clearBreakpoint(debugger->d.platform, address, dv->segmentValue); - if (debugger->d.platform->clearWatchpoint) { - debugger->d.platform->clearWatchpoint(debugger->d.platform, address, dv->segmentValue); + uint64_t id = dv->intValue; + debugger->d.platform->clearBreakpoint(debugger->d.platform, id); +} + +static void _listBreakpoints(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + UNUSED(dv); + struct mBreakpointList breakpoints; + mBreakpointListInit(&breakpoints, 0); + debugger->d.platform->listBreakpoints(debugger->d.platform, &breakpoints); + size_t i; + for (i = 0; i < mBreakpointListSize(&breakpoints); ++i) { + struct mBreakpoint* breakpoint = mBreakpointListGetPointer(&breakpoints, i); + if (breakpoint->segment >= 0) { + debugger->backend->printf(debugger->backend, "%" PRIz "i: %02X:%X\n", breakpoint->id, breakpoint->segment, breakpoint->address); + } else { + debugger->backend->printf(debugger->backend, "%" PRIz "i: 0x%X\n", breakpoint->id, breakpoint->address); + } } + mBreakpointListDeinit(&breakpoints); +} + +static void _listWatchpoints(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + UNUSED(dv); + struct mWatchpointList watchpoints; + mWatchpointListInit(&watchpoints, 0); + debugger->d.platform->listWatchpoints(debugger->d.platform, &watchpoints); + size_t i; + for (i = 0; i < mWatchpointListSize(&watchpoints); ++i) { + struct mWatchpoint* watchpoint = mWatchpointListGetPointer(&watchpoints, i); + if (watchpoint->segment >= 0) { + debugger->backend->printf(debugger->backend, "%" PRIz "i: %02X:%X\n", watchpoint->id, watchpoint->segment, watchpoint->address); + } else { + debugger->backend->printf(debugger->backend, "%" PRIz "i: 0x%X\n", watchpoint->id, watchpoint->address); + } + } + mWatchpointListDeinit(&watchpoints); } static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index 14e4d101c..1ba186f52 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -22,6 +22,9 @@ const uint32_t DEBUGGER_ID = 0xDEADBEEF; mLOG_DEFINE_CATEGORY(DEBUGGER, "Debugger", "core.debugger"); +DEFINE_VECTOR(mBreakpointList, struct mBreakpoint); +DEFINE_VECTOR(mWatchpointList, struct mWatchpoint); + static void mDebuggerInit(void* cpu, struct mCPUComponent* component); static void mDebuggerDeinit(struct mCPUComponent* component); diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index f5b5218d5..8a072f1e4 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -62,6 +62,8 @@ static void _gdbStubEntered(struct mDebugger* debugger, enum mDebuggerEntryReaso } return; } + // Fall through + case WATCHPOINT_WRITE_CHANGE: type = "watch"; break; case WATCHPOINT_READ: @@ -488,21 +490,32 @@ static void _setBreakpoint(struct GDBStub* stub, const char* message) { readAddress += i + 1; uint32_t kind = _readHex(readAddress, &i); + struct mBreakpoint breakpoint = { + .address = address, + .type = BREAKPOINT_HARDWARE + }; + struct mWatchpoint watchpoint = { + .address = address + }; + switch (message[0]) { case '0': ARMDebuggerSetSoftwareBreakpoint(stub->d.platform, address, kind == 2 ? MODE_THUMB : MODE_ARM); break; case '1': - stub->d.platform->setBreakpoint(stub->d.platform, address, -1); + stub->d.platform->setBreakpoint(stub->d.platform, &breakpoint); break; case '2': - stub->d.platform->setWatchpoint(stub->d.platform, address, -1, WATCHPOINT_WRITE); + watchpoint.type = WATCHPOINT_WRITE_CHANGE; + stub->d.platform->setWatchpoint(stub->d.platform, &watchpoint); break; case '3': - stub->d.platform->setWatchpoint(stub->d.platform, address, -1, WATCHPOINT_READ); + watchpoint.type = WATCHPOINT_READ; + stub->d.platform->setWatchpoint(stub->d.platform, &watchpoint); break; case '4': - stub->d.platform->setWatchpoint(stub->d.platform, address, -1, WATCHPOINT_RW); + watchpoint.type = WATCHPOINT_RW; + stub->d.platform->setWatchpoint(stub->d.platform, &watchpoint); break; default: stub->outgoing[0] = '\0'; @@ -517,17 +530,35 @@ static void _clearBreakpoint(struct GDBStub* stub, const char* message) { const char* readAddress = &message[2]; unsigned i = 0; uint32_t address = _readHex(readAddress, &i); + struct mBreakpointList breakpoints; + struct mWatchpointList watchpoints; + + size_t index; switch (message[0]) { case '0': - ARMDebuggerClearSoftwareBreakpoint(stub->d.platform, address); - break; case '1': - stub->d.platform->clearBreakpoint(stub->d.platform, address, -1); + mBreakpointListInit(&breakpoints, 0); + stub->d.platform->listBreakpoints(stub->d.platform, &breakpoints); + for (index = 0; index < mBreakpointListSize(&breakpoints); ++index) { + if (mBreakpointListGetPointer(&breakpoints, index)->address != address) { + continue; + } + stub->d.platform->clearBreakpoint(stub->d.platform, mBreakpointListGetPointer(&breakpoints, index)->id); + } + mBreakpointListDeinit(&breakpoints); break; case '2': case '3': case '4': - stub->d.platform->clearWatchpoint(stub->d.platform, address, -1); + mWatchpointListInit(&watchpoints, 0); + stub->d.platform->listWatchpoints(stub->d.platform, &watchpoints); + for (index = 0; index < mWatchpointListSize(&watchpoints); ++index) { + if (mWatchpointListGetPointer(&watchpoints, index)->address != address) { + continue; + } + stub->d.platform->clearBreakpoint(stub->d.platform, mWatchpointListGetPointer(&watchpoints, index)->id); + } + mWatchpointListDeinit(&watchpoints); break; default: break; diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 02f19138d..398131d5d 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -11,27 +11,28 @@ #include #include -DEFINE_VECTOR(LR35902DebugBreakpointList, struct LR35902DebugBreakpoint); -DEFINE_VECTOR(LR35902DebugWatchpointList, struct LR35902DebugWatchpoint); - -static struct LR35902DebugBreakpoint* _lookupBreakpoint(struct LR35902DebugBreakpointList* breakpoints, uint16_t address) { +static struct mBreakpoint* _lookupBreakpoint(struct mBreakpointList* breakpoints, struct LR35902Core* cpu) { size_t i; - for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) { - if (LR35902DebugBreakpointListGetPointer(breakpoints, i)->address == address) { - return LR35902DebugBreakpointListGetPointer(breakpoints, i); + for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { + struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); + if (breakpoint->address != cpu->pc) { + continue; + } + if (breakpoint->segment < 0 || breakpoint->segment == cpu->memory.currentSegment(cpu, breakpoint->address)) { + return breakpoint; } } - return 0; + return NULL; } -static void _destroyBreakpoint(struct LR35902DebugBreakpoint* breakpoint) { +static void _destroyBreakpoint(struct mBreakpoint* breakpoint) { if (breakpoint->condition) { parseFree(breakpoint->condition); free(breakpoint->condition); } } -static void _destroyWatchpoint(struct LR35902DebugWatchpoint* watchpoint) { +static void _destroyWatchpoint(struct mWatchpoint* watchpoint) { if (watchpoint->condition) { parseFree(watchpoint->condition); free(watchpoint->condition); @@ -40,13 +41,10 @@ static void _destroyWatchpoint(struct LR35902DebugWatchpoint* watchpoint) { static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform* d) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct LR35902DebugBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu->pc); + struct mBreakpoint* breakpoint = _lookupBreakpoint(&debugger->breakpoints, debugger->cpu); if (!breakpoint) { return; } - if (breakpoint->segment >= 0 && debugger->cpu->memory.currentSegment(debugger->cpu, breakpoint->address) != breakpoint->segment) { - return; - } if (breakpoint->condition) { int32_t value; int segment; @@ -65,12 +63,11 @@ static void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform); static void LR35902DebuggerEnter(struct mDebuggerPlatform* d, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info); -static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment); -static void LR35902DebuggerSetConditionalBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment, struct ParseTree* condition); -static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, uint32_t address, int segment); -static void LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type); -static void LR35902DebuggerSetConditionalWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment, enum mWatchpointType type, struct ParseTree* condition); -static void LR35902DebuggerClearWatchpoint(struct mDebuggerPlatform*, uint32_t address, int segment); +static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform*, const struct mBreakpoint*); +static void LR35902DebuggerListBreakpoints(struct mDebuggerPlatform*, struct mBreakpointList*); +static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform*, ssize_t id); +static ssize_t LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform*, const struct mWatchpoint*); +static void LR35902DebuggerListWatchpoints(struct mDebuggerPlatform*, struct mWatchpointList*); static void LR35902DebuggerCheckBreakpoints(struct mDebuggerPlatform*); static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform*); static void LR35902DebuggerTrace(struct mDebuggerPlatform*, char* out, size_t* length); @@ -83,11 +80,10 @@ struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) { platform->init = LR35902DebuggerInit; platform->deinit = LR35902DebuggerDeinit; platform->setBreakpoint = LR35902DebuggerSetBreakpoint; - platform->setConditionalBreakpoint = LR35902DebuggerSetConditionalBreakpoint; + platform->listBreakpoints = LR35902DebuggerListBreakpoints; platform->clearBreakpoint = LR35902DebuggerClearBreakpoint; platform->setWatchpoint = LR35902DebuggerSetWatchpoint; - platform->setConditionalWatchpoint = LR35902DebuggerSetConditionalWatchpoint; - platform->clearWatchpoint = LR35902DebuggerClearWatchpoint; + platform->listWatchpoints = LR35902DebuggerListWatchpoints; platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints; platform->hasBreakpoints = LR35902DebuggerHasBreakpoints; platform->trace = LR35902DebuggerTrace; @@ -100,22 +96,23 @@ void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; debugger->cpu = cpu; debugger->originalMemory = debugger->cpu->memory; - LR35902DebugBreakpointListInit(&debugger->breakpoints, 0); - LR35902DebugWatchpointListInit(&debugger->watchpoints, 0); + mBreakpointListInit(&debugger->breakpoints, 0); + mWatchpointListInit(&debugger->watchpoints, 0); + debugger->nextId = 1; } void LR35902DebuggerDeinit(struct mDebuggerPlatform* platform) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) platform; size_t i; - for (i = 0; i < LR35902DebugBreakpointListSize(&debugger->breakpoints); ++i) { - _destroyBreakpoint(LR35902DebugBreakpointListGetPointer(&debugger->breakpoints, i)); + for (i = 0; i < mBreakpointListSize(&debugger->breakpoints); ++i) { + _destroyBreakpoint(mBreakpointListGetPointer(&debugger->breakpoints, i)); } - LR35902DebugBreakpointListDeinit(&debugger->breakpoints); + mBreakpointListDeinit(&debugger->breakpoints); - for (i = 0; i < LR35902DebugWatchpointListSize(&debugger->watchpoints); ++i) { - _destroyWatchpoint(LR35902DebugWatchpointListGetPointer(&debugger->watchpoints, i)); + for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { + _destroyWatchpoint(mWatchpointListGetPointer(&debugger->watchpoints, i)); } - LR35902DebugWatchpointListDeinit(&debugger->watchpoints); + mWatchpointListDeinit(&debugger->watchpoints); } static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { @@ -130,65 +127,72 @@ static void LR35902DebuggerEnter(struct mDebuggerPlatform* platform, enum mDebug } } -static void LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { - LR35902DebuggerSetConditionalBreakpoint(d, address, segment, NULL); +static ssize_t LR35902DebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struct mBreakpoint* info) { + struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; + struct mBreakpoint* breakpoint = mBreakpointListAppend(&debugger->breakpoints); + *breakpoint = *info; + breakpoint->id = debugger->nextId; + ++debugger->nextId; + return breakpoint->id; + } -static void LR35902DebuggerSetConditionalBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, struct ParseTree* condition) { +static bool LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, ssize_t id) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListAppend(&debugger->breakpoints); - breakpoint->address = address; - breakpoint->segment = segment; - breakpoint->condition = condition; -} - -static void LR35902DebuggerClearBreakpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { - struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct LR35902DebugBreakpointList* breakpoints = &debugger->breakpoints; size_t i; - for (i = 0; i < LR35902DebugBreakpointListSize(breakpoints); ++i) { - struct LR35902DebugBreakpoint* breakpoint = LR35902DebugBreakpointListGetPointer(breakpoints, i); - if (breakpoint->address == address && breakpoint->segment == segment) { - _destroyBreakpoint(LR35902DebugBreakpointListGetPointer(breakpoints, i)); - LR35902DebugBreakpointListShift(breakpoints, i, 1); + + struct mBreakpointList* breakpoints = &debugger->breakpoints; + for (i = 0; i < mBreakpointListSize(breakpoints); ++i) { + struct mBreakpoint* breakpoint = mBreakpointListGetPointer(breakpoints, i); + if (breakpoint->id == id) { + _destroyBreakpoint(breakpoint); + mBreakpointListShift(breakpoints, i, 1); + return true; } } + + struct mWatchpointList* watchpoints = &debugger->watchpoints; + for (i = 0; i < mWatchpointListSize(watchpoints); ++i) { + struct mWatchpoint* watchpoint = mWatchpointListGetPointer(watchpoints, i); + if (watchpoint->id == id) { + _destroyWatchpoint(watchpoint); + mWatchpointListShift(watchpoints, i, 1); + if (!mWatchpointListSize(&debugger->watchpoints)) { + LR35902DebuggerRemoveMemoryShim(debugger); + } + return true; + } + } + return false; } static bool LR35902DebuggerHasBreakpoints(struct mDebuggerPlatform* d) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - return LR35902DebugBreakpointListSize(&debugger->breakpoints) || LR35902DebugWatchpointListSize(&debugger->watchpoints); + return mBreakpointListSize(&debugger->breakpoints) || mWatchpointListSize(&debugger->watchpoints); } -static void LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, enum mWatchpointType type) { - LR35902DebuggerSetConditionalWatchpoint(d, address, segment, type, NULL); -} - -static void LR35902DebuggerSetConditionalWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment, enum mWatchpointType type, struct ParseTree* condition) { +static ssize_t LR35902DebuggerSetWatchpoint(struct mDebuggerPlatform* d, const struct mWatchpoint* info) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - if (!LR35902DebugWatchpointListSize(&debugger->watchpoints)) { + if (!mWatchpointListSize(&debugger->watchpoints)) { LR35902DebuggerInstallMemoryShim(debugger); } - struct LR35902DebugWatchpoint* watchpoint = LR35902DebugWatchpointListAppend(&debugger->watchpoints); - watchpoint->address = address; - watchpoint->type = type; - watchpoint->segment = segment; - watchpoint->condition = condition; + struct mWatchpoint* watchpoint = mWatchpointListAppend(&debugger->watchpoints); + *watchpoint = *info; + watchpoint->id = debugger->nextId; + ++debugger->nextId; + return watchpoint->id; } -static void LR35902DebuggerClearWatchpoint(struct mDebuggerPlatform* d, uint32_t address, int segment) { +static void LR35902DebuggerListBreakpoints(struct mDebuggerPlatform* d, struct mBreakpointList* list) { struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; - struct LR35902DebugWatchpointList* watchpoints = &debugger->watchpoints; - size_t i; - for (i = 0; i < LR35902DebugWatchpointListSize(watchpoints); ++i) { - struct LR35902DebugWatchpoint* watchpoint = LR35902DebugWatchpointListGetPointer(watchpoints, i); - if (watchpoint->address == address && watchpoint->segment == segment) { - LR35902DebugWatchpointListShift(watchpoints, i, 1); - } - } - if (!LR35902DebugWatchpointListSize(&debugger->watchpoints)) { - LR35902DebuggerRemoveMemoryShim(debugger); - } + mBreakpointListClear(list); + mBreakpointListCopy(list, &debugger->breakpoints); +} + +static void LR35902DebuggerListWatchpoints(struct mDebuggerPlatform* d, struct mWatchpointList* list) { + struct LR35902Debugger* debugger = (struct LR35902Debugger*) d; + mWatchpointListClear(list); + mWatchpointListCopy(list, &debugger->watchpoints); } static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* length) { diff --git a/src/lr35902/debugger/memory-debugger.c b/src/lr35902/debugger/memory-debugger.c index b5c36a81e..b7adb0b6d 100644 --- a/src/lr35902/debugger/memory-debugger.c +++ b/src/lr35902/debugger/memory-debugger.c @@ -43,10 +43,10 @@ CREATE_WATCHPOINT_SHIM(load8, READ, 0, uint8_t, (struct LR35902Core* cpu, uint16 CREATE_WATCHPOINT_SHIM(store8, WRITE, value, void, (struct LR35902Core* cpu, uint16_t address, int8_t value), address, value) static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address, struct mDebuggerEntryInfo* info, enum mWatchpointType type, uint8_t newValue) { - struct LR35902DebugWatchpoint* watchpoint; + struct mWatchpoint* watchpoint; size_t i; - for (i = 0; i < LR35902DebugWatchpointListSize(&debugger->watchpoints); ++i) { - watchpoint = LR35902DebugWatchpointListGetPointer(&debugger->watchpoints, i); + for (i = 0; i < mWatchpointListSize(&debugger->watchpoints); ++i) { + watchpoint = mWatchpointListGetPointer(&debugger->watchpoints, i); if (watchpoint->address == address && (watchpoint->segment < 0 || watchpoint->segment == debugger->originalMemory.currentSegment(debugger->cpu, address)) && watchpoint->type & type) { if (watchpoint->condition) { int32_t value; From a36315097a8757e2c5c7ca0d8b2e639880655767 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Feb 2019 02:09:10 -0800 Subject: [PATCH 006/429] Qt: Fix tile and sprite views not always displaying at first --- CHANGES | 1 + src/platform/qt/ObjView.cpp | 3 +++ src/platform/qt/TilePainter.cpp | 1 + src/platform/qt/TilePainter.h | 1 + src/platform/qt/TileView.cpp | 3 +++ 5 files changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index 036e2bf4b..7b2557504 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Bugfixes: - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Switch: Fix final cleanup (fixes mgba.io/i/1283) + - Qt: Fix tile and sprite views not always displaying at first Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/ObjView.cpp b/src/platform/qt/ObjView.cpp index b4c0ae5ac..64b689640 100644 --- a/src/platform/qt/ObjView.cpp +++ b/src/platform/qt/ObjView.cpp @@ -46,6 +46,9 @@ ObjView::ObjView(std::shared_ptr controller, QWidget* parent) m_ui.mode->setFont(font); connect(m_ui.tiles, &TilePainter::indexPressed, this, &ObjView::translateIndex); + connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() { + updateTiles(true); + }); connect(m_ui.objId, static_cast(&QSpinBox::valueChanged), this, &ObjView::selectObj); connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), [this]() { updateTiles(true); diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index bbf975ca6..042d04732 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -31,6 +31,7 @@ void TilePainter::resizeEvent(QResizeEvent* event) { if (width() / m_size != m_backing.width() / m_size || m_backing.height() != calculatedHeight) { m_backing = QPixmap(width(), calculatedHeight); m_backing.fill(Qt::transparent); + emit needsRedraw(); } } diff --git a/src/platform/qt/TilePainter.h b/src/platform/qt/TilePainter.h index 7cd4c30bb..6adc45419 100644 --- a/src/platform/qt/TilePainter.h +++ b/src/platform/qt/TilePainter.h @@ -26,6 +26,7 @@ public slots: signals: void indexPressed(int index); + void needsRedraw(); protected: void paintEvent(QPaintEvent*) override; diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp index 063caf8d3..bc7381f7a 100644 --- a/src/platform/qt/TileView.cpp +++ b/src/platform/qt/TileView.cpp @@ -25,6 +25,9 @@ TileView::TileView(std::shared_ptr controller, QWidget* parent) m_ui.tile->setController(controller); connect(m_ui.tiles, &TilePainter::indexPressed, m_ui.tile, &AssetTile::selectIndex); + connect(m_ui.tiles, &TilePainter::needsRedraw, this, [this]() { + updateTiles(true); + }); connect(m_ui.paletteId, static_cast(&QSpinBox::valueChanged), this, &TileView::updatePalette); switch (m_controller->platform()) { From f7f8e38dc17ec7d1daeb1c570cfb124490cf2990 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 10 Feb 2019 16:29:51 -0800 Subject: [PATCH 007/429] GBA Peripherals: Start implementing BattleChip Gate --- include/mgba/gba/interface.h | 12 +++- src/gba/core.c | 3 + src/gba/extra/battlechip.c | 136 +++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 src/gba/extra/battlechip.c diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 0d85982f5..440a6e567 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -11,6 +11,7 @@ CXX_GUARD_START #include +#include enum GBASIOMode { SIO_NORMAL_8 = 0, @@ -36,7 +37,8 @@ struct GBAVideoRenderer; extern const int GBA_LUX_LEVELS[10]; enum { - mPERIPH_GBA_LUMINANCE = 0x1000 + mPERIPH_GBA_LUMINANCE = 0x1000, + mPERIPH_GBA_BATTLECHIP_GATE, }; struct GBALuminanceSource { @@ -58,6 +60,14 @@ struct GBASIODriver { void GBASIOJOYCreate(struct GBASIODriver* sio); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); +struct GBASIOBattlechipGate { + struct GBASIODriver d; + struct mTimingEvent event; + uint16_t chipId; + int32_t index; +}; + +void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); CXX_GUARD_END diff --git a/src/gba/core.c b/src/gba/core.c index 93dc98d84..193d6970a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -533,6 +533,9 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { case mPERIPH_GBA_LUMINANCE: gba->luminanceSource = periph; break; + case mPERIPH_GBA_BATTLECHIP_GATE: + GBASIOSetDriver(&gba->sio, periph, SIO_MULTI); + break; default: return; } diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c new file mode 100644 index 000000000..3af871432 --- /dev/null +++ b/src/gba/extra/battlechip.c @@ -0,0 +1,136 @@ +/* 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/. */ +#include + +#include +#include +#include + +mLOG_DECLARE_CATEGORY(GBA_BATTLECHIP); +mLOG_DEFINE_CATEGORY(GBA_BATTLECHIP, "GBA BattleChip Gate", "gba.battlechip"); + +enum { + BATTLECHIP_INDEX_HANDSHAKE_0 = 0, + BATTLECHIP_INDEX_HANDSHAKE_1 = 1, + BATTLECHIP_INDEX_ID = 2, + BATTLECHIP_INDEX_END = 6 +}; + +enum { + BATTLECHIP_OK = 0xFFC6, + BATTLECHIP_CONTINUE = 0xFFFF, +}; + +static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); +static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); + +static void _battlechipTransfer(struct GBASIOBattlechipGate* gate); +static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate); + +void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { + gate->d.init = NULL; + gate->d.deinit = NULL; + gate->d.load = GBASIOBattlechipGateLoad; + gate->d.unload = NULL; + gate->d.writeRegister = GBASIOBattlechipGateWriteRegister; + + gate->event.context = gate; + gate->event.callback = _battlechipTransferEvent; + gate->event.priority = 0x80; +} + +bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { + struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; + gate->index = BATTLECHIP_INDEX_END; + return true; +} + +uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { + struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; + switch (address) { + case REG_SIOCNT: + value &= ~0xC; + value |= 0x8; + if (value & 0x80) { + _battlechipTransfer(gate); + } + break; + case REG_SIOMLT_SEND: + break; + case REG_RCNT: + break; + default: + break; + } + return value; +} + +void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { + int32_t cycles = GBASIOCyclesPerTransfer[gate->d.p->multiplayerControl.baud][1]; + mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); +} + +void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate) { + struct GBASIOBattlechipGate* gate = user; + + uint16_t cmd = gate->d.p->p->memory.io[REG_SIOMLT_SEND >> 1]; + uint16_t reply = 0xFFFF; + gate->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = cmd; + gate->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF; + gate->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF; + gate->d.p->multiplayerControl.busy = 0; + gate->d.p->multiplayerControl.id = 0; + + mLOG(GBA_BATTLECHIP, DEBUG, "> %04x", cmd); + + switch (cmd) { + case 0x4000: + gate->index = 0; + // Fall through + case 0: + switch (gate->index) { + case BATTLECHIP_INDEX_HANDSHAKE_0: + reply = 0x00FE; + break; + case BATTLECHIP_INDEX_HANDSHAKE_1: + reply = 0xFFFE; + break; + case BATTLECHIP_INDEX_ID: + reply = gate->chipId; + break; + default: + if (gate->index >= BATTLECHIP_INDEX_END) { + reply = BATTLECHIP_OK; + } else if (gate->index < 0) { + reply = BATTLECHIP_CONTINUE; + } else { + reply = 0; + } + break; + } + ++gate->index; + break; + case 0x8FFF: + gate->index = -2; + // Fall through + default: + case 0xA3D0: + reply = BATTLECHIP_OK; + break; + case 0x4234: + case 0x574A: + reply = BATTLECHIP_CONTINUE; + break; + } + + mLOG(GBA_BATTLECHIP, DEBUG, "< %04x", reply); + + gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply; + + if (gate->d.p->multiplayerControl.irq) { + GBARaiseIRQ(gate->d.p->p, IRQ_SIO); + } +} From 22531a1315ff1f5e880dd352b244c88b403e2c5a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Feb 2019 21:40:45 -0800 Subject: [PATCH 008/429] GBA Peripherals: Add BattleChip Gate dummy interface --- src/gba/extra/battlechip.c | 9 +++++- src/platform/qt/BattleChipView.cpp | 36 ++++++++++++++++++++++++ src/platform/qt/BattleChipView.h | 36 ++++++++++++++++++++++++ src/platform/qt/BattleChipView.ui | 45 ++++++++++++++++++++++++++++++ src/platform/qt/CMakeLists.txt | 6 ++-- src/platform/qt/CoreController.cpp | 36 ++++++++++++++++++++---- src/platform/qt/CoreController.h | 16 +++++++++++ src/platform/qt/Window.cpp | 38 +++++++++++++++++-------- 8 files changed, 201 insertions(+), 21 deletions(-) create mode 100644 src/platform/qt/BattleChipView.cpp create mode 100644 src/platform/qt/BattleChipView.h create mode 100644 src/platform/qt/BattleChipView.ui diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 3af871432..2899347fd 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -24,6 +24,7 @@ enum { BATTLECHIP_CONTINUE = 0xFFFF, }; +static bool GBASIOBattlechipGateInit(struct GBASIODriver* driver); static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); @@ -31,7 +32,7 @@ static void _battlechipTransfer(struct GBASIOBattlechipGate* gate); static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate); void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { - gate->d.init = NULL; + gate->d.init = GBASIOBattlechipGateInit; gate->d.deinit = NULL; gate->d.load = GBASIOBattlechipGateLoad; gate->d.unload = NULL; @@ -42,6 +43,12 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->event.priority = 0x80; } +bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { + struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; + gate->chipId = 0; + return true; +} + bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; gate->index = BATTLECHIP_INDEX_END; diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp new file mode 100644 index 000000000..af9a0a9eb --- /dev/null +++ b/src/platform/qt/BattleChipView.cpp @@ -0,0 +1,36 @@ +/* Copyright (c) 2013-2019 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 "BattleChipView.h" + +#include "CoreController.h" + +using namespace QGBA; + +BattleChipView::BattleChipView(std::shared_ptr controller, QWidget* parent) + : QDialog(parent) + , m_controller(controller) +{ + m_ui.setupUi(this); + + connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { + m_ui.inserted->setChecked(Qt::Checked); + insertChip(true); + }); + connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); + connect(controller.get(), &CoreController::stopping, this, &QWidget::close); +} + +BattleChipView::~BattleChipView() { + m_controller->detachBattleChipGate(); +} + +void BattleChipView::insertChip(bool inserted) { + if (inserted) { + m_controller->setBattleChipId(m_ui.chipId->value()); + } else { + m_controller->setBattleChipId(0); + } +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h new file mode 100644 index 000000000..564f1f8b0 --- /dev/null +++ b/src/platform/qt/BattleChipView.h @@ -0,0 +1,36 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include + +#include + +#include + +#include "ui_BattleChipView.h" + +namespace QGBA { + +class CoreController; + +class BattleChipView : public QDialog { +Q_OBJECT + +public: + BattleChipView(std::shared_ptr controller, QWidget* parent = nullptr); + ~BattleChipView(); + +public slots: + void insertChip(bool); + +private: + Ui::BattleChipView m_ui; + + std::shared_ptr m_controller; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui new file mode 100644 index 000000000..5143c9d41 --- /dev/null +++ b/src/platform/qt/BattleChipView.ui @@ -0,0 +1,45 @@ + + + BattleChipView + + + + 0 + 0 + 217 + 100 + + + + BattleChip Gate + + + + + + Inserted + + + + + + + Chip ID + + + + + + + 1 + + + 65535 + + + + + + + + diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index b9c7d0ed8..8cf30dbc8 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -102,7 +102,6 @@ set(SOURCE_FILES OverrideView.cpp PaletteView.cpp PlacementControl.cpp - PrinterView.cpp RegisterView.cpp ROMInfo.cpp RotatedHeaderView.cpp @@ -124,6 +123,7 @@ set(UI_FILES AboutScreen.ui ArchiveInspector.ui AssetTile.ui + BattleChipView.ui CheatsView.ui DebuggerConsole.ui GIFView.ui @@ -147,10 +147,12 @@ set(UI_FILES VideoView.ui) set(GBA_SRC + BattleChipView.cpp GBAOverride.cpp) set(GB_SRC - GBOverride.cpp) + GBOverride.cpp + PrinterView.cpp) set(QT_LIBRARIES) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libqt5widgets5,libqt5opengl5") diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index e4f12087b..c5e8850ec 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -672,8 +672,8 @@ void CoreController::exportSharkport(const QString& path) { #endif } -void CoreController::attachPrinter() { #ifdef M_CORE_GB +void CoreController::attachPrinter() { if (platform() != PLATFORM_GB) { return; } @@ -703,11 +703,9 @@ void CoreController::attachPrinter() { }; Interrupter interrupter(this); GBSIOSetDriver(&gb->sio, &m_printer.d.d); -#endif } void CoreController::detachPrinter() { -#ifdef M_CORE_GB if (platform() != PLATFORM_GB) { return; } @@ -715,18 +713,44 @@ void CoreController::detachPrinter() { GB* gb = static_cast(m_threadContext.core->board); GBPrinterDonePrinting(&m_printer.d); GBSIOSetDriver(&gb->sio, nullptr); -#endif } void CoreController::endPrint() { -#ifdef M_CORE_GB if (platform() != PLATFORM_GB) { return; } Interrupter interrupter(this); GBPrinterDonePrinting(&m_printer.d); -#endif } +#endif + +#ifdef M_CORE_GBA +void CoreController::attachBattleChipGate() { + if (platform() != PLATFORM_GBA) { + return; + } + Interrupter interrupter(this); + clearMultiplayerController(); + GBASIOBattlechipGateCreate(&m_battlechip); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_BATTLECHIP_GATE, &m_battlechip); +} + +void CoreController::detachBattleChipGate() { + if (platform() != PLATFORM_GBA) { + return; + } + Interrupter interrupter(this); + m_threadContext.core->setPeripheral(m_threadContext.core, mPERIPH_GBA_BATTLECHIP_GATE, nullptr); +} + +void CoreController::setBattleChipId(uint16_t id) { + if (platform() != PLATFORM_GBA) { + return; + } + Interrupter interrupter(this); + m_battlechip.chipId = id; +} +#endif void CoreController::setAVStream(mAVStream* stream) { Interrupter interrupter(this); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 9d9537c6c..b7a740626 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -25,6 +25,10 @@ #include #endif +#ifdef M_CORE_GBA +#include +#endif + struct mCore; namespace QGBA { @@ -129,9 +133,17 @@ public slots: void importSharkport(const QString& path); void exportSharkport(const QString& path); +#ifdef M_CORE_GB void attachPrinter(); void detachPrinter(); void endPrint(); +#endif + +#ifdef M_CORE_GBA + void attachBattleChipGate(); + void detachBattleChipGate(); + void setBattleChipId(uint16_t id); +#endif void setAVStream(mAVStream*); void clearAVStream(); @@ -222,6 +234,10 @@ private: CoreController* parent; } m_printer; #endif + +#ifdef M_CORE_GBA + GBASIOBattlechipGate m_battlechip; +#endif }; } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index f5df80bd6..a49f3075f 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -21,6 +21,7 @@ #include "AboutScreen.h" #include "AudioProcessor.h" +#include "BattleChipView.h" #include "CheatsView.h" #include "ConfigController.h" #include "CoreController.h" @@ -1350,6 +1351,31 @@ void Window::setupMenu(QMenuBar* menubar) { addControlledAction(solarMenu, setSolar, QString("luminanceLevel.%1").arg(QString::number(i))); } +#ifdef M_CORE_GB + QAction* gbPrint = new QAction(tr("Game Boy Printer..."), emulationMenu); + connect(gbPrint, &QAction::triggered, [this]() { + PrinterView* view = new PrinterView(m_controller); + openView(view); + m_controller->attachPrinter(); + + }); + addControlledAction(emulationMenu, gbPrint, "gbPrint"); + m_gameActions.append(gbPrint); +#endif + +#ifdef M_CORE_GBA + QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu); + connect(bcGate, &QAction::triggered, [this]() { + BattleChipView* view = new BattleChipView(m_controller); + openView(view); + m_controller->attachBattleChipGate(); + + }); + addControlledAction(emulationMenu, bcGate, "bcGate"); + m_gbaActions.append(bcGate); + m_gameActions.append(bcGate); +#endif + QMenu* avMenu = menubar->addMenu(tr("Audio/&Video")); m_shortcutController->addMenu(avMenu); QMenu* frameMenu = avMenu->addMenu(tr("Frame size")); @@ -1495,18 +1521,6 @@ void Window::setupMenu(QMenuBar* menubar) { addControlledAction(avMenu, stopVL, "stopVL"); m_gameActions.append(stopVL); -#ifdef M_CORE_GB - QAction* gbPrint = new QAction(tr("Game Boy Printer..."), avMenu); - connect(gbPrint, &QAction::triggered, [this]() { - PrinterView* view = new PrinterView(m_controller); - openView(view); - m_controller->attachPrinter(); - - }); - addControlledAction(avMenu, gbPrint, "gbPrint"); - m_gameActions.append(gbPrint); -#endif - avMenu->addSeparator(); m_videoLayers = avMenu->addMenu(tr("Video layers")); m_shortcutController->addMenu(m_videoLayers, avMenu); From cab3a2272d6819387c096aa3591eeb230e114d9c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 11 Feb 2019 21:59:15 -0800 Subject: [PATCH 009/429] GBA Memory: Various AGBPrint fixes --- CHANGES | 2 ++ src/gba/memory.c | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 7b2557504..e6c00e8fc 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,8 @@ Bugfixes: - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Switch: Fix final cleanup (fixes mgba.io/i/1283) - Qt: Fix tile and sprite views not always displaying at first + - GBA Memory: Fix a few AGBPrint crashes + - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/memory.c b/src/gba/memory.c index 58dca916f..32d707c60 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1647,6 +1647,10 @@ void _pristineCow(struct GBA* gba) { } void GBAPrintFlush(struct GBA* gba) { + if (!gba->memory.agbPrintBuffer) { + return; + } + char oolBuf[0x101]; size_t i; for (i = 0; gba->memory.agbPrintCtx.get != gba->memory.agbPrintCtx.put && i < 0x100; ++i) { @@ -1688,8 +1692,8 @@ static void _agbPrintStore(struct GBA* gba, uint32_t address, int16_t value) { static int16_t _agbPrintLoad(struct GBA* gba, uint32_t address) { struct GBAMemory* memory = &gba->memory; - int16_t value = 0xFFFF; - if (address < AGB_PRINT_TOP) { + int16_t value = address >> 1; + if (address < AGB_PRINT_TOP && memory->agbPrintBuffer) { LOAD_16(value, address & (SIZE_AGB_PRINT - 1), memory->agbPrintBuffer); } else if ((address & 0x00FFFFF8) == (AGB_PRINT_STRUCT & 0x00FFFFF8)) { value = (&memory->agbPrintCtx.request)[(address & 7) >> 1]; From 0df180c0d010b4571ad024134dfbee23f9646728 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 12 Feb 2019 09:20:37 -0800 Subject: [PATCH 010/429] GB Serialize: Fix loading states with negative pixel x (fixes #1293) --- CHANGES | 1 + src/gb/serialize.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index e6c00e8fc..e8a00269a 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Bugfixes: - Qt: Fix tile and sprite views not always displaying at first - GBA Memory: Fix a few AGBPrint crashes - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory + - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 4eef6ae67..6c3db6308 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -113,7 +113,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { error = true; } LOAD_16LE(check16, 0, &state->video.x); - if (check16 < 0 || check16 > GB_VIDEO_HORIZONTAL_PIXELS) { + if (check16 < -7 || check16 > GB_VIDEO_HORIZONTAL_PIXELS) { mLOG(GB_STATE, WARN, "Savestate is corrupted: video x is out of range"); error = true; } From 0980b67736c6f3235710840c9a9e7030b4fcc75d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Feb 2019 20:14:22 -0800 Subject: [PATCH 011/429] Wii: Remove duplicate bindings --- src/platform/wii/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 8c37c1f4c..4328bd104 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -548,9 +548,7 @@ int main(int argc, char* argv[]) { _mapKey(&runner.params.keyMap, WIIMOTE_INPUT, WPAD_BUTTON_DOWN, GUI_INPUT_RIGHT); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_A, GUI_INPUT_SELECT); - _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_Y, GUI_INPUT_SELECT); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_B, GUI_INPUT_BACK); - _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_X, GUI_INPUT_BACK); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_HOME, GUI_INPUT_CANCEL); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_UP, GUI_INPUT_UP); _mapKey(&runner.params.keyMap, CLASSIC_INPUT, WPAD_CLASSIC_BUTTON_DOWN, GUI_INPUT_DOWN); From a0d0de137c16f025fdbb6c8952df9dd0cb3298c1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Feb 2019 20:14:57 -0800 Subject: [PATCH 012/429] Wii: Saturate joystick values --- src/platform/wii/main.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 4328bd104..dbdb467a9 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -1072,8 +1072,15 @@ static s8 WPAD_StickX(u8 chan, u8 right) { return 0; } int centered = (int) js->pos.x - (int) js->center.x; - int range = js->max.x - js->min.x; - return (centered * 0xFF) / range; + int range = (int) js->max.x - (int) js->min.x; + int value = (centered * 0xFF) / range; + if (value > 0x7F) { + return 0x7F; + } + if (value < -0x80) { + return -0x80; + } + return value; } static s8 WPAD_StickY(u8 chan, u8 right) { @@ -1103,8 +1110,15 @@ static s8 WPAD_StickY(u8 chan, u8 right) { return 0; } int centered = (int) js->pos.y - (int) js->center.y; - int range = js->max.y - js->min.y; - return (centered * 0xFF) / range; + int range = (int) js->max.y - (int) js->min.y; + int value = (centered * 0xFF) / range; + if (value > 0x7F) { + return 0x7F; + } + if (value < -0x80) { + return -0x80; + } + return value; } void _retraceCallback(u32 count) { From 86b6f2e9cd967be4d684ecac80ce26cdaddcfaf1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Feb 2019 21:43:16 -0800 Subject: [PATCH 013/429] GBA Peripherals: Improve BattleChip Gate support --- include/mgba/gba/interface.h | 3 +- src/gba/extra/battlechip.c | 112 +++++++++++++++++++++++------------ 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 440a6e567..0c61363e3 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -64,7 +64,8 @@ struct GBASIOBattlechipGate { struct GBASIODriver d; struct mTimingEvent event; uint16_t chipId; - int32_t index; + uint16_t data[2]; + int state; }; void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 2899347fd..40b80e3ec 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -13,10 +13,15 @@ mLOG_DECLARE_CATEGORY(GBA_BATTLECHIP); mLOG_DEFINE_CATEGORY(GBA_BATTLECHIP, "GBA BattleChip Gate", "gba.battlechip"); enum { - BATTLECHIP_INDEX_HANDSHAKE_0 = 0, - BATTLECHIP_INDEX_HANDSHAKE_1 = 1, - BATTLECHIP_INDEX_ID = 2, - BATTLECHIP_INDEX_END = 6 + BATTLECHIP_STATE_COMMAND = 0, + BATTLECHIP_STATE_UNK_0 = 1, + BATTLECHIP_STATE_UNK_1 = 2, + BATTLECHIP_STATE_DATA_0 = 3, + BATTLECHIP_STATE_DATA_1 = 4, + BATTLECHIP_STATE_ID = 5, + BATTLECHIP_STATE_UNK_2 = 6, + BATTLECHIP_STATE_UNK_3 = 7, + BATTLECHIP_STATE_END = 8 }; enum { @@ -51,7 +56,9 @@ bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; - gate->index = BATTLECHIP_INDEX_END; + gate->state = BATTLECHIP_STATE_COMMAND; + gate->data[0] = 0x00FE; + gate->data[1] = 0xFFFE; return true; } @@ -91,49 +98,80 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->multiplayerControl.busy = 0; gate->d.p->multiplayerControl.id = 0; - mLOG(GBA_BATTLECHIP, DEBUG, "> %04x", cmd); + mLOG(GBA_BATTLECHIP, DEBUG, "> %04X", cmd); - switch (cmd) { - case 0x4000: - gate->index = 0; - // Fall through - case 0: - switch (gate->index) { - case BATTLECHIP_INDEX_HANDSHAKE_0: - reply = 0x00FE; + switch (gate->state) { + case BATTLECHIP_STATE_COMMAND: + mLOG(GBA_BATTLECHIP, DEBUG, "C %04X", cmd); + switch (cmd) { + case 0x0000: + case 0x8FFF: + case 0xA380: + case 0xA390: + case 0xA3A0: + case 0xA3B0: + case 0xA3C0: + case 0xA3D0: + gate->state = -1; + // Fall through + case 0x5379: + case 0x537A: + case 0x537B: + case 0x537C: + case 0x537D: + case 0x537E: + case 0xD979: + case 0xD97A: + case 0xD97B: + case 0xD97C: + case 0xD97D: + case 0xD97E: + reply = BATTLECHIP_OK; break; - case BATTLECHIP_INDEX_HANDSHAKE_1: - reply = 0xFFFE; - break; - case BATTLECHIP_INDEX_ID: - reply = gate->chipId; + case 0x5745: + case 0x5746: + case 0x5747: + case 0x5748: + case 0x5749: + case 0x574A: + case 0xFC00: + // Resync + gate->state = BATTLECHIP_STATE_UNK_0; break; default: - if (gate->index >= BATTLECHIP_INDEX_END) { - reply = BATTLECHIP_OK; - } else if (gate->index < 0) { - reply = BATTLECHIP_CONTINUE; - } else { - reply = 0; - } + mLOG(GBA_BATTLECHIP, STUB, "? %04X", cmd); break; } - ++gate->index; break; - case 0x8FFF: - gate->index = -2; - // Fall through - default: - case 0xA3D0: + case BATTLECHIP_STATE_UNK_0: + case BATTLECHIP_STATE_UNK_1: + reply = 0xFFFF; + break; + case BATTLECHIP_STATE_DATA_0: + reply = gate->data[0]; + gate->data[0] += 3; + gate->data[0] &= 0xF0FF; + break; + case BATTLECHIP_STATE_DATA_1: + reply = gate->data[1]; + gate->data[1] -= 3; + gate->data[1] |= 0xFE00; + break; + case BATTLECHIP_STATE_ID: + reply = gate->chipId; + break; + case BATTLECHIP_STATE_UNK_2: + case BATTLECHIP_STATE_UNK_3: + reply = 0; + break; + case BATTLECHIP_STATE_END: reply = BATTLECHIP_OK; - break; - case 0x4234: - case 0x574A: - reply = BATTLECHIP_CONTINUE; + gate->state = -1; break; } + ++gate->state; - mLOG(GBA_BATTLECHIP, DEBUG, "< %04x", reply); + mLOG(GBA_BATTLECHIP, DEBUG, "< %04X", reply); gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply; From 7899e02db00c15e6f33c958d7c07f64f1047af96 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 15 Feb 2019 00:57:24 -0800 Subject: [PATCH 014/429] Qt: Flesh out BattleChip Gate UI --- CHANGES | 1 + res/chip-names-4.txt | 307 +++++++++++++++++++++++++++++ src/platform/qt/BattleChipView.cpp | 33 +++- src/platform/qt/BattleChipView.h | 3 + src/platform/qt/BattleChipView.ui | 23 ++- src/platform/qt/resources.qrc | 1 + 6 files changed, 358 insertions(+), 10 deletions(-) create mode 100644 res/chip-names-4.txt diff --git a/CHANGES b/CHANGES index e8a00269a..ed5cb8375 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ 0.8.0: (Future) Features: - Improved logging configuration + - One-Player BattleChip Gate support Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt new file mode 100644 index 000000000..fdfd868ae --- /dev/null +++ b/res/chip-names-4.txt @@ -0,0 +1,307 @@ +Cannon +Hi Cannon +Mega Cannon +Air Shot +Blizzard +Heat Breath +Silence +Tornado +Wide Shot 1 +Wide Shot 2 +Wide Shot 3 +Flame Line 1 +Flame Line 2 +Flame Line 3 +Vulcan 1 +Vulcan 2 +Vulcan 3 +Spreader +Heat Shot +Heat V +Heat Side +Bubbler +Bubble V +Bubble Side +Element Flare +Element Ice +Static +Life Sync +Mini Boomer +Energy Bomb +Mega Energy Bomb +Gun del Sol 1 +Gun del Sol 2 +Gun del Sol 3 +Mag Bolt 1 +Mag Bolt 2 +Mag Bolt 3 +Binder 1 +Binder 2 +Binder 3 +Bug Bomb +Elec Shock +Wood Powder +Cannonball +Geyser +Geyser +Sand Ring +Sword +Wide Sword +Long Sword +Wide Blade +Long Blade +Wind Racket +Custom Sword +Variable Sword +Slasher +Thunderball 1 +Thunderball 2 +Thunderball 3 +Counter 1 +Counter 2 +Counter 3 +Air Hockey 1 +Air Hockey 2 +Air Hockey 3 +Circle Gun 1 +Circle Gun 2 +Circle Gun 3 +Twin Fang 1 +Twin Fang 2 +Twin Fang 3 +White Web 1 +White Web 2 +White Web 3 +Boomerang 1 +Boomerang 2 +Boomerang 3 +Side Bamboo 1 +Side Bamboo 2 +Side Bamboo 3 +Lance +Hole +Boy's Bomb 1 +Boy's Bomb 2 +Boy's Bomb 3 +Guard 1 +Guard 2 +Guard 3 +Magnum +Grab Gel +Snake +Time Bomb +Mine +Rock Cube +Fanfare +Discord +Timpani +VDoll +Big Hammer 1 +Big Hammer 2 +Big Hammer 3 +Grab Revenge +Grab Banish +Geddon 1 +Geddon 2 +Geddon 3 +Element Leaf +Color Point +Element Sand +Moko Rush 1 +Moko Rush 2 +Moko Rush 3 +North Wind +Anti Fire +Anti Water +Anti Electric +Anti Wood +Anti Navi +Anti Damage +Anti Sword +Anti Recover +Copy Damage +Attack +10 +Navi +20 +Roll Arrow 1 +Roll Arrow 2 +Roll Arrow 3 +Guts Punch 1 +Guts Punch 2 +Guts Punch 3 +Propeller Bomb 1 +Propeller Bomb 2 +Propeller Bomb 3 +Search Bomb 1 +Search Bomb 2 +Search Bomb 3 +Meteors 1 +Meteors 2 +Meteors 3 +Lightning 1 +Lightning 2 +Lightning 3 +Hawk Cut 1 +Hawk Cut 2 +Hawk Cut 3 +Number Ball 1 +Number Ball 2 +Number Ball 3 +Metal Gear 1 +Metal Gear 2 +Metal Gear 3 +Panel Shoot 1 +Panel Shoot 2 +Panel Shoot 3 +Aqua Upper 1 +Aqua Upper 2 +Aqua Upper 3 +Green Wood 1 +Green Wood 2 +Green Wood 3 +Muramasa +Guardian +Anubis +Double Point +Full Custom +Shooting Star +Bug Chain +Jealousy +Element Dark +Black Wing +God Hammer +Dark Line +Neo Variable +Z Saber +Gun del Sol EX +Super Vulcan +Roll +Roll SP +Roll DS +GutsMan +GutsMan SP +GutsMan DS +WindMan +WindMan SP +WindMan DS +SearchMan +SearchMan SP +SearchMan DS +FireMan +FireMan SP +FireMan DS +ThunderMan +ThunderMan SP +ThunderMan DS +ProtoMan +ProtoMan SP +ProtoMan DS +NumberMan +NumberMan SP +NumberMan DS +MetalMan +MetalMan SP +MetalMan DS +JunkMan +JunkMan SP +JunkMan DS +AquaMan +AquaMan SP +AquaMan DS +WoodMan +WoodMan SP +WoodMan DS +TopMan +TopMan SP +TopMan DS +ShadeMan +ShadeMan SP +ShadeMan DS +BurnerMan +BurnerMan SP +BurnerMan DS +ColdMan +ColdMan SP +ColdMan DS +SparkMan +SparkMan SP +SparkMan DS +LaserMan +LaserMan SP +LaserMan DS +KendoMan +KendoMan SP +KendoMan DS +VideoMan +VideoMan SP +VideoMan DS +Marking +Cannon Mode +Cannonball Mode +Sword Mode +Fire Plus +Thunder Plus +Aqua Power +Wood Power +Black Weapon +Final Gun + + + + + +Bass +Delta Ray +Bug Curse +Red Sun +Bass Another +Holy Dream +Blue Moon +Bug Charge + + +Wind +Fan +Crack Out +Double Crack +Triple Crack +Recovery 10 +Recovery 30 +Recovery 50 +Recovery 80 +Recovery 120 +Recovery 150 +Recovery 200 +Recovery 300 +Repair +Panel Grab +Area Grab +Slow Gauge +Fast Gauge +Panel Return +Blinder +Pop Up +Invisible +Barrier +Barrier 100 +Barrier 200 +Holy Panel + +Life Aura +Attack +30 +Bug Fix +Sanctuary +Signal Red +Black Barrier +MegaMan Navi +Roll Navi +GutsMan Navi +WindMan Navi +SearchMan Navi +FireMan Navi +ThunderMan Navi +ProtoMan Navi +NumberMan Navi +MetalMan Navi +JunkMan Navi +AquaMan Navi +WoodMan Navi \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index af9a0a9eb..4f6b6a4b3 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -7,6 +7,9 @@ #include "CoreController.h" +#include +#include + using namespace QGBA; BattleChipView::BattleChipView(std::shared_ptr controller, QWidget* parent) @@ -16,21 +19,47 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg m_ui.setupUi(this); connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { - m_ui.inserted->setChecked(Qt::Checked); - insertChip(true); + m_ui.inserted->setChecked(Qt::Unchecked); }); + connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.chipName, &QComboBox::setCurrentIndex); + connect(m_ui.chipName, static_cast(&QComboBox::currentIndexChanged), m_ui.chipId, &QSpinBox::setValue); + connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); connect(controller.get(), &CoreController::stopping, this, &QWidget::close); + + setFlavor(4); } BattleChipView::~BattleChipView() { m_controller->detachBattleChipGate(); } +void BattleChipView::setFlavor(int flavor) { + loadChipNames(flavor); +} + void BattleChipView::insertChip(bool inserted) { if (inserted) { m_controller->setBattleChipId(m_ui.chipId->value()); } else { m_controller->setBattleChipId(0); } +} + +void BattleChipView::loadChipNames(int flavor) { + QStringList chipNames; + chipNames.append(tr("(None)")); + + QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); + file.open(QIODevice::ReadOnly | QIODevice::Text); + while (true) { + QByteArray line = file.readLine(); + if (line.isEmpty()) { + break; + } + chipNames.append(QString::fromUtf8(line).trimmed()); + } + + m_ui.chipName->clear(); + m_ui.chipName->addItems(chipNames); } \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 564f1f8b0..14b61a043 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -25,9 +25,12 @@ public: ~BattleChipView(); public slots: + void setFlavor(int); void insertChip(bool); private: + void loadChipNames(int); + Ui::BattleChipView m_ui; std::shared_ptr m_controller; diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 5143c9d41..092663ae7 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -6,38 +6,45 @@ 0 0 - 217 - 100 + 426 + 152 BattleChip Gate - + Inserted - + Chip ID - - - - 1 + + + + Chip Name + + + + 65535 + + + diff --git a/src/platform/qt/resources.qrc b/src/platform/qt/resources.qrc index 7d61b6dd1..80be2c8be 100644 --- a/src/platform/qt/resources.qrc +++ b/src/platform/qt/resources.qrc @@ -4,5 +4,6 @@ ../../../res/keymap.qpic ../../../res/patrons.txt ../../../res/no-cam.png + ../../../res/chip-names-4.txt From c82f9f0efcd8c8e1f000902773504cfa667c3ab7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 15 Feb 2019 01:14:03 -0800 Subject: [PATCH 015/429] Res: Add names for RME4.5 Navis --- res/chip-names-4.txt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index fdfd868ae..3ffc433c8 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -304,4 +304,12 @@ NumberMan Navi MetalMan Navi JunkMan Navi AquaMan Navi -WoodMan Navi \ No newline at end of file +WoodMan Navi +StarMan Navi +IceMan Navi +ShadowMan Navi +ElecMan Navi +KnightMan Navi +PlantMan Navi +NapalmMan Navi +Bass Navi \ No newline at end of file From 85a85672e434fc4df288828d26fe5a1beb9c7ed2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 15 Feb 2019 21:41:04 -0800 Subject: [PATCH 016/429] GBA Peripherals: Start implementing Progress Gate --- include/mgba/gba/interface.h | 7 + res/chip-names-5.txt | 379 +++++++++++++++++++++++++++++ src/gba/extra/battlechip.c | 37 ++- src/platform/qt/BattleChipView.cpp | 19 ++ src/platform/qt/BattleChipView.ui | 60 ++++- src/platform/qt/CoreController.cpp | 8 + src/platform/qt/CoreController.h | 1 + src/platform/qt/Window.cpp | 7 +- src/platform/qt/resources.qrc | 1 + 9 files changed, 501 insertions(+), 18 deletions(-) create mode 100644 res/chip-names-5.txt diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 0c61363e3..14eabc750 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -60,12 +60,19 @@ struct GBASIODriver { void GBASIOJOYCreate(struct GBASIODriver* sio); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); +enum GBASIOBattleChipGateFlavor { + GBA_FLAVOR_BATTLECHIP_GATE = 4, + GBA_FLAVOR_PROGRESS_GATE = 5, + GBA_FLAVOR_BEAST_LINK_GATE = 6, +}; + struct GBASIOBattlechipGate { struct GBASIODriver d; struct mTimingEvent event; uint16_t chipId; uint16_t data[2]; int state; + int flavor; }; void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt new file mode 100644 index 000000000..487d219da --- /dev/null +++ b/res/chip-names-5.txt @@ -0,0 +1,379 @@ +Cannon +Hi Cannon +Mega Cannon +Air Shot +Air Hockey + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Fanfare + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ProtoMan Navi +NumberMan Navi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 40b80e3ec..259f958a5 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -26,6 +26,8 @@ enum { enum { BATTLECHIP_OK = 0xFFC6, + PROGRESS_GATE_OK = 0xFFC7, + BEAST_LINK_GATE_OK = 0xFFC8, BATTLECHIP_CONTINUE = 0xFFFF, }; @@ -46,11 +48,13 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->event.context = gate; gate->event.callback = _battlechipTransferEvent; gate->event.priority = 0x80; + + gate->chipId = 0; + gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE; } bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; - gate->chipId = 0; return true; } @@ -100,6 +104,20 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle mLOG(GBA_BATTLECHIP, DEBUG, "> %04X", cmd); + uint16_t ok; + switch (gate->flavor) { + case GBA_FLAVOR_BATTLECHIP_GATE: + default: + ok = BATTLECHIP_OK; + break; + case GBA_FLAVOR_PROGRESS_GATE: + ok = PROGRESS_GATE_OK; + break; + case GBA_FLAVOR_BEAST_LINK_GATE: + ok = BEAST_LINK_GATE_OK; + break; + } + switch (gate->state) { case BATTLECHIP_STATE_COMMAND: mLOG(GBA_BATTLECHIP, DEBUG, "C %04X", cmd); @@ -112,6 +130,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xA3B0: case 0xA3C0: case 0xA3D0: + case 0xA6C0: gate->state = -1; // Fall through case 0x5379: @@ -120,14 +139,22 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x537C: case 0x537D: case 0x537E: + case 0xC4D8: case 0xD979: case 0xD97A: case 0xD97B: case 0xD97C: case 0xD97D: case 0xD97E: - reply = BATTLECHIP_OK; + reply = ok; break; + case 0x424A: + case 0x424B: + case 0x424C: + case 0x424D: + case 0x424E: + case 0x424F: + case 0x4250: case 0x5745: case 0x5746: case 0x5747: @@ -150,12 +177,12 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case BATTLECHIP_STATE_DATA_0: reply = gate->data[0]; gate->data[0] += 3; - gate->data[0] &= 0xF0FF; + gate->data[0] &= 0x00FF; break; case BATTLECHIP_STATE_DATA_1: reply = gate->data[1]; gate->data[1] -= 3; - gate->data[1] |= 0xFE00; + gate->data[1] |= 0xFC00; break; case BATTLECHIP_STATE_ID: reply = gate->chipId; @@ -165,7 +192,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle reply = 0; break; case BATTLECHIP_STATE_END: - reply = BATTLECHIP_OK; + reply = ok; gate->state = -1; break; } diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 4f6b6a4b3..d101c18f4 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -27,6 +27,24 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); connect(controller.get(), &CoreController::stopping, this, &QWidget::close); + connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { + if (on) { + setFlavor(4); + } + }); + connect(m_ui.gateProgress, &QAbstractButton::toggled, this, [this](bool on) { + if (on) { + setFlavor(5); + } + }); + connect(m_ui.gateBeastLink, &QAbstractButton::toggled, this, [this](bool on) { + if (on) { + setFlavor(6); + } + }); + + + m_controller->attachBattleChipGate(); setFlavor(4); } @@ -35,6 +53,7 @@ BattleChipView::~BattleChipView() { } void BattleChipView::setFlavor(int flavor) { + m_controller->setBattleChipFlavor(flavor); loadChipNames(flavor); } diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 092663ae7..63290a93c 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -7,46 +7,92 @@ 0 0 426 - 152 + 278 BattleChip Gate - + Inserted - + Chip ID - + - Chip Name + Chip name - + 65535 - + + + + + Gate type + + + + + + + Progress &Gate + + + gate + + + + + + + Ba&ttleChip Gate + + + true + + + gate + + + + + + + false + + + Beast &Link Gate + + + gate + + + + + + diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index c5e8850ec..ef641b3a1 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -750,6 +750,14 @@ void CoreController::setBattleChipId(uint16_t id) { Interrupter interrupter(this); m_battlechip.chipId = id; } + +void CoreController::setBattleChipFlavor(int flavor) { + if (platform() != PLATFORM_GBA) { + return; + } + Interrupter interrupter(this); + m_battlechip.flavor = flavor; +} #endif void CoreController::setAVStream(mAVStream* stream) { diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index b7a740626..dbcec9cf3 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -143,6 +143,7 @@ public slots: void attachBattleChipGate(); void detachBattleChipGate(); void setBattleChipId(uint16_t id); + void setBattleChipFlavor(int flavor); #endif void setAVStream(mAVStream*); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index a49f3075f..ce3b586b5 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1365,12 +1365,7 @@ void Window::setupMenu(QMenuBar* menubar) { #ifdef M_CORE_GBA QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu); - connect(bcGate, &QAction::triggered, [this]() { - BattleChipView* view = new BattleChipView(m_controller); - openView(view); - m_controller->attachBattleChipGate(); - - }); + connect(bcGate, &QAction::triggered, openControllerTView()); addControlledAction(emulationMenu, bcGate, "bcGate"); m_gbaActions.append(bcGate); m_gameActions.append(bcGate); diff --git a/src/platform/qt/resources.qrc b/src/platform/qt/resources.qrc index 80be2c8be..475ab337c 100644 --- a/src/platform/qt/resources.qrc +++ b/src/platform/qt/resources.qrc @@ -5,5 +5,6 @@ ../../../res/patrons.txt ../../../res/no-cam.png ../../../res/chip-names-4.txt + ../../../res/chip-names-5.txt From bf996df244cc4fe322c16ffbe550d4b2f600dc37 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 14:02:44 -0800 Subject: [PATCH 017/429] GBA Peripherals: Start filling in Progress Gate chip names (unchecked) --- res/chip-names-4.txt | 6 +- res/chip-names-5.txt | 348 +++++++++++++++++++++---------------------- 2 files changed, 177 insertions(+), 177 deletions(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index 3ffc433c8..ebd856004 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -54,9 +54,9 @@ Wind Racket Custom Sword Variable Sword Slasher -Thunderball 1 -Thunderball 2 -Thunderball 3 +Thunder Ball 1 +Thunder Ball 2 +Thunder Ball 3 Counter 1 Counter 2 Counter 3 diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index 487d219da..84bffa887 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -3,181 +3,181 @@ Hi Cannon Mega Cannon Air Shot Air Hockey - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Boomer +Silence +Tornado +Wide Shot 1 +Wide Shot 2 +Wide Shot 3 +Mark Cannon 1 +Mark Cannon 2 +Mark Cannon 3 +Vulcan 1 +Vulcan 2 +Vulcan 3 +Spreader +Thunder Ball +Ice Seed +Pulsar 1 +Pulsar 2 +Pulsar 3 +Space Shake 1 +Space Shake 2 +Space Shake 3 +Static +Life Sync +Mini Boomer +Energy Bomb +Mega Energy Bomb +Gun del Sol 1 +Gun del Sol 2 +Gun del Sol 3 +Quake 1 +Quake 2 +Quake 3 +Crack Bomb +Paralyze Bomb +Reset Bomb +Bug Bomb +Grass Seed +Lava Seed +Cannon Ball +Geyser +Black Bomb +Sea Seed +Sword +Wide Sword +Long Sword +Wide Blade +Long Blade +Wind Racket +Custom Sword +Variable Sword +Slasher +Moon Blade 1 +Moon Blade 2 +Moon Blade 3 +Katana 1 +Katana 2 +Katana 3 +Tank Cannon 1 +Tank Cannon 2 +Tank Cannon 3 +Red Fruit 1 +Red Fruit 2 +Red Fruit 3 +Skully 1 +Skully 2 +Skully 3 +Drill Arm 1 +Drill Arm 2 +Drill Arm 3 +Time Bomb 1 +Time Bomb 2 +Time Bomb3 +Voltz 1 +Voltz 2 +Voltz 3 +Lance +Yo-Yo +Wind +Fan +Boy's Bomb 1 +Boy's Bomb 2 +Boy's Bomb 3 +Guard 1 +Guard 2 +Guard 3 +Crack Out +Double Crack +Triple Crack +Magnum +Grab Gel +Snake +Circle Gun +Mine +Rock Cube Fanfare - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Discord +Timpani +VDoll +Asteroid 1 +Asteroid 2 +Asteroid 3 +Recovery 10 +Recovery 30 +Recovery 50 +Recovery 80 +Recovery 120 +Recovery 150 +Recovery 200 +Recovery 300 +Buster Up +Panel Grab +Area Grab +Grab Revenge +Grab Banish +Slow Gauge +Fast Gauge +Panel Return +Geddon 1 +Geddon 2 +Geddon 3 +Rainy Day +Color Point +Element Rage +Blinder +Air Spin 1 +Air Spin 2 +Air Spin 3 +Invisible +Bubble Wrap +Barrier +Barrier 100 +Barrier 200 +North Wind +Holy Panel +Anti Fire +Anti Water +Anti Electric +Anti Wood +Anti Navi +Anti Damage +Anti Sword +Anti Recovery +Copy Damage +Attck +10 +Navi +20 +Fire Hit 1 +Fire Hit 2 +Fire Hit 3 +Hot Body 1 +Hot Body 2 +Hot Body 3 +Aqua Whirl 1 +Aqua Whirl 2 +Aqua Whirl 3 +Side Bubble 1 +Side Bubble 2 +Side Bubble 3 +Elec Reel 1 +Elec Reel 2 +Elec Reel 3 +Custom Volt 1 +Custom Volt 2 +Custom Volt 3 +Curse Shield 1 +Curse Shield 2 +Curse Shield 3 +Wave Pit +Red Wave +Mud Wave +Cactus Ball 1 +Cactus Ball 2 +Cactus Ball 3 +Woody Nose 1 +Woody Nose 2 +Woody Nose 3 From fb473e5eb43fad9e4fa57345f64923c51b26071b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 14:05:09 -0800 Subject: [PATCH 018/429] GBA Peripherals: Partial Beast Link Gate support --- include/mgba/gba/interface.h | 1 + res/chip-names-6.txt | 399 +++++++++++++++++++++++++++++ src/gba/core.c | 1 + src/gba/extra/battlechip.c | 41 ++- src/platform/qt/BattleChipView.cpp | 15 +- src/platform/qt/BattleChipView.ui | 3 - src/platform/qt/resources.qrc | 1 + 7 files changed, 455 insertions(+), 6 deletions(-) create mode 100644 res/chip-names-6.txt diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 14eabc750..e620c108e 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -64,6 +64,7 @@ enum GBASIOBattleChipGateFlavor { GBA_FLAVOR_BATTLECHIP_GATE = 4, GBA_FLAVOR_PROGRESS_GATE = 5, GBA_FLAVOR_BEAST_LINK_GATE = 6, + GBA_FLAVOR_BEAST_LINK_GATE_US = 7, }; struct GBASIOBattlechipGate { diff --git a/res/chip-names-6.txt b/res/chip-names-6.txt new file mode 100644 index 000000000..2d8e0bacf --- /dev/null +++ b/res/chip-names-6.txt @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/gba/core.c b/src/gba/core.c index 193d6970a..7d00f963c 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -535,6 +535,7 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { break; case mPERIPH_GBA_BATTLECHIP_GATE: GBASIOSetDriver(&gba->sio, periph, SIO_MULTI); + GBASIOSetDriver(&gba->sio, periph, SIO_NORMAL_32); break; default: return; diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 259f958a5..75eb11bea 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -27,7 +27,8 @@ enum { enum { BATTLECHIP_OK = 0xFFC6, PROGRESS_GATE_OK = 0xFFC7, - BEAST_LINK_GATE_OK = 0xFFC8, + BEAST_LINK_GATE_OK = 0xFFC4, + BEAST_LINK_GATE_US_OK = 0xFF00, BATTLECHIP_CONTINUE = 0xFFFF, }; @@ -87,13 +88,29 @@ uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t } void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { - int32_t cycles = GBASIOCyclesPerTransfer[gate->d.p->multiplayerControl.baud][1]; + int32_t cycles; + if (gate->d.p->mode == SIO_NORMAL_32) { + cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; + } else { + cycles = GBASIOCyclesPerTransfer[gate->d.p->multiplayerControl.baud][1]; + } + mTimingDeschedule(&gate->d.p->p->timing, &gate->event); mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); } void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate) { struct GBASIOBattlechipGate* gate = user; + if (gate->d.p->mode == SIO_NORMAL_32) { + gate->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = 0; + gate->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0; + gate->d.p->normalControl.start = 0; + if (gate->d.p->normalControl.irq) { + GBARaiseIRQ(gate->d.p->p, IRQ_SIO); + } + return; + } + uint16_t cmd = gate->d.p->p->memory.io[REG_SIOMLT_SEND >> 1]; uint16_t reply = 0xFFFF; gate->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = cmd; @@ -116,6 +133,9 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case GBA_FLAVOR_BEAST_LINK_GATE: ok = BEAST_LINK_GATE_OK; break; + case GBA_FLAVOR_BEAST_LINK_GATE_US: + ok = BEAST_LINK_GATE_US_OK; + break; } switch (gate->state) { @@ -139,7 +159,18 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x537C: case 0x537D: case 0x537E: + case 0xB7D3: + case 0xB7D4: + case 0xB7D5: + case 0xB7D6: + case 0xB7D7: + case 0xB7D8: case 0xC4D8: + case 0xC4D9: + case 0xC4DA: + case 0xC4DB: + case 0xC4DC: + case 0xC4DD: case 0xD979: case 0xD97A: case 0xD97B: @@ -148,6 +179,12 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xD97E: reply = ok; break; + case 0x3545: + case 0x3546: + case 0x3547: + case 0x3548: + case 0x3549: + case 0x354A: case 0x424A: case 0x424B: case 0x424C: diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index d101c18f4..4f5206415 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -39,7 +39,16 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg }); connect(m_ui.gateBeastLink, &QAbstractButton::toggled, this, [this](bool on) { if (on) { - setFlavor(6); + char title[9]; + CoreController::Interrupter interrupter(m_controller); + mCore* core = m_controller->thread()->core; + title[8] = '\0'; + core->getGameCode(core, title); + if (title[7] == 'E' || title[7] == 'P') { + setFlavor(7); + } else { + setFlavor(6); + } } }); @@ -69,6 +78,10 @@ void BattleChipView::loadChipNames(int flavor) { QStringList chipNames; chipNames.append(tr("(None)")); + if (flavor == 7) { + flavor = 6; + } + QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); file.open(QIODevice::ReadOnly | QIODevice::Text); while (true) { diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 63290a93c..ba95e455a 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -77,9 +77,6 @@ - - false - Beast &Link Gate diff --git a/src/platform/qt/resources.qrc b/src/platform/qt/resources.qrc index 475ab337c..ea08c5e39 100644 --- a/src/platform/qt/resources.qrc +++ b/src/platform/qt/resources.qrc @@ -6,5 +6,6 @@ ../../../res/no-cam.png ../../../res/chip-names-4.txt ../../../res/chip-names-5.txt + ../../../res/chip-names-6.txt From 8e75d420f436ba5d46a34a0d08b88dd160e9553e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 15:59:03 -0800 Subject: [PATCH 019/429] GBA Peripherals: Fill in Progress Gate chip names --- res/chip-names-5.txt | 302 ++++++++++++++++++++----------------------- 1 file changed, 137 insertions(+), 165 deletions(-) diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index 84bffa887..1501aacf9 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -184,6 +184,132 @@ Woody Nose 3 +Dark Circle +Dark Sword +Dark Invis +Dark Plus +Dark Lance +Dark Wide +Dark Thunder +Dark Recovery +Dark Meteor +Dark Drill +Dark Tornado +Dark Sonic + + +Life Aura +Muramasa +Guardian +Anubis +Attack +30 +Bug Fix +Double Point +Sanctuary +Full Custom +Meteors +Number Ball +Jealousy +Poltergeist +Black Wing +Otenko +Justice One +Neo Variable +Z Saber +Gun del Sol EX +Super Vulcan +Roll +Roll SP +Roll DS +GyroMan +GyroMan SP +GyroMan DS +NapalmMan +NapalmMan SP +NapalmMan DS +SearchMan +SearchMan SP +SearchMan DS +MagnetMan +MagnetMan SP +MagnetMan DS +Meddy +Meddy SP +Meddy DS +ProtoMan +ProtoMan SP +ProtoMan DS +NumberMan +NumberMan SP +NumberMan DS +Colonel +Colonel SP +Colonel DS +ShadowMan +ShadowMan SP +ShadowMan DS +TomahawkMan +TomahawkMan SP +TomahawkMan DS +KnightMan +KnightMan SP +KnightMan DS +ToadMan +ToadMan SP +ToadMan DS +ShadeMan +ShadeMan SP +ShadeMan DS +BlizzardMan +BlizzardMan SP +BlizzardMan DS +CloudMan +CloudMan SP +CloudMan DS +CosmoMan +CosmoMan SP +CosmoMan DS +LarkMan +LarkMan SP +LarkMan DS +GridMan +GridMan SP +GridMan DS +Django +Django SP +Django DS +Cannon Mode +Cannon Ball +Sword Mode +Yo-Yo Mode +Drill Mode +L Curse Shield +L Step Sword +L Counter +Elememt Power +Final Gun + + + + + + + + + + +Bass +Delta Ray +Bug Curse +Meteor Knuckle +Omega Racket +Bass Another +Holy Dream +Big Hook +Cross Divide +Bug Charge +Phoenix +Death Phoenix @@ -201,137 +327,11 @@ Woody Nose 3 +MegaMan Navi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SearchMan Navi ProtoMan Navi @@ -340,40 +340,12 @@ NumberMan Navi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ShadowMan Navi +NapalmMan Navi +KnightMan Navi +ToadMan Navi +MagnetMan Navi +GyroMan Navi +Colonel Navi +Meddy Navi +TomahawkMan Navi \ No newline at end of file From a64236ce21800d5960f852176cfaa9f80c9b0dbd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 16:16:02 -0800 Subject: [PATCH 020/429] Qt: Auto-select correct Gate type --- src/platform/qt/BattleChipView.cpp | 37 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 4f5206415..d0522b157 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -18,6 +18,14 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg { m_ui.setupUi(this); + char title[9]; + CoreController::Interrupter interrupter(m_controller); + mCore* core = m_controller->thread()->core; + title[8] = '\0'; + core->getGameCode(core, title); + QString qtitle(title); + + connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { m_ui.inserted->setChecked(Qt::Unchecked); }); @@ -29,32 +37,33 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { if (on) { - setFlavor(4); + setFlavor(GBA_FLAVOR_BATTLECHIP_GATE); } }); connect(m_ui.gateProgress, &QAbstractButton::toggled, this, [this](bool on) { if (on) { - setFlavor(5); + setFlavor(GBA_FLAVOR_PROGRESS_GATE); } }); - connect(m_ui.gateBeastLink, &QAbstractButton::toggled, this, [this](bool on) { + connect(m_ui.gateBeastLink, &QAbstractButton::toggled, this, [this, qtitle](bool on) { if (on) { - char title[9]; - CoreController::Interrupter interrupter(m_controller); - mCore* core = m_controller->thread()->core; - title[8] = '\0'; - core->getGameCode(core, title); - if (title[7] == 'E' || title[7] == 'P') { - setFlavor(7); + if (qtitle.endsWith('E') || qtitle.endsWith('P')) { + setFlavor(GBA_FLAVOR_BEAST_LINK_GATE_US); } else { - setFlavor(6); + setFlavor(GBA_FLAVOR_BEAST_LINK_GATE); } } }); - m_controller->attachBattleChipGate(); setFlavor(4); + if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4")) { + m_ui.gateBattleChip->setChecked(Qt::Checked); + } else if (qtitle.startsWith("AGB-BRB") || qtitle.startsWith("AGB-BRK")) { + m_ui.gateProgress->setChecked(Qt::Checked); + } else if (qtitle.startsWith("AGB-BR5") || qtitle.startsWith("AGB-BR6")) { + m_ui.gateBeastLink->setChecked(Qt::Checked); + } } BattleChipView::~BattleChipView() { @@ -78,8 +87,8 @@ void BattleChipView::loadChipNames(int flavor) { QStringList chipNames; chipNames.append(tr("(None)")); - if (flavor == 7) { - flavor = 6; + if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) { + flavor = GBA_FLAVOR_BEAST_LINK_GATE; } QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); From 063375806f7365b7efcc9cc8f9bc50704a73d65a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 16:25:29 -0800 Subject: [PATCH 021/429] Qt: Prune empty chip names from list --- src/platform/qt/BattleChipView.cpp | 12 ++++++++++-- src/platform/qt/BattleChipView.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index d0522b157..e755e416d 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -29,8 +29,9 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { m_ui.inserted->setChecked(Qt::Unchecked); }); - connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.chipName, &QComboBox::setCurrentIndex); - connect(m_ui.chipName, static_cast(&QComboBox::currentIndexChanged), m_ui.chipId, &QSpinBox::setValue); + connect(m_ui.chipName, static_cast(&QComboBox::currentIndexChanged), m_ui.chipId, [this](int id) { + m_ui.chipId->setValue(m_chipIndexToId[id]); + }); connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); connect(controller.get(), &CoreController::stopping, this, &QWidget::close); @@ -87,17 +88,24 @@ void BattleChipView::loadChipNames(int flavor) { QStringList chipNames; chipNames.append(tr("(None)")); + m_chipIndexToId.clear(); if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) { flavor = GBA_FLAVOR_BEAST_LINK_GATE; } QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); file.open(QIODevice::ReadOnly | QIODevice::Text); + int id = 0; while (true) { QByteArray line = file.readLine(); if (line.isEmpty()) { break; } + ++id; + if (line.trimmed().isEmpty()) { + continue; + } + m_chipIndexToId[chipNames.length()] = id; chipNames.append(QString::fromUtf8(line).trimmed()); } diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 14b61a043..7dbdc9561 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -33,6 +33,7 @@ private: Ui::BattleChipView m_ui; + QMap m_chipIndexToId; std::shared_ptr m_controller; }; From 5a08abacf126476d81215c87ab499d6d25cc6c8e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 16:54:41 -0800 Subject: [PATCH 022/429] Qt: Fix audio context holding onto closed game controller --- CHANGES | 1 + src/platform/qt/Window.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index ed5cb8375..274b3ee52 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,7 @@ Bugfixes: - GBA Memory: Fix a few AGBPrint crashes - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) + - Qt: Fix audio context holding onto closed game controller Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ce3b586b5..26c588d88 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -797,6 +797,11 @@ void Window::gameStopped() { m_fpsTimer.stop(); m_focusCheck.stop(); + if (m_audioProcessor) { + m_audioProcessor->stop(); + m_audioProcessor.reset(); + } + emit paused(false); } From 1c4b89d0f4219c1940c983b0f58ab7dbb45361ba Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Feb 2019 17:13:40 -0800 Subject: [PATCH 023/429] Switch: Fix gyroscope orientation (fixes #1300) --- CHANGES | 1 + src/platform/switch/main.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 274b3ee52..bac57d7c4 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Bugfixes: - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) - Qt: Fix audio context holding onto closed game controller + - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index e344ff44d..cde839743 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -463,7 +463,7 @@ int32_t _readGyroZ(struct mRotationSource* source) { UNUSED(source); SixAxisSensorValues sixaxis; hidSixAxisSensorValuesRead(&sixaxis, CONTROLLER_P1_AUTO, 1); - return sixaxis.gyroscope.z * 1.1e9f; + return sixaxis.gyroscope.z * -1.1e9f; } static int _batteryState(void) { From 83dfd9229bba84b34e5f28a544c39821ff20856e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 02:24:49 -0800 Subject: [PATCH 024/429] GBA Peripherals: Fix Beast Link Gate slotting --- src/gba/extra/battlechip.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 75eb11bea..4ba5043d9 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -177,6 +177,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xD97C: case 0xD97D: case 0xD97E: + case 0xE49A: reply = ok; break; case 0x3545: @@ -198,12 +199,12 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x5748: case 0x5749: case 0x574A: - case 0xFC00: // Resync gate->state = BATTLECHIP_STATE_UNK_0; break; default: mLOG(GBA_BATTLECHIP, STUB, "? %04X", cmd); + gate->state = -1; break; } break; From f7a994a44a91afac1fdc86753bf9dd6ef7d58c7d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 10:57:50 -0800 Subject: [PATCH 025/429] Qt: Fill in Beast Link Gate chip names from EXE6 translation patch names --- res/chip-names-6.txt | 899 ++++++++++++++++++++++++------------------- 1 file changed, 500 insertions(+), 399 deletions(-) diff --git a/res/chip-names-6.txt b/res/chip-names-6.txt index 2d8e0bacf..879ff0e70 100644 --- a/res/chip-names-6.txt +++ b/res/chip-names-6.txt @@ -1,399 +1,500 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Cannon +HiCannon +MegaCannon +AirShot +Vulcan1 +Vulcan2 +Vulcan3 +SuperVulcan +Spreader1 +Spreader2 +Spreader3 +TankCannon1 +TankCannon2 +TankCannon3 +GunDelSol1 +GunDelSol2 +GunDelSol3 +GunDelSolEX +Yo-Yo +FireBurner1 +FireBurner2 +FireBurner3 +WideShot +TrainArrow1 +TrainArrow2 +TrainArrow3 +BubbleStar1 +BubbleStar2 +BubbleStar3 +Thunder +DollThunder1 +DollThunder2 +DollThunder3 +ElecPulse1 +ElecPulse2 +ElecPulse3 +RiskyHoney1 +RiskyHoney2 +RiskyHoney3 +RollingLog1 +RollingLog2 +RollingLog3 +MachineGun1 +MachineGun2 +MachineGun3 +HeatDragon +ElecDragon +AquaDragon +WoodDragon +AirHockey +DrillArm +Tornado +Static +MiniBomb +EnergyBomb +MegaEnergyBomb +FlashBomb1 +FlashBomb2 +FlashBomb3 +BlackBomb +AquaNeedle1 +AquaNeedle2 +AquaNeedle3 +CornShot1 +CornShot2 +CornShot3 +BugBomb +GrassSeed +IceSeed +PoisonSeed +Sword +WideSword +LongSword +WideBlade +LongBlade +FireSword +AquaSword +ElecSword +BambooSword +WindRacket +StepSword +VariableSword +NeoVariSword +MoonBlade +Muramasa +MachineSword +ElementSword +AssassinSword +CrackShot +DoubleShot +TripleShot +WaveArm1 +WaveArm2 +WaveArm3 +AuraHead1 +AuraHead2 +AuraHead3 +LittleBoiler1 +LittleBoiler2 +LittleBoiler3 +SandWorm1 +SandWorm2 +SandWorm3 +AirRaid1 +AirRaid2 +AirRaid3 +FireHit1 +FireHit2 +FireHit3 +BurnSquare1 +BurnSquare2 +BurnSquare3 +Sensor1 +Sensor2 +Sensor3 +Boomer +HiBoomer +MegaBoomer +Lance +GolemHit1 +GolemHit2 +GolemHit3 +IronShell1 +IronShell2 +IronShell3 +AirSpin1 +AirSpin2 +AirSpin3 +Wind +Fan +Reflector1 +Reflector2 +Reflector3 +Snake +SummonBlack1 +SummonBlack2 +SummonBlack3 +NumberBall +Meteors +JusticeOne +Magnum +CircleGun +RockCube +TimeBomb1 +Mine +Fanfare +Discord +Timpani +Silence +Vdoll +Guardian +Anubis +Otenko +Recover10 +Recover30 +Recover50 +Recover80 +Recover120 +Recover150 +Recover200 +Recover300 +PanelGrab +AreaGrab +GrabBanish +GrabRevenge +PanelReturn +Geddon +HolyPanel +Sanctuary +ComingRoad +GoingRoad +SlowGauge +FastGauge +FullCustom +BusterUp +BugFix +Invisible +Barrier +Barrier100 +Barrier200 +BubbleWrap +LifeAura +MagnetCoil +WhiteCapsule +Uninstall +AntiNavi +AntiDamage +AntiSword +AntiRecover +CopyDamage +LifeSync +Attack+10 +Navi+20 +ColorPoint +Attack+30 +DoublePoint +ElementTrap +ColonelArmy +BlizzardBall +TimeBomb2 +TimeBomb3 +BigBomb +DarkTornado +DarkCircle +DarkMeteors +DarkLance +DarkWide + + + + + + + + + + + + + +Roll +Roll2 +Roll3 +ProtoMan +ProtoManEX +ProtoManSP +HeatMan +HeatManEX +HeatManSP +ElecMan +ElecManEX +ElecManSP +SlashMan +SlashManEX +SlashManSP +EraseMan +EraseManEX +EraseManSP +ChargeMan +ChargeManEX +ChargeManSP +SpoutMan +SpoutManEX +SpoutManSP +TomahawkMan +TomahawkManEX +TomahawkManSP +TenguMan +TenguManEX +TenguManSP +GroundMan +GroundManEX +GroundManSP +DustMan +DustManEX +DustManSP +BlastMan +BlastManEX +BlastManSP +DiveMan +DiveManEX +DiveManSP +CircusMan +CircusManEX +CircusManSP +JudgeMan +JudgeManEX +JudgeManSP +ElementMan +ElementManEX +ElementManSP +Colonel +ColonelEX +ColonelSP +Count +CountEX +CountSP +Django +Django2 +Django3 +PunchArm +NeedleArm +PuzzleArm +BoomerArm +SynchroTrigger +DarkSword +DarkThunder +DarkRecover +DarkInvisible +DarkPlus + + + + + + + + + + +Bass +BigHook +DeltaRay +ColonelForce +BugRiseSword +BassAnomaly +MeteorKnuckle +CrossDivide +HubBatch +BugDeathThunder +DoubleBeast +Gregar +Falzar + + + + + + + +MegaManV1 +MegaManV2 +MegaManV3 +MegaManV4 +MegaManV5 +MegaManV6 +MegaManV7 +MegaManV8 +MegaManV9 +MegaManV10 +MegaManV11 +MegaManV12 +MegaManV13 +MegaManV14 +MegaManSP +HeatManV1 +HeatManV2 +HeatManV3 +HeatManV4 +HeatManV5 +HeatManV6 +HeatManV7 +HeatManV8 +HeatManV9 +HeatManV10 +HeatManV11 +HeatManV12 +HeatManV13 +HeatManV14 +HeatManSP +ElecManV1 +ElecManV2 +ElecManV3 +ElecManV4 +ElecManV5 +ElecManV6 +ElecManV7 +ElecManV8 +ElecManV9 +ElecManV10 +ElecManV11 +ElecManV12 +ElecManV13 +ElecManV14 +ElecManSP +SlashManV1 +SlashManV2 +SlashManV3 +SlashManV4 +SlashManV5 +SlashManV6 +SlashManV7 +SlashManV8 +SlashManV9 +SlashManV10 +SlashManV11 +SlashManV12 +SlashManV13 +SlashManV14 +SlashManSP +EraseManV1 +EraseManV2 +EraseManV3 +EraseManV4 +EraseManV5 +EraseManV6 +EraseManV7 +EraseManV8 +EraseManV9 +EraseManV10 +EraseManV11 +EraseManV12 +EraseManV13 +EraseManV14 +EraseManSP +ChargeManV1 +ChargeManV2 +ChargeManV3 +ChargeManV4 +ChargeManV5 +ChargeManV6 +ChargeManV7 +ChargeManV8 +ChargeManV9 +ChargeManV10 +ChargeManV11 +ChargeManV12 +ChargeManV13 +ChargeManV14 +ChargeManSP +SpoutManV1 +SpoutManV2 +SpoutManV3 +SpoutManV4 +SpoutManV5 +SpoutManV6 +SpoutManV7 +SpoutManV8 +SpoutManV9 +SpoutManV10 +SpoutManV11 +SpoutManV12 +SpoutManV13 +SpoutManV14 +SpoutManSP +TomahawkManV1 +TomahawkManV2 +TomahawkManV3 +TomahawkManV4 +TomahawkManV5 +TomahawkManV6 +TomahawkManV7 +TomahawkManV8 +TomahawkManV9 +TomahawkManV10 +TomahawkManV11 +TomahawkManV12 +TomahawkManV13 +TomahawkManV14 +TomahawkManSP +TenguManV1 +TenguManV2 +TenguManV3 +TenguManV4 +TenguManV5 +TenguManV6 +TenguManV7 +TenguManV8 +TenguManV9 +TenguManV10 +TenguManV11 +TenguManV12 +TenguManV13 +TenguManV14 +TenguManSP +GroundManV1 +GroundManV2 +GroundManV3 +GroundManV4 +GroundManV5 +GroundManV6 +GroundManV7 +GroundManV8 +GroundManV9 +GroundManV10 +GroundManV11 +GroundManV12 +GroundManV13 +GroundManV14 +GroundManSP +DustManV1 +DustManV2 +DustManV3 +DustManV4 +DustManV5 +DustManV6 +DustManV7 +DustManV8 +DustManV9 +DustManV10 +DustManV11 +DustManV12 +DustManV13 +DustManV14 +DustManSP +ProtoManV1 +ProtoManV2 +ProtoManV3 +ProtoManV4 +ProtoManV5 +ProtoManV6 +ProtoManV7 +ProtoManV8 +ProtoManV9 +ProtoManV10 +ProtoManV11 +ProtoManV12 +ProtoManV13 +ProtoManV14 +ProtoManSP \ No newline at end of file From f475a5d8c70aecb6eae27370dd7e1fb95d1c890b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 11:01:08 -0800 Subject: [PATCH 026/429] Qt: Update BN4/5 chip names in accordance with EXE6 translation patch names --- res/chip-names-4.txt | 508 +++++++++++++++++++++--------------------- res/chip-names-5.txt | 510 +++++++++++++++++++++---------------------- 2 files changed, 509 insertions(+), 509 deletions(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index ebd856004..a7f147f54 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -1,315 +1,315 @@ Cannon -Hi Cannon -Mega Cannon -Air Shot +HiCannon +MegaCannon +AirShot Blizzard -Heat Breath +HeatBreath Silence Tornado -Wide Shot 1 -Wide Shot 2 -Wide Shot 3 -Flame Line 1 -Flame Line 2 -Flame Line 3 -Vulcan 1 -Vulcan 2 -Vulcan 3 +WideShot1 +WideShot2 +WideShot3 +FlameLine1 +FlameLine2 +FlameLine3 +Vulcan1 +Vulcan2 +Vulcan3 Spreader -Heat Shot -Heat V -Heat Side +HeatShot +HeatV +HeatSide Bubbler -Bubble V -Bubble Side -Element Flare -Element Ice +BubbleV +BubbleSide +ElementFlare +ElementIce Static -Life Sync -Mini Boomer -Energy Bomb -Mega Energy Bomb -Gun del Sol 1 -Gun del Sol 2 -Gun del Sol 3 -Mag Bolt 1 -Mag Bolt 2 -Mag Bolt 3 -Binder 1 -Binder 2 -Binder 3 -Bug Bomb -Elec Shock -Wood Powder +LifeSync +MiniBoomer +EnergyBomb +MegaEnergyBomb +GunDelSol1 +GunDelSol2 +GunDelSol3 +MagBolt1 +MagBolt2 +MagBolt3 +Binder1 +Binder2 +Binder3 +BugBomb +ElecShock +WoodPowder Cannonball Geyser Geyser -Sand Ring +SandRing Sword -Wide Sword -Long Sword -Wide Blade -Long Blade -Wind Racket -Custom Sword -Variable Sword +WideSword +LongSword +WideBlade +LongBlade +WindRacket +CustomSword +VariableSword Slasher -Thunder Ball 1 -Thunder Ball 2 -Thunder Ball 3 -Counter 1 -Counter 2 -Counter 3 -Air Hockey 1 -Air Hockey 2 -Air Hockey 3 -Circle Gun 1 -Circle Gun 2 -Circle Gun 3 -Twin Fang 1 -Twin Fang 2 -Twin Fang 3 -White Web 1 -White Web 2 -White Web 3 -Boomerang 1 -Boomerang 2 -Boomerang 3 -Side Bamboo 1 -Side Bamboo 2 -Side Bamboo 3 +ThunderBall1 +ThunderBall2 +ThunderBall3 +Counter1 +Counter2 +Counter3 +AirHockey1 +AirHockey2 +AirHockey3 +CircleGun1 +CircleGun2 +CircleGun3 +TwinFang1 +TwinFang2 +TwinFang3 +WhiteWeb1 +WhiteWeb2 +WhiteWeb3 +Boomerang1 +Boomerang2 +Boomerang3 +SideBamboo1 +SideBamboo2 +SideBamboo3 Lance Hole -Boy's Bomb 1 -Boy's Bomb 2 -Boy's Bomb 3 -Guard 1 -Guard 2 -Guard 3 +Boy'sBomb1 +Boy'sBomb2 +Boy'sBomb3 +Guard1 +Guard2 +Guard3 Magnum -Grab Gel +GrabGel Snake -Time Bomb +TimeBomb Mine -Rock Cube +RockCube Fanfare Discord Timpani -VDoll -Big Hammer 1 -Big Hammer 2 -Big Hammer 3 -Grab Revenge -Grab Banish -Geddon 1 -Geddon 2 -Geddon 3 -Element Leaf -Color Point -Element Sand -Moko Rush 1 -Moko Rush 2 -Moko Rush 3 -North Wind -Anti Fire -Anti Water -Anti Electric -Anti Wood -Anti Navi -Anti Damage -Anti Sword -Anti Recover -Copy Damage -Attack +10 -Navi +20 -Roll Arrow 1 -Roll Arrow 2 -Roll Arrow 3 -Guts Punch 1 -Guts Punch 2 -Guts Punch 3 -Propeller Bomb 1 -Propeller Bomb 2 -Propeller Bomb 3 -Search Bomb 1 -Search Bomb 2 -Search Bomb 3 -Meteors 1 -Meteors 2 -Meteors 3 -Lightning 1 -Lightning 2 -Lightning 3 -Hawk Cut 1 -Hawk Cut 2 -Hawk Cut 3 -Number Ball 1 -Number Ball 2 -Number Ball 3 -Metal Gear 1 -Metal Gear 2 -Metal Gear 3 -Panel Shoot 1 -Panel Shoot 2 -Panel Shoot 3 -Aqua Upper 1 -Aqua Upper 2 -Aqua Upper 3 -Green Wood 1 -Green Wood 2 -Green Wood 3 +Vdoll +BigHammer1 +BigHammer2 +BigHammer3 +GrabRevenge +GrabBanish +Geddon1 +Geddon2 +Geddon3 +ElementLeaf +ColorPoint +ElementSand +MokoRush1 +MokoRush2 +MokoRush3 +NorthWind +AntiFire +AntiWater +AntiElectric +AntiWood +AntiNavi +AntiDamage +AntiSword +AntiRecover +CopyDamage +Attack+10 +Navi+20 +RollArrow1 +RollArrow2 +RollArrow3 +GutsPunch1 +GutsPunch2 +GutsPunch3 +PropellerBomb1 +PropellerBomb2 +PropellerBomb3 +SearchBomb1 +SearchBomb2 +SearchBomb3 +Meteors1 +Meteors2 +Meteors3 +Lightning1 +Lightning2 +Lightning3 +HawkCut1 +HawkCut2 +HawkCut3 +NumberBall1 +NumberBall2 +NumberBall3 +MetalGear1 +MetalGear2 +MetalGear3 +PanelShoot1 +PanelShoot2 +PanelShoot3 +AquaUpper1 +AquaUpper2 +AquaUpper3 +GreenWood1 +GreenWood2 +GreenWood3 Muramasa Guardian Anubis -Double Point -Full Custom -Shooting Star -Bug Chain +DoublePoint +FullCustom +ShootingStar +BugChain Jealousy -Element Dark -Black Wing -God Hammer -Dark Line -Neo Variable -Z Saber -Gun del Sol EX -Super Vulcan +ElementDark +BlackWing +GodHammer +DarkLine +NeoVariable +ZSaber +GunDelSolEX +SuperVulcan Roll -Roll SP -Roll DS +RollSP +RollDS GutsMan -GutsMan SP -GutsMan DS +GutsManSP +GutsManDS WindMan -WindMan SP -WindMan DS +WindManSP +WindManDS SearchMan -SearchMan SP -SearchMan DS +SearchManSP +SearchManDS FireMan -FireMan SP -FireMan DS +FireManSP +FireManDS ThunderMan -ThunderMan SP -ThunderMan DS +ThunderManSP +ThunderManDS ProtoMan -ProtoMan SP -ProtoMan DS +ProtoManSP +ProtoManDS NumberMan -NumberMan SP -NumberMan DS +NumberManSP +NumberManDS MetalMan -MetalMan SP -MetalMan DS +MetalManSP +MetalManDS JunkMan -JunkMan SP -JunkMan DS +JunkManSP +JunkManDS AquaMan -AquaMan SP -AquaMan DS +AquaManSP +AquaManDS WoodMan -WoodMan SP -WoodMan DS +WoodManSP +WoodManDS TopMan -TopMan SP -TopMan DS +TopManSP +TopManDS ShadeMan -ShadeMan SP -ShadeMan DS +ShadeManSP +ShadeManDS BurnerMan -BurnerMan SP -BurnerMan DS +BurnerManSP +BurnerManDS ColdMan -ColdMan SP -ColdMan DS +ColdManSP +ColdManDS SparkMan -SparkMan SP -SparkMan DS +SparkManSP +SparkManDS LaserMan -LaserMan SP -LaserMan DS +LaserManSP +LaserManDS KendoMan -KendoMan SP -KendoMan DS +KendoManSP +KendoManDS VideoMan -VideoMan SP -VideoMan DS +VideoManSP +VideoManDS Marking -Cannon Mode -Cannonball Mode -Sword Mode -Fire Plus -Thunder Plus -Aqua Power -Wood Power -Black Weapon -Final Gun +CannonMode +CannonballMode +SwordMode +FirePlus +ThunderPlus +AquaPower +WoodPower +BlackWeapon +FinalGun Bass -Delta Ray -Bug Curse -Red Sun -Bass Another -Holy Dream -Blue Moon -Bug Charge +DeltaRay +BugCurse +RedSun +BassAnother +HolyDream +BlueMoon +BugCharge Wind Fan -Crack Out -Double Crack -Triple Crack -Recovery 10 -Recovery 30 -Recovery 50 -Recovery 80 -Recovery 120 -Recovery 150 -Recovery 200 -Recovery 300 +CrackOut +DoubleCrack +TripleCrack +Recover10 +Recover30 +Recover50 +Recover80 +Recover120 +Recover150 +Recover200 +Recover300 Repair -Panel Grab -Area Grab -Slow Gauge -Fast Gauge -Panel Return +PanelGrab +AreaGrab +SlowGauge +FastGauge +PanelReturn Blinder -Pop Up +PopUp Invisible Barrier -Barrier 100 -Barrier 200 -Holy Panel +Barrier100 +Barrier200 +HolyPanel -Life Aura -Attack +30 -Bug Fix +LifeAura +Attack+30 +BugFix Sanctuary -Signal Red -Black Barrier -MegaMan Navi -Roll Navi -GutsMan Navi -WindMan Navi -SearchMan Navi -FireMan Navi -ThunderMan Navi -ProtoMan Navi -NumberMan Navi -MetalMan Navi -JunkMan Navi -AquaMan Navi -WoodMan Navi -StarMan Navi -IceMan Navi -ShadowMan Navi -ElecMan Navi -KnightMan Navi -PlantMan Navi -NapalmMan Navi -Bass Navi \ No newline at end of file +SignalRed +BlackBarrier +MegaManNavi +RollNavi +GutsManNavi +WindManNavi +SearchManNavi +FireManNavi +ThunderManNavi +ProtoManNavi +NumberManNavi +MetalManNavi +JunkManNavi +AquaManNavi +WoodManNavi +StarManNavi +IceManNavi +ShadowManNavi +ElecManNavi +KnightManNavi +PlantManNavi +NapalmManNavi +BassNavi \ No newline at end of file diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index 1501aacf9..9dfdb16e0 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -1,293 +1,293 @@ Cannon -Hi Cannon -Mega Cannon -Air Shot -Air Hockey +HiCannon +MegaCannon +AirShot +AirHockey Boomer Silence Tornado -Wide Shot 1 -Wide Shot 2 -Wide Shot 3 -Mark Cannon 1 -Mark Cannon 2 -Mark Cannon 3 -Vulcan 1 -Vulcan 2 -Vulcan 3 +WideShot1 +WideShot2 +WideShot3 +MarkCannon1 +MarkCannon2 +MarkCannon3 +Vulcan1 +Vulcan2 +Vulcan3 Spreader -Thunder Ball -Ice Seed -Pulsar 1 -Pulsar 2 -Pulsar 3 -Space Shake 1 -Space Shake 2 -Space Shake 3 +ThunderBall +IceSeed +Pulsar1 +Pulsar2 +Pulsar3 +SpaceShake1 +SpaceShake2 +SpaceShake3 Static -Life Sync -Mini Boomer -Energy Bomb -Mega Energy Bomb -Gun del Sol 1 -Gun del Sol 2 -Gun del Sol 3 -Quake 1 -Quake 2 -Quake 3 -Crack Bomb -Paralyze Bomb -Reset Bomb -Bug Bomb -Grass Seed -Lava Seed -Cannon Ball +LifeSync +MiniBoomer +EnergyBomb +MegaEnergyBomb +GunDelSol1 +GunDelSol2 +GunDelSol3 +Quake1 +Quake2 +Quake3 +CrackBomb +ParalyzeBomb +ResetBomb +BugBomb +GrassSeed +LavaSeed +CannonBall Geyser -Black Bomb -Sea Seed +BlackBomb +SeaSeed Sword -Wide Sword -Long Sword -Wide Blade -Long Blade -Wind Racket -Custom Sword -Variable Sword +WideSword +LongSword +WideBlade +LongBlade +WindRacket +CustomSword +VariableSword Slasher -Moon Blade 1 -Moon Blade 2 -Moon Blade 3 -Katana 1 -Katana 2 -Katana 3 -Tank Cannon 1 -Tank Cannon 2 -Tank Cannon 3 -Red Fruit 1 -Red Fruit 2 -Red Fruit 3 -Skully 1 -Skully 2 -Skully 3 -Drill Arm 1 -Drill Arm 2 -Drill Arm 3 -Time Bomb 1 -Time Bomb 2 -Time Bomb3 -Voltz 1 -Voltz 2 -Voltz 3 +MoonBlade1 +MoonBlade2 +MoonBlade3 +Katana1 +Katana2 +Katana3 +TankCannon1 +TankCannon2 +TankCannon3 +RedFruit1 +RedFruit2 +RedFruit3 +Skully1 +Skully2 +Skully3 +DrillArm1 +DrillArm2 +DrillArm3 +TimeBomb1 +TimeBomb2 +TimeBomb3 +Voltz1 +Voltz2 +Voltz3 Lance Yo-Yo Wind Fan -Boy's Bomb 1 -Boy's Bomb 2 -Boy's Bomb 3 -Guard 1 -Guard 2 -Guard 3 -Crack Out -Double Crack -Triple Crack +Boy'sBomb1 +Boy'sBomb2 +Boy'sBomb3 +Guard1 +Guard2 +Guard3 +CrackOut +DoubleCrack +TripleCrack Magnum -Grab Gel +GrabGel Snake -Circle Gun +CircleGun Mine -Rock Cube +RockCube Fanfare Discord Timpani -VDoll -Asteroid 1 -Asteroid 2 -Asteroid 3 -Recovery 10 -Recovery 30 -Recovery 50 -Recovery 80 -Recovery 120 -Recovery 150 -Recovery 200 -Recovery 300 -Buster Up -Panel Grab -Area Grab -Grab Revenge -Grab Banish -Slow Gauge -Fast Gauge -Panel Return -Geddon 1 -Geddon 2 -Geddon 3 -Rainy Day -Color Point -Element Rage +Vdoll +Asteroid1 +Asteroid2 +Asteroid3 +Recover10 +Recover30 +Recover50 +Recover80 +Recover120 +Recover150 +Recover200 +Recover300 +BusterUp +PanelGrab +AreaGrab +GrabRevenge +GrabBanish +SlowGauge +FastGauge +PanelReturn +Geddon1 +Geddon2 +Geddon3 +RainyDay +ColorPoint +ElementRage Blinder -Air Spin 1 -Air Spin 2 -Air Spin 3 +AirSpin1 +AirSpin2 +AirSpin3 Invisible -Bubble Wrap +BubbleWrap Barrier -Barrier 100 -Barrier 200 -North Wind -Holy Panel -Anti Fire -Anti Water -Anti Electric -Anti Wood -Anti Navi -Anti Damage -Anti Sword -Anti Recovery -Copy Damage -Attck +10 -Navi +20 -Fire Hit 1 -Fire Hit 2 -Fire Hit 3 -Hot Body 1 -Hot Body 2 -Hot Body 3 -Aqua Whirl 1 -Aqua Whirl 2 -Aqua Whirl 3 -Side Bubble 1 -Side Bubble 2 -Side Bubble 3 -Elec Reel 1 -Elec Reel 2 -Elec Reel 3 -Custom Volt 1 -Custom Volt 2 -Custom Volt 3 -Curse Shield 1 -Curse Shield 2 -Curse Shield 3 -Wave Pit -Red Wave -Mud Wave -Cactus Ball 1 -Cactus Ball 2 -Cactus Ball 3 -Woody Nose 1 -Woody Nose 2 -Woody Nose 3 +Barrier100 +Barrier200 +NorthWind +HolyPanel +AntiFire +AntiWater +AntiElectric +AntiWood +AntiNavi +AntiDamage +AntiSword +AntiRecovery +CopyDamage +Attck+10 +Navi+20 +FireHit1 +FireHit2 +FireHit3 +HotBody1 +HotBody2 +HotBody3 +AquaWhirl1 +AquaWhirl2 +AquaWhirl3 +SideBubble1 +SideBubble2 +SideBubble3 +ElecReel1 +ElecReel2 +ElecReel3 +CustomVolt1 +CustomVolt2 +CustomVolt3 +CurseShield1 +CurseShield2 +CurseShield3 +WavePit +RedWave +MudWave +CactusBall1 +CactusBall2 +CactusBall3 +WoodyNose1 +WoodyNose2 +WoodyNose3 -Dark Circle -Dark Sword -Dark Invis -Dark Plus -Dark Lance -Dark Wide -Dark Thunder -Dark Recovery -Dark Meteor -Dark Drill -Dark Tornado -Dark Sonic +DarkCircle +DarkSword +DarkInvis +DarkPlus +DarkLance +DarkWide +DarkThunder +DarkRecovery +DarkMeteor +DarkDrill +DarkTornado +DarkSonic -Life Aura +LifeAura Muramasa Guardian Anubis -Attack +30 -Bug Fix -Double Point +Attack+30 +BugFix +DoublePoint Sanctuary -Full Custom +FullCustom Meteors -Number Ball +NumberBall Jealousy Poltergeist -Black Wing +BlackWing Otenko -Justice One -Neo Variable -Z Saber -Gun del Sol EX -Super Vulcan +JusticeOne +NeoVariable +ZSaber +GunDelSolEX +SuperVulcan Roll -Roll SP -Roll DS +RollSP +RollDS GyroMan -GyroMan SP -GyroMan DS +GyroManSP +GyroManDS NapalmMan -NapalmMan SP -NapalmMan DS +NapalmManSP +NapalmManDS SearchMan -SearchMan SP -SearchMan DS +SearchManSP +SearchManDS MagnetMan -MagnetMan SP -MagnetMan DS +MagnetManSP +MagnetManDS Meddy -Meddy SP -Meddy DS +MeddySP +MeddyDS ProtoMan -ProtoMan SP -ProtoMan DS +ProtoManSP +ProtoManDS NumberMan -NumberMan SP -NumberMan DS +NumberManSP +NumberManDS Colonel -Colonel SP -Colonel DS +ColonelSP +ColonelDS ShadowMan -ShadowMan SP -ShadowMan DS +ShadowManSP +ShadowManDS TomahawkMan -TomahawkMan SP -TomahawkMan DS +TomahawkManSP +TomahawkManDS KnightMan -KnightMan SP -KnightMan DS +KnightManSP +KnightManDS ToadMan -ToadMan SP -ToadMan DS +ToadManSP +ToadManDS ShadeMan -ShadeMan SP -ShadeMan DS +ShadeManSP +ShadeManDS BlizzardMan -BlizzardMan SP -BlizzardMan DS +BlizzardManSP +BlizzardManDS CloudMan -CloudMan SP -CloudMan DS +CloudManSP +CloudManDS CosmoMan -CosmoMan SP -CosmoMan DS +CosmoManSP +CosmoManDS LarkMan -LarkMan SP -LarkMan DS +LarkManSP +LarkManDS GridMan -GridMan SP -GridMan DS +GridManSP +GridManDS Django -Django SP -Django DS -Cannon Mode -Cannon Ball -Sword Mode -Yo-Yo Mode -Drill Mode -L Curse Shield -L Step Sword -L Counter -Elememt Power -Final Gun +DjangoSP +DjangoDS +CannonMode +CannonBall +SwordMode +Yo-YoMode +DrillMode +LCurseShield +LStepSword +LCounter +ElememtPower +FinalGun @@ -299,17 +299,17 @@ Final Gun Bass -Delta Ray -Bug Curse -Meteor Knuckle -Omega Racket -Bass Another -Holy Dream -Big Hook -Cross Divide -Bug Charge +DeltaRay +BugCurse +MeteorKnuckle +OmegaRacket +BassAnother +HolyDream +BigHook +CrossDivide +BugCharge Phoenix -Death Phoenix +DeathPhoenix @@ -327,25 +327,25 @@ Death Phoenix -MegaMan Navi +MegaManNavi -SearchMan Navi +SearchManNavi -ProtoMan Navi -NumberMan Navi +ProtoManNavi +NumberManNavi -ShadowMan Navi -NapalmMan Navi -KnightMan Navi -ToadMan Navi -MagnetMan Navi -GyroMan Navi -Colonel Navi -Meddy Navi -TomahawkMan Navi \ No newline at end of file +ShadowManNavi +NapalmManNavi +KnightManNavi +ToadManNavi +MagnetManNavi +GyroManNavi +ColonelNavi +MeddyNavi +TomahawkManNavi \ No newline at end of file From e664d04e6a8fe78e3ac3584569eaf98a6c04fb5d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 11:15:54 -0800 Subject: [PATCH 027/429] CHANGES: Update for Progress/Beast Link gates --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index bac57d7c4..b907e1ebf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,7 @@ 0.8.0: (Future) Features: - Improved logging configuration - - One-Player BattleChip Gate support + - One-Player BattleChip/Progress/Beast Link Gate support Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs From 7189d7f13a158563246d8277afc64e7c73db6d7d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 11:39:54 -0800 Subject: [PATCH 028/429] Res: Fix some chip names --- res/chip-names-4.txt | 4 ++-- res/chip-names-5.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index a7f147f54..c3fc3ea2c 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -87,7 +87,7 @@ Guard1 Guard2 Guard3 Magnum -GrabGel +MetaGel Snake TimeBomb Mine @@ -253,7 +253,7 @@ Bass DeltaRay BugCurse RedSun -BassAnother +BassAnomaly HolyDream BlueMoon BugCharge diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index 9dfdb16e0..ea970ac94 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -92,7 +92,7 @@ CrackOut DoubleCrack TripleCrack Magnum -GrabGel +MetaGel Snake CircleGun Mine @@ -303,7 +303,7 @@ DeltaRay BugCurse MeteorKnuckle OmegaRacket -BassAnother +BassAnomaly HolyDream BigHook CrossDivide From a0a14f80b76bd86c35f11b171ab89fe5fc503f5d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 11:40:10 -0800 Subject: [PATCH 029/429] Qt: Add MMZ3 to gate detection --- src/platform/qt/BattleChipView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index e755e416d..fa12cbbf2 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -58,7 +58,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg m_controller->attachBattleChipGate(); setFlavor(4); - if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4")) { + if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4") || qtitle.startsWith("AGB-BZ3")) { m_ui.gateBattleChip->setChecked(Qt::Checked); } else if (qtitle.startsWith("AGB-BRB") || qtitle.startsWith("AGB-BRK")) { m_ui.gateProgress->setChecked(Qt::Checked); From 53f98db24635b672300148bfc643b624e6998522 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 13:00:46 -0800 Subject: [PATCH 030/429] Res: Minor BattleChip text fixes --- res/chip-names-4.txt | 6 +++--- res/chip-names-5.txt | 10 +++++----- res/chip-names-6.txt | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index c3fc3ea2c..93685c9b9 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -26,7 +26,7 @@ ElementFlare ElementIce Static LifeSync -MiniBoomer +MiniBomb EnergyBomb MegaEnergyBomb GunDelSol1 @@ -41,8 +41,8 @@ Binder3 BugBomb ElecShock WoodPowder -Cannonball -Geyser +CannonBall +BlackBomb Geyser SandRing Sword diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index ea970ac94..cf6880ebb 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -26,7 +26,7 @@ SpaceShake2 SpaceShake3 Static LifeSync -MiniBoomer +MiniBomb EnergyBomb MegaEnergyBomb GunDelSol1 @@ -146,7 +146,7 @@ AntiDamage AntiSword AntiRecovery CopyDamage -Attck+10 +Attack+10 Navi+20 FireHit1 FireHit2 @@ -234,8 +234,8 @@ MagnetMan MagnetManSP MagnetManDS Meddy -MeddySP MeddyDS +MeddySP ProtoMan ProtoManSP ProtoManDS @@ -286,7 +286,7 @@ DrillMode LCurseShield LStepSword LCounter -ElememtPower +ElementPower FinalGun @@ -302,7 +302,7 @@ Bass DeltaRay BugCurse MeteorKnuckle -OmegaRacket +OmegaRocket BassAnomaly HolyDream BigHook diff --git a/res/chip-names-6.txt b/res/chip-names-6.txt index 879ff0e70..be1e9a087 100644 --- a/res/chip-names-6.txt +++ b/res/chip-names-6.txt @@ -80,7 +80,7 @@ BambooSword WindRacket StepSword VariableSword -NeoVariSword +NeoVariable MoonBlade Muramasa MachineSword From 9e1d96ad3b60c316bb385af535708ee1c70411bf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 14:16:35 -0800 Subject: [PATCH 031/429] GBA Peripherals: Fix Progress Gate --- src/gba/extra/battlechip.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 4ba5043d9..cddb77d20 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -159,12 +159,18 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x537C: case 0x537D: case 0x537E: + case 0x6E8F: case 0xB7D3: case 0xB7D4: case 0xB7D5: case 0xB7D6: case 0xB7D7: case 0xB7D8: + case 0xC4D3: + case 0xC4D4: + case 0xC4D5: + case 0xC4D6: + case 0xC4D7: case 0xC4D8: case 0xC4D9: case 0xC4DA: From eab26d832fdd4b85ed9ab058577a438b2feffc5e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 14:20:47 -0800 Subject: [PATCH 032/429] Res: Minor BattleChip text fixes --- res/chip-names-4.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/chip-names-4.txt b/res/chip-names-4.txt index 93685c9b9..ea6d26dbc 100644 --- a/res/chip-names-4.txt +++ b/res/chip-names-4.txt @@ -42,8 +42,8 @@ BugBomb ElecShock WoodPowder CannonBall -BlackBomb Geyser +BlackBomb SandRing Sword WideSword From b60bb3b89c4421a68506d94b34bbaa7f751787f8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 14:32:03 -0800 Subject: [PATCH 033/429] Res: Remove Progress chips that do not exist --- res/chip-names-5.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/chip-names-5.txt b/res/chip-names-5.txt index cf6880ebb..677e99d96 100644 --- a/res/chip-names-5.txt +++ b/res/chip-names-5.txt @@ -308,8 +308,8 @@ HolyDream BigHook CrossDivide BugCharge -Phoenix -DeathPhoenix + + From 28ff4f375a5632e6e722a0056a0b800c8515716c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 15:25:05 -0800 Subject: [PATCH 034/429] GBA Peripherals: Fix Navi Change --- src/gba/extra/battlechip.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index cddb77d20..729635e42 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -160,6 +160,13 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x537D: case 0x537E: case 0x6E8F: + case 0x87D0: + case 0x87D1: + case 0x87D2: + case 0x87D3: + case 0x87D4: + case 0x87D5: + case 0x87DB: case 0xB7D3: case 0xB7D4: case 0xB7D5: @@ -184,6 +191,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xD97D: case 0xD97E: case 0xE49A: + case 0xE49B: + case 0xE49C: reply = ok; break; case 0x3545: From b7965523fd9c8c66d785617a2bbf4317616ada6e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 15:37:48 -0800 Subject: [PATCH 035/429] GBA Peripherals: More BattleChip and Progress IDs --- src/gba/extra/battlechip.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 729635e42..9d8f878fc 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -144,22 +144,27 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle switch (cmd) { case 0x0000: case 0x8FFF: + // EXE 5, 6 case 0xA380: case 0xA390: case 0xA3A0: case 0xA3B0: case 0xA3C0: case 0xA3D0: + // EXE 4 case 0xA6C0: gate->state = -1; // Fall through + // case 0x5379: case 0x537A: case 0x537B: case 0x537C: case 0x537D: case 0x537E: + // case 0x6E8F: + // case 0x87D0: case 0x87D1: case 0x87D2: @@ -173,6 +178,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xB7D6: case 0xB7D7: case 0xB7D8: + // case 0xC4D3: case 0xC4D4: case 0xC4D5: @@ -184,23 +190,33 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xC4DB: case 0xC4DC: case 0xC4DD: + // EXE 4 case 0xD979: case 0xD97A: case 0xD97B: case 0xD97C: case 0xD97D: case 0xD97E: + case 0xD97F: + case 0xD980: + case 0xD981: + case 0xD982: + case 0xD983: + case 0xD984: + // EXE 5 case 0xE49A: case 0xE49B: case 0xE49C: reply = ok; break; + // case 0x3545: case 0x3546: case 0x3547: case 0x3548: case 0x3549: case 0x354A: + // case 0x424A: case 0x424B: case 0x424C: @@ -208,6 +224,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x424E: case 0x424F: case 0x4250: + // case 0x5745: case 0x5746: case 0x5747: From 01a96c6313216f9111cc8670f45c30d588c8f97d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Feb 2019 22:13:40 -0800 Subject: [PATCH 036/429] GBA SIO: Prevent writing read-only multiplayer bits --- CHANGES | 1 + src/gba/sio.c | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index b907e1ebf..0495acfbe 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Bugfixes: - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) - Qt: Fix audio context holding onto closed game controller - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) + - GBA SIO: Prevent writing read-only multiplayer bits Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/sio.c b/src/gba/sio.c index d620be5a7..800af8aea 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -164,6 +164,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } break; case SIO_MULTI: + value &= 0xFF83; value |= 0xC; break; default: From 76fa9afc9c958381bcd8df143ce55b3339e8032a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Feb 2019 13:32:13 -0800 Subject: [PATCH 037/429] Qt: Fix color picking in sprite view (fixes #1307) --- CHANGES | 1 + src/platform/qt/AssetTile.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 0495acfbe..dfbc73d9b 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Bugfixes: - Qt: Fix audio context holding onto closed game controller - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) - GBA SIO: Prevent writing read-only multiplayer bits + - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/AssetTile.cpp b/src/platform/qt/AssetTile.cpp index 9bdb57150..ad16d47a3 100644 --- a/src/platform/qt/AssetTile.cpp +++ b/src/platform/qt/AssetTile.cpp @@ -137,7 +137,7 @@ void AssetTile::selectColor(int index) { mTileCache* tileCache = m_tileCaches[m_index >= m_boundary]; unsigned bpp = 8 << tileCache->bpp; int paletteId = m_paletteId; - data = mTileCacheGetTile(tileCache, m_index, m_paletteId); + data = mTileCacheGetTile(tileCache, m_index >= m_boundary ? m_index - m_boundary : m_index, m_paletteId); color_t color = data[index]; m_ui.color->setColor(0, color); m_ui.color->update(); From 80c46c5fd863be3c81c777d987560ad59f3248cc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Feb 2019 20:51:29 -0800 Subject: [PATCH 038/429] GBA Peripherals: Fix CrossBeast in EXE6 --- src/gba/extra/battlechip.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 9d8f878fc..6d464f7b0 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -162,6 +162,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0x537C: case 0x537D: case 0x537E: + // EXE 6 + case 0x65AF: // case 0x6E8F: // From f00b7fcf55167fdf243da731b4fe30ab0b56ffc8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 18 Feb 2019 21:52:40 -0800 Subject: [PATCH 039/429] GBA Periperals: Improve chip gate resync, remove switch table --- src/gba/extra/battlechip.c | 124 +++++++------------------------------ 1 file changed, 21 insertions(+), 103 deletions(-) diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 6d464f7b0..94d591efa 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -13,6 +13,7 @@ mLOG_DECLARE_CATEGORY(GBA_BATTLECHIP); mLOG_DEFINE_CATEGORY(GBA_BATTLECHIP, "GBA BattleChip Gate", "gba.battlechip"); enum { + BATTLECHIP_STATE_SYNC = -1, BATTLECHIP_STATE_COMMAND = 0, BATTLECHIP_STATE_UNK_0 = 1, BATTLECHIP_STATE_UNK_1 = 2, @@ -32,7 +33,6 @@ enum { BATTLECHIP_CONTINUE = 0xFFFF, }; -static bool GBASIOBattlechipGateInit(struct GBASIODriver* driver); static bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver); static uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); @@ -40,7 +40,7 @@ static void _battlechipTransfer(struct GBASIOBattlechipGate* gate); static void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate); void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { - gate->d.init = GBASIOBattlechipGateInit; + gate->d.init = NULL; gate->d.deinit = NULL; gate->d.load = GBASIOBattlechipGateLoad; gate->d.unload = NULL; @@ -54,14 +54,9 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) { gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE; } -bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { - struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; - return true; -} - bool GBASIOBattlechipGateLoad(struct GBASIODriver* driver) { struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; - gate->state = BATTLECHIP_STATE_COMMAND; + gate->state = BATTLECHIP_STATE_SYNC; gate->data[0] = 0x00FE; gate->data[1] = 0xFFFE; return true; @@ -119,7 +114,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->multiplayerControl.busy = 0; gate->d.p->multiplayerControl.id = 0; - mLOG(GBA_BATTLECHIP, DEBUG, "> %04X", cmd); + mLOG(GBA_BATTLECHIP, DEBUG, "Game: %04X (%i)", cmd, gate->state); uint16_t ok; switch (gate->flavor) { @@ -138,12 +133,9 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle break; } - switch (gate->state) { - case BATTLECHIP_STATE_COMMAND: - mLOG(GBA_BATTLECHIP, DEBUG, "C %04X", cmd); + if (gate->state != BATTLECHIP_STATE_COMMAND) { + // Resync if needed switch (cmd) { - case 0x0000: - case 0x8FFF: // EXE 5, 6 case 0xA380: case 0xA390: @@ -153,94 +145,20 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle case 0xA3D0: // EXE 4 case 0xA6C0: - gate->state = -1; - // Fall through - // - case 0x5379: - case 0x537A: - case 0x537B: - case 0x537C: - case 0x537D: - case 0x537E: - // EXE 6 - case 0x65AF: - // - case 0x6E8F: - // - case 0x87D0: - case 0x87D1: - case 0x87D2: - case 0x87D3: - case 0x87D4: - case 0x87D5: - case 0x87DB: - case 0xB7D3: - case 0xB7D4: - case 0xB7D5: - case 0xB7D6: - case 0xB7D7: - case 0xB7D8: - // - case 0xC4D3: - case 0xC4D4: - case 0xC4D5: - case 0xC4D6: - case 0xC4D7: - case 0xC4D8: - case 0xC4D9: - case 0xC4DA: - case 0xC4DB: - case 0xC4DC: - case 0xC4DD: - // EXE 4 - case 0xD979: - case 0xD97A: - case 0xD97B: - case 0xD97C: - case 0xD97D: - case 0xD97E: - case 0xD97F: - case 0xD980: - case 0xD981: - case 0xD982: - case 0xD983: - case 0xD984: - // EXE 5 - case 0xE49A: - case 0xE49B: - case 0xE49C: - reply = ok; - break; - // - case 0x3545: - case 0x3546: - case 0x3547: - case 0x3548: - case 0x3549: - case 0x354A: - // - case 0x424A: - case 0x424B: - case 0x424C: - case 0x424D: - case 0x424E: - case 0x424F: - case 0x4250: - // - case 0x5745: - case 0x5746: - case 0x5747: - case 0x5748: - case 0x5749: - case 0x574A: - // Resync - gate->state = BATTLECHIP_STATE_UNK_0; - break; - default: - mLOG(GBA_BATTLECHIP, STUB, "? %04X", cmd); - gate->state = -1; + mLOG(GBA_BATTLECHIP, DEBUG, "Resync detected"); + gate->state = BATTLECHIP_STATE_SYNC; break; } + } + + switch (gate->state) { + case BATTLECHIP_STATE_SYNC: + if (cmd != 0x8FFF) { + --gate->state; + } + // Fall through + case BATTLECHIP_STATE_COMMAND: + reply = ok; break; case BATTLECHIP_STATE_UNK_0: case BATTLECHIP_STATE_UNK_1: @@ -265,12 +183,12 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle break; case BATTLECHIP_STATE_END: reply = ok; - gate->state = -1; + gate->state = BATTLECHIP_STATE_SYNC; break; } - ++gate->state; - mLOG(GBA_BATTLECHIP, DEBUG, "< %04X", reply); + mLOG(GBA_BATTLECHIP, DEBUG, "Gate: %04X (%i)", reply, gate->state); + ++gate->state; gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply; From 3a8ff86d6b5a940630f3cd5d041ab3d13413214f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Feb 2019 19:44:11 -0800 Subject: [PATCH 040/429] GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM --- CHANGES | 1 + src/gb/gb.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index dfbc73d9b..db6a4acff 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ Bugfixes: - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) - GBA SIO: Prevent writing read-only multiplayer bits - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) + - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/gb.c b/src/gb/gb.c index 508483c1b..038401c83 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -202,7 +202,7 @@ void GBResizeSram(struct GB* gb, size_t size) { if (gb->memory.sram == (void*) -1) { gb->memory.sram = NULL; } - } else { + } else if (size) { uint8_t* newSram = anonymousMemoryMap(size); if (gb->memory.sram) { if (size > gb->sramSize) { From f3efd3726470ca3e46209a58e8443f80cc891f3c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Feb 2019 19:45:11 -0800 Subject: [PATCH 041/429] Python: Fix crash when deleting files owned by library --- CHANGES | 1 + src/platform/python/mgba/core.py | 10 ++++++++-- src/platform/python/mgba/vfs.py | 7 ++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index db6a4acff..e8cdfd2ca 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Bugfixes: - GBA SIO: Prevent writing read-only multiplayer bits - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM + - Python: Fix crash when deleting files owned by library Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 7a0672322..589ef0cb3 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -180,11 +180,17 @@ class Core(object): @protected def load_bios(self, vfile, id=0): - return bool(self._core.loadBIOS(self._core, vfile.handle, id)) + res = bool(self._core.loadBIOS(self._core, vfile.handle, id)) + if res: + vfile._claimed = True + return res @protected def load_save(self, vfile): - return bool(self._core.loadSave(self._core, vfile.handle)) + res = bool(self._core.loadSave(self._core, vfile.handle)) + if res: + vfile._claimed = True + return res @protected def load_temporary_save(self, vfile): diff --git a/src/platform/python/mgba/vfs.py b/src/platform/python/mgba/vfs.py index 2381a0aee..bab78c799 100644 --- a/src/platform/python/mgba/vfs.py +++ b/src/platform/python/mgba/vfs.py @@ -112,11 +112,16 @@ class VFile: def __init__(self, vf, _no_gc=None): self.handle = vf self._no_gc = _no_gc + self._claimed = False def __del__(self): - self.close() + if not self._claimed: + self.close() def close(self): + if self._claimed: + return False + self._claimed = True return bool(self.handle.close(self.handle)) def seek(self, offset, whence): From b5af2b584adfa9b11ab0675872ec8993347507a9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Feb 2019 19:45:54 -0800 Subject: [PATCH 042/429] Python: Make sure GB link object isn't GC'd before GB object --- CHANGES | 1 + src/platform/python/mgba/gb.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index e8cdfd2ca..36e868864 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Bugfixes: - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM - Python: Fix crash when deleting files owned by library + - Python: Make sure GB link object isn't GC'd before GB object Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/python/mgba/gb.py b/src/platform/python/mgba/gb.py index f4d6987c4..4e08faf39 100644 --- a/src/platform/python/mgba/gb.py +++ b/src/platform/python/mgba/gb.py @@ -27,6 +27,7 @@ class GB(Core): self.sprites = GBObjs(self) self.cpu = LR35902Core(self._core.cpu) self.memory = None + self._link = None @needs_reset def _init_cache(self, cache): @@ -43,10 +44,13 @@ class GB(Core): self.memory = GBMemory(self._core) def attach_sio(self, link): + self._link = link lib.GBSIOSetDriver(ffi.addressof(self._native.sio), link._native) def __del__(self): - lib.GBSIOSetDriver(ffi.addressof(self._native.sio), ffi.NULL) + if self._link: + lib.GBSIOSetDriver(ffi.addressof(self._native.sio), ffi.NULL) + self._link = None create_callback("GBSIOPythonDriver", "init") From 6e1ae2321eab2562bd7db11dd096a9bd1e7cd1a2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Feb 2019 20:34:03 -0800 Subject: [PATCH 043/429] GB: Add GBC color palettes for GB games --- include/mgba/core/interface.h | 1 + include/mgba/internal/gb/overrides.h | 1 + src/gb/core.c | 6 +- src/gb/overrides.c | 487 +++++++++++++++++++++++++++ 4 files changed, 494 insertions(+), 1 deletion(-) diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index e5c9dde18..0581c0bf2 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -32,6 +32,7 @@ typedef uint32_t color_t; #define M_B8(X) (((((X) >> 7) & 0xF8) * 0x21) >> 5) #define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19)) +#define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3)) #define M_RGB8_TO_BGR5(X) ((((X) & 0xF8) >> 3) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 9)) #define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19)) diff --git a/include/mgba/internal/gb/overrides.h b/include/mgba/internal/gb/overrides.h index f138ee9c8..5e0b2bbc6 100644 --- a/include/mgba/internal/gb/overrides.h +++ b/include/mgba/internal/gb/overrides.h @@ -22,6 +22,7 @@ struct GBCartridgeOverride { struct Configuration; bool GBOverrideFind(const struct Configuration*, struct GBCartridgeOverride* override); +bool GBOverrideColorFind(struct GBCartridgeOverride* override); void GBOverrideSave(struct Configuration*, const struct GBCartridgeOverride* override); struct GB; diff --git a/src/gb/core.c b/src/gb/core.c index c0c4f50da..68b613108 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -211,6 +211,7 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf mCoreConfigCopyValue(&core->config, config, "gb.model"); mCoreConfigCopyValue(&core->config, config, "sgb.model"); mCoreConfigCopyValue(&core->config, config, "cgb.model"); + mCoreConfigCopyValue(&core->config, config, "useCgbColors"); mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections"); int fakeBool = 0; @@ -359,10 +360,13 @@ static void _GBCoreReset(struct mCore* core) { } if (gb->memory.rom) { + int doColorOverride = 0; + mCoreConfigGetIntValue(&core->config, "useCgbColors", &doColorOverride); + struct GBCartridgeOverride override; const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; override.headerCrc32 = doCrc32(cart, sizeof(*cart)); - if (GBOverrideFind(gbcore->overrides, &override)) { + if (GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override))) { GBOverrideApply(gb, &override); } } diff --git a/src/gb/overrides.c b/src/gb/overrides.c index 382b67200..51a9bbf71 100644 --- a/src/gb/overrides.c +++ b/src/gb/overrides.c @@ -11,6 +11,482 @@ #include #include +#define PAL_ENTRY(A, B, C, D) \ + 0xFF000000 | M_RGB5_TO_RGB8(A), \ + 0xFF000000 | M_RGB5_TO_RGB8(B), \ + 0xFF000000 | M_RGB5_TO_RGB8(C), \ + 0xFF000000 | M_RGB5_TO_RGB8(D) + +#define PAL0 PAL_ENTRY(0x7FFF, 0x32BF, 0x00D0, 0x0000) +#define PAL1 PAL_ENTRY(0x639F, 0x4279, 0x15B0, 0x04CB) +#define PAL2 PAL_ENTRY(0x7FFF, 0x6E31, 0x454A, 0x0000) +#define PAL3 PAL_ENTRY(0x7FFF, 0x1BEF, 0x0200, 0x0000) +#define PAL4 PAL_ENTRY(0x7FFF, 0x421F, 0x1CF2, 0x0000) +#define PAL5 PAL_ENTRY(0x7FFF, 0x5294, 0x294A, 0x0000) +#define PAL6 PAL_ENTRY(0x7FFF, 0x03FF, 0x012F, 0x0000) +#define PAL7 PAL_ENTRY(0x7FFF, 0x03EF, 0x01D6, 0x0000) +#define PAL8 PAL_ENTRY(0x7FFF, 0x42B5, 0x3DC8, 0x0000) +#define PAL9 PAL_ENTRY(0x7E74, 0x03FF, 0x0180, 0x0000) +#define PAL10 PAL_ENTRY(0x67FF, 0x77AC, 0x1A13, 0x2D6B) +#define PAL11 PAL_ENTRY(0x7ED6, 0x4BFF, 0x2175, 0x0000) +#define PAL12 PAL_ENTRY(0x53FF, 0x4A5F, 0x7E52, 0x0000) +#define PAL13 PAL_ENTRY(0x4FFF, 0x7ED2, 0x3A4C, 0x1CE0) +#define PAL14 PAL_ENTRY(0x03ED, 0x7FFF, 0x255F, 0x0000) +#define PAL15 PAL_ENTRY(0x036A, 0x021F, 0x03FF, 0x7FFF) +#define PAL16 PAL_ENTRY(0x7FFF, 0x01DF, 0x0112, 0x0000) +#define PAL17 PAL_ENTRY(0x231F, 0x035F, 0x00F2, 0x0009) +#define PAL18 PAL_ENTRY(0x7FFF, 0x03EA, 0x011F, 0x0000) +#define PAL19 PAL_ENTRY(0x299F, 0x001A, 0x000C, 0x0000) +#define PAL20 PAL_ENTRY(0x7FFF, 0x027F, 0x001F, 0x0000) +#define PAL21 PAL_ENTRY(0x7FFF, 0x03E0, 0x0206, 0x0120) +#define PAL22 PAL_ENTRY(0x7FFF, 0x7EEB, 0x001F, 0x7C00) +#define PAL23 PAL_ENTRY(0x7FFF, 0x3FFF, 0x7E00, 0x001F) +#define PAL24 PAL_ENTRY(0x7FFF, 0x03FF, 0x001F, 0x0000) +#define PAL25 PAL_ENTRY(0x03FF, 0x001F, 0x000C, 0x0000) +#define PAL26 PAL_ENTRY(0x7FFF, 0x033F, 0x0193, 0x0000) +#define PAL27 PAL_ENTRY(0x0000, 0x4200, 0x037F, 0x7FFF) +#define PAL28 PAL_ENTRY(0x7FFF, 0x7E8C, 0x7C00, 0x0000) +#define PAL29 PAL_ENTRY(0x7FFF, 0x1BEF, 0x6180, 0x0000) +#define PAL30 PAL_ENTRY(0x7C00, 0x7FFF, 0x3FFF, 0x7E00) +#define PAL31 PAL_ENTRY(0x7FFF, 0x7FFF, 0x7E8C, 0x7C00) +#define PAL32 PAL_ENTRY(0x0000, 0x7FFF, 0x421F, 0x1CF2) + +#define PALETTE(X, Y, Z) { PAL ## X, PAL ## Y, PAL ## Z } + +static const struct GBCartridgeOverride _colorOverrides[] = { + // Adventures of Lolo (Europe) + { 0xFBE65286, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Alleyway (World) + { 0xCBAA161B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 9, 9) }, + + // Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe) + { 0x309FDB70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) }, + + // Arcade Classic No. 3 - Galaga & Galaxian (USA) + { 0xE13EF629, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) }, + + // Arcade Classic No. 4 - Defender & Joust (USA, Europe) + { 0x5C8B229D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Balloon Kid (USA, Europe) + { 0xEC3438FA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) }, + + // Baseball (World) + { 0xE02904BD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(15, 31, 4) }, + + // Battle Arena Toshinden (USA) + { 0xA2C3DF62, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Battletoads in Ragnarok's World (Europe) + { 0x51B259CF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 3) }, + + // Chessmaster, The (DMG-EM) (Europe) + { 0x96A68366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) }, + + // David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe) + { 0x6413F5E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) }, + + // Donkey Kong (Japan, USA) + { 0xA777EE2F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) }, + + // Donkey Kong (World) (Rev A) + { 0xC8F8ACDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 4, 4) }, + + // Donkey Kong Land (Japan) + { 0x2CA7EEF3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) }, + + // Donkey Kong Land (USA, Europe) + { 0x0D3E401D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) }, + + // Donkey Kong Land 2 (USA, Europe) + { 0x07ED9445, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) }, + + // Donkey Kong Land III (USA, Europe) + { 0xCA01A31C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) }, + + // Donkey Kong Land III (USA, Europe) (Rev A) + { 0x6805BA1E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 22) }, + + // Dr. Mario (World) + { 0xA3C2C1E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) }, + + // Dr. Mario (World) (Rev A) + { 0x69975661, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 28, 4) }, + + // Dr. Mario (World) (Beta) + { 0x22E55535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Dynablaster (Europe) + { 0xD9D0211F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) }, + + // F-1 Race (World) + { 0x8434CB2C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // F-1 Race (World) (Rev A) + { 0xBA63383B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Game & Watch Gallery (Europe) + { 0x4A43B8B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game & Watch Gallery (USA) + { 0xBD0736D4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game & Watch Gallery (USA) (Rev A) + { 0xA969B4F0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game Boy Camera Gold (USA) + { 0x83947EC8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Game Boy Gallery (Japan) + { 0xDC3C3642, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game Boy Gallery - 5 Games in One (Europe) + { 0xD83E3F82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Game Boy Gallery 2 (Australia) + { 0x6C477A30, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game Boy Gallery 2 (Japan) + { 0xC5AAAFDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(7, 4, 4) }, + + // Game Boy Wars (Japan) + { 0x03E3ED72, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) }, + + // Golf (World) + { 0x885C242D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) }, + + // Hoshi no Kirby (Japan) + { 0x4AA02A13, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Hoshi no Kirby (Japan) (Rev A) + { 0x88D03280, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Hoshi no Kirby 2 (Japan) + { 0x58B7A321, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // James Bond 007 (USA, Europe) + { 0x7DDEB68E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) }, + + // Kaeru no Tame ni Kane wa Naru (Japan) + { 0x7F805941, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 2) }, + + // Kid Icarus - Of Myths and Monsters (USA, Europe) + { 0x5D93DB0F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 4) }, + + // Killer Instinct (USA, Europe) + { 0x117043A9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 4, 0) }, + + // King of Fighters '95, The (USA) + { 0x0F81CC70, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // King of the Zoo (Europe) + { 0xB492FB51, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 28) }, + + // Kirby no Block Ball (Japan) + { 0x4203B79F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Kirby no Kirakira Kids (Japan) + { 0x74C3A937, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Kirby no Pinball (Japan) + { 0x89239AED, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) }, + + // Kirby's Block Ball (USA, Europe) + { 0xCE8B1B18, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Kirby's Dream Land (USA, Europe) + { 0x302017CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Kirby's Dream Land 2 (USA, Europe) + { 0xF6C9E5A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 30) }, + + // Kirby's Pinball Land (USA, Europe) + { 0x9C4AA9D8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(9, 19, 19) }, + + // Kirby's Star Stacker (USA, Europe) + { 0xC1B481CA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Legend of Zelda, The - Link's Awakening (Canada) + { 0x9F54D47B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Legend of Zelda, The - Link's Awakening (France) + { 0x441D7FAD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Legend of Zelda, The - Link's Awakening (Germany) + { 0x838D65D6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A) + { 0x24CAAB4D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B) + { 0xBCBB6BDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Legend of Zelda, The - Link's Awakening (USA, Europe) + { 0x9A193109, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Magnetic Soccer (Europe) + { 0x6735A1F5, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Mario & Yoshi (Europe) + { 0xEC14B007, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) }, + + // Mario no Picross (Japan) + { 0x602C2371, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Mario's Picross (USA, Europe) + { 0x725BBFF6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Mega Man - Dr. Wily's Revenge (Europe) + { 0xB2FE1EDB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Mega Man II (Europe) + { 0xC5EE1580, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Mega Man III (Europe) + { 0x88249B90, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Metroid II - Return of Samus (World) + { 0xBDCCC648, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 25, 3) }, + + // Moguranya (Japan) + { 0x41C1D13C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) }, + + // Mole Mania (USA, Europe) + { 0x32E8EEA3, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 16) }, + + // Mystic Quest (Europe) + { 0x8DC57012, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Mystic Quest (France) + { 0x09728780, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Mystic Quest (Germany) + { 0x6F8568A8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Nigel Mansell's World Championship Racing (Europe) + { 0xAC2D636D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Nintendo World Cup (USA, Europe) + { 0xB43E44C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) }, + + // Othello (Europe) + { 0x45F34317, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Pac-In-Time (Europe) + { 0x8C608574, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 28) }, + + // Picross 2 (Japan) + { 0xBA91DDD8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Pinocchio (Europe) + { 0x849C74C0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 2, 17) }, + + // Play Action Football (USA) + { 0x2B703514, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) }, + + // Pocket Bomberman (Europe) + { 0x9C5E0D5E, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(2, 17, 17) }, + + // Pocket Camera (Japan) (Rev A) + { 0x211A85AC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(26, 26, 26) }, + + // Pocket Monsters - Aka (Japan) + { 0x29D07340, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pocket Monsters - Aka (Japan) (Rev A) + { 0x6BB566EC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pocket Monsters - Ao (Japan) + { 0x65EF364B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pocket Monsters - Midori (Japan) + { 0x923D46DD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) }, + + // Pocket Monsters - Midori (Japan) (Rev A) + { 0x6C926BFF, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(29, 4, 29) }, + + // Pocket Monsters - Pikachu (Japan) + { 0xF52AD7C1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Pocket Monsters - Pikachu (Japan) (Rev A) + { 0x0B54FAEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Pocket Monsters - Pikachu (Japan) (Rev B) + { 0x9A161366, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Pocket Monsters - Pikachu (Japan) (Rev C) + { 0x8E1C14E4, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Pokemon - Blaue Edition (Germany) + { 0x6C3587F2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pokemon - Blue Version (USA, Europe) + { 0x28323CE0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pokemon - Edicion Azul (Spain) + { 0x93FCE15B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pokemon - Edicion Roja (Spain) + { 0xFD20BB1C, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pokemon - Red Version (USA, Europe) + { 0xCC25454F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pokemon - Rote Edition (Germany) + { 0xE5DD23CE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pokemon - Version Bleue (France) + { 0x98BFEC5A, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pokemon - Version Rouge (France) + { 0x1D6D8022, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // Pokemon - Versione Blu (Italy) + { 0x7864DECC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 28) }, + + // Pokemon - Versione Rossa (Italy) + { 0xFE2A3F93, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 3, 4) }, + + // QIX (World) + { 0x5EECB346, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) }, + + // Radar Mission (Japan) + { 0xD03B1A15, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) }, + + // Radar Mission (USA, Europe) + { 0xCEDD9FEB, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 8) }, + + // Soccer (Europe) + { 0xB0274CDA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) }, + + // SolarStriker (World) + { 0x981620E7, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) }, + + // Space Invaders (Europe) + { 0x3B032784, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) }, + + // Space Invaders (USA) + { 0x63A767E2, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(27, 27, 27) }, + + // Star Wars (USA, Europe) (Rev A) + { 0x44CE17EE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 3, 28) }, + + // Street Fighter II (USA) + { 0xC512D0B1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Street Fighter II (USA, Europe) (Rev A) + { 0x79E16545, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Super Donkey Kong GB (Japan) + { 0x940D4974, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(13, 17, 4) }, + + // Super Mario Land (World) + { 0x6C0ACA9F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) }, + + // Super Mario Land (World) (Rev A) + { 0xCA117ACC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(11, 32, 32) }, + + // Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A) + { 0x423E09E6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B) + { 0x445A0358, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super Mario Land 2 - 6 Golden Coins (USA, Europe) + { 0xDE2960A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super Mario Land 2 - 6-tsu no Kinka (Japan) + { 0xD47CED78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev A) + { 0xA4B4F9F9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev B) + { 0x5842F25D, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(10, 16, 28) }, + + // Super R.C. Pro-Am (USA, Europe) + { 0x8C39B1C8, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 28, 3) }, + + // Tennis (World) + { 0xD2BEBF08, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) }, + + // Tetris (World) + { 0xE906C6A6, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Tetris (World) (Rev A) + { 0x4674B43F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 24) }, + + // Tetris 2 (USA) + { 0x687505F1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) }, + + // Tetris 2 (USA, Europe) + { 0x6761459F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) }, + + // Tetris Attack (USA) + { 0x00E9474B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) }, + + // Tetris Blast (USA, Europe) + { 0xDDDEEEDE, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 20) }, + + // Tetris Attack (USA, Europe) (Rev A) + { 0x6628C535, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) }, + + // Tetris Flash (Japan) + { 0xED669A78, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(24, 24, 22) }, + + // Top Rank Tennis (USA) + { 0xA6497CC0, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) }, + + // Top Ranking Tennis (Europe) + { 0x62C12E05, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(14, 31, 0) }, + + // Toy Story (Europe) + { 0x67066E28, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 4) }, + + // Vegas Stakes (USA, Europe) + { 0x80CB217F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(3, 4, 28) }, + + // Wario Land - Super Mario Land 3 (World) + { 0xF1EA10E9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 16, 22) }, + + // Wario Land II (USA, Europe) + { 0xD56A50A1, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(8, 0, 28) }, + + // Wave Race (USA, Europe) + { 0x52A6E4CC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(28, 4, 23) }, + + // X (Japan) + { 0xFED4C47F, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(5, 5, 5) }, + + // Yakuman (Japan) + { 0x40604F17, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Yakuman (Japan) (Rev A) + { 0x2959ACFC, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(0, 0, 0) }, + + // Yoshi (USA) + { 0xAB1605B9, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) }, + + // Yoshi no Cookie (Japan) + { 0x841753DA, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) }, + + // Yoshi no Panepon (Japan) + { 0xAA1AD903, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 18, 22) }, + + // Yoshi no Tamago (Japan) + { 0xD4098A6B, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(18, 4, 4) }, + + // Yoshi's Cookie (USA, Europe) + { 0x940EDD87, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(20, 20, 22) }, + + // Zelda no Densetsu - Yume o Miru Shima (Japan) + { 0x259C9A82, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + // Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A) + { 0x61F269CD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, +}; + static const struct GBCartridgeOverride _overrides[] = { // Pokemon Spaceworld 1997 demo { 0x232a067d, GB_MODEL_AUTODETECT, GB_MBC3_RTC, { 0 } }, // Gold (debug) @@ -21,6 +497,17 @@ static const struct GBCartridgeOverride _overrides[] = { { 0, 0, 0, { 0 } } }; +bool GBOverrideColorFind(struct GBCartridgeOverride* override) { + int i; + for (i = 0; _colorOverrides[i].headerCrc32; ++i) { + if (override->headerCrc32 == _colorOverrides[i].headerCrc32) { + memcpy(override->gbColors, _colorOverrides[i].gbColors, sizeof(override->gbColors)); + return true; + } + } + return false; +} + bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) { override->model = GB_MODEL_AUTODETECT; override->mbc = GB_MBC_AUTODETECT; From 99a6db6738c82d1cb286c29a9b431a41cd5ea8ba Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 20 Feb 2019 20:40:54 -0800 Subject: [PATCH 044/429] Qt: Add option for CGB colors --- CHANGES | 1 + src/platform/qt/ConfigController.cpp | 2 ++ src/platform/qt/SettingsView.cpp | 2 ++ src/platform/qt/SettingsView.ui | 19 +++++++++++++------ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 36e868864..67845a325 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,7 @@ Features: - Improved logging configuration - One-Player BattleChip/Progress/Beast Link Gate support + - Add Game Boy Color palettes for original Game Boy games Bugfixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 36a520abb..6ea003d32 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -112,6 +112,8 @@ ConfigController::ConfigController(QObject* parent) m_opts.lockAspectRatio = true; mCoreConfigLoad(&m_config); mCoreConfigLoadDefaults(&m_config, &m_opts); + mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1); + mCoreConfigSetDefaultIntValue(&m_config, "useCgbColors", 1); mCoreConfigMap(&m_config, &m_opts); } diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 7f2ded961..271c59652 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -352,6 +352,7 @@ void SettingsView::updateConfig() { saveSetting("gbc.bios", m_ui.gbcBios); saveSetting("sgb.bios", m_ui.sgbBios); saveSetting("sgb.borders", m_ui.sgbBorders); + saveSetting("useCgbColors", m_ui.useCgbColors); saveSetting("useBios", m_ui.useBios); saveSetting("skipBios", m_ui.skipBios); saveSetting("audioBuffers", m_ui.audioBufferSize); @@ -485,6 +486,7 @@ void SettingsView::reloadConfig() { loadSetting("gbc.bios", m_ui.gbcBios); loadSetting("sgb.bios", m_ui.sgbBios); loadSetting("sgb.borders", m_ui.sgbBorders, true); + loadSetting("useCgbColors", m_ui.useCgbColors, true); loadSetting("useBios", m_ui.useBios); loadSetting("skipBios", m_ui.skipBios); loadSetting("audioBuffers", m_ui.audioBufferSize); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 0a2da478e..41fb9a7de 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -87,7 +87,7 @@ - 5 + 0 @@ -1215,7 +1215,7 @@ - 0 + 77 0 @@ -1540,28 +1540,28 @@ - + Super Game Boy borders - + Qt::Horizontal - + Camera driver: - + @@ -1665,6 +1665,13 @@ + + + + Use GBC colors in GB games + + + From ce419ee1c641a3c431d879fc52bb8ae583c55cca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 21 Feb 2019 02:00:11 -0800 Subject: [PATCH 045/429] Qt: Revamp BattleChip UI --- src/platform/qt/BattleChipView.cpp | 63 +++++++- src/platform/qt/BattleChipView.h | 13 ++ src/platform/qt/BattleChipView.ui | 240 ++++++++++++++++++++--------- 3 files changed, 243 insertions(+), 73 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index fa12cbbf2..c6d6578d4 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -5,9 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "BattleChipView.h" +#include "ConfigController.h" #include "CoreController.h" +#include "GBAApp.h" +#include #include +#include #include using namespace QGBA; @@ -16,6 +20,9 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg : QDialog(parent) , m_controller(controller) { + QResource::registerResource(GBAApp::dataDir() + "/chips.rcc"); + QResource::registerResource(ConfigController::configDir() + "/chips.rcc"); + m_ui.setupUi(this); char title[9]; @@ -34,6 +41,9 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg }); connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); + connect(m_ui.insert, &QAbstractButton::clicked, this, &BattleChipView::reinsert); + connect(m_ui.add, &QAbstractButton::clicked, this, &BattleChipView::addChip); + connect(m_ui.remove, &QAbstractButton::clicked, this, &BattleChipView::removeChip); connect(controller.get(), &CoreController::stopping, this, &QWidget::close); connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { @@ -56,6 +66,16 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg } }); + connect(m_controller.get(), &CoreController::frameAvailable, this, &BattleChipView::advanceFrameCounter); + + connect(m_ui.chipList, &QListWidget::itemClicked, this, [this](QListWidgetItem* item) { + QVariant chip = item->data(Qt::UserRole); + bool blocked = m_ui.chipId->blockSignals(true); + m_ui.chipId->setValue(chip.toInt()); + m_ui.chipId->blockSignals(blocked); + reinsert(); + }); + m_controller->attachBattleChipGate(); setFlavor(4); if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4") || qtitle.startsWith("AGB-BZ3")) { @@ -77,6 +97,9 @@ void BattleChipView::setFlavor(int flavor) { } void BattleChipView::insertChip(bool inserted) { + bool blocked = m_ui.inserted->blockSignals(true); + m_ui.inserted->setChecked(inserted); + m_ui.inserted->blockSignals(blocked); if (inserted) { m_controller->setBattleChipId(m_ui.chipId->value()); } else { @@ -84,14 +107,41 @@ void BattleChipView::insertChip(bool inserted) { } } +void BattleChipView::reinsert() { + if (m_ui.inserted->isChecked()) { + insertChip(false); + m_next = true; + m_frameCounter = UNINSERTED_TIME; + } else { + insertChip(true); + } +} + +void BattleChipView::addChip() { + int insertedChip = m_ui.chipId->value(); + if (insertedChip < 1) { + return; + } + QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[insertedChip]); + add->setData(Qt::UserRole, insertedChip); + add->setIcon(QIcon(QString(":/res/exe%1/%2.png").arg(m_flavor).arg(insertedChip, 3, 10, QLatin1Char('0')))); + m_ui.chipList->addItem(add); +} + +void BattleChipView::removeChip() { + qDeleteAll(m_ui.chipList->selectedItems()); +} + void BattleChipView::loadChipNames(int flavor) { QStringList chipNames; chipNames.append(tr("(None)")); m_chipIndexToId.clear(); + m_chipIdToName.clear(); if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) { flavor = GBA_FLAVOR_BEAST_LINK_GATE; } + m_flavor = flavor; QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); file.open(QIODevice::ReadOnly | QIODevice::Text); @@ -105,10 +155,21 @@ void BattleChipView::loadChipNames(int flavor) { if (line.trimmed().isEmpty()) { continue; } + QString name = QString::fromUtf8(line).trimmed(); m_chipIndexToId[chipNames.length()] = id; - chipNames.append(QString::fromUtf8(line).trimmed()); + m_chipIdToName[id] = name; + chipNames.append(name); } m_ui.chipName->clear(); m_ui.chipName->addItems(chipNames); +} + +void BattleChipView::advanceFrameCounter() { + if (m_frameCounter == 0) { + insertChip(m_next); + } + if (m_frameCounter >= 0) { + --m_frameCounter; + } } \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 7dbdc9561..6b4582c36 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -27,14 +27,27 @@ public: public slots: void setFlavor(int); void insertChip(bool); + void reinsert(); + +private slots: + void advanceFrameCounter(); + void addChip(); + void removeChip(); private: + static const int UNINSERTED_TIME = 10; + void loadChipNames(int); Ui::BattleChipView m_ui; QMap m_chipIndexToId; + QMap m_chipIdToName; std::shared_ptr m_controller; + int m_flavor; + + int m_frameCounter = -1; + bool m_next = false; }; } \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index ba95e455a..14ce62c55 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -6,90 +6,186 @@ 0 0 - 426 - 278 + 794 + 893 BattleChip Gate - - - - - Inserted - - + + + + + + + Gate type + + + + + + + Ba&ttleChip Gate + + + true + + + + + + + Progress &Gate + + + + + + + Beast &Link Gate + + + + - - - - Chip ID - - - - - - - Chip name - - - - - - - 65535 - - - - - - - - - - Gate type - - - - - - - Progress &Gate - - - gate - - - - - - - Ba&ttleChip Gate - - - true - - - gate - - + + + + + + Chip ID + + + + + + + 65535 + + + + + + + Inserted + + + + - - - Beast &Link Gate + + + Qt::Vertical + + + + + + + + + + + + + + Chip name + + + + + + + + + Add + + + + + + + Remove + + + + + + + Insert + + + + + + + + + true + + + true + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + + 56 + 48 + + + + QListView::Snap + + + true + + + QListView::Adjust + + + + 160 + 128 + + + + QListView::IconMode + + + + + + + QDialogButtonBox::Close - - gate - - - - - + + + buttonBox + rejected() + BattleChipView + close() + + + 310 + 632 + + + 310 + 331 + + + + From 64ad73c9f9c32334e117ff4fc6c930f981ec07db Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 21 Feb 2019 18:18:52 -0800 Subject: [PATCH 046/429] Qt: Add placeholders, minor revamps --- res/{chip-names-4.txt => exe4/chip-names.txt} | 0 res/exe4/placeholder.png | Bin 0 -> 483 bytes res/{chip-names-5.txt => exe5/chip-names.txt} | 0 res/exe5/placeholder.png | Bin 0 -> 475 bytes res/{chip-names-6.txt => exe6/chip-names.txt} | 0 res/exe6/placeholder.png | Bin 0 -> 476 bytes src/platform/qt/BattleChipView.cpp | 16 ++++++++++++++-- src/platform/qt/BattleChipView.ui | 4 ++-- src/platform/qt/resources.qrc | 9 ++++++--- 9 files changed, 22 insertions(+), 7 deletions(-) rename res/{chip-names-4.txt => exe4/chip-names.txt} (100%) create mode 100644 res/exe4/placeholder.png rename res/{chip-names-5.txt => exe5/chip-names.txt} (100%) create mode 100644 res/exe5/placeholder.png rename res/{chip-names-6.txt => exe6/chip-names.txt} (100%) create mode 100644 res/exe6/placeholder.png diff --git a/res/chip-names-4.txt b/res/exe4/chip-names.txt similarity index 100% rename from res/chip-names-4.txt rename to res/exe4/chip-names.txt diff --git a/res/exe4/placeholder.png b/res/exe4/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..f057bb2492d68c79ce533643aaee068278c11ed7 GIT binary patch literal 483 zcmV<90UZ8`P)|uP87m5D2<6)s*kkDKPX9OTb#_3c3x% zE8q#HBcBfnget?fv)|mXgmP&S2cZFoQ9! zU>SVbLy1Kx1&nnqhrCcq2_ve1iUJKS;Ly{@Awrc?i{7wSA0YUh_{@p_d{$Gj6G57~9R%DGK zVU8EX_a1mrMP`#4n8Xw3u?ghRZ^Eu>s z+6bG2lHb)bq6E)M`E$gzdLDYxSaL%+7G8|f2>_L~F@*bb#D!wK5zic`tc}MpKgr1{ z_cT^GxU4AjTR$T{GvP4ixaQ~KzG;#QVKR6C9l-k*hT~{%NCA=qTyky3p6YidFvi;2 zr2DGxVJsmN-#;vdFy3KSGJtWMe}EIYusKt=tM?6c$u+mRk?sDWy|FF_%^$v+Nj+2L R&XNEC002ovPDHLkV1mLO)nfnv literal 0 HcmV?d00001 diff --git a/res/chip-names-6.txt b/res/exe6/chip-names.txt similarity index 100% rename from res/chip-names-6.txt rename to res/exe6/chip-names.txt diff --git a/res/exe6/placeholder.png b/res/exe6/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..7873bb227f646c31efbc299850301fe5bb83c0ed GIT binary patch literal 476 zcmV<20VDp2P)A@Bg@m%DohDB&X3VbAJ9-L?_P863jLz^%cUX#&AeRTzpo< zil10z#jh;UEeP8XwjpdoXrW?W6{Lxj*g#HpFeXZAt<<-ae$f^&k)uQprIxsOY8g3BtSZ1(W*Dz>PQ;IR6rCgo z)BMbd&J{U@@rjTVopbt?N=>2h2;0et)<m!+Bj(7$Zw!f%C)| zS@-C|$YYN)XxhZw;_BkW$Yvb6{O!} #include +#include #include #include @@ -32,6 +33,13 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg core->getGameCode(core, title); QString qtitle(title); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 16); +#else + int size = QFontMetrics(QFont()).height() / (devicePixelRatio() * 16); +#endif + m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size); + m_ui.chipList->setIconSize(m_ui.chipList->iconSize() * size); connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { m_ui.inserted->setChecked(Qt::Unchecked); @@ -124,7 +132,11 @@ void BattleChipView::addChip() { } QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[insertedChip]); add->setData(Qt::UserRole, insertedChip); - add->setIcon(QIcon(QString(":/res/exe%1/%2.png").arg(m_flavor).arg(insertedChip, 3, 10, QLatin1Char('0')))); + QString path = QString(":/res/exe%1/%2.png").arg(m_flavor).arg(insertedChip, 3, 10, QLatin1Char('0')); + if (!QFile(path).exists()) { + path = QString(":/res/exe%1/placeholder.png").arg(m_flavor); + } + add->setIcon(QIcon(path)); m_ui.chipList->addItem(add); } @@ -143,7 +155,7 @@ void BattleChipView::loadChipNames(int flavor) { } m_flavor = flavor; - QFile file(QString(":/res/chip-names-%1.txt").arg(flavor)); + QFile file(QString(":/res/exe%1/chip-names.txt").arg(flavor)); file.open(QIODevice::ReadOnly | QIODevice::Text); int id = 0; while (true) { diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 14ce62c55..10e8000d8 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -151,8 +151,8 @@ - 160 - 128 + 80 + 72 diff --git a/src/platform/qt/resources.qrc b/src/platform/qt/resources.qrc index ea08c5e39..990203809 100644 --- a/src/platform/qt/resources.qrc +++ b/src/platform/qt/resources.qrc @@ -4,8 +4,11 @@ ../../../res/keymap.qpic ../../../res/patrons.txt ../../../res/no-cam.png - ../../../res/chip-names-4.txt - ../../../res/chip-names-5.txt - ../../../res/chip-names-6.txt + ../../../res/exe4/chip-names.txt + ../../../res/exe4/placeholder.png + ../../../res/exe5/chip-names.txt + ../../../res/exe5/placeholder.png + ../../../res/exe6/chip-names.txt + ../../../res/exe6/placeholder.png From 475c7790c5ddd94127eaa0f4b6b569e7beae2f79 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 21 Feb 2019 19:13:50 -0800 Subject: [PATCH 047/429] Qt: Add BattleChip "deck" save/load --- src/platform/qt/BattleChipView.cpp | 58 +++++- src/platform/qt/BattleChipView.h | 4 + src/platform/qt/BattleChipView.ui | 307 ++++++++++++++++++----------- 3 files changed, 246 insertions(+), 123 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index e05785f4f..53c9a3024 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include using namespace QGBA; @@ -53,6 +54,8 @@ BattleChipView::BattleChipView(std::shared_ptr controller, QWidg connect(m_ui.add, &QAbstractButton::clicked, this, &BattleChipView::addChip); connect(m_ui.remove, &QAbstractButton::clicked, this, &BattleChipView::removeChip); connect(controller.get(), &CoreController::stopping, this, &QWidget::close); + connect(m_ui.save, &QAbstractButton::clicked, this, &BattleChipView::saveDeck); + connect(m_ui.load, &QAbstractButton::clicked, this, &BattleChipView::loadDeck); connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { if (on) { @@ -130,9 +133,13 @@ void BattleChipView::addChip() { if (insertedChip < 1) { return; } - QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[insertedChip]); - add->setData(Qt::UserRole, insertedChip); - QString path = QString(":/res/exe%1/%2.png").arg(m_flavor).arg(insertedChip, 3, 10, QLatin1Char('0')); + addChipId(insertedChip); +} + +void BattleChipView::addChipId(int id) { + QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[id]); + add->setData(Qt::UserRole, id); + QString path = QString(":/res/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); if (!QFile(path).exists()) { path = QString(":/res/exe%1/placeholder.png").arg(m_flavor); } @@ -184,4 +191,49 @@ void BattleChipView::advanceFrameCounter() { if (m_frameCounter >= 0) { --m_frameCounter; } +} + +void BattleChipView::saveDeck() { + QString filename = GBAApp::app()->getSaveFileName(this, tr("Select deck file"), tr(("BattleChip deck file (*.deck)"))); + if (filename.isEmpty()) { + return; + } + + QStringList deck; + for (int i = 0; i < m_ui.chipList->count(); ++i) { + deck.append(m_ui.chipList->item(i)->data(Qt::UserRole).toString()); + } + + QSettings ini(filename, QSettings::IniFormat); + ini.clear(); + ini.beginGroup("BattleChipDeck"); + ini.setValue("version", m_flavor); + ini.setValue("deck", deck.join(',')); + ini.sync(); +} + +void BattleChipView::loadDeck() { + QString filename = GBAApp::app()->getOpenFileName(this, tr("Select deck file"), tr(("BattleChip deck file (*.deck)"))); + if (filename.isEmpty()) { + return; + } + + QSettings ini(filename, QSettings::IniFormat); + ini.beginGroup("BattleChipDeck"); + int flavor = ini.value("version").toInt(); + if (flavor != m_flavor) { + return; + } + + while (m_ui.chipList->count()) { + delete m_ui.chipList->takeItem(m_ui.chipList->count() - 1); + } + QStringList deck = ini.value("deck").toString().split(','); + for (const auto& item : deck) { + bool ok; + int id = item.toInt(&ok); + if (ok) { + addChipId(id); + } + } } \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 6b4582c36..423c937c8 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -32,8 +32,12 @@ public slots: private slots: void advanceFrameCounter(); void addChip(); + void addChipId(int); void removeChip(); + void saveDeck(); + void loadDeck(); + private: static const int UNINSERTED_TIME = 10; diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 10e8000d8..a31513ced 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -6,121 +6,15 @@ 0 0 - 794 - 893 + 630 + 722 BattleChip Gate - - - - - - - Gate type - - - - - - - Ba&ttleChip Gate - - - true - - - - - - - Progress &Gate - - - - - - - Beast &Link Gate - - - - - - - - - - - Chip ID - - - - - - - 65535 - - - - - - - Inserted - - - - - - - - - Qt::Vertical - - - - - - - - - - - - - - Chip name - - - - - - - - - Add - - - - - - - Remove - - - - - - - Insert - - - - - - + + true @@ -160,30 +54,203 @@ - - - - QDialogButtonBox::Close - + + + + + + + + + + + Chip name + + + + + + + + + Insert + + + + + + + + + + + Save + + + + + + + Load + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add + + + + + + + Remove + + + + + + + + + false + + + + + + + + Gate type + + + + + + + Ba&ttleChip Gate + + + true + + + + + + + Progress &Gate + + + + + + + Beast &Link Gate + + + + + + + + + Qt::Vertical + + + + + + + + + Chip ID + + + + + + + 65535 + + + + + + + Inserted + + + + + + + + + + + + Show advanced + + + + + + + QDialogButtonBox::Close + + + + + + + showAdvanced + toggled(bool) + advanced + setVisible(bool) + + + 109 + 34 + + + 396 + 654 + + + buttonBox rejected() BattleChipView - close() + reject() - 310 - 632 + 416 + 690 - 310 - 331 + 314 + 360 From b4698ab638e172b18892d9c16f392ae08d223e09 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 18:45:54 -0800 Subject: [PATCH 048/429] Qt: Kick focus back to main window when clicking a chip --- src/platform/qt/BattleChipView.cpp | 7 ++++++- src/platform/qt/BattleChipView.h | 5 ++++- src/platform/qt/Window.cpp | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 53c9a3024..2e00ac47b 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -8,6 +8,8 @@ #include "ConfigController.h" #include "CoreController.h" #include "GBAApp.h" +#include "ShortcutController.h" +#include "Window.h" #include #include @@ -18,9 +20,10 @@ using namespace QGBA; -BattleChipView::BattleChipView(std::shared_ptr controller, QWidget* parent) +BattleChipView::BattleChipView(std::shared_ptr controller, Window* window, QWidget* parent) : QDialog(parent) , m_controller(controller) + , m_window(window) { QResource::registerResource(GBAApp::dataDir() + "/chips.rcc"); QResource::registerResource(ConfigController::configDir() + "/chips.rcc"); @@ -126,6 +129,8 @@ void BattleChipView::reinsert() { } else { insertChip(true); } + m_window->setWindowState(m_window->windowState() & ~Qt::WindowActive); + m_window->setWindowState(m_window->windowState() | Qt::WindowActive); } void BattleChipView::addChip() { diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 423c937c8..ca6dfb942 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -16,12 +16,13 @@ namespace QGBA { class CoreController; +class Window; class BattleChipView : public QDialog { Q_OBJECT public: - BattleChipView(std::shared_ptr controller, QWidget* parent = nullptr); + BattleChipView(std::shared_ptr controller, Window* window, QWidget* parent = nullptr); ~BattleChipView(); public slots: @@ -52,6 +53,8 @@ private: int m_frameCounter = -1; bool m_next = false; + + Window* m_window; }; } \ No newline at end of file diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 26c588d88..7d53ea420 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1370,7 +1370,7 @@ void Window::setupMenu(QMenuBar* menubar) { #ifdef M_CORE_GBA QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu); - connect(bcGate, &QAction::triggered, openControllerTView()); + connect(bcGate, &QAction::triggered, openControllerTView(this)); addControlledAction(emulationMenu, bcGate, "bcGate"); m_gbaActions.append(bcGate); m_gameActions.append(bcGate); From 407f5988aaead60853542c7ec3503f1dcba074fa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 18:47:43 -0800 Subject: [PATCH 049/429] Qt: Quality of life improvements for BattleChip UI --- src/platform/qt/BattleChipView.cpp | 38 +++++++++------- src/platform/qt/BattleChipView.h | 2 +- src/platform/qt/BattleChipView.ui | 70 ++++++++++++++++++++---------- src/platform/qt/resources.qrc | 27 +++++++----- 4 files changed, 85 insertions(+), 52 deletions(-) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 2e00ac47b..42cca1fc4 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -21,12 +23,12 @@ using namespace QGBA; BattleChipView::BattleChipView(std::shared_ptr controller, Window* window, QWidget* parent) - : QDialog(parent) + : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) , m_controller(controller) , m_window(window) { - QResource::registerResource(GBAApp::dataDir() + "/chips.rcc"); - QResource::registerResource(ConfigController::configDir() + "/chips.rcc"); + QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe"); + QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe"); m_ui.setupUi(this); @@ -38,12 +40,12 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo QString qtitle(title); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 16); + int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 12); #else - int size = QFontMetrics(QFont()).height() / (devicePixelRatio() * 16); + int size = QFontMetrics(QFont()).height() / (devicePixelRatio() * 12); #endif - m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size); m_ui.chipList->setIconSize(m_ui.chipList->iconSize() * size); + m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size); connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { m_ui.inserted->setChecked(Qt::Unchecked); @@ -59,6 +61,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo connect(controller.get(), &CoreController::stopping, this, &QWidget::close); connect(m_ui.save, &QAbstractButton::clicked, this, &BattleChipView::saveDeck); connect(m_ui.load, &QAbstractButton::clicked, this, &BattleChipView::loadDeck); + connect(m_ui.buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, m_ui.chipList, &QListWidget::clear); connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { if (on) { @@ -144,11 +147,11 @@ void BattleChipView::addChip() { void BattleChipView::addChipId(int id) { QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[id]); add->setData(Qt::UserRole, id); - QString path = QString(":/res/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); + QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); if (!QFile(path).exists()) { - path = QString(":/res/exe%1/placeholder.png").arg(m_flavor); + path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor); } - add->setIcon(QIcon(path)); + add->setIcon(QPixmap(path).scaled(m_ui.chipList->iconSize())); m_ui.chipList->addItem(add); } @@ -167,7 +170,7 @@ void BattleChipView::loadChipNames(int flavor) { } m_flavor = flavor; - QFile file(QString(":/res/exe%1/chip-names.txt").arg(flavor)); + QFile file(QString(":/exe/exe%1/chip-names.txt").arg(flavor)); file.open(QIODevice::ReadOnly | QIODevice::Text); int id = 0; while (true) { @@ -227,12 +230,17 @@ void BattleChipView::loadDeck() { ini.beginGroup("BattleChipDeck"); int flavor = ini.value("version").toInt(); if (flavor != m_flavor) { + QMessageBox* error = new QMessageBox(this); + error->setIcon(QMessageBox::Warning); + error->setStandardButtons(QMessageBox::Ok); + error->setWindowTitle(tr("Incompatible deck")); + error->setText(tr("The selected deck is not compatible with this Chip Gate")); + error->setAttribute(Qt::WA_DeleteOnClose); + error->show(); return; } - - while (m_ui.chipList->count()) { - delete m_ui.chipList->takeItem(m_ui.chipList->count() - 1); - } + + m_ui.chipList->clear(); QStringList deck = ini.value("deck").toString().split(','); for (const auto& item : deck) { bool ok; @@ -241,4 +249,4 @@ void BattleChipView::loadDeck() { addChipId(id); } } -} \ No newline at end of file +} diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index ca6dfb942..88a24d8a3 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -57,4 +57,4 @@ private: Window* m_window; }; -} \ No newline at end of file +} diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index a31513ced..f379a3bdc 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -13,7 +13,7 @@ BattleChip Gate - + @@ -35,7 +35,7 @@ - QListView::Snap + QListView::Static true @@ -45,13 +45,19 @@ - 80 + 120 72 QListView::IconMode + + false + + + true + @@ -174,10 +180,10 @@ - - + + - Chip ID + Inserted @@ -188,10 +194,10 @@ - - + + - Inserted + Chip ID @@ -200,19 +206,19 @@ + + + + Show advanced + + + - - - - Show advanced - - - - QDialogButtonBox::Close + QDialogButtonBox::Close|QDialogButtonBox::Reset @@ -222,6 +228,22 @@ + + buttonBox + rejected() + BattleChipView + reject() + + + 416 + 690 + + + 314 + 360 + + + showAdvanced toggled(bool) @@ -239,18 +261,18 @@ - buttonBox - rejected() - BattleChipView - reject() + chipList + indexesMoved(QModelIndexList) + chipList + doItemsLayout() - 416 - 690 + 314 + 203 314 - 360 + 203 diff --git a/src/platform/qt/resources.qrc b/src/platform/qt/resources.qrc index 990203809..bfc5235cc 100644 --- a/src/platform/qt/resources.qrc +++ b/src/platform/qt/resources.qrc @@ -1,14 +1,17 @@ - + + - ../../../res/mgba-1024.png - ../../../res/keymap.qpic - ../../../res/patrons.txt - ../../../res/no-cam.png - ../../../res/exe4/chip-names.txt - ../../../res/exe4/placeholder.png - ../../../res/exe5/chip-names.txt - ../../../res/exe5/placeholder.png - ../../../res/exe6/chip-names.txt - ../../../res/exe6/placeholder.png + ../../../res/mgba-1024.png + ../../../res/keymap.qpic + ../../../res/patrons.txt + ../../../res/no-cam.png - + + ../../../res/exe4/chip-names.txt + ../../../res/exe4/placeholder.png + ../../../res/exe5/chip-names.txt + ../../../res/exe5/placeholder.png + ../../../res/exe6/chip-names.txt + ../../../res/exe6/placeholder.png + + From 6aa5647fc4b3d45aaa138a1541e0cba582056a5a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 18:48:41 -0800 Subject: [PATCH 050/429] GBA DMA: Fix Display Start DMAs --- CHANGES | 1 + src/gba/dma.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 67845a325..c9646faf8 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Bugfixes: - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM - Python: Fix crash when deleting files owned by library - Python: Make sure GB link object isn't GC'd before GB object + - GBA DMA: Fix Display Start DMAs Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/dma.c b/src/gba/dma.c index d3ad66c8a..3aad223ea 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -182,7 +182,7 @@ void _dmaEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) { dma->nextCount = 0; bool noRepeat = !GBADMARegisterIsRepeat(dma->reg); noRepeat |= GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_NOW; - noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM; + noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM && gba->video.vcount == VIDEO_VERTICAL_PIXELS + 1; if (noRepeat) { dma->reg = GBADMARegisterClearEnable(dma->reg); From ef2b6c78ff28f1adfff85ab21620eec598c5fbde Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 18:49:23 -0800 Subject: [PATCH 051/429] GBA DMA: Fix DMA start/end timing --- CHANGES | 1 + src/gba/dma.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index c9646faf8..362272cfd 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugfixes: - Python: Fix crash when deleting files owned by library - Python: Make sure GB link object isn't GC'd before GB object - GBA DMA: Fix Display Start DMAs + - GBA DMA: Fix DMA start/end timing Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/dma.c b/src/gba/dma.c index 3aad223ea..eb66635c4 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -237,9 +237,6 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { gba->cpuBlocked = true; if (info->count == info->nextCount) { - if (sourceRegion < REGION_CART0 || destRegion < REGION_CART0) { - cycles += 2; - } if (width == 4) { cycles += memory->waitstatesNonseq32[sourceRegion] + memory->waitstatesNonseq32[destRegion]; } else { @@ -302,6 +299,9 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { info->nextDest = dest; if (!wordsRemaining) { info->nextCount |= 0x80000000; + if (sourceRegion < REGION_CART0 || destRegion < REGION_CART0) { + info->when += 2; + } } GBADMAUpdate(gba); } From 56d263ef2456baa0781583839d91d3352cad272d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 18:50:07 -0800 Subject: [PATCH 052/429] Qt: Fix window icon on X11 --- CHANGES | 1 + src/platform/qt/Window.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 362272cfd..19b6c569f 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Bugfixes: - Python: Make sure GB link object isn't GC'd before GB object - GBA DMA: Fix Display Start DMAs - GBA DMA: Fix DMA start/end timing + - Qt: Fix window icon on X11 Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 7d53ea420..f655998c0 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -85,6 +85,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi m_logo.setDevicePixelRatio(m_screenWidget->devicePixelRatio()); m_logo = m_logo; // Free memory left over in old pixmap + setWindowIcon(m_logo); #if defined(M_CORE_GBA) float i = 2; From 5effd9c1132216b683291baa850965747663b7ff Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Feb 2019 22:22:06 -0800 Subject: [PATCH 053/429] GB, GBA Serialize: Fix loading two states in a row --- CHANGES | 1 + src/gb/serialize.c | 2 +- src/gba/serialize.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 19b6c569f..72bdd0dd5 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Bugfixes: - GBA DMA: Fix Display Start DMAs - GBA DMA: Fix DMA start/end timing - Qt: Fix window icon on X11 + - GB, GBA Serialize: Fix loading two states in a row Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 6c3db6308..7a4f5de4b 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -138,7 +138,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { if (error) { return false; } - gb->timing.root = NULL; + mTimingClear(&gb->timing); LOAD_32LE(gb->timing.masterCycles, 0, &state->masterCycles); gb->cpu->a = state->cpu.a; diff --git a/src/gba/serialize.c b/src/gba/serialize.c index 458ba3d3a..60b8524ca 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -132,7 +132,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) { if (error) { return false; } - gba->timing.root = NULL; + mTimingClear(&gba->timing); LOAD_32(gba->timing.masterCycles, 0, &state->masterCycles); size_t i; From e5161b766d6b8bdd21a174724b435c68185462e0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Feb 2019 00:13:22 -0800 Subject: [PATCH 054/429] GBA Video: Fix enabling layers in non-tile modes (fixes #1317) --- CHANGES | 1 + src/gba/renderers/video-software.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 72bdd0dd5..db72bf169 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Bugfixes: - GBA DMA: Fix DMA start/end timing - Qt: Fix window icon on X11 - GB, GBA Serialize: Fix loading two states in a row + - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 614f9087f..f31239d09 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -727,7 +727,8 @@ static void _enableBg(struct GBAVideoSoftwareRenderer* renderer, int bg, bool ac if (!active) { renderer->bg[bg].enabled = 0; } else if (!wasActive && active) { - if (renderer->nextY == 0) { + if (renderer->nextY == 0 || GBARegisterDISPCNTGetMode(renderer->dispcnt) > 2) { + // TODO: Investigate in more depth how switching background works in different modes renderer->bg[bg].enabled = 4; } else { renderer->bg[bg].enabled = 1; From 31dc70e6370239292dee9649b54e28ff71f08073 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Feb 2019 01:15:58 -0800 Subject: [PATCH 055/429] Qt: Fix quick load recent accidentally saving (fixes #1309) --- CHANGES | 1 + src/platform/qt/Window.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index db72bf169..05309b6b5 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Bugfixes: - Qt: Fix window icon on X11 - GB, GBA Serialize: Fix loading two states in a row - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) + - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index f655998c0..d46b107bf 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1108,7 +1108,7 @@ void Window::setupMenu(QMenuBar* menubar) { addControlledAction(quickLoadMenu, quickLoad, "quickLoad"); QAction* quickSave = new QAction(tr("Save recent"), quickSaveMenu); - connect(quickLoad, &QAction::triggered, [this] { + connect(quickSave, &QAction::triggered, [this] { m_controller->saveState(); }); m_gameActions.append(quickSave); From 92aa78cf0c374e37ba4ef3b7f95a969295e15847 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Feb 2019 02:08:30 -0800 Subject: [PATCH 056/429] GBA: Fix video timing when skipping BIOS (fixes #1318) --- CHANGES | 1 + src/gba/gba.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 05309b6b5..e8f2be434 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Bugfixes: - GB, GBA Serialize: Fix loading two states in a row - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) + - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) 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 8954df16b..357910767 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -254,7 +254,8 @@ void GBASkipBIOS(struct GBA* gba) { } else { cpu->gprs[ARM_PC] = BASE_WORKING_RAM; } - gba->memory.io[REG_VCOUNT >> 1] = 0x7E; + gba->video.vcount = 0x7D; + gba->memory.io[REG_VCOUNT >> 1] = 0x7D; gba->memory.io[REG_POSTFLG >> 1] = 1; ARMWritePC(cpu); } From 4b32348601c17f69f24eaa05f8ec6c75b56233d9 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Sat, 23 Feb 2019 22:46:03 +0100 Subject: [PATCH 057/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 813 ++++++++++++++++++++-------------- 1 file changed, 476 insertions(+), 337 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index 5f2748367..8e6b08892 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -125,6 +125,79 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.0x00 (00) + + BattleChipView + + + BattleChip Gate + BattleChip Gate + + + + Chip name + Chip-Name + + + + Insert + Einsetzen + + + + Save + Speichern + + + + Load + Laden + + + + Add + Hinzufügen + + + + Remove + Entfernen + + + + Gate type + Gate-Typ + + + + Ba&ttleChip Gate + Ba&ttleChip Gate + + + + Progress &Gate + Progress &Gate + + + + Beast &Link Gate + Beast &Link Gate + + + + Inserted + Eingesetzt + + + + Chip ID + Chip-ID + + + + Show advanced + Erweiterte Optionen anzeigen + + CheatsView @@ -632,56 +705,56 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - 1 Byte - 1 Byte + &1 Byte + &1 Byte - 2 Bytes - 2 Bytes + &2 Bytes + &2 Bytes - 4 Bytes - 4 Bytes + &4 Bytes + &4 Bytes - + Signed Integer: Signed Integer: - + String: String: - + Load TBL TBL laden - + Copy Selection Auswahl kopieren - + Paste Einfügen - + Save Selection Auswahl speichern - + Load Laden - + Unsigned Integer: Unsigned Integer: @@ -1211,22 +1284,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -2728,40 +2801,89 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Speicherplatz %1 + + QGBA::LogConfigModel + + + + Default + Standard + + + + Fatal + Kritisch + + + + Error + Fehler + + + + Warning + Warnung + + + + Info + Info + + + + Debug + Debug + + + + Stub + Stub + + + + Game Error + Spiel-Fehler + + QGBA::LogController - + + [%1] %2: %3 + [%1] %2: %3 + + + DEBUG DEBUG - + STUB STUB - + INFO INFO - + WARN WARN - + ERROR ERROR - + FATAL FATAL - + GAME ERROR GAME ERROR @@ -2903,54 +3025,54 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 0x%0 - + Off Aus - + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Ungültig - - + + N/A N/A - + Export sprite Sprite exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 Fehler beim Öffnen der Ausgabe-PNG-Datei: %1 @@ -2995,19 +3117,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Fehler beim Öffnen der Ausgabe-Palettendatei: %1 - - QGBA::PrinterView - - - Save Printout - Ausdruck speichern - - - - Portable Network Graphics (*.png) - Portable Network Graphics (*.png) - - QGBA::ROMInfo @@ -3034,59 +3143,59 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (erzwinge Version 1.x) - + None (Still Image) Keiner (Standbild) - + Keyboard Tastatur - + Controllers Gamepads - + Shortcuts Tastenkürzel - - + + Shaders Shader - + Select BIOS BIOS auswählen @@ -3163,103 +3272,103 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) - - - + + + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3268,628 +3377,633 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + F10 F10 - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Shift+F10 Umschalt+F10 - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + F11 F11 - + Undo save state Speichern des Savestate rückgängig machen - + Shift+F11 Umschalt+F11 - - + + State &%1 Savestate &%1 - + F%1 F%1 - + Shift+F%1 Umschalt+F%1 - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + About Über - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Ctrl+R Strg+R - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + Ctrl+P Strg+P - + &Next frame &Nächstes Bild - + Ctrl+N Strg+N - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Shift+Tab Umschalt+Tab - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + ~ ~ - + Step backwards Schrittweiser Rücklauf - + Ctrl+B Strg+B - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Solar-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + + BattleChip Gate... + BattleChip Gate... + + + Audio/&Video Audio/&Video - + Frame size Bildgröße - + %1x %1x - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Record output... Ausgabe aufzeichen... - + Record GIF... GIF aufzeichen... - + Record video log... Video-Log aufzeichnen... - + Stop video log Video-Log beenden - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + Game &Pak sensors... Game &Pak-Sensoren... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... - + Select folder Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -4053,504 +4167,529 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Einstellungen - + Audio/Video Audio/Video - + Interface Benutzeroberfläche - + Emulation Emulation - + Paths Verzeichnisse - + + Logging + Protokoll + + + Game Boy Game Boy - + Audio driver: Audio-Treiber: - + Audio buffer: Audio-Puffer: - - + + 1536 1536 - + 512 512 - + 768 768 - + 1024 1024 - + 2048 2048 - + 3072 3072 - + 4096 4096 - + samples Samples - + Sample rate: Abtastrate: - - + + 44100 44100 - + 22050 22050 - + 32000 32000 - + 48000 48000 - + Hz Hz - + Volume: Lautstärke: - - + + Mute Stummschalten - + Fast forward volume: Vorspul-Lautstärke: - + Display driver: Anzeige-Treiber: - + Frameskip: Frameskip: - + Skip every Überspringe - - + + frames Bild(er) - + FPS target: Bildwiederholrate: - + frames per second Bilder pro Sekunde - + Sync: Synchronisierung: - + Video Video - + Audio Audio - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Erzwinge pixelgenaue Skalierung (Integer scaling) - + Language Sprache - + English Englisch - + List view Listenansicht - + Tree view Baumansicht - + Show FPS in title bar Bildwiederholrate in der Titelleiste anzeigen - + Automatically save cheats Cheats automatisch speichern - + Automatically load cheats Cheats automatisch laden - + Automatically save state Zustand (Savestate) automatisch speichern - + Automatically load state Zustand (Savestate) automatisch laden - + Cheats Cheats - + + Log to file + In Datei protokollieren + + + + Log to console + Auf die Konsole protokollieren + + + + Select Log File + Protokoll-Datei auswählen + + + Game Boy model Game Boy-Modell - - - + + + Autodetect Automatisch erkennen - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Super Game Boy model Super Game Boy-Modell - + Game Boy Color model Game Boy Color-Modell - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + + Use GBC colors in GB games + Verwende GBC-Farben in GB-Spielen + + + Super Game Boy borders Super Game Boy-Rahmen - + Camera driver: Kamera-Treiber: - + Library: Bibliothek: - + Show when no game open Anzeigen, wenn kein Spiel geöffnet ist - + Clear cache Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - - + + + + + + + + + Browse Durchsuchen - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - + × × - + Unbounded unbegrenzt - + Suspend screensaver Bildschirmschoner deaktivieren - + BIOS BIOS - + Pause when inactive Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen - + Allow opposing input directions Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren - + Bilinear filtering Bilineare Filterung - + Rewind history: Rücklauf-Verlauf: - + Idle loops: Leerlaufprozesse: - + Savestate extra data: Zusätzliche Savestate-Daten: - + Load extra data: Lade zusätzliche Daten: - + Autofire interval: Autofeuer-Intervall: - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches From 2b09a8c207d9a80f9529516b369a522a371cde71 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Feb 2019 18:33:42 -0800 Subject: [PATCH 058/429] 3DS: Work around menu freezing (fixes #1294) --- CHANGES | 1 + src/feature/gui/gui-runner.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index e8f2be434..cda0153ad 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Bugfixes: - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) + - 3DS: Work around menu freezing (fixes mgba.io/i/1294) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 3dc0965a6..0afbd355e 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -548,6 +548,10 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->params.drawStart(); runner->drawFrame(runner, true); runner->params.drawEnd(); +#ifdef _3DS + // XXX: Why does this fix #1294? + usleep(1000); +#endif GUIPollInput(&runner->params, 0, &keys); } if (runner->unpaused) { From cf0881534714464312cf38ef5f4ae7c00d2dceee Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Feb 2019 18:38:54 -0800 Subject: [PATCH 059/429] Qt: Updated Italian translation (by Vecna) --- CHANGES | 1 + src/platform/qt/ts/mgba-it.ts | 642 +++++++++++++++++----------------- 2 files changed, 322 insertions(+), 321 deletions(-) diff --git a/CHANGES b/CHANGES index cda0153ad..c7c94ee4c 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Misc: - Qt: Don't unload ROM immediately if it crashes - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) - Debugger: Add breakpoint and watchpoint listing + - Qt: Updated Italian translation (by Vecna) 0.7.0: (2019-01-26) Features: diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index affde3f37..6b08a7f60 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -6,7 +6,7 @@ About - About + Info... @@ -26,7 +26,7 @@ © 2013 – 2016 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 - 2016 Jeffrey Pfau, sotto licenza Mozilla Public License, versione 2.0 + © 2013 - 2016 Jeffrey Pfau, sotto licenza Mozilla Public License, versione 2.0 Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. @@ -43,7 +43,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 - 2016 Jeffrey Pfau, sotto licenza Mozilla Public License, versione 2.0 + © 2013 - 2016 Jeffrey Pfau, sotto licenza Mozilla Public License, versione 2.0 Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ?} {2.0 ?} @@ -68,7 +68,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Open in archive... - Apri il file in ... + Apri il file in archivio... @@ -97,7 +97,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Palette # - + Palette Nº @@ -122,7 +122,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Blue - Blue + Blu @@ -142,7 +142,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Remove - Rimuovere + Rimuovi @@ -157,7 +157,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Add New Set - Aggiungere Nuovo Set + Aggiungi Nuovo Set @@ -180,7 +180,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Break - Pausa + Interruzione @@ -198,7 +198,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Stop - Stop + Ferma @@ -208,7 +208,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Frameskip - Salta Frame + Salto Frame @@ -319,34 +319,34 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Name - Nome + Nome Location - Posizione + Posizione Platform - Piattaforma + Piattaforma Size - Dimensione + Dimensioni CRC32 - CRC32 + CRC32 LibraryView Library - Biblioteca + Biblioteca @@ -436,7 +436,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Stub - Stub + Matrice @@ -471,7 +471,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Max Lines - Linee di massima + Linee massime @@ -479,22 +479,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Maps - + Mappe × - × + × Magnification - Magnification + Ingrandimento Export - + Esporta @@ -502,124 +502,124 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Memory Search - + Ricerca Memoria Address - Indirizzo + Indirizzo Current Value - + Valore corrente Type - + Tipo Value - Valore + Valore Numeric - + Numerico Text - + Testo Width - + Larghezza Guess - + Indovina 1 Byte (8-bit) - + 1 Byte (8-bit) 2 Bytes (16-bit) - + 2 Bytes (16-bit) 4 Bytes (32-bit) - + 4 Bytes (32-bit) Number type - + Tipo di numero Decimal - + Decimale Hexadecimal - + Esadecimale Compare - + Confronta Equal - + Uguale Greater - + Maggiore Less - + Minore Delta - + Delta Search - + Cerca Search Within - + Cerca all'interno Open in Memory Viewer - + Apri nel Visualizzatore Memoria Refresh - Aggiornare + Aggiorna @@ -632,7 +632,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Inspect Address: - Ispezionare indirizzo: + Ispeziona indirizzo: @@ -642,27 +642,27 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Set Alignment: - Set di allignamento: + Set di allineamento: 1 Byte - 1 byte + 1 Byte 2 Bytes - 2 bytes + 2 Bytes 4 Bytes - 4 bytes + 4 Bytes Signed Integer: - Integer Signato: + Intero segnato: @@ -687,7 +687,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Save Selection - Salva Selezione + Salva la selezione @@ -697,7 +697,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Unsigned Integer: - Integer non signato: + Intero non segnato: @@ -716,12 +716,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Magnification - Magnification + Ingrandimento Export - + Esporta @@ -731,7 +731,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Transform - Transformazione + Trasformazione @@ -754,7 +754,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Double Size - Doppia Dimensione + Dimensioni doppie @@ -827,7 +827,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Dimensions - Dimensione + Dimensioni @@ -851,7 +851,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Game Overrides - Valori specifici per gioco + Valori specifici per il gioco @@ -869,7 +869,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Realtime clock - RealTime clock + Clock in tempo reale @@ -950,7 +950,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Super Game Boy (SGB) - + Super Game Boy (SGB) @@ -985,7 +985,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? MBC3 + RTC - MBC3 + Reloj + MBC3 + RTC @@ -1005,12 +1005,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Pocket Cam - + Pocket Cam TAMA5 - + TAMA5 @@ -1020,17 +1020,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Background Colors - + Colori di sfondo Sprite Colors 1 - + Colori Sprite 1 Sprite Colors 2 - + Colori Sprite 2 @@ -1043,12 +1043,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Background - SFondo (BG) + Sfondo Objects - Oggetti (OBJ) + Oggetti @@ -1068,7 +1068,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Blue - Blue + Blu @@ -1123,27 +1123,27 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Adjust placement - + Regola posizionamento All - Tutto + Tutto Offset - + Offset X - + X Y - + Y @@ -1151,17 +1151,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Game Boy Printer - + Stampante Game Boy Hurry up! - + Sbrigati! Tear off - + Strappa @@ -1184,17 +1184,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Can't set format of context-less audio device - + Impossibile impostare il formato del dispositivo audio Audio device is missing its core - + Il dispositivo audio non possiede alcun core Writing data to read-only audio device - + Scrittura dei dati per il dispositivo audio in sola-lettura @@ -1202,7 +1202,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Can't start an audio processor without input - + Impossibile avviare un processore audio senza input @@ -1210,7 +1210,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Can't start an audio processor without input - + Impossibile avviare un processore audio senza input @@ -1261,22 +1261,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Failed to open save file: %1 - Impossibile aprire il file di salvataggio: %1 + Impossibile aprire il file di salvataggio: %1 Failed to open game file: %1 - Impossibile aprire il file di gioco: %1 + Impossibile aprire il file di gioco: %1 Failed to open snapshot file for reading: %1 - Impossibile aprire il file snapshot per la lettura: %1 + Impossibile aprire il file snapshot per la lettura: %1 Failed to open snapshot file for writing: %1 - Impossibile aprire il file snapshot per la scrittura: %1 + Impossibile aprire il file snapshot per la scrittura: %1 @@ -1284,7 +1284,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Failed to open game file: %1 - Impossibile aprire il file di gioco: %1 + Impossibile aprire il file di gioco: %1 @@ -1292,22 +1292,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Clear Button - Pulisci bottoni + Svuota i pulsanti Clear Analog - Pulisci analogici + Svuota Analogici Refresh - Aggiornare + Aggiorna Set all - Impostare tutti + Imposta tutti @@ -1330,12 +1330,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Break - Break + Interruzione Stop - Stop + Ferma @@ -1368,30 +1368,30 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Graphics Interchange Format (*.gif) - Formato di interconnessione grafica (*.gif) + Graphics Interchange Format (*.gif) QGBA::GameController Failed to open game file: %1 - Impossibile aprire il file di gioco: %1 + Impossibile aprire il file di gioco: %1 Failed to open save file: %1 - Impossibile aprire il file di salvataggio: %1 + Impossibile aprire il file di salvataggio: %1 Failed to open snapshot file for reading: %1 - Impossibile aprire il file snapshot per la lettura: %1 + Impossibile aprire il file snapshot per la lettura: %1 Failed to open snapshot file for writing: %1 - Impossibile aprire il file snapshot per la scrittura: %1 + Impossibile aprire il file snapshot per la scrittura: %1 Failed to start audio processor - Impossibile avviare il processore audio + Impossibile avviare il processore audio @@ -1514,17 +1514,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Enable VBlank IRQ generation - Abilita VBlank + Abilita creazione IRQ VBlank Enable HBlank IRQ generation - Abilita HBlank generazione IRQ + Abilita creazione IRQ HBlank Enable VCounter IRQ generation - Abilita generazione IRQ VCounter + Abilita creazione IRQ VCounter @@ -1632,7 +1632,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Integer part - Parte Integer + Parte Intero @@ -1640,7 +1640,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Integer part (bottom) - Parte Integer (inferiore) + Parte Intero (inferiore) @@ -1648,7 +1648,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Integer part (top) - Parte Integer (superiore) + Parte Intero (superiore) @@ -1722,7 +1722,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Window 1 enable BG 3 - AbilitaWindow 1 BG 3 + Abilita Window 1 BG 3 @@ -1857,17 +1857,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Additive blending - Miscelazione dell'additivo + Miscelazione additiva Brighten - Schiarire + Illumina Darken - Oscurire + Oscura @@ -1927,7 +1927,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Sweep time (in 1/128s) - Tempo di sweep (in 1/128seg) + Tempo di sweep (in 1/128s) @@ -2041,7 +2041,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Clock divider - Divisore dell'orologio + Divisore del Clock @@ -2304,7 +2304,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Destination offset - Compensazione offset + Offset di destinazione @@ -2356,7 +2356,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Source offset - Compensazione di origine + Offset di origine @@ -2433,7 +2433,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Enable - Abilitare + Abilita @@ -2515,13 +2515,13 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Select - Seleziona + Select Start - Avvia + Start @@ -2539,7 +2539,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Up - + Su @@ -2754,12 +2754,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Gamepak prefetch - Gamepak prefetch + Precaricamento Gamepak Enable IRQs - Abilitare IRQs + Abilita IRQs @@ -2775,39 +2775,39 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? QGBA::LibraryModel Name - Nome + Nome Filename - Nome del file + Nome del file Size - Dimensione + Dimensioni Platform - Piattaforma + Piattaforma GBA - GBA + GBA GB - GB + GB ? - ? + ? Location - Posizione + Posizione CRC32 - CRC32 + CRC32 @@ -2881,47 +2881,47 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Map Addr. - + Indir. Mappa Mirror - + Specchiatura None - Nessuno + Nessuno Both - + Entrambi Horizontal - + Orizzontale Vertical - + Verticale Export map - + Esporta Mappa Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) Failed to open output PNG file: %1 - + Impossibile aprire il file PNG: %1 @@ -2929,12 +2929,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Copy selection - Copia selezionato + Copia selezione Save selection - Salva selezionato + Salva selezione @@ -2960,7 +2960,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Save selected memory - Salva la memoria selezionate + Salva la memoria selezionata @@ -2993,22 +2993,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? (%0/%1×) - + (%0/%1×) (⅟%0×) - + (⅟%0×) (%0×) - + (%0×) %1 byte%2 - + %1 byte%2 @@ -3042,28 +3042,28 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Invalid - Invalido + Non valido N/A - n/d + N/D Export sprite - + Esporta sprite Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) Failed to open output PNG file: %1 - + Impossibile aprire il file PNG: %1 @@ -3103,7 +3103,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Failed to open output palette file: %1 - Errore nell'aprire il file palette di output : %1 + Errore nell'aprire il file palette di output: %1 @@ -3111,12 +3111,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Save Printout - + Salva Stampa Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -3173,7 +3173,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? None (Still Image) - + Niente (Immagine fissa) @@ -3188,13 +3188,13 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Shortcuts - Tasti di scelta rapida + Scorciatoie Shaders - Shaders + Shader @@ -3207,7 +3207,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? No shader active - Nessun shader attivo + Nessuno shader attivo @@ -3216,22 +3216,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? %1 Shader (%.shader) - %1 Shader (%.shader) + %1 Shader (%.shader) No shader loaded - Nessun shader caricato + Nessuno shader caricato by %1 - por %1 + per %1 Preprocessing - Preprocesso + Pre-elaborazione @@ -3272,7 +3272,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Select output file - Seleziona file di output + Seleziona file di uscita @@ -3280,12 +3280,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Game Boy Advance ROMs (%1) - ROM di Game Boy Advance (%1) + ROM per Game Boy Advance (%1) Game Boy ROMs (%1) - ROMs del Game Boy (%1) + ROM per Game Boy (%1) @@ -3295,12 +3295,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? %1 Video Logs (*.mvl) - + %1 log Video (*.mvl) Archives (%1) - Archivio (%1) + Archivi (%1) @@ -3334,12 +3334,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Select image - + Seleziona immagine Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + File immagine (*.png *.gif *.jpg *.jpeg);;Tutti i file (*) @@ -3350,12 +3350,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Select video log - + Seleziona log video Video logs (*.mvl) - + Log video (*.mvl) @@ -3394,12 +3394,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Really make portable? - Davvero rendere portatile? + Vuoi davvero rendere portatile l'applicazione? This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - In questo modo l'emulatore carica la propria configurazione dalla stessa directory dell'eseguibile. Vuoi continuare? + In questo modo l'emulatore carica la propria configurazione dalla stessa cartella dell'eseguibile. Vuoi continuare? @@ -3409,7 +3409,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Some changes will not take effect until the emulator is restarted. - Alcune modifiche non avranno effetto finché l'emulatore non viene riavviato. + Alcune modifiche non avranno effetto finché l'emulatore non verrà riavviato. @@ -3434,12 +3434,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? &File - &File + File Load &ROM... - Carica &ROM... + Carica ROM... @@ -3449,7 +3449,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Load alternate save... - + Carica il salvataggio alternativo... @@ -3459,22 +3459,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Load &patch... - Carica &patch... + Carica patch... Boot BIOS - Boot BIOS + Avvia BIOS Replace ROM... - Sostituire la ROM... + Sostituisci la ROM... ROM &info... - ROM &info... + Informazioni ROM... @@ -3489,7 +3489,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? &Load state - &Carica stato + Carica stato @@ -3499,7 +3499,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? &Save state - &Salva stato + Salva stato @@ -3541,7 +3541,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Undo save state - Annulla salva stato + Annulla salvataggio stato @@ -3553,7 +3553,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? State &%1 - Stato &%1 + Stato %1 @@ -3569,7 +3569,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Load camera image... - + Carica immagine camera... @@ -3589,22 +3589,22 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? About - About + Info... E&xit - Uscire (&X) + Esci (&X) &Emulation - &Emulazione + Emulazione &Reset - &Reset + Reset @@ -3624,7 +3624,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? &Pause - &Pausa + Pausa @@ -3644,7 +3644,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Fast forward (held) - Avanzamento rapido (sostenuto) + Avanzamento rapido (tieni premuto) @@ -3664,7 +3664,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Unbounded - Illimitato + Illimitata @@ -3674,12 +3674,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Rewind (held) - Riavvolgi (sostenuto) + Riavvolgimento (tieni premuto) Re&wind - Riavvolgi (&W) + Riavvolgimento (&W) @@ -3699,12 +3699,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Sync to &video - Sincronizzare su &video + Sincronizza con il video Sync to &audio - Sincronizzare su &audio + Sincronizza con l'audio @@ -3739,12 +3739,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Audio/&Video - Audio/&Video + Audio/Video Frame size - Dimensione Frame + Dimensioni Frame @@ -3754,25 +3754,25 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Toggle fullscreen - Abilita schermo intero + Abilita Schermo Intero Lock aspect ratio - Blocca aspect ratio + Blocca rapporti aspetto Resample video - Rimostra video + Ricampiona video Frame&skip - Frame&skip + Salto frame Shader options... - Opzioni shader... + Opzioni shader... @@ -3782,7 +3782,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? FPS target - FPS mirato + FPS finali @@ -3827,7 +3827,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Take &screenshot - Effettua &screenshot + Acquisisci screenshot @@ -3837,7 +3837,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Record output... - Registra salida... + Registra uscita... @@ -3851,11 +3851,11 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Background %0 - Sfondo %0 + Sfondo %0 OBJ (sprites) - OBJ (sprites) + OBJ (sprites) @@ -3864,20 +3864,20 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Channel %0 - Canale %0 + Canale %0 Channel A - Canale A + Canale A Channel B - Canale B + Canale B &Tools - &Strumenti + Strumenti @@ -3887,17 +3887,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Game &overrides... - Val&specifico per il gioco... + Valore specifico per il gioco... Game &Pak sensors... - Sensori di gioco &Pak... + Sensori Game Pak... &Cheats... - &Trucchi... + Trucchi... @@ -3907,7 +3907,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Start &GDB server... - Avvia server &GDB... + Avvia server GDB... @@ -3927,132 +3927,132 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Force integer scaling - + Forza l'integer scaling Bilinear filtering - + Filtro bilineare Record video log... - + Registra log video... Stop video log - + Interrompi log video Game Boy Printer... - + Stampante Game Boy... Adjust layer placement... - + Regola posizionamento layer... View &palette... - Ver &palette... + Mostra palette... View &sprites... - Ver &sprites... + Mostra sprites... View &tiles... - Ver &tiles... + Mostra tiles... View &map... - + Mostra mappa... View memory... - Ver memoria... + Mostra memoria... Search memory... - + Ricerca memoria... View &I/O registers... - Ver reg&registri I/O... + Mostra registri I/O... Exit fullscreen - Esci da schermo intero + Esci da Schermo Intero GameShark Button (held) - + Pulsante GameShark (tieni premuto) Autofire - Pulsanti Auto fuoco + Pulsanti Autofire Autofire A - Auto fuoco A + Autofire A Autofire B - Auto fuoco B + Autofire B Autofire L - Auto fuoco L + Autofire L Autofire R - Auto fuoco R + Autofire R Autofire Start - Avvia Auto fuoco + Autofire Start Autofire Select - Seleziona Auto fuoco + Autofire Select Autofire Up - Auto fuoco sù + Autofire Su Autofire Right - Auto fuoco destro + AAutofire Destra Autofire Down - Auto fuoco giù + Autofire Giù Autofire Left - Auto fuoco sinistro + Autofire Sinistra @@ -4060,17 +4060,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? GBA - GBA + GBA GB - GB + GB ? - ? + ? @@ -4078,7 +4078,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? ROM Info - Informazioni della ROM + Informazioni sulla ROM @@ -4113,7 +4113,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? File size: - Dimensione del file: + Dimensioni del file: @@ -4141,7 +4141,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Realtime clock - Realtime clock + Clock in tempo reale @@ -4166,7 +4166,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? MM/dd/yy hh:mm:ss AP - dd/MM/yy HH:mm:ss + gg/MM/aa OO:mm:ss @@ -4231,12 +4231,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Paths - Paths + Cartelle Game Boy - Game Boy + Game Boy @@ -4287,12 +4287,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? samples - samples + campioni Sample rate: - Sample rate: + Freq. di campionamento: @@ -4338,7 +4338,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Frameskip: - Frameskip: + Salto frame: @@ -4354,17 +4354,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? FPS target: - FPS mirato: + FPS finali: frames per second - frame per secondo + frame al secondo Sync: - Sincronizzare: + Sincronizza: @@ -4379,91 +4379,91 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Lock aspect ratio - Blocca aspect ratio + Blocca rapporti aspetto Cheats - Trucchi + Trucchi Game Boy model - Modello del Game Boy + Modello del Game Boy Autodetect - Rilevamento automatico + Rilevamento automatico Game Boy (DMG) - Game Boy (DMG) + Game Boy (DMG) Super Game Boy (SGB) - + Game Boy Color (CGB) - Game Boy Color (CGB) + Game Boy Color (CGB) Game Boy Advance (AGB) - Game Boy Advance (AGB) + Game Boy Advance (AGB) Super Game Boy model - + Modello di Super Game Boy Game Boy Color model - + Modello di Game Boy Color Default BG colors: - + Colori predefiniti BG: Super Game Boy borders - + Bordi Super Game Boy Camera driver: - + Driver della fotocamera: Default sprite colors 1: - + Colori predefiniti sprite 1: Default sprite colors 2: - + Colori predefiniti sprite 2: Resample video - Rimostrare video + Ricampionamento Video @@ -4478,7 +4478,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Clear cache - Cancella cache + Svuota la cache @@ -4501,12 +4501,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Use BIOS file if found - Utilizzare il file del BIOS se è stato trovato + Usa il file del BIOS se è presente Skip BIOS intro - Salta BIOS intro + Salta intro del BIOS @@ -4531,12 +4531,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Pause when inactive - Pausa se inattivo + In Pausa se inattivo Run all - Avviare tutto + Avvia tutto @@ -4574,67 +4574,67 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Enable rewind - Abilita riavvolgi + Abilita riavvolgimento Bilinear filtering - + Filtro bilineare Force integer scaling - + Forza scaling con numeri interi Language - + Lingua English - + List view - + Inglese Tree view - + Visualizza ad albero Show FPS in title bar - + Mostra gli FPS nella barra del titolo Automatically save cheats - + Salva i trucchi automaticamente Automatically load cheats - + Carica i trucchi automaticamente Automatically save state - + Salva stato automaticamente Automatically load state - + Carica stato automaticamente Rewind history: - Riavvolgi storia: + Cronologia riavvolgimento: @@ -4644,7 +4644,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Savestate extra data: - Salva dati extra: + Dati extra salvataggio stato: @@ -4654,42 +4654,42 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Rewind affects save data - + Il riavvolgimento influenza i dati salvataggio Preload entire ROM into memory - + Precarica tutta la ROM nella memoria Autofire interval: - + Intervallo Autofire: GB BIOS file: - File GB BIOS: + File BIOS del GB: GBA BIOS file: - File GBA BIOS: + File BIOS del GBA: GBC BIOS file: - File GBC BIOS: + File BIOS del GBC: SGB BIOS file: - + File BIOS del SGB: Save games - Salva il gioco + Salva le partite @@ -4698,17 +4698,17 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Same directory as the ROM - Stessa directory della ROM + Stessa cartella della ROM Save states - Salva Stato + Salvataggio Stati Screenshots - Screenshots + Screenshot @@ -4721,7 +4721,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Shaders - Shaders + Shader @@ -4751,7 +4751,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Load New Shader - Carica Nuovo shader + Carica nuovo shader @@ -4759,7 +4759,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Edit Shortcuts - Edita Shortcuts + Modifica le Scorciatoie @@ -4774,7 +4774,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Clear - Cancella + Svuota @@ -4797,7 +4797,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Magnification - Magnification + Ingrandimento @@ -4805,7 +4805,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Record Video - Registra video + Registra Video @@ -4815,7 +4815,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Stop - Stop + Ferma @@ -4825,7 +4825,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Presets - Presets + Profili @@ -4890,7 +4890,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? PNG - PNG + PNG @@ -4900,21 +4900,21 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? h.264 (NVENC) - + h.264 (NVENC) HEVC - + HEVC VP8 - + VP8 Xvid - Xvid + Xvid @@ -4954,7 +4954,7 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Bitrate (kbps) - Bitrate (kbps) + Bitrate (kbps) @@ -4984,12 +4984,12 @@ Game Boy Advance è un marchio registrato di Nintendo Co., Ltd. {2013 ?} {2018 ? Lock aspect ratio - Blocca aspect ratio + Blocca rapporti aspetto Show advanced - Mostra avanzato + Mostra avanzate From f9f105a8520813a5d6300bc082e5bf98d6c01d95 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Feb 2019 00:28:49 -0800 Subject: [PATCH 060/429] GBA: Improve delayed IRQ timing --- CHANGES | 1 + include/mgba/internal/gba/gba.h | 4 ++-- src/gba/dma.c | 2 +- src/gba/extra/battlechip.c | 4 ++-- src/gba/gba.c | 21 +++++++++++++-------- src/gba/hardware.c | 2 +- src/gba/io.c | 6 +++--- src/gba/sio.c | 2 +- src/gba/sio/joybus.c | 6 +++--- src/gba/sio/lockstep.c | 6 +++--- src/gba/timer.c | 2 +- src/gba/video.c | 6 +++--- 12 files changed, 34 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index c7c94ee4c..3d0f61df1 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Misc: - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) - Debugger: Add breakpoint and watchpoint listing - Qt: Updated Italian translation (by Vecna) + - GBA: Improve delayed IRQ timing 0.7.0: (2019-01-26) Features: diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index 4bd899fe6..f1b3fa2f5 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -143,8 +143,8 @@ void GBADestroy(struct GBA* gba); void GBAReset(struct ARMCore* cpu); void GBASkipBIOS(struct GBA* gba); -void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq); -void GBATestIRQ(struct ARMCore* cpu); +void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq, uint32_t cyclesLate); +void GBATestIRQ(struct GBA* gba, uint32_t cyclesLate); void GBAHalt(struct GBA* gba); void GBAStop(struct GBA* gba); void GBADebug(struct GBA* gba, uint16_t value); diff --git a/src/gba/dma.c b/src/gba/dma.c index eb66635c4..7ab7a85c7 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -193,7 +193,7 @@ void _dmaEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) { dma->nextDest = dma->dest; } if (GBADMARegisterIsDoIRQ(dma->reg)) { - GBARaiseIRQ(gba, IRQ_DMA0 + memory->activeDMA); + GBARaiseIRQ(gba, IRQ_DMA0 + memory->activeDMA, cyclesLate); } GBADMAUpdate(gba); } diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index 94d591efa..b76247cd0 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -101,7 +101,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0; gate->d.p->normalControl.start = 0; if (gate->d.p->normalControl.irq) { - GBARaiseIRQ(gate->d.p->p, IRQ_SIO); + GBARaiseIRQ(gate->d.p->p, IRQ_SIO, cyclesLate); } return; } @@ -193,6 +193,6 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply; if (gate->d.p->multiplayerControl.irq) { - GBARaiseIRQ(gate->d.p->p, IRQ_SIO); + GBARaiseIRQ(gate->d.p->p, IRQ_SIO, cyclesLate); } } diff --git a/src/gba/gba.c b/src/gba/gba.c index 357910767..e144ce45a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -46,6 +46,7 @@ static void GBAProcessEvents(struct ARMCore* cpu); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); static void GBAIllegal(struct ARMCore* cpu, uint32_t opcode); static void GBABreakpoint(struct ARMCore* cpu, int immediate); +static void GBATestIRQNoDelay(struct ARMCore* cpu); static void _triggerIRQ(struct mTiming*, void* user, uint32_t cyclesLate); @@ -180,7 +181,7 @@ void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { irqh->swi16 = GBASwi16; irqh->swi32 = GBASwi32; irqh->hitIllegal = GBAIllegal; - irqh->readCPSR = GBATestIRQ; + irqh->readCPSR = GBATestIRQNoDelay; irqh->hitStub = GBAHitStub; irqh->bkpt16 = GBABreakpoint; irqh->bkpt32 = GBABreakpoint; @@ -433,7 +434,7 @@ void GBAYankROM(struct GBA* gba) { gba->yankedRomSize = gba->memory.romSize; gba->memory.romSize = 0; gba->memory.romMask = 0; - GBARaiseIRQ(gba, IRQ_GAMEPAK); + GBARaiseIRQ(gba, IRQ_GAMEPAK, 0); } void GBALoadBIOS(struct GBA* gba, struct VFile* vf) { @@ -486,16 +487,20 @@ void GBAApplyPatch(struct GBA* gba, struct Patch* patch) { gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize); } -void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq) { +void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq, uint32_t cyclesLate) { gba->memory.io[REG_IF >> 1] |= 1 << irq; - GBATestIRQ(gba->cpu); + GBATestIRQ(gba, cyclesLate); } -void GBATestIRQ(struct ARMCore* cpu) { +void GBATestIRQNoDelay(struct ARMCore* cpu) { struct GBA* gba = (struct GBA*) cpu->master; + GBATestIRQ(gba, 0); +} + +void GBATestIRQ(struct GBA* gba, uint32_t cyclesLate) { if (gba->memory.io[REG_IE >> 1] & gba->memory.io[REG_IF >> 1]) { if (!mTimingIsScheduled(&gba->timing, &gba->irqEvent)) { - mTimingSchedule(&gba->timing, &gba->irqEvent, GBA_IRQ_DELAY); + mTimingSchedule(&gba->timing, &gba->irqEvent, GBA_IRQ_DELAY - cyclesLate); } } } @@ -846,9 +851,9 @@ void GBATestKeypadIRQ(struct GBA* gba) { uint16_t keyInput = *gba->keySource & keycnt; if (isAnd && keycnt == keyInput) { - GBARaiseIRQ(gba, IRQ_KEYPAD); + GBARaiseIRQ(gba, IRQ_KEYPAD, 0); } else if (!isAnd && keyInput) { - GBARaiseIRQ(gba, IRQ_KEYPAD); + GBARaiseIRQ(gba, IRQ_KEYPAD, 0); } } diff --git a/src/gba/hardware.c b/src/gba/hardware.c index e981a9649..c2c19d50e 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -585,7 +585,7 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx; gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16; if (gbp->d.p->normalControl.irq) { - GBARaiseIRQ(gbp->p->p, IRQ_SIO); + GBARaiseIRQ(gbp->p->p, IRQ_SIO, cyclesLate); } gbp->d.p->normalControl.start = 0; gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080; diff --git a/src/gba/io.c b/src/gba/io.c index c3561dd50..7b7c4ba3a 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -548,16 +548,16 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case REG_IE: gba->memory.io[REG_IE >> 1] = value; - GBATestIRQ(gba->cpu); + GBATestIRQ(gba->cpu, 1); return; case REG_IF: value = gba->memory.io[REG_IF >> 1] & ~value; gba->memory.io[REG_IF >> 1] = value; - GBATestIRQ(gba->cpu); + GBATestIRQ(gba->cpu, 1); return; case REG_IME: gba->memory.io[REG_IME >> 1] = value; - GBATestIRQ(gba->cpu); + GBATestIRQ(gba->cpu, 1); return; case REG_MAX: // Some bad interrupt libraries will write to this diff --git a/src/gba/sio.c b/src/gba/sio.c index 800af8aea..95e860363 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -158,7 +158,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { if ((value & 0x0081) == 0x0081) { if (value & 0x4000) { // TODO: Test this on hardware to see if this is correct - GBARaiseIRQ(sio->p, IRQ_SIO); + GBARaiseIRQ(sio->p, IRQ_SIO, 0); } value &= ~0x0080; } diff --git a/src/gba/sio/joybus.c b/src/gba/sio/joybus.c index e7aa934e6..8d6fc2d77 100644 --- a/src/gba/sio/joybus.c +++ b/src/gba/sio/joybus.c @@ -37,7 +37,7 @@ int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command case JOY_RESET: sio->p->p->memory.io[REG_JOYCNT >> 1] |= 1; if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) { - GBARaiseIRQ(sio->p->p, IRQ_SIO); + GBARaiseIRQ(sio->p->p, IRQ_SIO, 0); } // Fall through case JOY_POLL: @@ -55,7 +55,7 @@ int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command data[0] = sio->p->p->memory.io[REG_JOYSTAT >> 1]; if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) { - GBARaiseIRQ(sio->p->p, IRQ_SIO); + GBARaiseIRQ(sio->p->p, IRQ_SIO, 0); } return 1; case JOY_TRANS: @@ -68,7 +68,7 @@ int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command data[4] = sio->p->p->memory.io[REG_JOYSTAT >> 1]; if (sio->p->p->memory.io[REG_JOYCNT >> 1] & 0x40) { - GBARaiseIRQ(sio->p->p, IRQ_SIO); + GBARaiseIRQ(sio->p->p, IRQ_SIO, 0); } return 5; } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index c196fc3fa..848dc9b4d 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -166,7 +166,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { sio->multiplayerControl.busy = 0; sio->multiplayerControl.id = node->id; if (sio->multiplayerControl.irq) { - GBARaiseIRQ(sio->p, IRQ_SIO); + GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; case SIO_NORMAL_8: @@ -179,7 +179,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { node->d.p->p->memory.io[REG_SIODATA8 >> 1] = 0xFFFF; } if (sio->multiplayerControl.irq) { - GBARaiseIRQ(sio->p, IRQ_SIO); + GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; case SIO_NORMAL_32: @@ -194,7 +194,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0xFFFF; } if (sio->multiplayerControl.irq) { - GBARaiseIRQ(sio->p, IRQ_SIO); + GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; default: diff --git a/src/gba/timer.c b/src/gba/timer.c index c0a6fb81d..9e097eff6 100644 --- a/src/gba/timer.c +++ b/src/gba/timer.c @@ -22,7 +22,7 @@ static void GBATimerUpdate(struct GBA* gba, int timerId, uint32_t cyclesLate) { } if (GBATimerFlagsIsDoIrq(timer->flags)) { - GBARaiseIRQ(gba, IRQ_TIMER0 + timerId); + GBARaiseIRQ(gba, IRQ_TIMER0 + timerId, cyclesLate); } if (gba->audio.enable && timerId < 2) { diff --git a/src/gba/video.c b/src/gba/video.c index ade66932a..ee9a8306c 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -133,7 +133,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (video->vcount == GBARegisterDISPSTATGetVcountSetting(dispstat)) { dispstat = GBARegisterDISPSTATFillVcounter(dispstat); if (GBARegisterDISPSTATIsVcounterIRQ(dispstat)) { - GBARaiseIRQ(video->p, IRQ_VCOUNTER); + GBARaiseIRQ(video->p, IRQ_VCOUNTER, cyclesLate); } } else { dispstat = GBARegisterDISPSTATClearVcounter(dispstat); @@ -152,7 +152,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { } GBADMARunVblank(video->p, -cyclesLate); if (GBARegisterDISPSTATIsVblankIRQ(dispstat)) { - GBARaiseIRQ(video->p, IRQ_VBLANK); + GBARaiseIRQ(video->p, IRQ_VBLANK, cyclesLate); } GBAFrameEnded(video->p); mCoreSyncPostFrame(video->p->sync); @@ -188,7 +188,7 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) { GBADMARunDisplayStart(video->p, -cyclesLate); } if (GBARegisterDISPSTATIsHblankIRQ(dispstat)) { - GBARaiseIRQ(video->p, IRQ_HBLANK); + GBARaiseIRQ(video->p, IRQ_HBLANK, cyclesLate); } video->p->memory.io[REG_DISPSTAT >> 1] = dispstat; } From cce4b0fcd433a99411fa73c99a7a62017461e3e2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Feb 2019 11:06:19 -0800 Subject: [PATCH 061/429] GBA DMA: Fix invalid DMA handling (fixes #1301) --- CHANGES | 1 + src/gba/dma.c | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 3d0f61df1..754f9a28f 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Bugfixes: - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) - 3DS: Work around menu freezing (fixes mgba.io/i/1294) + - GBA DMA: Fix invalid DMA handling (fixes mgba.io/i/1301) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/dma.c b/src/gba/dma.c index 7ab7a85c7..bb13350a9 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -260,15 +260,13 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { } gba->bus = memory->dmaTransferRegister; cpu->memory.store32(cpu, dest, memory->dmaTransferRegister, 0); - memory->dmaTransferRegister &= 0xFFFF0000; - memory->dmaTransferRegister |= memory->dmaTransferRegister >> 16; } else { if (sourceRegion == REGION_CART2_EX && (memory->savedata.type == SAVEDATA_EEPROM || memory->savedata.type == SAVEDATA_EEPROM512)) { memory->dmaTransferRegister = GBASavedataReadEEPROM(&memory->savedata); - } else { - if (source) { - memory->dmaTransferRegister = cpu->memory.load16(cpu, source, 0); - } + memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; + } else if (source) { + memory->dmaTransferRegister = cpu->memory.load16(cpu, source, 0); + memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; } if (destRegion == REGION_CART2_EX) { if (memory->savedata.type == SAVEDATA_AUTODETECT) { @@ -282,7 +280,6 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) { cpu->memory.store16(cpu, dest, memory->dmaTransferRegister, 0); } - memory->dmaTransferRegister |= memory->dmaTransferRegister << 16; gba->bus = memory->dmaTransferRegister; } int sourceOffset = DMA_OFFSET[GBADMARegisterGetSrcControl(info->reg)] * width; From e33f1d37f23b4e38cd01e23bf80ad658c69badd9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Feb 2019 12:31:27 -0800 Subject: [PATCH 062/429] PSP2: Fix file descriptors dying on suspend (fixes #1123) --- CHANGES | 1 + src/feature/gui/gui-runner.c | 12 +++++++++++- src/platform/psp2/main.c | 3 ++- src/platform/psp2/psp2-context.c | 16 ++++++++++++++++ src/platform/psp2/psp2-context.h | 1 + 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 754f9a28f..35624b77f 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Bugfixes: - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) - 3DS: Work around menu freezing (fixes mgba.io/i/1294) - GBA DMA: Fix invalid DMA handling (fixes mgba.io/i/1301) + - PSP2: Fix file descriptors dying on suspend (fixes mgba.io/i/1123) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 0afbd355e..50c9dea42 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -271,7 +271,17 @@ static void _log(struct mLogger* logger, int category, enum mLogLevel level, con if (len >= sizeof(log2)) { len = sizeof(log2) - 1; } - guiLogger->vf->write(guiLogger->vf, log2, len); + if (guiLogger->vf->write(guiLogger->vf, log2, len) < 0) { + char path[PATH_MAX]; + mCoreConfigDirectory(path, PATH_MAX); + strncat(path, PATH_SEP "log", PATH_MAX - strlen(path)); + guiLogger->vf->close(guiLogger->vf); + guiLogger->vf = VFileOpen(path, O_CREAT | O_WRONLY | O_APPEND); + if (guiLogger->vf->write(guiLogger->vf, log2, len) < 0) { + guiLogger->vf->close(guiLogger->vf); + guiLogger->vf = NULL; + } + } } void mGUIRun(struct mGUIRunner* runner, const char* path) { diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index 8060d26ae..f5843a911 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -160,7 +160,8 @@ int main() { .unpaused = mPSP2Unpaused, .incrementScreenMode = mPSP2IncrementScreenMode, .setFrameLimiter = mPSP2SetFrameLimiter, - .pollGameInput = mPSP2PollInput + .pollGameInput = mPSP2PollInput, + .running = mPSP2SystemPoll }; sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 41e3a4a11..98f44934c 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -38,6 +39,9 @@ #define RUMBLE_PWM 8 #define CDRAM_ALIGN 0x40000 +mLOG_DECLARE_CATEGORY(GUI_PSP2); +mLOG_DEFINE_CATEGORY(GUI_PSP2, "Vita", "gui.psp2"); + static enum ScreenMode { SM_BACKDROP, SM_PLAIN, @@ -539,6 +543,18 @@ void mPSP2IncrementScreenMode(struct mGUIRunner* runner) { mCoreConfigSetUIntValue(&runner->config, "screenMode", screenMode); } +bool mPSP2SystemPoll(struct mGUIRunner* runner) { + SceAppMgrSystemEvent event; + if (sceAppMgrReceiveSystemEvent(&event) < 0) { + return true; + } + if (event.systemEvent == SCE_APPMGR_SYSTEMEVENT_ON_RESUME) { + mLOG(GUI_PSP2, INFO, "Suspend detected, reloading save"); + mCoreAutoloadSave(runner->core); + } + return true; +} + __attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) { printf("ASSERT FAILED: %s in %s at %s:%i\n", expr, func, file, line); exit(1); diff --git a/src/platform/psp2/psp2-context.h b/src/platform/psp2/psp2-context.h index 28a403ba3..389f9f534 100644 --- a/src/platform/psp2/psp2-context.h +++ b/src/platform/psp2/psp2-context.h @@ -25,5 +25,6 @@ void mPSP2DrawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsig void mPSP2IncrementScreenMode(struct mGUIRunner* runner); void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit); uint16_t mPSP2PollInput(struct mGUIRunner* runner); +bool mPSP2SystemPoll(struct mGUIRunner* runner); #endif From 292eabcecc8c77d2c54381539603fcbc931512ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Feb 2019 17:31:11 -0800 Subject: [PATCH 063/429] Res: Update patrons for February --- res/patrons.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/patrons.txt b/res/patrons.txt index deaca59b2..306534b40 100644 --- a/res/patrons.txt +++ b/res/patrons.txt @@ -1,8 +1,8 @@ -Elijah Chondropoulos Jaime J. Denizard Fog Philip Horton Oskenso Kashi +Mored1984 Rohit Nirmal Rhys Powell Yuri Kunde Schlesner From b45f30c58a321e980113c78415379bd335823c54 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Feb 2019 17:37:09 -0800 Subject: [PATCH 064/429] CHANGES: Update for 0.7.1 --- CHANGES | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 35624b77f..f42f555bc 100644 --- a/CHANGES +++ b/CHANGES @@ -7,37 +7,40 @@ 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) - - Switch: Fix final cleanup (fixes mgba.io/i/1283) - - Qt: Fix tile and sprite views not always displaying at first - - GBA Memory: Fix a few AGBPrint crashes - - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory - - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) - - Qt: Fix audio context holding onto closed game controller - - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) - - GBA SIO: Prevent writing read-only multiplayer bits - - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) - - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM - - Python: Fix crash when deleting files owned by library - - Python: Make sure GB link object isn't GC'd before GB object - - GBA DMA: Fix Display Start DMAs - - GBA DMA: Fix DMA start/end timing - - Qt: Fix window icon on X11 - - GB, GBA Serialize: Fix loading two states in a row - - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) - - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) - - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) - - 3DS: Work around menu freezing (fixes mgba.io/i/1294) - - GBA DMA: Fix invalid DMA handling (fixes mgba.io/i/1301) - - PSP2: Fix file descriptors dying on suspend (fixes mgba.io/i/1123) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes - - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) - Debugger: Add breakpoint and watchpoint listing + +0.7.1: (2019-02-24) +Bugfixes: + - 3DS: Work around menu freezing (fixes mgba.io/i/1294) + - GB: Fix crash when accessing SRAM if no save loaded and cartridge has no SRAM + - GB Serialize: Fix loading states with negative pixel x (fixes mgba.io/i/1293) + - GB, GBA Serialize: Fix loading two states in a row + - GBA: Fix video timing when skipping BIOS (fixes mgba.io/i/1318) + - GBA DMA: Fix Display Start DMAs + - GBA DMA: Fix DMA start/end timing + - GBA DMA: Fix invalid DMA handling (fixes mgba.io/i/1301) + - GBA Memory: Fix a few AGBPrint crashes + - GBA Memory: Fix OOB ROM reads showing up as AGBPrint memory + - GBA SIO: Prevent writing read-only multiplayer bits + - GBA Video: Fix enabling layers in non-tile modes (fixes mgba.io/i/1317) + - Python: Fix crash when deleting files owned by library + - Python: Make sure GB link object isn't GC'd before GB object + - PSP2: Fix file descriptors dying on suspend (fixes mgba.io/i/1123) + - Qt: Fix tile and sprite views not always displaying at first + - Qt: Fix audio context holding onto closed game controller + - Qt: Fix color picking in sprite view (fixes mgba.io/i/1307) + - Qt: Fix window icon on X11 + - Qt: Fix quick load recent accidentally saving (fixes mgba.io/i/1309) + - Switch: Fix final cleanup (fixes mgba.io/i/1283) + - Switch: Fix gyroscope orientation (fixes mgba.io/i/1300) +Misc: + - GBA Video: Improve sprite cycle counting (fixes mgba.io/i/1274) - Qt: Updated Italian translation (by Vecna) - - GBA: Improve delayed IRQ timing 0.7.0: (2019-01-26) Features: From d1c6bcacd9fab75a3bbea90b7d00c15fde638bcc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Feb 2019 20:15:50 -0800 Subject: [PATCH 065/429] Qt: Revamp BattleChipView, add drag and drop --- src/platform/qt/BattleChipModel.cpp | 167 ++++++++++++++++++++++++++++ src/platform/qt/BattleChipModel.h | 53 +++++++++ src/platform/qt/BattleChipView.cpp | 97 ++++++---------- src/platform/qt/BattleChipView.h | 8 +- src/platform/qt/BattleChipView.ui | 32 +----- src/platform/qt/CMakeLists.txt | 1 + 6 files changed, 264 insertions(+), 94 deletions(-) create mode 100644 src/platform/qt/BattleChipModel.cpp create mode 100644 src/platform/qt/BattleChipModel.h diff --git a/src/platform/qt/BattleChipModel.cpp b/src/platform/qt/BattleChipModel.cpp new file mode 100644 index 000000000..8d1636e6f --- /dev/null +++ b/src/platform/qt/BattleChipModel.cpp @@ -0,0 +1,167 @@ +/* Copyright (c) 2013-2019 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 "BattleChipModel.h" + +#include "ConfigController.h" +#include "GBAApp.h" + +#include +#include +#include + +using namespace QGBA; + +BattleChipModel::BattleChipModel(QObject* parent) + : QAbstractListModel(parent) +{ + QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe"); + QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe"); +} + +int BattleChipModel::rowCount(const QModelIndex& parent) const { + if (parent.isValid()) { + return 0; + } + return m_deck.count(); +} + +QVariant BattleChipModel::data(const QModelIndex& index, int role) const { + const BattleChip& item = m_deck[index.row()]; + + switch (role) { + case Qt::DisplayRole: + return item.name; + case Qt::DecorationRole: + return item.icon; + case Qt::UserRole: + return item.id; + } + return QVariant(); +} + +Qt::ItemFlags BattleChipModel::flags(const QModelIndex& index) const { + return Qt::ItemIsSelectable | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; +} + +bool BattleChipModel::removeRows(int row, int count, const QModelIndex& parent) { + if (parent.isValid()) { + return false; + } + beginRemoveRows(QModelIndex(), row, row + count - 1); + for (size_t i = 0; i < count; ++i) { + m_deck.removeAt(row); + } + endRemoveRows(); + return true; +} + +QStringList BattleChipModel::mimeTypes() const { + return {"text/plain"}; +} + +Qt::DropActions BattleChipModel::supportedDropActions() const { + return Qt::MoveAction; +} + +QMimeData* BattleChipModel::mimeData(const QModelIndexList& indices) const { + QStringList deck; + for (const QModelIndex& index : indices) { + if (index.parent().isValid()) { + continue; + } + deck.append(QString::number(m_deck[index.row()].id)); + } + + QMimeData* mimeData = new QMimeData(); + mimeData->setData("text/plain", deck.join(',').toLocal8Bit()); + return mimeData; +} + +bool BattleChipModel::dropMimeData(const QMimeData* data, Qt::DropAction, int row, int, const QModelIndex& parent) { + if (parent.parent().isValid()) { + return false; + } + QStringList deck = QString::fromLocal8Bit(data->data("text/plain")).split(','); + if (deck.isEmpty()) { + return true; + } + + row = parent.row(); + beginInsertRows(QModelIndex(), row, row + deck.count() - 1); + for (int i = 0; i < deck.count(); ++i) { + int id = deck[i].toInt(); + m_deck.insert(row + i, createChip(id)); + } + endInsertRows(); + return true; +} + +void BattleChipModel::setFlavor(int flavor) { + m_chipIdToName.clear(); + if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) { + flavor = GBA_FLAVOR_BEAST_LINK_GATE; + } + m_flavor = flavor; + + QFile file(QString(":/exe/exe%1/chip-names.txt").arg(flavor)); + file.open(QIODevice::ReadOnly | QIODevice::Text); + int id = 0; + while (true) { + QByteArray line = file.readLine(); + if (line.isEmpty()) { + break; + } + ++id; + if (line.trimmed().isEmpty()) { + continue; + } + QString name = QString::fromUtf8(line).trimmed(); + m_chipIdToName[id] = name; + } + +} + +void BattleChipModel::addChip(int id) { + beginInsertRows(QModelIndex(), m_deck.count(), m_deck.count()); + m_deck.append(createChip(id)); + endInsertRows(); +} + +void BattleChipModel::removeChip(const QModelIndex& index) { + beginRemoveRows(QModelIndex(), index.row(), index.row()); + m_deck.removeAt(index.row()); + endRemoveRows(); +} + +void BattleChipModel::setChips(QList ids) { + beginResetModel(); + m_deck.clear(); + for (int id : ids) { + m_deck.append(createChip(id)); + } + endResetModel(); +} + +void BattleChipModel::clear() { + beginResetModel(); + m_deck.clear(); + endResetModel(); +} + +BattleChipModel::BattleChip BattleChipModel::createChip(int id) const { + QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); + if (!QFile(path).exists()) { + path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor); + } + QIcon icon(path); + + BattleChip chip = { + id, + m_chipIdToName[id], + icon + }; + return chip; +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipModel.h b/src/platform/qt/BattleChipModel.h new file mode 100644 index 000000000..a2e652509 --- /dev/null +++ b/src/platform/qt/BattleChipModel.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include +#include + +namespace QGBA { + +class BattleChipModel : public QAbstractListModel { +Q_OBJECT + +public: + BattleChipModel(QObject* parent = nullptr); + + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + virtual Qt::ItemFlags flags(const QModelIndex& index) const override; + virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; + virtual Qt::DropActions supportedDropActions() const override; + virtual QStringList mimeTypes() const override; + virtual QMimeData* mimeData(const QModelIndexList& indices) const override; + virtual bool dropMimeData(const QMimeData* data, Qt::DropAction, int row, int column, const QModelIndex& parent) override; + + int flavor() const { return m_flavor; } + QMap chipNames() const { return m_chipIdToName; } + +public slots: + void setFlavor(int); + void addChip(int id); + void removeChip(const QModelIndex&); + void setChips(QList ids); + void clear(); + +private: + struct BattleChip { + int id; + QString name; + QIcon icon; + }; + + BattleChip createChip(int id) const; + + QMap m_chipIdToName; + int m_flavor; + + QList m_deck; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 42cca1fc4..f97239a76 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -5,18 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "BattleChipView.h" -#include "ConfigController.h" #include "CoreController.h" -#include "GBAApp.h" #include "ShortcutController.h" #include "Window.h" #include -#include #include #include #include -#include #include #include @@ -27,10 +23,8 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo , m_controller(controller) , m_window(window) { - QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe"); - QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe"); - m_ui.setupUi(this); + m_ui.chipList->setModel(&m_model); char title[9]; CoreController::Interrupter interrupter(m_controller); @@ -51,7 +45,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_ui.inserted->setChecked(Qt::Unchecked); }); connect(m_ui.chipName, static_cast(&QComboBox::currentIndexChanged), m_ui.chipId, [this](int id) { - m_ui.chipId->setValue(m_chipIndexToId[id]); + m_ui.chipId->setValue(m_model.chipNames().keys()[id]); }); connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); @@ -61,7 +55,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo connect(controller.get(), &CoreController::stopping, this, &QWidget::close); connect(m_ui.save, &QAbstractButton::clicked, this, &BattleChipView::saveDeck); connect(m_ui.load, &QAbstractButton::clicked, this, &BattleChipView::loadDeck); - connect(m_ui.buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, m_ui.chipList, &QListWidget::clear); + connect(m_ui.buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, &m_model, &BattleChipModel::clear); connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { if (on) { @@ -85,13 +79,14 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo connect(m_controller.get(), &CoreController::frameAvailable, this, &BattleChipView::advanceFrameCounter); - connect(m_ui.chipList, &QListWidget::itemClicked, this, [this](QListWidgetItem* item) { - QVariant chip = item->data(Qt::UserRole); + connect(m_ui.chipList, &QAbstractItemView::clicked, this, [this](const QModelIndex& index) { + QVariant chip = m_model.data(index, Qt::UserRole); bool blocked = m_ui.chipId->blockSignals(true); m_ui.chipId->setValue(chip.toInt()); m_ui.chipId->blockSignals(blocked); reinsert(); }); + connect(m_ui.chipList, &QListView::indexesMoved, this, &BattleChipView::resort); m_controller->attachBattleChipGate(); setFlavor(4); @@ -110,7 +105,8 @@ BattleChipView::~BattleChipView() { void BattleChipView::setFlavor(int flavor) { m_controller->setBattleChipFlavor(flavor); - loadChipNames(flavor); + m_model.setFlavor(flavor); + m_ui.chipName->addItems(m_model.chipNames().values()); } void BattleChipView::insertChip(bool inserted) { @@ -141,55 +137,13 @@ void BattleChipView::addChip() { if (insertedChip < 1) { return; } - addChipId(insertedChip); -} - -void BattleChipView::addChipId(int id) { - QListWidgetItem* add = new QListWidgetItem(m_chipIdToName[id]); - add->setData(Qt::UserRole, id); - QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); - if (!QFile(path).exists()) { - path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor); - } - add->setIcon(QPixmap(path).scaled(m_ui.chipList->iconSize())); - m_ui.chipList->addItem(add); + m_model.addChip(insertedChip); } void BattleChipView::removeChip() { - qDeleteAll(m_ui.chipList->selectedItems()); -} - -void BattleChipView::loadChipNames(int flavor) { - QStringList chipNames; - chipNames.append(tr("(None)")); - - m_chipIndexToId.clear(); - m_chipIdToName.clear(); - if (flavor == GBA_FLAVOR_BEAST_LINK_GATE_US) { - flavor = GBA_FLAVOR_BEAST_LINK_GATE; + for (const auto& index : m_ui.chipList->selectionModel()->selectedIndexes()) { + m_model.removeChip(index); } - m_flavor = flavor; - - QFile file(QString(":/exe/exe%1/chip-names.txt").arg(flavor)); - file.open(QIODevice::ReadOnly | QIODevice::Text); - int id = 0; - while (true) { - QByteArray line = file.readLine(); - if (line.isEmpty()) { - break; - } - ++id; - if (line.trimmed().isEmpty()) { - continue; - } - QString name = QString::fromUtf8(line).trimmed(); - m_chipIndexToId[chipNames.length()] = id; - m_chipIdToName[id] = name; - chipNames.append(name); - } - - m_ui.chipName->clear(); - m_ui.chipName->addItems(chipNames); } void BattleChipView::advanceFrameCounter() { @@ -208,14 +162,14 @@ void BattleChipView::saveDeck() { } QStringList deck; - for (int i = 0; i < m_ui.chipList->count(); ++i) { - deck.append(m_ui.chipList->item(i)->data(Qt::UserRole).toString()); + for (int i = 0; i < m_model.rowCount(); ++i) { + deck.append(m_model.data(m_model.index(i, 0), Qt::UserRole).toString()); } QSettings ini(filename, QSettings::IniFormat); ini.clear(); ini.beginGroup("BattleChipDeck"); - ini.setValue("version", m_flavor); + ini.setValue("version", m_model.flavor()); ini.setValue("deck", deck.join(',')); ini.sync(); } @@ -229,7 +183,7 @@ void BattleChipView::loadDeck() { QSettings ini(filename, QSettings::IniFormat); ini.beginGroup("BattleChipDeck"); int flavor = ini.value("version").toInt(); - if (flavor != m_flavor) { + if (flavor != m_model.flavor()) { QMessageBox* error = new QMessageBox(this); error->setIcon(QMessageBox::Warning); error->setStandardButtons(QMessageBox::Ok); @@ -240,13 +194,30 @@ void BattleChipView::loadDeck() { return; } - m_ui.chipList->clear(); + QList newDeck; QStringList deck = ini.value("deck").toString().split(','); for (const auto& item : deck) { bool ok; int id = item.toInt(&ok); if (ok) { - addChipId(id); + newDeck.append(id); } } + m_model.setChips(newDeck); } + +void BattleChipView::resort() { + QMap chips; + for (int i = 0; i < m_model.rowCount(); ++i) { + QModelIndex index = m_model.index(i, 0); + QRect visualRect = m_ui.chipList->visualRect(index); + QSize gridSize = m_ui.chipList->gridSize(); + int x = visualRect.y() / gridSize.height(); + x *= m_ui.chipList->viewport()->width(); + x += visualRect.x(); + x *= m_model.rowCount(); + x += index.row(); + chips[x] = m_model.data(index, Qt::UserRole).toInt(); + } + m_model.setChips(chips.values()); +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index 88a24d8a3..ea96c4284 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once +#include "BattleChipModel.h" + #include #include @@ -29,11 +31,11 @@ public slots: void setFlavor(int); void insertChip(bool); void reinsert(); + void resort(); private slots: void advanceFrameCounter(); void addChip(); - void addChipId(int); void removeChip(); void saveDeck(); @@ -46,10 +48,8 @@ private: Ui::BattleChipView m_ui; - QMap m_chipIndexToId; - QMap m_chipIdToName; + BattleChipModel m_model; std::shared_ptr m_controller; - int m_flavor; int m_frameCounter = -1; bool m_next = false; diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index f379a3bdc..8fb9122d3 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -15,7 +15,7 @@ - + true @@ -35,7 +35,7 @@ - QListView::Static + QListView::Free true @@ -52,12 +52,6 @@ QListView::IconMode - - false - - - true - @@ -132,9 +126,9 @@ - - false - + + false + @@ -260,21 +254,5 @@ - - chipList - indexesMoved(QModelIndexList) - chipList - doItemsLayout() - - - 314 - 203 - - - 314 - 203 - - - diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 8cf30dbc8..e3dc64053 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -147,6 +147,7 @@ set(UI_FILES VideoView.ui) set(GBA_SRC + BattleChipModel.cpp BattleChipView.cpp GBAOverride.cpp) From 6f7573dda4eea59cd2ea8291890476861281ddaa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Feb 2019 20:39:11 -0800 Subject: [PATCH 066/429] Qt: Re-add battle chip icon scaling --- src/platform/qt/BattleChipModel.cpp | 8 ++++++-- src/platform/qt/BattleChipModel.h | 6 ++++-- src/platform/qt/BattleChipView.cpp | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/BattleChipModel.cpp b/src/platform/qt/BattleChipModel.cpp index 8d1636e6f..f7851912d 100644 --- a/src/platform/qt/BattleChipModel.cpp +++ b/src/platform/qt/BattleChipModel.cpp @@ -35,7 +35,7 @@ QVariant BattleChipModel::data(const QModelIndex& index, int role) const { case Qt::DisplayRole: return item.name; case Qt::DecorationRole: - return item.icon; + return item.icon.scaled(item.icon.size() * m_scale); case Qt::UserRole: return item.id; } @@ -151,12 +151,16 @@ void BattleChipModel::clear() { endResetModel(); } +void BattleChipModel::setScale(int scale) { + m_scale = scale; +} + BattleChipModel::BattleChip BattleChipModel::createChip(int id) const { QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); if (!QFile(path).exists()) { path = QString(":/exe/exe%1/placeholder.png").arg(m_flavor); } - QIcon icon(path); + QPixmap icon(path); BattleChip chip = { id, diff --git a/src/platform/qt/BattleChipModel.h b/src/platform/qt/BattleChipModel.h index a2e652509..a9de45951 100644 --- a/src/platform/qt/BattleChipModel.h +++ b/src/platform/qt/BattleChipModel.h @@ -6,7 +6,7 @@ #pragma once #include -#include +#include namespace QGBA { @@ -34,18 +34,20 @@ public slots: void removeChip(const QModelIndex&); void setChips(QList ids); void clear(); + void setScale(int); private: struct BattleChip { int id; QString name; - QIcon icon; + QPixmap icon; }; BattleChip createChip(int id) const; QMap m_chipIdToName; int m_flavor; + int m_scale = 1; QList m_deck; }; diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index f97239a76..1fdfe3679 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -40,6 +40,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo #endif m_ui.chipList->setIconSize(m_ui.chipList->iconSize() * size); m_ui.chipList->setGridSize(m_ui.chipList->gridSize() * size); + m_model.setScale(size); connect(m_ui.chipId, static_cast(&QSpinBox::valueChanged), m_ui.inserted, [this]() { m_ui.inserted->setChecked(Qt::Unchecked); From 8b88e7ae6a4434b37a4812accea648cdbb62331d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Feb 2019 20:54:47 -0800 Subject: [PATCH 067/429] Qt: More app metadata fixes --- CHANGES | 1 + src/platform/qt/GBAApp.cpp | 8 -------- src/platform/qt/Window.cpp | 1 - src/platform/qt/main.cpp | 7 +++++++ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index f42f555bc..7aa062fe0 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,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) + - Qt: More app metadata fixes Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index b88328778..6a25d71c1 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -42,17 +41,10 @@ GBAApp::GBAApp(int& argc, char* argv[], ConfigController* config) SDL_Init(SDL_INIT_NOPARACHUTE); #endif -#ifndef Q_OS_MAC - setWindowIcon(QIcon(":/res/mgba-512.png")); -#endif - SocketSubsystemInit(); qRegisterMetaType("const uint32_t*"); qRegisterMetaType("mCoreThread*"); - QApplication::setApplicationName(projectName); - QApplication::setApplicationVersion(projectVersion); - if (!m_configController->getQtOption("displayDriver").isNull()) { Display::setDriver(static_cast(m_configController->getQtOption("displayDriver").toInt())); } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d46b107bf..506e410e1 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -85,7 +85,6 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi m_logo.setDevicePixelRatio(m_screenWidget->devicePixelRatio()); m_logo = m_logo; // Free memory left over in old pixmap - setWindowIcon(m_logo); #if defined(M_CORE_GBA) float i = 2; diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index ae7992157..8edc96e79 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -61,8 +61,15 @@ int main(int argc, char* argv[]) { return 0; } + QApplication::setApplicationName(projectName); + QApplication::setApplicationVersion(projectVersion); + GBAApp application(argc, argv, &configController); +#ifndef Q_OS_MAC + QApplication::setWindowIcon(QIcon(":/res/mgba-1024.png")); +#endif + QTranslator qtTranslator; qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); application.installTranslator(&qtTranslator); From 38c8e4c4e1d04ef3a6d3439a9c0c55499dd9e701 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 18:23:07 -0800 Subject: [PATCH 068/429] Qt: Fix battlechip crashes --- src/platform/qt/BattleChipView.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index 1fdfe3679..a86cad1d1 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -46,6 +46,9 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_ui.inserted->setChecked(Qt::Unchecked); }); connect(m_ui.chipName, static_cast(&QComboBox::currentIndexChanged), m_ui.chipId, [this](int id) { + if (id < 0) { + return; + } m_ui.chipId->setValue(m_model.chipNames().keys()[id]); }); @@ -107,6 +110,7 @@ BattleChipView::~BattleChipView() { void BattleChipView::setFlavor(int flavor) { m_controller->setBattleChipFlavor(flavor); m_model.setFlavor(flavor); + m_ui.chipName->clear(); m_ui.chipName->addItems(m_model.chipNames().values()); } From c9e1f5d6a62fdea62acc56c55fec310a8b91dcb4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 20:55:39 -0800 Subject: [PATCH 069/429] Qt: Add option to download chip data --- src/platform/qt/AbstractUpdater.cpp | 89 +++++++++++++++++++++++++++ src/platform/qt/AbstractUpdater.h | 47 ++++++++++++++ src/platform/qt/BattleChipModel.cpp | 15 +++++ src/platform/qt/BattleChipModel.h | 3 + src/platform/qt/BattleChipUpdater.cpp | 47 ++++++++++++++ src/platform/qt/BattleChipUpdater.h | 22 +++++++ src/platform/qt/BattleChipView.cpp | 34 ++++++++++ src/platform/qt/BattleChipView.h | 4 ++ src/platform/qt/BattleChipView.ui | 15 ++++- src/platform/qt/CMakeLists.txt | 2 + 10 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 src/platform/qt/AbstractUpdater.cpp create mode 100644 src/platform/qt/AbstractUpdater.h create mode 100644 src/platform/qt/BattleChipUpdater.cpp create mode 100644 src/platform/qt/BattleChipUpdater.h diff --git a/src/platform/qt/AbstractUpdater.cpp b/src/platform/qt/AbstractUpdater.cpp new file mode 100644 index 000000000..c165ae1a0 --- /dev/null +++ b/src/platform/qt/AbstractUpdater.cpp @@ -0,0 +1,89 @@ +/* Copyright (c) 2013-2019 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 "AbstractUpdater.h" + +#include +#include + +using namespace QGBA; + +AbstractUpdater::AbstractUpdater(QObject* parent) + : QObject(parent) + , m_netman(new QNetworkAccessManager(this)) +{ +} + +void AbstractUpdater::checkUpdate() { + QNetworkReply* reply = m_netman->get(QNetworkRequest(manifestLocation())); + chaseRedirects(reply, &AbstractUpdater::manifestDownloaded); +} + +void AbstractUpdater::downloadUpdate() { + if (m_isUpdating) { + return; + } + if (m_manifest.isEmpty()) { + m_isUpdating = true; + checkUpdate(); + return; + } + QUrl url = parseManifest(m_manifest); + if (!url.isValid()) { + emit updateDone(false); + return; + } + m_isUpdating = true; + QNetworkReply* reply = m_netman->get(QNetworkRequest(url)); + chaseRedirects(reply, &AbstractUpdater::updateDownloaded); +} + +void AbstractUpdater::chaseRedirects(QNetworkReply* reply, void (AbstractUpdater::*cb)(QNetworkReply*)) { + connect(reply, &QNetworkReply::finished, this, [this, reply, cb]() { + // TODO: check domains, etc + if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() / 100 == 3) { + QNetworkReply* newReply = m_netman->get(QNetworkRequest(reply->header(QNetworkRequest::LocationHeader).toString())); + chaseRedirects(newReply, cb); + } else { + (this->*cb)(reply); + } + }); +} + +void AbstractUpdater::manifestDownloaded(QNetworkReply* reply) { + m_manifest = reply->readAll(); + QUrl url = parseManifest(m_manifest); + if (m_isUpdating) { + if (!url.isValid()) { + emit updateDone(false); + } else { + QNetworkReply* reply = m_netman->get(QNetworkRequest(url)); + chaseRedirects(reply, &AbstractUpdater::updateDownloaded); + } + } else { + emit updateAvailable(url.isValid()); + } +} + +void AbstractUpdater::updateDownloaded(QNetworkReply* reply) { + m_isUpdating = false; + if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() / 100 != 2) { + emit updateDone(false); + return; + } + QFile f(destination()); + if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + emit updateDone(false); + return; + } + while (true) { + QByteArray bytes = reply->read(4096); + if (!bytes.size()) { + break; + } + f.write(bytes); + } + emit updateDone(true); +} diff --git a/src/platform/qt/AbstractUpdater.h b/src/platform/qt/AbstractUpdater.h new file mode 100644 index 000000000..298fe7a82 --- /dev/null +++ b/src/platform/qt/AbstractUpdater.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include +#include +#include + +class QNetworkAccessManager; +class QNetworkReply; + +namespace QGBA { + +class AbstractUpdater : public QObject { +Q_OBJECT + +public: + AbstractUpdater(QObject* parent = nullptr); + virtual ~AbstractUpdater() {} + +public slots: + void checkUpdate(); + void downloadUpdate(); + +signals: + void updateAvailable(bool); + void updateDone(bool); + +protected: + virtual QUrl manifestLocation() const = 0; + virtual QUrl parseManifest(const QByteArray&) const = 0; + virtual QString destination() const = 0; + +private: + void chaseRedirects(QNetworkReply*, void (AbstractUpdater::*cb)(QNetworkReply*)); + void manifestDownloaded(QNetworkReply*); + void updateDownloaded(QNetworkReply*); + + bool m_isUpdating = false; + QNetworkAccessManager* m_netman; + QByteArray m_manifest; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipModel.cpp b/src/platform/qt/BattleChipModel.cpp index f7851912d..bd65dfebe 100644 --- a/src/platform/qt/BattleChipModel.cpp +++ b/src/platform/qt/BattleChipModel.cpp @@ -155,6 +155,21 @@ void BattleChipModel::setScale(int scale) { m_scale = scale; } +void BattleChipModel::reloadAssets() { + QResource::unregisterResource(ConfigController::configDir() + "/chips.rcc", "/exe"); + QResource::unregisterResource(GBAApp::dataDir() + "/chips.rcc", "/exe"); + + QResource::registerResource(GBAApp::dataDir() + "/chips.rcc", "/exe"); + QResource::registerResource(ConfigController::configDir() + "/chips.rcc", "/exe"); + + emit layoutAboutToBeChanged(); + setFlavor(m_flavor); + for (int i = 0; i < m_deck.count(); ++i) { + m_deck[i] = createChip(m_deck[i].id); + } + emit layoutChanged(); +} + BattleChipModel::BattleChip BattleChipModel::createChip(int id) const { QString path = QString(":/exe/exe%1/%2.png").arg(m_flavor).arg(id, 3, 10, QLatin1Char('0')); if (!QFile(path).exists()) { diff --git a/src/platform/qt/BattleChipModel.h b/src/platform/qt/BattleChipModel.h index a9de45951..c0f115896 100644 --- a/src/platform/qt/BattleChipModel.h +++ b/src/platform/qt/BattleChipModel.h @@ -10,6 +10,8 @@ namespace QGBA { +class BattleChipUpdater; + class BattleChipModel : public QAbstractListModel { Q_OBJECT @@ -35,6 +37,7 @@ public slots: void setChips(QList ids); void clear(); void setScale(int); + void reloadAssets(); private: struct BattleChip { diff --git a/src/platform/qt/BattleChipUpdater.cpp b/src/platform/qt/BattleChipUpdater.cpp new file mode 100644 index 000000000..d2d919a99 --- /dev/null +++ b/src/platform/qt/BattleChipUpdater.cpp @@ -0,0 +1,47 @@ +/* Copyright (c) 2013-2019 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 "BattleChipUpdater.h" + +#include "ConfigController.h" +#include "GBAApp.h" + +#include +#include +#include +#include + +using namespace QGBA; + +BattleChipUpdater::BattleChipUpdater(QObject* parent) + : AbstractUpdater(parent) +{ +} + +QUrl BattleChipUpdater::manifestLocation() const { + return {"https://api.github.com/repos/mgba-emu/chip-assets/releases/latest"}; +} + +QUrl BattleChipUpdater::parseManifest(const QByteArray& manifest) const { + QJsonDocument manifestDoc(QJsonDocument::fromJson(manifest)); + if (manifestDoc.isNull()) { + return QUrl(); + } + for (const auto& assetv : manifestDoc.object()["assets"].toArray()) { + QJsonObject asset = assetv.toObject(); + if (asset["name"].toString() == "chips.rcc") { + return asset["browser_download_url"].toString(); + } + } + return QUrl(); +} + +QString BattleChipUpdater::destination() const { + QFileInfo info(GBAApp::dataDir() + "/chips.rcc"); + if (info.isWritable()) { + return info.filePath(); + } + return ConfigController::configDir() + "/chips.rcc"; +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipUpdater.h b/src/platform/qt/BattleChipUpdater.h new file mode 100644 index 000000000..4ec06e127 --- /dev/null +++ b/src/platform/qt/BattleChipUpdater.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include "AbstractUpdater.h" + +namespace QGBA { + +class BattleChipUpdater : public AbstractUpdater { +public: + BattleChipUpdater(QObject* parent = nullptr); + +protected: + virtual QUrl manifestLocation() const override; + virtual QUrl parseManifest(const QByteArray&) const override; + virtual QString destination() const override; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index a86cad1d1..7baa7deb5 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -5,11 +5,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "BattleChipView.h" +#include "BattleChipUpdater.h" +#include "ConfigController.h" #include "CoreController.h" +#include "GBAApp.h" #include "ShortcutController.h" #include "Window.h" #include +#include #include #include #include @@ -59,6 +63,7 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo connect(controller.get(), &CoreController::stopping, this, &QWidget::close); connect(m_ui.save, &QAbstractButton::clicked, this, &BattleChipView::saveDeck); connect(m_ui.load, &QAbstractButton::clicked, this, &BattleChipView::loadDeck); + connect(m_ui.updateData, &QAbstractButton::clicked, this, &BattleChipView::updateData); connect(m_ui.buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, &m_model, &BattleChipModel::clear); connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) { @@ -101,6 +106,18 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo } else if (qtitle.startsWith("AGB-BR5") || qtitle.startsWith("AGB-BR6")) { m_ui.gateBeastLink->setChecked(Qt::Checked); } + + if (!QFileInfo(GBAApp::dataDir() + "/chips.rcc").exists() && !QFileInfo(ConfigController::configDir() + "/chips.rcc").exists()) { + QMessageBox* download = new QMessageBox(this); + download->setIcon(QMessageBox::Information); + download->setStandardButtons(QMessageBox::Yes | QMessageBox::No); + download->setWindowTitle(tr("BattleChip data missing")); + download->setText(tr("BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now?")); + download->setAttribute(Qt::WA_DeleteOnClose); + download->setWindowModality(Qt::NonModal); + connect(download, &QDialog::accepted, this, &BattleChipView::updateData); + download->show(); + } } BattleChipView::~BattleChipView() { @@ -225,4 +242,21 @@ void BattleChipView::resort() { chips[x] = m_model.data(index, Qt::UserRole).toInt(); } m_model.setChips(chips.values()); +} + +void BattleChipView::updateData() { + if (m_updater) { + return; + } + m_updater = new BattleChipUpdater(this); + connect(m_updater, &BattleChipUpdater::updateDone, this, [this](bool success) { + if (success) { + m_model.reloadAssets(); + m_ui.chipName->clear(); + m_ui.chipName->addItems(m_model.chipNames().values()); + } + delete m_updater; + m_updater = nullptr; + }); + m_updater->downloadUpdate(); } \ No newline at end of file diff --git a/src/platform/qt/BattleChipView.h b/src/platform/qt/BattleChipView.h index ea96c4284..0617c6f98 100644 --- a/src/platform/qt/BattleChipView.h +++ b/src/platform/qt/BattleChipView.h @@ -41,6 +41,8 @@ private slots: void saveDeck(); void loadDeck(); + void updateData(); + private: static const int UNINSERTED_TIME = 10; @@ -55,6 +57,8 @@ private: bool m_next = false; Window* m_window; + + BattleChipUpdater* m_updater = nullptr; }; } diff --git a/src/platform/qt/BattleChipView.ui b/src/platform/qt/BattleChipView.ui index 8fb9122d3..0b50fe0be 100644 --- a/src/platform/qt/BattleChipView.ui +++ b/src/platform/qt/BattleChipView.ui @@ -6,7 +6,7 @@ 0 0 - 630 + 658 722 @@ -195,6 +195,19 @@ + + + + + 0 + 0 + + + + Update Chip data + + + diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index e3dc64053..cc719d97a 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -66,6 +66,7 @@ endif() set(SOURCE_FILES AboutScreen.cpp + AbstractUpdater.cpp AssetTile.cpp AssetView.cpp AudioProcessor.cpp @@ -148,6 +149,7 @@ set(UI_FILES set(GBA_SRC BattleChipModel.cpp + BattleChipUpdater.cpp BattleChipView.cpp GBAOverride.cpp) From 0cd1c3ffeb1076666d91b677844632f331b9bb68 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 21:17:19 -0800 Subject: [PATCH 070/429] Qt: Add missing link library on Windows --- src/platform/qt/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index cc719d97a..cc02550ed 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -286,7 +286,7 @@ if(QT_STATIC) find_library(QTPCRE NAMES qtpcre2 qtpcre) if(WIN32) list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport) - set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32") + set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32;iphlpapi") elseif(APPLE) find_package(Cups) find_package(Qt5PrintSupport) From f8cd425fad34dca37c373cee762915202a07e686 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 21:56:53 -0800 Subject: [PATCH 071/429] Qt: Add missing HEVC NVENC option (fixes #1323) --- CHANGES | 1 + src/platform/qt/VideoView.ui | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index 7aa062fe0..f78f68473 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Misc: - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing + - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/VideoView.ui b/src/platform/qt/VideoView.ui index 1e9dfe367..24a3c5e75 100644 --- a/src/platform/qt/VideoView.ui +++ b/src/platform/qt/VideoView.ui @@ -269,6 +269,11 @@ HEVC + + + HEVC (NVENC) + + VP8 From 27f8abff155aad5df5632b415a8d83213586a34f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:02:19 -0800 Subject: [PATCH 072/429] Qt: Fix build on macOS --- src/platform/qt/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index cc02550ed..3e5400838 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -293,7 +293,7 @@ if(QT_STATIC) find_library(QTFREETYPE NAMES qtfreetype) find_library(QTHARFBUZZ NAMES qtharfbuzzng qtharfbuzz) find_library(QTPLATFORMSUPPORT NAMES Qt5PlatformSupport) - list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin ${QTPLATFORMSUPPORT} "-framework AVFoundation" "-framework CoreMedia") + list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin ${QTPLATFORMSUPPORT} "-framework AVFoundation" "-framework CoreMedia" "-framework SystemConfiguration" "-framework Security") set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};${QTHARFBUZZ};${QTFREETYPE}") link_directories() endif() From 3c5a9258a72ef9b7f5904783857c42232064119d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:02:40 -0800 Subject: [PATCH 073/429] Qt: Fix updater not flushing --- src/platform/qt/AbstractUpdater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/qt/AbstractUpdater.cpp b/src/platform/qt/AbstractUpdater.cpp index c165ae1a0..02f23c956 100644 --- a/src/platform/qt/AbstractUpdater.cpp +++ b/src/platform/qt/AbstractUpdater.cpp @@ -85,5 +85,7 @@ void AbstractUpdater::updateDownloaded(QNetworkReply* reply) { } f.write(bytes); } + f.flush(); + f.close(); emit updateDone(true); } From 6ee24a21de74fd76fe0af51ee4db7db2e6fcc786 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:42:22 -0800 Subject: [PATCH 074/429] Qt: Update static build info --- src/platform/qt/CMakeLists.txt | 6 +++--- src/platform/qt/main.cpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 3e5400838..36766daf7 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -181,7 +181,7 @@ if(Qt5Multimedia_FOUND) list(APPEND SOURCE_FILES VideoDumper.cpp) if (WIN32 AND QT_STATIC) - list(APPEND QT_LIBRARIES Qt5::QWindowsAudioPlugin Qt5::DSServicePlugin + list(APPEND QT_LIBRARIES Qt5::QWindowsAudioPlugin Qt5::DSServicePlugin Qt5::QWindowsVistaStylePlugin strmiids mfuuid mfplat mf ksguid dxva2 evr d3d9) endif() list(APPEND QT_LIBRARIES Qt5::Multimedia) @@ -285,8 +285,8 @@ endif() if(QT_STATIC) find_library(QTPCRE NAMES qtpcre2 qtpcre) if(WIN32) - list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport) - set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32;iphlpapi") + list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport Qt5WindowsUIAutomationSupport) + set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32") elseif(APPLE) find_package(Cups) find_package(Qt5PrintSupport) diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 8edc96e79..ec6a1b9e8 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -21,6 +21,7 @@ #include #ifdef Q_OS_WIN Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin); #ifdef BUILD_QT_MULTIMEDIA Q_IMPORT_PLUGIN(QWindowsAudioPlugin); Q_IMPORT_PLUGIN(DSServicePlugin); From 16688a59717d43518dfa7f9c2c10fdde148e1a70 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 22:07:34 -0800 Subject: [PATCH 075/429] Qt: Minor about screen fixes --- src/platform/qt/AboutScreen.ui | 2 +- src/platform/qt/Window.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/AboutScreen.ui b/src/platform/qt/AboutScreen.ui index d01aacdbb..c6f166e57 100644 --- a/src/platform/qt/AboutScreen.ui +++ b/src/platform/qt/AboutScreen.ui @@ -83,7 +83,7 @@ - © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 + © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 506e410e1..7a8c97dfc 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1190,7 +1190,7 @@ void Window::setupMenu(QMenuBar* menubar) { fileMenu->addSeparator(); #endif - QAction* about = new QAction(tr("About"), fileMenu); + QAction* about = new QAction(tr("About..."), fileMenu); connect(about, &QAction::triggered, openTView()); fileMenu->addAction(about); From eafb1ca06be6adcaa737cabf52eeef41e1b0d7d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Feb 2019 19:23:35 -0800 Subject: [PATCH 076/429] Qt: Fix load recent from archive (fixes #1325) --- CHANGES | 1 + src/platform/qt/CoreManager.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index f78f68473..4e9653d92 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ Bugfixes: - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Qt: More app metadata fixes + - Qt: Fix load recent from archive (fixes mgba.io/i/1325) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/CoreManager.cpp b/src/platform/qt/CoreManager.cpp index adb002c18..a77334cc5 100644 --- a/src/platform/qt/CoreManager.cpp +++ b/src/platform/qt/CoreManager.cpp @@ -49,7 +49,7 @@ CoreController* CoreManager::loadGame(const QString& path) { vf = vfclone; } dir->close(dir); - loadGame(vf, fname, base); + return loadGame(vf, fname, base); } else { LOG(QT, ERROR) << tr("Failed to open game file: %1").arg(path); } From f9ff88302f3de521a0f71ffbe8d15d9bfd9d0c8c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 12:46:46 -0800 Subject: [PATCH 077/429] GB Video: Delay LYC STAT check (fixes #1331) --- CHANGES | 1 + src/gb/video.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4e9653d92..e79ec1691 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Bugfixes: - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) + - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/video.c b/src/gb/video.c index d63460088..8aa978292 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -224,7 +224,6 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { ++video->ly; video->p->memory.io[REG_LY] = video->ly; GBRegisterSTAT oldStat = video->stat; - video->stat = GBRegisterSTATSetLYC(video->stat, lyc == video->ly); if (video->ly < GB_VIDEO_VERTICAL_PIXELS) { next = GB_VIDEO_MODE_2_LENGTH; video->mode = 2; @@ -246,6 +245,14 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (!_statIRQAsserted(video, oldStat) && _statIRQAsserted(video, video->stat)) { video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT); } + + // LYC stat is delayed 1 T-cycle + oldStat = video->stat; + video->stat = GBRegisterSTATSetLYC(video->stat, lyc == 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; mTimingSchedule(timing, &video->modeEvent, (next << video->p->doubleSpeed) - cyclesLate); From f9b12a86122f4da639fbaad72c32ba7e4a97bb8f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 14:14:21 -0800 Subject: [PATCH 078/429] GBA I/O: Fix IRQ register write checks (fixes #1335) --- src/gba/io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gba/io.c b/src/gba/io.c index 7b7c4ba3a..68c77c8d5 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -548,16 +548,16 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case REG_IE: gba->memory.io[REG_IE >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_IF: value = gba->memory.io[REG_IF >> 1] & ~value; gba->memory.io[REG_IF >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_IME: gba->memory.io[REG_IME >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_MAX: // Some bad interrupt libraries will write to this From b78825738ee6d094e892c3980c730d67db315c13 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 14:21:36 -0800 Subject: [PATCH 079/429] CHANGES: Break out emulation fixes from other fixes --- CHANGES | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e79ec1691..7cc88f132 100644 --- a/CHANGES +++ b/CHANGES @@ -3,13 +3,14 @@ Features: - Improved logging configuration - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games -Bugfixes: +Emulation fixes: - 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) + - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) +Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) - - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash From a3c79c92d78c5802d0608639bc4feb87d2faa1d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 17:27:53 -0800 Subject: [PATCH 080/429] GB Video: Fix window being enabled mid-scanline (fixes #1328) --- CHANGES | 1 + include/mgba/internal/gb/renderers/software.h | 2 ++ src/gb/renderers/software.c | 20 +++++++++++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 7cc88f132..04eb39e17 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ Emulation fixes: - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) + - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index 3b8f7a210..fe4b1ff98 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -32,7 +32,9 @@ struct GBVideoSoftwareRenderer { uint8_t wy; uint8_t wx; uint8_t currentWy; + uint8_t currentWx; int lastY; + int lastX; bool hasWindow; GBRegisterLCDC lcdc; diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index c5e0d3c7a..4b1517ae0 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -190,7 +190,9 @@ static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum G softwareRenderer->scx = 0; softwareRenderer->wy = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->hasWindow = false; softwareRenderer->wx = 0; softwareRenderer->model = model; @@ -232,6 +234,9 @@ static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* renderer->currentWy = GB_VIDEO_VERTICAL_PIXELS; } else { renderer->currentWy = renderer->lastY - renderer->wy; + if (renderer->lastY == renderer->wy && renderer->lastX > renderer->wx) { + ++renderer->currentWy; + } } } else { renderer->currentWy += renderer->lastY; @@ -489,6 +494,7 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, ui static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; softwareRenderer->lastY = y; + softwareRenderer->lastX = endX; uint8_t* maps = &softwareRenderer->d.vram[GB_BASE_MAP]; if (GBRegisterLCDCIsTileMap(softwareRenderer->lcdc)) { maps += GB_SIZE_MAP; @@ -498,9 +504,10 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i } if (GBRegisterLCDCIsBgEnable(softwareRenderer->lcdc) || softwareRenderer->model >= GB_MODEL_CGB) { int wy = softwareRenderer->wy + softwareRenderer->currentWy; - if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && endX >= softwareRenderer->wx - 7) { - if (softwareRenderer->wx - 7 > 0 && !softwareRenderer->d.disableBG) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, softwareRenderer->wx - 7, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); + int wx = softwareRenderer->wx + softwareRenderer->currentWx - 7; + if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && wx <= endX) { + if (wx > 0 && !softwareRenderer->d.disableBG) { + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, wx, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); } maps = &softwareRenderer->d.vram[GB_BASE_MAP]; @@ -508,7 +515,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i maps += GB_SIZE_MAP; } if (!softwareRenderer->d.disableWIN) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, softwareRenderer->wx - 7, endX, 7 - softwareRenderer->wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, wx, endX, -wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); } } else if (!softwareRenderer->d.disableBG) { GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, endX, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); @@ -612,6 +619,9 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; + softwareRenderer->lastX = 0; + softwareRenderer->currentWx = 0; + if (softwareRenderer->sgbTransfer == 1) { size_t offset = 2 * ((y & 7) + (y >> 3) * GB_VIDEO_HORIZONTAL_PIXELS); if (offset >= 0x1000) { @@ -702,7 +712,9 @@ static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer) } } softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->hasWindow = false; } From 267074fcd975527cc068f3b1334050344257e3d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 17:56:33 -0800 Subject: [PATCH 081/429] GB I/O: Filter IE top bits properly (fixes #1329) --- CHANGES | 1 + src/gb/io.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 04eb39e17..6f66be9c1 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Emulation fixes: - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) + - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gb/io.c b/src/gb/io.c index 84b3a35bc..c5f138b60 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -465,7 +465,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { } break; case REG_IE: - gb->memory.ie = value; + gb->memory.ie = value & 0x1F; GBUpdateIRQs(gb); return; default: @@ -578,7 +578,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_JOYP: return _readKeysFiltered(gb); case REG_IE: - return gb->memory.ie; + return gb->memory.ie | 0xE0; case REG_WAVE_0: case REG_WAVE_1: case REG_WAVE_2: From ce2732823985041f17107a4178d43ac3234ea1f7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 18:03:06 -0800 Subject: [PATCH 082/429] cinema: Add tests for #1328 --- cinema/gb/window/007wne-hud/baseline_0000.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0001.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0002.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0003.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/test.mvl | Bin 0 -> 14295 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 cinema/gb/window/007wne-hud/baseline_0000.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0001.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0002.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0003.png create mode 100644 cinema/gb/window/007wne-hud/test.mvl diff --git a/cinema/gb/window/007wne-hud/baseline_0000.png b/cinema/gb/window/007wne-hud/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0001.png b/cinema/gb/window/007wne-hud/baseline_0001.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0002.png b/cinema/gb/window/007wne-hud/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0003.png b/cinema/gb/window/007wne-hud/baseline_0003.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/test.mvl b/cinema/gb/window/007wne-hud/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..d5dc5d28826cd831880a6dc48ec269004b8fdb7e GIT binary patch literal 14295 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 literal 0 HcmV?d00001 From 0421228a77fdf228551584fbcb300c6e27f2583e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 18:07:10 -0800 Subject: [PATCH 083/429] GB I/O: Alternate fix for #1329 that doesn't break tests --- src/gb/gb.c | 2 +- src/gb/io.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index 038401c83..fc3c174b0 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -630,7 +630,7 @@ void GBDetectModel(struct GB* gb) { } void GBUpdateIRQs(struct GB* gb) { - int irqs = gb->memory.ie & gb->memory.io[REG_IF]; + int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F; if (!irqs) { gb->cpu->irqPending = false; return; diff --git a/src/gb/io.c b/src/gb/io.c index c5f138b60..84b3a35bc 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -465,7 +465,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { } break; case REG_IE: - gb->memory.ie = value & 0x1F; + gb->memory.ie = value; GBUpdateIRQs(gb); return; default: @@ -578,7 +578,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_JOYP: return _readKeysFiltered(gb); case REG_IE: - return gb->memory.ie | 0xE0; + return gb->memory.ie; case REG_WAVE_0: case REG_WAVE_1: case REG_WAVE_2: From f5ddeb3611248a9632fdd6ed28d0e390ac1fb6c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:24:45 -0800 Subject: [PATCH 084/429] LR35902: Fix disassembly of several CB-prefix instructions --- CHANGES | 1 + src/lr35902/decoder.c | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 6f66be9c1..217ec4ddf 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Emulation fixes: Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) + - LR35902: Fix disassembly of several CB-prefix instructions Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/lr35902/decoder.c b/src/lr35902/decoder.c index 3d3098441..76c6b9f02 100644 --- a/src/lr35902/decoder.c +++ b/src/lr35902/decoder.c @@ -314,15 +314,21 @@ DEFINE_POPPUSH_DECODER_LR35902(DE); DEFINE_POPPUSH_DECODER_LR35902(HL); DEFINE_POPPUSH_DECODER_LR35902(AF); +#define DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, OP) \ + DEFINE_DECODER_LR35902(NAME ## B, info->OP.reg = LR35902_REG_B; BODY) \ + DEFINE_DECODER_LR35902(NAME ## C, info->OP.reg = LR35902_REG_C; BODY) \ + DEFINE_DECODER_LR35902(NAME ## D, info->OP.reg = LR35902_REG_D; BODY) \ + DEFINE_DECODER_LR35902(NAME ## E, info->OP.reg = LR35902_REG_E; BODY) \ + DEFINE_DECODER_LR35902(NAME ## H, info->OP.reg = LR35902_REG_H; BODY) \ + DEFINE_DECODER_LR35902(NAME ## L, info->OP.reg = LR35902_REG_L; BODY) \ + DEFINE_DECODER_LR35902(NAME ## HL, info->OP.reg = LR35902_REG_HL; info->OP.flags = LR35902_OP_FLAG_MEMORY; BODY) \ + DEFINE_DECODER_LR35902(NAME ## A, info->OP.reg = LR35902_REG_A; BODY) + #define DEFINE_CB_2_DECODER_LR35902(NAME, BODY) \ - DEFINE_DECODER_LR35902(NAME ## B, info->op2.reg = LR35902_REG_B; BODY) \ - DEFINE_DECODER_LR35902(NAME ## C, info->op2.reg = LR35902_REG_C; BODY) \ - DEFINE_DECODER_LR35902(NAME ## D, info->op2.reg = LR35902_REG_D; BODY) \ - DEFINE_DECODER_LR35902(NAME ## E, info->op2.reg = LR35902_REG_E; BODY) \ - DEFINE_DECODER_LR35902(NAME ## H, info->op2.reg = LR35902_REG_H; BODY) \ - DEFINE_DECODER_LR35902(NAME ## L, info->op2.reg = LR35902_REG_L; BODY) \ - DEFINE_DECODER_LR35902(NAME ## HL, info->op2.reg = LR35902_REG_HL; info->op2.flags = LR35902_OP_FLAG_MEMORY; BODY) \ - DEFINE_DECODER_LR35902(NAME ## A, info->op2.reg = LR35902_REG_A; BODY) + DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op2) + +#define DEFINE_CB_1_DECODER_LR35902(NAME, BODY) \ + DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op1) #define DEFINE_CB_DECODER_LR35902(NAME, BODY) \ DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \ @@ -339,17 +345,19 @@ DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES) DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET) #define DEFINE_CB_X_DECODER_LR35902(NAME) \ - DEFINE_CB_2_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \ - DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A) + DEFINE_CB_1_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \ + DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; \ + info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \ + info->op1.reg = LR35902_REG_A;) DEFINE_CB_X_DECODER_LR35902(RL) DEFINE_CB_X_DECODER_LR35902(RLC) DEFINE_CB_X_DECODER_LR35902(RR) DEFINE_CB_X_DECODER_LR35902(RRC) -DEFINE_CB_2_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA) -DEFINE_CB_2_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA) -DEFINE_CB_2_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL) -DEFINE_CB_2_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP) +DEFINE_CB_1_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA) +DEFINE_CB_1_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA) +DEFINE_CB_1_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL) +DEFINE_CB_1_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP) DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI) DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI) From c3ec7311e80127bb648418defee171178be9075b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:27:13 -0800 Subject: [PATCH 085/429] Debugger: Add unary operators and memory dereferencing --- CHANGES | 1 + include/mgba/internal/debugger/parser.h | 1 + src/debugger/parser.c | 86 +++++++++++++++++++++++-- src/lr35902/debugger/cli-debugger.c | 2 +- src/lr35902/debugger/debugger.c | 2 +- 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 217ec4ddf..962e2e6a2 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Features: - Improved logging configuration - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games + - Debugger: Add unary operators and memory dereferencing Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/internal/debugger/parser.h b/include/mgba/internal/debugger/parser.h index 6092c1f8c..37f194ddb 100644 --- a/include/mgba/internal/debugger/parser.h +++ b/include/mgba/internal/debugger/parser.h @@ -38,6 +38,7 @@ enum Operation { OP_NOT, OP_SHIFT_L, OP_SHIFT_R, + OP_DEREFERENCE, }; struct Token { diff --git a/src/debugger/parser.c b/src/debugger/parser.c index 41eafc6d4..adad22e21 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include #include @@ -89,6 +90,29 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta break; } *state = LEX_ERROR; + } + if (*state == LEX_ROOT || *state == LEX_ERROR) { + struct Token* lvNext = LexVectorAppend(lv); + lvNext->type = TOKEN_OPERATOR_TYPE; + *state = LEX_ROOT; + switch (operator) { + case '-': + lvNext->operatorValue = OP_NEGATE; + break; + case '~': + lvNext->operatorValue = OP_FLIP; + break; + case '!': + lvNext->operatorValue = OP_NOT; + break; + case '*': + lvNext->operatorValue = OP_DEREFERENCE; + break; + default: + lvNext->type = TOKEN_ERROR_TYPE; + *state = LEX_ERROR; + break; + } return; } struct Token* lvNext = LexVectorAppend(lv); @@ -247,6 +271,12 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_OPEN_PAREN_TYPE; break; + case '!': + case '-': + case '~': + case '*': + _lexOperator(lv, token, &state); + break; case ' ': case '\t': break; @@ -499,6 +529,7 @@ static const int _operatorPrecedence[] = { [OP_NOT] = 2, [OP_SHIFT_L] = 5, [OP_SHIFT_R] = 5, + [OP_DEREFERENCE] = 2, }; static struct ParseTree* _parseTreeCreate() { @@ -622,7 +653,7 @@ void parseFree(struct ParseTree* tree) { } } -static bool _performOperation(enum Operation operation, int32_t current, int32_t next, int32_t* value) { +static bool _performOperation(struct mDebugger* debugger, enum Operation operation, int32_t current, int32_t next, int32_t* value, int* segment) { switch (operation) { case OP_ASSIGN: current = next; @@ -683,12 +714,29 @@ static bool _performOperation(enum Operation operation, int32_t current, int32_t case OP_GE: current = current >= next; break; + case OP_NEGATE: + current = -next; + break; + case OP_FLIP: + current = ~next; + break; + case OP_NOT: + current = !next; + break; case OP_SHIFT_L: current <<= next; break; case OP_SHIFT_R: current >>= next; break; + case OP_DEREFERENCE: + if (*segment < 0) { + current = debugger->core->busRead8(debugger->core, next); + } else { + current = debugger->core->rawRead8(debugger->core, next, *segment); + } + *segment = -1; + break; default: return false; } @@ -714,13 +762,37 @@ bool mDebuggerEvaluateParseTree(struct mDebugger* debugger, struct ParseTree* tr } return mDebuggerEvaluateParseTree(debugger, tree->lhs, segment, NULL); case TOKEN_OPERATOR_TYPE: - if (!mDebuggerEvaluateParseTree(debugger, tree->lhs, &lhs, segment)) { - return false; + switch (tree->token.operatorValue) { + case OP_ASSIGN: + case OP_ADD: + case OP_SUBTRACT: + case OP_MULTIPLY: + case OP_DIVIDE: + case OP_MODULO: + case OP_AND: + case OP_OR: + case OP_XOR: + case OP_LESS: + case OP_GREATER: + case OP_EQUAL: + case OP_NOT_EQUAL: + case OP_LOGICAL_AND: + case OP_LOGICAL_OR: + case OP_LE: + case OP_GE: + case OP_SHIFT_L: + case OP_SHIFT_R: + if (!mDebuggerEvaluateParseTree(debugger, tree->lhs, &lhs, segment)) { + return false; + } + // Fall through + default: + if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, &rhs, segment)) { + return false; + } + break; } - if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, &rhs, segment)) { - return false; - } - return _performOperation(tree->token.operatorValue, lhs, rhs, value); + return _performOperation(debugger, tree->token.operatorValue, lhs, rhs, value, segment); case TOKEN_IDENTIFIER_TYPE: return mDebuggerLookupIdentifier(debugger, tree->token.identifierValue, value, segment); case TOKEN_ERROR_TYPE: diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index fe85bca27..4fefd77f3 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -74,7 +74,7 @@ static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address }; disPtr[0] = '\t'; ++disPtr; - LR35902Disassemble(&info, disPtr, sizeof(disassembly) - (disPtr - disassembly)); + LR35902Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly)); be->printf(be, "%s\n", disassembly); return address; } diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 398131d5d..47ae68533 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -215,7 +215,7 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* disPtr[0] = ':'; disPtr[1] = ' '; disPtr += 2; - LR35902Disassemble(&info, disPtr, sizeof(disassembly) - (disPtr - disassembly)); + LR35902Disassemble(&info, address, 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: %02X:%04X | %s", cpu->a, cpu->f.packed, cpu->b, cpu->c, From d6ac0dc6f526ac111c4e750e282050c034724b76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:28:27 -0800 Subject: [PATCH 086/429] LR35902: Support PC-relative opcode decoding --- CHANGES | 1 + include/mgba/internal/lr35902/decoder.h | 3 ++- src/lr35902/decoder.c | 16 +++++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 962e2e6a2..c5c787633 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Misc: - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) + - LR35902: Support PC-relative opcode decoding 0.7.1: (2019-02-24) Bugfixes: diff --git a/include/mgba/internal/lr35902/decoder.h b/include/mgba/internal/lr35902/decoder.h index 101a104c3..ba9ceec36 100644 --- a/include/mgba/internal/lr35902/decoder.h +++ b/include/mgba/internal/lr35902/decoder.h @@ -86,6 +86,7 @@ enum { LR35902_OP_FLAG_MEMORY = 2, LR35902_OP_FLAG_INCREMENT = 4, LR35902_OP_FLAG_DECREMENT = 8, + LR35902_OP_FLAG_RELATIVE = 16, }; struct LR35902Operand { @@ -104,7 +105,7 @@ struct LR35902InstructionInfo { }; size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info); -int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen); +int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen); CXX_GUARD_END diff --git a/src/lr35902/decoder.c b/src/lr35902/decoder.c index 76c6b9f02..089b52c69 100644 --- a/src/lr35902/decoder.c +++ b/src/lr35902/decoder.c @@ -199,6 +199,7 @@ DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \ DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \ info->mnemonic = LR35902_MN_JR; \ info->condition = CONDITION; \ + info->op1.flags = LR35902_OP_FLAG_RELATIVE; \ return 1;) #define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \ @@ -497,7 +498,7 @@ static const char* _lr35902MnemonicStrings[] = { }; -static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { +static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, int blen) { int total = 0; if (op.flags & LR35902_OP_FLAG_IMPLICIT) { return 0; @@ -511,7 +512,12 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]); ADVANCE(written); } else { - int written = snprintf(buffer, blen - 1, "$%02X", op.immediate); + int written; + if (op.flags & LR35902_OP_FLAG_RELATIVE) { + written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate); + } else { + written = snprintf(buffer, blen - 1, "$%02X", op.immediate); + } ADVANCE(written); if (op.reg) { strncpy(buffer, "+", blen - 1); @@ -533,7 +539,7 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { return total; } -int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) { +int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) { const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic]; int written; int total = 0; @@ -553,7 +559,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl } if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) { - written = _decodeOperand(info->op1, buffer, blen); + written = _decodeOperand(info->op1, pc, buffer, blen); ADVANCE(written); } @@ -562,7 +568,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl strncpy(buffer, ", ", blen - 1); ADVANCE(2); } - written = _decodeOperand(info->op2, buffer, blen); + written = _decodeOperand(info->op2, pc, buffer, blen); ADVANCE(written); } From b3687bfbe9611b0534da93ebd1075ae8d9b129cd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:30:36 -0800 Subject: [PATCH 087/429] GB Debugger: Expose platform info in CLI --- CHANGES | 1 + CMakeLists.txt | 1 + include/mgba/internal/gb/debugger/debugger.h | 20 ++++++++ .../mgba/internal/lr35902/debugger/debugger.h | 3 ++ src/gb/core.c | 22 +-------- src/gb/debugger/debugger.c | 46 +++++++++++++++++++ src/lr35902/debugger/cli-debugger.c | 5 +- src/lr35902/debugger/debugger.c | 31 +++++++------ 8 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 include/mgba/internal/gb/debugger/debugger.h create mode 100644 src/gb/debugger/debugger.c diff --git a/CHANGES b/CHANGES index c5c787633..e55b9ad74 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ Features: - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games - Debugger: Add unary operators and memory dereferencing + - GB: Expose platform information to CLI debugger Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/CMakeLists.txt b/CMakeLists.txt index fa01e3a50..a3dd284a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -747,6 +747,7 @@ if(M_CORE_GB) ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/memory-debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/symbols.c) list(APPEND TEST_SRC ${LR35902_TEST_SRC} diff --git a/include/mgba/internal/gb/debugger/debugger.h b/include/mgba/internal/gb/debugger/debugger.h new file mode 100644 index 000000000..2eeee8ed1 --- /dev/null +++ b/include/mgba/internal/gb/debugger/debugger.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2013-2019 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/. */ +#ifndef GB_DEBUGGER_H +#define GB_DEBUGGER_H + +#include + +CXX_GUARD_START + +struct GB; +struct mDebuggerPlatform; + +struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb); + +CXX_GUARD_END + +#endif \ No newline at end of file diff --git a/include/mgba/internal/lr35902/debugger/debugger.h b/include/mgba/internal/lr35902/debugger/debugger.h index 1114c5c1a..6e62b6ce9 100644 --- a/include/mgba/internal/lr35902/debugger/debugger.h +++ b/include/mgba/internal/lr35902/debugger/debugger.h @@ -20,6 +20,7 @@ struct LR35902Segment { const char* name; }; +struct CLIDebuggerSystem; struct LR35902Debugger { struct mDebuggerPlatform d; struct LR35902Core* cpu; @@ -31,6 +32,8 @@ struct LR35902Debugger { ssize_t nextId; const struct LR35902Segment* segments; + + void (*printStatus)(struct CLIDebuggerSystem*); }; struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void); diff --git a/src/gb/core.c b/src/gb/core.c index 68b613108..1671a1142 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -37,20 +38,6 @@ static const struct mCoreChannelInfo _GBAudioChannels[] = { { 3, "ch4", "Channel 4", "Noise" }, }; -static const struct LR35902Segment _GBSegments[] = { - { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, - { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, - { 0 } -}; - -static const struct LR35902Segment _GBCSegments[] = { - { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, - { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, - { .name = "WRAM", .start = GB_BASE_WORKING_RAM_BANK1, .end = 0xE000 }, - { .name = "VRAM", .start = GB_BASE_VRAM, .end = GB_BASE_EXTERNAL_RAM }, - { 0 } -}; - static const struct mCoreMemoryBlock _GBMemoryBlocks[] = { { -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL }, { GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 }, @@ -692,12 +679,7 @@ static struct mDebuggerPlatform* _GBCoreDebuggerPlatform(struct mCore* core) { struct GBCore* gbcore = (struct GBCore*) core; struct GB* gb = core->board; if (!gbcore->debuggerPlatform) { - struct LR35902Debugger* platform = (struct LR35902Debugger*) LR35902DebuggerPlatformCreate(); - if (gb->model >= GB_MODEL_CGB) { - platform->segments = _GBCSegments; - } else { - platform->segments = _GBSegments; - } + struct LR35902Debugger* platform = (struct LR35902Debugger*) GBDebuggerCreate(gb); gbcore->debuggerPlatform = &platform->d; } return gbcore->debuggerPlatform; diff --git a/src/gb/debugger/debugger.c b/src/gb/debugger/debugger.c new file mode 100644 index 000000000..41444806b --- /dev/null +++ b/src/gb/debugger/debugger.c @@ -0,0 +1,46 @@ +/* Copyright (c) 2013-2019 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 + + #include + #include + #include + #include + #include + #include + +static const struct LR35902Segment _GBSegments[] = { + { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, + { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, + { 0 } +}; + +static const struct LR35902Segment _GBCSegments[] = { + { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, + { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, + { .name = "WRAM", .start = GB_BASE_WORKING_RAM_BANK1, .end = 0xE000 }, + { .name = "VRAM", .start = GB_BASE_VRAM, .end = GB_BASE_EXTERNAL_RAM }, + { 0 } +}; + +static void _printStatus(struct CLIDebuggerSystem* debugger) { + struct CLIDebuggerBackend* be = debugger->p->backend; + struct GB* gb = debugger->p->d.core->board; + be->printf(be, "IE: %02X IF: %02X IME: %i\n", gb->memory.ie, gb->memory.io[REG_IF], gb->memory.ime); + be->printf(be, "LCDC: %02X STAT: %02X LY: %02X\n", gb->memory.io[REG_LCDC], gb->memory.io[REG_STAT] | 0x80, gb->memory.io[REG_LY]); + be->printf(be, "Next video mode: %i\n", mTimingUntil(&gb->timing, &gb->video.modeEvent) / 4); +} + +struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb) { + struct LR35902Debugger* platform = (struct LR35902Debugger*) LR35902DebuggerPlatformCreate(); + if (gb->model >= GB_MODEL_CGB) { + platform->segments = _GBCSegments; + } else { + platform->segments = _GBSegments; + } + platform->printStatus = _printStatus; + return &platform->d; +} \ No newline at end of file diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index 4fefd77f3..300a3dd8f 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -87,6 +87,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { 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); + _printFlags(be, cpu->f); struct LR35902Debugger* platDebugger = (struct LR35902Debugger*) debugger->p->d.platform; size_t i; @@ -96,7 +97,9 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { if (i) { be->printf(be, "\n"); } - _printFlags(be, cpu->f); + if (platDebugger->printStatus) { + platDebugger->printStatus(debugger); + } _printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc)); } diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 47ae68533..fb7e4a247 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -75,21 +75,22 @@ static bool LR35902DebuggerGetRegister(struct mDebuggerPlatform*, const char* na static bool LR35902DebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value); struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) { - struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger)); - platform->entered = LR35902DebuggerEnter; - platform->init = LR35902DebuggerInit; - platform->deinit = LR35902DebuggerDeinit; - platform->setBreakpoint = LR35902DebuggerSetBreakpoint; - platform->listBreakpoints = LR35902DebuggerListBreakpoints; - platform->clearBreakpoint = LR35902DebuggerClearBreakpoint; - platform->setWatchpoint = LR35902DebuggerSetWatchpoint; - platform->listWatchpoints = LR35902DebuggerListWatchpoints; - platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints; - platform->hasBreakpoints = LR35902DebuggerHasBreakpoints; - platform->trace = LR35902DebuggerTrace; - platform->getRegister = LR35902DebuggerGetRegister; - platform->setRegister = LR35902DebuggerSetRegister; - return platform; + struct LR35902Debugger* platform = malloc(sizeof(struct LR35902Debugger)); + platform->d.entered = LR35902DebuggerEnter; + platform->d.init = LR35902DebuggerInit; + platform->d.deinit = LR35902DebuggerDeinit; + platform->d.setBreakpoint = LR35902DebuggerSetBreakpoint; + platform->d.listBreakpoints = LR35902DebuggerListBreakpoints; + platform->d.clearBreakpoint = LR35902DebuggerClearBreakpoint; + platform->d.setWatchpoint = LR35902DebuggerSetWatchpoint; + platform->d.listWatchpoints = LR35902DebuggerListWatchpoints; + platform->d.checkBreakpoints = LR35902DebuggerCheckBreakpoints; + platform->d.hasBreakpoints = LR35902DebuggerHasBreakpoints; + platform->d.trace = LR35902DebuggerTrace; + platform->d.getRegister = LR35902DebuggerGetRegister; + platform->d.setRegister = LR35902DebuggerSetRegister; + platform->printStatus = NULL; + return &platform->d; } void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { From 7b59e620f13acfe8498b85bce67340a207d0b610 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 19:16:43 -0800 Subject: [PATCH 088/429] Debugger: Clean up token lexing --- src/debugger/parser.c | 52 ++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/debugger/parser.c b/src/debugger/parser.c index adad22e21..9d8db0262 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -92,73 +92,75 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta *state = LEX_ERROR; } if (*state == LEX_ROOT || *state == LEX_ERROR) { - struct Token* lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_OPERATOR_TYPE; + struct Token lvNext; + lvNext.type = TOKEN_OPERATOR_TYPE; *state = LEX_ROOT; switch (operator) { case '-': - lvNext->operatorValue = OP_NEGATE; + lvNext.operatorValue = OP_NEGATE; break; case '~': - lvNext->operatorValue = OP_FLIP; + lvNext.operatorValue = OP_FLIP; break; case '!': - lvNext->operatorValue = OP_NOT; + lvNext.operatorValue = OP_NOT; break; case '*': - lvNext->operatorValue = OP_DEREFERENCE; + lvNext.operatorValue = OP_DEREFERENCE; break; default: - lvNext->type = TOKEN_ERROR_TYPE; + lvNext.type = TOKEN_ERROR_TYPE; *state = LEX_ERROR; - break; + return; } + *LexVectorAppend(lv) = lvNext; return; } - struct Token* lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_OPERATOR_TYPE; - *state = LEX_EXPECT_OPERATOR2; + struct Token lvNext; + lvNext.type = TOKEN_OPERATOR_TYPE; switch (operator) { case '=': - lvNext->operatorValue = OP_ASSIGN; + lvNext.operatorValue = OP_ASSIGN; break; case '+': - lvNext->operatorValue = OP_ADD; + lvNext.operatorValue = OP_ADD; break; case '-': - lvNext->operatorValue = OP_SUBTRACT; + lvNext.operatorValue = OP_SUBTRACT; break; case '*': - lvNext->operatorValue = OP_MULTIPLY; + lvNext.operatorValue = OP_MULTIPLY; break; case '/': - lvNext->operatorValue = OP_DIVIDE; + lvNext.operatorValue = OP_DIVIDE; break; case '%': - lvNext->operatorValue = OP_MODULO; + lvNext.operatorValue = OP_MODULO; break; case '&': - lvNext->operatorValue = OP_AND; + lvNext.operatorValue = OP_AND; break; case '|': - lvNext->operatorValue = OP_OR; + lvNext.operatorValue = OP_OR; break; case '^': - lvNext->operatorValue = OP_XOR; + lvNext.operatorValue = OP_XOR; break; case '<': - lvNext->operatorValue = OP_LESS; + lvNext.operatorValue = OP_LESS; break; case '>': - lvNext->operatorValue = OP_GREATER; + lvNext.operatorValue = OP_GREATER; break; case '!': - lvNext->operatorValue = OP_NOT; + lvNext.operatorValue = OP_NOT; break; default: - lvNext->type = TOKEN_ERROR_TYPE; - break; + *state = LEX_ERROR; + return; } + *state = LEX_EXPECT_OPERATOR2; + *LexVectorAppend(lv) = lvNext; } static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexState* state) { From 03aed12d2889544f9e88ef8da32c6037b9375362 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 17:34:02 -0800 Subject: [PATCH 089/429] Qt: Improve camera initialization --- CHANGES | 1 + src/platform/qt/InputController.cpp | 28 ++++++++++++++++++++-------- src/platform/qt/InputController.h | 6 ++++-- src/platform/qt/VideoDumper.cpp | 18 +++++++++++------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index e55b9ad74..e644bca84 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Misc: - Debugger: Add breakpoint and watchpoint listing - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) - LR35902: Support PC-relative opcode decoding + - Qt: Improve camera initialization 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index ce73a5255..8869dac82 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -725,12 +725,23 @@ void InputController::setupCam() { #ifdef BUILD_QT_MULTIMEDIA if (!m_camera) { m_camera = std::make_unique(); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); } - QVideoFrame::PixelFormat format(QVideoFrame::Format_RGB32); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + m_camera->setCaptureMode(QCamera::CaptureVideo); + m_camera->setViewfinder(&m_videoDumper); m_camera->load(); +#endif +} + +#ifdef BUILD_QT_MULTIMEDIA +void InputController::prepareCamSettings(QCamera::Status status) { + if (status != QCamera::LoadedStatus || m_camera->state() == QCamera::ActiveState) { + return; + } +#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + QVideoFrame::PixelFormat format(QVideoFrame::Format_RGB32); QCameraViewfinderSettings settings; - QSize size(1920, 1080); + QSize size(1280, 720); auto cameraRes = m_camera->supportedViewfinderResolutions(settings); for (auto& cameraSize : cameraRes) { if (cameraSize.width() < m_image.w || cameraSize.height() < m_image.h) { @@ -741,10 +752,11 @@ void InputController::setupCam() { } } settings.setResolution(size); + auto cameraFormats = m_camera->supportedViewfinderPixelFormats(settings); auto goodFormats = m_videoDumper.supportedPixelFormats(); bool goodFormatFound = false; - for (auto& goodFormat : goodFormats) { + for (const auto& goodFormat : goodFormats) { if (cameraFormats.contains(goodFormat)) { settings.setPixelFormat(goodFormat); format = goodFormat; @@ -754,20 +766,20 @@ void InputController::setupCam() { } if (!goodFormatFound) { LOG(QT, WARN) << "Could not find a valid camera format!"; + for (const auto& format : cameraFormats) { + LOG(QT, WARN) << "Camera supported format: " << QString::number(format); + } } m_camera->setViewfinderSettings(settings); #endif - m_camera->setCaptureMode(QCamera::CaptureVideo); - m_camera->setViewfinder(&m_videoDumper); m_camera->start(); -#endif } +#endif void InputController::teardownCam() { #ifdef BUILD_QT_MULTIMEDIA if (m_camera) { m_camera->stop(); - m_camera.reset(); } #endif } diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index 0fb6b16e0..d15bd0e22 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -27,13 +27,12 @@ #ifdef BUILD_QT_MULTIMEDIA #include "VideoDumper.h" +#include #endif struct mRotationSource; struct mRumble; -class QCamera; - namespace QGBA { class ConfigController; @@ -124,6 +123,9 @@ public slots: void setCamImage(const QImage& image); private slots: +#ifdef BUILD_QT_MULTIMEDIA + void prepareCamSettings(QCamera::Status); +#endif void setupCam(); void teardownCam(); diff --git a/src/platform/qt/VideoDumper.cpp b/src/platform/qt/VideoDumper.cpp index c5ed93eb2..c5df8d208 100644 --- a/src/platform/qt/VideoDumper.cpp +++ b/src/platform/qt/VideoDumper.cpp @@ -23,14 +23,18 @@ bool VideoDumper::present(const QVideoFrame& frame) { QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(vFormat); bool swap = false; if (format == QImage::Format_Invalid) { - vFormat = static_cast(vFormat - QVideoFrame::Format_BGRA32 + QVideoFrame::Format_ARGB32); - format = QVideoFrame::imageFormatFromPixelFormat(vFormat); - if (format == QImage::Format_ARGB32) { - format = QImage::Format_RGBA8888; - } else if (format == QImage::Format_ARGB32_Premultiplied) { - format = QImage::Format_RGBA8888_Premultiplied; + if (vFormat < QVideoFrame::Format_BGRA5658_Premultiplied) { + vFormat = static_cast(vFormat - QVideoFrame::Format_BGRA32 + QVideoFrame::Format_ARGB32); + format = QVideoFrame::imageFormatFromPixelFormat(vFormat); + if (format == QImage::Format_ARGB32) { + format = QImage::Format_RGBA8888; + } else if (format == QImage::Format_ARGB32_Premultiplied) { + format = QImage::Format_RGBA8888_Premultiplied; + } + swap = true; + } else { + return false; } - swap = true; } uchar* bits = mappedFrame.bits(); QImage image(bits, mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(), format); From 1fd8b1b299e785ee75df6ec45bfb6a8d434af684 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 17:37:21 -0800 Subject: [PATCH 090/429] Qt: Support switching webcams --- CHANGES | 1 + src/platform/qt/InputController.cpp | 31 ++++++++++++++++++++++++++++- src/platform/qt/InputController.h | 4 ++++ src/platform/qt/SettingsView.cpp | 16 +++++++++++++++ src/platform/qt/SettingsView.h | 1 + src/platform/qt/SettingsView.ui | 26 +++++++++++++++++++++--- src/platform/qt/Window.cpp | 1 + 7 files changed, 76 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index e644bca84..52b42650c 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Misc: - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) - LR35902: Support PC-relative opcode decoding - Qt: Improve camera initialization + - Qt: Support switching webcams 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 8869dac82..b655e86d9 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -15,7 +15,7 @@ #include #include #ifdef BUILD_QT_MULTIMEDIA -#include +#include #include #endif @@ -98,6 +98,10 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren } #ifdef BUILD_QT_MULTIMEDIA if (image->p->m_config->getQtOption("cameraDriver").toInt() == static_cast(CameraDriver::QT_MULTIMEDIA)) { + QByteArray camera = image->p->m_config->getQtOption("camera").toByteArray(); + if (!camera.isNull()) { + QMetaObject::invokeMethod(image->p, "setCamera", Q_ARG(QByteArray, camera)); + } QMetaObject::invokeMethod(image->p, "setupCam"); } #endif @@ -691,6 +695,17 @@ void InputController::setCamImage(const QImage& image) { m_image.outOfDate = true; } +QList> InputController::listCameras() const { + QList> out; +#ifdef BUILD_QT_MULTIMEDIA + QList cams = QCameraInfo::availableCameras(); + for (const auto& cam : cams) { + out.append(qMakePair(cam.deviceName().toLatin1(), cam.description())); + } +#endif + return out; +} + void InputController::increaseLuminanceLevel() { setLuminanceLevel(m_luxLevel + 1); } @@ -783,3 +798,17 @@ void InputController::teardownCam() { } #endif } + +void InputController::setCamera(const QByteArray& name) { +#ifdef BUILD_QT_MULTIMEDIA + bool needsRestart = false; + if (m_camera) { + needsRestart = m_camera->state() == QCamera::ActiveState; + } + m_camera = std::make_unique(name); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); + if (needsRestart) { + setupCam(); + } +#endif +} \ No newline at end of file diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index d15bd0e22..6418343c1 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -96,6 +96,8 @@ public: void stealFocus(QWidget* focus); void releaseFocus(QWidget* focus); + QList> listCameras() const; + mRumble* rumble(); mRotationSource* rotationSource(); mImageSource* imageSource() { return &m_image; } @@ -122,6 +124,8 @@ public slots: void loadCamImage(const QString& path); void setCamImage(const QImage& image); + void setCamera(const QByteArray& id); + private slots: #ifdef BUILD_QT_MULTIMEDIA void prepareCamSettings(QCamera::Status); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 271c59652..1dbf92d35 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -180,12 +180,22 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC m_ui.cameraDriver->addItem(tr("None (Still Image)"), static_cast(InputController::CameraDriver::NONE)); if (cameraDriver.isNull() || cameraDriver.toInt() == static_cast(InputController::CameraDriver::NONE)) { m_ui.cameraDriver->setCurrentIndex(m_ui.cameraDriver->count() - 1); + m_ui.camera->setEnabled(false); } #ifdef BUILD_QT_MULTIMEDIA m_ui.cameraDriver->addItem(tr("Qt Multimedia"), static_cast(InputController::CameraDriver::QT_MULTIMEDIA)); if (!cameraDriver.isNull() && cameraDriver.toInt() == static_cast(InputController::CameraDriver::QT_MULTIMEDIA)) { m_ui.cameraDriver->setCurrentIndex(m_ui.cameraDriver->count() - 1); + m_ui.camera->setEnabled(true); + } + QList> cameras = inputController->listCameras(); + QByteArray currentCamera = m_controller->getQtOption("camera").toByteArray(); + for (const auto& camera : cameras) { + m_ui.camera->addItem(camera.second, camera.first); + if (camera.first == currentCamera) { + m_ui.camera->setCurrentIndex(m_ui.camera->count() - 1); + } } #endif @@ -442,6 +452,12 @@ void SettingsView::updateConfig() { emit cameraDriverChanged(); } + QVariant camera = m_ui.camera->itemData(m_ui.camera->currentIndex()); + if (camera != m_controller->getQtOption("camera")) { + m_controller->setQtOption("camera", camera); + emit cameraChanged(camera.toByteArray()); + } + QLocale language = m_ui.languages->itemData(m_ui.languages->currentIndex()).toLocale(); if (language != m_controller->getQtOption("language").toLocale() && !(language.bcp47Name() == QLocale::system().bcp47Name() && m_controller->getQtOption("language").isNull())) { m_controller->setQtOption("language", language.bcp47Name()); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 017b55693..b04d21805 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -39,6 +39,7 @@ signals: void audioDriverChanged(); void displayDriverChanged(); void cameraDriverChanged(); + void cameraChanged(const QByteArray&); void pathsChanged(); void languageChanged(); void libraryCleared(); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 41fb9a7de..792d4b4e8 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -1261,7 +1261,7 @@ - Game Boy model + Game Boy model: @@ -1297,7 +1297,7 @@ - Super Game Boy model + Super Game Boy model: @@ -1333,7 +1333,7 @@ - Game Boy Color model + Game Boy Color model: @@ -1672,6 +1672,26 @@ + + + + Camera: + + + + + + + false + + + + 0 + 0 + + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 7a8c97dfc..aef833f42 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -443,6 +443,7 @@ void Window::openSettingsWindow() { connect(settingsWindow, &SettingsView::displayDriverChanged, this, &Window::reloadDisplayDriver); connect(settingsWindow, &SettingsView::audioDriverChanged, this, &Window::reloadAudioDriver); connect(settingsWindow, &SettingsView::cameraDriverChanged, this, &Window::mustRestart); + connect(settingsWindow, &SettingsView::cameraChanged, &m_inputController, &InputController::setCamera); connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig); #ifdef USE_SQLITE3 From 51030d98fd01679834abf8d99812ac3e5fe0793e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 18:20:30 -0800 Subject: [PATCH 091/429] Qt: Fix camera on Windows --- src/platform/qt/InputController.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index b655e86d9..fd15333fd 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -806,9 +806,9 @@ void InputController::setCamera(const QByteArray& name) { needsRestart = m_camera->state() == QCamera::ActiveState; } m_camera = std::make_unique(name); - connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection); if (needsRestart) { setupCam(); } #endif -} \ No newline at end of file +} From d9fef21f92e7438c11ffc29cb1dc1f233d731f9c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 18:24:10 -0800 Subject: [PATCH 092/429] Qt: Fix camera on Windows part 2 --- src/platform/qt/InputController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index fd15333fd..9935626bc 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -740,7 +740,7 @@ void InputController::setupCam() { #ifdef BUILD_QT_MULTIMEDIA if (!m_camera) { m_camera = std::make_unique(); - connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings, Qt::QueuedConnection); } m_camera->setCaptureMode(QCamera::CaptureVideo); m_camera->setViewfinder(&m_videoDumper); From 5d129e26bf53c68261b217ac9b28950e148915c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 6 Mar 2019 00:22:00 -0800 Subject: [PATCH 093/429] Test: Add tests for unary operators --- src/debugger/test/lexer.c | 57 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/debugger/test/lexer.c b/src/debugger/test/lexer.c index 89e1024df..c9ba4e953 100644 --- a/src/debugger/test/lexer.c +++ b/src/debugger/test/lexer.c @@ -350,6 +350,58 @@ M_TEST_DEFINE(lexIdentifierGreaterOperator) { assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); } +M_TEST_DEFINE(lexNotOperator) { + LEX("!1"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_NOT); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); +} + +M_TEST_DEFINE(lexNotNotOperator) { + LEX("!!1"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_NOT); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 2)->uintValue, 1); +} + +M_TEST_DEFINE(lexNegateOperator) { + LEX("-1"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_NEGATE); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); +} + +M_TEST_DEFINE(lexFlipOperator) { + LEX("~1"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_FLIP); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); +} + +M_TEST_DEFINE(lexDereferenceOperator) { + LEX("*1"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_DEREFERENCE); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); +} + M_TEST_DEFINE(lexEqualsOperator) { LEX("1=="); @@ -814,6 +866,11 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexIdentifierLessOperator), cmocka_unit_test(lexGreaterOperator), cmocka_unit_test(lexIdentifierGreaterOperator), + cmocka_unit_test(lexNotOperator), + cmocka_unit_test(lexNotNotOperator), + cmocka_unit_test(lexNegateOperator), + cmocka_unit_test(lexFlipOperator), + cmocka_unit_test(lexDereferenceOperator), cmocka_unit_test(lexEqualsOperator), cmocka_unit_test(lexIdentifierEqualsOperator), cmocka_unit_test(lexNotEqualsOperator), From e0b1caf48c7f39585fa3d84b7dec18cbf351ca13 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 7 Mar 2019 18:52:22 -0800 Subject: [PATCH 094/429] Debugger: Make operator lexing a bit more generic --- src/debugger/parser.c | 105 ++++++++------------- src/debugger/test/lexer.c | 183 ------------------------------------- src/debugger/test/parser.c | 32 ++++++- 3 files changed, 69 insertions(+), 251 deletions(-) diff --git a/src/debugger/parser.c b/src/debugger/parser.c index 9d8db0262..41197b53e 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -21,7 +21,6 @@ enum LexState { LEX_EXPECT_HEX_FIRST, LEX_EXPECT_HEX, LEX_EXPECT_PREFIX, - LEX_EXPECT_OPERATOR, LEX_EXPECT_OPERATOR2, }; @@ -91,31 +90,6 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta } *state = LEX_ERROR; } - if (*state == LEX_ROOT || *state == LEX_ERROR) { - struct Token lvNext; - lvNext.type = TOKEN_OPERATOR_TYPE; - *state = LEX_ROOT; - switch (operator) { - case '-': - lvNext.operatorValue = OP_NEGATE; - break; - case '~': - lvNext.operatorValue = OP_FLIP; - break; - case '!': - lvNext.operatorValue = OP_NOT; - break; - case '*': - lvNext.operatorValue = OP_DEREFERENCE; - break; - default: - lvNext.type = TOKEN_ERROR_TYPE; - *state = LEX_ERROR; - return; - } - *LexVectorAppend(lv) = lvNext; - return; - } struct Token lvNext; lvNext.type = TOKEN_OPERATOR_TYPE; switch (operator) { @@ -155,6 +129,9 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta case '!': lvNext.operatorValue = OP_NOT; break; + case '~': + lvNext.operatorValue = OP_FLIP; + break; default: *state = LEX_ERROR; return; @@ -190,14 +167,14 @@ static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexS lvNext->uintValue = next; lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - *state = LEX_EXPECT_OPERATOR; + *state = LEX_ROOT; break; case ' ': case '\t': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_UINT_TYPE; lvNext->uintValue = next; - *state = LEX_EXPECT_OPERATOR; + *state = LEX_ROOT; break; default: *state = LEX_ERROR; @@ -264,21 +241,30 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co state = LEX_EXPECT_HEX_FIRST; next = 0; break; - case '%': - state = LEX_EXPECT_BINARY_FIRST; - next = 0; - break; case '(': state = LEX_ROOT; lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_OPEN_PAREN_TYPE; break; - case '!': + case '=': + case '+': case '-': - case '~': case '*': + case '/': + case '%': + case '&': + case '|': + case '^': + case '<': + case '>': + case '!': + case '~': _lexOperator(lv, token, &state); break; + case ')': + lvNext = LexVectorAppend(lv); + lvNext->type = TOKEN_CLOSE_PAREN_TYPE; + break; case ' ': case '\t': break; @@ -305,6 +291,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co case '<': case '>': case '!': + case '~': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_IDENTIFIER_TYPE; lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); @@ -316,14 +303,14 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - state = LEX_EXPECT_OPERATOR; + state = LEX_ROOT; break; case ' ': case '\t': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_IDENTIFIER_TYPE; lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); - state = LEX_EXPECT_OPERATOR; + state = LEX_ROOT; break; default: break; @@ -446,33 +433,6 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co break; } break; - case LEX_EXPECT_OPERATOR: - switch (token) { - case '=': - case '+': - case '-': - case '*': - case '/': - case '%': - case '&': - case '|': - case '^': - case '<': - case '>': - case '!': - _lexOperator(lv, token, &state); - break; - case ')': - lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_CLOSE_PAREN_TYPE; - break; - case ' ': - case '\t': - break; - default: - state = LEX_ERROR; - } - break; case LEX_ERROR: // This shouldn't be reached break; @@ -494,7 +454,6 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co lvNext->identifierValue = strndup(tokenStart, string - tokenStart); break; case LEX_ROOT: - case LEX_EXPECT_OPERATOR: case LEX_EXPECT_OPERATOR2: break; case LEX_EXPECT_BINARY_FIRST: @@ -568,9 +527,6 @@ static size_t _parseExpression(struct ParseTree* tree, struct LexVector* lv, siz tree->rhs = _parseTreeCreate(); tree->token.type = TOKEN_SEGMENT_TYPE; i = _parseExpression(tree->rhs, lv, i + 1, precedence, openParens); - if (tree->token.type == TOKEN_ERROR_TYPE) { - tree->token.type = TOKEN_ERROR_TYPE; - } break; case TOKEN_OPEN_PAREN_TYPE: ++*openParens; @@ -583,6 +539,21 @@ static size_t _parseExpression(struct ParseTree* tree, struct LexVector* lv, siz --*openParens; return i + 1; case TOKEN_OPERATOR_TYPE: + if (tree->token.type == TOKEN_ERROR_TYPE) { + switch (token->operatorValue) { + case OP_SUBTRACT: + token->operatorValue = OP_NEGATE; + break; + case OP_MULTIPLY: + token->operatorValue = OP_DEREFERENCE; + break; + case OP_NOT: + case OP_FLIP: + break; + default: + break; + } + } newPrecedence = _operatorPrecedence[token->operatorValue]; if (newPrecedence < precedence) { newTree = _parseTreeCreate(); diff --git a/src/debugger/test/lexer.c b/src/debugger/test/lexer.c index c9ba4e953..ef2f228e6 100644 --- a/src/debugger/test/lexer.c +++ b/src/debugger/test/lexer.c @@ -59,14 +59,6 @@ M_TEST_DEFINE(lexBinary) { assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 2); } -M_TEST_DEFINE(lexSigilBinary) { - LEX("%10"); - - assert_int_equal(LexVectorSize(lv), 1); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 2); -} - M_TEST_DEFINE(lexHex) { LEX("0x10"); @@ -111,13 +103,6 @@ M_TEST_DEFINE(lexTruncatedBinary) { assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); } -M_TEST_DEFINE(lexTruncatedSigilBinary) { - LEX("%"); - - assert_int_equal(LexVectorSize(lv), 1); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); -} - M_TEST_DEFINE(lexTruncatedSigilHex) { LEX("$"); @@ -372,16 +357,6 @@ M_TEST_DEFINE(lexNotNotOperator) { assert_int_equal(LexVectorGetPointer(lv, 2)->uintValue, 1); } -M_TEST_DEFINE(lexNegateOperator) { - LEX("-1"); - - assert_int_equal(LexVectorSize(lv), 2); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_NEGATE); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); -} - M_TEST_DEFINE(lexFlipOperator) { LEX("~1"); @@ -392,16 +367,6 @@ M_TEST_DEFINE(lexFlipOperator) { assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); } -M_TEST_DEFINE(lexDereferenceOperator) { - LEX("*1"); - - assert_int_equal(LexVectorSize(lv), 2); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->operatorValue, OP_DEREFERENCE); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->uintValue, 1); -} - M_TEST_DEFINE(lexEqualsOperator) { LEX("1=="); @@ -562,138 +527,6 @@ M_TEST_DEFINE(lexIdentifierShiftROperator) { assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_R); } -M_TEST_DEFINE(lexEqualsInvalidOperator) { - LEX("1=|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierEqualsInvalidOperator) { - LEX("x=|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexNotInvalidOperator) { - LEX("1!|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierNotInvalidOperator) { - LEX("x!|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexLessInvalidOperator) { - LEX("1<|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierLessInvalidOperator) { - LEX("x<|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexGreaterInvalidOperator) { - LEX("1>|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierGreaterInvalidOperator) { - LEX("x>|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexAndInvalidOperator) { - LEX("1&|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierAndInvalidOperator) { - LEX("x&|"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexOrInvalidOperator) { - LEX("1|>"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - -M_TEST_DEFINE(lexIdentifierOrInvalidOperator) { - LEX("x|>"); - - assert_int_equal(LexVectorSize(lv), 3); - assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); - assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); - assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); - assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); - assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); -} - M_TEST_DEFINE(lexSimpleExpression) { LEX("1+1"); @@ -834,7 +667,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexInt), cmocka_unit_test(lexDecimal), cmocka_unit_test(lexBinary), - cmocka_unit_test(lexSigilBinary), cmocka_unit_test(lexHex), cmocka_unit_test(lexSigilHex), cmocka_unit_test(lexSigilSegmentHex), @@ -844,7 +676,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexTruncatedHex), cmocka_unit_test(lexTruncatedSigilHex), cmocka_unit_test(lexTruncatedBinary), - cmocka_unit_test(lexTruncatedSigilBinary), cmocka_unit_test(lexIdentifier), cmocka_unit_test(lexAddOperator), cmocka_unit_test(lexIdentifierAddOperator), @@ -868,9 +699,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexIdentifierGreaterOperator), cmocka_unit_test(lexNotOperator), cmocka_unit_test(lexNotNotOperator), - cmocka_unit_test(lexNegateOperator), cmocka_unit_test(lexFlipOperator), - cmocka_unit_test(lexDereferenceOperator), cmocka_unit_test(lexEqualsOperator), cmocka_unit_test(lexIdentifierEqualsOperator), cmocka_unit_test(lexNotEqualsOperator), @@ -887,18 +716,6 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexIdentifierShiftLOperator), cmocka_unit_test(lexShiftROperator), cmocka_unit_test(lexIdentifierShiftROperator), - cmocka_unit_test(lexEqualsInvalidOperator), - cmocka_unit_test(lexIdentifierEqualsInvalidOperator), - cmocka_unit_test(lexNotInvalidOperator), - cmocka_unit_test(lexIdentifierNotInvalidOperator), - cmocka_unit_test(lexLessInvalidOperator), - cmocka_unit_test(lexIdentifierLessInvalidOperator), - cmocka_unit_test(lexGreaterInvalidOperator), - cmocka_unit_test(lexIdentifierGreaterInvalidOperator), - cmocka_unit_test(lexAndInvalidOperator), - cmocka_unit_test(lexIdentifierAndInvalidOperator), - cmocka_unit_test(lexOrInvalidOperator), - cmocka_unit_test(lexIdentifierOrInvalidOperator), cmocka_unit_test(lexSimpleExpression), cmocka_unit_test(lexOpenParen), cmocka_unit_test(lexCloseParen), diff --git a/src/debugger/test/parser.c b/src/debugger/test/parser.c index 412fc65c9..a2635f4fb 100644 --- a/src/debugger/test/parser.c +++ b/src/debugger/test/parser.c @@ -56,6 +56,12 @@ M_TEST_DEFINE(parseLexError) { assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); } +M_TEST_DEFINE(parseError) { + PARSE("1 2"); + + assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); +} + M_TEST_DEFINE(parseSimpleExpression) { PARSE("1+2"); @@ -108,11 +114,35 @@ M_TEST_DEFINE(parseParentheticalAddMultplyExpression) { assert_int_equal(tree->rhs->token.uintValue, 3); } +M_TEST_DEFINE(parseIsolatedOperator) { + PARSE("+"); + + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->lhs->token.type, TOKEN_ERROR_TYPE); + assert_int_equal(tree->rhs->token.type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(parseUnaryChainedOperator) { + PARSE("1+*2"); + + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_ADD); + assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->token.uintValue, 1); + assert_int_equal(tree->rhs->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->rhs->token.operatorValue, OP_DEREFERENCE); + assert_int_equal(tree->rhs->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->rhs->token.uintValue, 2); +} + M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Parser, cmocka_unit_test(parseEmpty), cmocka_unit_test(parseInt), cmocka_unit_test(parseLexError), + cmocka_unit_test(parseError), cmocka_unit_test(parseSimpleExpression), cmocka_unit_test(parseAddMultplyExpression), cmocka_unit_test(parseParentheticalExpression), - cmocka_unit_test(parseParentheticalAddMultplyExpression)) + cmocka_unit_test(parseParentheticalAddMultplyExpression), + cmocka_unit_test(parseIsolatedOperator), + cmocka_unit_test(parseUnaryChainedOperator)) From 348c1fd74148b8c117765637e11c3180ed1c262c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 7 Mar 2019 18:53:41 -0800 Subject: [PATCH 095/429] Debugger: Fix nargs-style argument passing --- src/debugger/cli-debugger.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index e77e317ce..5c133325f 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -746,10 +746,11 @@ static int _tryCommands(struct CLIDebugger* debugger, struct CLIDebuggerCommandS if (commands[i].format[arg] == '+') { dvNext = _parseArg(debugger, args, adjusted, lastArg); - --args; + --arg; } else { nextArgMandatory = isupper(commands[i].format[arg]) || (commands[i].format[arg] == '*'); dvNext = _parseArg(debugger, args, adjusted, commands[i].format[arg]); + lastArg = commands[i].format[arg]; } args += adjusted; From 4aff3016384eb379c580d1276b616d1d2ec60a7b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 7 Mar 2019 18:54:18 -0800 Subject: [PATCH 096/429] Debugger: Print now chains arguments into a single expression --- src/debugger/cli-debugger.c | 121 ++++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 40 deletions(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 5c133325f..1cdfc20e8 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -28,6 +28,8 @@ const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share const char* ERROR_OVERFLOW = "Arguments overflow"; const char* ERROR_INVALID_ARGS = "Invalid arguments"; +static struct ParseTree* _parseTree(const char** string); + #if !defined(NDEBUG) && !defined(_WIN32) static void _breakInto(struct CLIDebugger*, struct CLIDebugVector*); #endif @@ -84,12 +86,12 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "listw", _listWatchpoints, "", "List watchpoints" }, { "n", _next, "", "Execute next instruction" }, { "next", _next, "", "Execute next instruction" }, - { "p", _print, "I", "Print a value" }, - { "p/t", _printBin, "I", "Print a value as binary" }, - { "p/x", _printHex, "I", "Print a value as hexadecimal" }, - { "print", _print, "I", "Print a value" }, - { "print/t", _printBin, "I", "Print a value as binary" }, - { "print/x", _printHex, "I", "Print a value as hexadecimal" }, + { "p", _print, "S+", "Print a value" }, + { "p/t", _printBin, "S+", "Print a value as binary" }, + { "p/x", _printHex, "S+", "Print a value as hexadecimal" }, + { "print", _print, "S+", "Print a value" }, + { "print/t", _printBin, "S+", "Print a value as binary" }, + { "print/x", _printHex, "S+", "Print a value as hexadecimal" }, { "q", _quit, "", "Quit the emulator" }, { "quit", _quit, "", "Quit the emulator" }, { "reset", _reset, "", "Reset the emulation" }, @@ -158,33 +160,72 @@ static void _disassemble(struct CLIDebugger* debugger, struct CLIDebugVector* dv debugger->system->disassemble(debugger->system, dv); } -static void _print(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { - for (; dv; dv = dv->next) { - if (dv->segmentValue >= 0) { - debugger->backend->printf(debugger->backend, " $%02X:%04X", dv->segmentValue, dv->intValue); - continue; - } - debugger->backend->printf(debugger->backend, " %u", dv->intValue); +static bool _parseExpression(struct mDebugger* debugger, struct CLIDebugVector* dv, int32_t* intValue, int* segmentValue) { + size_t args = 0; + struct CLIDebugVector* accum; + for (accum = dv; accum; accum = accum->next) { + ++args; + } + const char** arglist = malloc(sizeof(const char*) * (args + 1)); + args = 0; + for (accum = dv; accum; accum = accum->next) { + arglist[args] = accum->charValue; + ++args; + } + arglist[args] = NULL; + struct ParseTree* tree = _parseTree(arglist); + free(arglist); + + if (!tree) { + return false; + } + if (!mDebuggerEvaluateParseTree(debugger, tree, intValue, segmentValue)) { + parseFree(tree); + free(tree); + return false; + } + parseFree(tree); + free(tree); + return true; +} + +static void _print(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { + int32_t intValue = 0; + int segmentValue = -1; + if (!_parseExpression(&debugger->d, dv, &intValue, &segmentValue)) { + debugger->backend->printf(debugger->backend, "Parse error\n"); + return; + } + if (segmentValue >= 0) { + debugger->backend->printf(debugger->backend, " $%02X:%04X\n", segmentValue, intValue); + } else { + debugger->backend->printf(debugger->backend, " %u\n", intValue); } - debugger->backend->printf(debugger->backend, "\n"); } static void _printBin(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { - for (; dv; dv = dv->next) { - debugger->backend->printf(debugger->backend, " 0b"); - int i = 32; - while (i--) { - debugger->backend->printf(debugger->backend, "%u", (dv->intValue >> i) & 1); - } + int32_t intValue = 0; + int segmentValue = -1; + if (!_parseExpression(&debugger->d, dv, &intValue, &segmentValue)) { + debugger->backend->printf(debugger->backend, "Parse error\n"); + return; + } + debugger->backend->printf(debugger->backend, " 0b"); + int i = 32; + while (i--) { + debugger->backend->printf(debugger->backend, "%u", (intValue >> i) & 1); } debugger->backend->printf(debugger->backend, "\n"); } static void _printHex(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { - for (; dv; dv = dv->next) { - debugger->backend->printf(debugger->backend, " 0x%08X", dv->intValue); + int32_t intValue = 0; + int segmentValue = -1; + if (!_parseExpression(&debugger->d, dv, &intValue, &segmentValue)) { + debugger->backend->printf(debugger->backend, "Parse error\n"); + return; } - debugger->backend->printf(debugger->backend, "\n"); + debugger->backend->printf(debugger->backend, " 0x%08X\n", intValue); } static void _printHelp(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { @@ -460,31 +501,31 @@ static void _source(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { } #endif -static struct ParseTree* _parseTree(const char* string) { +static struct ParseTree* _parseTree(const char** string) { struct LexVector lv; bool error = false; LexVectorInit(&lv, 0); - size_t length = strlen(string); - size_t adjusted = lexExpression(&lv, string, length, NULL); - struct ParseTree* tree = malloc(sizeof(*tree)); - if (!adjusted) { - error = true; - } else { - parseLexedExpression(tree, &lv); - - if (adjusted > length) { + size_t i; + for (i = 0; string[i]; ++i) { + size_t length = strlen(string[i]); + size_t adjusted = lexExpression(&lv, string[i], length, NULL); + if (!adjusted || adjusted > length) { error = true; - } else { - length -= adjusted; - string += adjusted; } } + struct ParseTree* tree = NULL; + if (!error) { + tree = malloc(sizeof(*tree)); + parseLexedExpression(tree, &lv); + } lexFree(&lv); LexVectorClear(&lv); LexVectorDeinit(&lv); if (error) { - parseFree(tree); - free(tree); + if (tree) { + parseFree(tree); + free(tree); + } return NULL; } else { return tree; @@ -502,7 +543,7 @@ static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* .type = BREAKPOINT_HARDWARE }; if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { - struct ParseTree* tree = _parseTree(dv->next->charValue); + struct ParseTree* tree = _parseTree((const char*[]) { dv->next->charValue, NULL }); if (tree) { breakpoint.condition = tree; } else { @@ -528,7 +569,7 @@ static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* .type = type }; if (dv->next && dv->next->type == CLIDV_CHAR_TYPE) { - struct ParseTree* tree = _parseTree(dv->next->charValue); + struct ParseTree* tree = _parseTree((const char*[]) { dv->next->charValue, NULL }); if (tree) { watchpoint.condition = tree; } else { From 0425fa805c464ed8bae501039738ab051b0d0b39 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 8 Mar 2019 09:55:51 -0800 Subject: [PATCH 097/429] Core: Add keysRead callback --- CHANGES | 1 + include/mgba/core/interface.h | 1 + src/gb/io.c | 9 +++++++++ src/gba/io.c | 9 +++++++++ 4 files changed, 20 insertions(+) diff --git a/CHANGES b/CHANGES index 52b42650c..eb0a4e69d 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Misc: - LR35902: Support PC-relative opcode decoding - Qt: Improve camera initialization - Qt: Support switching webcams + - Core: Add keysRead callback 0.7.1: (2019-02-24) Bugfixes: diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 0581c0bf2..2e9ff63a7 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -86,6 +86,7 @@ struct mCoreCallbacks { void (*videoFrameEnded)(void* context); void (*coreCrashed)(void* context); void (*sleep)(void* context); + void (*keysRead)(void* context); }; DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks); diff --git a/src/gb/io.c b/src/gb/io.c index 84b3a35bc..beecce12a 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -576,6 +576,15 @@ static uint8_t _readKeysFiltered(struct GB* gb) { uint8_t GBIORead(struct GB* gb, unsigned address) { switch (address) { case REG_JOYP: + { + size_t c; + for (c = 0; c < mCoreCallbacksListSize(&gb->coreCallbacks); ++c) { + struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gb->coreCallbacks, c); + if (callbacks->keysRead) { + callbacks->keysRead(callbacks->context); + } + } + } return _readKeysFiltered(gb); case REG_IE: return gb->memory.ie; diff --git a/src/gba/io.c b/src/gba/io.c index 68c77c8d5..2946e6ab7 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -725,6 +725,15 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { break; case REG_KEYINPUT: + { + size_t c; + for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) { + struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c); + if (callbacks->keysRead) { + callbacks->keysRead(callbacks->context); + } + } + } if (gba->rr && gba->rr->isPlaying(gba->rr)) { return 0x3FF ^ gba->rr->queryInput(gba->rr); } else { From c6556260955cb92d5f42e95d248e91c44515a915 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 11:27:52 -0800 Subject: [PATCH 098/429] GBA Video: Fix scanline cache with scale factor change edge cases --- CHANGES | 1 + src/gba/renderers/video-software.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index eb0a4e69d..80b70b01c 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Emulation fixes: - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) + - GBA Video: Fix scanline cache with scale factor change edge cases Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index f31239d09..6c4853bab 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -539,6 +539,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render dirty = true; } + if (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt) != 0) { + if (softwareRenderer->cache[y].scale[0][0] != softwareRenderer->bg[2].sx || + softwareRenderer->cache[y].scale[0][1] != softwareRenderer->bg[2].sy || + softwareRenderer->cache[y].scale[1][0] != softwareRenderer->bg[3].sx || + softwareRenderer->cache[y].scale[1][1] != softwareRenderer->bg[3].sy) { + dirty = true; + } + } softwareRenderer->cache[y].scale[0][0] = softwareRenderer->bg[2].sx; softwareRenderer->cache[y].scale[0][1] = softwareRenderer->bg[2].sy; softwareRenderer->cache[y].scale[1][0] = softwareRenderer->bg[3].sx; From a04cb97653efc918e4879771c6ae06000200b43c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 11:31:38 -0800 Subject: [PATCH 099/429] GBA DMA: Fix DMA0-2 lengths (fixes #1344) --- CHANGES | 1 + src/gba/io.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 80b70b01c..3cbbde329 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Emulation fixes: - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - GBA Video: Fix scanline cache with scale factor change edge cases + - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gba/io.c b/src/gba/io.c index 2946e6ab7..c5a5a7c71 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -461,19 +461,19 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case REG_DMA0CNT_LO: - GBADMAWriteCNT_LO(gba, 0, value); + GBADMAWriteCNT_LO(gba, 0, value & 0x3FFF); break; case REG_DMA0CNT_HI: value = GBADMAWriteCNT_HI(gba, 0, value); break; case REG_DMA1CNT_LO: - GBADMAWriteCNT_LO(gba, 1, value); + GBADMAWriteCNT_LO(gba, 1, value & 0x3FFF); break; case REG_DMA1CNT_HI: value = GBADMAWriteCNT_HI(gba, 1, value); break; case REG_DMA2CNT_LO: - GBADMAWriteCNT_LO(gba, 2, value); + GBADMAWriteCNT_LO(gba, 2, value & 0x3FFF); break; case REG_DMA2CNT_HI: value = GBADMAWriteCNT_HI(gba, 2, value); From 837f952230ae3a83bdbfa4f3d459ba0841622daf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 12:01:00 -0800 Subject: [PATCH 100/429] Python: Add support for keysRead core callback --- src/platform/python/core.c | 1 + src/platform/python/core.h | 1 + src/platform/python/mgba/core.py | 11 +++++++++++ 3 files changed, 13 insertions(+) diff --git a/src/platform/python/core.c b/src/platform/python/core.c index dccd393d7..6d7c1c855 100644 --- a/src/platform/python/core.c +++ b/src/platform/python/core.c @@ -13,6 +13,7 @@ struct mCoreCallbacks* mCorePythonCallbackCreate(void* pyobj) { callbacks->videoFrameEnded = _mCorePythonCallbacksVideoFrameEnded; callbacks->coreCrashed = _mCorePythonCallbacksCoreCrashed; callbacks->sleep = _mCorePythonCallbacksSleep; + callbacks->keysRead = _mCorePythonCallbacksKeysRead; callbacks->context = pyobj; return callbacks; diff --git a/src/platform/python/core.h b/src/platform/python/core.h index ed4790917..5e6f23be0 100644 --- a/src/platform/python/core.h +++ b/src/platform/python/core.h @@ -13,3 +13,4 @@ PYEXPORT void _mCorePythonCallbacksVideoFrameStarted(void* user); PYEXPORT void _mCorePythonCallbacksVideoFrameEnded(void* user); PYEXPORT void _mCorePythonCallbacksCoreCrashed(void* user); PYEXPORT void _mCorePythonCallbacksSleep(void* user); +PYEXPORT void _mCorePythonCallbacksKeysRead(void* user); diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 589ef0cb3..8987f8d42 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -79,6 +79,12 @@ def _mCorePythonCallbacksSleep(user): # pylint: disable=invalid-name context._sleep() +@ffi.def_extern() +def _mCorePythonCallbacksKeysRead(user): # pylint: disable=invalid-name + context = ffi.from_handle(user) + context._keys_read() + + class CoreCallbacks(object): def __init__(self): self._handle = ffi.new_handle(self) @@ -86,6 +92,7 @@ class CoreCallbacks(object): self.video_frame_ended = [] self.core_crashed = [] self.sleep = [] + self.keys_read = [] self.context = lib.mCorePythonCallbackCreate(self._handle) def _video_frame_started(self): @@ -104,6 +111,10 @@ class CoreCallbacks(object): for callback in self.sleep: callback() + def _keys_read(self): + for callback in self.keys_read: + callback() + class Core(object): if hasattr(lib, 'PLATFORM_GBA'): From 57ad372c782ef6ccd8cb776dca35d20a7076d006 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 12:44:11 -0800 Subject: [PATCH 101/429] GB Video: Fix window y changing mid-window (fixes #1345) --- CHANGES | 1 + cinema/gb/window/ccmmr-hud/baseline_0000.png | Bin 0 -> 3979 bytes cinema/gb/window/ccmmr-hud/baseline_0001.png | Bin 0 -> 3979 bytes cinema/gb/window/ccmmr-hud/baseline_0002.png | Bin 0 -> 3979 bytes cinema/gb/window/ccmmr-hud/baseline_0003.png | Bin 0 -> 3994 bytes cinema/gb/window/ccmmr-hud/baseline_0004.png | Bin 0 -> 3994 bytes cinema/gb/window/ccmmr-hud/baseline_0005.png | Bin 0 -> 3999 bytes cinema/gb/window/ccmmr-hud/test.mvl | Bin 0 -> 23971 bytes src/gb/renderers/software.c | 15 +++++++++------ 9 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0000.png create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0001.png create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0002.png create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0003.png create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0004.png create mode 100644 cinema/gb/window/ccmmr-hud/baseline_0005.png create mode 100644 cinema/gb/window/ccmmr-hud/test.mvl diff --git a/CHANGES b/CHANGES index 3cbbde329..4a5e142d7 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Emulation fixes: - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - GBA Video: Fix scanline cache with scale factor change edge cases - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) + - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/cinema/gb/window/ccmmr-hud/baseline_0000.png b/cinema/gb/window/ccmmr-hud/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..75fc1974e22c3db866a1af0fef9f3cb04ff72ae6 GIT binary patch literal 3979 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/ccmmr-hud/test.mvl b/cinema/gb/window/ccmmr-hud/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..ced08c1d93039c8a4ba2c102fd1258954ba11c3c GIT binary patch literal 23971 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 Obn0mAKVACA<^KRlq_80X literal 0 HcmV?d00001 diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 4b1517ae0..169dadf74 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -220,15 +220,15 @@ static void GBVideoSoftwareRendererDeinit(struct GBVideoRenderer* renderer) { UNUSED(softwareRenderer); } -static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* renderer, bool before, bool after) { - if (renderer->lastY >= GB_VIDEO_VERTICAL_PIXELS || after == before) { +static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* renderer, bool before, bool after, uint8_t oldWy) { + if (renderer->lastY >= GB_VIDEO_VERTICAL_PIXELS || !(after || before)) { return; } if (renderer->lastY >= renderer->wy) { if (!after) { renderer->currentWy -= renderer->lastY; renderer->hasWindow = true; - } else { + } else if (!before) { if (!renderer->hasWindow) { if (renderer->lastY > renderer->wy) { renderer->currentWy = GB_VIDEO_VERTICAL_PIXELS; @@ -241,6 +241,8 @@ static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* } else { renderer->currentWy += renderer->lastY; } + } else if (renderer->wy != oldWy) { + renderer->currentWy += oldWy - renderer->wy; } } } @@ -251,10 +253,11 @@ static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* GBVideoCacheWriteVideoRegister(renderer->cache, address, value); } bool wasWindow = _inWindow(softwareRenderer); + uint8_t wy = softwareRenderer->wy; switch (address) { case REG_LCDC: softwareRenderer->lcdc = value; - GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer)); + GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer), wy); break; case REG_SCY: softwareRenderer->scy = value; @@ -264,11 +267,11 @@ static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* break; case REG_WY: softwareRenderer->wy = value; - GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer)); + GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer), wy); break; case REG_WX: softwareRenderer->wx = value; - GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer)); + GBVideoSoftwareRendererUpdateWindow(softwareRenderer, wasWindow, _inWindow(softwareRenderer), wy); break; case REG_BGP: softwareRenderer->lookup[0] = value & 3; From c85d0b10967be088c101e85efda29b72730110d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 14:11:55 -0800 Subject: [PATCH 102/429] GB Video: Fix more window edge cases (fixes #1346) --- CHANGES | 1 + cinema/gb/window/rfs-hud/baseline_0000.png | Bin 0 -> 3380 bytes cinema/gb/window/rfs-hud/baseline_0001.png | Bin 0 -> 3380 bytes cinema/gb/window/rfs-hud/baseline_0002.png | Bin 0 -> 3587 bytes cinema/gb/window/rfs-hud/baseline_0003.png | Bin 0 -> 3587 bytes cinema/gb/window/rfs-hud/baseline_0004.png | Bin 0 -> 3587 bytes cinema/gb/window/rfs-hud/baseline_0005.png | Bin 0 -> 3587 bytes cinema/gb/window/rfs-hud/baseline_0006.png | Bin 0 -> 3669 bytes cinema/gb/window/rfs-hud/baseline_0007.png | Bin 0 -> 3669 bytes cinema/gb/window/rfs-hud/baseline_0008.png | Bin 0 -> 3669 bytes cinema/gb/window/rfs-hud/baseline_0009.png | Bin 0 -> 3669 bytes cinema/gb/window/rfs-hud/baseline_0010.png | Bin 0 -> 3779 bytes cinema/gb/window/rfs-hud/baseline_0011.png | Bin 0 -> 3779 bytes cinema/gb/window/rfs-hud/baseline_0012.png | Bin 0 -> 3779 bytes cinema/gb/window/rfs-hud/baseline_0013.png | Bin 0 -> 3779 bytes cinema/gb/window/rfs-hud/baseline_0014.png | Bin 0 -> 3781 bytes cinema/gb/window/rfs-hud/test.mvl | Bin 0 -> 93492 bytes src/gb/renderers/software.c | 18 +++++++++--------- 18 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 cinema/gb/window/rfs-hud/baseline_0000.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0001.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0002.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0003.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0004.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0005.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0006.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0007.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0008.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0009.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0010.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0011.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0012.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0013.png create mode 100644 cinema/gb/window/rfs-hud/baseline_0014.png create mode 100644 cinema/gb/window/rfs-hud/test.mvl diff --git a/CHANGES b/CHANGES index 4a5e142d7..a8593d2cc 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ Emulation fixes: - GBA Video: Fix scanline cache with scale factor change edge cases - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) + - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/cinema/gb/window/rfs-hud/baseline_0000.png b/cinema/gb/window/rfs-hud/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..a4199c67a9b985b92e3774a6080b449214a3d548 GIT binary patch literal 3380 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0007.png b/cinema/gb/window/rfs-hud/baseline_0007.png new file mode 100644 index 0000000000000000000000000000000000000000..7489e9768fbf410d2bac85cb1e26a568e5ff2bb1 GIT binary patch literal 3669 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0008.png b/cinema/gb/window/rfs-hud/baseline_0008.png new file mode 100644 index 0000000000000000000000000000000000000000..7489e9768fbf410d2bac85cb1e26a568e5ff2bb1 GIT binary patch literal 3669 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0009.png b/cinema/gb/window/rfs-hud/baseline_0009.png new file mode 100644 index 0000000000000000000000000000000000000000..7489e9768fbf410d2bac85cb1e26a568e5ff2bb1 GIT binary patch literal 3669 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0010.png b/cinema/gb/window/rfs-hud/baseline_0010.png new file mode 100644 index 0000000000000000000000000000000000000000..3348062175dfb40f9b139a6ab275edaf5ef506d4 GIT binary patch literal 3779 zcmd6q`8(8K|Ht3R5XKTpl))%VwxmQd5>fVS+3wLNB(h}7HZvkyCE9FZ#+I>-r6gOU zQn<5bkS2RshA~;*<}<^4-1E8a`+xX;e>vBAo#%C4*Ylj~ydLMAbbDJ1xR9(6008jI zmS$H0fQQ=!W(0Y;?G2>1004+SxNLU8DY}4Os2Dwe_Fy-9gTLUrmT-T=3C}Up9Glq& z55wCtTGUPr>b*~~p{e~1BGuPZrMJKHKc3JUX*3|1J@K{54w}e@IOIBXcjS?CBb+@u zJG;jAr_IXmhh8$$(u|=`Q^%EJtem?JJ-sTV*r;(%KGReXdO9^9TWW}sz;MDHs6M-- zu0xAa*}jyd(ms!)d(Dd>7_H{$GZ+f$M};RWXcV`zfDV}dx|mtM8IPOF!WG!Xan_TU zyp{o_#9iq2RJ;Y=_$Wo}D)f4qN<$s#V_GVeV_6XjO0ihnl)?e#&Ii*R`^uQ>zp&m|v0-Duq{xJD}&OOEGUbH=UtyGO3Ne$&@C zL9Y0LlIhyYP6OfTYlb~2pTn19UbKrV;zA}V8n>w>xPFW4AWzMo5T%T=G~HVD|R?Ko8L=~v{@w|Ydxkuz7r{=ymiJQ+jq>iY){W* zVcwPeB|vBhE_mIB=SD{pqpwlqG+rG^M8~6r=+4FXYLjLn@9EcTXU3{WGxIZhhiEtq zrdGa&kDSM=xGT_DxfW2)QN=M@2pd?tZNz$W@xq0r330P6#`LznzP_@s(t+t`@po(a zmw%vc$$5(_JbE$8>ogi-dv`>886K!xunc#lnr2>vZl?UM?f6uKsr>MP9woODVD3OE zqQ5yo`Zvdu6i1s7zqGMQPn$3?zM^R|qoF^3GJ}RcDGfSKc2$(9n#$fAA0L1DQf}|0 zxr3DXb$VZ;brT>IW3@$cN_8ejb#X#Tupt^VE}@XUQpPB5_)D?`yW!_J_QwTm&RDMt z9f0}Qu>3uz64)07oye&I!vkJ+7_Bb}r_J-H$tIxwtU6EIar%}k8DBg|wj8s^31C_D zCuyPx>^L>U1iIC@zcTvF`_^k9D!WlZdLvn!%-MBG-9zI@z0az^I3mhsOcBKHRX=nl z&owwTkCL?%yJkNznrO`lY)3zO><84?S92)eqQs&NsK+sH%*kAB*6p=rUyNt91S#Wr=+|+SdxO$ANb#(^p$TaL|jTuW&bXgIDIjZR@ZS4mV3L0 zNOMA;u}Cbf+(QK!&qUltzpbO#np_kn(OJWudX2?AerIw6yew zJ9rsudj=tWbZG~=yXOh6Za^TBd}Z6!e*x)Bk3DHj;FN_9@F%h{-9BzH`*VllN{cxZ zf0_L$Y^3gcHe$+HB({ZrM(&@O7pzDRSC*kMvld&1_XiK)2ppfv!(0W5UK6kKH3e@R zAv}4(7NCjEDq+s=Pt;m@Wq9aLt|x>hV~=jp!f%?}?|DBe#dZY!%Zic8vs>T+5K)Hn z-JHouTd&~=evz3)!vi9qh0jKx#cTIk7$g(K+SaTsmmRmqMSOEW`TM}ZZhq;(7>B)h z;E+8T(Z!jVEf8|xr!o1!L5Up}pcPNU_r~r~F>gNaRFovKs{?E7tO5#W@>RN=+!ENY zGY43Z^SAb9;Rc*wz9S)-h>{`VrQxsy_B?lSDT9DL&Xd5|cSjbWWeQX9$HD(9Dpnah z1kO7XNbQE)f0eW4_jHITt@Gny)rHg32Sx6)THgLM*|3{4vUwSEYZ$pL)(skbuqAM| zw|e8drt40KPX7F90wpyn5>aQ)kA{%!weNoqzKKd!^X2-v0MVE0upKUVta>0qj374C zeV)4$%@te<2`XxKD_1<@y)TC#>!rmF~@PB5hT!L+lnA05oy4Cvn zt9OSE__EId^7ct|NzN^JOLP6^+8gn2yErx%vb(L1Wa(>i6a~sQD@{qT5fn-?`p)cy) zM=v^l#T`&K=X-buPbtGOFFOXgfj<4_+;I zb4pbEWP@LXT1lC&FSN~+wmi+|IolVuNf-_JD=Lk8Mi9Sun+3zxd~0ErQ`r!gol%LA zKT2O6%shqlsYFK_ebk!=CXwvmp=eu4w&ZyhtLm?>Fa$h;GW;W)(Sc^)v zw6C1V7Ydj{h`^N6rHF%=jwtCRmV%jD;)5M%=Xu@>MyT&93I_D6bZY(to6~-S$1Wxnj|gzn^*Lzz65jUM?0=>V=XbS6X5#|X^H)cS?f)NWk7yNla5W! zfkB3Ik~sao=V2-!?9n@f*y$DbHv>IB@&7SFTskTs;|`5lGSp-rJ2D0vYdjWil>E}d zi&ldEhdQG*J9`??gKETn+@)$J({(Se4WHH{I|YLd_X6`ow04a_K09y)qID~7U^^;l z#j)o;_O|Gz@O*g$k@7F&Hw6YZPg3ut#q33@&aA1t=1*8F)p^Hryf?n*WO3L~er8E{ z2f1jGne$6P^8p5wCtuf8wSP?@ku>j*cZcT++ z2YY%RPN}vm8SqNodfWGAg+-+DJJmz&sW&1cvkpZb4-?YMU`O`2 zrZ)};N|{Eq9aG>3T~BTvURk)D!;{6!N}u4hMul^MeUy_^hE=aN`t|<$kfk1ltxVBHURTjz^x?1_Nb76ku4TH^8%-#sM+* ziV-T;w5uvLW?za1{p+tNngFy+<+UbZ)wM+w?<+j5IvO3_W4iV*m2EImE%ZE*t?A^T z+Wz-Q6vUahr=Eph(=k;M&phk_t%y|SUKf*V-fi8#P{!UAZ12|lBCA3h_92vv7E z1z&Ka{Nic|j}mEGY{B*%pE3z+t`8!&H_Kv<%tZG&TVpU7%?EQ4hLO46lBVnxX43EB zcD<6_Crgc#1>fBC`?={vh+$B77t^wU08c7e*{1ic&OYiDFP<( zfAa=bNZUVBZ378dopbRpqSwfUD~9rcMgXYNvmBAnMwUGu0o)wfu$I0M>my3e8IIzo)gJaAq&cWVOQJ8+Xo_I7Dy|*J)xcAx6}OZHjkw5 ztglDM8b_wRYilc%ZpqB-o}3)`QCGh&2nzsTe*NUVw%&BJE7Cl8+@MxUFk$$+efhHh z2OBRZ`;c?Y<3{|nC@f$YO5$}sC0=emjt%=6ToRSf2r{w*Gm18o-V!8NZ%#QXnjpD` z{ziTP`UGWwdKe6-xyJ(pdIO!Z{|nv9U2?o?T^w=ybQCI=;hKOqTm-nr#|Mmc0tu&e n{_jI&W`Q^GW#9ilW4nj~2^@TuH}3X7f7Hw7wq_(#@5KKA;Kw@N literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0011.png b/cinema/gb/window/rfs-hud/baseline_0011.png new file mode 100644 index 0000000000000000000000000000000000000000..3348062175dfb40f9b139a6ab275edaf5ef506d4 GIT binary patch literal 3779 zcmd6q`8(8K|Ht3R5XKTpl))%VwxmQd5>fVS+3wLNB(h}7HZvkyCE9FZ#+I>-r6gOU zQn<5bkS2RshA~;*<}<^4-1E8a`+xX;e>vBAo#%C4*Ylj~ydLMAbbDJ1xR9(6008jI zmS$H0fQQ=!W(0Y;?G2>1004+SxNLU8DY}4Os2Dwe_Fy-9gTLUrmT-T=3C}Up9Glq& z55wCtTGUPr>b*~~p{e~1BGuPZrMJKHKc3JUX*3|1J@K{54w}e@IOIBXcjS?CBb+@u zJG;jAr_IXmhh8$$(u|=`Q^%EJtem?JJ-sTV*r;(%KGReXdO9^9TWW}sz;MDHs6M-- zu0xAa*}jyd(ms!)d(Dd>7_H{$GZ+f$M};RWXcV`zfDV}dx|mtM8IPOF!WG!Xan_TU zyp{o_#9iq2RJ;Y=_$Wo}D)f4qN<$s#V_GVeV_6XjO0ihnl)?e#&Ii*R`^uQ>zp&m|v0-Duq{xJD}&OOEGUbH=UtyGO3Ne$&@C zL9Y0LlIhyYP6OfTYlb~2pTn19UbKrV;zA}V8n>w>xPFW4AWzMo5T%T=G~HVD|R?Ko8L=~v{@w|Ydxkuz7r{=ymiJQ+jq>iY){W* zVcwPeB|vBhE_mIB=SD{pqpwlqG+rG^M8~6r=+4FXYLjLn@9EcTXU3{WGxIZhhiEtq zrdGa&kDSM=xGT_DxfW2)QN=M@2pd?tZNz$W@xq0r330P6#`LznzP_@s(t+t`@po(a zmw%vc$$5(_JbE$8>ogi-dv`>886K!xunc#lnr2>vZl?UM?f6uKsr>MP9woODVD3OE zqQ5yo`Zvdu6i1s7zqGMQPn$3?zM^R|qoF^3GJ}RcDGfSKc2$(9n#$fAA0L1DQf}|0 zxr3DXb$VZ;brT>IW3@$cN_8ejb#X#Tupt^VE}@XUQpPB5_)D?`yW!_J_QwTm&RDMt z9f0}Qu>3uz64)07oye&I!vkJ+7_Bb}r_J-H$tIxwtU6EIar%}k8DBg|wj8s^31C_D zCuyPx>^L>U1iIC@zcTvF`_^k9D!WlZdLvn!%-MBG-9zI@z0az^I3mhsOcBKHRX=nl z&owwTkCL?%yJkNznrO`lY)3zO><84?S92)eqQs&NsK+sH%*kAB*6p=rUyNt91S#Wr=+|+SdxO$ANb#(^p$TaL|jTuW&bXgIDIjZR@ZS4mV3L0 zNOMA;u}Cbf+(QK!&qUltzpbO#np_kn(OJWudX2?AerIw6yew zJ9rsudj=tWbZG~=yXOh6Za^TBd}Z6!e*x)Bk3DHj;FN_9@F%h{-9BzH`*VllN{cxZ zf0_L$Y^3gcHe$+HB({ZrM(&@O7pzDRSC*kMvld&1_XiK)2ppfv!(0W5UK6kKH3e@R zAv}4(7NCjEDq+s=Pt;m@Wq9aLt|x>hV~=jp!f%?}?|DBe#dZY!%Zic8vs>T+5K)Hn z-JHouTd&~=evz3)!vi9qh0jKx#cTIk7$g(K+SaTsmmRmqMSOEW`TM}ZZhq;(7>B)h z;E+8T(Z!jVEf8|xr!o1!L5Up}pcPNU_r~r~F>gNaRFovKs{?E7tO5#W@>RN=+!ENY zGY43Z^SAb9;Rc*wz9S)-h>{`VrQxsy_B?lSDT9DL&Xd5|cSjbWWeQX9$HD(9Dpnah z1kO7XNbQE)f0eW4_jHITt@Gny)rHg32Sx6)THgLM*|3{4vUwSEYZ$pL)(skbuqAM| zw|e8drt40KPX7F90wpyn5>aQ)kA{%!weNoqzKKd!^X2-v0MVE0upKUVta>0qj374C zeV)4$%@te<2`XxKD_1<@y)TC#>!rmF~@PB5hT!L+lnA05oy4Cvn zt9OSE__EId^7ct|NzN^JOLP6^+8gn2yErx%vb(L1Wa(>i6a~sQD@{qT5fn-?`p)cy) zM=v^l#T`&K=X-buPbtGOFFOXgfj<4_+;I zb4pbEWP@LXT1lC&FSN~+wmi+|IolVuNf-_JD=Lk8Mi9Sun+3zxd~0ErQ`r!gol%LA zKT2O6%shqlsYFK_ebk!=CXwvmp=eu4w&ZyhtLm?>Fa$h;GW;W)(Sc^)v zw6C1V7Ydj{h`^N6rHF%=jwtCRmV%jD;)5M%=Xu@>MyT&93I_D6bZY(to6~-S$1Wxnj|gzn^*Lzz65jUM?0=>V=XbS6X5#|X^H)cS?f)NWk7yNla5W! zfkB3Ik~sao=V2-!?9n@f*y$DbHv>IB@&7SFTskTs;|`5lGSp-rJ2D0vYdjWil>E}d zi&ldEhdQG*J9`??gKETn+@)$J({(Se4WHH{I|YLd_X6`ow04a_K09y)qID~7U^^;l z#j)o;_O|Gz@O*g$k@7F&Hw6YZPg3ut#q33@&aA1t=1*8F)p^Hryf?n*WO3L~er8E{ z2f1jGne$6P^8p5wCtuf8wSP?@ku>j*cZcT++ z2YY%RPN}vm8SqNodfWGAg+-+DJJmz&sW&1cvkpZb4-?YMU`O`2 zrZ)};N|{Eq9aG>3T~BTvURk)D!;{6!N}u4hMul^MeUy_^hE=aN`t|<$kfk1ltxVBHURTjz^x?1_Nb76ku4TH^8%-#sM+* ziV-T;w5uvLW?za1{p+tNngFy+<+UbZ)wM+w?<+j5IvO3_W4iV*m2EImE%ZE*t?A^T z+Wz-Q6vUahr=Eph(=k;M&phk_t%y|SUKf*V-fi8#P{!UAZ12|lBCA3h_92vv7E z1z&Ka{Nic|j}mEGY{B*%pE3z+t`8!&H_Kv<%tZG&TVpU7%?EQ4hLO46lBVnxX43EB zcD<6_Crgc#1>fBC`?={vh+$B77t^wU08c7e*{1ic&OYiDFP<( zfAa=bNZUVBZ378dopbRpqSwfUD~9rcMgXYNvmBAnMwUGu0o)wfu$I0M>my3e8IIzo)gJaAq&cWVOQJ8+Xo_I7Dy|*J)xcAx6}OZHjkw5 ztglDM8b_wRYilc%ZpqB-o}3)`QCGh&2nzsTe*NUVw%&BJE7Cl8+@MxUFk$$+efhHh z2OBRZ`;c?Y<3{|nC@f$YO5$}sC0=emjt%=6ToRSf2r{w*Gm18o-V!8NZ%#QXnjpD` z{ziTP`UGWwdKe6-xyJ(pdIO!Z{|nv9U2?o?T^w=ybQCI=;hKOqTm-nr#|Mmc0tu&e n{_jI&W`Q^GW#9ilW4nj~2^@TuH}3X7f7Hw7wq_(#@5KKA;Kw@N literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0012.png b/cinema/gb/window/rfs-hud/baseline_0012.png new file mode 100644 index 0000000000000000000000000000000000000000..3348062175dfb40f9b139a6ab275edaf5ef506d4 GIT binary patch literal 3779 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0013.png b/cinema/gb/window/rfs-hud/baseline_0013.png new file mode 100644 index 0000000000000000000000000000000000000000..3348062175dfb40f9b139a6ab275edaf5ef506d4 GIT binary patch literal 3779 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/rfs-hud/baseline_0014.png b/cinema/gb/window/rfs-hud/baseline_0014.png new file mode 100644 index 0000000000000000000000000000000000000000..7c444e0053b3f575fd9e96b6a9ac3534fa79ab4f GIT binary patch literal 3781 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

9rKZ@CD%u4?2uXWg*<3 zaC8!ZzaKAqxp53v%V1(|4p<{#EOd+h^-3OJ;6#471YhS zPuPT~i#nfu^xM-}FhYdVfQk?$zXldOo5zSZW8Dmzp+2OncdwyKG34hT`^<-vBQSVO?T9fPXTBm1s1m zbwbykyM<`?C$Bw53({^*Gb_fZzt?0tE9oc_%Vn3(zEBhCDhBEVoMs4KSK~zEPxRSN ziaO*&WkG@OB;W0F?YfQX2$FtMSK%@Relvf^C^ek@lJnQ=Iye#uj4ttga?McnuI_z9 z%|LZgO3MJ6nOCKgmYV)^A|EY-@MhqwCbi5Z%gNfe_(m0OLfqhbmdt`n{dtbl6!>Z1 zf-3|7HG6@Jf@i4LO~h@x;`*&kL0G}FZj%5d{yWB{cUM?egZ$x{k-T{p=qHi}vi2g9 z-67&oLAH1*cw;PfYPy?_+O>q3<4%G5MH z2k$MA87p3L>OPTxds9{QXRDQG;DiqXdtQ!P>%lz4Q)8meN~Zd51A&=cQkfbl&sW zdw}@l4?WG49)XCb&TI7!itbSfUzHAt&RiGYH~>@=jDMdpd3OFPx9>3E>iOC<{R`4| zZsX5YNgU&&_1M7h%(r{F~J*8$D=nGsQY3;X*86Tc~JPi0gZ zsau|w7V+&Pg}KPL=rTHEIAh>SLLwj9V>Q<`YWGUp$JfkB`#9c`e3HvA%t&{M$(o29l3E5<*gB#Og_Ct_12clRF*8%Ozps|TNo`UIOrk* zrnLE$mo@Vu!c1W69W1NA*3sa(G49^?F|!=@_xaD5HtgfSIOFaO&_CS2C>Pd{zt4Z% z7ay|zmU%YSf`$K~M3@}`pVj^~Gza@D(tiecg26mq!2dr#x;27fFC%mXP@t?J*O z@XxJ7+`qej?!kJ#*DAxy8CNZ{zmy@vS(Ic|;XBp#Bnla(q|6IW9<~f=4x!JVm2s7G zC@?Q#>BO+bN>J=bUy**K{Mh!x$@E99*KUN_ErvtNd%}4^KBt?Ar^eG%HLXR5KHX>w z7q@-$!n3tyUGC=ljF<|Ft+KeYvrM^5IY`H?n+mv8TaC1ZOnkb|b8Y;5?KWNCJEjw) z*X@j=N4>79Sue%?#46Lv=PAitLU0g%L5a4pz2 z{@L6Ab|*~OcRR~`RP<i-q4A_^GfwEg=$q9>GZ)ytV+`XlOIUfnG0~RuHQ_L+|7?5{T-*7hXx{~UFuyi*M6mrYe3mPghJODUK`XMCK}m%rr3hSZxt=fCcyT&IUXJ##?5Bd|}GkE;@gZlP+mQ=rrl z7~T~)1s2wSk_IC1W}Veo>OHu{-&fYn;U27u z->iSg0VR*XgsjlwpqA_~(;QIN2<)ZRXdKjE0@TN6mIuR3g=twu#zXnoVPJ`Mv0WHz zaWongj8XzdmkKkUBm4mA5AB%c+sj-3bSZ3D-aG}28v*93QBDDemI|lVP0A;y*5$`w zt~qB_H=)=3<(#??+94goC0GY`)c384kMJAmb7{;F%t<@Sd#^I9pzFr?Cw_OJ)P-9d zq&EDnH53%Qe;aqAgadoGDJ*wA9((c_vM%=ok$?#-Lg6m-si1NaFrOL-QV)#$LZ9XV z-sCYl1ZKQRO7$Ra@@Tk8N)9Ei5z^2yE}CEe;t1g!0E1$5U>LDSz<141qU|Se{8eMh z4^YPT(PU*K8Spp=UM8DAV|IijJ)q2K<$S$$?hwxp%0^pM-hqB4 z5>+v`c>1K#0Af#ocpOsh>xIbDh2@Z5}G4$@GP_4~7M z>^?2uj2VtkgSZd+iw7lRm8$7(X0xcXdpT zTQT;)oBtD%nXmQp47r+sfIa@q%cUGXNz9Dimg)YZN>-@`ol;bb0P)>6)M zZ~aAvBaw>(A7`|eiz69xl$wjfDb%zAZ8TrPsTghan}ky;+NeNIs+qWoB!}AGg!!D4 zF=uF{B93rY&$to}=z9-~G!7`HheaL-$Que0PAn7QXZrvPlG+!^6;u zwSo%YeZo&3H_0u_X>!-gbIFH6;M;E{P{QDcUI~ypF65GCwcXnyNPCtW+b35XQZE54 z7l*h=05imWa3;BVXY`e>=lN&WMXtFQCMvC&(>ok}$cjO+`*zMnpwN9gLP=1`;E7&6 zhf@jwWs=3A2$Z^S=UM~`+_!Tm(wDuKdw-aW1z`_<&<=&pDbJx5bC;Q^sktrF-RgX~ z{T=qhWNbO~=0>^BDy@cnjuC7ked3s-dn)3EG`Y4R;zc{Tb|BK~XRg6Bu_jsP#yhd5 zQ0K-!Q9-qo$W=$AzD-kqi+LiLYffsx&QAK3k6gu41MB1i(vnx`jULj{W5|sV($cI% z>ymFns(Jc*^E29|$M@!>WJ^e&c+c|Zs+xRDyzCRa?jjX%;vYCAYWsqA$#Xmgf=rnv z%j&bgN^u-no6q5ldJ?7KX0RyK*XkRodP2-*Fi{lX`^HX`sB=FrBnJA1Z);+MOPDB@|K> z?5#d1>Fv?+8v@@3{CM{Ob|P9rogk^e>}*#~Eot47gd92nrQ>R}6a5OiD+! z=Y}<@L=3&;3unpQ3qd0jXrs~jImH-fSQjb2?{{k@J|1^0Xks(+_P=OVL4Qvdk_+>WUJ zPt!~mOs~a|=B?AFO#5m$t}~qKe1UxyRI1UVj9Zyija5+C^NmNjlLXw+wEpSg+CgKW zN#p9KDp+Vc&MGNbvQ*$J?;6UQ1;R(mVgEp1owMROmCb%-$~nSvj9{^^D+#(qtCy{k zW_v)cE8!l-ItdE4yQ90^nKzuz-vT63Rx)EZWYVthz2mMf-Qj!vq8z zXn8d3CivSUSr2-8@aXSvzTerCD}{l%^=cP5)^Y+BceF!(-@chZ@d1#*!+3DAKpK{^ zm0o3$kREXGaM|+HkOw4C5+bSX5sg@hmx%X+35p4_;CQ&`FAfXum7u=p9$=!XPMNcw zOAjCIt9b7~*&zHd6zsHybFw2GesgtOqUh1SCQzN_Y^BWOF|{*QPKY_H;&NDFtP6s= z%vT@fPD-2XFU&CTc5UR2)+p-uCoRzcnYYH(fK#OAq~p_m5liR$j zQ{&?DB#|BaIEe|8CfZqBMmZ!73 zsQPpgC8~QLvZ?lyZjrAP*!OfBcv21ZyzI^b+fT#rw`qq@y<@6-mDLLJ86f_fXPmXV4PNRl)RQDG1*LE6cp6EuGlu!j=wp| z#<1|6m!DdV{`t*~-GXR`HJkr?v;GB#YTKqe6po2uJ+n&Mn~TU`B+W+py>Y-$rgxSP z7Y{I-Z)|N3Uz2S;D~Hva)017UtE>?mDZ2svl`ar+9d8PeOPT<4-Na{!6 zgYi1;@zrt-HuktP=i@q~>l$OOj)4do6&j*ONXs>78}wqftFJ{cCt9zxi~pl%_sY zPa1cK@8R$A-K#+(wdIyA(7Jb3<*xHlXvjNLa%B{NFp;H~^i?f?RO#}Lx4;Ph@10h_ zdD_v%?j>sft6G1E*Wt?Va_Q3(L#Adts$p(dfk1qXsEjP%m^V zvUh9JoJXK3I&~?<qtY-Fe^|#ZVX7m0BPQ}X%3p2C}u=G_}7D(HraC z9>ppU%x+Qh3#W;=_7?^JPG%G1ckOF}YY<-zIAN5IcLIas3G+Ee#w@)+eArhbGb1-v z;x|YDZ1>*Q^;X(k4dYOtOdBDr_3q4=MbfHE*}-(yJW|WpP>I(Lt$1$V(s_1&$+=v@ zn!Ap0)Sf8bgLIB#lF>&=MyYx2w=JuVQ2UCmU4S==Z>WMxYio8vXZaDepjI>iNHpqf z&asZzr$$I6i?`ZgDoO@r)F;v_Tzg((YZ=EocKenN+<&+}<*9x!>K)X5U3?)v9nBeX zA~;&SZeZ>u_NH$3#If~F26v+pN4J@I4*eBQTHnED>xO5uZiH9HQ3+yuPNB1T>j^O0 z;8jJ;%ZeBO9sa%y5ndGrN9(l2z6?#BZ-4z)7_iz0I*h-yh5!*L?E~fQ5&k;}-sl*v zI3Z}mfE&m<PJ=diVMqt}OMLjd9FsoL~P37_goPIE>@a@NA>tbpBsBeA_6Czft}> zSP9&_n)Xl@(LKb_-QoT_-XLbOo_dHyiD$;3X1;jFxkj-tMwWu;Pu7?{u&Gn_%fGCD zM*a%~#LpY4no}N&6hl{a5dg<==S22*uGvG? zMWIK*xcL|$`1Jiw_|@O>)oYNo#{Vkbo|VOxoiOgiR1K z-pglPWEfywFA_eh|1TiI|Cy6jO^7!VqY=9y);Koa1+gK<^N)Pgf4Q0bAKeI0!&8pG zOUjco8ete>d7*f@r`?Tze@^4Oqz)#dSot^Q*8j|tmEd`%0XTSUy)VO4WHo!xyC__- zZ>pXP4V@Ifp1~}QXDGNV&HwtZ;D7S|7ySQBFQSj4fX@I6AwV(&^_OfQr}dUk`{wOA z$>*n&wxhp8;R}Qll$<2|VgFD3GWaw6A)LDAu$f{YmtH;SC}lTgO+44LZi0nr~t1i(Ip6i^{*T8FNCaLR{DER5Znr z?sX(+&+@}S2w8t!su$t=qy`%%&H|Zt6qAF~)PE-UKViUH6>`x_5k_1UVi6!|O~trL zf7u+Ou<7~pF8%N2_(k!_0IRO!pUywde;iTMCFPxdQG}s{YYsdj26F0*J-+S*`Q7UD zg0TN}iMtTP4d4stOCDwQ>V=?Qe*bGlzDxdD6MVdII@ezmvdG~@n-I}JPSxj2vrZ`W zfcj6UF@MRBA-sAfXgK=hKem6)f6_SP3a4{;7C;G4Db0sMWCsbEcLen>ShfVUFZSr0 z>B8@X7sDq*|5QFxNdH&m(+A_Z@|kAm;!@a}_VoO;5B6mxq2H4l3LG}a=l2naSP07f z?<6e}UlPAZ_QRBxM)=$r%l59{C+dv6>cP}>{B&$`mDj6BRN<)U@RX18EMv8H{G+T^ z>U(>98A@qB=ls*w#uD3>hvBT#%m_;6bvLDW=mP-sxY}~7zUl>B8^?YnYVIWcZAadv zyg^+%e^h<;-JwbH@KOBscWhO7+0lsa*sxIC+kFyU4jmK5)Qfk+C?$c3Ve~ZuTeS## z+Q9rHDWhu5A7SHr1)DjWcnA1wB=f01B0=~^&s+VhkX`0+vRuFVEaEISwZ71ldjNzu zelxQAb6)wVoTUB0C`_PoZ%744*r*=!P4{mQ5}b-<96hE1h;`%Mws9P{V)`Kke0h&6 zsr%C+Af|&QbdpGr0PRzN`AnIQiU4z7$Z+qmYNAom$d^*JZnE~gc~)mZlIY%~_T##5 zLM3WRVoQpbq(1HKStQyw>~gbG?lqRN5#(O2H`3LNE%0u{Q1Z@sr}Th)tT_i^ zRNY`rKjn)HkK%8(0Q4(qulPA3Ol>?=sdo{#43B-*;;s&z<{VwulXcpfM(rb7!F${! zWkT5ebjYh`G}9or>C*M_=}E2{{pHGH4Z5&g=FsU%E-pT2e~zOT@v|~j1_n_GNM>tX z%Ic#!z4B`l-efpx^^X0UJArFAnX&jpc9%9jJ>@cW7c`1uh~SJnGktM}`{HqEz4`}w ztboJAOUKf)dred000}Xw%yK%)B$etFU2=L~{F$ zoR1m0P1Pr54KIyHIbB3v{KikQ%2riMHdZHo327L!dZ`h@$-iA>I=%~hwI~9kD0JvD zp{~uW!g<6KYh%9skZZ?`i7eMIt<>zHAlAf$nP_C!FI=w6SE;+aS|hhyUTvc6!9IZ22^CeM$#I#do%oTzOd+N7>K?z$rfX#}!w~b4*!Q24T zr}j_TV-LgZ?O@cf*Cih+b$=bg5DtpT6iBU)Jex{mXF(A~!2P_?GMdtpM^0y|C%vuZ z=Sk_b8fY9b+XUaV%r&=MVYt~)SPi7*Zc}CBObN#V58Hg@DdGWAV5S~Ias9fRA?Ge~ zZJBl3OXIDB#K^;uF!p@;B-Ga<56LkONBSp#`t)neTId$z3f`rh(HzXd7}UW6jdy?g z=2Vdb?{}jJEJP8zWGJSwYAv@b8(op$kT9OTP>O!f@A@R%B1~DBD3*`8BJH|m3bVU>^O{z10EvSPIEicZ0Q-AEFYGW|6Ig(?Tlxjbf#NL^x&?uEEr;N|>9xg;FSj zuGp4@MhKIR8#(W)(L!>o-z;fGj>WTg5|Xv zhd7}Vl+_@lF1M#yq*>k0v6xwaw|9g}K?%3H5@tgtokrTjQ9sUmvl3<;ZW!uWFm(M< zvQRt;7I}Ru6`)$`QL}8*NGG$ocs9}z=^O{TXUPl+m6c`hmxX&h1T-T*b@hl|$$rYe z^m|BpplMgpiz<&4&V|)NKW?!ZHxepS4xtX|552!6acdQc0CE5-VD-@DyN}gr(h;j) zImOyP>(_jgR>?>_)CE@%DyNVo)OyPlVNpe^$_vxW7!3BEF|NPEJrZzc(wT11txKyD$RH7FzsFIyzr3ojQ2v#7W1~{))qmd6h&AHcoj! zIoAG=xmW90>87ho8@2v5b_Cx7Uv)uu64J*K^-ylHk|6Mq`tXau@GwYDN2M{!MaEjF z@oM3dzs;wDiE$dD;p^h->E9EDljC&3LaQ64K;ySn*LF*Kn9a!B6fxmV_D#q~8j7q{ z4naDv9I*x@$?$#u-SG3%=?NT>R5k6Cr28J8A}x%;+Y}^sU{)-iB_Rw57D@#;#)OM7 z!~K!!Fk&{cI^w(v{}A?pnZ7;Gc}Y#K@qdc_t@`sP8NP#|1C}hFjs&JXmgq0Z2&6p< znu+M`iPHaH3z0cT)XJuW^GMkJ4bp#RrSt0bAJdaZbI5O2ot_aS*??4{zGhQfCeG%N zi|^qEsGDl&71?k{bRbbYz{&BYLBIc{=87Hwy|U6M3^_kcCdS(7yB30Z{Inh3{aCLf7gNgSL1on zpPN7}=Ijrs%!U;I40mzI$o<}8led#=$oa(l@*kzY8lOM^5j8Z?>FQx@`u~`F>#(T0 zc7L3bPy_^|LqI?T1O!C7MM6-KZjdek=@?2n1f;t~x|^Y-yM_>kMw($@h+$@aqwjg2 z^Td13b*}GUzke2=`(F3DW3A!Z*IsMy&kk0OLkoX3_|^S~Wz)~*VCC9XQZ}YPMg1fE zzW{ofl0Qtk5G2%~?O6T~c4&V^f3D(x@TVTKN;+?0wi5C*zzJVHPF9KtQy6EHF5G~PK0)Q*vE8r@l(lU@3+Crj^(;g9DwQ~CRc_M>zq4=v+Luv~-J#Fe_!`q*A*D56bSx-{y`PthXawGF{Dyj!7 z0TlMNFzt_bAJn$T4>Ayv1f5ZbcesQnh%;tgZ}s~ix>2XDv9PBGRFmNYKkMEaS*}NC zfz;@aydFXjz02WO;fI<}4fzb85SakL>I*@DH|~A9&l4gG*shnXPYIT>4y)e!tLz${1tcc9-WolBU_f^7(^tE4 z8`YjMuM*76*?h3gwSIL_6-00#ZRyKt*j8ks4BxqLus0k{6Ml22J!^QEy;1Fg;rjG! z)^S&)6csQ&OI#0RxkxLo8J;h1>?iIOkz@iE8EwgJr7mu~Vw~9LgXg!qqf$XJ{gSJo zi%>axwT?;jCg32l%1>x1p@KJY`rEA3S*V0jrH}5FoUb~+Mo;mu6Kj#~9UZM~(YWc2 z<0l6+V4dPaW83WD(DIVQ`q<`g!V}qLi31R%oG4Fd6!Z7@w}oYh;={}nd$lzc2`d{T z&qc~VNj)R2N&Yx5*+^h_w{X&y{f%HzFS%DJmBTV+vRTB!11!vIf7;Iz#SfP=gg?Sq z+4Q^yj|T2{E3O5T*x#xD6#T5GFw#j)B?6aOy2u47L+&D$U!Z(DvxVzU_u02r%8r?p zFViIr+_g!$M=0fwI!{%BFqs=hGqs|<=(l?!JXmv{AIHhn)xORVZ)-=|@UeDCRP>oI zTQ)`OFJ>|Noeq;AUKUkS@~7|%d_JT;R1bgqqFN*CeG$eh z=~{lVUQ2z_%5b@#7Y222U%XTQAUke>ZQ7C-7f;P0ZolA%eWzga= z(Z#s-7B&@le~cx4UHo;{=Jg$&K__va2M5M1b&e&~4-84~Xu}3^P0g!nw8it*wEcY> zKh|2rZ9;1s8mi;wzz#+o3?Lbs*LNS+=@$kkiA$HijY#z8x@v<-w1ZL2E@S8&_mY^c zU59QITPbJSi0lK3sE}*D@1{_yY|6-L1SS0?y#RfcyV)4I^6Ztw%;H{+lXH0L`^8&! z^59o<48|N%d2d$teeL(oh3QX2*yxsqYF@RU}c%s;q1>F z3@aHv*KD<5?)a)ttRM?-u+2()$8+~h#;uF#*v|!Q_mNx3!A5XgGNcthWg zTc8igj-{5Ihux0~P}^4s!tu!fskNT`NF_k8InSueWzhny(EV7BOuJ!nO}7d%?&v2p zJQ^o<;faTG%5Nc5CCuO{=*a%5=w!TrM5?`E@^K&l z)b8?4vl($4X$8zU(3@hPXs?OQVBnniMUuTKfzmWxcTdx;RT-5D?TyD(cKVIFB z=V(?1)4lQ?uc{4j+@Hd`bUU-kIT@OolCDTsUONyjEDX{YN?y={+_YhKq>kiX-7o2| z?kEOujim||8^8T_Ojil&Uz^G(wSYH&b-hzr?jC7ax!G8&Tqs=2`h-b$#I;P}NAnT# zhSQ`0D)Cu~QweXpAw&7r)!07LP00Z>F}JeS=rp7aZ?yH18qFy~o8{?H*V2!8J@!g` z;thDkVB_+k1Y}{*q%i<>Wt2^vZnT-CuwxY~cIK)m1*0UVB&c9!dO&&q>U&$pQ*HUB z_hphiY9ubWhJoz;hZmb3I8GU_#WX{j4U=2784TX_4P8*ex3E%rn^J)O!bGU-^mmLLFQO z+rV*Baf0~oD=Uyiz5Z-<<@L!4e;PBCR~&m~?Wun=7xu^&hKna|3Ma;P1R*a!hQ$lq z6dV5%2CSYXJ2tV_fQ;MDj|WN~6bJqd=oe%RH49`Y5&x_E6#PyOPm-4$@PT!ewnD{B z^3MFYl9?p!{J5%_B;NeEq8Z?R74UI1Lf=?YDBAaKRi&btB=P*XvKc_I3Mdkd5bQ*z zF&(5H#^W+Iy)P+^@U6Vnv`FX##dPosX}X2c_&_$}_6M7gCX&uiPkU!E^_NMS{IMIw z^q)L2(qnphBjazB!iv=O2f9(+*x$|DX()7vB{L#EIoDaQ#J=3G=|y9ZWw;~8We67} z62tFJ(j_ehGKBENJ%p3}N3$j$Bofol39ZCL_L-b;(uifZ~VY-Ar*ohB5qfk}mZykVz(4v~=SgJa|o8va6?bP4MFZe&3bbRgFYJ2D7WK zmAZQ_E(i7)-g*@COPDYiR}~m*-qAdu9ozVL01IyKk8q=yKgKw4ujyPNsB*XP_dSX6 zA@io}ToELM<>GSehY>n1he;n&6>Vj$Y|BFH$cxFlrxTkGNxQw^AExVvp<*^4elpyuwYX$EbaV zJ%Wt^mBLLq#vHkL+9`(5OH34G%`sGeO=-+9gaP&Szw*OPamA>8f<5Bpuak{gbkCTE zztavQ*Ss z_w%qN-(87H`MMQUg9#4Yi>kr54%`c?0p#_cHXY$16&9*(^~dXdoyCb)p#dl?_zxP8xj*r|tycvl7ApUc-%g(g>(bPp5&Oo- zG~06HTHBwe8kDWihHOuif{RzGGE3hrZGK%G_o@>`tDB zCI5Y)MYH&QWhr0B8W2PuxZuEF!E@`}2=}CM-d44Or*SD|zcCQjI@-bB>?is&)^WkN z`&`r?<%oUbE`>O*gMZ$4$Go}i52T$zF|>|1caY9V5@z*Z1YUzJWA9afiO)1JPzJA2 zv#^x)YZ~vEwQF5}0LBc;8%DKx9fW}*@#p|BUK&}(>Qq$XUB2)KW1!z~h;^!P#JPO6 zdUc9_0$k`|Z|be3g-lc4X5rrXUEJc-&t|_DT#B@uP)_?=Y`ja!rzp< zd&Y>3p!P@I`HYhEM{-R7uujGUZcqegs9R^g7$~s;bQ#!EJdGf!vGblS zk_@HQh1-hGWeZm{MpWCt0A7{cnRq?zI_}0QJH3j{fgKO6B#(Qm-gp~QkY!CB9eMXA z1`n;pj{K#~#JGtG22!9yG-RjMABjv`-q$YHF!xWz=OyFs)W6M}Y~i1Z!<+E5Qw29= zklGlxO^ak>h_8a~ug#6xeJuujV}0SiM6-W2&9c0|jCkJhUHR{kOBidLI0}-{J4)y8 zyVP9Xk9#5`zD=4^{@UTd#Fj1liip19^?OHqvq+5wzq+IWY0|v#-J#^6l&xT;ki@Wa^)_~s!Id=+#CeB?5bszlsNL?Q_--WlWOUvhukx1S6XA)RpxKp`yG+U zp6tx4wUT1VYcM0Cyh9CeSSI1Y9a0+GBWY6BuNHGG4jn7)hgs_?-?0sG-(ChfZaXT+ zEG55EiW$E-M8H>4`#-|^8ZT@w8op$g`5J-rbd&6qii+4uf#vRZAKzYfwTcTn59xmW zhyj%R)AC9}Zu)&{yQCU0y2!Kz8n&=;2Oq3A*)IF}oQw&lV|(D0d#B&qmwgE$JF1VG zO?X3fJL%-?{TZABPIY!8tgVlYREW!ho9HYzrhkAS4@p8zSuHkHszg-5%f#8r6Yc7! zi*GA;-a3ngp+=64lL;B>32kVT9TKqffo};-=~V0yv)+ZYX|NkhTR+5u&HdjA> zojTv@JudF`5xW{l^{JJ7c6QbQnFD71AUh7DkJ3G!WiE*HnV)vu{%KviUB@Dzdu46$ z^qk(eH7s=uD1$`&)Snu@4r-TL8YT_5`X6bU~l&rw{aLERbK1v=Uv zA4X@#vVY7JkJWz?0d11kVC8$Z)MxtkX6GQ$YWbeCjB7LDhCGy1Q~<`qxsmBk^gWi# z8-=L48dKQ6O5YfT#0)VeqQ*qkTYobi*o@C)Z7mPC+S=^t89u-6p1cO_87(cdkvjCws|8NF(k$Q@tp!7kcGe*I+_IhUWt;28ajWm`=KqZ zG!EJmg!EAX42d(0=9QUt&rF~4&W+l<;gUhcEMGMZC|;5_i#w0cI~01qpfqEnlI`lB znD|jM{DImud$GPoeg9x4tXl2$b? zR=PRh2DMA$3BE-p$-9&x9n3rWbRiQ7mY06%pfc~d_72RYx2gV`h;s>V5^*KGP5q6$ zZlLDy(PovWLCHcM%aTOU*4O6L!?V%7q!HKfiAIe^{Z^X_%nt6IX17^=Y+upLX`i1< zjTZI%0Dng?%}yb7G<3RgW6A^ephE|V0Upx_8G|z4o=aCOOI>gS$@oB zerMGaQ;f%d=hjIZMiyl!6wAX9)zxK#0 zitl&GKVokZc3_Q3$^A;>w@w<3f*hryx<39Rkxr_h%4dB!`PhG(h~MIW7yj?rpj`3{ zfc$An0)I_Z=O;!pUV5{CSN`ubf+_>}sbc?FrNCc^(kH6RoXX6f5BG14k!zH+0^UDn z!zaj;5GgsXCk**@PG3#+mvef9J0H|RsU0ox<(%*Jo<8fE$6ZJX7JBB0jY}Y7C*$#n zCrJJat(6nL;LG`t^n`P3og-ka$e*5aD zhvY5FRgZ9nU(PMK9JTj%AQ7MK8UqYETwZ7c$F7j5AKpj%H$K?~j}Vl!Jl_oJMKg$s zw==S9v|<4)4>lmk;SQ$$^r+2BDs`cS2<%y0t^a*FJox?MYP%w_kM}1w@g?8jTG$ z`yfxh=(Nvnc>~=`xFNEzAUPvf$Gi}Z7lIdW+}z&0(OGD6QcivxF-{r%c<5x!XgYG# zLMxL9aNbRQr~gQAZt<)ZaI@*i)9$lo3q+(R{oBe$LsPd&qIBs8yf+oCqFb{f#Jb*>H#&fMJkI6B!k1r;n#80_o2-`cu| zMD+PYGB@-XQQVeij>D*olX}3QR`Jr1=++3$sYi{cV#P*1uOWFPHJmw}+zc+BHa^@Q zF6-|~wET75f5`Mn()iGVsas0j89CpCS# z>>ot#nxAwC^CKkYltRs-m#=3MgQu+*8jhA+`1J-?J~xH=;hvZ*h#aU?5?BrmW^l!| zq^TT%86(@vlS4wV-EXFWtUUC(zNT05-O`iOkAUpFVrH0RlD23K`dvkvs zTXAJ!^##R#4R`q0%Nq~br&n&XvXeq;Q9O6bR;o7JclMTF6ogDfTj@$kp&IfZ4y4{RRUy@OI!?e+(JHF1$l*XZ@I9xv4Q zmB_NQMV<5mpQB9MINSn_=%ZYKpM0n0oOeg$eK&oWWqeK&&b}>$ipHSHp?#APJE_fO z1|te$4kIr#+UMZ`pTWnIk<%qc3TK(l*B`~kVy{(~o+Bv@6p=?0)iBuQtOs){Ifx}a zdV|hw_Slk7Ei13rRQINpt8Y(_Q-1 zf*?U4sfgD}@nCiqO5S-P-*zvk3j-+O{v9r%T%}PO}Kql~CSK>+$OFFCR-n19UyS{H41Ua#43vV<*Z6P^E(j`sF` z>EhdlFN!4n)E4Txq3g4O{&8pE)-A|+DC#ELe!kG8nBqKl4W}fgk zye{DzO!IIplc4#s#0jfv@{SPIc|^{(lz(O&33ZXzjy8 z67hTR=YCH-gmswH1*rPaMZD!tKpdv9sBU8i1Pf9bms`myi1c~d)s@@I*C&-%8Xg<9<2 zTf#s3^_O~yCZlnBe#~C4{7~Ffv{6TBnM>8yZn$W0+t4%;#!y{e-mucpx-{Xv;4oZ} zde~)XhIij(y4AGRb61QaXj`M3bm`E!S#%liyy}IMg{VB#EVkLa_0?V6R)Y_{QTE^! zg2oc@wDKKH$@(EL$7d7IeDl4Q9T0T8maU>oLB5$m5q=c65+%l^Cs!2g%s$@W9I-S6 zG;qW)Q4kN^HK=2vxV4o=;bfj=+Tn;e@wU`ox3OI$Lh4rK&n0n3Jw~3=`2N0-|K<7` zB&j%-L-$|T)-jA*zfi>nGn?_ZD`c=XkmH3zXFTIe4*G^t*zlN(C(7{J!qou5IXU&x zwaGC2@jX_3gW{<0Z8^5!ppa!{T?2V>m*pl~^7FfFA;!$i}m%iKzP z{1)#&9$7Yp$k0e^`VC-2r6#2q85OJnDp*=Ro%~0XIG%4;@gT7D_)xR`aQ@St$Ee zzD<<;cjN(ISJYUJYg;~8|8?W>yk)-LjUy;jTdpjr_%ykdB^9xdog)(`H9WlaKH%w`-)M`?_Ata3O?RvSI_5=<;sj1(SV1I#~0yg4L`oL zyGR*8O?)bj$I%z><2>-Z^i2?vW$RAfu{tVNrX|&xP29<7gz+vxs1G80z{aJ1yYY(< z4-viUg2=mOH;Ph278a+rTAKZU+RQ{XLkily+Y2}_KG81b7nM(>XJIXhCS0sZKU{^r26)*#l>^XR8pcsJ59Z|a8JV4 zpPvQ<}B9Ir;dIC!oL^32!_eOCajq~pyFb@AK4MrcQdn08!_HAx;R zim1cBq^lM89DIYACq%0;R6>+G_Irtp`+i1cBn+f{*x5<>o?R(W*Sz$`PKdHLEvtt# zQh|?}Xj^5OyfQ}a63(Ks8K4Ozo9YkUiB1alN!RDFY;}_)#wkm5Rim zjuQM{-<0(6A-zw%NS6_7?PH%;KkCI#rJi%eOvKEV$V2i{KtI9tLBYgp%26ydQJ&wu zd*&1=J>7MqX47_MIcAOO zjDpNTVA7e(5|pk76^DHjO-I7}ji0w~uxu@{t38$!U{gHwpOVeSPHN-jj;s zW_s2`B#Z&AKXLNNziuKqAF99!I-BsoC8NB;@(tzG6mZnjUY`OWghX44ga zh8}JHqIXg#WA%=eh+$s)%8fy5Wcr!2WTVTaNX!OnnvkSmTh3)^4c(S~(!5B^2RVpG ztqMuUvS!`0wj6z0?sUPmrHHw@?t6F^v=QZ_x*)$d=N9(woH(NGqwG_B-`|Thc>9CJ4K&}UX|)kyeGs0IH0v4y>RVPZ zQ%lq5gs2PH?+I)KEZIkMPl~w}E~uE&rmwIxY5dH-!|T4s6k$hN6H ztZeN2OaIp9S0iEV{F1NBMsr5zpi-O+20y%O@97T@*E?LaFY7`*cD-9gl~uEMRx>Y_ zc_w_bf@u34_k6Qyw<;jCfrwr|ebrAWX4YdN!P#{ zKS`;PM~4++S^<4)4Pv3yLS8r@7WF;bWMLoF9FE~1f|s*2UVj#6X19D7`=XT{l%AmR zbI9fKryc`0cj>`wk5518$IPIUv2SPYeflKc!1KyPmPm(>^QGL5{`-yThiGTqtv~LRAN@if3~ULDq|Gp*F$HiZsHFZ4eD2W% z6|q?n=J5IVVbEaz0ZwjpQeqfk_+b7EtiIUzXXrA%6x@G?9{p!%dRxNBxqk~_Mc6?V zEv-)Wmu!Bg^|z`&aZ2Y4OKIkpDtWhJv^n6IB1h7R0aJi5zs_RAisA$Uh7F zr{-^^{;|@(!K2kXKR(a|?f##_;r`S4KQ;fCaMZq5gb%Zgi$1C4=pJ-jk251I3wI^c z&$5?ew{u~=BU}Ngvb-)&J4aYknyHPy5fq7FkB9}PCSzJibd8K-)cPA!oCOT7Ro<^B z8`3OG(`Kp`#L?r&IFJc6NWpZQ4cBoCFp#T?#PvTXD+6H6V|3x-`WvWJMdJAz$W$rg z`nM+azgx>sy8KEX z94oS(??57vbdPZucWuLMeFG+asjce6#TXnb8Wt;h4XMs`i!kf?RwC|G_CP|Du)AMr z-OL!=){Q~; zz&Hlvg7l^xyBDl*a&eagAlU_$l)AyjK}kto_S=@$Fc=An4@ZEdPH1t%0H0SG4=j&Z z4NZke5BdnJL_uSWoK@-gZqpc5(t&r0FyJIz5&{?p7Jrot9<_dkH8;`q33SD z+5F=8g(-nyKuUpqaAXxX_DDVs)CxDHAAh@=kk^Pgg~!}~L6vt2-X%csZa<};U>icn zt41|`D@tHtiJRgTSTc?Qeb^-6O{nkmJR>D6CzSOd66W9?665F`q&WTVDe{ouQP_x;P|H;V$6I znPgfKYPjH64^ZYB7+-|qn?j`&0;i|6=AW4kL$?|!^nBROs=s&4w)Ml@CFq6hLl+vl zO(Rq4DfFV80>4v83~@CCt$s&MmDkL#qomn%?W&{iQ|S3Qrq>xfMDilj-d8VMs95ii z_&f>cK`zI0phr^_;Kr6YQ&8H{!$T2h8uOv~Hh*26Bm3pnw!~)`{Wc%R;r;h*oTED) z)|F2$QtPx5AeBs)qNA3o)|G-6)pf_raK}tfRVBE?Q^x&K;W(K1Lu5M+fRP%7*rrp0 zV+NxCBZ=c7jsiRSi|GTGL7QGTB-AJiC{-Mc!cDkIAV zD&CV&$y>BbQnlh(?enGRh?(Z1C_zWoYW71&_S0A=>tp82<<0Aw&|a`@7TMH_!U=p3 zawX8k_yE+18|e5DlpVCq$9yQeEzEvMB8=+B0nBHZSxcH_;Wq#0^Q$$%(;MD2F-fb;~sPDGkQRD-9X~W8BHwy!|if0>`NzNF=Yi;DwE|T%x}NBK|PB{)aPnqV3_auCrE_ z-*(6~OxK6_T%=O>#++0%yO&`|T&ezY_#x~AsrRD`t=aX;#`*ht*Z~prk@ok!ljjAX z9VXG@Uo5d_*Lf1=KRtxK&a!o zy$uAkI4=xxGB~+{M^_otX=Oc{7aZqz7g_H6IgiR zrcmPqfhBv78P_j};eF`FyC2;^;GvfY*&8I2ABqGB2m?#Dxd8!}fGzmlTqA!!%*<@ES=F-5%Y?JS^9roC6t^&+gpEF_JyQzB71kcW;vMG8~zc zwz?Cyf8`TsBz01Y@Ar%vOy>;9fZy7ueAsCCk>V0{i;eZQ!>Kik~0!+OXR!z1->(e-ie$8rwqv4FC={W`a4L!?#X3!2+E^7#&d7)+KjOPz*F z*9}SBcdhH|r;BW?;Q2h0H0tv?v+ph)({*VmulqD-@$4d}4UZaknxWs5$)x%A?(~9> z)j|=MhBuo>!b=x%vQ%bVyGmRQGRt4>XXb1{C40`UspDESgo7r9(swx_TPCbC-3=jEE-qhjH?Or*@{y>{_;%{* zq519AH|weA(dk7d?`vE9`Y|tR)`ipFy&))1Udg0ll=R$-!OlyI5jDSH2F?x29*cQj z4*2@A78bI)aK3N$eUw=BI8n8DNnKHg2q%TT>utw-9r_V&vTWY(G_B1hek)%rE<%#1Dh_t|8% zv9|ezU7Pf}WnTTmxD=X5&uf5iH1NUktNOS3?}nVIjrblm@LXYcVF1J)CJ!rRwrCra zJ%SmYXR@ouUVPkWE-Gq<41)xpEorFtXsfFW*f4rqaz$2iF3!zY@qb}la;sygF^fJT zP|{JR4e^}&VbPN1=e-SS2)NEr8iT~>ufDawsz9;--hCd5|rowD*J18LCHVF2vB zuMsTfrOeFwDyAO;TzdtXA5$A9XRNlU;h>4s-AJrw@7ewA_uRYY3Z~&*-*IH1o892PZ)leJ z?3on&(HOg-+33zAem^_0+Q(oC(dQlD68=4%S`9K5(TB;nhi@Rys`by!TkDK@?U%Kt z#6`iHrWPW;Q-oBxb^uH7MTzWXgyZXu%4YcZPdapC#or8P96*lG%uTEcJ4r~6>?blr z=bgD4PD=jxjxqoQdH^p@78Qvhix*q+d zFLNKEWp7H0Z1v<&<5Sw=uJlXKypFAke*)-Bj-yZVi1r3DE5kPq6-0^M+o#$a z%(cd!*cZbr?F-B{+eHB?v{pTOXG{>G0f2`U{#Wj$y~2Ebg3B2EeFlY)iY!Tiq+zvJOZ ziX`AgSKk=edatd4;)fWzH=19;GYmDjrLE5hfgR=#$QTdl6m2<_ zBH~EGUw629Kb8SgyN$bFlRfm5*>06UNj%Ux0ilE!HLr_(9ZtTv!eC!&wsnu6nY3p! zw)mn?h%$MU7#*hLFV4W?1x3Bc4f&AV{gRnY2{!jPNB&#Hi~vDyVgBUkt%&cS-NfBT z!%s5{b%qu?uQoEF;q(6R_6+K`H``-))06MS7Od@gcC#v%wFZ+Wg+lJ32)?UHY>GjEXl4z<=*Y49b~KfWR!%c`0dPjOQ=XlPzMp~>^u|n z6nl&QH4d+54lm|^F)|W+lB70;k3fP|k2q`;St71-)_gLWOjFp`Y!5w3x2)+*>xB9D%0aH!0CAhyZ%BC_64kD> z7PzhSaO^KFsXg(`)fhRpZv+J1_^8`iDRfeve0pdYQ1$io^Io~;YxX&7J?5iV2H;el z2JhPAK22*UM_<2=_dt8S!M2+pdM^6*P7pf3HVJY9*JSx`4TIj-XM?LT?`qkr`_K9<%aFRe%I zFSYQy|F<*(DL;Hl>o=Qjk-`7pLXo8P-5+wPSZxRvuENpA;=)YAQ1)l-BsC`ZFVX)& zRd8Nou<$MIZvFq%kD)9@qAfG2*Zsqqiz%ZvxFsfCd%1{0vr(sBESE3~L(QMPlWdjX z1jhqQ49&dqTO`5BdVQAlS~G|J%Q&;zXHTPwH(Foc$d_n-JI%KIo9(~Ez+XNnVZov$8|Sx(ohSb4F%>acz>*vTC=xRZ8o6nCJ`v2y661aHSbkN6`4 ze5}Y6ZVJ9*EQ;znmN@N}lG(SRTmLWe$%c) zQRaWj{J*^hqKQc%>~kG3OanXF4XuEwr63vwGGJ;~54)Hp$Ra1K`sF}xN+o{!S+@UU{(gBQ z!J%*}(d`Yy;xf(cXFh^z_ab~+rf2>9)f!tCeXGL8N16L#?$L{U0WJprb@u<23wkP= z-f@|lU{bs}tj34no){zx9-R5`_#J<{=a^I|6K_e7W&sz z6{a@KO!3O>UN=LU}qRy#l5Sf_5@J;R!u4 zEbeAnCHa8=9ET2z2s6}Qwi7MlW1)e5ne5Ey1XCVEsMWT5=rFaz(5TDeI@$HziiXD( z2CF2s-At!T^^JG`Ys{ZqJitf$;!_U|8=GL-6DMNo*k478W|fK&F(CnA`v!-zAHsAF zNnjGjK1!_ri2VT{Cjgy9kxSS$wTRrv1_`LT1R%7*$q?Ekagj1j0giqYAWQy9_DiCM z{P56$@LVIy|K!7&=w5oR>?3pmq#&LrmfCAhVYV)sYjs+Nt8fw&o@D`S_t!08)?c}1 z4DS5mnyIKbD&YM1()A@T)58*6tToo)WSr=C`Ed`JA9Yxe7i!?pG0JV-Q+z3y6Uf36 zwJ{deich_qx=`Ed(zh(^G9uI=ic8Mj>P?IxaIK);OX9_N6g7+Nv2>|MI&riJqS z7&=n1aRT;E8v|eXp#b}H7n2?LU3^DCL>&Ec^&e<`d1ZzFb!+J5)d#2v%t>EKpg$ z^>5z{eIYGOsh6N4kQ2?Dv}=V_(nQ zqC;VoiSL=v85-Kuvk$mH|JbE&OBj3POU(v18X6g1;TtI_(yX zOt$Y^I=0Go6VzWnKULe`Bkey^@&)MWd3svhNk&Zv9xbrjNW52Iq6&$F*h@ZCj>kA>hdNjS!hNjTW{Lf{MqBZy~mv544T_+-iPm9 z#c4C$_Nw|qL=)@WydPZnDMn=(lJeQ^w?IBs&wl9L$d5R)Nz41X=Tjd8^Jq4uDr+Sr z*c0ikdFb8t$+_h1x0$ceiw$o3>fRGLJ!_#$Jk50l-wO5uBknvdGOROIPMBMnn)u8x zi)m6PRoT=TrDMMCu_$YDtrN%qr$Jm3gAGWd!b%`NbH&pcVsowh4VOQP2~r)*POMb% z=5Jx2YoXaaSvOlBRvJ}kq|vm=M7mopb%R{J*gZ0RYIq;NQ!p}mM3N-Qw4Au@abLy+ z@Gb(FcxliRam%~jz+SZ8U~wh%V(*pih2JS*Nik1aE3Imr_BdR;`j$035?dV4Q=-Jr zgllSkAnB*UFwK2NvaYdKQtmVmtsqJ>?{G;{^BbCz#yvzKnG~KTJNbdCK{DsZH{m6o z&+5GkegSrDV=!-0OTxpa&a33DS=o74(QeW2;>`uLkUsYj?xPC94REJ4^p^kB%}C^? z-Mtc4ml1vCO*b<^D-;3`!?6y0KI6md$>Q)!m{~% z68}o!G&WN!Uh(~uV@dlbZL^=~XR(??8&D=wt&u+C9yYGEBBeHEPc@SwBSv7!34FAM zG3|6L%e{6esymIJZUR#d0VB_Ij@52><2=@G)pm4_sqPgJ$Xu(vRha8918QeC6Qs+7 z=n%{7**?x^K-28F1SP(70RNMRU5C|*|- zZaH{)|FrFvbM;f@c1?JNuy&^BaxU0zfwA=1<_OJ5BhoniPG4opQ)uA(W{B*V^9ln` zoVWSn`L3rFgW@sj)?&{l_WojyC*kp7lwDFLz=sD@Pxf(ZU=`Uc{w?$jDFbddq+7a9Od|t0GB6} zAFKVGpb3*hFMXR9&M4iIN&_uAv@{!RoS=4=u*O+^nGD1}bMK?+#NhbXvDU{^WKu5` zbtL@LYy!l- zencKoXd11}pXW5gl26#>l3F~=a+_<~IcVkKE)DDD+Y@e+{>OZBdMN>oH=+H&y0FA! zd>w_)PlQtP?HQ8$S;GaqZ@85G6pa@qB|@y}#*st4Q0Hy;>iu>3^(K0aUFWzgtPVhA zJFJ%F)|`L?TX;v&GN9RZar;H``-O!LAWIk<`r*h_F#6|!>;vKeF`QG9zXAfXQ<5EG;(G&ep;UMtVKmn*pe}xu z_i*Y^@$e1{;RD_4Az212&oDoauqXpN0U9Z^fWOJ~IrOhUCFOJI<@6R)-`0R^6rPwI z#tF%WKSSVbrOQ0oFI#2>hQRuyifSuU%dst)|INo5Qy+1sY}IIA2E3A2IE;XZ2 zNk})-3H?tV(Osgt$cm}|f#HOVZIh&9Y$trk^JPF*;lfHfbErQZ zmNWhU(}TYNHkAP;AK&M}Y3M=WzdBC<-JTt;_Xp?uolDZwj@uK?fUd zal>_mRyyx3JnAQ`Gx?=4+#2i}#xhP!WhmvP^~@5CY$)#Pd2=Bsa_r3c(?jiZcu><%7xzOJ#O#RyRMM z|NL6J+bhnv@@1aHh+Z)HcCUGpH#C7|JW5;w6$A%BCXW-YlPuK=K(B5x0jge4Ya`!V zTrVh|@-1W8H`ZjU#Bh6phd>{1jr@h<1`CfUQ-z0a4c|vGg#ufo5F6Y>XXtHyQ$^!wnU2ihHjZDS_q1|lf zn(KExlSvo5kdz%W$MFF5O1f8VKiA|sR zJ{h$ieKK}eC~LAY+-A3vGC*?5*s9xA`VMIgcYSEkW>}7l6|WAynQm zinkwO6h(6I8@M4Ve%)Pd`tmyLYtU-WJyFA!)Z^a#A~{ME(QN@mL5R@vmYiAZ!5Y@r z>0kEE<)91kGsRyktFb{|fLtxS^xObX{uA;O?q`Pm%XfS zil2>rLsfGmviLP7OC!ceiyd*c(k?k1o>sT7OMEZAkfNQr#XXT)&ebnc9Q8P9o{2tp z_LMtqPSd$lnx1)0gkO15iTwQJy zfaT;4H9OvW{^P16I5E~G=IAYI?^C@7sg(kcRCFkL@S$z+Ma9$m4}Y)wmHM>=rIK$& z)N?%ehMa>Y+cogUcK}6&g~cW=7H$S-*7e_z7U3qm<1Op}mr^CZ>l090_VLcn`Uc#J zbWRRa+*=E2Nk6`HaekTLc?`xMGbz#G6^%LZJP}_2js<{Xwt_C~htk&5M4_Sj21cS9 z{7-9NYvLM=fqz{G@gh|w=L^RSRrHaISvwv6)Rf?J%qCZMy1&K=U&mV{9K;Thr(%y3yHDuqIk!5 zGy=(~4&3_js!D2F9DJ>#(iM2vcm4Sh!|U;R!d_(cc_k{*vt@Q}#h|A8Zav<7$(X3y?6L}jy1edwHhU%+pz8j|w)VfXC&LcXo5-FTPPy92Lf zEp4LGk(JMYAFs)W`qn%{5M zeyoN|#y%-|axKshsP>X06MPdDInMr_NcQN%6UO5QZ5QccLTCOnD|YpzNSHH^kxuIq zVdVpZ&y}Dl--BAAAbWfa64*k_C*U}kds?S{>8CXyKuevJe5-=8OCTkYIxNJ~>?76T z6LZ3lkigWL%X`wEM|hf9O83CG^39*|4!bw2ZNB9)OTz??V*|k@(^AtUDr3XEoa(lZ zar@6`y;0=Zh>2IafQIHS9ks>BqsBr)%&w_hHsjFUZR3ILm2V_VIuCj1k;Kb8NTspa zx^puEM;B}B?DfG{RCk5g#!jam_OrbvWbB?)5D!*60@$9CP2gDQlcnzB2+0r+h2S`U zBuk~o5#k^odhMT}LUH3^)xRZ_TRVUW_wV4N7gb(7Um9@-yOT6Y9F& znq}=I3iUT4sEYXN-+tFbfC2Bq$-mv_-obf9p;rY!cDScH3THu_;D83lyANmf9q~nf zw5O-o@;K+R$2MggLier@uPiZ(dZ*Ha#FZ|d53d9*l`N$ zkH?pFq*ssXmX%G$Wf>gl0#9{$BYyu@9;HQne*>vsEy=5N7EGOGgSfTKCez#g z%?u_-Be-xre}pz!syEJ7mcmmzuJeam#{SJ>#6!L~&H%DhB<>cP@hJn2#S5}j3x8{@ zI!>o_EdG{)zvolpp%*ytH_119uigO7lCRU{Z`Aen9Ei@vEQ>*elhF8lKawIWNB88Q zd$0wB=ZzM{&^vp7IMH6Cc`=A|5}KUvCshQ^%I_fBv(eiNWjbHFFh0vOf|6bk*?VWg z>g~n?SbkyLMzap}_Fy>Y?w^W5RFlxOd^AT6nnQ0-?#`av_k6Tj4%!S`j(6^kwaPFF z&CExy=b+d1_JG)!BW}spn*P_C*qX$X(1d*SpP(e4iZPr;m`};q-U>JE(bvXGMi#C9 z!<8wTjH2rweluQdUPz11p1X`T$hgft3q7ns+_8@!YXf&!;FB%jAA4T-B`+WvH0^86 zGFGY(9T5wJtms>C4Gg3U&^jyV)i?5)F#$+*i7mGEYxyK6Cc=W6~&caC!vP$UPk zt8Vn2DGU2=>|=0Gcn)MYE_A<0C*c4H*L0+gvWK*BWKAk7n`Fp(Ssb!C>@{(~@9~eR z6i_M`5}R&(oth0Z_ZGA8)->zEIE{q?*uTeH{Y}Hd(NOnUp##C5!!%Yurp{W-3-OgI z%LTK@1!o+;isAMz-ppaZIGKmdGAw66nN9(m6M+Ws(?$W@D>(*q77^`Q#ojtsS~~F_m*O zcxaQnz$1^c!9nYfqLVH}Mh^GoQTw=PqER%%p*LQm1KyRxthcm1kg5)2fn@GJG>}JP zKi}m!H;oco#4$_SmZ*E3P_lVosBg^LMJ6lyfj4>YVJnVbxv%E>g`_{gq4Hz1ub4Oh zS_2DM>>wT@zMOY$^39g9Xz~U5LN+dl{ITC6;sfWAL*hek-bNO@t0*@ndk4G|v4zV| z_71pL_x*u%z0l9lp5~=H$95(@_O(d=g~JP(?1cwAn5Uf%jWGcWQk^~^sudR88+efn zQPWMTOyL)A+9n`2JPcR?39^GIEc)TCT;gDZ+90zD_M_T!Zjc8Okqc15lWe?AC_emT zA_oPLN5K}H*&Bg4(=X)ewx8O|;jdwuWkQ{h0yuthopK~=ELGcv_ACTf5554its2K9 zfI0yP1HAoErz*cITwS>jLFYjPTa~6yfl-9;8SSS)L?=q`?iPgdDbSt}UPwL!?K43q zccPYvwj7{18Q(C(TJamYweI565d4#0ci;2YBfhCMTz>=GpQ}VWMZ1$y2;jAeE4DGL zEa9&VBD+$S3!Bu$2!}9`V;s3G=d%Q2)JA4*w$BPThVjNDfCa|t_Z#>|CWqzrRUFZ3 zXBrE41C9yFSAQnlDvq!I=eT7KvDJN5N$ycpPhboJAMC%ItdZb$dzDa;p0{2!*Hx#b#UtdW1kY6tIOQJR@Tj_e4N7^|5KyT_WnG6Xnm#aZ8 zx7%2F?!R+91I3U|E$SoyYOQ}3zu+Ns46VhkmY{3;m`K;iEN{3ZQRWfexM5NmuDLtM zDSYt@RKYIWTO?Sei7&|nueY`J*vqlzLNd33Y z5Mv>L=5LT33u*8FftfhdW>hsOj0$NH0DGfRd;>I1zD|(8QPJC*3B0b?+tVaE=e8`) z-glrry>3P`<5prJMczneuB@K}3#c&$x&Ve9u3ui9cq6aceNoH*UQC{N{6~7zMd{~& z+0T3}o5LSOPA6Q=4Gxdy9v(ZF(7XPrO#6e``Sy_ZBOTXTk%So^4GM!tHQejfeNPPJ z^wl+s&)?(PY&re^j6z_wkN|i{{5w5?bYxTVFc*b7J(bTXD5!pWkD5zWY(Dpu zjQK+whab}bN#yv6L2~cK%{5H!YM>aF;jz~PLLEDt-(2$)o}&!}b-fu+Zkx&YdALA| z8v*D~po04PYI_gwu1uumO#!ONcQy~TQwCjZ#vBq3S!hmqSANtq*gW}q>C#?qH`niC zZ(TjocuuYK@<%HfAEh8m5bbRus@uM4e&1m)gw>PhgzlX0Tl42j#Wcxu$gg?xw7B1@ zf-Bw%h>3TaVETgl_~H65c5Kj?c5Kj??@&g?kMc21{=h9GL7RCbtq>kOHkQiP=Q~m| zi*W5}+0dT2kZrV(+d-F*N{hQHi^0~(Yfha6%L!yeP8vNxekkMYfo*oG@W`H*nwm5^ zFiqc}(fGU+IIUSRzymmQ`T~juaxeqoi|(>;iwRV6lsSNpCygX%5+Dc${lbwCPr(0rU(atjYK`Xi3 zGC|*4IeFPzATB3Y*4$tnxJrLBanUX#6J8shS5b?M8+_@=+*nk?IbvaO@o6@@20YTo zzLC1;MBfkJVmq3c1r32096*WUKEvLykfH6*`j^l)R2zzdLn+b+dHA@x&>-7Bb6h6h z+uYW?tfQm)u$cqGWbKoGk|bm2J+BH*j?R1r{EbRt(6+xiq2LklJ>Sxyw{W`LI8tqY z=aA#cFFNjEMyGVNoM{zeY|Li*vS3~vrNyFj~z!4yzyg_TiNPwUezzh7R87uy+Ch28*6U>xK$WjR0hLrVT~Ms%D^7?DBy!0uc=&gh zhMTn@{}%yk{h3Kc!15&eccw$TUg5(Hk^1-1reXpXF$mJz50~Ha-dPjR>XovJ8#ogG z7IM}fyqhd!R%;rkso*)(Nc;2sre{F`4?bUwDRNHJ(vmb%hBU7>;0k$p~5q19+qsd|u1p}hPJ&K~g_Isa?iN%9;&oOAplmjAiP zl|4e zNva4;1Tfy?v5P_G<_#>>IfI4kldKCyrR0D5*EeV*7vTq=^QV5h$$yHjL(6JL*882I zvbN_eb>=PMXG*7ypmWh*%+!$XROcuCx>72!;^86edO3Y*H;0rrsU1p}-zAhSIa7cpTlK!A z2TbheZ_~b7rJkYRauoSuMKBz_1dk-wt4^qUWOdgZz`QRnpL*_1gb3*x)plK7RZ?kYz`$3s$07I zcJ`YMfja_%QZzHPa5n>5YzB+>b4k4zlG3`&d;09l)AL{))mRaKvfm`pE9zUjt6gxg# zvj&`| z5jW*NIH;Vg)>E8T6l20@bDN9iU1RA-t!bZ@BH~$>7H5Z~q7>5Q!s@aS)7EGh&gTma z7sO%>r`iuz62IvAwUE7}VeC&0z2-Bg*i9m{XN!}C(4V6H>j&pNwx4}mNTt|blzDe4 zzL2Jj0Xup3??X?9743W)&OHqPm{SY4#JLMOwlS*`wWJR!&NfGHo=S5_OD*Oo4%srq zxUwE>Dp|Qjb?9cs-uVs_IACQC0vDeo2~m z4ooqS>3d$6yRrUQ!*b%zXDLkO@(nUtD9t?*E@L1fo)0|fOYuH;pL3U=zUEhksi0q? z4c;Cjp0mBI_A^jAJgG);^Pd-Mzd#H6$syTn=bayaYM*^}(?v>ys}helPMxCry+M{u zTltl5soPWW3j~v^5n^)p5`L|1r;RdnRbRR+n;iIUYsXM;1D;Zc<*J_0v*-1cc#X87meeiEvAP0|`IJ)lZ)f6G{w z!&H7K1>$&r0fJv_@3b`9XR-cHE8lmKoF+-TS{T&?FE*WZK1PSKtk#Fh5VNE&i=N4f zP2f+6y;8D5j_vM?g>U;oHD9S>;GkWKK^w*9`P{bSgJD&LIe?bIi{J;8i8h~66?Y(< zmbA_e^svezR({RhdyC9tu#2W}8}?!*0V%ciKwTc4nb&J4H}!tazx9qPPiK_NTHb7m zUcOSnm+b=dEw7X(^Mo#kt}Bkcf4|P8^H#7r?@c045KWdoFezqI8`&p6%y~LjU?O6Z ze(uNa7*$%%M-MIJ^a=`RU7Fn3#0+hP;<636180%eFj@k?xGn*qtB|jpwfoNVUXy+N z&zJhSo`Rn1#cj>JMwO^Auh4!w2oxL=&_g~|UHJN_vj(O9-?%X3$zAcMqJJmyB;YBwCXCby9Zvy%1N=rcwoX&O>_J+ciW93pQ+^x%)6d@&k z;P%?3+%+-=ttXX}+4PfiDI)IL%qIJ^l^N*W06#5u_w$y2>jv9uU7hUaBR;z73$AVc zIC0w&cGZ`RUwHr2E-HUQJ+pNmB9=K_x74b0^k~DVbqKK)9urh9ndp&GZajO;h>gu9x)VwtQnYJFGS7&$q1GX4#C)9i-W6cH$2sT{(k z7GSNhjY=LiZwakXt^66WgDk5@j+e4eW-SySO|*aae){z3+jh0X(Yi(pxh!!XE3X%y zhWqou=n@%|hRKuodh)1;Yql&k8gL|Cf5U5c>_|eyAv>mK5r^ALZM1A&11;MMwC2l@ zGOXLAUu9YhS3PhB%4~Q{j4)M))g3{{+popyK_39>uGR4LOwjc2>F+pxGr^Wz7F&yg ztaM;pNcEbxYFm^8=u7i>YK%i3@$$`p00dOxmXE!`5yKZ@xt8O;Dc%C~GL}?7sz#vp zpUk`+E@(b)bmg9byl6*pWm!r-kMtk7bzE|&it{oIYzxiAN@vQJmmCy99MZvI19SF6quAUYqX5k7lf`Cx zp*EV?(GMv@hh8#+2rfLpAEJw;T|Zl#)<@4sS`=6o%y7+cF)*aNgT|1r9N^(wRGF<( z?lT%CnZnLpLxlScl?&(~W1+?@pAF7RAr2W1qsl28bzYbW;@d^Ig>Q$!iGgNARvj25 zhmb%00$uG$&PvXLJ<0U;E4Vp83Dj?DmfOX=;y8dek1oepeXTIIYnbsmb&!;_7Vt$Q z2I}mqRBS#hyr157-Mu8S$;#~6Vxoh85^<=GMSWXBJFX5~JqxJIV9vhFWqE!gMTH^@ zalK0lbkG|mTuLIntUrGwBXeh%Z>-POQCihC69Rma^z=GC0$4g;COn~IJ$9+rR^%=% zi(NY_v{L_URw6@D-){pb;87hCWPWxa3KPf=K%dZB+_W6-oLEZwWlCr$^WKl)B+Hlm z0I}9NQ}9N8|9K@_^5Eo(i9moUVOJBPDmy(0O5%_~O|D(yU5+K&@$nsiQviT)V|a>$ z$Xgar7FUDm*b|FQPSwck22)x`_4;@lA)aSPN3-8lK7Oo8OQLBUjxd_mi46r`NZ4!- z%AhdMV}H)`8#9WKmlX+CteK{i&(hH%DIx|B?cg0Ws)Q-EcHU4!#Yff)w$ict-`~tP zv^#1a*)B95s(5>EFQu&MCn7Q-9xYmbu&P2w`AE}E$O0wc4L((ukKwg$9CUHx_Y&DkIF$UD0TT*!1hMM6fUsLv{sXNDo#V5kaQ+2#7Qz3I1|?Rl zbDRI^{xtVr5GAU!2)NwIDD8k_{J*5z#wL?8 z4klz-VmNaDOi#bv_}}_BnLok5!GBi6?gAo^^Zz96V8V~JA@Cn5Hhb(}4-s}?@r*ri z{}87~z}xG#fad>fK;-BAWP2+7ZMvL5Bsb1-%D~w{;r|?N0>daO*#aI6Ri;bN0JpYmJg=&{~O5%{sa8|?cX__ z>)#cyh4L*b5QbE_ZaC2u!ICwcfPbL@euHY~L*i#82hlL2y#jKV18vG?c8X>^qR#J2 z?(wztd$~*OExAUWAGuAodZ&720LlzsJSS;g_HDUyytDN>nUFj?G`_c2HRJEh2c^WG*f#d;QnX&GS4 zsS?1~k}3F|N$~q%m}4bJf4ez$pKn<8!2?s?CRdz&gF>B^(&%CYLJVb!L=bPOrYOAI>Rs-|Twy}Ej@BDJFFO0gB@Da_7AdaV`! z91Tom=XFf`VbukZbT&+a)5#R;eyI|Fp=QX)5MOXw(7zxCR||WVA;uv_N-SGs zDNJhx-8HKkS*4y%qFBdOiX?s&R_&Umv)D4vEooNf-m43E6-m6xwelB2W7-r6jPd>j znNE6!`yNvsQ!4*q*_r|;CiML)He`jz^)_MEb{M|3hM;wsh3MB$vp&{zQJB4;7i4zo z^(cy@BbPFjmVO<1{n6B?-8FuHe}B(NdYU6zH)c`3Oo^$QnTc(>c90WNTY8hVYHH`w zJMV#CEh=GZ*Ak!`BVj5d+KtkyZeU5%rOq9u$Ssegd#e;_g*EQp>w$V;COsoLcfQ#2 z_*LX^G+p{&ST!M<_&*T%2xxdL_pc~-1VgX_{5!?20AJ-|=AK0guGpG@YXp0DNg5<0 zyQlZdFu}QKsu?|u$`#Rnps)KUq|E<8_Rl(B-)=MD9h3f@l#fY)-#S(YKKdxU9HE`H z>k_!LZt-W8Jw5!nf3Je z<-M_-fX`1U6$xK5T2OO6!IO>s#S;+x0so2kvxnK733l%kWA~2i$5o)=JJK0rdT5M(0j2}9FT1x~5`%fj2;Mb} z*)K!Z!E}#6UyX}O%7N_6-?U!tH;dD*|J15C^puto<yRGHnVj+DU~&W zH}eP4uDz_b9-}doD*O_BpX@m88wJzMFjuoiMbKvj;~#DP#fII{Bb!dGzOruz$>XW$z=Io~3InVpgBI8kxQ{jDGy~xnWBycp=ld;OvTqMfxft z20dCXBJFPaiulY1sM#_e5s^oGy@d6I^bE2UQ;U7QYxrfBSIjNAI5_<(Oqr9NYT9Q$ z)Ovlex_b4wAq|))b=}IFA!|Ql>f{X)d`IXzYBL-(W&949HOt~qILuu~zIVx@*|#7i zJbmfL=!QG?ovDH%iBmb_+%g;Y;TM9;ljQaMzF-dYAL2 z*4lXVNL%#Dp>xt@V&$Pk z)!o#0kC~+GX&GD}5Gsk@s|l^s11RkRISWP`5}Gn%DJk1uxHN9P?+gCqa!UyZx=qAs z_+iXQBg>;3y$L+RzhE#uFZk$zc#2$Z?j?8T~=Ex9whjI%3EXZjj#mJ!Z>Caz| zv>I)`%Mb&G+WF0$sNl4RM?jA6k9N2LzQ#A;-t}Fd_Slvf5y^bhcDY0UU2(>QVS&iz z`#O~IEgDH$Z{fT4GV-AlX5n{w)fiwCR&NW(D$JPVhjtd*ARKpovJw`bnDu_tyz|&S zf7o;)%OsJN@1xmM>E6QZLhU}&Gq{GNuxw50ax5jO03A7)y;^s2kG>MP9_{h5Y~0x4 z#gF9H9bV@%Iq=jJ*ZcW|~-+$gdZ?)7wRT;W>}9_gF20 z=1d)X_bC-F<~E{!nHHbdwzPC)^*fw9Og>RnBpdt~KA-fh`0)0rV)2_h-vS}~PSv{a z(U1(sBg$%Bb9Mt~Dx~ETL*q-Uzz45`*W;FrPY?vv%1?gsQ-&)V{EX5-iRxd}LUK6A zJtb=wnM;@wyPbM ziA1(@U)mzlB)IjXcPb}ja=^m&E?`Wi^l4J}kv=ar{iT;05eP8Uq=!%0*-9446c zw~y_tXruYkY{#fAq*f;HpOW;Gn7h??+Dg?E{`gY%CfV$C?o}&F!%l%NyF_%J>(+;K zu~N%78jsR9j)zTiUG?fjQ)fP`mEC`L)6Fo|-4uWC%nq#m;k9o{^4Uq|H@j}dA3q7M zv%Ie1-rMs6_BI#g`7dlxUimQ8QkRY9Xa!ADflCDu|<)|D)tt|z^|B+Xghxt6w9Gkvwd)YYg+4(W) zxP5vJaT~G2^+@?^?@sUI=m8$09p@nXthP4$d(cL8W3N`^tfggB*A5UZCSm0pU@!!E zCn|I7`u5G)_Wk=`D)9Ip-KV}n9F)DI`^oig12VF8Ro0v7u1pR@Oo~PMF@j_Gcn>Bz?kc`gVH}@PHNF6;ijs;~z|XUp z1~_3()uDGUQoERi3F2h46G8+|&e$f+r15IG6Zhi}(!ym#!i^3T;$)xxKKPg-NdWR1O^bvdR5th*T0*58!M4`Az zpF#OHO6F2VvPP?NY7fOQ$6a0Tp;9Lsp>o&9u)6m7(!zRlE*&p(D6soY3=8v;^IoQo z>|E)i;o&ld}Qd5YL-m&LhEIRP{hfD{L7L{;m~LuP@(nk@QlOjr2bdV zZS>V{qm5)-_j4Tt&TjrpHXV8$*4;4weDrfCKaVdzKeoe@vkXD_%dhb#jO?SR#x#dV zN!9J7mnhDdNN(p$hv&t#L}n#~Q7Y7g$6+M1meX7>#=U@o(oacBifRznZ8LKr9Ay2x zulw~(#5JIq`w*82_rebg;|tER%>mLWUZ60#kX6FoM@zDq?c8qrmLlcVf^i;WSl5yA znVUU8-Fv=>Mq{vS8mTfcVCM(SN=BP);TP!u!!O%YhP}i24N{6V-gCvvUE^VA(NPhN z_IGyUb+kONNYED(C-E8&L|Y0=F?nj%_l9|2tER9q**pay#-5dz<5uqSp^n*c5=2VK z=Cqe=aS5VZ3Ks5|0_4{tyU+^3!NJV=%5y+Q`x?oKVpm)^66+{&&NSb%ccjShC%cXf zXl@?A^9_}DVv$~%#LBZRT%IwP*Wm~cpNV2dGihd3w|4Xvhy_~Sz(qDX)zx+>^^15Q z`n{6IgSd%+H&(~AbbTw0mj|4$B#@K{2!~EAzbJFb=jd1FGW$1S?1MiQWU<+x26oyn zKO~J@8!u;IoJXv(8|vI#i!G<@)y?*?UJ~ch_QuI7frky@!8z#Q4&bzV|1ZJ0&GB>E z$cGJ&4=_XhQn0qN4&b^sY^raacqm2s;#S5cQ-aXL?M(LqH`%GP4-=CclN<3PT$x&0 zBEt|CPqgxIsYvCK_40(FuD-71`L|*nUcJUoOEEF2=BqZ19sMo^oQ0e(^p#5s%sKc9 z>orBZeH#x2eC$?jG>~Gh%ZrHTU=pVK!}>$bN8SzX4hJKf?4=7c zOv>K|ergmu>l43tNca3Bn0rQ+>)Fb^Q679q zs>BERUk@HyBlURsBrUS--gq@@muqwFt-HE;XIAchqa-|BCECzy3nm!Bu2den^B7CI z04HEA$et?I1Ue{O?6Fp zij9m6)C2%9WYU5S`e|sv2sq19LaBbCqTt++$#O@k#50=3feJ`l{%n*rY}zp4GwKvZcfL*jdQ}SEin$2Z=vAE_X|^i zR`24Zud;7iC-#swjS>@AE>K+6_Ub9U(%>HVP8iJhM`7mg#qZczCf)P)OQHiWT7XUp z+Ub?j0UGH&W#p6ndD~asq5KPGs-R)e>I3G`Z9x^kZlR)*VTXAma=S{>zSBE)ihN}u zGJ3fa|4OvpD8n+5lRa~SGcx`-3boJG@C<6>YvJJ!y`uFad6YZTk1!J#Rld}NGF1r% zn>_gHFF~04{;#ZO@bR&!2JRNM$$!JTBvRgg5%`B5>&HLZD2XlVMX}(FKqQj{VOtPP zv#>cQ*iw=lCzJTuj!6aH)|0=mZWbw>k9Yr*g1;(fI5*$H9n$JFBplL`@BYKD`Y9Ov z>#tf#p8{~;g#Sy1PDS8dnswl8k(hMgQ2ybaVkhnlWlY_$#~$}kS%Ji%IkjXvWekBD zGNZ*Tfg>;Ew|}thlo3nrV+(M1Z0Y2|BR#XXHpDDqp#&RZ=CRPb8)BBR4mhWz^cxHT zK4wG+K6yViB1E~opA8Y>AuBXdp@aSxRs~A5(P$p)fP2bEzd^%V`6)I=a$~ONd9X1z zpJ%^-%Z?CQ(x%c<8oNO93+;9fa&h-m${!VtJute$RZm$9>=m(A;X?6(4pqzM`(=FJw(COvcZ#~AWhq|*k-s&N<|t-$>;KCA$o ztLHg#_pjt2dsOKHc-MVr`nxM&Tnv{s%e>EHE6rOwDY%%;=<|dV%29FyQ1-wU7#~Ab zCRl?A&yk^#$M~!O<3$QY<>+@btFzc_{hk~H14M{z(a)c<2$*_=2Z2(JHKnf9$|TI- z6aE<09Jx$mBqJ(+nz0r^FOPZV#piY`6o45lm#~KG_@gWFu50}7l0Mw^j^w!3F@UNu8q5W*8k?GZ&f=s_KbXa|75mhG_gUKBur62Q5h3B01!zswm1 z5Tk1AEklApxV@lXEtYnEg2zCPQPAyPP;U#^4sEdld^`#w?8Wfes8=D(e%A(m8Fn+(jN^le6FQ9;w+t>OFrelnxLUk{wq0S@KWq9EKI zhq_O;epJ}}o%#uO9k@GUcsG2V7;PKUM#RG$=-sVt(Nc2Tjy`?3oiXkW3*q%bx#%p4 ztO^PvxF!!md-i_E7sV9S7tW&itNdU@*D(QCAe%!4QH=N~6#ooFyavRRcBl)yS}2nl z+5(ZI4nK-wc#knD)6AdYK*F<2yqj%*jPG=o z4ICNZN2m*hG@7~`LCsAt_dDS)1U>vbh@|BbgSLrr4*;Gfm?wnD8SN?{VJA9`_yU4g zg>}f+H!pAWGbwo4BJuoLffm@jP^iBiOscIt;fl_-p z>_LGn`5EHlUTZ*yH_pwP-xQT4)$3~O$@QG;4V7D6o%rc7k6FjM9EXS4VP&lBL zdoP>AggZ+?RFz;i=eTzrPywWCG4nr4{kTKqZ*LOY+~@M*GIIO54fmHH>QtmRwmI1{ zuWuN0vV~sX80KV4z4oP8(IH{lFTC-)p&~ZsA{%cUbsPQYU1uW&s}iGzdUjq~U2rXb zba>PO4}gsw6u0#(zwx2Pf#!NLuP|NYIBb=g+J!WlP9XTZytbUKnTDP3!m3gRV7e>r z!Vo}PkMTp$HZCaF(|&{L;u(Su&rb>7HYjyqerj+R6}=^q={`HS;m&w0_5IRj`J+Gr zloDI73FnUqhsVcK52S;(!h<595@KzT1p~cl@!W~vXoC4a1 z73fEVP?7h0M}!!V_j4jbJeK!UB|;R-`+X)tkocnr={E!jPH8P-LAQPZ5*5&FZK-$&6R|s*gT-Hgfzc#6^ zCgQ^vO^(8r1w=W-boRUZN5Srza0vTHA@3)jUh>_hN7Ogs88k+BPuq1)+Xc;fnRLXS zcd`Sgh9Fg6X%0PEX~i@A(iKG1mGB~^H^>HsQz@&NLt zb&e%uTT9E#Mc-F!Ecw>MC%((JV*<(4>Sbhueea^L{IL6S_Jeb#x!J3&Ce;SUHZzpX zniaG7Lph6;pTwT(p2g{k`>`^|fFFgkN2I(QQf)|8uJZ8A?AvF5+nxVb_z6*-v}c=i zv*FrO*_RIwUoEp|_Hx$hm{xm8$FXJ(Xwb5T*zQ~V%sc{rmoqBnBBwf?HmF$Ek;&aW zq6Yl9DbfRO&-^ZAn$kgd0q*heOquB`FDxt?8fGxB{sd+vwVf&Ug_hA|RO~-)EwF24 zilbAi)aAVQ=oTTK1!-$^xnA?-?04PXvY7G1uEPtxyhn=b;?oVrcWSMCWiNEH=YBOC zYKxtrYK&leyQ~l{%I^i)`T2ciZ?u2aa1J;He7X>4O#jmgX`5+5_Z8_s7GVUMNvAx zVe+c3k@Rbree^`BtD9Ei2Z&09PY!xqC80oKV}5Y+)QPO_JG_Me@Fs(IN*meq3OceS z;b7&$mf!sL91k#oK4l z0OU>DKe>Xr#yl*tJ9j;qWcmbVNw(L?IC0*fcI=154foQ6lw@*w;J-TFBY(-Ba$@tw zJ>pcXDC9bWZ=PXz7&30_2J? zLC>`^PbT`_-E$^!;!Xz0g!W+wRg&ZSdkmze-6w0W)WT7rZu-BT)ckG%aKL8T4KQx& z>BBmZxw)G6a}{j`b(NnnJ$4KOpKGpfNoY_%M~9={BkMm=rkzRs7Q5$6<~ugd+@T?0ju1u`H6RqjDhS_`GS?7 z&n-yg_Mn^pu`YBHH`vF(|1JOVDW195M;oJLh`^T0#AbRTj3Hr4Pn+f1u4j3qB>MWI zi89w)D!)xS{zH5Z7u1UW>rBt{g>DgYo969HTT*NU9Gz1Dq7d+!D-O_kmu^E-E@a%Xwe?7 z-Z{`2?hAo&POW#FX1`lqaBe+*v=`Ts$Bz*5B9`7tG{5%D%hAbt>iMAdXm9m)3iT}H z#&yuotEq-#ky#K4$zoa0D?Y9NZ5Aw}8JyR@e0A`AJFP6d*A5eW`2u#?o;UW`1`~N6 ztrYp;_uS6~uZ@SC`H&8=tVb$Rhy_eNiD2Ek#1cW0(BLynT3D;rB42|FkWWSc^cbW7 zOQfZ;nJlaWPLu7$?6hvAGA3lDp!IF3+*=JKeqyl8qK6K3&=O6q64TpmmRgP?hUzEL zPx+jO->sK8YMm?+@b~T!R(zw9e$LiDeh2(5AH-3|F$6guqA^sEJqW)wmNSw=(5DAW zGZ2~Sf&XAyB(nfk*g<>Do#%Ym09`tf#REWbz_v78TAew|EM$7$B`y#0C@zJ=!C5L9 z?ke0Z>^tG-(mm*`cM~mHOIYlcNk6~k=xKkA9vnKoN;+ftKGLH;p|bHSz80;7%Of=cC<}&;RyxQ+!nrPLvfJ<$$9f?le7n(}`I&!0svC{$22Y0Jb|lV)PF8 zh&vf(C2og_5HRWDd(&Iz&3LJ$oEYrX_jWm$LvYAC!i}X(DZ*Z|-ap~a0TDhVT$-`E6x2DiOX z`ls6eu=h919U8ps4p=L)o$PzNuG#oD9=A4LKFwg?SP^5rAD~NMN&&sa8|cRC8<=!w zBYZ34#eZoDov5pbep(fV=l@a~rz)(TRbWlQD@pRoHOPblL+n6(H|39`0fOP591Svo zF4R-)otBpFwY3{y`&oHEyJxuUxF5n!dsyRCaBj2XJ-PEl`2#g|(l2rZ%`=jst5PDn z>~h~*4ZblQa4)a3_AF*Q>*12a(u?-@KCsGdYrAO{&FcD3W1mGWgf5q)gv7ir8RF;E zZE3FjVDz=nOjwMRGi<2+vS;LxN<1}1Ud<`HT~LPtpb#=zXRRMKn6&;LPoZ9wq{MY1 z@bj9KYInjJr+LrIZv%BPvsq8dtKNxl-Ala~TNIf0%X-~G9|NZP;3F$WLrc^6TJBf4 zV*CJrsuE1zA9SJ*&@k>~dBl_T29Tdrga{BbSpEb6Cn>76u{{XicoRo(d$i^C6#sa4 ziGJDF$>-Y0uU1+I&APnz^C@ptUDrIQji(I*>-m}o{Xfioby!qg*EgM#N(s!6A}vaH zh$ty2-62RfNDe6=-O`GL(%mq0he$WlFmwzt%*;33_jBLh6Yuj~*ZbdhU0krwI={8{ z+H3E_%-QFx-v{An9^pwCS6g}qnb%Q&>Fa&kT%u{j z%jXG;4msRSstF0*F{Q>uI`)2TXcW^fJgI&UZ~W&?&(GZxtkzE~eq9Bn2-=3VX-&M< zoRBSY@5LAKI)z`FS8k`5=3?Dq{~#|i5iq?l5qMSGIX92&w8?z&hP-7IcF)@kjt+kK z>(Q)V44}`bDu=FK)d~blNt)C)e)6qpnWIE|a{6NzfMg-nMn>~p)6bwWUB9j+UT<2* zjxjuY8FGPAYg&J^{ih*_ZXb%>3HRyj)c3XLQK{cQcBpDIb?Cpv|KRHt$W;5XbeeL< zXTHSo8*y~oei#|DM#t|^XbW8Ant6%alTQ;hNE#2{mh{d;+rDW%tekEB$o7MUxQ@S1Lz}c5l-%@!3c?$& z7NG-*SXAr2@gdKly%Bf0n&{ei;`J#-d%=zTk)D8b+oEO<=S3+LAw& zNB_Y%F`^-dVc)Cw8j0f50Fmq=&txD{q98Nt;NCspcymb$f3YS~G~qV-L`7D~8@_1~ zOgYZ%4P+#Vx3cz%yNO@QON<+_czVsp4faZ-GlLs5_Vp`md=?-+k8ATdW%3&T5OgTM zs4(wl1UenF7+Tn{0KwB{_)Z0>4A$i$t7$M0(>wUH%3sQ6ZWad@zUh~Rd=esk zly01c9rb8`7t*5;>0;9@uqkHmFL=eV&!a z{R{YL-)Q^d8Z&fHetzmE(b9@y=*Aqp;Qzh2tU8~$Kw)=QHNPS*Z?Nmjg9J!S1kB6N zm*pqbm%?ly2R-xIT$aJgtL3UPB0a_HIaSUrBi9=IUXou0J_Re1eo~w#=7i_{1;MsC z6S@1h z9hcy;)S1F&_WQkIUQZMi*`;lQ1A-{b6XIN5J26(TX(-!$ro=}5!dXM*JN`ikLew5j zR<_5_CU*Xt-}CYSh3EQP#xG^z(2%(aQQ9)ew3kZ+FrPfHO)y>gLCN0xic#PZFn`bD zfB;U`xpm*vT>%9D@D;ACgcF{D44sifUcwXd3{#NN(0YZWNgFS8L6Tg?jmpeBpQW~sgPdS+j;nhK@Ilz=H9Y&q??Cf_;*P#@CGJY=w0_`QZ*VUsC8h?7Ykzw?r1IDRlU`s#QYPD&j;Fh zqOVRK%eyIYl5^G}+m72f8pkKTHw3vP7s^Cn?RGZ=E{}%5vwNFf#BzmQzJlr8z5uK+ zZ@%(!i8tWZj@5f|6FB~HBW-)`Af8og$N!GMk}m&u{zv0iFs-4Hnvd29t=s;q)Q58j zzmaLOJSZ*KPeAO@x`u_GxQtfP7p6+4$=GWy>M_ZD*cqJbPlpZnvUr+vY?aP-t=i-UNs52PD z9^=rN39ORZ?s(|@bgc7hXiIT0`V*GvP8ak}Xl8e;M}PK&>3=rD_aN-?Xq;RU8gV6o zQ#kDowC2mo`)9;uDlQdq{^P9|;mq{q0Kg z=Nt$Vg}uCx@zMEvHve`&Muyl~%QgIzQMeoXQrXS0qO^B|)U=(Ea&An|Y19e(1CKf1 z(hI_yzlIVgXVK1R0(}0LWB+2v!#Ugut$seJ6Ha(kj$v*FrZR@ ztNdl-ZfRKwhJEjklY5InJdP&(oEg<^b|}rw#q~cT7$@h8|KD{f!@dv4$$bxyn^c+> z0}5L;+!Igju-rkHnK{1v$2z{Eb;6rP{>zHK^W*hvl;u{DkaWhd?-+Es#7^OJtBp}g zyIKr8u782oj!+{;%Khc--|nMAcXF{ts)?F8=K#53G&-|KD7Pt>PO;(Se}S$DPy}e8 z|GW_HB)+wDW(FVW%*0no6L;z~SMMdVLY9&Ya%Ah(gZ$g#aR0oRP}dv>F**!*cVYdD z9fCUv$e5T*!mwYxGmh4O}ZUDW}Gg<-Qx>nSy`7U($Y(I3Q|uNlE)3Z=MF*;QBiO?!b5A z%)r}#OYm6uiL!B68}6S*?&NpifS@3hg^vEK4lm+c6Q;jauy5OKq`KZeE1~}z`Dah4 z*+&_zTF1Rledy}UFnk9mAh-j_odrL{^?!o@SI?v9{y&%Chs|8% zN1*@F`mgH_7L)?b-wHDR?Ke3>VH6-4>&;T1e|Y}a$Wi~MNJicLpUedUm1X{KKzy=o z%RcE^4L6m=|2fis!3+35=?Mg8@*ZRA{#3KdF|WoBCA`>_!q#BPI|3eHcy zp&kvzo#rMojbQfOm;B+R~GXA8yP2`;EQ+;$Ci7hKJM7LjM*=~_yi$Uu5s z_ocSDAE_-Pz6dqK=MsNhlOu<~Y!bUY^1le-hY!5Mc>JJxtS=wAbBj78Z)Rz3iN}qG zhAZ+5DhPxbSNgF|3)YxVy($T0jQ|`$t(q-8muF65MuR+%=P2$(-bdN7zzFxxXTjeE zj@B<8;3%K@7?BuB+n3&VPm88p893mLs=mYodm4YcrCd)cy1fBFzky;FKygXp5~LlM9pj4!)h zO&I%r79Nc~3SPcB^!)}BmC-mb^>fTt6Rm!$W<8CcYkYp~jZrx1S)=XtM!e0aeV_aFi7~okel~DOF_?6gJL;pSJpWzhVzs-BRTp_0AbwE zW@f`Ad{G!FiH`R`;Lh7!^WBgKk^Ije=7s-O9K=^Mh`|1)sl3fEo6?%CJ~%6@PJ*@5 zYSWqSHCBIg?D0N+bNYM&F2zFgI_eGh%71O@SC99u57514}lh!9&Hhu_Ub$QQu zL;7sePx8RLF(=x_8WD-QAF?hx9k7HNmV)s&eX3}cHrpwFfF{eglMF=uL3k&V75=t* zymf2rmiWIk-U)sTyNareXnLRIzpR$gtB^8IsF6QK*jtoKH2&B)YwN21Fp@&v_8Klo z=g^!Ced^r7ARyF7@+c`J;haUn=5M~nc`nX%1Liz&0}XCeV4a+^5x29|H2D| z7?Yw>hDZ0ytAFZ!OmUr(Z3Rd*KG#Ze{;{;>%uaBTQo1zpqu{Ob z1DEQiaX+IbA)SV1<;Bvx(a6j$56=8|rk@vz79M*#a)UiG zeIL&6f8q7yGU<%U1xff|v-8I%_C_-Y{~i8IejlNJm4ytzO~9fo$cf6xK+7Y2{V;Xz z+0dY>>mvMD`{g!Kzx`lI+B=Hf#$A6kka4Dnk7Y;q`QmaW9q>}iay0$-cCNr^1~{PZ zWz1T=XDa(MtH%Zp-+vy`jcjmTg2Q+}HupfJ*^3{G!5ugoHR5;ymqj(L*l#}yJMee~ z8wG2xI5D3A&L6fkS{^WLFDBXAY6+3V!wS+VY!}%iZ+!bVS8@=G5*vs(u_yDzj?J** z1e12-*AEg57}=@uLT_EN>*=({1=*q7o3E-oR~bLFIDq>g@f#XHz6+yWZZ#~*2abPr zp>$Lwlf*0p32Z zTSX4Rexc~B8YXmtZr?W0uQV7g-;Q9yg+=~8dKQ<%ASL4;bc=P3e|mp|tzYfm1lvjd z7(nVMpfYZYX;U!#o{3afhySCBoLv(s!r8Hh-Pv=35?K&?(ai04IlSopsTMohxVL*x z&ohW_EvDjLWKT==ElZ7yJ?*1*52m7+!QeG2;)Sj_wNQBkBGu6h(a|6Ll@utyB3L zTB5TDZKo!bj>7H=cNPhEzJ6lHg~dl{Nou}1A#*g?6?&MgfFeID!S8fa>G~j}S&7lkNr}-OJ*hc6aq4(E4vl2hi z4I`h1{$}V7^|Rimq~>#|UU2zRNSJ%47<#8rJrjjHk32CmAT%=&dmiOZ=(-3=xmkSD zOF(MggA(JK8K9h=38tR0A~lCkm@h#{sC;IC+Q>G4i8s1OQEuobup;aJ-JR*e@Fq$p3zCKxQojjuFnzkXey}&aoMX#KWVwfI5 z{m9h-V{3QcTkA#DGW5=ycE88rOGgcll5{=gp1GZo0je@h!LKN1&TwbQ6SGAevqiz~ zMQ2E-Iyve+uG^V+yCAV+u!Is)EC5L#e6>A?$UX92ZI&clA!_%OqiplUSP{cLxtMJm z-sV|#)y9#e4IJxb^wpDlXSsBUBk5_i>Pm9l$cCBY6FAmNb7hAinep`48eNi`=4uhw z_i(7)>e=yJX5bj*YITn(yp>|s(Y;~?XTM%#c77H@*?M%CAg&MnEQAh!n|#T&SyaOg{%^>v*_2cWVUUem%(HZ z>d`={Ll9s8}B1eKC6VeF1)v>*s zq%X#HNLrkkLQEu$;QH?y{d=UrAHdH7Z!@Z_L1NC}GI>SX@BOwQZzi$*@BQ@KRIIoek2Z9?nDhx=Q zRWQyZ(z1D^v5j)Wv2KRh0F1o>o;pPRCAuodMAQf0dd~WNf$bsj>h*5R)}vs z(U4gTNFGv0p<~C|KI*a~^u7s8V^@Qjj_X)7Wa}46SUcQV>KN1xFmFJ7SyE^~#QCYX z!qFN)Qul6w=og^LHe4q--zrl07>V;8c^@hf3^`~=evx?L41X1eWPbv_E|5@IyQvRA zN(J1iEnKpcfoQKlxKT%A0kA?;Vygi%tBCbyhe>p2*`V67*J zP2$eCK?f9{n1<)B>5Lx+u|3U^%@?SDQo~ta;j3N7w7-og1h0sgTY#Q!zM?n*%*6I3$w0OzpQv+OAo`*%V~uw(lK^N z{C=?n_bje%*Fk-P(-;d04#Jbn)099IRAJ~2x_Jjh{sE=lpvSL|3;m$##VNfUe@v+x z?%CAxMu-Q+OH?&HtdD;h6LNpxPKTpkjJ%EY&X5+$&~KMJ?IYnhPZn{MuOgfDBq(Ip z;2rXQdyAdyNB^nza#1<(S-^@HF;emw*{qsdML9ZDfEbz>;3tR#_1Ymp_l%)1suMrL zxmL&DcK&Ta3sz?aJ-G^nK2#C{%#dx4=U}_+Vp4dOSDEbj&|%}JSDH#Gs@V)TR+k1n z(#ZYnV(OioT~~_WYpWaO&>isYc-rBn+Q{IZ*Qbu#XMQPWPmszv->8SBCafL@Z5{0w ze$e8QSYf`gy1DH(L8M8F@qGprjH%q)%2|4LKLuH&z9MRcMnCLO%!JBPAJ$}w!U9YGi z0$O%+p$=X4pP|;*Yt3R&_F*|b2j$F4YYOIH-%p-s7jhdSAD~Ee-(0&NPze+=0Yld- zb@(~(ii*@{)aPI1ra!_9u~@W@4f{lsV_G5kGZreP^(udqiZWZu4>50@T687^zcP3V z7roYPYHngTRKhBrH-G#3wU(BqfTgluE5l<&aUMLmk97QzLz|R-fLhDxB;9X*c(hO!x5y*MvPu zoo2l5u5mt9z9(JtTv2%~1pLI`+qrkfY`Zqj14f=cyrOQkI=$&P;IFruf{|lZMhe3+*T-FN zKb75-*p(vZsLpvk1U=pIcnW?sjg~3!P}QC_$ZN9VH@+k#$7jD_PGE?KQj6p_8GJmc zn(LvAh7b9+AQ84dVpDvtOoahbgZpzAGy1FC)chZQu3oO>{6s85x9ikis=nm0H=Z|o z^JeAzS467nBv>8U8(4s;lHa8iruLc7wD;GA(hPDnL~|SLb(t}2>FeTKC0qW})_UnB z#0yTi)YvA5*anLrRhE&Z2lch!MX1Zd;&fx_m<_H+OCi|vX64+=HuZVuZ_-vt&t8~M z!lUSDt(I#?#4Z$b18c6r6pJ0KQ#_N$gum^*bb*lVnsEJGDy>_kszpLiHXxa`y4jfl z&BuHtB2r^$oiq8uk;H9EuQUF&0c-^)U_5>7$0+gxzI=bb zjLzm=VakiXqO@VdXP!I~zLNEC2ugs{lOcYSV71lsCDmv4RGmTAV*-&u!oS$p;589* zXCpzMDGm$m8!L6IcNT+MhU-c6tQJ}^&a%w8tF|g?D>^N~E*bJ=bNf^hi-%|{qkWc* zjaeS!tevx34uN4MlLm%n`W={%yN0>zx50T+yOng@YbZ~ppY2uILQh}cR?{KBXM~|i zooB>|elyS1k)3tH598bw!v)?cN89{}#!Ac@3s=GgZG0Y&_9GIDM8XWy(lyTG%B?T} zf$#wjAKhrzoH$X3>3tUPh42JIl-4|zL|Gn zm(b!jfas2Y$g;Xd&@6A_+Aa=}jJQ1m5(dVG!jCKQu5>0zfYI#==2E^~IFgi?oeCe2 zM2E*6w5`A8YK^wc@sBI>fRYZ_k`4!9e^d_fziJ>tl?TBE7Sldz(iT#6kpm6|#J+i;xD=`?&(Hp@Sbx?R@#|22!ODu!Nc+RGQ%e%P-sGBMl0; zdct}i$!p`623eZwNRMid?1$9EJ(v#_w84HCJ=lceKT!2JCmK6A8>q^CQuE0mmzu>q z?-|vv!bD)s^)4F;0OoXdW>tWC$xXz=cOrgb4`fpw_r!1a)5B7&k(z=P#Wt@korU#X z$3pD_t9(zLsSi_E5zZkKUbn+dE6ZtmIXV>D=I8LRHl4<2*t;E6A9J!#PMD?O8=lsF zXM|P-bsY_(mwC+f7{X5v@ey-4u zo^Dy2pbgFo^Mj)Szpd~4e9*m-AIuTcY6H#Z-!jX@wS8QMoaceAlIdbb;+MSxlg@=8 zu+q#UT-rlB*{n0v&Tfp=i^JEWMbl{GyiePRuS-sU+|*fq`ly!rMiI5OJNy+zq3V-} zfUecWm%7jMbS0C~w|rt$p(OagqF?HHoH(b*Hl~CVukke7_jydh=lm&ab8Gi`H`!FT zX=_T1Iq81%UuGcsccd1|-~8B|1-`O8@cu~cu#}o`|C0#A{)m*qp$i5%V-XFHktLA4 ziZ%5hTIGQ%VPVJz{s%<(>RtJf>}s-~aLqN9J>sa;&%JS8X;Yq6aS?V3eA6DiesxCa zSp3k?%oO!n!Chr9tCbJz7qJmmE}P+#UI2*OtDY*UtdL#tOpQ|B;abWWazz_IMU{aj z)XpxtXcjH)B`li;jw_0V6oPFufjC( zH>2eG;9C{07g9%z_k0YM)n0}cP(^9;MJ>n_65P^y_9>Z9jb7B{nr*|ypW3(8gx=?7 zXJ_37EPcb8Iu znrhpbrInykr=^x*23^HyH$+2~0m%T)0R(Zv%F2X+0BTQIRw(+-@`E@IdC!@u8~sDs zff~<};EpvS+9Ca_&487$eR|vZ+u68;(<4+(VEc8mjOl#sq}b}A4_jjG`bu(&FBF+G zEhDbCN?CuL6IgefDDm*aHn&Sztu3so=XhV`PUlXEC$}=iP!IK3HjWGO+7nSa@@{A3 zk2;eP>QwWWv|#ksxzKI^^j?^g@E(yjKdV>&me05O1R7GjJyN^y1Iee|F{^Dnu{vwa z`D#X`#>fTJ*RBx44`pel=`J`^XPxK&k$Y%RW3v&xe`T^QN?b#AST#_)V; zaoCb2vg;R=y&_GDB=3}LGu7d)##ivQKkt||cW!=|zgT|7g6r{g^P%N5>J#KLMt^GL zbH-+!GiRqncbnB>Rr28*W7Pg%795OZn=|)`&xAm$3ajZ1nScQkfD2&M4W7D8#rXhLBdWmdJ9v6@7LQj9w3-N5zj{q zmewly3ZtYJ>dSIZgBV3~NO&>tVb)Iq)=_|WS3Ko0)^!74p z5G(BGEI-UN=!3kqbt+<$-68;6y;91K?<8Q4P8>}{w0~SChSFsO!n9+@*Gh;e)CvgG9odsm#Ziq8% zql=LAdr6OC{_jPEE&v{}(Jl!ICnA8ucc|o|@Z19Zj0yHCcL{Ysd2;*AAo^7kl?Z8n zpfoX-3qu@cARXR@Gy^Wi|6YVGLYhjCyS9w(M5M(ygVu=CFCblp?m`r28(@IB@sQzv zEvjIcS*==sShDxg_I0l_5fiT5VgJ`Ax@;NhTO{6Z|C>gVtH$yi|3igk%u_(zWk3t= zh6KYAx)({mkM#dqWFoWN^{&sS0ZbwuOhhCUN&ApiIlBY1|Cw|)`suwms{nD#4H||q zG%uY0y@;#-S;PJZ91^##XOHvydOxyv<_qH#cOWAwnt+mR*uK8SKuG|WBw#-*R-nBv z-NE<4yyS<4+IA0npdApSj^v^PsupmN<7N)2v`-rmHK{Jc%_v9^vCIq$9O-JUxE8Fq z_TaSxpbN&HcUnqR=&lfE;8jGNcW$YhoV`b#z!Z$V=(NPFnEM$`#HozRDPH-kfOP(X z`~ZNfNQ2%0;3Lu?R{)$_8l(h(mr8?d0dRY1kUju@APw>Xz){(~NeUp`pDXbSAhw?? zX$r=eH+lg0r1qC4Mu80k=Ba5yFI9s;>0yKApq1*!I27Ox&(mIdDEzfx3eW&vwV`=gjN5H!LWt z0~2*))^3Z*%{lm)!#Bd|iF2R1)-9yMrNRN)t}g8{yZxc<{!hZk z{HHz;u?@9nkH6J+a^VY?3IWWxxZqdtVnb0$Jlen3MO6U=`$PNNItl=swbTi7CN`4# z?e=)i05~2gI029-tcwoSgq|fc$6}o*%z>L+H^!lKVyDz5Ac}CQ6hNYg7hMI=QA$qu z6pJ)x1pYv^?W6t}z{g?B`P3aM&>cTFtFpQAiosu?!m1H~8idb7HZ^Q$i9J4>8tzGX zJ=k@F#^lyE0Ip1m#90VqUcuY9-L1?_vN zq`yzJ@F`|H%6TMZIBKK3fX<7k!q`@-OY~H35k71VHXr@H;SQA;hzHi8M&cL@>0^eb zyKh{yOJeK;v1iKr_5}|6X#?OdU}6gXbloc!Irn2)Xl5PJq53kn_U$VkCMy;z=5$`T zJ7cP_Ojiq{DA0r1BaG{PoS8m}b_6~Qu->mWZ`&Q8Q#EF-uuNFC0t8Q#BNSfXkA> zWistnBWsvv?=|~QArN@H4(U+Sb$wUw&$6nphwk&v|AW3%#l>ZZ2WbWUB<=!Q1<`p& z9qBA3w8P^`1^r^zL$kVMl0~MsWf`cVU^*r-wqzB&d*52`ITc+my8rTuMUaIl4M?05 z-4MI9;ojV1a6x$AzpDh+e-_z)4N=)=WPnO%w>}>=b~H;3n8oyRcpw65jW8rIBiTsP z-nhMZ1f{q`%*c-dqejf44eNgjcyuwPT1dS)b;do-W^_TE_Rtfo5pTd>ZrpB0>f@lA zt*UoTv3uS0{jl%-*F#kGbf~6J&0W(|I9x355)^-y%Ikm~E=Ia2`v(@In;vhO$pyhf z;knlIVy2rYa-<=d;ZWL%=?+x?TtHEphm~W3(hZK;*}TDVc)m@1VW!0CnSzd+e-$x^c(%U7RBX z+Fp*iluHONG(+QT$|^V8`%Y2D2(KDYAEKy7orj0L3i3jdSKuK}l4Ex@lD15wXStX$ zXFxdx=5a0gm7WNi@g;`wC2{)<$0{WDz`)Sndhigrr`oTxDNNriqnXH{+KeF z@@FSeBg2HjqoTwq0(qLEq{ls6u-7FV{`{yE?)UNUQh0|xPsxhJqqxm+hGyh*pZBwm zf2Vu>X)1oNK~dhVn&WjAwO4A*{bHSONVdS|ER5un*!w5LDF;uj@Q=%A} z-ZlqmW{zYIy(5v^vMPO{P!Qb`_j0GnIet1zE4WTklR{oo>49xGzKH8qB=6eEH`8K8 z)J;isN|Z@jg?O&IKP5tE#yB+L%W_^);+aD*afvaMlXdUC&&as{K9f(sv#l_ZFo&J` zDI|L5`AW+2&H1#k1AH@uB)!dKT$c!_@>~Z*FJU!OIt`Q@D{p+uLH>Itb1b!adG+Bf z*bo$9lRBj5X9wr=v4Z=_MQuMTohPEd9Z4xTgE7QBltM;eY`wg#YP(=@NvSDi7V? z;wc0>v!594RnPZ4%cyNt@u_LmJDaxjD@zeq&Sn!h|01C46I0_!cl17IjvWLy>mw`7 z)&vXg@z+(cHrbR^-X`IBEM?5+Ui&(qRgD=axQwbScNo+EC@7f=^ZN$Qx5M0w%{f3#sg0YlBN>>JH2*>~GC8Yx4IW^SF z0VNx7F|GH%t&U+nRW+yRN0P-M9iZP}~;RwQYpOERr zTX~7R7q#D07&lM}!KG>%VpUl+WT(_=(*DX2-esn+IobGrzSD;ymP@#zFALII6paM3 z^P_n!`&CBgw#G_g;?=&}Z93lmyuyu6KfRvl;TVu-mH)=+m_BlfOlMJu zsR)fMSG&g6Dfzsy^{cq>ytHGn z?N7hI!9R|7&3gR~!fnAt1Eb||d^G*=#@i}vQRZw#@u|0Nk*a05BK&U&9&p?_O=b&dPfk6!I!_S$87a zH5BP5uh3C>lQ#*twU|sd?-QaIDMhephSP~i)Q&{ZGvgmP!6pT_w}bm67jJLVe&jS5 zDv&u(sADxd1MYQoAIb*`JXX3K?u4&~O7HNCaet@RTc2Fjuk$=8ts z2Ypu_Y(QZAv#0dlg~jI_0-p^BYD+iFA&Xz!KR=rnnX(f&66|rPol4PPntsNm@nl-_O$9^;?Bm1jNc4YCndW-B!e0)ZpZaUml zo(k3xI;S2|x5@&>Q@a)>t^3iR5xKt2Hpsf~xn|8NPprf|TT0#VfA^(Ino!HRv*zbb zzM02$!@y&wNmmz5BEC@a#t|QZJcXHQBuud>=WN+EJY^zFAcuLe_--2m%N|K6%IGUh3pulsetM*Q6x ztCbA3q`c(Y1Eg>=Y2a~wbx#onB^PKov>{{D&n5CSbx>(fY;WOQ*^9MO@FEkTc0&@) z7Ts#29L>(l4q~tGhb@j^@FB*p;t@hO5131bRINe$BqZ<_8Tnt5i0`t1bt)LLoxIlY!Li`J|B{^jN4hpP;Tl0I zTiG$}3KsRB`P+X>Q0B@|<_OvVPN7v>gAUHv`2SN{_&?II2`RfNczg_G_HeWx*EnMX zl#ZGIdrGxQN03hEyI9sMSODui+5gPU{!7vxgk2dj1W=-$#N}fA?+Mx|0oa6Q_^A>p zq&t`?ufzXqBKP08*R!}>rcNX}ok)zJ(tPT>2mLe;{w3pg$;XX$3RUQ?INmPWOqW?- z^)^9bFj)9&oN!10<|AfYxev*GbzJs=y`c}PXbE`G6XLqRu`J+th}3?Cf169}W?!K0stYf8US~Z0IpJ( z#>=AO?78&UHXAOxrK9y%ed*slZ3f&pGzWtkWX;^u3b|gdRT*&iZ4em2EJWkyk_Rk) zaj`_qq|SUUtjM!&X$u;FK)$gnequ^a7~CLu*Ys=hF`<7pUIv?r@mIM?V%Yb*iL|JK z@vpxbbJ*TC@ilwoB;yFSfIF#|)pj{ib;3p|OC&C-POGCp^CpNs$Q}${nu;4dS~xOt z6F??Z=Q#WN%^QO*T2S+ctK1G<@V1YP@&s4Oj8T0xaDdz_Wy2M8{QVqZG zXg|=^O8RUEbXLU0T>(iY&P|!JsT0T(uur$!c0xLAHG~PbZD5f@5A`#?i@7h`RbkR5 z$hs(}rP;dLNePZ~yMg_LRgTnuNB>${{w@=(pfDrRb{OsMSh7_A+po<%Thzlk%NLY& zohew~*>Gg;nK5xOs_L1+StBFXVt*WI57Mh1v#OU|MqHh$!eAlk3sru5FJQN6mZ{cM zj~kulSB{UHk4^;|7mQ!At9^ZGzivqD>CW;LN>*KNYis=ShuXat`H#GGZR1La9Of!4 z$~z9Re0F`5p62mYd*Xi;Z&e6epI%OgdCSjiQ@(dpw_MYpztm(J*`#@3G-J>8CaiwK zz9v+Ki>MxuFUJg1_((~03Ou0Ob^k@S$y}|n$*pfu+AEoY%RZ1_dZQ;mJ*;!IsXS8< z?D8#bpv4yFp8C=5e*c3qhC&4Xwd#~1NH$i(6OQi}(gXqij7{6qXgb?bZAz5v`Gwkt zj-H^^`6T6v3-jzjAKZfrD`o5?a@qUD0AhbWYWk_D@^T!;XlO(JL5N`FZ-hS-}O6V$JDs+K9i)u6#`svVp0(^Ep%7(|D1GEsSBR}VSKA3{5 z5BR4h59A18Su;M++nIFxU_z2B-=Nxvhh8x*(Kpnao=piRFN@-+9@l?Y(~F+UI$S#2 zN6SDtd+y3s;&g*I zt`wup*wy%4FU2}uIdkVZGfjermebmCO4KPuLnq6}pDym(Bu`J=l!_+wj0X+NNTkSPRm-m6lF|EN-W-(yk?3ixaedolcypnszo|9GP36V4%#RKhZ&rWcoHa?aJo4JDOfw-I9!jMjNpIe{`u%8SC%R6 z!5j7Iah0ltv|{m})4wQ5L#`~V(#pXjx}boNS32LxE%B=hYP1oC`L8gPFd>*2zax?} z_8$%0JRaCiEKeBm#G^0yC_l6SQ5*Tt7M<#NSaJE~wZkce{k9OFlAGfuE zJH54mpTq(SW4ysNkKiV*g1XPOtB*LYS^!)7{Z;&9tPdFC=-Ft09FpRp4mwUk`q{mM zHcqkpzcup+@fv4ums?GYxq5xTY(ZZ}a|{q_r(GpF#`(vgG{Y)U;skA8;s?3UQecT` zQg>as02SN08qs>LvGR3u9BqWUpy9z_xmDs5cJ829Y*VrdJRK}93`+FK0Qq(%lRpkI z?hf#Hj6a9Vzx}|q#uzIvzF!%pFzc4g3AWVGe}1Av`Y-r@s56jOgb&z|Q52exB?BT? zgCjI~P;aJe`;d`T{a8viCW;i^{eLK$ktL%P`C{c4w=2VsKD1FeOJ$U~Z2|-2m3_JJ z{>i()oh8N7=@zjet9(-t&JinLVljb}DsZdf;HQdkoU55kHpY&;8a9{tkI|v@1Et%U zMkyk{i(*H9-m46!Xk4)to<6o0gn#246BD;DyKU`8AO%dwK#2eDaP<^ZL3TG&gT%0r zd$1#Pj~DfQ(i#x9b1d9lKYO0U38MOqTNwwYB|d44#{5m{geQzehe3=U79iKoxcbK- z26~vVKAqV-7JcsgI;rP|f6i~=uB_}MIo}EIM-NViev=x{3X}ee%0DbHkUE7wn_?_t z+aVPIgk7cgF}59EOLhy*)^sO>vs74}!Y7^*hy2~qKlO`;MYpEx9G;FZ`n(jSwdWkJ zKX-mvc57U{OQ4Mq^aZX((cpIe!@+;jb3!R%5IZ-~<$44Wt8Y7pXGFk-nCPq;dQjzi z!DerYIgu21%JeAZpNK!l_fP6~gI|ku32#F6+uFzIfC^Ho1bC<+UM02pRH%b-G~Jnj z4\-v%3a7c5EMuLMUb zTxMLm?-q^|D_3(L=BOz;>Xf|gNuynDUC9Z)N9;TugSpaj*fZ5<1)>9duk=784usKxZk0BT3prk>q{#7m(=qKjhYOA!Jx!_l(US}&Cw3kc33)~t zBKHN}@vnhHO%tAQ_jCGO=OAK6AG+MBbyDpQ{;3_vu~8*Muh7*axy%LP-%;3a*oCp? zf&Ub)yTyW99RYHg!;BlKkaez;-Zm2pHD{VuZo^1#9pwzx290Bm^No|6sk3fNc!~WJn8SiXd!>fL@gSXv*vXL`R_B5@tf5gIENEqY) zu=XBcO>Im6Fd&GEN)?bUh^RE_QbUm0NpW5Tv)z zYaq!N&%N*YpK|YczyJ4q&+lPpvdYZtnc17{wbowqd#iu(ro(*~z>?M!<+SjUuC3z3 z%>K3WHee5N8e0xImc+fn=FbBJFt!pe68`#%hYNV_b7g$`-2VqQ6&$0ls{fCMc7_(s z_J7y^q4^E`tHp@3_xa9O#&@yB`#~4DdEHSnEVUU!8LEF{e1-EafH6(j{~3r5kVJ%K zo%RUe6!rc;>VVbgxu5?t4?4he#^1EV#@3(ZGm-4Sf4N7v9=%Kmbh&u9*q3RA9!=w{ z^=*5o3wOqJx4r8DcY|jui_b4cDkI!Jecu%R7F97!UZC-l&F&LfC=n-Xx`nF5Qq`ep zzKA%WChd4;J&Z)nztMbR$ot2g7=K8-P}yOy5qdMZvb)ds!*|RYBW+6>lX8lHd{ws` zF>#Cd`3`OYe5p|cMeioGO;SPlX$Dka2j5U?=f1nU3HCe|&GCpb;;A1|U2|RIvn;dC z2qx4Pn+-;_NrQX6+$0KEI(y~A$uDbQ1Jc`QCzj4MWTBkh zC-k{x<9<&jC^sa?>eS$gzt40ammD61Jh(?Tq#AKX9a>k&vf6pX5K6Vn}5m&l$b z4DtJPCrUwn<$a&gL|=-O%&3J*g=l$mF}T|NIscmxKvS8@e8;6&4(>wY(1};^g0iE; zjQA(wqtNt5GLayy5#eLb`tW>2-L3v<*L$Cxw-C#q^ohV96Y&yKJ}!&}H}*uo*}<*l zM$A<#wL>7Z3akC>W-6lYgqjhw=5ejH!+Mh3fW#OLTcM()|gjm zdlcc99@c7@sK^9<3&{#V`K+GYggFY=aDhcf_lOH4+@$ccBNKQ-;L}b%eKbb7ZzhWDWW8y2e|wW<5fz%rX`{ zuv_Bf_lc`}Q8to&dKGl7W2$Ycb3119NA^`yI@IPf*Bn4!UsO~V<=Q>98C>*|HR~Zq z-#3%(jI4q9qLr@?uPeDOA6=bB)3dvDzOAAZyc+l7e4}07@u1N8%sEQ&QzTQ-stx3( z%JMST-`51p^=1E zN%f@|H7-Ck8Zkmuye&>Eyx?iqYdj^ornGbalUoKsJ8kgfy(>=YcneK8qjar?Aor?+ zAoeu@8Xby@KP1SpPfpc^cYb#!RrIRR(Wg3dfR(~1 zz;1V7?tb%0_EcMfX8F&Hh8hrc>%b}w?V(A)w%8tI7&AICbVwDl6m;~0y>AZY?w)S% z<6k;mW$)fRQyM)3DH1E&HHvMMwo#taK;V8%n=;eVfv8#Bz_3eW= zIwH5y(eGrsCEU)>f&q8IHeLhVnxDTC!#(Pmp9V2&@+^hNe5D8v`r!1k2^vYyKK2G^hU4K%s%pTaE7ImipLYcI*U3s&RzWTFidWweKuR z9ZXUo4?bw$uvU-`lwtVv2|w7QT#9)`bE)H_3e;ZkNt$KDysNuUii4Wks7lC0cO^Jp za7G+4GiV*2K9(Wvag&m$4X-yPz0RYn8F}@|jmZ}m z(xWGJJtlo}u#oBT4UrPraH|OI$ex+P8Bxw}ZdM3AcKO%B-&f;5|5z&YxEnmSd2o(u zGk#1FT5hD6;+7wmP8C}qDj|H-4hNi~57Oacd^y`^AF(4Q&gXA8T3GhV^(f6o-iB+6 z>c=v=(}^GXZ=bGc^b*Fp#`zSd_zR&>$0n&mr+lgY9%`npzJ~gbDMNYJ6huXdVr94^ zM8q%S3c%-=09FlAxCmcP0#XwUqT(xhZ=r>TR_$nJSQ_)XH)6DMtfJrdCw z&5J?Tst3jKDyEE8EF6~BZe|=M4iQ^WnK`!wqDXs-;uwK`fcyoRgYu^t$Ue*S8N-U2 z!ff*4!>fZYUQ+yWD-6U;W7#p)?Ofr+&MmBoO%x4Mq9y60v)Mnbbi(uLpNRhqqqTph zllN(r=I0MLsBMU|W`*JDr2t~~fSBXle~imR>2ZDR&9Q-tOpaBdQ4rwVeF?r)X5Qx} zcjlV5r15m}MBgn59<1?Tn|RH@HoW6~=wRrp@0o|W>DG)b>0IAz%JC#T)xxGa-uQ2J z5EyIirPX(@3SG%PYmLk_74&Hf>p@27+Rg9{&@9%BHs0r2dkIYV8rFHfj=GxkoW6yY zyzX^|XP;2v#6g*$o!^SRpF&2b`D+%m-s~6-gOU+QTRnUGMq!hO5%KJ+x2{XaNsmb< z#FT5=FTW-?$xO;hXCFNxvp5LIgZsVvaK}XHIHyFAfdsq0dq=m}2UT2JTC|KxoDzC! z`;e~iw&wM^dE@&~aV~xd9h%$cchugsKS0hRFy9F-xk$rR!m0Aplu^68r5Wyd5igjG zW+->-pE5-MWF)0)GwfJCSo7q|JRfXipv-(33F`B;6gH%zzoGT<`x+9Qpo_Yq-0$t2 zo#|@NzJBhK+gnf;IB}+vVQNRiZVp+;9O=a0jf1r zZ+EQ05L@lHo?>mr53~J?bQ>}SDkv}Ab3gZGei%ZErr#fS{ZzKN!j_p+dO$(wDe?NRXLF+ ztY(oTg)<}&gjM@vdWQ%Go8F+c+D7+klL&-^V7CP|U5Wl6U#)pWbJv>waU`_P%l1oc z^W1{nTOd`FBtI=nKl@k5B1f4tmcH7(*Q?^b9%uG*o@Ua*C*odxOR|;euuLa`6Yv^*G~9xMF8bm@yKo6?^|;*n^cxb zcqZhUTFauESykjGVh;fj%3W+6E~Ij<%Z9H`3WVkDK*O65FG4&eb?4~0!$8{Z(`~bihgXF8+ z7=DQ4tJ)Z5MpjjBz+W6Y_GJT7H->j*fE!#A&)S>Le<(xG4P>1(g_qVy=F;e#g~;ay zg_j&2)aoN!3C@Q{Q(h)0C8{wvc59RSp5Pp~-t^zaIXJrEzkqY_Adq-90Gq|;v+HVB zY8oEnqw{@i)lGji&H>R4|2CWhDA`pBYEgSi*}25Xzob73sIX5&7}65C=t#@d{BhCt zdI<2vemJrlyp117sURl7Nf8?;Ixk*x2_oe3+ji>?GG zCk@v18m^EGf}hD~l?YAD?pIXUkqCY!r|rjnA*iTeCZw$)ba0v3i9w%nYF)6fZ(Hxmuxq@2cv_*s_%MPZ?yHeBVw<-=2 zq^4_wr)${=X=#ZE+#JOChno%}KM8kFlF-^-H(53^U0%Sph@P%3Bc{FQH$DBvwW!(p zLfUY;K6ARhg;8H^QrQ(ycO~ZmgiMm@+a8sl;8dJQGC&v}LKp_xCq+zc4H+SQc95;R zLFsOe1H_7= zn^b~dCD8BXO*;brEDIJLfoI5q2}j^DvS79mc(N>*Y6PAji_y)-*ioY9Uw}O*QQq0W zOxc!q8$#wIaGB#X>{03X%yJ}}1f@WU`l?^~#MsHsod120-mNb2uA=Hv)bTjt+l;>Eu9ilcEwUH(HdBfkW9C&1}pB2a+%Z z{f+}!MuO6=+z=u|bzx~Tly=odi`+4=KN}nCsdh+))Y4D%FSLgH8SM`7?$f?LEOCiM z?0F&U;|(kAzp1$QP)EeN(JruN&M2ntFndD93fSu;XWvv(FMFmI55*~-l3`@b8RK{2 zBoYi1_GLmb%rhX?%bOBR!z_wikI=!SC^F_mvMZ-0%u_Fwc(K66{uQ6%Sa~wc>LJZj zFN*tW1Z~le(B0FMY7Yo+Hmf%SpLlT`08|%PSfkmNlO^}H$uUzsK7}ix_<)zqGLOA@ z4*;@5xU4{>wPiP#DE15QI>ILx*M&jxVhQJ&a{EGk0RS$?LNA$tXX zxSkseirWUt?z@IyQdjA;4mt6GoWmE28A?~fajr(a4@NQ1+J@QCi0yEtQf_w)(M_~q zUH+3gISCC#BkTpZnylUnjYD(C41bB;V>-{nZ;3bt*ZEo|GzLb1S=-<*ku8c6%Zkn6 zi`xCJpJMkOp)g?vMBT^77ye6N&NhG~67$8tHNG+GyewfIpB3=p zsw~kqJ{Eg#kiUU`y@cVx3ii6z<`}sO=)jClUCqc{d7q03?z!xPlU!}%V+2MqEeSrku`Q|#!Oc?p@P{a{%uIL8a*-e9v-Ibg}SVZ#E! zXTNi?U{itsOOilPcSMb-4QNhRm^I;V)8n|`XuEqKXHver8P}NTCd3J6ItyR) zEzUG^Am0pnLOWvqM#4 z_@3#KXr>3{yd^gkygg*kcLDk~waLIYkpzCx$i5}$Q+LkA+I-|SJYj$8av+{|KD176 z2%YKgJk#v(kXR?0w=5HalTTqcRg>Up<8khvxGU4#J?ppbDmeP9gQ1-7x@+m!Z+&C2 zeU%GgJF80#zu1VC{33lQ4${>)B!6-AAi$DzGQTmm!YV}_@tb};SUCqQSUJ$M&2QUf zH)#)jL1)Qo14_`D?O_n>L9$w!>MwF#XNfO!I@_UYDs$Mm10-?q3fl*ex!mhBdrtR^ z{D!6U-K3(MYg=^Brbq?^bkX7<=8?=KSuoj1X1pwzcO)}S7JO?YGgcO(mkqY3L~Yw4 z2@HduDFNHhZZ2Np@B87MOW^uu;xwz_z}W)!$Tu*T_;{UvC}Se}pQ>8l@cYC`pGk=~ zpwH=+SY;Y5L#Xbw55tFNVm;i@WLvzzcb&9-^z=*VFB=6exWlMq(ch`bxQmuhBi^#5 z<|al#*er+VUK>?EK%(HPBO$hy_9&47@&wQBrSn|O=1iSWFdl&?z{Mh(XU_JiCt8EUsJXXqluNB1GFv_d#MBuW>>THgxeWDTbXjAb z19d#n#~0g{r&@_S=L>aFE73F2v3?Wuy*8KIA}w+R1Qr$v3FMDB48B^o8Pfu+h-uw> zI3{P9-w1dh=bS~UphB2Kpu|P6YgvZyaYGAc9#F8L?B^sg;lqvGjvfS%zm9fHvlH{! z=>~i9ky%@jB>tRE3x+oyXj`zYmg~;+(t=O+Q@hu02zT}$Y;}DM8=L6X`1bK*9;|-5 z)Nm3-DI4)VQ-ryK8ql+4Pe0nJo1= zwu@T}hMgZ=__*0E&1QTrUw*x8HCC+&5Dv|LD7M6O8g%mI+mm7Ld_t24Kh;7mtTVRX zOeCq47yhWwo~3WtJLRN`z1kTUhYTDT41TVF)(=yeRE2rs^4X5YQLcBGBh{bQ*lLTR zqja~nJ>UmrEeh$d2GcY8r8t3rfom_=06A`beW&FX^!?KYr%Jns(m%VzqD7_*b`FP$y%xRVdvME%vsn#H2Kr~-3}zjm;bMCA6HxBAxvoCU zW)vlKw4MrR*)lJ32nb0Dp$XN~9KsD2CVmlV*%kjGS{sr{YqJmy65;a4?q!+jFFZmA z_^wU3J>zJR`L;Sk)Om78xP_E-;o=E)9|^zo%Vb^drhfExhn@TDx#$<)>uJZfIwpwa zr608DiZN{8e$sbsppu zYPh=6onkO6kiIJ~f`SNltc9GnlsoTC`-DboGXRWWlkOcNE1}xP9&MkpWIi&83f7@c zkW<@i9?H8q6U~K9g*GPbP&MDnj_<^j{y(OFOurH-d^^4}69+1rZL~S^P}Onk9l4CU zHIN(ilK$Seur~r_Fi-JJq?uyLULQI(M=5F+0iW^LzJ!%HLb+^o#}D;#ori}t007kX z_);YMwvBDOuix(J*|pE+{fYYM&vYm~KNit8hy(p#AGc;fA(@+VjnUa0u+|5CTc4DA z+oVRCLvJc{zS*EQE+eICw zrzf9MD;0F2qPt-OXvNEAW+E1%nSKs4K)A)R>NFMY8*k-8k=OUiY>PCPYZ%8^Vjka* zo-E)%_9yLq4;ju!yU#c5ITm8<5B*fa<;;FUSPr7e3)I)g5_e9Ocz1kszE`s`-ypD4 zIF#-lKP6NPF%+I-X5b_xvNH`AZYB|EL&9yVS<(;vNlTHp~>3`?vmp#3Atk^aJG-#MdEDVUS8Cj)>XBOP+BZ`jGpAr~ zU)HHKYiq&^T3J#U!E*((^xpRNYd@9eVpI&Bf){dT&~*FqMU`ikM2KgE6PLA`ik84- zEkuo<`1_O#2Cbr#i`!wR62AIP%fwEM&79RTuB*CNkG0?O9CAF5!B~Vl^iyqcX5t*+ zbr6woOE&&Tf}(?{w9&L@Zx6Qx=L&D1sFfS%e+X*+7GovhbAm;x03eP(?(f7Q!6)tj zU)&WUY;M^LydJ9B(L;i_zkic##<_J!fTlSon0gNk@Wfpr2%%y!`ZwX5b%00z2Ys;8 z(YMYCg#Ikxm!y?$?&sJvz<<^VtJ*JtSP_5K;kTk!zw~;CeVB8)cK%1Hzl;Aj@i>I) z3yFW*n?IfHuhS0ny&#}$|EnGT-$@MtKD&4IzgYU!jTU39Vg6!JDfAUy+q2)z{yXvC zPV+bGQ~WacBJUEF^0k(~I`*7wi9q#tpJQ!I!d;6^XD<}^CpZ4m!9UG?%xrX0DN}sZ@yks3a2WT|NSbH!cu|#@xW)~e-Glnm;5f_ zua^H;qzC%GV~_fc)$eZoJArlduK?2mTm@nXhw2P5zvdh|Nd7eEkmlz^u}a^a+0@i9 zzZ|<0ga3}CR_0Bs&_2OUn(20RGg5qOQTvj5}dtsoAic|Eg7D$;DF`evwomS2U zmJG=$Sq>l=(B(wQ_*%;sSd6dG(YFb%P`;ac1cj<)g3eAI_PE;ItIceiTNq#N)`2qD z&l(Z^N6Sb0(jl_9z9)G~i;V6kP8!@hqd4*#%N~s-8^)L}B z64{sP@m6m%1tOzZC^>a5zAN}Y_OLqNggP$xlphteQzf7mD$gc-E{(?2Fa{2o{e?E4L-+tN6PN+t`dS0?9^E>ka~%siS_ zt2MrUmL}%D$*2+sZQ1+kt#C=-G{TTTSWGyGkjq@a-1U3s_vX+w3d*=}_;fp3oDn7u zcK3ywENeo+d+RXQlg~Ofue>DE_7Ddgk8?)M3i%{=!UOpW>B5_HB+6!9D)HW9DJ;4l zsr{Iu!leA3 zYrX!}<^Hcf=saGg+vF|jz3l4XQ_2?A3NU|3Me|rhq5R2XQ5lYr_}jA4v)81pH0#&! zb06mE1_})VHp1dE4vdk$yf30YDL>5!i;HJXl4vjMPgW4=8tb(Euy{mprLi)W?>!bK z-6MQd+H%#4(8ojB*od!cY8;e}zcJsQZtji*Y!Ykd$GKdH3C_eSCZg-_SROgOaBD7~ z(vus@>9Uj&pwOs%!9I{b1{8afFE#1aYi`3~D$`9EAW}l^7YmHJCro3Kz?hYR%r2SD z57XQkXM@q0&{VOttFdnL=WwQ5W-=OUu#C9ve2A!AljW^=E0(T$PyP{g{iSH~+Og@G zH*D4$^9a%>wydVWoOMQ1`5@JQj4|>n(Ringa=7T$W^@Ay7-9nmgI7_?6b>b&z)7!Qr4AZIXqvR-bZ{5Ok zw4Fisgq(53sB%wkE63D>`v*^S{WS!cy*bFaBf}o{_8o7$wUnMZF=|TWyfVu7yK+s~ zO0b4hz5uY(hjxwE`k?@WT0ttf`Ud<;j)-L%lSCGEu}eK`?ZMS2DpX@4Tf!JMqf@D= ztgEWi3nMG)RK7~nb2RR@usiYN+Oxp9$sMSYhpbd=_G=YaOnuQQZhiWxkE8r<-l5k? zk~#_d(E8(szy@%C@X@x9pULD`k-~~gnbnfo>?3!Oh{b5HX05hTLTT+AUIUq|Cs`zy z5A0^c$=m>Q{Fr{=H=_PZy3gz9VQ|^}g_%PcZEqhR^M*!!5wc|Osd>&O*3Fwio?cM? z{^qKRZwAf5t6p}nywrl40q#CLBadl)JqNoK_F?xb3nM7BnnOq}4m2gYDbfIZ;ApLz zp+5wG!I#oyTic$l>Qzv!^rb20uRov_B7v0wJtBH3;|g8KXA?rImwg zscubO5RiC?2DhE{{Q@|vE+jY4BF#VX;qKbh#580zmX))L-M-2fY|Y7qt@~N52zzJz z%0;PPiL37UN?85j;c$s5A6dLi=MJS;Z)YXDv)17HMMQ{6MLgKV4RR*-N#7D0k%^#A zq}^&lp>1RxuEl8_!xHLm4!7AhyK{1j4<(7Zv|mM%N7Qiw)4+yH6p$7PjM7xNyae@w zf>`hspGV)-qu18At6HiQ#0>40r&;itk zgjXFxar|o9g|6=dr;GUo2bWHQQ)Con-2A^j7=Ku`B>f(KKa%EJEQyUVAwF#a@}S#^ zrlE&lfS_PvVz9WEA_1vj_(gb}DQ2zf6SYH%tb}eTKQFBKgfG-l&(&20BO$%fO@Vju zhP4OGxz-=>X~(sN{`~7Q!8?HYe)nzkmj~=S7ipyn2s7d=|4Y&&K$bzm^04yNx0m-< ziNki@yEXbfLT`e8YEnpZsl$@!r>SK1%jX?JlEfn|bK+ zhF|znx5g7_bHeP$K{#kKn{C~98f^rNS+Na`IC?X9iYnfs02(||S!Rz%^j!IW z=1};oX;9S(jH2!e#jdH4VH;}l6f^YObBta;93BN7l5aL$xbH2C(B>FBbw%jxMDS^q zFh8UjERS?ITaLDKKBcsQ9TFvGE_hi$&Q{@!$j$@C+n9}#%$5^c*WkLn55oTJsuK*+ zetk_00O2{;tJbQ$-5=Gv4idKsKhIY$2Wnf=ak-}sJ@;*67eYKQk0?-iL<#_r|RL;;g2;}8AuDa)@$SuEa8__Fubz1 zSGSub5Ps=JAH2z;4$T_%=CRqTcG6kAARbT8N-6=M(VF9mLo~Ak`x(_M{iE24M~~It`keeSTsS zs~3BZA7%D)B)Kb3F40<|=Dcg5H2uizz-`K~dEKYC-0a)7gvV`ra%;hl#UpdkCI$EE zJLvsL#yB;1JLQw5^JBmf|#_9z{77U|e>s^qXQP8T4RZyn7pQQOhEPoMQwsdiQKh zcvKd>cikl(m8ol6zSh0-xhnLB&hjv1Le-I7Owyhnrh*YHkB>UMcy=2kNXd4w(Ji2< zX&3VlMBKZ&DAjIU)Ew_Vi3uY;YPy6*N70zcE%0BQD3Is~w`^!=79KT}l=gRV&!G8| zRmNBfnRF((8p4}sFoWCAos6RoW|8j+$&&|EL2=!T@2<5yInmf6rqfCCtKJ?d4XO*O zyEAiV1_IHXk0utAD7S$Z`iakr&kt6mfH)26oi;xX(h3527B{v~Q@iUHlq-}gdV^Y3 z>6`P)YDs&^yC?G{;1l%3Wzz{T4rS^-wOHB~g^ohYS7(%Pr*PkGaxn7RMw&B|f~M9h zo8Tj2O-P&Wg)J0dcPs1KacP6)*yjrOszHUV-IMxL^!I@(*Xe`S=WIpGrVsMy8_rxv zdz3DmRC`s1<*LH3*MS0k9?uEzS2*gHfdOBce{NY2in3C9xMCSVPBh$n)OLDk@wr{G=XTKQjiV)JXtT!T!rIF3_^OvMZ=I_OQ9~4|mAAiA1ciJrW@dMbUkxb{y!xAfI;E z>sDR7X(yUTu!KpCctf_WPROirW#xPm2n(2V})M2p-3EjVbr|3onDQz={i zBzJmwaHKi~Ao;dW%+!o?KoG($>5IEWL;}Q48FWznhoS%~9Bv#VoJJf^+xqG z6x{H9H*D zK2<9a=kLV37990^z#kv~i?V;#|G%mI>pYki2_6~xO3^O;FE*1bTq64X;QtRxy`%z` z+XZ6Z#t|;6aWX!6?}mGRXHh5sj^lsrKM_p(w8}%z-z$-V0-j&%xX(0%<9t1YPcjX6 z={CvVi~i)6zxWBiu{AfGul5)o$%iA46NN*E`y9^+fAK~uX#h*o9NoJce=hoao40>x zL*j%VchGb#@n_SuzXZcR9_A)DQ{X>@%P+ki(f^?hRx{8qW-9v&xKVeC>jFC_4LAqd zFA4t^K@vO}lKB5iNMXb0f7;+Jw7(_-(foc z&FUXx`CjwxW9RG##ioV?a#RPkJ$EB3yWKd;CpblQmmK!0cUO=u5~Np zKB3L~nzm1Lu`CazulT1%>9UjU2}=n|3AnFwL(ugnQ|tbcs=`)&M#}Uiso8=Nepx@*s+ zM}7NNvs105#-^z^`Ue1V>hVRatlHcLsKaYAtNDI_=2+z>dHkQUO-Xs zM4a|SmJg2sm;*sB;(f6<>}DX0TG+eW@8Tnx`f=}QI3Gb28ewC8&(yLUJO5xA`g*NpZ!v}3(r(&%qf6C5)(1o;IG<7x~M~!(?03|0bzxdugBdz zD>%Bz1}`Z;5nJ05vuS?}5rC4Y{17X&{UP-1rPnKKjR}u6F>+CFb2)pflaHON=1F5yRGO=hK~}-R_jaV3zLpU?m(QcxOcPx zK6$RjlK0=J7xtCP-z6+rUrKLddZ}PRm#7fZ2Z+J94wdh{_|l$bEr0UBy>|ylxqQ62 z+}CY8lyh=l0&>h{(g)Ev~;e>{bH!?*08&p1`) zH03n8xU8<|9$8|y=ypX6F&@*@ZH^-~iiZYP2FxS%awf+bgV&0-K!sj@Ld!zwHX;_0 z7=^2m^O5Epzew>&@v?q;LjNrE()Y4)i{Ucso53>2$TZtM?Did6CA_n?A}1d9^tp*U z3*td~80jtK)8UcQEzEsSQN|=KFX1vKZX4n=+J&yj=d= zC5L3W(U>gO#cekAfq(|M$kC}eZV8Q5UO{v##u^Fg zbnV)VMD=&qbaonNRki2@?-rL!lwO$@a?N1p9)*mEdgD=9!@eRG z4TO>(=JKR>q$<;muBS{Vc$uuZU7;Ayyk{l^s}KbM_RlUg>{`P4LcJ0mV_9U-ZjOE0 zy@E1+E(G;T*{$_{bk&-bp;`ZSMG7{Xb5OYRYcBPv9+k+17a+OsU8f{!)Xy^vv-)h( z+;%B5>kQX^Ks%>9Hg<8K6PIEQ(zbJIc3`~oTEam}NliJKa$fcM zaT{AgNf#kjN;EHRzr6)-NgwXyd4MnHLitKCPMheRJx(@>*(tvV=YT`ehsppZxoQTM z0w47~HZ?<$5vb6Kw2hgK)K)-DjoB)&; zR?c}U7Zht9K?T~QiqR5sGMVI*;2*E@i8^&SkY0Jm=f^DkiG0h*^sJY&B5*&QGWo@f z4U+x1J5fu#yUfskA5_?fg!}P$YN2m>$z>*J*T~oujHYi~#9yT~$E$0Ujc3BJJ1s;v z14Ia$JyutQS6N(rThu1llmsMTS##)T=+a@39?cDdyENo4FrO%|=k~u-d(YT|%zyMX zmP`TPjF)Ib;pmCSC@mvgs00+_`^q&peQh?SBrKARa(>3Hm}@n9uiHgJRNKzjF6@!aegxMlFB z|8quu^cO~39%0f~?oXv;)d?b}eBXN1^E%$!tn8EWU>NMP6LGV{3mFkzPNwk5mVTef z_Sy3tO`Y)G<2Al;!`I-hPRc|(P;JPU`Mh!2oa2+C58`ZkDr!AAhzx*Me@1sQyLGh3 zFw`tzM0o84lE0QevN_9C>8{0O>w@MTS1wlniOG+6`=VmB)`;~6ZPL55jYpL}*rhaay>|VldkJ#Uw1c$(u zd%1!;>ww@^+x*4sP9+-8f^HUXzRroIIl{{D1d=;PBrq1=(+jB@&&;N2Z-$Twjly6q zK^m%l#gb)z=CbODe3LHw{MhXEMHaPEP)%@>D~q_enMRE8)L0Im;D=!A%WwC$1rOIT zKL9((B`}6t*v^Z9JE38%mAuU${T&o%cw&v%p^*O_WR0!q z2dHaOzL>uYY|9)X-`~goCz$=ag~G2!(DgIo5BsQV`*?o^ScJQ^{XgjWe>9H}{#Og8 zHf*yiFMo`r6+Rr$>ORdJ&h4ZJ2`*~U;#!?zc)F~M>VzP}<#oWJCFod_tupKSHIRcdEeGbyT*(ly6 zq95Uw6LOHm*=2_PP|=TY#4=rmP)A2IcacM=)gqX?;;%k zf5#M`J#lMw+dm*uc1{XX^aCBI7!}`zW`+ znV2GUp4NL5AJ&I=&Kif;{Cs3;-*I-;`r@yc6Cvkee1!K8Fdaw^QBAs$bmJlR5CS{$ z@fTe9AmB+eiSsusQtG`YG`VB^59mr0@VxV@<4x>g5mJ3!4gNu3+Wa!=gNhI-yIuIb z=1`sCX;X2Hhgu1&lch46SEWNQy_{3*om1pVKxeT}hUWVVwwwiFOLkmj!6-2QDF=P` zoqNl=`Vk;`(q(-JHJnB^V%?4>gH|?z6GE*oN4o5#AF(b^YF5PAHOb7Q$jejg2A$b* zU{{|?_}0H=2c4LaP)&fs}6s9l)?}ulAy6+?f zQW@X+ze88;ll?Y|*5AO?MiC*UvH$%SAA7j{{?eWC8SA2|qw8DMtz3UaLiE@wSX@&%ma?_kxa-doJGmCv>H;P2W<(4kD`sV2AzGoM^oRo2Cx%FYPeVAN;1g z!0cDJ|A=>;j8_0UH+}hE!&a_${xobwgI$U2>Y& zmB~>smC;AG#}9`$B2-s2{g2b>k*C+V=}J#vR#i3>W4P* zCaJ?eIDTFJDOiJxca6_)<=~AbcBVLKWcr5W<9G#}S4L<{MZHH+S% zGqmrn$NS+E0Or6EfR1yQ6qU%0M0BoRRZIsz_CC<2nk7_gy4b{hZD-p)?_@I~L+Iey zvL*e&sg#@!w5k zM;xX;b~s&^%{XKFu`5UYs?dC9gDCn=#JLyOiu~+8MS$+qoeuK8J55f^X}1!;8wx&^ z9DDyrV^HnU>)YxVR%6jM!8h2F?RgY9jPKkkTf7LJt>D13vZfC4Dz@_Iwh_IUF7K=S zJbk!aM^^fQJH>@e7q^G=>7Zob)1svXLrs@q)|mFYyDS8+9N zHS0%9+&j7dSr3}(r=YCxl{jXski9cTkXV1kB;mZh35~S*bnsSyioW9zk}B2anJNWYl|7=TP%K z<0E{`OZ=>h7nLSuX9k~aQ|D!f&X-edMoGbq@-!qu+zHJPXRWT^GTL@=mxO6>AW@mdUa=O ztbir7Ly9B%3<&K;B)<~LIv)Qv(@UiXv`SA;N!N=rh$}90wDb9PnYY`u9N7(n&BE{| z-fhhgfw&E-tOxTG8}1nRFD;PkSZdj570MNj(2zJtJ5S}#}5+fjm6 zCyH+b&$hpx5%ES(KFfF~2IA17+9KtuO51@2>04+5!_+h%$@B_~Z=3{Jmhgn{&*3d3&)0Km~DV7Q5 zM(dquuWW*{q>r=C*pFLpZaLYg9=>z9(z@GyFiQ3s=+>HlqN1{4s@sJhePDK5<%29z z*Z9F$^{P8P)1emcmx2_@GMR@Qj;!y~u0&q+LnC{uFK)S*%@-SrD0y5f7FA2>S_$E) zV18KY%WMB2uJ%XgGl|R~hnh$~nPER8={&0j`*tDt$2%PYg{=^ixkTs4r`734kv%Z` zs%=KdD3M*&c1ac}0J~J@gF`HlozIP?R*0-OKtO9wcVk*<#H=Iz+NZ4Odr+RS4PTf9 z&{DbFF=l|vqyll|?Kks-xuY1jIJk4=4($Ms#bXh&UYOHAMxWMYDw#8e=~ zH1Y|7cH`K9o2N_jlhWPS#$)RMAxEOV%R*cO(YtRy<;x{MfIxQ`1%kIyvoFa7)crVa zkxAlJARj%$&Mgdv$wr(~v)vA86Mdt5$8awSIpBW(|7q(wgPK5;Fuetk;u)$ykRnwM zsTUsQ0-h8pIROpj@F)Qifk-C`s3Fo0I14=}Ri#OdNB|9Yvcs zl=@2JE2lAfN0M1To54nl-W^t^j>_{fZtS`3>j21OtaOFB62!0Lsyu=ZE8k>TsIEKP zVJlBB;ZBcNi_kSe{kjL_)jEnnQD+vqvFr~qGuectd6@cF)n#nMuYU|keUvE+ISS6Q z7W5Vna=PAbv)cviaOkrTdCMQ2z-h5<*pcHgvI}Ptp1mxeU1pa=LSk-j*#4$c5N~&F zYBYNnNSC;`GriXd$;aDZgO{PMNrKZwyxhX;%J6;s!JxK7zdSHF?rEp9xUF%1yQpV- zBi$r6kV?lJh@8$vI2)_A^C?_utB1{%M5ueBm|!&j%nswlmn498fD_mkY-;mJKbrX% z)s?pSph@ZWd;L3D6wL>$c9u)OVa5G;$a2{-Pkx@?Y6*jf43FGNceAR`6sxn+=zqKM z!pNj9APD{Lqg};tV=jzVHDO%0+*h2X>(K*}0UH%?aED$311?zgQu}(PJWO(@^#C#v z3%m*WN(gLWZnqxV1C*>DnIpE4DQBe#3ApY$zbLjMR#3Lk1h}Ngqvu>vg+wdw+O!5` zgqtmMw<(GPx`~SAP?_`FEjshrj8Fwgg{xH+@C9ytP?SaiF;J%;Q$Kl! z=&?J(yGUw@CMACWkO%iP9wxh}oQkkK_WMDS*wW;R^-dc1b`lTUWEiya=>0s(Ot z>&Z~Rw-ULTel5@qh-8PP53n8oreLm_&hV*cds}AS_&%Xwi^#ZeYhXkcmN6$Nr(>Ia1Sl@xldNpMt2 zff+7d4o-y;Ig0#u#vTZ)Q|TeU$Zu|ztuVxWAdpRdicgwBw1mAr_CFWITqvX`yr|~a zIY|Ubf>$`FM!wrqQa;w7wS|*VIO*CAgOW<;%(v^Py7tR!h^1$QtLul3(*%`?TukJP zC8ZdsOqPOXZBH*=Iq!GFEKz%*0n%r!DoVghdY@)Fs!27s^HcS(95Cm%(N{9-5)#?t z8vS9=2fh-(Zl%B}MRI3RLzCN`^8qc^zrL-E3Ldnjqt2}2!0yKjKc&w!&r^8H>xCw3 zL@!MY92+7{jg;Ydvr~qjgS6?eInB0py|VVW{pxw4J)_#TEjJpb4EaSSanF?~2--Hz zxc0pL=K0Y1pPYAIjJ45U_6e_a?9D_Zmyx!>7@cAh?iQ(|(H&{8g3nTS-E_K)KZ^qbr@Sc z<8Bi5+pv76Z#QHJyWNNPR`gD$6ZrjWe^^#D? zc$357?d6=lAII&*R7gO7!joWMl)~PV{Pt`TIbZF(QsQ$o@ivWAxMh`ZZ;c6Xx!JqG z1?tQ`v76=$kp^%rdUd%upBV&XvQWOVG3L^P&$$vGAEj_GQ>eaMb6V$r?OI}%IB%IH zLLI3ilE(Wy|AJq}VU8b$-l>H$1Pfxh_|K&RN2Rzs4!V@$s9_bj&;Nw}1*z=2j-UTG z)&D0r_ihzds!c5a!_EB{|CV-@S~TGYvoDc$W}L{tjPAK0T8K7r&Yu>dN$lwC>L?Ll z-;!kyfSASU-daS3hAomW=~3dsCA* xcb^ubOJolastY >= GB_VIDEO_VERTICAL_PIXELS || !(after || before)) { return; } - if (renderer->lastY >= renderer->wy) { + if (renderer->lastY >= oldWy) { if (!after) { renderer->currentWy -= renderer->lastY; renderer->hasWindow = true; } else if (!before) { if (!renderer->hasWindow) { - if (renderer->lastY > renderer->wy) { - renderer->currentWy = GB_VIDEO_VERTICAL_PIXELS; - } else { - renderer->currentWy = renderer->lastY - renderer->wy; - if (renderer->lastY == renderer->wy && renderer->lastX > renderer->wx) { - ++renderer->currentWy; - } + renderer->currentWy = renderer->lastY - renderer->wy; + if (renderer->lastY >= renderer->wy && renderer->lastX > renderer->wx) { + ++renderer->currentWy; } } else { renderer->currentWy += renderer->lastY; } } else if (renderer->wy != oldWy) { renderer->currentWy += oldWy - renderer->wy; + renderer->hasWindow = true; } } } @@ -508,7 +505,10 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i if (GBRegisterLCDCIsBgEnable(softwareRenderer->lcdc) || softwareRenderer->model >= GB_MODEL_CGB) { int wy = softwareRenderer->wy + softwareRenderer->currentWy; int wx = softwareRenderer->wx + softwareRenderer->currentWx - 7; - if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && wx <= endX) { + if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy == y && wx <= endX) { + softwareRenderer->hasWindow = true; + } + if (softwareRenderer->hasWindow && wx <= endX) { if (wx > 0 && !softwareRenderer->d.disableBG) { GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, wx, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); } From beaa35f35c7605c38fabe5fd4cac53346cfba7f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 9 Mar 2019 15:29:02 -0800 Subject: [PATCH 103/429] GB: Fix boundary condition in GB color lookup (fixes #1348) --- src/gb/overrides.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gb/overrides.c b/src/gb/overrides.c index 51a9bbf71..8e2265662 100644 --- a/src/gb/overrides.c +++ b/src/gb/overrides.c @@ -485,6 +485,8 @@ static const struct GBCartridgeOverride _colorOverrides[] = { // Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A) { 0x61F269CD, GB_MODEL_AUTODETECT, GB_MBC_AUTODETECT, PALETTE(4, 21, 28) }, + + { 0, 0, 0, { 0 } } }; static const struct GBCartridgeOverride _overrides[] = { From 7a2dc0ecea7e987cdfe21013662c6a2180fc1939 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Sun, 10 Mar 2019 14:25:39 +0100 Subject: [PATCH 104/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 179 ++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 82 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index 8e6b08892..ea9bab6b6 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -23,6 +23,13 @@ {projectName} would like to thank the following patrons from Patreon: {projectName} möchte den folgenden Unterstützern auf Patreon danken: + + + © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + © 2013 – 2019 Jeffrey Pfau, lizenziert unter der Mozilla Public License, Version 2.0 +Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. + {patrons} @@ -33,13 +40,6 @@ {projectVersion} {projectVersion} - - - © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 -Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 – 2018 Jeffrey Pfau, lizenziert unter der Mozilla Public License, Version 2.0 -Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - {logo} @@ -133,67 +133,72 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.BattleChip Gate - + Chip name Chip-Name - + Insert Einsetzen - + Save Speichern - + Load Laden - + Add Hinzufügen - + Remove Entfernen - + Gate type Gate-Typ - + Ba&ttleChip Gate Ba&ttleChip Gate - + Progress &Gate Progress &Gate - + Beast &Link Gate Beast &Link Gate - + Inserted Eingesetzt - + Chip ID Chip-ID - + + Update Chip data + Chip-Daten aktualisieren + + + Show advanced Erweiterte Optionen anzeigen @@ -3144,7 +3149,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.QGBA::SettingsView - + Qt Multimedia Qt Multimedia @@ -3174,28 +3179,28 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Keiner (Standbild) - + Keyboard Tastatur - + Controllers Gamepads - + Shortcuts Tastenkürzel - + Shaders Shader - + Select BIOS BIOS auswählen @@ -3272,83 +3277,83 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) - - - + + + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) @@ -3597,11 +3602,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.New multiplayer window Neues Multiplayer-Fenster - - - About - Über - E&xit @@ -3888,7 +3888,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Einstellungen... - + Select folder Ordner auswählen @@ -3897,6 +3897,11 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Add folder to library... Ordner zur Bibliothek hinzufügen... + + + About... + Über... + Bilinear filtering @@ -4417,9 +4422,9 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Protokoll-Datei auswählen - - Game Boy model - Game Boy-Modell + + Camera: + Kamera: @@ -4456,16 +4461,6 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Game Boy Advance (AGB) Game Boy Advance (AGB) - - - Super Game Boy model - Super Game Boy-Modell - - - - Game Boy Color model - Game Boy Color-Modell - Default BG colors: @@ -4491,6 +4486,21 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Super Game Boy borders Super Game Boy-Rahmen + + + Game Boy model: + Game Boy-Modell: + + + + Super Game Boy model: + Super Game Boy-Modell: + + + + Game Boy Color model: + Game Boy Color-Modell: + Camera driver: @@ -4893,86 +4903,91 @@ wenn vorhanden + HEVC (NVENC) + HEVC (NVENC) + + + VP8 VP8 - + VP9 VP9 - + FFV1 FFV1 - + FLAC FLAC - + Opus Opus - + Vorbis Vorbis - + MP3 MP3 - + AAC AAC - + Uncompressed Unkomprimiert - + Bitrate (kbps) Bitrate (kbps) - + VBR VBR - + ABR ABR - + Dimensions Abmessungen - + : : - + × × - + Lock aspect ratio Seitenverhältnis sperren - + Show advanced Erweiterte Optionen anzeigen From 03163b8497f27d99dd11a86d35fb4231797878f4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 12 Mar 2019 18:41:09 -0700 Subject: [PATCH 105/429] Qt: Support Discord Rich Presence --- CHANGES | 1 + CMakeLists.txt | 7 + src/platform/qt/CMakeLists.txt | 6 + src/platform/qt/ConfigController.cpp | 8 +- src/platform/qt/GBAApp.cpp | 21 + src/platform/qt/GBAApp.h | 2 +- src/platform/qt/SettingsView.cpp | 2 + src/platform/qt/SettingsView.ui | 19 +- src/platform/qt/Window.cpp | 12 + src/third-party/discord-rpc/.clang-format | 92 ++++ src/third-party/discord-rpc/.gitignore | 5 + src/third-party/discord-rpc/CMakeLists.txt | 36 ++ src/third-party/discord-rpc/LICENSE | 19 + src/third-party/discord-rpc/README.md | 152 ++++++ .../discord-rpc/include/discord_register.h | 26 + .../discord-rpc/include/discord_rpc.h | 87 +++ .../discord-rpc/src/CMakeLists.txt | 87 +++ src/third-party/discord-rpc/src/backoff.h | 40 ++ src/third-party/discord-rpc/src/connection.h | 19 + .../discord-rpc/src/connection_unix.cpp | 125 +++++ .../discord-rpc/src/connection_win.cpp | 128 +++++ .../src/discord_register_linux.cpp | 102 ++++ .../discord-rpc/src/discord_register_osx.m | 80 +++ .../discord-rpc/src/discord_register_win.cpp | 185 +++++++ .../discord-rpc/src/discord_rpc.cpp | 504 ++++++++++++++++++ src/third-party/discord-rpc/src/dllmain.cpp | 8 + src/third-party/discord-rpc/src/msg_queue.h | 36 ++ .../discord-rpc/src/rpc_connection.cpp | 137 +++++ .../discord-rpc/src/rpc_connection.h | 59 ++ .../discord-rpc/src/serialization.cpp | 245 +++++++++ .../discord-rpc/src/serialization.h | 215 ++++++++ 31 files changed, 2456 insertions(+), 9 deletions(-) create mode 100644 src/third-party/discord-rpc/.clang-format create mode 100644 src/third-party/discord-rpc/.gitignore create mode 100644 src/third-party/discord-rpc/CMakeLists.txt create mode 100644 src/third-party/discord-rpc/LICENSE create mode 100644 src/third-party/discord-rpc/README.md create mode 100644 src/third-party/discord-rpc/include/discord_register.h create mode 100644 src/third-party/discord-rpc/include/discord_rpc.h create mode 100644 src/third-party/discord-rpc/src/CMakeLists.txt create mode 100644 src/third-party/discord-rpc/src/backoff.h create mode 100644 src/third-party/discord-rpc/src/connection.h create mode 100644 src/third-party/discord-rpc/src/connection_unix.cpp create mode 100644 src/third-party/discord-rpc/src/connection_win.cpp create mode 100644 src/third-party/discord-rpc/src/discord_register_linux.cpp create mode 100644 src/third-party/discord-rpc/src/discord_register_osx.m create mode 100644 src/third-party/discord-rpc/src/discord_register_win.cpp create mode 100644 src/third-party/discord-rpc/src/discord_rpc.cpp create mode 100644 src/third-party/discord-rpc/src/dllmain.cpp create mode 100644 src/third-party/discord-rpc/src/msg_queue.h create mode 100644 src/third-party/discord-rpc/src/rpc_connection.cpp create mode 100644 src/third-party/discord-rpc/src/rpc_connection.h create mode 100644 src/third-party/discord-rpc/src/serialization.cpp create mode 100644 src/third-party/discord-rpc/src/serialization.h diff --git a/CHANGES b/CHANGES index a8593d2cc..51628af73 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ Features: - Add Game Boy Color palettes for original Game Boy games - Debugger: Add unary operators and memory dereferencing - GB: Expose platform information to CLI debugger + - Support Discord Rich Presence Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/CMakeLists.txt b/CMakeLists.txt index a3dd284a3..9391ca462 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ set(USE_ELF ON CACHE BOOL "Whether or not to enable ELF support") set(M_CORE_GBA ON CACHE BOOL "Build Game Boy Advance core") set(M_CORE_GB ON CACHE BOOL "Build Game Boy core") set(USE_LZMA ON CACHE BOOL "Whether or not to enable 7-Zip support") +set(USE_DISCORD_RPC ON CACHE BOOL "Whether or not to enable Discord RPC support") set(ENABLE_SCRIPTING ON CACHE BOOL "Whether or not to enable scripting support") set(BUILD_QT ON CACHE BOOL "Build Qt frontend") set(BUILD_SDL ON CACHE BOOL "Build SDL frontend") @@ -724,6 +725,12 @@ if(USE_ELF) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libelf1") endif() +if (USE_DISCORD_RPC) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/discord-rpc discord-rpc) + list(APPEND FEATURES DISCORD_RPC) + include_directories(AFTER ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/discord-rpc/include) +endif() + if(ENABLE_SCRIPTING) list(APPEND ENABLES SCRIPTING) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 36766daf7..a910a97c8 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -214,6 +214,12 @@ if(USE_SQLITE3) library/LibraryTree.cpp) endif() +if(USE_DISCORD_RPC) + message(STATUS What) + list(APPEND QT_LIBRARIES discord-rpc) + list(APPEND SOURCE_FILES DiscordCoordinator.cpp) +endif() + qt5_add_resources(RESOURCES resources.qrc) if(APPLE) set(MACOSX_BUNDLE_ICON_FILE mgba.icns) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 6ea003d32..b176a069f 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -36,7 +36,9 @@ QAction* ConfigOption::addValue(const QString& text, const QVariant& value, QMen QObject::connect(parent, &QAction::destroyed, [this, action, value]() { m_actions.removeAll(qMakePair(action, value)); }); - parent->addAction(action); + if (parent) { + parent->addAction(action); + } m_actions.append(qMakePair(action, value)); return action; } @@ -54,7 +56,9 @@ QAction* ConfigOption::addBoolean(const QString& text, QMenu* parent) { QObject::connect(parent, &QAction::destroyed, [this, action]() { m_actions.removeAll(qMakePair(action, 1)); }); - parent->addAction(action); + if (parent) { + parent->addAction(action); + } m_actions.append(qMakePair(action, 1)); return action; } diff --git a/src/platform/qt/GBAApp.cpp b/src/platform/qt/GBAApp.cpp index 6a25d71c1..32d4d4d9e 100644 --- a/src/platform/qt/GBAApp.cpp +++ b/src/platform/qt/GBAApp.cpp @@ -25,6 +25,10 @@ #include "feature/sqlite3/no-intro.h" #endif +#ifdef USE_DISCORD_RPC +#include "DiscordCoordinator.h" +#endif + using namespace QGBA; static GBAApp* g_app = nullptr; @@ -60,6 +64,19 @@ GBAApp::GBAApp(int& argc, char* argv[], ConfigController* config) LogController::global()->load(m_configController); +#ifdef USE_DISCORD_RPC + ConfigOption* useDiscordPresence = m_configController->addOption("useDiscordPresence"); + useDiscordPresence->addBoolean(tr("Enable Discord Rich Presence")); + useDiscordPresence->connect([](const QVariant& value) { + if (value.toBool()) { + DiscordCoordinator::init(); + } else { + DiscordCoordinator::deinit(); + } + }, this); + m_configController->updateOption("useDiscordPresence"); +#endif + connect(this, &GBAApp::aboutToQuit, this, &GBAApp::cleanup); } @@ -75,6 +92,10 @@ void GBAApp::cleanup() { NoIntroDBDestroy(m_db); } #endif + +#ifdef USE_DISCORD_RPC + DiscordCoordinator::deinit(); +#endif } bool GBAApp::event(QEvent* event) { diff --git a/src/platform/qt/GBAApp.h b/src/platform/qt/GBAApp.h index 0ce099f33..82c25593c 100644 --- a/src/platform/qt/GBAApp.h +++ b/src/platform/qt/GBAApp.h @@ -29,7 +29,7 @@ mLOG_DECLARE_CATEGORY(QT); namespace QGBA { class ConfigController; -class GameController; +class CoreController; class Window; #ifdef USE_SQLITE3 diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 1dbf92d35..c892efc63 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -400,6 +400,7 @@ void SettingsView::updateConfig() { saveSetting("logToFile", m_ui.logToFile); saveSetting("logToStdout", m_ui.logToStdout); saveSetting("logFile", m_ui.logFile); + saveSetting("useDiscordPresence", m_ui.useDiscordPresence); if (m_ui.fastForwardUnbounded->isChecked()) { saveSetting("fastForwardRatio", "-1"); @@ -539,6 +540,7 @@ void SettingsView::reloadConfig() { loadSetting("logToFile", m_ui.logToFile); loadSetting("logToStdout", m_ui.logToStdout); loadSetting("logFile", m_ui.logFile); + loadSetting("useDiscordPresence", m_ui.useDiscordPresence); m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt()); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 792d4b4e8..ea9cab924 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -553,21 +553,21 @@ - + Qt::Horizontal - + Qt::Horizontal - + Automatically save cheats @@ -577,7 +577,7 @@ - + Automatically load cheats @@ -587,7 +587,7 @@ - + Automatically save state @@ -597,7 +597,7 @@ - + Automatically load state @@ -607,6 +607,13 @@ + + + + Enable Discord Rich Presence + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index aef833f42..8ef5b48e7 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -53,6 +53,10 @@ #include "TileView.h" #include "VideoView.h" +#ifdef USE_DISCORD_RPC +#include "DiscordCoordinator.h" +#endif + #include #include #ifdef M_CORE_GB @@ -764,6 +768,10 @@ void Window::gameStarted() { m_audioChannels->addAction(action); } } + +#ifdef USE_DISCORD_RPC + DiscordCoordinator::gameStarted(m_controller); +#endif } void Window::gameStopped() { @@ -803,6 +811,10 @@ void Window::gameStopped() { m_audioProcessor.reset(); } +#ifdef USE_DISCORD_RPC + DiscordCoordinator::gameStopped(); +#endif + emit paused(false); } diff --git a/src/third-party/discord-rpc/.clang-format b/src/third-party/discord-rpc/.clang-format new file mode 100644 index 000000000..1be83906c --- /dev/null +++ b/src/third-party/discord-rpc/.clang-format @@ -0,0 +1,92 @@ +--- +AccessModifierOffset: -4 +AlignAfterOpenBracket: true +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: false +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Stroustrup +BreakBeforeInheritanceComma: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +FixNamespaceComments: true +ForEachMacros: [] +IndentCaseLabels: false +IncludeCategories: + - Regex: '^("|<)stdafx\.h(pp)?("|>)' + Priority: -1 + - Regex: '^<(W|w)indows.h>' + Priority: 1 + - Regex: '^<' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '(_test|_win|_linux|_mac|_ios|_osx|_null)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +PenaltyBreakAssignment: 0 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 9999999 +PointerAlignment: Left +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +--- +Language: Cpp +--- +Language: ObjC +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +--- +Language: Java +BasedOnStyle: Google +BreakAfterJavaFieldAnnotations: true +... diff --git a/src/third-party/discord-rpc/.gitignore b/src/third-party/discord-rpc/.gitignore new file mode 100644 index 000000000..223c07d70 --- /dev/null +++ b/src/third-party/discord-rpc/.gitignore @@ -0,0 +1,5 @@ +/build*/ +/.vscode/ +/thirdparty/ +.vs/ +.DS_Store \ No newline at end of file diff --git a/src/third-party/discord-rpc/CMakeLists.txt b/src/third-party/discord-rpc/CMakeLists.txt new file mode 100644 index 000000000..15bf008e1 --- /dev/null +++ b/src/third-party/discord-rpc/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required (VERSION 3.1.0) +project (DiscordRPC) + +include(GNUInstallDirs) + +# format +file(GLOB_RECURSE ALL_SOURCE_FILES + include/*.h + src/*.cpp src/*.h src/*.c +) + +# thirdparty stuff +execute_process( + COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty + ERROR_QUIET +) + +find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) +if (NOT RAPIDJSONTEST) + message("no rapidjson, download") + set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz) + file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE}) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty + ) + file(REMOVE ${RJ_TAR_FILE}) +endif(NOT RAPIDJSONTEST) + +find_file(RAPIDJSON NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) + +add_library(rapidjson STATIC IMPORTED ${RAPIDJSON}) + +# add subdirs + +add_subdirectory(src) diff --git a/src/third-party/discord-rpc/LICENSE b/src/third-party/discord-rpc/LICENSE new file mode 100644 index 000000000..17fca3d50 --- /dev/null +++ b/src/third-party/discord-rpc/LICENSE @@ -0,0 +1,19 @@ +Copyright 2017 Discord, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/third-party/discord-rpc/README.md b/src/third-party/discord-rpc/README.md new file mode 100644 index 000000000..0aa2d68d4 --- /dev/null +++ b/src/third-party/discord-rpc/README.md @@ -0,0 +1,152 @@ +# Discord RPC + +This is a library for interfacing your game with a locally running Discord desktop client. It's known to work on Windows, macOS, and Linux. You can use the lib directly if you like, or use it as a guide to writing your own if it doesn't suit your game as is. PRs/feedback welcome if you have an improvement everyone might want, or can describe how this doesn't meet your needs. + +Included here are some quick demos that implement the very minimal subset to show current status, and +have callbacks for where a more complete game would do more things (joining, spectating, etc). + +## Documentation + +The most up to date documentation for Rich Presence can always be found on our [developer site](https://discordapp.com/developers/docs/rich-presence/how-to)! If you're interested in rolling your own native implementation of Rich Presence via IPC sockets instead of using our SDK—hey, you've got free time, right?—check out the ["Hard Mode" documentation](https://github.com/discordapp/discord-rpc/blob/master/documentation/hard-mode.md). + +## Basic Usage + +Zeroith, you should be set up to build things because you are a game developer, right? + +First, head on over to the [Discord developers site](https://discordapp.com/developers/applications/me) and make yourself an app. Keep track of `Client ID` -- you'll need it here to pass to the init function. + +### Unity Setup + +If you're a Unity developer looking to integrate Rich Presence into your game, follow this simple guide to get started towards success: + +1. Download the DLLs for any platform that you need from [our releases](https://github.com/discordapp/discord-rpc/releases) +2. In your Unity project, create a `Plugins` folder inside your `Assets` folder if you don't already have one +3. Copy the file `DiscordRpc.cs` from [here](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordRpc.cs) into your `Assets` folder. This is basically your header file for the SDK + +We've got our `Plugins` folder ready, so let's get platform-specific! + +#### Windows + +4. Create `x86` and `x86_64` folders inside `Assets/Plugins/` +5. Copy `discord-rpc-win/win64-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86_64/` +6. Copy `discord-rpc-win/win32-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86/` +7. Click on both DLLs and make sure they are targetting the correct architectures in the Unity editor properties pane +8. Done! + +#### MacOS + +4. Copy `discord-rpc-osx/osx-dynamic/lib/libdiscord-rpc.dylib` to `Assets/Plugins/` +5. Rename `libdiscord-rpc.dylib` to `discord-rpc.bundle` +6. Done! + +#### Linux + +4. Copy `discord-rpc-linux/linux-dynamic-lib/libdiscord-rpc.so` to `Assets/Plugins/` +5. Done! + +You're ready to roll! For code examples on how to interact with the SDK using the `DiscordRpc.cs` header file, check out [our example](https://github.com/discordapp/discord-rpc/blob/master/examples/button-clicker/Assets/DiscordController.cs) + +### From package + +Download a release package for your platform(s) -- they have subdirs with various prebuilt options, select the one you need add `/include` to your compile includes, `/lib` to your linker paths, and link with `discord-rpc`. For the dynamically linked builds, you'll need to ship the associated file along with your game. + +### From repo + +First-eth, you'll want `CMake`. There's a few different ways to install it on your system, and you should refer to [their website](https://cmake.org/install/). Many package managers provide ways of installing CMake as well. + +To make sure it's installed correctly, type `cmake --version` into your flavor of terminal/cmd. If you get a response with a version number, you're good to go! + +There's a [CMake](https://cmake.org/download/) file that should be able to generate the lib for you; Sometimes I use it like this: + +```sh + cd + mkdir build + cd build + cmake .. -DCMAKE_INSTALL_PREFIX= + cmake --build . --config Release --target install +``` + +There is a wrapper build script `build.py` that runs `cmake` with a few different options. + +Usually, I run `build.py` to get things started, then use the generated project files as I work on things. It does depend on `click` library, so do a quick `pip install click` to make sure you have it if you want to run `build.py`. + +There are some CMake options you might care about: + +| flag | default | does | +| ---------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `ENABLE_IO_THREAD` | `ON` | When enabled, we start up a thread to do io processing, if disabled you should call `Discord_UpdateConnection` yourself. | +| `USE_STATIC_CRT` | `OFF` | (Windows) Enable to statically link the CRT, avoiding requiring users install the redistributable package. (The prebuilt binaries enable this option) | +| [`BUILD_SHARED_LIBS`](https://cmake.org/cmake/help/v3.7/variable/BUILD_SHARED_LIBS.html) | `OFF` | Build library as a DLL | +| `WARNINGS_AS_ERRORS` | `OFF` | When enabled, compiles with `-Werror` (on \*nix platforms). | + +## Continuous Builds + +Why do we have three of these? Three times the fun! + +| CI | badge | +| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| TravisCI | [![Build status](https://travis-ci.org/discordapp/discord-rpc.svg?branch=master)](https://travis-ci.org/discordapp/discord-rpc) | +| AppVeyor | [![Build status](https://ci.appveyor.com/api/projects/status/qvkoc0w1c4f4b8tj?svg=true)](https://ci.appveyor.com/project/crmarsh/discord-rpc) | +| Buildkite (internal) | [![Build status](https://badge.buildkite.com/e103d79d247f6776605a15246352a04b8fd83d69211b836111.svg)](https://buildkite.com/discord/discord-rpc) | + +## Sample: send-presence + +This is a text adventure "game" that inits/deinits the connection to Discord, and sends a presence update on each command. + +## Sample: button-clicker + +This is a sample [Unity](https://unity3d.com/) project that wraps a DLL version of the library, and sends presence updates when you click on a button. Run `python build.py unity` in the root directory to build the correct library files and place them in their respective folders. + +## Sample: unrealstatus + +This is a sample [Unreal](https://www.unrealengine.com) project that wraps the DLL version of the library with an Unreal plugin, exposes a blueprint class for interacting with it, and uses that to make a very simple UI. Run `python build.py unreal` in the root directory to build the correct library files and place them in their respective folders. + +### Using the Unreal Engine plugin with your own project + +To use the Rich Presense plugin with Unreal Engine Projects: + +1. Download the latest [release](https://github.com/discordapp/discord-rpc/releases) for each operating system you are targeting and the zipped source code +2. In the source code zip, copy the UE plugin—`examples/unrealstatus/Plugins/discordrpc`—to your project's plugin directory +3. At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create an `Include` folder and copy `discord_rpc.h` and `discord_register.h` to it from the zip +4. Follow the steps below for each OS +5. Build your UE4 project +6. Launch the editor, and enable the Discord plugin. + +#### Windows + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Win64` folder +- Copy `lib/discord-rpc.lib` and `bin/discord-rpc.dll` from `[RELEASE_ZIP]/win64-dynamic` to the `Win64` folder + +#### Mac + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Mac` folder +- Copy `libdiscord-rpc.dylib` from `[RELEASE_ZIP]/osx-dynamic/lib` to the `Mac` folder + +#### Linux + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Linux` folder +- Inside, create another folder `x86_64-unknown-linux-gnu` +- Copy `libdiscord-rpc.so` from `[RELEASE_ZIP]/linux-dynamic/lib` to `Linux/x86_64-unknown-linux-gnu` + +## Wrappers and Implementations + +Below is a table of unofficial, community-developed wrappers for and implementations of Rich Presence in various languages. If you would like to have yours added, please make a pull request adding your repository to the table. The repository should include: + +- The code +- A brief ReadMe of how to use it +- A working example + +###### Rich Presence Wrappers and Implementations + +| Name | Language | +| ------------------------------------------------------------------------- | --------------------------------- | +| [Discord RPC C#](https://github.com/Lachee/discord-rpc-csharp) | C# | +| [Discord RPC D](https://github.com/voidblaster/discord-rpc-d) | [D](https://dlang.org/) | +| [discord-rpc.jar](https://github.com/Vatuu/discord-rpc 'Discord-RPC.jar') | Java | +| [java-discord-rpc](https://github.com/MinnDevelopment/java-discord-rpc) | Java | +| [Discord-IPC](https://github.com/jagrosh/DiscordIPC) | Java | +| [Discord Rich Presence](https://npmjs.org/discord-rich-presence) | JavaScript | +| [drpc4k](https://github.com/Bluexin/drpc4k) | [Kotlin](https://kotlinlang.org/) | +| [lua-discordRPC](https://github.com/pfirsich/lua-discordRPC) | LuaJIT (FFI) | +| [pypresence](https://github.com/qwertyquerty/pypresence) | [Python](https://python.org/) | +| [SwordRPC](https://github.com/Azoy/SwordRPC) | [Swift](https://swift.org) | diff --git a/src/third-party/discord-rpc/include/discord_register.h b/src/third-party/discord-rpc/include/discord_register.h new file mode 100644 index 000000000..16fb42f32 --- /dev/null +++ b/src/third-party/discord-rpc/include/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/src/third-party/discord-rpc/include/discord_rpc.h b/src/third-party/discord-rpc/include/discord_rpc.h new file mode 100644 index 000000000..3e1441e05 --- /dev/null +++ b/src/third-party/discord-rpc/include/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordUser { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordUser; + +typedef struct DiscordEventHandlers { + void (*ready)(const DiscordUser* request); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordUser* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/src/third-party/discord-rpc/src/CMakeLists.txt b/src/third-party/discord-rpc/src/CMakeLists.txt new file mode 100644 index 000000000..f83a119bc --- /dev/null +++ b/src/third-party/discord-rpc/src/CMakeLists.txt @@ -0,0 +1,87 @@ +include_directories(${PROJECT_SOURCE_DIR}/include) + +option(ENABLE_IO_THREAD "Start up a separate I/O thread, otherwise I'd need to call an update function" ON) +option(USE_STATIC_CRT "Use /MT[d] for dynamic library" OFF) +option(WARNINGS_AS_ERRORS "When enabled, compiles with `-Werror` (on *nix platforms)." OFF) + +set(CMAKE_CXX_STANDARD 14) + +set(BASE_RPC_SRC + ${PROJECT_SOURCE_DIR}/include/discord_rpc.h + discord_rpc.cpp + ${PROJECT_SOURCE_DIR}/include/discord_register.h + rpc_connection.h + rpc_connection.cpp + serialization.h + serialization.cpp + connection.h + backoff.h + msg_queue.h +) + +if(WIN32) + add_definitions(-DDISCORD_WINDOWS) + set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_win.cpp discord_register_win.cpp) + add_library(discord-rpc STATIC ${BASE_RPC_SRC}) + if (MSVC) + if(USE_STATIC_CRT) + foreach(CompilerFlag + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELEASE + CMAKE_C_FLAGS + CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_RELEASE) + string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") + endforeach() + endif(USE_STATIC_CRT) + target_compile_options(discord-rpc PRIVATE /EHsc + /Wall + /wd4100 # unreferenced formal parameter + /wd4514 # unreferenced inline + /wd4625 # copy constructor deleted + /wd5026 # move constructor deleted + /wd4626 # move assignment operator deleted + /wd4668 # not defined preprocessor macro + /wd4710 # function not inlined + /wd4711 # function was inlined + /wd4820 # structure padding + /wd4946 # reinterpret_cast used between related classes + /wd5027 # move assignment operator was implicitly defined as deleted + ) + endif(MSVC) + target_link_libraries(discord-rpc PRIVATE psapi advapi32) +endif(WIN32) + +if(UNIX) + set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_unix.cpp) + + if (APPLE) + add_definitions(-DDISCORD_OSX) + set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_osx.m) + else (APPLE) + add_definitions(-DDISCORD_LINUX) + set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_linux.cpp) + endif(APPLE) + + add_library(discord-rpc STATIC ${BASE_RPC_SRC}) + target_link_libraries(discord-rpc PUBLIC pthread) + + if (${WARNINGS_AS_ERRORS}) + target_compile_options(discord-rpc PRIVATE -Werror) + endif (${WARNINGS_AS_ERRORS}) + + if (${BUILD_SHARED_LIBS}) + target_compile_options(discord-rpc PRIVATE -fPIC) + endif (${BUILD_SHARED_LIBS}) + + if (APPLE) + target_link_libraries(discord-rpc PRIVATE "-framework AppKit") + endif (APPLE) +endif(UNIX) + +target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include) + +if (NOT ${ENABLE_IO_THREAD}) + target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DISABLE_IO_THREAD) +endif (NOT ${ENABLE_IO_THREAD}) diff --git a/src/third-party/discord-rpc/src/backoff.h b/src/third-party/discord-rpc/src/backoff.h new file mode 100644 index 000000000..a3e736fb7 --- /dev/null +++ b/src/third-party/discord-rpc/src/backoff.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include + +struct Backoff { + int64_t minAmount; + int64_t maxAmount; + int64_t current; + int fails; + std::mt19937_64 randGenerator; + std::uniform_real_distribution<> randDistribution; + + double rand01() { return randDistribution(randGenerator); } + + Backoff(int64_t min, int64_t max) + : minAmount(min) + , maxAmount(max) + , current(min) + , fails(0) + , randGenerator((uint64_t)time(0)) + { + } + + void reset() + { + fails = 0; + current = minAmount; + } + + int64_t nextDelay() + { + ++fails; + int64_t delay = (int64_t)((double)current * 2.0 * rand01()); + current = std::min(current + delay, maxAmount); + return current; + } +}; diff --git a/src/third-party/discord-rpc/src/connection.h b/src/third-party/discord-rpc/src/connection.h new file mode 100644 index 000000000..a8f99b9f1 --- /dev/null +++ b/src/third-party/discord-rpc/src/connection.h @@ -0,0 +1,19 @@ +#pragma once + +// This is to wrap the platform specific kinds of connect/read/write. + +#include +#include + +// not really connectiony, but need per-platform +int GetProcessId(); + +struct BaseConnection { + static BaseConnection* Create(); + static void Destroy(BaseConnection*&); + bool isOpen{false}; + bool Open(); + bool Close(); + bool Write(const void* data, size_t length); + bool Read(void* data, size_t length); +}; diff --git a/src/third-party/discord-rpc/src/connection_unix.cpp b/src/third-party/discord-rpc/src/connection_unix.cpp new file mode 100644 index 000000000..85dace3cc --- /dev/null +++ b/src/third-party/discord-rpc/src/connection_unix.cpp @@ -0,0 +1,125 @@ +#include "connection.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int GetProcessId() +{ + return ::getpid(); +} + +struct BaseConnectionUnix : public BaseConnection { + int sock{-1}; +}; + +static BaseConnectionUnix Connection; +static sockaddr_un PipeAddr{}; +#ifdef MSG_NOSIGNAL +static int MsgFlags = MSG_NOSIGNAL; +#else +static int MsgFlags = 0; +#endif + +static const char* GetTempPath() +{ + const char* temp = getenv("XDG_RUNTIME_DIR"); + temp = temp ? temp : getenv("TMPDIR"); + temp = temp ? temp : getenv("TMP"); + temp = temp ? temp : getenv("TEMP"); + temp = temp ? temp : "/tmp"; + return temp; +} + +/*static*/ BaseConnection* BaseConnection::Create() +{ + PipeAddr.sun_family = AF_UNIX; + return &Connection; +} + +/*static*/ void BaseConnection::Destroy(BaseConnection*& c) +{ + auto self = reinterpret_cast(c); + self->Close(); + c = nullptr; +} + +bool BaseConnection::Open() +{ + const char* tempPath = GetTempPath(); + auto self = reinterpret_cast(this); + self->sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (self->sock == -1) { + return false; + } + fcntl(self->sock, F_SETFL, O_NONBLOCK); +#ifdef SO_NOSIGPIPE + int optval = 1; + setsockopt(self->sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)); +#endif + + for (int pipeNum = 0; pipeNum < 10; ++pipeNum) { + snprintf( + PipeAddr.sun_path, sizeof(PipeAddr.sun_path), "%s/discord-ipc-%d", tempPath, pipeNum); + int err = connect(self->sock, (const sockaddr*)&PipeAddr, sizeof(PipeAddr)); + if (err == 0) { + self->isOpen = true; + return true; + } + } + self->Close(); + return false; +} + +bool BaseConnection::Close() +{ + auto self = reinterpret_cast(this); + if (self->sock == -1) { + return false; + } + close(self->sock); + self->sock = -1; + self->isOpen = false; + return true; +} + +bool BaseConnection::Write(const void* data, size_t length) +{ + auto self = reinterpret_cast(this); + + if (self->sock == -1) { + return false; + } + + ssize_t sentBytes = send(self->sock, data, length, MsgFlags); + if (sentBytes < 0) { + Close(); + } + return sentBytes == (ssize_t)length; +} + +bool BaseConnection::Read(void* data, size_t length) +{ + auto self = reinterpret_cast(this); + + if (self->sock == -1) { + return false; + } + + int res = (int)recv(self->sock, data, length, MsgFlags); + if (res < 0) { + if (errno == EAGAIN) { + return false; + } + Close(); + } + else if (res == 0) { + Close(); + } + return res == (int)length; +} diff --git a/src/third-party/discord-rpc/src/connection_win.cpp b/src/third-party/discord-rpc/src/connection_win.cpp new file mode 100644 index 000000000..2dd2750c0 --- /dev/null +++ b/src/third-party/discord-rpc/src/connection_win.cpp @@ -0,0 +1,128 @@ +#include "connection.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOSERVICE +#define NOIME +#include +#include + +int GetProcessId() +{ + return (int)::GetCurrentProcessId(); +} + +struct BaseConnectionWin : public BaseConnection { + HANDLE pipe{INVALID_HANDLE_VALUE}; +}; + +static BaseConnectionWin Connection; + +/*static*/ BaseConnection* BaseConnection::Create() +{ + return &Connection; +} + +/*static*/ void BaseConnection::Destroy(BaseConnection*& c) +{ + auto self = reinterpret_cast(c); + self->Close(); + c = nullptr; +} + +bool BaseConnection::Open() +{ + wchar_t pipeName[]{L"\\\\?\\pipe\\discord-ipc-0"}; + const size_t pipeDigit = sizeof(pipeName) / sizeof(wchar_t) - 2; + pipeName[pipeDigit] = L'0'; + auto self = reinterpret_cast(this); + for (;;) { + self->pipe = ::CreateFileW( + pipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); + if (self->pipe != INVALID_HANDLE_VALUE) { + self->isOpen = true; + return true; + } + + auto lastError = GetLastError(); + if (lastError == ERROR_FILE_NOT_FOUND) { + if (pipeName[pipeDigit] < L'9') { + pipeName[pipeDigit]++; + continue; + } + } + else if (lastError == ERROR_PIPE_BUSY) { + if (!WaitNamedPipeW(pipeName, 10000)) { + return false; + } + continue; + } + return false; + } +} + +bool BaseConnection::Close() +{ + auto self = reinterpret_cast(this); + ::CloseHandle(self->pipe); + self->pipe = INVALID_HANDLE_VALUE; + self->isOpen = false; + return true; +} + +bool BaseConnection::Write(const void* data, size_t length) +{ + if (length == 0) { + return true; + } + auto self = reinterpret_cast(this); + assert(self); + if (!self) { + return false; + } + if (self->pipe == INVALID_HANDLE_VALUE) { + return false; + } + assert(data); + if (!data) { + return false; + } + const DWORD bytesLength = (DWORD)length; + DWORD bytesWritten = 0; + return ::WriteFile(self->pipe, data, bytesLength, &bytesWritten, nullptr) == TRUE && + bytesWritten == bytesLength; +} + +bool BaseConnection::Read(void* data, size_t length) +{ + assert(data); + if (!data) { + return false; + } + auto self = reinterpret_cast(this); + assert(self); + if (!self) { + return false; + } + if (self->pipe == INVALID_HANDLE_VALUE) { + return false; + } + DWORD bytesAvailable = 0; + if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr)) { + if (bytesAvailable >= length) { + DWORD bytesToRead = (DWORD)length; + DWORD bytesRead = 0; + if (::ReadFile(self->pipe, data, bytesToRead, &bytesRead, nullptr) == TRUE) { + assert(bytesToRead == bytesRead); + return true; + } + else { + Close(); + } + } + } + else { + Close(); + } + return false; +} diff --git a/src/third-party/discord-rpc/src/discord_register_linux.cpp b/src/third-party/discord-rpc/src/discord_register_linux.cpp new file mode 100644 index 000000000..09911dcc6 --- /dev/null +++ b/src/third-party/discord-rpc/src/discord_register_linux.cpp @@ -0,0 +1,102 @@ +#include "discord_rpc.h" +#include "discord_register.h" +#include + +#include +#include +#include +#include +#include +#include + +static bool Mkdir(const char* path) +{ + int result = mkdir(path, 0755); + if (result == 0) { + return true; + } + if (errno == EEXIST) { + return true; + } + return false; +} + +// we want to register games so we can run them from Discord client as discord-:// +extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) +{ + // Add a desktop file and update some mime handlers so that xdg-open does the right thing. + + const char* home = getenv("HOME"); + if (!home) { + return; + } + + char exePath[1024]; + if (!command || !command[0]) { + ssize_t size = readlink("/proc/self/exe", exePath, sizeof(exePath)); + if (size <= 0 || size >= (ssize_t)sizeof(exePath)) { + return; + } + exePath[size] = '\0'; + command = exePath; + } + + const char* destopFileFormat = "[Desktop Entry]\n" + "Name=Game %s\n" + "Exec=%s %%u\n" // note: it really wants that %u in there + "Type=Application\n" + "NoDisplay=true\n" + "Categories=Discord;Games;\n" + "MimeType=x-scheme-handler/discord-%s;\n"; + char desktopFile[2048]; + int fileLen = snprintf( + desktopFile, sizeof(desktopFile), destopFileFormat, applicationId, command, applicationId); + if (fileLen <= 0) { + return; + } + + char desktopFilename[256]; + snprintf(desktopFilename, sizeof(desktopFilename), "/discord-%s.desktop", applicationId); + + char desktopFilePath[1024]; + snprintf(desktopFilePath, sizeof(desktopFilePath), "%s/.local", home); + if (!Mkdir(desktopFilePath)) { + return; + } + strcat(desktopFilePath, "/share"); + if (!Mkdir(desktopFilePath)) { + return; + } + strcat(desktopFilePath, "/applications"); + if (!Mkdir(desktopFilePath)) { + return; + } + strcat(desktopFilePath, desktopFilename); + + FILE* fp = fopen(desktopFilePath, "w"); + if (fp) { + fwrite(desktopFile, 1, fileLen, fp); + fclose(fp); + } + else { + return; + } + + char xdgMimeCommand[1024]; + snprintf(xdgMimeCommand, + sizeof(xdgMimeCommand), + "xdg-mime default discord-%s.desktop x-scheme-handler/discord-%s", + applicationId, + applicationId); + if (system(xdgMimeCommand) < 0) { + fprintf(stderr, "Failed to register mime handler\n"); + } +} + +extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, + const char* steamId) +{ + char command[256]; + sprintf(command, "xdg-open steam://rungameid/%s", steamId); + Discord_Register(applicationId, command); +} diff --git a/src/third-party/discord-rpc/src/discord_register_osx.m b/src/third-party/discord-rpc/src/discord_register_osx.m new file mode 100644 index 000000000..d71010286 --- /dev/null +++ b/src/third-party/discord-rpc/src/discord_register_osx.m @@ -0,0 +1,80 @@ +#include +#include + +#import + +#include "discord_register.h" + +static void RegisterCommand(const char* applicationId, const char* command) +{ + // There does not appear to be a way to register arbitrary commands on OSX, so instead we'll save the command + // to a file in the Discord config path, and when it is needed, Discord can try to load the file there, open + // the command therein (will pass to js's window.open, so requires a url-like thing) + + // Note: will not work for sandboxed apps + NSString *home = NSHomeDirectory(); + if (!home) { + return; + } + + NSString *path = [[[[[[home stringByAppendingPathComponent:@"Library"] + stringByAppendingPathComponent:@"Application Support"] + stringByAppendingPathComponent:@"discord"] + stringByAppendingPathComponent:@"games"] + stringByAppendingPathComponent:[NSString stringWithUTF8String:applicationId]] + stringByAppendingPathExtension:@"json"]; + [[NSFileManager defaultManager] createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil]; + + NSString *jsonBuffer = [NSString stringWithFormat:@"{\"command\": \"%s\"}", command]; + [jsonBuffer writeToFile:path atomically:NO encoding:NSUTF8StringEncoding error:nil]; +} + +static void RegisterURL(const char* applicationId) +{ + char url[256]; + snprintf(url, sizeof(url), "discord-%s", applicationId); + CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8); + + NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier]; + if (!myBundleId) { + fprintf(stderr, "No bundle id found\n"); + return; + } + + NSURL* myURL = [[NSBundle mainBundle] bundleURL]; + if (!myURL) { + fprintf(stderr, "No bundle url found\n"); + return; + } + + OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId); + if (status != noErr) { + fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status); + return; + } + + status = LSRegisterURL((__bridge CFURLRef)myURL, true); + if (status != noErr) { + fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status); + } +} + +void Discord_Register(const char* applicationId, const char* command) +{ + if (command) { + RegisterCommand(applicationId, command); + } + else { + // raii lite + @autoreleasepool { + RegisterURL(applicationId); + } + } +} + +void Discord_RegisterSteamGame(const char* applicationId, const char* steamId) +{ + char command[256]; + snprintf(command, 256, "steam://rungameid/%s", steamId); + Discord_Register(applicationId, command); +} diff --git a/src/third-party/discord-rpc/src/discord_register_win.cpp b/src/third-party/discord-rpc/src/discord_register_win.cpp new file mode 100644 index 000000000..e441318dd --- /dev/null +++ b/src/third-party/discord-rpc/src/discord_register_win.cpp @@ -0,0 +1,185 @@ +#include "discord_rpc.h" +#include "discord_register.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOSERVICE +#define NOIME +#include +#include +#include +#include + +/** + * Updated fixes for MinGW and WinXP + * This block is written the way it does not involve changing the rest of the code + * Checked to be compiling + * 1) strsafe.h belongs to Windows SDK and cannot be added to MinGW + * #include guarded, functions redirected to substitutes + * 2) RegSetKeyValueW and LSTATUS are not declared in + * The entire function is rewritten + */ +#ifdef __MINGW32__ +/// strsafe.h fixes +static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) +{ + HRESULT ret; + va_list va; + va_start(va, pszFormat); + cbDest /= 2; // Size is divided by 2 to convert from bytes to wide characters - causes segfault + // othervise + ret = vsnwprintf(pszDest, cbDest, pszFormat, va); + pszDest[cbDest - 1] = 0; // Terminate the string in case a buffer overflow; -1 will be returned + va_end(va); + return ret; +} +#else +#include +#endif // __MINGW32__ + +/// winreg.h fixes +#ifndef LSTATUS +#define LSTATUS LONG +#endif +#ifdef RegSetKeyValueW +#undefine RegSetKeyValueW +#endif +#define RegSetKeyValueW regset +static LSTATUS regset(HKEY hkey, + LPCWSTR subkey, + LPCWSTR name, + DWORD type, + const void* data, + DWORD len) +{ + HKEY htkey = hkey, hsubkey = nullptr; + LSTATUS ret; + if (subkey && subkey[0]) { + if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) != + ERROR_SUCCESS) + return ret; + htkey = hsubkey; + } + ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len); + if (hsubkey && hsubkey != hkey) + RegCloseKey(hsubkey); + return ret; +} + +static void Discord_RegisterW(const wchar_t* applicationId, const wchar_t* command) +{ + // https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx + // we want to register games so we can run them as discord-:// + // Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. + + wchar_t exeFilePath[MAX_PATH]; + DWORD exeLen = GetModuleFileNameW(nullptr, exeFilePath, MAX_PATH); + wchar_t openCommand[1024]; + + if (command && command[0]) { + StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", command); + } + else { + // StringCbCopyW(openCommand, sizeof(openCommand), exeFilePath); + StringCbPrintfW(openCommand, sizeof(openCommand), L"%s", exeFilePath); + } + + wchar_t protocolName[64]; + StringCbPrintfW(protocolName, sizeof(protocolName), L"discord-%s", applicationId); + wchar_t protocolDescription[128]; + StringCbPrintfW( + protocolDescription, sizeof(protocolDescription), L"URL:Run game %s protocol", applicationId); + wchar_t urlProtocol = 0; + + wchar_t keyName[256]; + StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%s", protocolName); + HKEY key; + auto status = + RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, nullptr, 0, KEY_WRITE, nullptr, &key, nullptr); + if (status != ERROR_SUCCESS) { + fprintf(stderr, "Error creating key\n"); + return; + } + DWORD len; + LSTATUS result; + len = (DWORD)lstrlenW(protocolDescription) + 1; + result = + RegSetKeyValueW(key, nullptr, nullptr, REG_SZ, protocolDescription, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + len = (DWORD)lstrlenW(protocolDescription) + 1; + result = RegSetKeyValueW(key, nullptr, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + result = RegSetKeyValueW( + key, L"DefaultIcon", nullptr, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing icon\n"); + } + + len = (DWORD)lstrlenW(openCommand) + 1; + result = RegSetKeyValueW( + key, L"shell\\open\\command", nullptr, REG_SZ, openCommand, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing command\n"); + } + RegCloseKey(key); +} + +extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command) +{ + wchar_t appId[32]; + MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); + + wchar_t openCommand[1024]; + const wchar_t* wcommand = nullptr; + if (command && command[0]) { + const auto commandBufferLen = sizeof(openCommand) / sizeof(*openCommand); + MultiByteToWideChar(CP_UTF8, 0, command, -1, openCommand, commandBufferLen); + wcommand = openCommand; + } + + Discord_RegisterW(appId, wcommand); +} + +extern "C" DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, + const char* steamId) +{ + wchar_t appId[32]; + MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); + + wchar_t wSteamId[32]; + MultiByteToWideChar(CP_UTF8, 0, steamId, -1, wSteamId, 32); + + HKEY key; + auto status = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Valve\\Steam", 0, KEY_READ, &key); + if (status != ERROR_SUCCESS) { + fprintf(stderr, "Error opening Steam key\n"); + return; + } + + wchar_t steamPath[MAX_PATH]; + DWORD pathBytes = sizeof(steamPath); + status = RegQueryValueExW(key, L"SteamExe", nullptr, nullptr, (BYTE*)steamPath, &pathBytes); + RegCloseKey(key); + if (status != ERROR_SUCCESS || pathBytes < 1) { + fprintf(stderr, "Error reading SteamExe key\n"); + return; + } + + DWORD pathChars = pathBytes / sizeof(wchar_t); + for (DWORD i = 0; i < pathChars; ++i) { + if (steamPath[i] == L'/') { + steamPath[i] = L'\\'; + } + } + + wchar_t command[1024]; + StringCbPrintfW(command, sizeof(command), L"\"%s\" steam://rungameid/%s", steamPath, wSteamId); + + Discord_RegisterW(appId, command); +} diff --git a/src/third-party/discord-rpc/src/discord_rpc.cpp b/src/third-party/discord-rpc/src/discord_rpc.cpp new file mode 100644 index 000000000..03924538c --- /dev/null +++ b/src/third-party/discord-rpc/src/discord_rpc.cpp @@ -0,0 +1,504 @@ +#include "discord_rpc.h" + +#include "backoff.h" +#include "discord_register.h" +#include "msg_queue.h" +#include "rpc_connection.h" +#include "serialization.h" + +#include +#include +#include + +#ifndef DISCORD_DISABLE_IO_THREAD +#include +#include +#endif + +constexpr size_t MaxMessageSize{16 * 1024}; +constexpr size_t MessageQueueSize{8}; +constexpr size_t JoinQueueSize{8}; + +struct QueuedMessage { + size_t length; + char buffer[MaxMessageSize]; + + void Copy(const QueuedMessage& other) + { + length = other.length; + if (length) { + memcpy(buffer, other.buffer, length); + } + } +}; + +struct User { + // snowflake (64bit int), turned into a ascii decimal string, at most 20 chars +1 null + // terminator = 21 + char userId[32]; + // 32 unicode glyphs is max name size => 4 bytes per glyph in the worst case, +1 for null + // terminator = 129 + char username[344]; + // 4 decimal digits + 1 null terminator = 5 + char discriminator[8]; + // optional 'a_' + md5 hex digest (32 bytes) + null terminator = 35 + char avatar[128]; + // Rounded way up because I'm paranoid about games breaking from future changes in these sizes +}; + +static RpcConnection* Connection{nullptr}; +static DiscordEventHandlers QueuedHandlers{}; +static DiscordEventHandlers Handlers{}; +static std::atomic_bool WasJustConnected{false}; +static std::atomic_bool WasJustDisconnected{false}; +static std::atomic_bool GotErrorMessage{false}; +static std::atomic_bool WasJoinGame{false}; +static std::atomic_bool WasSpectateGame{false}; +static std::atomic_bool UpdatePresence{false}; +static char JoinGameSecret[256]; +static char SpectateGameSecret[256]; +static int LastErrorCode{0}; +static char LastErrorMessage[256]; +static int LastDisconnectErrorCode{0}; +static char LastDisconnectErrorMessage[256]; +static std::mutex PresenceMutex; +static std::mutex HandlerMutex; +static QueuedMessage QueuedPresence{}; +static MsgQueue SendQueue; +static MsgQueue JoinAskQueue; +static User connectedUser; + +// We want to auto connect, and retry on failure, but not as fast as possible. This does expoential +// backoff from 0.5 seconds to 1 minute +static Backoff ReconnectTimeMs(500, 60 * 1000); +static auto NextConnect = std::chrono::system_clock::now(); +static int Pid{0}; +static int Nonce{1}; + +#ifndef DISCORD_DISABLE_IO_THREAD +static void Discord_UpdateConnection(void); +class IoThreadHolder { +private: + std::atomic_bool keepRunning{true}; + std::mutex waitForIOMutex; + std::condition_variable waitForIOActivity; + std::thread ioThread; + +public: + void Start() + { + keepRunning.store(true); + ioThread = std::thread([&]() { + const std::chrono::duration maxWait{500LL}; + Discord_UpdateConnection(); + while (keepRunning.load()) { + std::unique_lock lock(waitForIOMutex); + waitForIOActivity.wait_for(lock, maxWait); + Discord_UpdateConnection(); + } + }); + } + + void Notify() { waitForIOActivity.notify_all(); } + + void Stop() + { + keepRunning.exchange(false); + Notify(); + if (ioThread.joinable()) { + ioThread.join(); + } + } + + ~IoThreadHolder() { Stop(); } +}; +#else +class IoThreadHolder { +public: + void Start() {} + void Stop() {} + void Notify() {} +}; +#endif // DISCORD_DISABLE_IO_THREAD +static IoThreadHolder* IoThread{nullptr}; + +static void UpdateReconnectTime() +{ + NextConnect = std::chrono::system_clock::now() + + std::chrono::duration{ReconnectTimeMs.nextDelay()}; +} + +#ifdef DISCORD_DISABLE_IO_THREAD +extern "C" DISCORD_EXPORT void Discord_UpdateConnection(void) +#else +static void Discord_UpdateConnection(void) +#endif +{ + if (!Connection) { + return; + } + + if (!Connection->IsOpen()) { + if (std::chrono::system_clock::now() >= NextConnect) { + UpdateReconnectTime(); + Connection->Open(); + } + } + else { + // reads + + for (;;) { + JsonDocument message; + + if (!Connection->Read(message)) { + break; + } + + const char* evtName = GetStrMember(&message, "evt"); + const char* nonce = GetStrMember(&message, "nonce"); + + if (nonce) { + // in responses only -- should use to match up response when needed. + + if (evtName && strcmp(evtName, "ERROR") == 0) { + auto data = GetObjMember(&message, "data"); + LastErrorCode = GetIntMember(data, "code"); + StringCopy(LastErrorMessage, GetStrMember(data, "message", "")); + GotErrorMessage.store(true); + } + } + else { + // should have evt == name of event, optional data + if (evtName == nullptr) { + continue; + } + + auto data = GetObjMember(&message, "data"); + + if (strcmp(evtName, "ACTIVITY_JOIN") == 0) { + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(JoinGameSecret, secret); + WasJoinGame.store(true); + } + } + else if (strcmp(evtName, "ACTIVITY_SPECTATE") == 0) { + auto secret = GetStrMember(data, "secret"); + if (secret) { + StringCopy(SpectateGameSecret, secret); + WasSpectateGame.store(true); + } + } + else if (strcmp(evtName, "ACTIVITY_JOIN_REQUEST") == 0) { + auto user = GetObjMember(data, "user"); + auto userId = GetStrMember(user, "id"); + auto username = GetStrMember(user, "username"); + auto avatar = GetStrMember(user, "avatar"); + auto joinReq = JoinAskQueue.GetNextAddMessage(); + if (userId && username && joinReq) { + StringCopy(joinReq->userId, userId); + StringCopy(joinReq->username, username); + auto discriminator = GetStrMember(user, "discriminator"); + if (discriminator) { + StringCopy(joinReq->discriminator, discriminator); + } + if (avatar) { + StringCopy(joinReq->avatar, avatar); + } + else { + joinReq->avatar[0] = 0; + } + JoinAskQueue.CommitAdd(); + } + } + } + } + + // writes + if (UpdatePresence.exchange(false) && QueuedPresence.length) { + QueuedMessage local; + { + std::lock_guard guard(PresenceMutex); + local.Copy(QueuedPresence); + } + if (!Connection->Write(local.buffer, local.length)) { + // if we fail to send, requeue + std::lock_guard guard(PresenceMutex); + QueuedPresence.Copy(local); + UpdatePresence.exchange(true); + } + } + + while (SendQueue.HavePendingSends()) { + auto qmessage = SendQueue.GetNextSendMessage(); + Connection->Write(qmessage->buffer, qmessage->length); + SendQueue.CommitSend(); + } + } +} + +static void SignalIOActivity() +{ + if (IoThread != nullptr) { + IoThread->Notify(); + } +} + +static bool RegisterForEvent(const char* evtName) +{ + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteSubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); + SendQueue.CommitAdd(); + SignalIOActivity(); + return true; + } + return false; +} + +static bool DeregisterForEvent(const char* evtName) +{ + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteUnsubscribeCommand(qmessage->buffer, sizeof(qmessage->buffer), Nonce++, evtName); + SendQueue.CommitAdd(); + SignalIOActivity(); + return true; + } + return false; +} + +extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId) +{ + IoThread = new (std::nothrow) IoThreadHolder(); + if (IoThread == nullptr) { + return; + } + + if (autoRegister) { + if (optionalSteamId && optionalSteamId[0]) { + Discord_RegisterSteamGame(applicationId, optionalSteamId); + } + else { + Discord_Register(applicationId, nullptr); + } + } + + Pid = GetProcessId(); + + { + std::lock_guard guard(HandlerMutex); + + if (handlers) { + QueuedHandlers = *handlers; + } + else { + QueuedHandlers = {}; + } + + Handlers = {}; + } + + if (Connection) { + return; + } + + Connection = RpcConnection::Create(applicationId); + Connection->onConnect = [](JsonDocument& readyMessage) { + Discord_UpdateHandlers(&QueuedHandlers); + if (QueuedPresence.length > 0) { + UpdatePresence.exchange(true); + SignalIOActivity(); + } + auto data = GetObjMember(&readyMessage, "data"); + auto user = GetObjMember(data, "user"); + auto userId = GetStrMember(user, "id"); + auto username = GetStrMember(user, "username"); + auto avatar = GetStrMember(user, "avatar"); + if (userId && username) { + StringCopy(connectedUser.userId, userId); + StringCopy(connectedUser.username, username); + auto discriminator = GetStrMember(user, "discriminator"); + if (discriminator) { + StringCopy(connectedUser.discriminator, discriminator); + } + if (avatar) { + StringCopy(connectedUser.avatar, avatar); + } + else { + connectedUser.avatar[0] = 0; + } + } + WasJustConnected.exchange(true); + ReconnectTimeMs.reset(); + }; + Connection->onDisconnect = [](int err, const char* message) { + LastDisconnectErrorCode = err; + StringCopy(LastDisconnectErrorMessage, message); + WasJustDisconnected.exchange(true); + UpdateReconnectTime(); + }; + + IoThread->Start(); +} + +extern "C" DISCORD_EXPORT void Discord_Shutdown(void) +{ + if (!Connection) { + return; + } + Connection->onConnect = nullptr; + Connection->onDisconnect = nullptr; + Handlers = {}; + QueuedPresence.length = 0; + UpdatePresence.exchange(false); + if (IoThread != nullptr) { + IoThread->Stop(); + delete IoThread; + IoThread = nullptr; + } + + RpcConnection::Destroy(Connection); +} + +extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence) +{ + { + std::lock_guard guard(PresenceMutex); + QueuedPresence.length = JsonWriteRichPresenceObj( + QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); + UpdatePresence.exchange(true); + } + SignalIOActivity(); +} + +extern "C" DISCORD_EXPORT void Discord_ClearPresence(void) +{ + Discord_UpdatePresence(nullptr); +} + +extern "C" DISCORD_EXPORT void Discord_Respond(const char* userId, /* DISCORD_REPLY_ */ int reply) +{ + // if we are not connected, let's not batch up stale messages for later + if (!Connection || !Connection->IsOpen()) { + return; + } + auto qmessage = SendQueue.GetNextAddMessage(); + if (qmessage) { + qmessage->length = + JsonWriteJoinReply(qmessage->buffer, sizeof(qmessage->buffer), userId, reply, Nonce++); + SendQueue.CommitAdd(); + SignalIOActivity(); + } +} + +extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void) +{ + // Note on some weirdness: internally we might connect, get other signals, disconnect any number + // of times inbetween calls here. Externally, we want the sequence to seem sane, so any other + // signals are book-ended by calls to ready and disconnect. + + if (!Connection) { + return; + } + + bool wasDisconnected = WasJustDisconnected.exchange(false); + bool isConnected = Connection->IsOpen(); + + if (isConnected) { + // if we are connected, disconnect cb first + std::lock_guard guard(HandlerMutex); + if (wasDisconnected && Handlers.disconnected) { + Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); + } + } + + if (WasJustConnected.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.ready) { + DiscordUser du{connectedUser.userId, + connectedUser.username, + connectedUser.discriminator, + connectedUser.avatar}; + Handlers.ready(&du); + } + } + + if (GotErrorMessage.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.errored) { + Handlers.errored(LastErrorCode, LastErrorMessage); + } + } + + if (WasJoinGame.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.joinGame) { + Handlers.joinGame(JoinGameSecret); + } + } + + if (WasSpectateGame.exchange(false)) { + std::lock_guard guard(HandlerMutex); + if (Handlers.spectateGame) { + Handlers.spectateGame(SpectateGameSecret); + } + } + + // Right now this batches up any requests and sends them all in a burst; I could imagine a world + // where the implementer would rather sequentially accept/reject each one before the next invite + // is sent. I left it this way because I could also imagine wanting to process these all and + // maybe show them in one common dialog and/or start fetching the avatars in parallel, and if + // not it should be trivial for the implementer to make a queue themselves. + while (JoinAskQueue.HavePendingSends()) { + auto req = JoinAskQueue.GetNextSendMessage(); + { + std::lock_guard guard(HandlerMutex); + if (Handlers.joinRequest) { + DiscordUser du{req->userId, req->username, req->discriminator, req->avatar}; + Handlers.joinRequest(&du); + } + } + JoinAskQueue.CommitSend(); + } + + if (!isConnected) { + // if we are not connected, disconnect message last + std::lock_guard guard(HandlerMutex); + if (wasDisconnected && Handlers.disconnected) { + Handlers.disconnected(LastDisconnectErrorCode, LastDisconnectErrorMessage); + } + } +} + +extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers) +{ + if (newHandlers) { +#define HANDLE_EVENT_REGISTRATION(handler_name, event) \ + if (!Handlers.handler_name && newHandlers->handler_name) { \ + RegisterForEvent(event); \ + } \ + else if (Handlers.handler_name && !newHandlers->handler_name) { \ + DeregisterForEvent(event); \ + } + + std::lock_guard guard(HandlerMutex); + HANDLE_EVENT_REGISTRATION(joinGame, "ACTIVITY_JOIN") + HANDLE_EVENT_REGISTRATION(spectateGame, "ACTIVITY_SPECTATE") + HANDLE_EVENT_REGISTRATION(joinRequest, "ACTIVITY_JOIN_REQUEST") + +#undef HANDLE_EVENT_REGISTRATION + + Handlers = *newHandlers; + } + else { + std::lock_guard guard(HandlerMutex); + Handlers = {}; + } + return; +} diff --git a/src/third-party/discord-rpc/src/dllmain.cpp b/src/third-party/discord-rpc/src/dllmain.cpp new file mode 100644 index 000000000..fbfc2950d --- /dev/null +++ b/src/third-party/discord-rpc/src/dllmain.cpp @@ -0,0 +1,8 @@ +#include + +// outsmart GCC's missing-declarations warning +BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID); +BOOL WINAPI DllMain(HMODULE, DWORD, LPVOID) +{ + return TRUE; +} diff --git a/src/third-party/discord-rpc/src/msg_queue.h b/src/third-party/discord-rpc/src/msg_queue.h new file mode 100644 index 000000000..77f380e70 --- /dev/null +++ b/src/third-party/discord-rpc/src/msg_queue.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +// A simple queue. No locks, but only works with a single thread as producer and a single thread as +// a consumer. Mutex up as needed. + +template +class MsgQueue { + ElementType queue_[QueueSize]; + std::atomic_uint nextAdd_{0}; + std::atomic_uint nextSend_{0}; + std::atomic_uint pendingSends_{0}; + +public: + MsgQueue() {} + + ElementType* GetNextAddMessage() + { + // if we are falling behind, bail + if (pendingSends_.load() >= QueueSize) { + return nullptr; + } + auto index = (nextAdd_++) % QueueSize; + return &queue_[index]; + } + void CommitAdd() { ++pendingSends_; } + + bool HavePendingSends() const { return pendingSends_.load() != 0; } + ElementType* GetNextSendMessage() + { + auto index = (nextSend_++) % QueueSize; + return &queue_[index]; + } + void CommitSend() { --pendingSends_; } +}; diff --git a/src/third-party/discord-rpc/src/rpc_connection.cpp b/src/third-party/discord-rpc/src/rpc_connection.cpp new file mode 100644 index 000000000..093316216 --- /dev/null +++ b/src/third-party/discord-rpc/src/rpc_connection.cpp @@ -0,0 +1,137 @@ +#include "rpc_connection.h" +#include "serialization.h" + +#include + +static const int RpcVersion = 1; +static RpcConnection Instance; + +/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) +{ + Instance.connection = BaseConnection::Create(); + StringCopy(Instance.appId, applicationId); + return &Instance; +} + +/*static*/ void RpcConnection::Destroy(RpcConnection*& c) +{ + c->Close(); + BaseConnection::Destroy(c->connection); + c = nullptr; +} + +void RpcConnection::Open() +{ + if (state == State::Connected) { + return; + } + + if (state == State::Disconnected && !connection->Open()) { + return; + } + + if (state == State::SentHandshake) { + JsonDocument message; + if (Read(message)) { + auto cmd = GetStrMember(&message, "cmd"); + auto evt = GetStrMember(&message, "evt"); + if (cmd && evt && !strcmp(cmd, "DISPATCH") && !strcmp(evt, "READY")) { + state = State::Connected; + if (onConnect) { + onConnect(message); + } + } + } + } + else { + sendFrame.opcode = Opcode::Handshake; + sendFrame.length = (uint32_t)JsonWriteHandshakeObj( + sendFrame.message, sizeof(sendFrame.message), RpcVersion, appId); + + if (connection->Write(&sendFrame, sizeof(MessageFrameHeader) + sendFrame.length)) { + state = State::SentHandshake; + } + else { + Close(); + } + } +} + +void RpcConnection::Close() +{ + if (onDisconnect && (state == State::Connected || state == State::SentHandshake)) { + onDisconnect(lastErrorCode, lastErrorMessage); + } + connection->Close(); + state = State::Disconnected; +} + +bool RpcConnection::Write(const void* data, size_t length) +{ + sendFrame.opcode = Opcode::Frame; + memcpy(sendFrame.message, data, length); + sendFrame.length = (uint32_t)length; + if (!connection->Write(&sendFrame, sizeof(MessageFrameHeader) + length)) { + Close(); + return false; + } + return true; +} + +bool RpcConnection::Read(JsonDocument& message) +{ + if (state != State::Connected && state != State::SentHandshake) { + return false; + } + MessageFrame readFrame; + for (;;) { + bool didRead = connection->Read(&readFrame, sizeof(MessageFrameHeader)); + if (!didRead) { + if (!connection->isOpen) { + lastErrorCode = (int)ErrorCode::PipeClosed; + StringCopy(lastErrorMessage, "Pipe closed"); + Close(); + } + return false; + } + + if (readFrame.length > 0) { + didRead = connection->Read(readFrame.message, readFrame.length); + if (!didRead) { + lastErrorCode = (int)ErrorCode::ReadCorrupt; + StringCopy(lastErrorMessage, "Partial data in frame"); + Close(); + return false; + } + readFrame.message[readFrame.length] = 0; + } + + switch (readFrame.opcode) { + case Opcode::Close: { + message.ParseInsitu(readFrame.message); + lastErrorCode = GetIntMember(&message, "code"); + StringCopy(lastErrorMessage, GetStrMember(&message, "message", "")); + Close(); + return false; + } + case Opcode::Frame: + message.ParseInsitu(readFrame.message); + return true; + case Opcode::Ping: + readFrame.opcode = Opcode::Pong; + if (!connection->Write(&readFrame, sizeof(MessageFrameHeader) + readFrame.length)) { + Close(); + } + break; + case Opcode::Pong: + break; + case Opcode::Handshake: + default: + // something bad happened + lastErrorCode = (int)ErrorCode::ReadCorrupt; + StringCopy(lastErrorMessage, "Bad ipc frame"); + Close(); + return false; + } + } +} diff --git a/src/third-party/discord-rpc/src/rpc_connection.h b/src/third-party/discord-rpc/src/rpc_connection.h new file mode 100644 index 000000000..bbdd05c79 --- /dev/null +++ b/src/third-party/discord-rpc/src/rpc_connection.h @@ -0,0 +1,59 @@ +#pragma once + +#include "connection.h" +#include "serialization.h" + +// I took this from the buffer size libuv uses for named pipes; I suspect ours would usually be much +// smaller. +constexpr size_t MaxRpcFrameSize = 64 * 1024; + +struct RpcConnection { + enum class ErrorCode : int { + Success = 0, + PipeClosed = 1, + ReadCorrupt = 2, + }; + + enum class Opcode : uint32_t { + Handshake = 0, + Frame = 1, + Close = 2, + Ping = 3, + Pong = 4, + }; + + struct MessageFrameHeader { + Opcode opcode; + uint32_t length; + }; + + struct MessageFrame : public MessageFrameHeader { + char message[MaxRpcFrameSize - sizeof(MessageFrameHeader)]; + }; + + enum class State : uint32_t { + Disconnected, + SentHandshake, + AwaitingResponse, + Connected, + }; + + BaseConnection* connection{nullptr}; + State state{State::Disconnected}; + void (*onConnect)(JsonDocument& message){nullptr}; + void (*onDisconnect)(int errorCode, const char* message){nullptr}; + char appId[64]{}; + int lastErrorCode{0}; + char lastErrorMessage[256]{}; + RpcConnection::MessageFrame sendFrame; + + static RpcConnection* Create(const char* applicationId); + static void Destroy(RpcConnection*&); + + inline bool IsOpen() const { return state == State::Connected; } + + void Open(); + void Close(); + bool Write(const void* data, size_t length); + bool Read(JsonDocument& message); +}; diff --git a/src/third-party/discord-rpc/src/serialization.cpp b/src/third-party/discord-rpc/src/serialization.cpp new file mode 100644 index 000000000..6cc1e9013 --- /dev/null +++ b/src/third-party/discord-rpc/src/serialization.cpp @@ -0,0 +1,245 @@ +#include "serialization.h" +#include "connection.h" +#include "discord_rpc.h" + +template +void NumberToString(char* dest, T number) +{ + if (!number) { + *dest++ = '0'; + *dest++ = 0; + return; + } + if (number < 0) { + *dest++ = '-'; + number = -number; + } + char temp[32]; + int place = 0; + while (number) { + auto digit = number % 10; + number = number / 10; + temp[place++] = '0' + (char)digit; + } + for (--place; place >= 0; --place) { + *dest++ = temp[place]; + } + *dest = 0; +} + +// it's ever so slightly faster to not have to strlen the key +template +void WriteKey(JsonWriter& w, T& k) +{ + w.Key(k, sizeof(T) - 1); +} + +struct WriteObject { + JsonWriter& writer; + WriteObject(JsonWriter& w) + : writer(w) + { + writer.StartObject(); + } + template + WriteObject(JsonWriter& w, T& name) + : writer(w) + { + WriteKey(writer, name); + writer.StartObject(); + } + ~WriteObject() { writer.EndObject(); } +}; + +struct WriteArray { + JsonWriter& writer; + template + WriteArray(JsonWriter& w, T& name) + : writer(w) + { + WriteKey(writer, name); + writer.StartArray(); + } + ~WriteArray() { writer.EndArray(); } +}; + +template +void WriteOptionalString(JsonWriter& w, T& k, const char* value) +{ + if (value && value[0]) { + w.Key(k, sizeof(T) - 1); + w.String(value); + } +} + +static void JsonWriteNonce(JsonWriter& writer, int nonce) +{ + WriteKey(writer, "nonce"); + char nonceBuffer[32]; + NumberToString(nonceBuffer, nonce); + writer.String(nonceBuffer); +} + +size_t JsonWriteRichPresenceObj(char* dest, + size_t maxLen, + int nonce, + int pid, + const DiscordRichPresence* presence) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject top(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("SET_ACTIVITY"); + + { + WriteObject args(writer, "args"); + + WriteKey(writer, "pid"); + writer.Int(pid); + + if (presence != nullptr) { + WriteObject activity(writer, "activity"); + + WriteOptionalString(writer, "state", presence->state); + WriteOptionalString(writer, "details", presence->details); + + if (presence->startTimestamp || presence->endTimestamp) { + WriteObject timestamps(writer, "timestamps"); + + if (presence->startTimestamp) { + WriteKey(writer, "start"); + writer.Int64(presence->startTimestamp); + } + + if (presence->endTimestamp) { + WriteKey(writer, "end"); + writer.Int64(presence->endTimestamp); + } + } + + if ((presence->largeImageKey && presence->largeImageKey[0]) || + (presence->largeImageText && presence->largeImageText[0]) || + (presence->smallImageKey && presence->smallImageKey[0]) || + (presence->smallImageText && presence->smallImageText[0])) { + WriteObject assets(writer, "assets"); + WriteOptionalString(writer, "large_image", presence->largeImageKey); + WriteOptionalString(writer, "large_text", presence->largeImageText); + WriteOptionalString(writer, "small_image", presence->smallImageKey); + WriteOptionalString(writer, "small_text", presence->smallImageText); + } + + if ((presence->partyId && presence->partyId[0]) || presence->partySize || + presence->partyMax) { + WriteObject party(writer, "party"); + WriteOptionalString(writer, "id", presence->partyId); + if (presence->partySize && presence->partyMax) { + WriteArray size(writer, "size"); + writer.Int(presence->partySize); + writer.Int(presence->partyMax); + } + } + + if ((presence->matchSecret && presence->matchSecret[0]) || + (presence->joinSecret && presence->joinSecret[0]) || + (presence->spectateSecret && presence->spectateSecret[0])) { + WriteObject secrets(writer, "secrets"); + WriteOptionalString(writer, "match", presence->matchSecret); + WriteOptionalString(writer, "join", presence->joinSecret); + WriteOptionalString(writer, "spectate", presence->spectateSecret); + } + + writer.Key("instance"); + writer.Bool(presence->instance != 0); + } + } + } + + return writer.Size(); +} + +size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + WriteKey(writer, "v"); + writer.Int(version); + WriteKey(writer, "client_id"); + writer.String(applicationId); + } + + return writer.Size(); +} + +size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("SUBSCRIBE"); + + WriteKey(writer, "evt"); + writer.String(evtName); + } + + return writer.Size(); +} + +size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + JsonWriteNonce(writer, nonce); + + WriteKey(writer, "cmd"); + writer.String("UNSUBSCRIBE"); + + WriteKey(writer, "evt"); + writer.String(evtName); + } + + return writer.Size(); +} + +size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce) +{ + JsonWriter writer(dest, maxLen); + + { + WriteObject obj(writer); + + WriteKey(writer, "cmd"); + if (reply == DISCORD_REPLY_YES) { + writer.String("SEND_ACTIVITY_JOIN_INVITE"); + } + else { + writer.String("CLOSE_ACTIVITY_JOIN_REQUEST"); + } + + WriteKey(writer, "args"); + { + WriteObject args(writer); + + WriteKey(writer, "user_id"); + writer.String(userId); + } + + JsonWriteNonce(writer, nonce); + } + + return writer.Size(); +} diff --git a/src/third-party/discord-rpc/src/serialization.h b/src/third-party/discord-rpc/src/serialization.h new file mode 100644 index 000000000..9c462dc28 --- /dev/null +++ b/src/third-party/discord-rpc/src/serialization.h @@ -0,0 +1,215 @@ +#pragma once + +#include + +#ifndef __MINGW32__ +#pragma warning(push) + +#pragma warning(disable : 4061) // enum is not explicitly handled by a case label +#pragma warning(disable : 4365) // signed/unsigned mismatch +#pragma warning(disable : 4464) // relative include path contains +#pragma warning(disable : 4668) // is not defined as a preprocessor macro +#pragma warning(disable : 6313) // Incorrect operator +#endif // __MINGW32__ + +#include "rapidjson/document.h" +#include "rapidjson/stringbuffer.h" +#include "rapidjson/writer.h" + +#ifndef __MINGW32__ +#pragma warning(pop) +#endif // __MINGW32__ + +// if only there was a standard library function for this +template +inline size_t StringCopy(char (&dest)[Len], const char* src) +{ + if (!src || !Len) { + return 0; + } + size_t copied; + char* out = dest; + for (copied = 1; *src && copied < Len; ++copied) { + *out++ = *src++; + } + *out = 0; + return copied - 1; +} + +size_t JsonWriteHandshakeObj(char* dest, size_t maxLen, int version, const char* applicationId); + +// Commands +struct DiscordRichPresence; +size_t JsonWriteRichPresenceObj(char* dest, + size_t maxLen, + int nonce, + int pid, + const DiscordRichPresence* presence); +size_t JsonWriteSubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); + +size_t JsonWriteUnsubscribeCommand(char* dest, size_t maxLen, int nonce, const char* evtName); + +size_t JsonWriteJoinReply(char* dest, size_t maxLen, const char* userId, int reply, int nonce); + +// I want to use as few allocations as I can get away with, and to do that with RapidJson, you need +// to supply some of your own allocators for stuff rather than use the defaults + +class LinearAllocator { +public: + char* buffer_; + char* end_; + LinearAllocator() + { + assert(0); // needed for some default case in rapidjson, should not use + } + LinearAllocator(char* buffer, size_t size) + : buffer_(buffer) + , end_(buffer + size) + { + } + static const bool kNeedFree = false; + void* Malloc(size_t size) + { + char* res = buffer_; + buffer_ += size; + if (buffer_ > end_) { + buffer_ = res; + return nullptr; + } + return res; + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) + { + if (newSize == 0) { + return nullptr; + } + // allocate how much you need in the first place + assert(!originalPtr && !originalSize); + // unused parameter warning + (void)(originalPtr); + (void)(originalSize); + return Malloc(newSize); + } + static void Free(void* ptr) + { + /* shrug */ + (void)ptr; + } +}; + +template +class FixedLinearAllocator : public LinearAllocator { +public: + char fixedBuffer_[Size]; + FixedLinearAllocator() + : LinearAllocator(fixedBuffer_, Size) + { + } + static const bool kNeedFree = false; +}; + +// wonder why this isn't a thing already, maybe I missed it +class DirectStringBuffer { +public: + using Ch = char; + char* buffer_; + char* end_; + char* current_; + + DirectStringBuffer(char* buffer, size_t maxLen) + : buffer_(buffer) + , end_(buffer + maxLen) + , current_(buffer) + { + } + + void Put(char c) + { + if (current_ < end_) { + *current_++ = c; + } + } + void Flush() {} + size_t GetSize() const { return (size_t)(current_ - buffer_); } +}; + +using MallocAllocator = rapidjson::CrtAllocator; +using PoolAllocator = rapidjson::MemoryPoolAllocator; +using UTF8 = rapidjson::UTF8; +// Writer appears to need about 16 bytes per nested object level (with 64bit size_t) +using StackAllocator = FixedLinearAllocator<2048>; +constexpr size_t WriterNestingLevels = 2048 / (2 * sizeof(size_t)); +using JsonWriterBase = + rapidjson::Writer; +class JsonWriter : public JsonWriterBase { +public: + DirectStringBuffer stringBuffer_; + StackAllocator stackAlloc_; + + JsonWriter(char* dest, size_t maxLen) + : JsonWriterBase(stringBuffer_, &stackAlloc_, WriterNestingLevels) + , stringBuffer_(dest, maxLen) + , stackAlloc_() + { + } + + size_t Size() const { return stringBuffer_.GetSize(); } +}; + +using JsonDocumentBase = rapidjson::GenericDocument; +class JsonDocument : public JsonDocumentBase { +public: + static const int kDefaultChunkCapacity = 32 * 1024; + // json parser will use this buffer first, then allocate more if needed; I seriously doubt we + // send any messages that would use all of this, though. + char parseBuffer_[32 * 1024]; + MallocAllocator mallocAllocator_; + PoolAllocator poolAllocator_; + StackAllocator stackAllocator_; + JsonDocument() + : JsonDocumentBase(rapidjson::kObjectType, + &poolAllocator_, + sizeof(stackAllocator_.fixedBuffer_), + &stackAllocator_) + , poolAllocator_(parseBuffer_, sizeof(parseBuffer_), kDefaultChunkCapacity, &mallocAllocator_) + , stackAllocator_() + { + } +}; + +using JsonValue = rapidjson::GenericValue; + +inline JsonValue* GetObjMember(JsonValue* obj, const char* name) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsObject()) { + return &member->value; + } + } + return nullptr; +} + +inline int GetIntMember(JsonValue* obj, const char* name, int notFoundDefault = 0) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsInt()) { + return member->value.GetInt(); + } + } + return notFoundDefault; +} + +inline const char* GetStrMember(JsonValue* obj, + const char* name, + const char* notFoundDefault = nullptr) +{ + if (obj) { + auto member = obj->FindMember(name); + if (member != obj->MemberEnd() && member->value.IsString()) { + return member->value.GetString(); + } + } + return notFoundDefault; +} From 85a3c6f00e4bb0b347b8ebeb4e0ca0843d7816ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 12 Mar 2019 19:56:14 -0700 Subject: [PATCH 106/429] Qt: Fix spurious connect error --- src/platform/qt/ConfigController.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index b176a069f..b31528c11 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -33,10 +33,10 @@ QAction* ConfigOption::addValue(const QString& text, const QVariant& value, QMen QObject::connect(action, &QAction::triggered, [this, value]() { emit valueChanged(value); }); - QObject::connect(parent, &QAction::destroyed, [this, action, value]() { - m_actions.removeAll(qMakePair(action, value)); - }); if (parent) { + QObject::connect(parent, &QAction::destroyed, [this, action, value]() { + m_actions.removeAll(qMakePair(action, value)); + }); parent->addAction(action); } m_actions.append(qMakePair(action, value)); @@ -53,10 +53,10 @@ QAction* ConfigOption::addBoolean(const QString& text, QMenu* parent) { QObject::connect(action, &QAction::triggered, [this, action]() { emit valueChanged(action->isChecked()); }); - QObject::connect(parent, &QAction::destroyed, [this, action]() { - m_actions.removeAll(qMakePair(action, 1)); - }); if (parent) { + QObject::connect(parent, &QAction::destroyed, [this, action]() { + m_actions.removeAll(qMakePair(action, 1)); + }); parent->addAction(action); } m_actions.append(qMakePair(action, 1)); From bfe6c021592e4fa921a63191a1110bea3ae366b8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 18:33:08 -0700 Subject: [PATCH 107/429] Qt: Fix overrides getting discarded (fixes #1354) --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 51628af73..825ccd81b 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) - LR35902: Fix disassembly of several CB-prefix instructions + - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index ef641b3a1..5f6f8ba04 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -866,8 +866,33 @@ void CoreController::updateFastForward() { m_threadContext.impl->sync.fpsTarget = m_fpsTarget; setSync(true); } - // XXX: Have a way of just updating opts - m_threadContext.core->loadConfig(m_threadContext.core, &m_threadContext.core->config); + // XXX: Have a way of just updating volume + switch (platform()) { +#ifdef M_CORE_GBA + case PLATFORM_GBA: { + GBA* gba = static_cast(m_threadContext.core->board); + if (m_threadContext.core->opts.mute) { + gba->audio.masterVolume = 0; + } else { + gba->audio.masterVolume = m_threadContext.core->opts.volume; + } + break; + } +#endif +#ifdef M_CORE_GB + case PLATFORM_GB: { + GB* gb = static_cast(m_threadContext.core->board); + if (m_threadContext.core->opts.mute) { + gb->audio.masterVolume = 0; + } else { + gb->audio.masterVolume = m_threadContext.core->opts.volume; + } + break; + } +#endif + default: + break; + } } CoreController::Interrupter::Interrupter(CoreController* parent, bool fromThread) From 41e24b93d96a6c99665be3f8460bc7c837702331 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 18:56:11 -0700 Subject: [PATCH 108/429] CMake: Fix embedded build --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9391ca462..88c280175 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,6 +302,7 @@ if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH) set(IS_EMBEDDED ON) set(USE_DEBUGGERS OFF) set(USE_SQLITE3 OFF) + set(USE_DISCORD_RPC OFF) endif() if(DEFINED 3DS) From 9197e5a1fbc8574ca26ce9d73b575cdeaebedccb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 19:20:16 -0700 Subject: [PATCH 109/429] Third-Party: Vendor rapidjson too --- res/licenses/discord-rpc.txt | 19 + res/licenses/rapidjson.txt | 57 + src/third-party/discord-rpc/CMakeLists.txt | 22 - .../include/rapidjson/allocators.h | 271 ++ .../discord-rpc/include/rapidjson/document.h | 2575 +++++++++++++++++ .../include/rapidjson/encodedstream.h | 299 ++ .../discord-rpc/include/rapidjson/encodings.h | 716 +++++ .../discord-rpc/include/rapidjson/error/en.h | 74 + .../include/rapidjson/error/error.h | 155 + .../include/rapidjson/filereadstream.h | 99 + .../include/rapidjson/filewritestream.h | 104 + .../discord-rpc/include/rapidjson/fwd.h | 151 + .../include/rapidjson/internal/biginteger.h | 290 ++ .../include/rapidjson/internal/diyfp.h | 258 ++ .../include/rapidjson/internal/dtoa.h | 245 ++ .../include/rapidjson/internal/ieee754.h | 78 + .../include/rapidjson/internal/itoa.h | 304 ++ .../include/rapidjson/internal/meta.h | 181 ++ .../include/rapidjson/internal/pow10.h | 55 + .../include/rapidjson/internal/regex.h | 701 +++++ .../include/rapidjson/internal/stack.h | 230 ++ .../include/rapidjson/internal/strfunc.h | 55 + .../include/rapidjson/internal/strtod.h | 269 ++ .../include/rapidjson/internal/swap.h | 46 + .../include/rapidjson/istreamwrapper.h | 115 + .../discord-rpc/include/rapidjson/license.txt | 57 + .../include/rapidjson/memorybuffer.h | 70 + .../include/rapidjson/memorystream.h | 71 + .../include/rapidjson/msinttypes/inttypes.h | 316 ++ .../include/rapidjson/msinttypes/stdint.h | 300 ++ .../include/rapidjson/ostreamwrapper.h | 81 + .../discord-rpc/include/rapidjson/pointer.h | 1358 +++++++++ .../include/rapidjson/prettywriter.h | 255 ++ .../discord-rpc/include/rapidjson/rapidjson.h | 615 ++++ .../discord-rpc/include/rapidjson/reader.h | 1879 ++++++++++++ .../discord-rpc/include/rapidjson/schema.h | 2006 +++++++++++++ .../discord-rpc/include/rapidjson/stream.h | 179 ++ .../include/rapidjson/stringbuffer.h | 117 + .../discord-rpc/include/rapidjson/writer.h | 610 ++++ .../discord-rpc/src/CMakeLists.txt | 2 - 40 files changed, 15261 insertions(+), 24 deletions(-) create mode 100644 res/licenses/discord-rpc.txt create mode 100644 res/licenses/rapidjson.txt create mode 100644 src/third-party/discord-rpc/include/rapidjson/allocators.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/document.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/encodedstream.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/encodings.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/error/en.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/error/error.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/filereadstream.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/filewritestream.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/fwd.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/biginteger.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/diyfp.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/dtoa.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/ieee754.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/itoa.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/meta.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/pow10.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/regex.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/stack.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/strfunc.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/strtod.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/internal/swap.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/istreamwrapper.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/license.txt create mode 100644 src/third-party/discord-rpc/include/rapidjson/memorybuffer.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/memorystream.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/msinttypes/inttypes.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/msinttypes/stdint.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/ostreamwrapper.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/pointer.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/prettywriter.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/rapidjson.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/reader.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/schema.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/stream.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/stringbuffer.h create mode 100644 src/third-party/discord-rpc/include/rapidjson/writer.h diff --git a/res/licenses/discord-rpc.txt b/res/licenses/discord-rpc.txt new file mode 100644 index 000000000..17fca3d50 --- /dev/null +++ b/res/licenses/discord-rpc.txt @@ -0,0 +1,19 @@ +Copyright 2017 Discord, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/res/licenses/rapidjson.txt b/res/licenses/rapidjson.txt new file mode 100644 index 000000000..7ccc161c8 --- /dev/null +++ b/res/licenses/rapidjson.txt @@ -0,0 +1,57 @@ +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. +If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. +A copy of the MIT License is included in this file. + +Other dependencies and licenses: + +Open Source Software Licensed Under the BSD License: +-------------------------------------------------------------------- + +The msinttypes r29 +Copyright (c) 2006-2013 Alexander Chemeris +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Open Source Software Licensed Under the JSON License: +-------------------------------------------------------------------- + +json.org +Copyright (c) 2002 JSON.org +All Rights Reserved. + +JSON_checker +Copyright (c) 2002 JSON.org +All Rights Reserved. + + +Terms of the JSON License: +--------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Terms of the MIT License: +-------------------------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/third-party/discord-rpc/CMakeLists.txt b/src/third-party/discord-rpc/CMakeLists.txt index 15bf008e1..09e05c3f3 100644 --- a/src/third-party/discord-rpc/CMakeLists.txt +++ b/src/third-party/discord-rpc/CMakeLists.txt @@ -9,28 +9,6 @@ file(GLOB_RECURSE ALL_SOURCE_FILES src/*.cpp src/*.h src/*.c ) -# thirdparty stuff -execute_process( - COMMAND mkdir ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty - ERROR_QUIET -) - -find_file(RAPIDJSONTEST NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) -if (NOT RAPIDJSONTEST) - message("no rapidjson, download") - set(RJ_TAR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/v1.1.0.tar.gz) - file(DOWNLOAD https://github.com/miloyip/rapidjson/archive/v1.1.0.tar.gz ${RJ_TAR_FILE}) - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${RJ_TAR_FILE} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty - ) - file(REMOVE ${RJ_TAR_FILE}) -endif(NOT RAPIDJSONTEST) - -find_file(RAPIDJSON NAMES rapidjson rapidjson-1.1.0 PATHS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty CMAKE_FIND_ROOT_PATH_BOTH) - -add_library(rapidjson STATIC IMPORTED ${RAPIDJSON}) - # add subdirs add_subdirectory(src) diff --git a/src/third-party/discord-rpc/include/rapidjson/allocators.h b/src/third-party/discord-rpc/include/rapidjson/allocators.h new file mode 100644 index 000000000..98affe03f --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/allocators.h @@ -0,0 +1,271 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ALLOCATORS_H_ +#define RAPIDJSON_ALLOCATORS_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Allocator + +/*! \class rapidjson::Allocator + \brief Concept for allocating, resizing and freeing memory block. + + Note that Malloc() and Realloc() are non-static but Free() is static. + + So if an allocator need to support Free(), it needs to put its pointer in + the header of memory block. + +\code +concept Allocator { + static const bool kNeedFree; //!< Whether this allocator needs to call Free(). + + // Allocate a memory block. + // \param size of the memory block in bytes. + // \returns pointer to the memory block. + void* Malloc(size_t size); + + // Resize a memory block. + // \param originalPtr The pointer to current memory block. Null pointer is permitted. + // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.) + // \param newSize the new size in bytes. + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize); + + // Free a memory block. + // \param pointer to the memory block. Null pointer is permitted. + static void Free(void *ptr); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// CrtAllocator + +//! C-runtime library allocator. +/*! This class is just wrapper for standard C library memory routines. + \note implements Allocator concept +*/ +class CrtAllocator { +public: + static const bool kNeedFree = true; + void* Malloc(size_t size) { + if (size) // behavior of malloc(0) is implementation defined. + return std::malloc(size); + else + return NULL; // standardize to returning NULL. + } + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + (void)originalSize; + if (newSize == 0) { + std::free(originalPtr); + return NULL; + } + return std::realloc(originalPtr, newSize); + } + static void Free(void *ptr) { std::free(ptr); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// MemoryPoolAllocator + +//! Default memory allocator used by the parser and DOM. +/*! This allocator allocate memory blocks from pre-allocated memory chunks. + + It does not free memory blocks. And Realloc() only allocate new memory. + + The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default. + + User may also supply a buffer as the first chunk. + + If the user-buffer is full then additional chunks are allocated by BaseAllocator. + + The user-buffer is not deallocated by this allocator. + + \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator. + \note implements Allocator concept +*/ +template +class MemoryPoolAllocator { +public: + static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator) + + //! Constructor with chunkSize. + /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + } + + //! Constructor with user-supplied buffer. + /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size. + + The user buffer will not be deallocated when this allocator is destructed. + + \param buffer User supplied buffer. + \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader). + \param chunkSize The size of memory chunk. The default is kDefaultChunkSize. + \param baseAllocator The allocator for allocating memory chunks. + */ + MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) : + chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0) + { + RAPIDJSON_ASSERT(buffer != 0); + RAPIDJSON_ASSERT(size > sizeof(ChunkHeader)); + chunkHead_ = reinterpret_cast(buffer); + chunkHead_->capacity = size - sizeof(ChunkHeader); + chunkHead_->size = 0; + chunkHead_->next = 0; + } + + //! Destructor. + /*! This deallocates all memory chunks, excluding the user-supplied buffer. + */ + ~MemoryPoolAllocator() { + Clear(); + RAPIDJSON_DELETE(ownBaseAllocator_); + } + + //! Deallocates all memory chunks, excluding the user-supplied buffer. + void Clear() { + while (chunkHead_ && chunkHead_ != userBuffer_) { + ChunkHeader* next = chunkHead_->next; + baseAllocator_->Free(chunkHead_); + chunkHead_ = next; + } + if (chunkHead_ && chunkHead_ == userBuffer_) + chunkHead_->size = 0; // Clear user buffer + } + + //! Computes the total capacity of allocated memory chunks. + /*! \return total capacity in bytes. + */ + size_t Capacity() const { + size_t capacity = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + capacity += c->capacity; + return capacity; + } + + //! Computes the memory blocks allocated. + /*! \return total used bytes. + */ + size_t Size() const { + size_t size = 0; + for (ChunkHeader* c = chunkHead_; c != 0; c = c->next) + size += c->size; + return size; + } + + //! Allocates a memory block. (concept Allocator) + void* Malloc(size_t size) { + if (!size) + return NULL; + + size = RAPIDJSON_ALIGN(size); + if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity) + if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size)) + return NULL; + + void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size; + chunkHead_->size += size; + return buffer; + } + + //! Resizes a memory block (concept Allocator) + void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) { + if (originalPtr == 0) + return Malloc(newSize); + + if (newSize == 0) + return NULL; + + originalSize = RAPIDJSON_ALIGN(originalSize); + newSize = RAPIDJSON_ALIGN(newSize); + + // Do not shrink if new size is smaller than original + if (originalSize >= newSize) + return originalPtr; + + // Simply expand it if it is the last allocation and there is sufficient space + if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) { + size_t increment = static_cast(newSize - originalSize); + if (chunkHead_->size + increment <= chunkHead_->capacity) { + chunkHead_->size += increment; + return originalPtr; + } + } + + // Realloc process: allocate and copy memory, do not free original buffer. + if (void* newBuffer = Malloc(newSize)) { + if (originalSize) + std::memcpy(newBuffer, originalPtr, originalSize); + return newBuffer; + } + else + return NULL; + } + + //! Frees a memory block (concept Allocator) + static void Free(void *ptr) { (void)ptr; } // Do nothing + +private: + //! Copy constructor is not permitted. + MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */; + //! Copy assignment operator is not permitted. + MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */; + + //! Creates a new chunk. + /*! \param capacity Capacity of the chunk in bytes. + \return true if success. + */ + bool AddChunk(size_t capacity) { + if (!baseAllocator_) + ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator()); + if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) { + chunk->capacity = capacity; + chunk->size = 0; + chunk->next = chunkHead_; + chunkHead_ = chunk; + return true; + } + else + return false; + } + + static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity. + + //! Chunk header for perpending to each chunk. + /*! Chunks are stored as a singly linked list. + */ + struct ChunkHeader { + size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself). + size_t size; //!< Current size of allocated memory in bytes. + ChunkHeader *next; //!< Next chunk in the linked list. + }; + + ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation. + size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated. + void *userBuffer_; //!< User supplied buffer. + BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks. + BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object. +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/document.h b/src/third-party/discord-rpc/include/rapidjson/document.h new file mode 100644 index 000000000..e3e20dfbd --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/document.h @@ -0,0 +1,2575 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_DOCUMENT_H_ +#define RAPIDJSON_DOCUMENT_H_ + +/*! \file document.h */ + +#include "reader.h" +#include "internal/meta.h" +#include "internal/strfunc.h" +#include "memorystream.h" +#include "encodedstream.h" +#include // placement new +#include + +RAPIDJSON_DIAG_PUSH +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_OFF(effc++) +#if __GNUC__ >= 6 +RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions +#endif +#endif // __GNUC__ + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS +#include // std::iterator, std::random_access_iterator_tag +#endif + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +// Forward declaration. +template +class GenericValue; + +template +class GenericDocument; + +//! Name-value pair in a JSON object value. +/*! + This class was internal to GenericValue. It used to be a inner struct. + But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. + https://code.google.com/p/rapidjson/issues/detail?id=64 +*/ +template +struct GenericMember { + GenericValue name; //!< name of member (must be a string) + GenericValue value; //!< value of member. +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericMemberIterator + +#ifndef RAPIDJSON_NOMEMBERITERATORCLASS + +//! (Constant) member iterator for a JSON object value +/*! + \tparam Const Is this a constant iterator? + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. + + This class implements a Random Access Iterator for GenericMember elements + of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. + + \note This iterator implementation is mainly intended to avoid implicit + conversions from iterator values to \c NULL, + e.g. from GenericValue::FindMember. + + \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a + pointer-based implementation, if your platform doesn't provide + the C++ header. + + \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator + */ +template +class GenericMemberIterator + : public std::iterator >::Type> { + + friend class GenericValue; + template friend class GenericMemberIterator; + + typedef GenericMember PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef std::iterator BaseType; + +public: + //! Iterator type itself + typedef GenericMemberIterator Iterator; + //! Constant iterator type + typedef GenericMemberIterator ConstIterator; + //! Non-constant iterator type + typedef GenericMemberIterator NonConstIterator; + + //! Pointer to (const) GenericMember + typedef typename BaseType::pointer Pointer; + //! Reference to (const) GenericMember + typedef typename BaseType::reference Reference; + //! Signed integer type (e.g. \c ptrdiff_t) + typedef typename BaseType::difference_type DifferenceType; + + //! Default constructor (singular value) + /*! Creates an iterator pointing to no element. + \note All operations, except for comparisons, are undefined on such values. + */ + GenericMemberIterator() : ptr_() {} + + //! Iterator conversions to more const + /*! + \param it (Non-const) iterator to copy from + + Allows the creation of an iterator from another GenericMemberIterator + that is "less const". Especially, creating a non-constant iterator + from a constant iterator are disabled: + \li const -> non-const (not ok) + \li const -> const (ok) + \li non-const -> const (ok) + \li non-const -> non-const (ok) + + \note If the \c Const template parameter is already \c false, this + constructor effectively defines a regular copy-constructor. + Otherwise, the copy constructor is implicitly defined. + */ + GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} + Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } + + //! @name stepping + //@{ + Iterator& operator++(){ ++ptr_; return *this; } + Iterator& operator--(){ --ptr_; return *this; } + Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } + Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } + //@} + + //! @name increment/decrement + //@{ + Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } + Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } + + Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } + Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } + //@} + + //! @name relations + //@{ + bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } + bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } + bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } + bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } + bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } + bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } + //@} + + //! @name dereference + //@{ + Reference operator*() const { return *ptr_; } + Pointer operator->() const { return ptr_; } + Reference operator[](DifferenceType n) const { return ptr_[n]; } + //@} + + //! Distance + DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } + +private: + //! Internal constructor from plain pointer + explicit GenericMemberIterator(Pointer p) : ptr_(p) {} + + Pointer ptr_; //!< raw pointer +}; + +#else // RAPIDJSON_NOMEMBERITERATORCLASS + +// class-based member iterator implementation disabled, use plain pointers + +template +struct GenericMemberIterator; + +//! non-const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain pointer as iterator type + typedef GenericMember* Iterator; +}; +//! const GenericMemberIterator +template +struct GenericMemberIterator { + //! use plain const pointer as iterator type + typedef const GenericMember* Iterator; +}; + +#endif // RAPIDJSON_NOMEMBERITERATORCLASS + +/////////////////////////////////////////////////////////////////////////////// +// GenericStringRef + +//! Reference to a constant string (not taking a copy) +/*! + \tparam CharType character type of the string + + This helper class is used to automatically infer constant string + references for string literals, especially from \c const \b (!) + character arrays. + + The main use is for creating JSON string values without copying the + source string via an \ref Allocator. This requires that the referenced + string pointers have a sufficient lifetime, which exceeds the lifetime + of the associated GenericValue. + + \b Example + \code + Value v("foo"); // ok, no need to copy & calculate length + const char foo[] = "foo"; + v.SetString(foo); // ok + + const char* bar = foo; + // Value x(bar); // not ok, can't rely on bar's lifetime + Value x(StringRef(bar)); // lifetime explicitly guaranteed by user + Value y(StringRef(bar, 3)); // ok, explicitly pass length + \endcode + + \see StringRef, GenericValue::SetString +*/ +template +struct GenericStringRef { + typedef CharType Ch; //!< character type of the string + + //! Create string reference from \c const character array +#ifndef __clang__ // -Wdocumentation + /*! + This constructor implicitly creates a constant string reference from + a \c const character array. It has better performance than + \ref StringRef(const CharType*) by inferring the string \ref length + from the array length, and also supports strings containing null + characters. + + \tparam N length of the string, automatically inferred + + \param str Constant character array, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note Constant complexity. + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + template + GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT + : s(str), length(N-1) {} + + //! Explicitly create string reference from \c const character pointer +#ifndef __clang__ // -Wdocumentation + /*! + This constructor can be used to \b explicitly create a reference to + a constant string pointer. + + \see StringRef(const CharType*) + + \param str Constant character pointer, lifetime assumed to be longer + than the use of the string in e.g. a GenericValue + + \post \ref s == str + + \note There is a hidden, private overload to disallow references to + non-const character arrays to be created via this constructor. + By this, e.g. function-scope arrays used to be filled via + \c snprintf are excluded from consideration. + In such cases, the referenced string should be \b copied to the + GenericValue instead. + */ +#endif + explicit GenericStringRef(const CharType* str) + : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); } + + //! Create constant string reference from pointer and length +#ifndef __clang__ // -Wdocumentation + /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param len length of the string, excluding the trailing NULL terminator + + \post \ref s == str && \ref length == len + \note Constant complexity. + */ +#endif + GenericStringRef(const CharType* str, SizeType len) + : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); } + + GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} + + GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; } + + //! implicit conversion to plain CharType pointer + operator const Ch *() const { return s; } + + const Ch* const s; //!< plain CharType pointer + const SizeType length; //!< length of the string (excluding the trailing NULL terminator) + +private: + //! Disallow construction from non-const array + template + GenericStringRef(CharType (&str)[N]) /* = delete */; +}; + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + \tparam CharType Character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + + \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember +*/ +template +inline GenericStringRef StringRef(const CharType* str) { + return GenericStringRef(str, internal::StrLen(str)); +} + +//! Mark a character pointer as constant string +/*! Mark a plain character pointer as a "string literal". This function + can be used to avoid copying a character string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + This version has better performance with supplied length, and also + supports string containing null characters. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \param length The length of source string. + \return GenericStringRef string reference object + \relatesalso GenericStringRef +*/ +template +inline GenericStringRef StringRef(const CharType* str, size_t length) { + return GenericStringRef(str, SizeType(length)); +} + +#if RAPIDJSON_HAS_STDSTRING +//! Mark a string object as constant string +/*! Mark a string object (e.g. \c std::string) as a "string literal". + This function can be used to avoid copying a string to be referenced as a + value in a JSON GenericValue object, if the string's lifetime is known + to be valid long enough. + + \tparam CharType character type of the string + \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue + \return GenericStringRef string reference object + \relatesalso GenericStringRef + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. +*/ +template +inline GenericStringRef StringRef(const std::basic_string& str) { + return GenericStringRef(str.data(), SizeType(str.size())); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue type traits +namespace internal { + +template +struct IsGenericValueImpl : FalseType {}; + +// select candidates according to nested encoding and allocator types +template struct IsGenericValueImpl::Type, typename Void::Type> + : IsBaseOf, T>::Type {}; + +// helper to match arbitrary GenericValue instantiations, including derived classes +template struct IsGenericValue : IsGenericValueImpl::Type {}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// TypeHelper + +namespace internal { + +template +struct TypeHelper {}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsBool(); } + static bool Get(const ValueType& v) { return v.GetBool(); } + static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } + static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt(); } + static int Get(const ValueType& v) { return v.GetInt(); } + static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } + static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint(); } + static unsigned Get(const ValueType& v) { return v.GetUint(); } + static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } + static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsInt64(); } + static int64_t Get(const ValueType& v) { return v.GetInt64(); } + static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } + static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsUint64(); } + static uint64_t Get(const ValueType& v) { return v.GetUint64(); } + static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } + static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsDouble(); } + static double Get(const ValueType& v) { return v.GetDouble(); } + static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } + static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } +}; + +template +struct TypeHelper { + static bool Is(const ValueType& v) { return v.IsFloat(); } + static float Get(const ValueType& v) { return v.GetFloat(); } + static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } + static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } +}; + +template +struct TypeHelper { + typedef const typename ValueType::Ch* StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return v.GetString(); } + static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } + static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; + +#if RAPIDJSON_HAS_STDSTRING +template +struct TypeHelper > { + typedef std::basic_string StringType; + static bool Is(const ValueType& v) { return v.IsString(); } + static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } + static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } +}; +#endif + +template +struct TypeHelper { + typedef typename ValueType::Array ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(ValueType& v) { return v.GetArray(); } + static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } + static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstArray ArrayType; + static bool Is(const ValueType& v) { return v.IsArray(); } + static ArrayType Get(const ValueType& v) { return v.GetArray(); } +}; + +template +struct TypeHelper { + typedef typename ValueType::Object ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(ValueType& v) { return v.GetObject(); } + static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } + static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; } +}; + +template +struct TypeHelper { + typedef typename ValueType::ConstObject ObjectType; + static bool Is(const ValueType& v) { return v.IsObject(); } + static ObjectType Get(const ValueType& v) { return v.GetObject(); } +}; + +} // namespace internal + +// Forward declarations +template class GenericArray; +template class GenericObject; + +/////////////////////////////////////////////////////////////////////////////// +// GenericValue + +//! Represents a JSON value. Use Value for UTF8 encoding and default allocator. +/*! + A JSON value can be one of 7 types. This class is a variant type supporting + these types. + + Use the Value if UTF8 and default allocator + + \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) + \tparam Allocator Allocator type for allocating memory of object, array and string. +*/ +template > +class GenericValue { +public: + //! Name-value pair in an object. + typedef GenericMember Member; + typedef Encoding EncodingType; //!< Encoding type from template parameter. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericStringRef StringRefType; //!< Reference to a constant string + typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object. + typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. + typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. + typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. + typedef GenericValue ValueType; //!< Value type of itself. + typedef GenericArray Array; + typedef GenericArray ConstArray; + typedef GenericObject Object; + typedef GenericObject ConstObject; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor creates a null value. + GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { + rhs.data_.f.flags = kNullFlag; // give up contents + } +#endif + +private: + //! Copy constructor is not permitted. + GenericValue(const GenericValue& rhs); + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Moving from a GenericDocument is not permitted. + template + GenericValue(GenericDocument&& rhs); + + //! Move assignment from a GenericDocument is not permitted. + template + GenericValue& operator=(GenericDocument&& rhs); +#endif + +public: + + //! Constructor with JSON value type. + /*! This creates a Value of specified type with default content. + \param type Type of the value. + \note Default content for number is zero. + */ + explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { + static const uint16_t defaultFlags[7] = { + kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, + kNumberAnyFlag + }; + RAPIDJSON_ASSERT(type <= kNumberType); + data_.f.flags = defaultFlags[type]; + + // Use ShortString to store empty string. + if (type == kStringType) + data_.ss.SetLength(0); + } + + //! Explicit copy constructor (with allocator) + /*! Creates a copy of a Value by using the given Allocator + \tparam SourceAllocator allocator of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). + \see CopyFrom() + */ + template< typename SourceAllocator > + GenericValue(const GenericValue& rhs, Allocator & allocator); + + //! Constructor for boolean value. + /*! \param b Boolean value + \note This constructor is limited to \em real boolean values and rejects + implicitly converted types like arbitrary pointers. Use an explicit cast + to \c bool, if you want to construct a boolean JSON value in such cases. + */ +#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen + template + explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472 +#else + explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT +#endif + : data_() { + // safe-guard against failing SFINAE + RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value)); + data_.f.flags = b ? kTrueFlag : kFalseFlag; + } + + //! Constructor for int value. + explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i; + data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; + } + + //! Constructor for unsigned value. + explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u; + data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); + } + + //! Constructor for int64_t value. + explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.i64 = i64; + data_.f.flags = kNumberInt64Flag; + if (i64 >= 0) { + data_.f.flags |= kNumberUint64Flag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + else if (i64 >= static_cast(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for uint64_t value. + explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { + data_.n.u64 = u64; + data_.f.flags = kNumberUint64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) + data_.f.flags |= kInt64Flag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) + data_.f.flags |= kUintFlag; + if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) + data_.f.flags |= kIntFlag; + } + + //! Constructor for double value. + explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } + + //! Constructor for constant string (i.e. do not make a copy of string) + GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } + + //! Constructor for constant string (i.e. do not make a copy of string) + explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } + + //! Constructor for copy-string (i.e. do make a copy of string) + GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor for copy-string from a string object (i.e. do make a copy of string) + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue(const std::basic_string& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } +#endif + + //! Constructor for Array. + /*! + \param a An array obtained by \c GetArray(). + \note \c Array is always pass-by-value. + \note the source array is moved into this value and the sourec array becomes empty. + */ + GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { + a.value_.data_ = Data(); + a.value_.data_.f.flags = kArrayFlag; + } + + //! Constructor for Object. + /*! + \param o An object obtained by \c GetObject(). + \note \c Object is always pass-by-value. + \note the source object is moved into this value and the sourec object becomes empty. + */ + GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { + o.value_.data_ = Data(); + o.value_.data_.f.flags = kObjectFlag; + } + + //! Destructor. + /*! Need to destruct elements of array, members of object, or copy-string. + */ + ~GenericValue() { + if (Allocator::kNeedFree) { // Shortcut by Allocator's trait + switch(data_.f.flags) { + case kArrayFlag: + { + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + Allocator::Free(e); + } + break; + + case kObjectFlag: + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + Allocator::Free(GetMembersPointer()); + break; + + case kCopyStringFlag: + Allocator::Free(const_cast(GetStringPointer())); + break; + + default: + break; // Do nothing for other types. + } + } + } + + //@} + + //!@name Assignment operators + //@{ + + //! Assignment with move semantics. + /*! \param rhs Source of the assignment. It will become a null value after assignment. + */ + GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + RAPIDJSON_ASSERT(this != &rhs); + this->~GenericValue(); + RawAssign(rhs); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { + return *this = rhs.Move(); + } +#endif + + //! Assignment of constant string reference (no copy) + /*! \param str Constant string reference to be assigned + \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. + \see GenericStringRef, operator=(T) + */ + GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { + GenericValue s(str); + return *this = s; + } + + //! Assignment with primitive types. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value The value to be assigned. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref SetString(const Ch*, Allocator&) (for copying) or + \ref StringRef() (to explicitly mark the pointer as constant) instead. + All other pointer types would implicitly convert to \c bool, + use \ref SetBool() instead. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer), (GenericValue&)) + operator=(T value) { + GenericValue v(value); + return *this = v; + } + + //! Deep-copy assignment from Value + /*! Assigns a \b copy of the Value to the current Value object + \tparam SourceAllocator Allocator type of \c rhs + \param rhs Value to copy from (read-only) + \param allocator Allocator to use for copying + */ + template + GenericValue& CopyFrom(const GenericValue& rhs, Allocator& allocator) { + RAPIDJSON_ASSERT(static_cast(this) != static_cast(&rhs)); + this->~GenericValue(); + new (this) GenericValue(rhs, allocator); + return *this; + } + + //! Exchange the contents of this value with those of other. + /*! + \param other Another value. + \note Constant complexity. + */ + GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { + GenericValue temp; + temp.RawAssign(*this); + RawAssign(other); + other.RawAssign(temp); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.value, b.value); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Prepare Value for move semantics + /*! \return *this */ + GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } + //@} + + //!@name Equal-to and not-equal-to operators + //@{ + //! Equal-to operator + /*! + \note If an object contains duplicated named member, comparing equality with any object is always \c false. + \note Linear time complexity (number of all values in the subtree and total lengths of all strings). + */ + template + bool operator==(const GenericValue& rhs) const { + typedef GenericValue RhsType; + if (GetType() != rhs.GetType()) + return false; + + switch (GetType()) { + case kObjectType: // Warning: O(n^2) inner-loop + if (data_.o.size != rhs.data_.o.size) + return false; + for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { + typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); + if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) + return false; + } + return true; + + case kArrayType: + if (data_.a.size != rhs.data_.a.size) + return false; + for (SizeType i = 0; i < data_.a.size; i++) + if ((*this)[i] != rhs[i]) + return false; + return true; + + case kStringType: + return StringEqual(rhs); + + case kNumberType: + if (IsDouble() || rhs.IsDouble()) { + double a = GetDouble(); // May convert from integer to double. + double b = rhs.GetDouble(); // Ditto + return a >= b && a <= b; // Prevent -Wfloat-equal + } + else + return data_.n.u64 == rhs.data_.n.u64; + + default: + return true; + } + } + + //! Equal-to operator with const C-string pointer + bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } + +#if RAPIDJSON_HAS_STDSTRING + //! Equal-to operator with string object + /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + bool operator==(const std::basic_string& rhs) const { return *this == GenericValue(StringRef(rhs)); } +#endif + + //! Equal-to operator with primitive types + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr,internal::IsGenericValue >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } + + //! Not-equal-to operator + /*! \return !(*this == rhs) + */ + template + bool operator!=(const GenericValue& rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with const C-string pointer + bool operator!=(const Ch* rhs) const { return !(*this == rhs); } + + //! Not-equal-to operator with arbitrary types + /*! \return !(*this == rhs) + */ + template RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } + + //! Equal-to operator with arbitrary types (symmetric version) + /*! \return (rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } + + //! Not-Equal-to operator with arbitrary types (symmetric version) + /*! \return !(rhs == lhs) + */ + template friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } + //@} + + //!@name Type + //@{ + + Type GetType() const { return static_cast(data_.f.flags & kTypeMask); } + bool IsNull() const { return data_.f.flags == kNullFlag; } + bool IsFalse() const { return data_.f.flags == kFalseFlag; } + bool IsTrue() const { return data_.f.flags == kTrueFlag; } + bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } + bool IsObject() const { return data_.f.flags == kObjectFlag; } + bool IsArray() const { return data_.f.flags == kArrayFlag; } + bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } + bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } + bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } + bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } + bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } + bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } + bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } + + // Checks whether a number can be losslessly converted to a double. + bool IsLosslessDouble() const { + if (!IsNumber()) return false; + if (IsUint64()) { + uint64_t u = GetUint64(); + volatile double d = static_cast(u); + return (d >= 0.0) + && (d < static_cast(std::numeric_limits::max())) + && (u == static_cast(d)); + } + if (IsInt64()) { + int64_t i = GetInt64(); + volatile double d = static_cast(i); + return (d >= static_cast(std::numeric_limits::min())) + && (d < static_cast(std::numeric_limits::max())) + && (i == static_cast(d)); + } + return true; // double, int, uint are always lossless + } + + // Checks whether a number is a float (possible lossy). + bool IsFloat() const { + if ((data_.f.flags & kDoubleFlag) == 0) + return false; + double d = GetDouble(); + return d >= -3.4028234e38 && d <= 3.4028234e38; + } + // Checks whether a number can be losslessly converted to a float. + bool IsLosslessFloat() const { + if (!IsNumber()) return false; + double a = GetDouble(); + if (a < static_cast(-std::numeric_limits::max()) + || a > static_cast(std::numeric_limits::max())) + return false; + double b = static_cast(static_cast(a)); + return a >= b && a <= b; // Prevent -Wfloat-equal + } + + //@} + + //!@name Null + //@{ + + GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } + + //@} + + //!@name Bool + //@{ + + bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } + //!< Set boolean value + /*! \post IsBool() == true */ + GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } + + //@} + + //!@name Object + //@{ + + //! Set this value as an empty object. + /*! \post IsObject() == true */ + GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } + + //! Get the number of members in the object. + SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } + + //! Check whether the object is empty. + bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) + \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. + Since 0.2, if the name is not correct, it will assert. + If user is unsure whether a member exists, user should use HasMember() first. + A better approach is to use FindMember(). + \note Linear time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(GenericValue&)) operator[](T* name) { + GenericValue n(StringRef(name)); + return (*this)[n]; + } + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast(*this)[name]; } + + //! Get a value from an object associated with the name. + /*! \pre IsObject() == true + \tparam SourceAllocator Allocator of the \c name value + + \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). + And it can also handle strings with embedded null characters. + + \note Linear time complexity. + */ + template + GenericValue& operator[](const GenericValue& name) { + MemberIterator member = FindMember(name); + if (member != MemberEnd()) + return member->value; + else { + RAPIDJSON_ASSERT(false); // see above note + + // This will generate -Wexit-time-destructors in clang + // static GenericValue NullValue; + // return NullValue; + + // Use static buffer and placement-new to prevent destruction + static char buffer[sizeof(GenericValue)]; + return *new (buffer) GenericValue(); + } + } + template + const GenericValue& operator[](const GenericValue& name) const { return const_cast(*this)[name]; } + +#if RAPIDJSON_HAS_STDSTRING + //! Get a value from an object associated with name (string object). + GenericValue& operator[](const std::basic_string& name) { return (*this)[GenericValue(StringRef(name))]; } + const GenericValue& operator[](const std::basic_string& name) const { return (*this)[GenericValue(StringRef(name))]; } +#endif + + //! Const member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } + //! Const \em past-the-end member iterator + /*! \pre IsObject() == true */ + ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } + //! Member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } + //! \em Past-the-end member iterator + /*! \pre IsObject() == true */ + MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } + + //! Check whether a member exists in the object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } + +#if RAPIDJSON_HAS_STDSTRING + //! Check whether a member exists in the object with string object. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + bool HasMember(const std::basic_string& name) const { return FindMember(name) != MemberEnd(); } +#endif + + //! Check whether a member exists in the object with GenericValue name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Whether a member with that name exists. + \note It is better to use FindMember() directly if you need the obtain the value as well. + \note Linear time complexity. + */ + template + bool HasMember(const GenericValue& name) const { return FindMember(name) != MemberEnd(); } + + //! Find member by name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + MemberIterator FindMember(const Ch* name) { + GenericValue n(StringRef(name)); + return FindMember(n); + } + + ConstMemberIterator FindMember(const Ch* name) const { return const_cast(*this).FindMember(name); } + + //! Find member by name. + /*! + This version is faster because it does not need a StrLen(). It can also handle string with null character. + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + + \note Earlier versions of Rapidjson returned a \c NULL pointer, in case + the requested member doesn't exist. For consistency with e.g. + \c std::map, this has been changed to MemberEnd() now. + \note Linear time complexity. + */ + template + MemberIterator FindMember(const GenericValue& name) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + MemberIterator member = MemberBegin(); + for ( ; member != MemberEnd(); ++member) + if (name.StringEqual(member->name)) + break; + return member; + } + template ConstMemberIterator FindMember(const GenericValue& name) const { return const_cast(*this).FindMember(name); } + +#if RAPIDJSON_HAS_STDSTRING + //! Find member by string object name. + /*! + \param name Member name to be searched. + \pre IsObject() == true + \return Iterator to member, if it exists. + Otherwise returns \ref MemberEnd(). + */ + MemberIterator FindMember(const std::basic_string& name) { return FindMember(GenericValue(StringRef(name))); } + ConstMemberIterator FindMember(const std::basic_string& name) const { return FindMember(GenericValue(StringRef(name))); } +#endif + + //! Add a member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c name and \c value will be transferred to this object on success. + \pre IsObject() && name.IsString() + \post name.IsNull() && value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(name.IsString()); + + ObjectData& o = data_.o; + if (o.size >= o.capacity) { + if (o.capacity == 0) { + o.capacity = kDefaultObjectCapacity; + SetMembersPointer(reinterpret_cast(allocator.Malloc(o.capacity * sizeof(Member)))); + } + else { + SizeType oldCapacity = o.capacity; + o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 + SetMembersPointer(reinterpret_cast(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member)))); + } + } + Member* members = GetMembersPointer(); + members[o.size].name.RawAssign(name); + members[o.size].value.RawAssign(value); + o.size++; + return *this; + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Add a string object as member (name-value pair) to the object. + /*! \param name A string value as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(GenericValue& name, std::basic_string& value, Allocator& allocator) { + GenericValue v(value, allocator); + return AddMember(name, v, allocator); + } +#endif + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A string value as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(GenericValue& name, T value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { + return AddMember(name, value, allocator); + } + GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + + //! Add a member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value Value of any type. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this object on success. + \pre IsObject() + \post value.IsNull() + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Add a constant string value as member (name-value pair) to the object. + /*! \param name A constant string reference as name of member. + \param value constant string reference as value of member. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. + \note Amortized Constant time complexity. + */ + GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { + GenericValue v(value); + return AddMember(name, v, allocator); + } + + //! Add any primitive value as member (name-value pair) to the object. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param name A constant string reference as name of member. + \param value Value of primitive type \c T as value of member + \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \pre IsObject() + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref + AddMember(StringRefType, StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized Constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + AddMember(StringRefType name, T value, Allocator& allocator) { + GenericValue n(name); + return AddMember(n, value, allocator); + } + + //! Remove all members in the object. + /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void RemoveAllMembers() { + RAPIDJSON_ASSERT(IsObject()); + for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) + m->~Member(); + data_.o.size = 0; + } + + //! Remove a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Linear time complexity. + */ + bool RemoveMember(const Ch* name) { + GenericValue n(StringRef(name)); + return RemoveMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) { return RemoveMember(GenericValue(StringRef(name))); } +#endif + + template + bool RemoveMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + RemoveMember(m); + return true; + } + else + return false; + } + + //! Remove a member in object by iterator. + /*! \param m member iterator (obtained by FindMember() or MemberBegin()). + \return the new iterator after removal. + \note This function may reorder the object members. Use \ref + EraseMember(ConstMemberIterator) if you need to preserve the + relative order of the remaining members. + \note Constant time complexity. + */ + MemberIterator RemoveMember(MemberIterator m) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); + + MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); + if (data_.o.size > 1 && m != last) + *m = *last; // Move the last one to this place + else + m->~Member(); // Only one left, just destroy + --data_.o.size; + return m; + } + + //! Remove a member from an object by iterator. + /*! \param pos iterator to the member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() + \return Iterator following the removed element. + If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. + \note This function preserves the relative order of the remaining object + members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator pos) { + return EraseMember(pos, pos +1); + } + + //! Remove members in the range [first, last) from an object. + /*! \param first iterator to the first member to remove + \param last iterator following the last member to remove + \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() + \return Iterator following the last removed element. + \note This function preserves the relative order of the remaining object + members. + \note Linear time complexity. + */ + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { + RAPIDJSON_ASSERT(IsObject()); + RAPIDJSON_ASSERT(data_.o.size > 0); + RAPIDJSON_ASSERT(GetMembersPointer() != 0); + RAPIDJSON_ASSERT(first >= MemberBegin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= MemberEnd()); + + MemberIterator pos = MemberBegin() + (first - MemberBegin()); + for (MemberIterator itr = pos; itr != last; ++itr) + itr->~Member(); + std::memmove(&*pos, &*last, static_cast(MemberEnd() - last) * sizeof(Member)); + data_.o.size -= static_cast(last - first); + return pos; + } + + //! Erase a member in object by its name. + /*! \param name Name of member to be removed. + \return Whether the member existed. + \note Linear time complexity. + */ + bool EraseMember(const Ch* name) { + GenericValue n(StringRef(name)); + return EraseMember(n); + } + +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) { return EraseMember(GenericValue(StringRef(name))); } +#endif + + template + bool EraseMember(const GenericValue& name) { + MemberIterator m = FindMember(name); + if (m != MemberEnd()) { + EraseMember(m); + return true; + } + else + return false; + } + + Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } + ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } + + //@} + + //!@name Array + //@{ + + //! Set this value as an empty array. + /*! \post IsArray == true */ + GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } + + //! Get the number of elements in array. + SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } + + //! Get the capacity of array. + SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } + + //! Check whether the array is empty. + bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } + + //! Remove all elements in the array. + /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. + \note Linear time complexity. + */ + void Clear() { + RAPIDJSON_ASSERT(IsArray()); + GenericValue* e = GetElementsPointer(); + for (GenericValue* v = e; v != e + data_.a.size; ++v) + v->~GenericValue(); + data_.a.size = 0; + } + + //! Get an element from array by index. + /*! \pre IsArray() == true + \param index Zero-based index of element. + \see operator[](T*) + */ + GenericValue& operator[](SizeType index) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(index < data_.a.size); + return GetElementsPointer()[index]; + } + const GenericValue& operator[](SizeType index) const { return const_cast(*this)[index]; } + + //! Element iterator + /*! \pre IsArray() == true */ + ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } + //! \em Past-the-end element iterator + /*! \pre IsArray() == true */ + ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } + //! Constant element iterator + /*! \pre IsArray() == true */ + ConstValueIterator Begin() const { return const_cast(*this).Begin(); } + //! Constant \em past-the-end element iterator + /*! \pre IsArray() == true */ + ConstValueIterator End() const { return const_cast(*this).End(); } + + //! Request the array to have enough capacity to store elements. + /*! \param newCapacity The capacity that the array at least need to have. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \note Linear time complexity. + */ + GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (newCapacity > data_.a.capacity) { + SetElementsPointer(reinterpret_cast(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); + data_.a.capacity = newCapacity; + } + return *this; + } + + //! Append a GenericValue at the end of the array. + /*! \param value Value to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \post value.IsNull() == true + \return The value itself for fluent API. + \note The ownership of \c value will be transferred to this array on success. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + */ + GenericValue& PushBack(GenericValue& value, Allocator& allocator) { + RAPIDJSON_ASSERT(IsArray()); + if (data_.a.size >= data_.a.capacity) + Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); + GetElementsPointer()[data_.a.size++].RawAssign(value); + return *this; + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { + return PushBack(value, allocator); + } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + + //! Append a constant string reference at the end of the array. + /*! \param value Constant string reference to be appended. + \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + \note Amortized constant time complexity. + \see GenericStringRef + */ + GenericValue& PushBack(StringRefType value, Allocator& allocator) { + return (*this).template PushBack(value, allocator); + } + + //! Append a primitive value at the end of the array. + /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t + \param value Value of primitive type T to be appended. + \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). + \pre IsArray() == true + \return The value itself for fluent API. + \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. + + \note The source type \c T explicitly disallows all pointer types, + especially (\c const) \ref Ch*. This helps avoiding implicitly + referencing character strings with insufficient lifetime, use + \ref PushBack(GenericValue&, Allocator&) or \ref + PushBack(StringRefType, Allocator&). + All other pointer types would implicitly convert to \c bool, + use an explicit cast instead, if needed. + \note Amortized constant time complexity. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericValue&)) + PushBack(T value, Allocator& allocator) { + GenericValue v(value); + return PushBack(v, allocator); + } + + //! Remove the last element in the array. + /*! + \note Constant time complexity. + */ + GenericValue& PopBack() { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(!Empty()); + GetElementsPointer()[--data_.a.size].~GenericValue(); + return *this; + } + + //! Remove an element of array by iterator. + /*! + \param pos iterator to the element to remove + \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() + \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator pos) { + return Erase(pos, pos + 1); + } + + //! Remove elements in the range [first, last) of the array. + /*! + \param first iterator to the first element to remove + \param last iterator following the last element to remove + \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() + \return Iterator following the last removed element. + \note Linear time complexity. + */ + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { + RAPIDJSON_ASSERT(IsArray()); + RAPIDJSON_ASSERT(data_.a.size > 0); + RAPIDJSON_ASSERT(GetElementsPointer() != 0); + RAPIDJSON_ASSERT(first >= Begin()); + RAPIDJSON_ASSERT(first <= last); + RAPIDJSON_ASSERT(last <= End()); + ValueIterator pos = Begin() + (first - Begin()); + for (ValueIterator itr = pos; itr != last; ++itr) + itr->~GenericValue(); + std::memmove(pos, last, static_cast(End() - last) * sizeof(GenericValue)); + data_.a.size -= static_cast(last - first); + return pos; + } + + Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } + ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } + + //@} + + //!@name Number + //@{ + + int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } + unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } + int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } + uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } + + //! Get the value as double type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. + */ + double GetDouble() const { + RAPIDJSON_ASSERT(IsNumber()); + if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. + if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double + if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double + if ((data_.f.flags & kInt64Flag) != 0) return static_cast(data_.n.i64); // int64_t -> double (may lose precision) + RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast(data_.n.u64); // uint64_t -> double (may lose precision) + } + + //! Get the value as float type. + /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. + */ + float GetFloat() const { + return static_cast(GetDouble()); + } + + GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } + GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } + GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } + GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } + GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } + GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; } + + //@} + + //!@name String + //@{ + + const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } + + //! Get the length of string. + /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). + */ + SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } + + //! Set this value as a string without copying source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string pointer. + \param length The length of source string, excluding the trailing null terminator. + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == length + \see SetString(StringRefType) + */ + GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } + + //! Set this value as a string without copying source string. + /*! \param s source string reference + \return The value itself for fluent API. + \post IsString() == true && GetString() == s && GetStringLength() == s.length + */ + GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } + + //! Set this value as a string by copying from source string. + /*! This version has better performance with supplied length, and also support string containing null character. + \param s source string. + \param length The length of source string, excluding the trailing null terminator. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } + + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length + */ + GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } + +#if RAPIDJSON_HAS_STDSTRING + //! Set this value as a string by copying from source string. + /*! \param s source string. + \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). + \return The value itself for fluent API. + \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + GenericValue& SetString(const std::basic_string& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } +#endif + + //@} + + //!@name Array + //@{ + + //! Templated version for checking whether this value is type T. + /*! + \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string + */ + template + bool Is() const { return internal::TypeHelper::Is(*this); } + + template + T Get() const { return internal::TypeHelper::Get(*this); } + + template + T Get() { return internal::TypeHelper::Get(*this); } + + template + ValueType& Set(const T& data) { return internal::TypeHelper::Set(*this, data); } + + template + ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper::Set(*this, data, allocator); } + + //@} + + //! Generate events of this value to a Handler. + /*! This function adopts the GoF visitor pattern. + Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. + It can also be used to deep clone this value via GenericDocument, which is also a Handler. + \tparam Handler type of handler. + \param handler An object implementing concept Handler. + */ + template + bool Accept(Handler& handler) const { + switch(GetType()) { + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); + + case kObjectType: + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + return false; + for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { + RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. + if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) + return false; + if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) + return false; + } + return handler.EndObject(data_.o.size); + + case kArrayType: + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + return false; + for (const GenericValue* v = Begin(); v != End(); ++v) + if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) + return false; + return handler.EndArray(data_.a.size); + + case kStringType: + return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); + + default: + RAPIDJSON_ASSERT(GetType() == kNumberType); + if (IsDouble()) return handler.Double(data_.n.d); + else if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else return handler.Uint64(data_.n.u64); + } + } + +private: + template friend class GenericValue; + template friend class GenericDocument; + + enum { + kBoolFlag = 0x0008, + kNumberFlag = 0x0010, + kIntFlag = 0x0020, + kUintFlag = 0x0040, + kInt64Flag = 0x0080, + kUint64Flag = 0x0100, + kDoubleFlag = 0x0200, + kStringFlag = 0x0400, + kCopyFlag = 0x0800, + kInlineStrFlag = 0x1000, + + // Initial flags of different types. + kNullFlag = kNullType, + kTrueFlag = kTrueType | kBoolFlag, + kFalseFlag = kFalseType | kBoolFlag, + kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, + kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, + kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, + kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, + kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, + kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, + kConstStringFlag = kStringType | kStringFlag, + kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, + kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, + kObjectFlag = kObjectType, + kArrayFlag = kArrayType, + + kTypeMask = 0x07 + }; + + static const SizeType kDefaultArrayCapacity = 16; + static const SizeType kDefaultObjectCapacity = 16; + + struct Flag { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer +#elif RAPIDJSON_64BIT + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes +#else + char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes +#endif + uint16_t flags; + }; + + struct String { + SizeType length; + SizeType hashcode; //!< reserved + const Ch* str; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars + // (excluding the terminating zero) and store a value to determine the length of the contained + // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string + // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as + // the string terminator as well. For getting the string length back from that value just use + // "MaxSize - str[LenPos]". + // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, + // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). + struct ShortString { + enum { MaxChars = sizeof(static_cast(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; + Ch str[MaxChars]; + + inline static bool Usable(SizeType len) { return (MaxSize >= len); } + inline void SetLength(SizeType len) { str[LenPos] = static_cast(MaxSize - len); } + inline SizeType GetLength() const { return static_cast(MaxSize - str[LenPos]); } + }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + // By using proper binary layout, retrieval of different integer types do not need conversions. + union Number { +#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN + struct I { + int i; + char padding[4]; + }i; + struct U { + unsigned u; + char padding2[4]; + }u; +#else + struct I { + char padding[4]; + int i; + }i; + struct U { + char padding2[4]; + unsigned u; + }u; +#endif + int64_t i64; + uint64_t u64; + double d; + }; // 8 bytes + + struct ObjectData { + SizeType size; + SizeType capacity; + Member* members; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + struct ArrayData { + SizeType size; + SizeType capacity; + GenericValue* elements; + }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode + + union Data { + String s; + ShortString ss; + Number n; + ObjectData o; + ArrayData a; + Flag f; + }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION + + RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } + RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } + RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } + RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } + RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } + RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } + + // Initialize this value as array with initial data, without calling destructor. + void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { + data_.f.flags = kArrayFlag; + if (count) { + GenericValue* e = static_cast(allocator.Malloc(count * sizeof(GenericValue))); + SetElementsPointer(e); + std::memcpy(e, values, count * sizeof(GenericValue)); + } + else + SetElementsPointer(0); + data_.a.size = data_.a.capacity = count; + } + + //! Initialize this value as object with initial data, without calling destructor. + void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { + data_.f.flags = kObjectFlag; + if (count) { + Member* m = static_cast(allocator.Malloc(count * sizeof(Member))); + SetMembersPointer(m); + std::memcpy(m, members, count * sizeof(Member)); + } + else + SetMembersPointer(0); + data_.o.size = data_.o.capacity = count; + } + + //! Initialize this value as constant string, without calling destructor. + void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { + data_.f.flags = kConstStringFlag; + SetStringPointer(s); + data_.s.length = s.length; + } + + //! Initialize this value as copy string with initial data, without calling destructor. + void SetStringRaw(StringRefType s, Allocator& allocator) { + Ch* str = 0; + if (ShortString::Usable(s.length)) { + data_.f.flags = kShortStringFlag; + data_.ss.SetLength(s.length); + str = data_.ss.str; + } else { + data_.f.flags = kCopyStringFlag; + data_.s.length = s.length; + str = static_cast(allocator.Malloc((s.length + 1) * sizeof(Ch))); + SetStringPointer(str); + } + std::memcpy(str, s, s.length * sizeof(Ch)); + str[s.length] = '\0'; + } + + //! Assignment without calling destructor + void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { + data_ = rhs.data_; + // data_.f.flags = rhs.data_.f.flags; + rhs.data_.f.flags = kNullFlag; + } + + template + bool StringEqual(const GenericValue& rhs) const { + RAPIDJSON_ASSERT(IsString()); + RAPIDJSON_ASSERT(rhs.IsString()); + + const SizeType len1 = GetStringLength(); + const SizeType len2 = rhs.GetStringLength(); + if(len1 != len2) { return false; } + + const Ch* const str1 = GetString(); + const Ch* const str2 = rhs.GetString(); + if(str1 == str2) { return true; } // fast path for constant string + + return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); + } + + Data data_; +}; + +//! GenericValue with UTF8 encoding +typedef GenericValue > Value; + +/////////////////////////////////////////////////////////////////////////////// +// GenericDocument + +//! A document for parsing JSON text as DOM. +/*! + \note implements Handler concept + \tparam Encoding Encoding for both parsing and string storage. + \tparam Allocator Allocator for allocating memory for the DOM + \tparam StackAllocator Allocator for allocating memory for stack during parsing. + \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue. +*/ +template , typename StackAllocator = CrtAllocator> +class GenericDocument : public GenericValue { +public: + typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. + typedef GenericValue ValueType; //!< Value type of the document. + typedef Allocator AllocatorType; //!< Allocator type from template parameter. + + //! Constructor + /*! Creates an empty document of specified type. + \param type Mandatory type of object to create. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + GenericValue(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + + //! Constructor + /*! Creates an empty document which type is Null. + \param allocator Optional allocator for allocating memory. + \param stackCapacity Optional initial capacity of stack in bytes. + \param stackAllocator Optional allocator for allocating memory for stack. + */ + GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : + allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + : ValueType(std::forward(rhs)), // explicit cast to avoid prohibited move from Document + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(std::move(rhs.stack_)), + parseResult_(rhs.parseResult_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + } +#endif + + ~GenericDocument() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move assignment in C++11 + GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT + { + // The cast to ValueType is necessary here, because otherwise it would + // attempt to call GenericValue's templated assignment operator. + ValueType::operator=(std::forward(rhs)); + + // Calling the destructor here would prematurely call stack_'s destructor + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = std::move(rhs.stack_); + parseResult_ = rhs.parseResult_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.parseResult_ = ParseResult(); + + return *this; + } +#endif + + //! Exchange the contents of this document with those of another. + /*! + \param rhs Another document. + \note Constant complexity. + \see GenericValue::Swap + */ + GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { + ValueType::Swap(rhs); + stack_.Swap(rhs.stack_); + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(parseResult_, rhs.parseResult_); + return *this; + } + + //! free-standing swap function helper + /*! + Helper function to enable support for common swap implementation pattern based on \c std::swap: + \code + void swap(MyClass& a, MyClass& b) { + using std::swap; + swap(a.doc, b.doc); + // ... + } + \endcode + \see Swap() + */ + friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } + + //! Populate this document by a generator which produces SAX events. + /*! \tparam Generator A functor with bool f(Handler) prototype. + \param g Generator functor which sends SAX events to the parameter. + \return The document itself for fluent API. + */ + template + GenericDocument& Populate(Generator& g) { + ClearStackOnExit scope(*this); + if (g(*this)) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //!@name Parse from stream + //!@{ + + //! Parse JSON text from an input stream (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam SourceEncoding Encoding of input stream + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + GenericReader reader( + stack_.HasAllocator() ? &stack_.GetAllocator() : 0); + ClearStackOnExit scope(*this); + parseResult_ = reader.template Parse(is, *this); + if (parseResult_) { + RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object + ValueType::operator=(*stack_.template Pop(1));// Move value from stack to document + } + return *this; + } + + //! Parse JSON text from an input stream + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + + //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \param is Input stream to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseStream(InputStream& is) { + return ParseStream(is); + } + //!@} + + //!@name Parse in-place from mutable string + //!@{ + + //! Parse JSON text from a mutable string + /*! \tparam parseFlags Combination of \ref ParseFlag. + \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + template + GenericDocument& ParseInsitu(Ch* str) { + GenericInsituStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) + /*! \param str Mutable zero-terminated string to be parsed. + \return The document itself for fluent API. + */ + GenericDocument& ParseInsitu(Ch* str) { + return ParseInsitu(str); + } + //!@} + + //!@name Parse from read-only string + //!@{ + + //! Parse JSON text from a read-only string (with Encoding conversion) + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \tparam SourceEncoding Transcoding from input Encoding + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + GenericStringStream s(str); + return ParseStream(s); + } + + //! Parse JSON text from a read-only string + /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). + \param str Read-only zero-terminated string to be parsed. + */ + template + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) + /*! \param str Read-only zero-terminated string to be parsed. + */ + GenericDocument& Parse(const Ch* str) { + return Parse(str); + } + + template + GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { + RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); + MemoryStream ms(static_cast(str), length * sizeof(typename SourceEncoding::Ch)); + EncodedInputStream is(ms); + ParseStream(is); + return *this; + } + + template + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + + GenericDocument& Parse(const Ch* str, size_t length) { + return Parse(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + template + GenericDocument& Parse(const std::basic_string& str) { + // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) + return Parse(str.c_str()); + } + + template + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str.c_str()); + } + + GenericDocument& Parse(const std::basic_string& str) { + return Parse(str); + } +#endif // RAPIDJSON_HAS_STDSTRING + + //!@} + + //!@name Handling parse errors + //!@{ + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseError() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + + //! Implicit conversion to get the last parse result +#ifndef __clang // -Wdocumentation + /*! \return \ref ParseResult of the last parse operation + + \code + Document doc; + ParseResult ok = doc.Parse(json); + if (!ok) + printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); + \endcode + */ +#endif + operator ParseResult() const { return parseResult_; } + //!@} + + //! Get the allocator of this document. + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + //! Get the capacity of stack in bytes. + size_t GetStackCapacity() const { return stack_.GetCapacity(); } + +private: + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} + ~ClearStackOnExit() { d_.ClearStack(); } + private: + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + GenericDocument& d_; + }; + + // callers of the following private Handler functions + // template friend class GenericReader; // for parsing + template friend class GenericValue; // for deep copying + +public: + // Implementation of Handler + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } + + bool RawNumber(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool String(const Ch* str, SizeType length, bool copy) { + if (copy) + new (stack_.template Push()) ValueType(str, length, GetAllocator()); + else + new (stack_.template Push()) ValueType(str, length); + return true; + } + + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } + + bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount) { + typename ValueType::Member* members = stack_.template Pop(memberCount); + stack_.template Top()->SetObjectRaw(members, memberCount, GetAllocator()); + return true; + } + + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } + + bool EndArray(SizeType elementCount) { + ValueType* elements = stack_.template Pop(elementCount); + stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; + } + +private: + //! Prohibit copying + GenericDocument(const GenericDocument&); + //! Prohibit assignment + GenericDocument& operator=(const GenericDocument&); + + void ClearStack() { + if (Allocator::kNeedFree) + while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) + (stack_.template Pop(1))->~ValueType(); + else + stack_.Clear(); + stack_.ShrinkToFit(); + } + + void Destroy() { + RAPIDJSON_DELETE(ownAllocator_); + } + + static const size_t kDefaultStackCapacity = 1024; + Allocator* allocator_; + Allocator* ownAllocator_; + internal::Stack stack_; + ParseResult parseResult_; +}; + +//! GenericDocument with UTF8 encoding +typedef GenericDocument > Document; + +// defined here due to the dependency on GenericDocument +template +template +inline +GenericValue::GenericValue(const GenericValue& rhs, Allocator& allocator) +{ + switch (rhs.GetType()) { + case kObjectType: + case kArrayType: { // perform deep copy via SAX Handler + GenericDocument d(&allocator); + rhs.Accept(d); + RawAssign(*d.stack_.template Pop(1)); + } + break; + case kStringType: + if (rhs.data_.f.flags == kConstStringFlag) { + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + } else { + SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); + } + break; + default: + data_.f.flags = rhs.data_.f.flags; + data_ = *reinterpret_cast(&rhs.data_); + break; + } +} + +//! Helper class for accessing Value of array type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetArray(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericArray { +public: + typedef GenericArray ConstArray; + typedef GenericArray Array; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef ValueType* ValueIterator; // This may be const or non-const iterator + typedef const ValueT* ConstValueIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + + template + friend class GenericValue; + + GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} + GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } + ~GenericArray() {} + + SizeType Size() const { return value_.Size(); } + SizeType Capacity() const { return value_.Capacity(); } + bool Empty() const { return value_.Empty(); } + void Clear() const { value_.Clear(); } + ValueType& operator[](SizeType index) const { return value_[index]; } + ValueIterator Begin() const { return value_.Begin(); } + ValueIterator End() const { return value_.End(); } + GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } + GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } + GenericArray PopBack() const { value_.PopBack(); return *this; } + ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } + ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + ValueIterator begin() const { return value_.Begin(); } + ValueIterator end() const { return value_.End(); } +#endif + +private: + GenericArray(); + GenericArray(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +//! Helper class for accessing Value of object type. +/*! + Instance of this helper class is obtained by \c GenericValue::GetObject(). + In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. +*/ +template +class GenericObject { +public: + typedef GenericObject ConstObject; + typedef GenericObject Object; + typedef ValueT PlainType; + typedef typename internal::MaybeAddConst::Type ValueType; + typedef GenericMemberIterator MemberIterator; // This may be const or non-const iterator + typedef GenericMemberIterator ConstMemberIterator; + typedef typename ValueType::AllocatorType AllocatorType; + typedef typename ValueType::StringRefType StringRefType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename ValueType::Ch Ch; + + template + friend class GenericValue; + + GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} + GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } + ~GenericObject() {} + + SizeType MemberCount() const { return value_.MemberCount(); } + bool ObjectEmpty() const { return value_.ObjectEmpty(); } + template ValueType& operator[](T* name) const { return value_[name]; } + template ValueType& operator[](const GenericValue& name) const { return value_[name]; } +#if RAPIDJSON_HAS_STDSTRING + ValueType& operator[](const std::basic_string& name) const { return value_[name]; } +#endif + MemberIterator MemberBegin() const { return value_.MemberBegin(); } + MemberIterator MemberEnd() const { return value_.MemberEnd(); } + bool HasMember(const Ch* name) const { return value_.HasMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool HasMember(const std::basic_string& name) const { return value_.HasMember(name); } +#endif + template bool HasMember(const GenericValue& name) const { return value_.HasMember(name); } + MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } + template MemberIterator FindMember(const GenericValue& name) const { return value_.FindMember(name); } +#if RAPIDJSON_HAS_STDSTRING + MemberIterator FindMember(const std::basic_string& name) const { return value_.FindMember(name); } +#endif + GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_STDSTRING + GenericObject AddMember(ValueType& name, std::basic_string& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + template RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } + void RemoveAllMembers() { return value_.RemoveAllMembers(); } + bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool RemoveMember(const std::basic_string& name) const { return value_.RemoveMember(name); } +#endif + template bool RemoveMember(const GenericValue& name) const { return value_.RemoveMember(name); } + MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } + MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } + MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } + bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } +#if RAPIDJSON_HAS_STDSTRING + bool EraseMember(const std::basic_string& name) const { return EraseMember(ValueType(StringRef(name))); } +#endif + template bool EraseMember(const GenericValue& name) const { return value_.EraseMember(name); } + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR + MemberIterator begin() const { return value_.MemberBegin(); } + MemberIterator end() const { return value_.MemberEnd(); } +#endif + +private: + GenericObject(); + GenericObject(ValueType& value) : value_(value) {} + ValueType& value_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_DOCUMENT_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/encodedstream.h b/src/third-party/discord-rpc/include/rapidjson/encodedstream.h new file mode 100644 index 000000000..145068386 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/encodedstream.h @@ -0,0 +1,299 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODEDSTREAM_H_ +#define RAPIDJSON_ENCODEDSTREAM_H_ + +#include "stream.h" +#include "memorystream.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Input byte stream wrapper with a statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam InputByteStream Type of input byte stream. For example, FileReadStream. +*/ +template +class EncodedInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedInputStream(InputByteStream& is) : is_(is) { + current_ = Encoding::TakeBOM(is_); + } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); + + InputByteStream& is_; + Ch current_; +}; + +//! Specialized for UTF8 MemoryStream. +template <> +class EncodedInputStream, MemoryStream> { +public: + typedef UTF8<>::Ch Ch; + + EncodedInputStream(MemoryStream& is) : is_(is) { + if (static_cast(is_.Peek()) == 0xEFu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBBu) is_.Take(); + if (static_cast(is_.Peek()) == 0xBFu) is_.Take(); + } + Ch Peek() const { return is_.Peek(); } + Ch Take() { return is_.Take(); } + size_t Tell() const { return is_.Tell(); } + + // Not implemented + void Put(Ch) {} + void Flush() {} + Ch* PutBegin() { return 0; } + size_t PutEnd(Ch*) { return 0; } + + MemoryStream& is_; + +private: + EncodedInputStream(const EncodedInputStream&); + EncodedInputStream& operator=(const EncodedInputStream&); +}; + +//! Output byte stream wrapper with statically bound encoding. +/*! + \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE. + \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream. +*/ +template +class EncodedOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef typename Encoding::Ch Ch; + + EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) { + if (putBOM) + Encoding::PutBOM(os_); + } + + void Put(Ch c) { Encoding::Put(os_, c); } + void Flush() { os_.Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + EncodedOutputStream(const EncodedOutputStream&); + EncodedOutputStream& operator=(const EncodedOutputStream&); + + OutputByteStream& os_; +}; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + +//! Input stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for reading. + \tparam InputByteStream type of input byte stream to be wrapped. +*/ +template +class AutoUTFInputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param is input stream to be wrapped. + \param type UTF encoding type if it is not detected from the stream. + */ + AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + DetectType(); + static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) }; + takeFunc_ = f[type_]; + current_ = takeFunc_(*is_); + } + + UTFType GetType() const { return type_; } + bool HasBOM() const { return hasBOM_; } + + Ch Peek() const { return current_; } + Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; } + size_t Tell() const { return is_->Tell(); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFInputStream(const AutoUTFInputStream&); + AutoUTFInputStream& operator=(const AutoUTFInputStream&); + + // Detect encoding type with BOM or RFC 4627 + void DetectType() { + // BOM (Byte Order Mark): + // 00 00 FE FF UTF-32BE + // FF FE 00 00 UTF-32LE + // FE FF UTF-16BE + // FF FE UTF-16LE + // EF BB BF UTF-8 + + const unsigned char* c = reinterpret_cast(is_->Peek4()); + if (!c) + return; + + unsigned bom = static_cast(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24)); + hasBOM_ = false; + if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); } + else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); } + + // RFC 4627: Section 3 + // "Since the first two characters of a JSON text will always be ASCII + // characters [RFC0020], it is possible to determine whether an octet + // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + // at the pattern of nulls in the first four octets." + // 00 00 00 xx UTF-32BE + // 00 xx 00 xx UTF-16BE + // xx 00 00 00 UTF-32LE + // xx 00 xx 00 UTF-16LE + // xx xx xx xx UTF-8 + + if (!hasBOM_) { + unsigned pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0); + switch (pattern) { + case 0x08: type_ = kUTF32BE; break; + case 0x0A: type_ = kUTF16BE; break; + case 0x01: type_ = kUTF32LE; break; + case 0x05: type_ = kUTF16LE; break; + case 0x0F: type_ = kUTF8; break; + default: break; // Use type defined by user. + } + } + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + } + + typedef Ch (*TakeFunc)(InputByteStream& is); + InputByteStream* is_; + UTFType type_; + Ch current_; + TakeFunc takeFunc_; + bool hasBOM_; +}; + +//! Output stream wrapper with dynamically bound encoding and automatic encoding detection. +/*! + \tparam CharType Type of character for writing. + \tparam OutputByteStream type of output byte stream to be wrapped. +*/ +template +class AutoUTFOutputStream { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); +public: + typedef CharType Ch; + + //! Constructor. + /*! + \param os output stream to be wrapped. + \param type UTF encoding type. + \param putBOM Whether to write BOM at the beginning of the stream. + */ + AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) { + RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE); + + // Runtime check whether the size of character type is sufficient. It only perform checks with assertion. + if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2); + if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4); + + static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) }; + putFunc_ = f[type_]; + + if (putBOM) + PutBOM(); + } + + UTFType GetType() const { return type_; } + + void Put(Ch c) { putFunc_(*os_, c); } + void Flush() { os_->Flush(); } + + // Not implemented + Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;} + Ch Take() { RAPIDJSON_ASSERT(false); return 0;} + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + AutoUTFOutputStream(const AutoUTFOutputStream&); + AutoUTFOutputStream& operator=(const AutoUTFOutputStream&); + + void PutBOM() { + typedef void (*PutBOMFunc)(OutputByteStream&); + static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) }; + f[type_](*os_); + } + + typedef void (*PutFunc)(OutputByteStream&, Ch); + + OutputByteStream* os_; + UTFType type_; + PutFunc putFunc_; +}; + +#undef RAPIDJSON_ENCODINGS_FUNC + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/encodings.h b/src/third-party/discord-rpc/include/rapidjson/encodings.h new file mode 100644 index 000000000..baa7c2b17 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/encodings.h @@ -0,0 +1,716 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ENCODINGS_H_ +#define RAPIDJSON_ENCODINGS_H_ + +#include "rapidjson.h" + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#elif defined(__GNUC__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(overflow) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Encoding + +/*! \class rapidjson::Encoding + \brief Concept for encoding of Unicode characters. + +\code +concept Encoding { + typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition. + + enum { supportUnicode = 1 }; // or 0 if not supporting unicode + + //! \brief Encode a Unicode codepoint to an output stream. + //! \param os Output stream. + //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively. + template + static void Encode(OutputStream& os, unsigned codepoint); + + //! \brief Decode a Unicode codepoint from an input stream. + //! \param is Input stream. + //! \param codepoint Output of the unicode codepoint. + //! \return true if a valid codepoint can be decoded from the stream. + template + static bool Decode(InputStream& is, unsigned* codepoint); + + //! \brief Validate one Unicode codepoint from an encoded stream. + //! \param is Input stream to obtain codepoint. + //! \param os Output for copying one codepoint. + //! \return true if it is valid. + //! \note This function just validating and copying the codepoint without actually decode it. + template + static bool Validate(InputStream& is, OutputStream& os); + + // The following functions are deal with byte streams. + + //! Take a character from input byte stream, skip BOM if exist. + template + static CharType TakeBOM(InputByteStream& is); + + //! Take a character from input byte stream. + template + static Ch Take(InputByteStream& is); + + //! Put BOM to output byte stream. + template + static void PutBOM(OutputByteStream& os); + + //! Put a character to output byte stream. + template + static void Put(OutputByteStream& os, Ch c); +}; +\endcode +*/ + +/////////////////////////////////////////////////////////////////////////////// +// UTF8 + +//! UTF-8 encoding. +/*! http://en.wikipedia.org/wiki/UTF-8 + http://tools.ietf.org/html/rfc3629 + \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char. + \note implements Encoding concept +*/ +template +struct UTF8 { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + os.Put(static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + os.Put(static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + os.Put(static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + os.Put(static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + os.Put(static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + os.Put(static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + if (codepoint <= 0x7F) + PutUnsafe(os, static_cast(codepoint & 0xFF)); + else if (codepoint <= 0x7FF) { + PutUnsafe(os, static_cast(0xC0 | ((codepoint >> 6) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint & 0x3F)))); + } + else if (codepoint <= 0xFFFF) { + PutUnsafe(os, static_cast(0xE0 | ((codepoint >> 12) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, static_cast(0xF0 | ((codepoint >> 18) & 0xFF))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 12) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | ((codepoint >> 6) & 0x3F))); + PutUnsafe(os, static_cast(0x80 | (codepoint & 0x3F))); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { +#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast(c) & 0x3Fu) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + typename InputStream::Ch c = is.Take(); + if (!(c & 0x80)) { + *codepoint = static_cast(c); + return true; + } + + unsigned char type = GetRange(static_cast(c)); + if (type >= 32) { + *codepoint = 0; + } else { + *codepoint = (0xFF >> type) & static_cast(c); + } + bool result = true; + switch (type) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + template + static bool Validate(InputStream& is, OutputStream& os) { +#define COPY() os.Put(c = is.Take()) +#define TRANS(mask) result &= ((GetRange(static_cast(c)) & mask) != 0) +#define TAIL() COPY(); TRANS(0x70) + Ch c; + COPY(); + if (!(c & 0x80)) + return true; + + bool result = true; + switch (GetRange(static_cast(c))) { + case 2: TAIL(); return result; + case 3: TAIL(); TAIL(); return result; + case 4: COPY(); TRANS(0x50); TAIL(); return result; + case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result; + case 6: TAIL(); TAIL(); TAIL(); return result; + case 10: COPY(); TRANS(0x20); TAIL(); return result; + case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result; + default: return false; + } +#undef COPY +#undef TRANS +#undef TAIL + } + + static unsigned char GetRange(unsigned char c) { + // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ + // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types. + static const unsigned char type[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + }; + return type[c]; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + typename InputByteStream::Ch c = Take(is); + if (static_cast(c) != 0xEFu) return c; + c = is.Take(); + if (static_cast(c) != 0xBBu) return c; + c = is.Take(); + if (static_cast(c) != 0xBFu) return c; + c = is.Take(); + return c; + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xEFu)); + os.Put(static_cast(0xBBu)); + os.Put(static_cast(0xBFu)); + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF16 + +//! UTF-16 encoding. +/*! http://en.wikipedia.org/wiki/UTF-16 + http://tools.ietf.org/html/rfc2781 + \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF16LE and UTF16BE, which handle endianness. +*/ +template +struct UTF16 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + os.Put(static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + os.Put(static_cast((v >> 10) | 0xD800)); + os.Put((v & 0x3FF) | 0xDC00); + } + } + + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + if (codepoint <= 0xFFFF) { + RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair + PutUnsafe(os, static_cast(codepoint)); + } + else { + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + unsigned v = codepoint - 0x10000; + PutUnsafe(os, static_cast((v >> 10) | 0xD800)); + PutUnsafe(os, (v & 0x3FF) | 0xDC00); + } + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + typename InputStream::Ch c = is.Take(); + if (c < 0xD800 || c > 0xDFFF) { + *codepoint = static_cast(c); + return true; + } + else if (c <= 0xDBFF) { + *codepoint = (static_cast(c) & 0x3FF) << 10; + c = is.Take(); + *codepoint |= (static_cast(c) & 0x3FF); + *codepoint += 0x10000; + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2); + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2); + typename InputStream::Ch c; + os.Put(static_cast(c = is.Take())); + if (c < 0xD800 || c > 0xDFFF) + return true; + else if (c <= 0xDBFF) { + os.Put(c = is.Take()); + return c >= 0xDC00 && c <= 0xDFFF; + } + return false; + } +}; + +//! UTF-16 little endian encoding. +template +struct UTF16LE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(static_cast(c) & 0xFFu)); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + } +}; + +//! UTF-16 big endian encoding. +template +struct UTF16BE : UTF16 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0xFEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 8; + c |= static_cast(is.Take()); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((static_cast(c) >> 8) & 0xFFu)); + os.Put(static_cast(static_cast(c) & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// UTF32 + +//! UTF-32 encoding. +/*! http://en.wikipedia.org/wiki/UTF-32 + \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead. + \note implements Encoding concept + + \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness. + For streaming, use UTF32LE and UTF32BE, which handle endianness. +*/ +template +struct UTF32 { + typedef CharType Ch; + RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4); + + enum { supportUnicode = 1 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + os.Put(codepoint); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4); + RAPIDJSON_ASSERT(codepoint <= 0x10FFFF); + PutUnsafe(os, codepoint); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c = is.Take(); + *codepoint = c; + return c <= 0x10FFFF; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4); + Ch c; + os.Put(c = is.Take()); + return c <= 0x10FFFF; + } +}; + +//! UTF-32 little endian enocoding. +template +struct UTF32LE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(is.Take()); + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 24; + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0xFFu)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 24) & 0xFFu)); + } +}; + +//! UTF-32 big endian encoding. +template +struct UTF32BE : UTF32 { + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + CharType c = Take(is); + return static_cast(c) == 0x0000FEFFu ? Take(is) : c; + } + + template + static CharType Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + unsigned c = static_cast(static_cast(is.Take())) << 24; + c |= static_cast(static_cast(is.Take())) << 16; + c |= static_cast(static_cast(is.Take())) << 8; + c |= static_cast(static_cast(is.Take())); + return static_cast(c); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0x00u)); + os.Put(static_cast(0xFEu)); + os.Put(static_cast(0xFFu)); + } + + template + static void Put(OutputByteStream& os, CharType c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast((c >> 24) & 0xFFu)); + os.Put(static_cast((c >> 16) & 0xFFu)); + os.Put(static_cast((c >> 8) & 0xFFu)); + os.Put(static_cast(c & 0xFFu)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// ASCII + +//! ASCII encoding. +/*! http://en.wikipedia.org/wiki/ASCII + \tparam CharType Code unit for storing 7-bit ASCII data. Default is char. + \note implements Encoding concept +*/ +template +struct ASCII { + typedef CharType Ch; + + enum { supportUnicode = 0 }; + + template + static void Encode(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + os.Put(static_cast(codepoint & 0xFF)); + } + + template + static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + RAPIDJSON_ASSERT(codepoint <= 0x7F); + PutUnsafe(os, static_cast(codepoint & 0xFF)); + } + + template + static bool Decode(InputStream& is, unsigned* codepoint) { + uint8_t c = static_cast(is.Take()); + *codepoint = c; + return c <= 0X7F; + } + + template + static bool Validate(InputStream& is, OutputStream& os) { + uint8_t c = static_cast(is.Take()); + os.Put(static_cast(c)); + return c <= 0x7F; + } + + template + static CharType TakeBOM(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + uint8_t c = static_cast(Take(is)); + return static_cast(c); + } + + template + static Ch Take(InputByteStream& is) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1); + return static_cast(is.Take()); + } + + template + static void PutBOM(OutputByteStream& os) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + (void)os; + } + + template + static void Put(OutputByteStream& os, Ch c) { + RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1); + os.Put(static_cast(c)); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +// AutoUTF + +//! Runtime-specified UTF encoding type of a stream. +enum UTFType { + kUTF8 = 0, //!< UTF-8. + kUTF16LE = 1, //!< UTF-16 little endian. + kUTF16BE = 2, //!< UTF-16 big endian. + kUTF32LE = 3, //!< UTF-32 little endian. + kUTF32BE = 4 //!< UTF-32 big endian. +}; + +//! Dynamically select encoding according to stream's runtime-specified UTF encoding type. +/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType(). +*/ +template +struct AutoUTF { + typedef CharType Ch; + + enum { supportUnicode = 1 }; + +#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8::x, UTF16LE::x, UTF16BE::x, UTF32LE::x, UTF32BE::x + + template + RAPIDJSON_FORCEINLINE static void Encode(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static void EncodeUnsafe(OutputStream& os, unsigned codepoint) { + typedef void (*EncodeFunc)(OutputStream&, unsigned); + static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) }; + (*f[os.GetType()])(os, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Decode(InputStream& is, unsigned* codepoint) { + typedef bool (*DecodeFunc)(InputStream&, unsigned*); + static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) }; + return (*f[is.GetType()])(is, codepoint); + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + typedef bool (*ValidateFunc)(InputStream&, OutputStream&); + static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) }; + return (*f[is.GetType()])(is, os); + } + +#undef RAPIDJSON_ENCODINGS_FUNC +}; + +/////////////////////////////////////////////////////////////////////////////// +// Transcoder + +//! Encoding conversion. +template +struct Transcoder { + //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream. + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::Encode(os, codepoint); + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + unsigned codepoint; + if (!SourceEncoding::Decode(is, &codepoint)) + return false; + TargetEncoding::EncodeUnsafe(os, codepoint); + return true; + } + + //! Validate one Unicode codepoint from an encoded stream. + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Transcode(is, os); // Since source/target encoding is different, must transcode. + } +}; + +// Forward declaration. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c); + +//! Specialization of Transcoder with same source and target encoding. +template +struct Transcoder { + template + RAPIDJSON_FORCEINLINE static bool Transcode(InputStream& is, OutputStream& os) { + os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool TranscodeUnsafe(InputStream& is, OutputStream& os) { + PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class. + return true; + } + + template + RAPIDJSON_FORCEINLINE static bool Validate(InputStream& is, OutputStream& os) { + return Encoding::Validate(is, os); // source/target encoding are the same + } +}; + +RAPIDJSON_NAMESPACE_END + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ENCODINGS_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/error/en.h b/src/third-party/discord-rpc/include/rapidjson/error/en.h new file mode 100644 index 000000000..2db838bff --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/error/en.h @@ -0,0 +1,74 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_EN_H_ +#define RAPIDJSON_ERROR_EN_H_ + +#include "error.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(covered-switch-default) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Maps error code of parsing into error message. +/*! + \ingroup RAPIDJSON_ERRORS + \param parseErrorCode Error code obtained in parsing. + \return the error message. + \note User can make a copy of this function for localization. + Using switch-case is safer for future modification of error codes. +*/ +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) { + switch (parseErrorCode) { + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); + + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values."); + + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); + + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member."); + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member."); + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member."); + + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element."); + + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string."); + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid."); + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string."); + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string."); + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string."); + + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double."); + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number."); + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number."); + + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error."); + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error."); + + default: return RAPIDJSON_ERROR_STRING("Unknown error."); + } +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_EN_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/error/error.h b/src/third-party/discord-rpc/include/rapidjson/error/error.h new file mode 100644 index 000000000..95cb31a72 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/error/error.h @@ -0,0 +1,155 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ERROR_ERROR_H_ +#define RAPIDJSON_ERROR_ERROR_H_ + +#include "../rapidjson.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +/*! \file error.h */ + +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */ + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_CHARTYPE + +//! Character type of error messages. +/*! \ingroup RAPIDJSON_ERRORS + The default character type is \c char. + On Windows, user can define this macro as \c TCHAR for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_CHARTYPE +#define RAPIDJSON_ERROR_CHARTYPE char +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ERROR_STRING + +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[]. +/*! \ingroup RAPIDJSON_ERRORS + By default this conversion macro does nothing. + On Windows, user can define this macro as \c _T(x) for supporting both + unicode/non-unicode settings. +*/ +#ifndef RAPIDJSON_ERROR_STRING +#define RAPIDJSON_ERROR_STRING(x) x +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseErrorCode + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericReader::Parse, GenericReader::GetParseErrorCode +*/ +enum ParseErrorCode { + kParseErrorNone = 0, //!< No error. + + kParseErrorDocumentEmpty, //!< The document is empty. + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. + + kParseErrorValueInvalid, //!< Invalid value. + + kParseErrorObjectMissName, //!< Missing a name for object member. + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member. + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member. + + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element. + + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string. + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid. + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string. + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string. + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string. + + kParseErrorNumberTooBig, //!< Number too big to be stored in double. + kParseErrorNumberMissFraction, //!< Miss fraction part in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination, //!< Parsing was terminated. + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error. +}; + +//! Result of parsing (wraps ParseErrorCode) +/*! + \ingroup RAPIDJSON_ERRORS + \code + Document doc; + ParseResult ok = doc.Parse("[42]"); + if (!ok) { + fprintf(stderr, "JSON parse error: %s (%u)", + GetParseError_En(ok.Code()), ok.Offset()); + exit(EXIT_FAILURE); + } + \endcode + \see GenericReader::Parse, GenericDocument::Parse +*/ +struct ParseResult { +public: + //! Default constructor, no error. + ParseResult() : code_(kParseErrorNone), offset_(0) {} + //! Constructor to set an error. + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {} + + //! Get the error code. + ParseErrorCode Code() const { return code_; } + //! Get the error offset, if \ref IsError(), 0 otherwise. + size_t Offset() const { return offset_; } + + //! Conversion to \c bool, returns \c true, iff !\ref IsError(). + operator bool() const { return !IsError(); } + //! Whether the result is an error. + bool IsError() const { return code_ != kParseErrorNone; } + + bool operator==(const ParseResult& that) const { return code_ == that.code_; } + bool operator==(ParseErrorCode code) const { return code_ == code; } + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; } + + //! Reset error code. + void Clear() { Set(kParseErrorNone); } + //! Update error code and offset. + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; } + +private: + ParseErrorCode code_; + size_t offset_; +}; + +//! Function pointer type of GetParseError(). +/*! \ingroup RAPIDJSON_ERRORS + + This is the prototype for \c GetParseError_X(), where \c X is a locale. + User can dynamically change locale in runtime, e.g.: +\code + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode()); +\endcode +*/ +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode); + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_ERROR_ERROR_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/filereadstream.h b/src/third-party/discord-rpc/include/rapidjson/filereadstream.h new file mode 100644 index 000000000..b56ea13b3 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/filereadstream.h @@ -0,0 +1,99 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEREADSTREAM_H_ +#define RAPIDJSON_FILEREADSTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! File byte stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileReadStream { +public: + typedef char Ch; //!< Character type (byte). + + //! Constructor. + /*! + \param fp File pointer opened for read. + \param buffer user-supplied buffer. + \param bufferSize size of buffer in bytes. Must >=4 bytes. + */ + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) { + RAPIDJSON_ASSERT(fp_ != 0); + RAPIDJSON_ASSERT(bufferSize >= 4); + Read(); + } + + Ch Peek() const { return *current_; } + Ch Take() { Ch c = *current_; Read(); return c; } + size_t Tell() const { return count_ + static_cast(current_ - buffer_); } + + // Not implemented + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return (current_ + 4 <= bufferLast_) ? current_ : 0; + } + +private: + void Read() { + if (current_ < bufferLast_) + ++current_; + else if (!eof_) { + count_ += readCount_; + readCount_ = fread(buffer_, 1, bufferSize_, fp_); + bufferLast_ = buffer_ + readCount_ - 1; + current_ = buffer_; + + if (readCount_ < bufferSize_) { + buffer_[readCount_] = '\0'; + ++bufferLast_; + eof_ = true; + } + } + } + + std::FILE* fp_; + Ch *buffer_; + size_t bufferSize_; + Ch *bufferLast_; + Ch *current_; + size_t readCount_; + size_t count_; //!< Number of characters read + bool eof_; +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/filewritestream.h b/src/third-party/discord-rpc/include/rapidjson/filewritestream.h new file mode 100644 index 000000000..6378dd60e --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/filewritestream.h @@ -0,0 +1,104 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FILEWRITESTREAM_H_ +#define RAPIDJSON_FILEWRITESTREAM_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of C file stream for input using fread(). +/*! + \note implements Stream concept +*/ +class FileWriteStream { +public: + typedef char Ch; //!< Character type. Only support char. + + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) { + RAPIDJSON_ASSERT(fp_ != 0); + } + + void Put(char c) { + if (current_ >= bufferEnd_) + Flush(); + + *current_++ = c; + } + + void PutN(char c, size_t n) { + size_t avail = static_cast(bufferEnd_ - current_); + while (n > avail) { + std::memset(current_, c, avail); + current_ += avail; + Flush(); + n -= avail; + avail = static_cast(bufferEnd_ - current_); + } + + if (n > 0) { + std::memset(current_, c, n); + current_ += n; + } + } + + void Flush() { + if (current_ != buffer_) { + size_t result = fwrite(buffer_, 1, static_cast(current_ - buffer_), fp_); + if (result < static_cast(current_ - buffer_)) { + // failure deliberately ignored at this time + // added to avoid warn_unused_result build errors + } + current_ = buffer_; + } + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + // Prohibit copy constructor & assignment operator. + FileWriteStream(const FileWriteStream&); + FileWriteStream& operator=(const FileWriteStream&); + + std::FILE* fp_; + char *buffer_; + char *bufferEnd_; + char *current_; +}; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(FileWriteStream& stream, char c, size_t n) { + stream.PutN(c, n); +} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_FILESTREAM_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/fwd.h b/src/third-party/discord-rpc/include/rapidjson/fwd.h new file mode 100644 index 000000000..e8104e841 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/fwd.h @@ -0,0 +1,151 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_FWD_H_ +#define RAPIDJSON_FWD_H_ + +#include "rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN + +// encodings.h + +template struct UTF8; +template struct UTF16; +template struct UTF16BE; +template struct UTF16LE; +template struct UTF32; +template struct UTF32BE; +template struct UTF32LE; +template struct ASCII; +template struct AutoUTF; + +template +struct Transcoder; + +// allocators.h + +class CrtAllocator; + +template +class MemoryPoolAllocator; + +// stream.h + +template +struct GenericStringStream; + +typedef GenericStringStream > StringStream; + +template +struct GenericInsituStringStream; + +typedef GenericInsituStringStream > InsituStringStream; + +// stringbuffer.h + +template +class GenericStringBuffer; + +typedef GenericStringBuffer, CrtAllocator> StringBuffer; + +// filereadstream.h + +class FileReadStream; + +// filewritestream.h + +class FileWriteStream; + +// memorybuffer.h + +template +struct GenericMemoryBuffer; + +typedef GenericMemoryBuffer MemoryBuffer; + +// memorystream.h + +struct MemoryStream; + +// reader.h + +template +struct BaseReaderHandler; + +template +class GenericReader; + +typedef GenericReader, UTF8, CrtAllocator> Reader; + +// writer.h + +template +class Writer; + +// prettywriter.h + +template +class PrettyWriter; + +// document.h + +template +struct GenericMember; + +template +class GenericMemberIterator; + +template +struct GenericStringRef; + +template +class GenericValue; + +typedef GenericValue, MemoryPoolAllocator > Value; + +template +class GenericDocument; + +typedef GenericDocument, MemoryPoolAllocator, CrtAllocator> Document; + +// pointer.h + +template +class GenericPointer; + +typedef GenericPointer Pointer; + +// schema.h + +template +class IGenericRemoteSchemaDocumentProvider; + +template +class GenericSchemaDocument; + +typedef GenericSchemaDocument SchemaDocument; +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +template < + typename SchemaDocumentType, + typename OutputHandler, + typename StateAllocator> +class GenericSchemaValidator; + +typedef GenericSchemaValidator, void>, CrtAllocator> SchemaValidator; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSONFWD_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/biginteger.h b/src/third-party/discord-rpc/include/rapidjson/internal/biginteger.h new file mode 100644 index 000000000..9d3e88c99 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/biginteger.h @@ -0,0 +1,290 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_BIGINTEGER_H_ +#define RAPIDJSON_BIGINTEGER_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include // for _umul128 +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class BigInteger { +public: + typedef uint64_t Type; + + BigInteger(const BigInteger& rhs) : count_(rhs.count_) { + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + + explicit BigInteger(uint64_t u) : count_(1) { + digits_[0] = u; + } + + BigInteger(const char* decimals, size_t length) : count_(1) { + RAPIDJSON_ASSERT(length > 0); + digits_[0] = 0; + size_t i = 0; + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19 + while (length >= kMaxDigitPerIteration) { + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration); + length -= kMaxDigitPerIteration; + i += kMaxDigitPerIteration; + } + + if (length > 0) + AppendDecimal64(decimals + i, decimals + i + length); + } + + BigInteger& operator=(const BigInteger &rhs) + { + if (this != &rhs) { + count_ = rhs.count_; + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type)); + } + return *this; + } + + BigInteger& operator=(uint64_t u) { + digits_[0] = u; + count_ = 1; + return *this; + } + + BigInteger& operator+=(uint64_t u) { + Type backup = digits_[0]; + digits_[0] += u; + for (size_t i = 0; i < count_ - 1; i++) { + if (digits_[i] >= backup) + return *this; // no carry + backup = digits_[i + 1]; + digits_[i + 1] += 1; + } + + // Last carry + if (digits_[count_ - 1] < backup) + PushBack(1); + + return *this; + } + + BigInteger& operator*=(uint64_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + uint64_t hi; + digits_[i] = MulAdd64(digits_[i], u, k, &hi); + k = hi; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator*=(uint32_t u) { + if (u == 0) return *this = 0; + if (u == 1) return *this; + if (*this == 1) return *this = u; + + uint64_t k = 0; + for (size_t i = 0; i < count_; i++) { + const uint64_t c = digits_[i] >> 32; + const uint64_t d = digits_[i] & 0xFFFFFFFF; + const uint64_t uc = u * c; + const uint64_t ud = u * d; + const uint64_t p0 = ud + k; + const uint64_t p1 = uc + (p0 >> 32); + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32); + k = p1 >> 32; + } + + if (k > 0) + PushBack(k); + + return *this; + } + + BigInteger& operator<<=(size_t shift) { + if (IsZero() || shift == 0) return *this; + + size_t offset = shift / kTypeBit; + size_t interShift = shift % kTypeBit; + RAPIDJSON_ASSERT(count_ + offset <= kCapacity); + + if (interShift == 0) { + std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type)); + count_ += offset; + } + else { + digits_[count_] = 0; + for (size_t i = count_; i > 0; i--) + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift)); + digits_[offset] = digits_[0] << interShift; + count_ += offset; + if (digits_[count_]) + count_++; + } + + std::memset(digits_, 0, offset * sizeof(Type)); + + return *this; + } + + bool operator==(const BigInteger& rhs) const { + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0; + } + + bool operator==(const Type rhs) const { + return count_ == 1 && digits_[0] == rhs; + } + + BigInteger& MultiplyPow5(unsigned exp) { + static const uint32_t kPow5[12] = { + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + if (exp == 0) return *this; + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27 + for (; exp >= 13; exp -= 13) *this *= static_cast(1220703125u); // 5^13 + if (exp > 0) *this *= kPow5[exp - 1]; + return *this; + } + + // Compute absolute difference of this and rhs. + // Assume this != rhs + bool Difference(const BigInteger& rhs, BigInteger* out) const { + int cmp = Compare(rhs); + RAPIDJSON_ASSERT(cmp != 0); + const BigInteger *a, *b; // Makes a > b + bool ret; + if (cmp < 0) { a = &rhs; b = this; ret = true; } + else { a = this; b = &rhs; ret = false; } + + Type borrow = 0; + for (size_t i = 0; i < a->count_; i++) { + Type d = a->digits_[i] - borrow; + if (i < b->count_) + d -= b->digits_[i]; + borrow = (d > a->digits_[i]) ? 1 : 0; + out->digits_[i] = d; + if (d != 0) + out->count_ = i + 1; + } + + return ret; + } + + int Compare(const BigInteger& rhs) const { + if (count_ != rhs.count_) + return count_ < rhs.count_ ? -1 : 1; + + for (size_t i = count_; i-- > 0;) + if (digits_[i] != rhs.digits_[i]) + return digits_[i] < rhs.digits_[i] ? -1 : 1; + + return 0; + } + + size_t GetCount() const { return count_; } + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; } + bool IsZero() const { return count_ == 1 && digits_[0] == 0; } + +private: + void AppendDecimal64(const char* begin, const char* end) { + uint64_t u = ParseUint64(begin, end); + if (IsZero()) + *this = u; + else { + unsigned exp = static_cast(end - begin); + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u + } + } + + void PushBack(Type digit) { + RAPIDJSON_ASSERT(count_ < kCapacity); + digits_[count_++] = digit; + } + + static uint64_t ParseUint64(const char* begin, const char* end) { + uint64_t r = 0; + for (const char* p = begin; p != end; ++p) { + RAPIDJSON_ASSERT(*p >= '0' && *p <= '9'); + r = r * 10u + static_cast(*p - '0'); + } + return r; + } + + // Assume a * b + k < 2^128 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t low = _umul128(a, b, outHigh) + k; + if (low < k) + (*outHigh)++; + return low; +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(a) * static_cast(b); + p += k; + *outHigh = static_cast(p >> 64); + return static_cast(p); +#else + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32; + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1; + x1 += (x0 >> 32); // can't give carry + x1 += x2; + if (x1 < x2) + x3 += (static_cast(1) << 32); + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF); + uint64_t hi = x3 + (x1 >> 32); + + lo += k; + if (lo < k) + hi++; + *outHigh = hi; + return lo; +#endif + } + + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000 + static const size_t kCapacity = kBitCount / sizeof(Type); + static const size_t kTypeBit = sizeof(Type) * 8; + + Type digits_[kCapacity]; + size_t count_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_BIGINTEGER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/diyfp.h b/src/third-party/discord-rpc/include/rapidjson/internal/diyfp.h new file mode 100644 index 000000000..c9fefdc61 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/diyfp.h @@ -0,0 +1,258 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DIYFP_H_ +#define RAPIDJSON_DIYFP_H_ + +#include "../rapidjson.h" + +#if defined(_MSC_VER) && defined(_M_AMD64) +#include +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_umul128) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +struct DiyFp { + DiyFp() : f(), e() {} + + DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} + + explicit DiyFp(double d) { + union { + double d; + uint64_t u64; + } u = { d }; + + int biased_e = static_cast((u.u64 & kDpExponentMask) >> kDpSignificandSize); + uint64_t significand = (u.u64 & kDpSignificandMask); + if (biased_e != 0) { + f = significand + kDpHiddenBit; + e = biased_e - kDpExponentBias; + } + else { + f = significand; + e = kDpMinExponent + 1; + } + } + + DiyFp operator-(const DiyFp& rhs) const { + return DiyFp(f - rhs.f, e); + } + + DiyFp operator*(const DiyFp& rhs) const { +#if defined(_MSC_VER) && defined(_M_AMD64) + uint64_t h; + uint64_t l = _umul128(f, rhs.f, &h); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) + __extension__ typedef unsigned __int128 uint128; + uint128 p = static_cast(f) * static_cast(rhs.f); + uint64_t h = static_cast(p >> 64); + uint64_t l = static_cast(p); + if (l & (uint64_t(1) << 63)) // rounding + h++; + return DiyFp(h, e + rhs.e + 64); +#else + const uint64_t M32 = 0xFFFFFFFF; + const uint64_t a = f >> 32; + const uint64_t b = f & M32; + const uint64_t c = rhs.f >> 32; + const uint64_t d = rhs.f & M32; + const uint64_t ac = a * c; + const uint64_t bc = b * c; + const uint64_t ad = a * d; + const uint64_t bd = b * d; + uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); + tmp += 1U << 31; /// mult_round + return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); +#endif + } + + DiyFp Normalize() const { +#if defined(_MSC_VER) && defined(_M_AMD64) + unsigned long index; + _BitScanReverse64(&index, f); + return DiyFp(f << (63 - index), e - (63 - index)); +#elif defined(__GNUC__) && __GNUC__ >= 4 + int s = __builtin_clzll(f); + return DiyFp(f << s, e - s); +#else + DiyFp res = *this; + while (!(res.f & (static_cast(1) << 63))) { + res.f <<= 1; + res.e--; + } + return res; +#endif + } + + DiyFp NormalizeBoundary() const { + DiyFp res = *this; + while (!(res.f & (kDpHiddenBit << 1))) { + res.f <<= 1; + res.e--; + } + res.f <<= (kDiySignificandSize - kDpSignificandSize - 2); + res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2); + return res; + } + + void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const { + DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary(); + DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1); + mi.f <<= mi.e - pl.e; + mi.e = pl.e; + *plus = pl; + *minus = mi; + } + + double ToDouble() const { + union { + double d; + uint64_t u64; + }u; + const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 : + static_cast(e + kDpExponentBias); + u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize); + return u.d; + } + + static const int kDiySignificandSize = 64; + static const int kDpSignificandSize = 52; + static const int kDpExponentBias = 0x3FF + kDpSignificandSize; + static const int kDpMaxExponent = 0x7FF - kDpExponentBias; + static const int kDpMinExponent = -kDpExponentBias; + static const int kDpDenormalExponent = -kDpExponentBias + 1; + static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + uint64_t f; + int e; +}; + +inline DiyFp GetCachedPowerByIndex(size_t index) { + // 10^-348, 10^-340, ..., 10^340 + static const uint64_t kCachedPowers_F[] = { + RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76), + RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea), + RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df), + RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f), + RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c), + RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5), + RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d), + RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637), + RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7), + RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5), + RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b), + RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996), + RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6), + RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8), + RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053), + RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd), + RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94), + RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b), + RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac), + RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3), + RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb), + RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c), + RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000), + RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984), + RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70), + RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245), + RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8), + RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a), + RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea), + RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85), + RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2), + RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3), + RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25), + RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece), + RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5), + RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a), + RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c), + RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a), + RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129), + RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429), + RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d), + RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841), + RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9), + RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b) + }; + static const int16_t kCachedPowers_E[] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, + -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, + -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, + -422, -396, -369, -343, -316, -289, -263, -236, -210, -183, + -157, -130, -103, -77, -50, -24, 3, 30, 56, 83, + 109, 136, 162, 189, 216, 242, 269, 295, 322, 348, + 375, 402, 428, 455, 481, 508, 534, 561, 588, 614, + 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, + 907, 933, 960, 986, 1013, 1039, 1066 + }; + return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]); +} + +inline DiyFp GetCachedPower(int e, int* K) { + + //int k = static_cast(ceil((-61 - e) * 0.30102999566398114)) + 374; + double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive + int k = static_cast(dk); + if (dk - k > 0.0) + k++; + + unsigned index = static_cast((k >> 3) + 1); + *K = -(-348 + static_cast(index << 3)); // decimal exponent no need lookup table + + return GetCachedPowerByIndex(index); +} + +inline DiyFp GetCachedPower10(int exp, int *outExp) { + unsigned index = (static_cast(exp) + 348u) / 8u; + *outExp = -348 + static_cast(index) * 8; + return GetCachedPowerByIndex(index); + } + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +RAPIDJSON_DIAG_OFF(padded) +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DIYFP_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/dtoa.h b/src/third-party/discord-rpc/include/rapidjson/internal/dtoa.h new file mode 100644 index 000000000..8d6350e62 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/dtoa.h @@ -0,0 +1,245 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +// This is a C++ header-only implementation of Grisu2 algorithm from the publication: +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with +// integers." ACM Sigplan Notices 45.6 (2010): 233-243. + +#ifndef RAPIDJSON_DTOA_ +#define RAPIDJSON_DTOA_ + +#include "itoa.h" // GetDigitsLut() +#include "diyfp.h" +#include "ieee754.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124 +#endif + +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) { + while (rest < wp_w && delta - rest >= ten_kappa && + (rest + ten_kappa < wp_w || /// closer + wp_w - rest > rest + ten_kappa - wp_w)) { + buffer[len - 1]--; + rest += ten_kappa; + } +} + +inline unsigned CountDecimalDigit32(uint32_t n) { + // Simple pure C++ implementation was faster than __builtin_clz version in this situation. + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + if (n < 100000) return 5; + if (n < 1000000) return 6; + if (n < 10000000) return 7; + if (n < 100000000) return 8; + // Will not reach 10 digits in DigitGen() + //if (n < 1000000000) return 9; + //return 10; + return 9; +} + +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) { + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 }; + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e); + const DiyFp wp_w = Mp - W; + uint32_t p1 = static_cast(Mp.f >> -one.e); + uint64_t p2 = Mp.f & (one.f - 1); + unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9] + *len = 0; + + while (kappa > 0) { + uint32_t d = 0; + switch (kappa) { + case 9: d = p1 / 100000000; p1 %= 100000000; break; + case 8: d = p1 / 10000000; p1 %= 10000000; break; + case 7: d = p1 / 1000000; p1 %= 1000000; break; + case 6: d = p1 / 100000; p1 %= 100000; break; + case 5: d = p1 / 10000; p1 %= 10000; break; + case 4: d = p1 / 1000; p1 %= 1000; break; + case 3: d = p1 / 100; p1 %= 100; break; + case 2: d = p1 / 10; p1 %= 10; break; + case 1: d = p1; p1 = 0; break; + default:; + } + if (d || *len) + buffer[(*len)++] = static_cast('0' + static_cast(d)); + kappa--; + uint64_t tmp = (static_cast(p1) << -one.e) + p2; + if (tmp <= delta) { + *K += kappa; + GrisuRound(buffer, *len, delta, tmp, static_cast(kPow10[kappa]) << -one.e, wp_w.f); + return; + } + } + + // kappa = 0 + for (;;) { + p2 *= 10; + delta *= 10; + char d = static_cast(p2 >> -one.e); + if (d || *len) + buffer[(*len)++] = static_cast('0' + d); + p2 &= one.f - 1; + kappa--; + if (p2 < delta) { + *K += kappa; + int index = -static_cast(kappa); + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[-static_cast(kappa)] : 0)); + return; + } + } +} + +inline void Grisu2(double value, char* buffer, int* length, int* K) { + const DiyFp v(value); + DiyFp w_m, w_p; + v.NormalizedBoundaries(&w_m, &w_p); + + const DiyFp c_mk = GetCachedPower(w_p.e, K); + const DiyFp W = v.Normalize() * c_mk; + DiyFp Wp = w_p * c_mk; + DiyFp Wm = w_m * c_mk; + Wm.f++; + Wp.f--; + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K); +} + +inline char* WriteExponent(int K, char* buffer) { + if (K < 0) { + *buffer++ = '-'; + K = -K; + } + + if (K >= 100) { + *buffer++ = static_cast('0' + static_cast(K / 100)); + K %= 100; + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else if (K >= 10) { + const char* d = GetDigitsLut() + K * 2; + *buffer++ = d[0]; + *buffer++ = d[1]; + } + else + *buffer++ = static_cast('0' + static_cast(K)); + + return buffer; +} + +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) { + const int kk = length + k; // 10^(kk-1) <= v < 10^kk + + if (0 <= k && kk <= 21) { + // 1234e7 -> 12340000000 + for (int i = length; i < kk; i++) + buffer[i] = '0'; + buffer[kk] = '.'; + buffer[kk + 1] = '0'; + return &buffer[kk + 2]; + } + else if (0 < kk && kk <= 21) { + // 1234e-2 -> 12.34 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast(length - kk)); + buffer[kk] = '.'; + if (0 > k + maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[kk + 2]; // Reserve one zero + } + else + return &buffer[length + 1]; + } + else if (-6 < kk && kk <= 0) { + // 1234e-6 -> 0.001234 + const int offset = 2 - kk; + std::memmove(&buffer[offset], &buffer[0], static_cast(length)); + buffer[0] = '0'; + buffer[1] = '.'; + for (int i = 2; i < offset; i++) + buffer[i] = '0'; + if (length - kk > maxDecimalPlaces) { + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1 + // Remove extra trailing zeros (at least one) after truncation. + for (int i = maxDecimalPlaces + 1; i > 2; i--) + if (buffer[i] != '0') + return &buffer[i + 1]; + return &buffer[3]; // Reserve one zero + } + else + return &buffer[length + offset]; + } + else if (kk < -maxDecimalPlaces) { + // Truncate to zero + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else if (length == 1) { + // 1e30 + buffer[1] = 'e'; + return WriteExponent(kk - 1, &buffer[2]); + } + else { + // 1234e30 -> 1.234e33 + std::memmove(&buffer[2], &buffer[1], static_cast(length - 1)); + buffer[1] = '.'; + buffer[length + 1] = 'e'; + return WriteExponent(kk - 1, &buffer[0 + length + 2]); + } +} + +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) { + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1); + Double d(value); + if (d.IsZero()) { + if (d.Sign()) + *buffer++ = '-'; // -0.0, Issue #289 + buffer[0] = '0'; + buffer[1] = '.'; + buffer[2] = '0'; + return &buffer[3]; + } + else { + if (value < 0) { + *buffer++ = '-'; + value = -value; + } + int length, K; + Grisu2(value, buffer, &length, &K); + return Prettify(buffer, length, K, maxDecimalPlaces); + } +} + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_DTOA_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/ieee754.h b/src/third-party/discord-rpc/include/rapidjson/internal/ieee754.h new file mode 100644 index 000000000..82bb0b99e --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/ieee754.h @@ -0,0 +1,78 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_IEEE754_ +#define RAPIDJSON_IEEE754_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +class Double { +public: + Double() {} + Double(double d) : d_(d) {} + Double(uint64_t u) : u_(u) {} + + double Value() const { return d_; } + uint64_t Uint64Value() const { return u_; } + + double NextPositiveDouble() const { + RAPIDJSON_ASSERT(!Sign()); + return Double(u_ + 1).Value(); + } + + bool Sign() const { return (u_ & kSignMask) != 0; } + uint64_t Significand() const { return u_ & kSignificandMask; } + int Exponent() const { return static_cast(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); } + + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; } + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; } + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; } + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; } + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; } + + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); } + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; } + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; } + + static unsigned EffectiveSignificandSize(int order) { + if (order >= -1021) + return 53; + else if (order <= -1074) + return 0; + else + return static_cast(order) + 1074; + } + +private: + static const int kSignificandSize = 52; + static const int kExponentBias = 0x3FF; + static const int kDenormalExponent = 1 - kExponentBias; + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000); + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF); + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000); + + union { + double d_; + uint64_t u_; + }; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_IEEE754_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/itoa.h b/src/third-party/discord-rpc/include/rapidjson/internal/itoa.h new file mode 100644 index 000000000..01a4e7e72 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/itoa.h @@ -0,0 +1,304 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ITOA_ +#define RAPIDJSON_ITOA_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline const char* GetDigitsLut() { + static const char cDigitsLut[200] = { + '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9', + '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9', + '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9', + '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9', + '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9', + '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9', + '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9', + '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9', + '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9', + '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9' + }; + return cDigitsLut; +} + +inline char* u32toa(uint32_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + + if (value < 10000) { + const uint32_t d1 = (value / 100) << 1; + const uint32_t d2 = (value % 100) << 1; + + if (value >= 1000) + *buffer++ = cDigitsLut[d1]; + if (value >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else if (value < 100000000) { + // value = bbbbcccc + const uint32_t b = value / 10000; + const uint32_t c = value % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + else { + // value = aabbbbcccc in decimal + + const uint32_t a = value / 100000000; // 1 to 42 + value %= 100000000; + + if (a >= 10) { + const unsigned i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else + *buffer++ = static_cast('0' + static_cast(a)); + + const uint32_t b = value / 10000; // 0 to 9999 + const uint32_t c = value % 10000; // 0 to 9999 + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + return buffer; +} + +inline char* i32toa(int32_t value, char* buffer) { + uint32_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u32toa(u, buffer); +} + +inline char* u64toa(uint64_t value, char* buffer) { + const char* cDigitsLut = GetDigitsLut(); + const uint64_t kTen8 = 100000000; + const uint64_t kTen9 = kTen8 * 10; + const uint64_t kTen10 = kTen8 * 100; + const uint64_t kTen11 = kTen8 * 1000; + const uint64_t kTen12 = kTen8 * 10000; + const uint64_t kTen13 = kTen8 * 100000; + const uint64_t kTen14 = kTen8 * 1000000; + const uint64_t kTen15 = kTen8 * 10000000; + const uint64_t kTen16 = kTen8 * kTen8; + + if (value < kTen8) { + uint32_t v = static_cast(value); + if (v < 10000) { + const uint32_t d1 = (v / 100) << 1; + const uint32_t d2 = (v % 100) << 1; + + if (v >= 1000) + *buffer++ = cDigitsLut[d1]; + if (v >= 100) + *buffer++ = cDigitsLut[d1 + 1]; + if (v >= 10) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + } + else { + // value = bbbbcccc + const uint32_t b = v / 10000; + const uint32_t c = v % 10000; + + const uint32_t d1 = (b / 100) << 1; + const uint32_t d2 = (b % 100) << 1; + + const uint32_t d3 = (c / 100) << 1; + const uint32_t d4 = (c % 100) << 1; + + if (value >= 10000000) + *buffer++ = cDigitsLut[d1]; + if (value >= 1000000) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= 100000) + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + } + } + else if (value < kTen16) { + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + if (value >= kTen15) + *buffer++ = cDigitsLut[d1]; + if (value >= kTen14) + *buffer++ = cDigitsLut[d1 + 1]; + if (value >= kTen13) + *buffer++ = cDigitsLut[d2]; + if (value >= kTen12) + *buffer++ = cDigitsLut[d2 + 1]; + if (value >= kTen11) + *buffer++ = cDigitsLut[d3]; + if (value >= kTen10) + *buffer++ = cDigitsLut[d3 + 1]; + if (value >= kTen9) + *buffer++ = cDigitsLut[d4]; + if (value >= kTen8) + *buffer++ = cDigitsLut[d4 + 1]; + + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + else { + const uint32_t a = static_cast(value / kTen16); // 1 to 1844 + value %= kTen16; + + if (a < 10) + *buffer++ = static_cast('0' + static_cast(a)); + else if (a < 100) { + const uint32_t i = a << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else if (a < 1000) { + *buffer++ = static_cast('0' + static_cast(a / 100)); + + const uint32_t i = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + } + else { + const uint32_t i = (a / 100) << 1; + const uint32_t j = (a % 100) << 1; + *buffer++ = cDigitsLut[i]; + *buffer++ = cDigitsLut[i + 1]; + *buffer++ = cDigitsLut[j]; + *buffer++ = cDigitsLut[j + 1]; + } + + const uint32_t v0 = static_cast(value / kTen8); + const uint32_t v1 = static_cast(value % kTen8); + + const uint32_t b0 = v0 / 10000; + const uint32_t c0 = v0 % 10000; + + const uint32_t d1 = (b0 / 100) << 1; + const uint32_t d2 = (b0 % 100) << 1; + + const uint32_t d3 = (c0 / 100) << 1; + const uint32_t d4 = (c0 % 100) << 1; + + const uint32_t b1 = v1 / 10000; + const uint32_t c1 = v1 % 10000; + + const uint32_t d5 = (b1 / 100) << 1; + const uint32_t d6 = (b1 % 100) << 1; + + const uint32_t d7 = (c1 / 100) << 1; + const uint32_t d8 = (c1 % 100) << 1; + + *buffer++ = cDigitsLut[d1]; + *buffer++ = cDigitsLut[d1 + 1]; + *buffer++ = cDigitsLut[d2]; + *buffer++ = cDigitsLut[d2 + 1]; + *buffer++ = cDigitsLut[d3]; + *buffer++ = cDigitsLut[d3 + 1]; + *buffer++ = cDigitsLut[d4]; + *buffer++ = cDigitsLut[d4 + 1]; + *buffer++ = cDigitsLut[d5]; + *buffer++ = cDigitsLut[d5 + 1]; + *buffer++ = cDigitsLut[d6]; + *buffer++ = cDigitsLut[d6 + 1]; + *buffer++ = cDigitsLut[d7]; + *buffer++ = cDigitsLut[d7 + 1]; + *buffer++ = cDigitsLut[d8]; + *buffer++ = cDigitsLut[d8 + 1]; + } + + return buffer; +} + +inline char* i64toa(int64_t value, char* buffer) { + uint64_t u = static_cast(value); + if (value < 0) { + *buffer++ = '-'; + u = ~u + 1; + } + + return u64toa(u, buffer); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ITOA_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/meta.h b/src/third-party/discord-rpc/include/rapidjson/internal/meta.h new file mode 100644 index 000000000..5a9aaa428 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/meta.h @@ -0,0 +1,181 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_META_H_ +#define RAPIDJSON_INTERNAL_META_H_ + +#include "../rapidjson.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif +#if defined(_MSC_VER) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(6334) +#endif + +#if RAPIDJSON_HAS_CXX11_TYPETRAITS +#include +#endif + +//@cond RAPIDJSON_INTERNAL +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching +template struct Void { typedef void Type; }; + +/////////////////////////////////////////////////////////////////////////////// +// BoolType, TrueType, FalseType +// +template struct BoolType { + static const bool Value = Cond; + typedef BoolType Type; +}; +typedef BoolType TrueType; +typedef BoolType FalseType; + + +/////////////////////////////////////////////////////////////////////////////// +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr +// + +template struct SelectIfImpl { template struct Apply { typedef T1 Type; }; }; +template <> struct SelectIfImpl { template struct Apply { typedef T2 Type; }; }; +template struct SelectIfCond : SelectIfImpl::template Apply {}; +template struct SelectIf : SelectIfCond {}; + +template struct AndExprCond : FalseType {}; +template <> struct AndExprCond : TrueType {}; +template struct OrExprCond : TrueType {}; +template <> struct OrExprCond : FalseType {}; + +template struct BoolExpr : SelectIf::Type {}; +template struct NotExpr : SelectIf::Type {}; +template struct AndExpr : AndExprCond::Type {}; +template struct OrExpr : OrExprCond::Type {}; + + +/////////////////////////////////////////////////////////////////////////////// +// AddConst, MaybeAddConst, RemoveConst +template struct AddConst { typedef const T Type; }; +template struct MaybeAddConst : SelectIfCond {}; +template struct RemoveConst { typedef T Type; }; +template struct RemoveConst { typedef T Type; }; + + +/////////////////////////////////////////////////////////////////////////////// +// IsSame, IsConst, IsMoreConst, IsPointer +// +template struct IsSame : FalseType {}; +template struct IsSame : TrueType {}; + +template struct IsConst : FalseType {}; +template struct IsConst : TrueType {}; + +template +struct IsMoreConst + : AndExpr::Type, typename RemoveConst::Type>, + BoolType::Value >= IsConst::Value> >::Type {}; + +template struct IsPointer : FalseType {}; +template struct IsPointer : TrueType {}; + +/////////////////////////////////////////////////////////////////////////////// +// IsBaseOf +// +#if RAPIDJSON_HAS_CXX11_TYPETRAITS + +template struct IsBaseOf + : BoolType< ::std::is_base_of::value> {}; + +#else // simplified version adopted from Boost + +template struct IsBaseOfImpl { + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0); + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0); + + typedef char (&Yes)[1]; + typedef char (&No) [2]; + + template + static Yes Check(const D*, T); + static No Check(const B*, int); + + struct Host { + operator const B*() const; + operator const D*(); + }; + + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) }; +}; + +template struct IsBaseOf + : OrExpr, BoolExpr > >::Type {}; + +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS + + +////////////////////////////////////////////////////////////////////////// +// EnableIf / DisableIf +// +template struct EnableIfCond { typedef T Type; }; +template struct EnableIfCond { /* empty */ }; + +template struct DisableIfCond { typedef T Type; }; +template struct DisableIfCond { /* empty */ }; + +template +struct EnableIf : EnableIfCond {}; + +template +struct DisableIf : DisableIfCond {}; + +// SFINAE helpers +struct SfinaeTag {}; +template struct RemoveSfinaeTag; +template struct RemoveSfinaeTag { typedef T Type; }; + +#define RAPIDJSON_REMOVEFPTR_(type) \ + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \ + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type + +#define RAPIDJSON_ENABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type * = NULL + +#define RAPIDJSON_DISABLEIF(cond) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type * = NULL + +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \ + ::Type + +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \ + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \ + ::Type + +} // namespace internal +RAPIDJSON_NAMESPACE_END +//@endcond + +#if defined(__GNUC__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/pow10.h b/src/third-party/discord-rpc/include/rapidjson/internal/pow10.h new file mode 100644 index 000000000..02f475d70 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/pow10.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +#include "../rapidjson.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n non-negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes + 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n >= 0 && n <= 308); + return e[n]; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_POW10_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/regex.h b/src/third-party/discord-rpc/include/rapidjson/internal/regex.h new file mode 100644 index 000000000..422a5240b --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/regex.h @@ -0,0 +1,701 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_REGEX_H_ +#define RAPIDJSON_INTERNAL_REGEX_H_ + +#include "../allocators.h" +#include "../stream.h" +#include "stack.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +RAPIDJSON_DIAG_OFF(implicit-fallthrough) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +#ifndef RAPIDJSON_REGEX_VERBOSE +#define RAPIDJSON_REGEX_VERBOSE 0 +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// GenericRegex + +static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1 +static const SizeType kRegexInvalidRange = ~SizeType(0); + +//! Regular expression engine with subset of ECMAscript grammar. +/*! + Supported regular expression syntax: + - \c ab Concatenation + - \c a|b Alternation + - \c a? Zero or one + - \c a* Zero or more + - \c a+ One or more + - \c a{3} Exactly 3 times + - \c a{3,} At least 3 times + - \c a{3,5} 3 to 5 times + - \c (ab) Grouping + - \c ^a At the beginning + - \c a$ At the end + - \c . Any character + - \c [abc] Character classes + - \c [a-c] Character class range + - \c [a-z0-9_] Character class combination + - \c [^abc] Negated character classes + - \c [^a-c] Negated character class range + - \c [\b] Backspace (U+0008) + - \c \\| \\\\ ... Escape characters + - \c \\f Form feed (U+000C) + - \c \\n Line feed (U+000A) + - \c \\r Carriage return (U+000D) + - \c \\t Tab (U+0009) + - \c \\v Vertical tab (U+000B) + + \note This is a Thompson NFA engine, implemented with reference to + Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).", + https://swtch.com/~rsc/regexp/regexp1.html +*/ +template +class GenericRegex { +public: + typedef typename Encoding::Ch Ch; + + GenericRegex(const Ch* source, Allocator* allocator = 0) : + states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(), + stateSet_(), state0_(allocator, 0), state1_(allocator, 0), anchorBegin_(), anchorEnd_() + { + GenericStringStream ss(source); + DecodedStream > ds(ss); + Parse(ds); + } + + ~GenericRegex() { + Allocator::Free(stateSet_); + } + + bool IsValid() const { + return root_ != kRegexInvalidState; + } + + template + bool Match(InputStream& is) const { + return SearchWithAnchoring(is, true, true); + } + + bool Match(const Ch* s) const { + GenericStringStream is(s); + return Match(is); + } + + template + bool Search(InputStream& is) const { + return SearchWithAnchoring(is, anchorBegin_, anchorEnd_); + } + + bool Search(const Ch* s) const { + GenericStringStream is(s); + return Search(is); + } + +private: + enum Operator { + kZeroOrOne, + kZeroOrMore, + kOneOrMore, + kConcatenation, + kAlternation, + kLeftParenthesis + }; + + static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.' + static const unsigned kRangeCharacterClass = 0xFFFFFFFE; + static const unsigned kRangeNegationFlag = 0x80000000; + + struct Range { + unsigned start; // + unsigned end; + SizeType next; + }; + + struct State { + SizeType out; //!< Equals to kInvalid for matching state + SizeType out1; //!< Equals to non-kInvalid for split + SizeType rangeStart; + unsigned codepoint; + }; + + struct Frag { + Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {} + SizeType start; + SizeType out; //!< link-list of all output states + SizeType minIndex; + }; + + template + class DecodedStream { + public: + DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); } + unsigned Peek() { return codepoint_; } + unsigned Take() { + unsigned c = codepoint_; + if (c) // No further decoding when '\0' + Decode(); + return c; + } + + private: + void Decode() { + if (!Encoding::Decode(ss_, &codepoint_)) + codepoint_ = 0; + } + + SourceStream& ss_; + unsigned codepoint_; + }; + + State& GetState(SizeType index) { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + const State& GetState(SizeType index) const { + RAPIDJSON_ASSERT(index < stateCount_); + return states_.template Bottom()[index]; + } + + Range& GetRange(SizeType index) { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + const Range& GetRange(SizeType index) const { + RAPIDJSON_ASSERT(index < rangeCount_); + return ranges_.template Bottom()[index]; + } + + template + void Parse(DecodedStream& ds) { + Allocator allocator; + Stack operandStack(&allocator, 256); // Frag + Stack operatorStack(&allocator, 256); // Operator + Stack atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis) + + *atomCountStack.template Push() = 0; + + unsigned codepoint; + while (ds.Peek() != 0) { + switch (codepoint = ds.Take()) { + case '^': + anchorBegin_ = true; + break; + + case '$': + anchorEnd_ = true; + break; + + case '|': + while (!operatorStack.Empty() && *operatorStack.template Top() < kAlternation) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + *operatorStack.template Push() = kAlternation; + *atomCountStack.template Top() = 0; + break; + + case '(': + *operatorStack.template Push() = kLeftParenthesis; + *atomCountStack.template Push() = 0; + break; + + case ')': + while (!operatorStack.Empty() && *operatorStack.template Top() != kLeftParenthesis) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + if (operatorStack.Empty()) + return; + operatorStack.template Pop(1); + atomCountStack.template Pop(1); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '?': + if (!Eval(operandStack, kZeroOrOne)) + return; + break; + + case '*': + if (!Eval(operandStack, kZeroOrMore)) + return; + break; + + case '+': + if (!Eval(operandStack, kOneOrMore)) + return; + break; + + case '{': + { + unsigned n, m; + if (!ParseUnsigned(ds, &n)) + return; + + if (ds.Peek() == ',') { + ds.Take(); + if (ds.Peek() == '}') + m = kInfinityQuantifier; + else if (!ParseUnsigned(ds, &m) || m < n) + return; + } + else + m = n; + + if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}') + return; + ds.Take(); + } + break; + + case '.': + PushOperand(operandStack, kAnyCharacterClass); + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '[': + { + SizeType range; + if (!ParseRange(ds, &range)) + return; + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass); + GetState(s).rangeStart = range; + *operandStack.template Push() = Frag(s, s, s); + } + ImplicitConcatenation(atomCountStack, operatorStack); + break; + + case '\\': // Escape character + if (!CharacterEscape(ds, &codepoint)) + return; // Unsupported escape character + // fall through to default + + default: // Pattern character + PushOperand(operandStack, codepoint); + ImplicitConcatenation(atomCountStack, operatorStack); + } + } + + while (!operatorStack.Empty()) + if (!Eval(operandStack, *operatorStack.template Pop(1))) + return; + + // Link the operand to matching state. + if (operandStack.GetSize() == sizeof(Frag)) { + Frag* e = operandStack.template Pop(1); + Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0)); + root_ = e->start; + +#if RAPIDJSON_REGEX_VERBOSE + printf("root: %d\n", root_); + for (SizeType i = 0; i < stateCount_ ; i++) { + State& s = GetState(i); + printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint); + } + printf("\n"); +#endif + } + + // Preallocate buffer for SearchWithAnchoring() + RAPIDJSON_ASSERT(stateSet_ == 0); + if (stateCount_ > 0) { + stateSet_ = static_cast(states_.GetAllocator().Malloc(GetStateSetSize())); + state0_.template Reserve(stateCount_); + state1_.template Reserve(stateCount_); + } + } + + SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) { + State* s = states_.template Push(); + s->out = out; + s->out1 = out1; + s->codepoint = codepoint; + s->rangeStart = kRegexInvalidRange; + return stateCount_++; + } + + void PushOperand(Stack& operandStack, unsigned codepoint) { + SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint); + *operandStack.template Push() = Frag(s, s, s); + } + + void ImplicitConcatenation(Stack& atomCountStack, Stack& operatorStack) { + if (*atomCountStack.template Top()) + *operatorStack.template Push() = kConcatenation; + (*atomCountStack.template Top())++; + } + + SizeType Append(SizeType l1, SizeType l2) { + SizeType old = l1; + while (GetState(l1).out != kRegexInvalidState) + l1 = GetState(l1).out; + GetState(l1).out = l2; + return old; + } + + void Patch(SizeType l, SizeType s) { + for (SizeType next; l != kRegexInvalidState; l = next) { + next = GetState(l).out; + GetState(l).out = s; + } + } + + bool Eval(Stack& operandStack, Operator op) { + switch (op) { + case kConcatenation: + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2); + { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + Patch(e1.out, e2.start); + *operandStack.template Push() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex)); + } + return true; + + case kAlternation: + if (operandStack.GetSize() >= sizeof(Frag) * 2) { + Frag e2 = *operandStack.template Pop(1); + Frag e1 = *operandStack.template Pop(1); + SizeType s = NewState(e1.start, e2.start, 0); + *operandStack.template Push() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex)); + return true; + } + return false; + + case kZeroOrOne: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + *operandStack.template Push() = Frag(s, Append(e.out, s), e.minIndex); + return true; + } + return false; + + case kZeroOrMore: + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(s, s, e.minIndex); + return true; + } + return false; + + default: + RAPIDJSON_ASSERT(op == kOneOrMore); + if (operandStack.GetSize() >= sizeof(Frag)) { + Frag e = *operandStack.template Pop(1); + SizeType s = NewState(kRegexInvalidState, e.start, 0); + Patch(e.out, s); + *operandStack.template Push() = Frag(e.start, s, e.minIndex); + return true; + } + return false; + } + } + + bool EvalQuantifier(Stack& operandStack, unsigned n, unsigned m) { + RAPIDJSON_ASSERT(n <= m); + RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag)); + + if (n == 0) { + if (m == 0) // a{0} not support + return false; + else if (m == kInfinityQuantifier) + Eval(operandStack, kZeroOrMore); // a{0,} -> a* + else { + Eval(operandStack, kZeroOrOne); // a{0,5} -> a? + for (unsigned i = 0; i < m - 1; i++) + CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a? + for (unsigned i = 0; i < m - 1; i++) + Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a? + } + return true; + } + + for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a + CloneTopOperand(operandStack); + + if (m == kInfinityQuantifier) + Eval(operandStack, kOneOrMore); // a{3,} -> a a a+ + else if (m > n) { + CloneTopOperand(operandStack); // a{3,5} -> a a a a + Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a? + for (unsigned i = n; i < m - 1; i++) + CloneTopOperand(operandStack); // a{3,5} -> a a a a? a? + for (unsigned i = n; i < m; i++) + Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a? + } + + for (unsigned i = 0; i < n - 1; i++) + Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a? + + return true; + } + + static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; } + + void CloneTopOperand(Stack& operandStack) { + const Frag src = *operandStack.template Top(); // Copy constructor to prevent invalidation + SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_) + State* s = states_.template Push(count); + memcpy(s, &GetState(src.minIndex), count * sizeof(State)); + for (SizeType j = 0; j < count; j++) { + if (s[j].out != kRegexInvalidState) + s[j].out += count; + if (s[j].out1 != kRegexInvalidState) + s[j].out1 += count; + } + *operandStack.template Push() = Frag(src.start + count, src.out + count, src.minIndex + count); + stateCount_ += count; + } + + template + bool ParseUnsigned(DecodedStream& ds, unsigned* u) { + unsigned r = 0; + if (ds.Peek() < '0' || ds.Peek() > '9') + return false; + while (ds.Peek() >= '0' && ds.Peek() <= '9') { + if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295 + return false; // overflow + r = r * 10 + (ds.Take() - '0'); + } + *u = r; + return true; + } + + template + bool ParseRange(DecodedStream& ds, SizeType* range) { + bool isBegin = true; + bool negate = false; + int step = 0; + SizeType start = kRegexInvalidRange; + SizeType current = kRegexInvalidRange; + unsigned codepoint; + while ((codepoint = ds.Take()) != 0) { + if (isBegin) { + isBegin = false; + if (codepoint == '^') { + negate = true; + continue; + } + } + + switch (codepoint) { + case ']': + if (start == kRegexInvalidRange) + return false; // Error: nothing inside [] + if (step == 2) { // Add trailing '-' + SizeType r = NewRange('-'); + RAPIDJSON_ASSERT(current != kRegexInvalidRange); + GetRange(current).next = r; + } + if (negate) + GetRange(start).start |= kRangeNegationFlag; + *range = start; + return true; + + case '\\': + if (ds.Peek() == 'b') { + ds.Take(); + codepoint = 0x0008; // Escape backspace character + } + else if (!CharacterEscape(ds, &codepoint)) + return false; + // fall through to default + + default: + switch (step) { + case 1: + if (codepoint == '-') { + step++; + break; + } + // fall through to step 0 for other characters + + case 0: + { + SizeType r = NewRange(codepoint); + if (current != kRegexInvalidRange) + GetRange(current).next = r; + if (start == kRegexInvalidRange) + start = r; + current = r; + } + step = 1; + break; + + default: + RAPIDJSON_ASSERT(step == 2); + GetRange(current).end = codepoint; + step = 0; + } + } + } + return false; + } + + SizeType NewRange(unsigned codepoint) { + Range* r = ranges_.template Push(); + r->start = r->end = codepoint; + r->next = kRegexInvalidRange; + return rangeCount_++; + } + + template + bool CharacterEscape(DecodedStream& ds, unsigned* escapedCodepoint) { + unsigned codepoint; + switch (codepoint = ds.Take()) { + case '^': + case '$': + case '|': + case '(': + case ')': + case '?': + case '*': + case '+': + case '.': + case '[': + case ']': + case '{': + case '}': + case '\\': + *escapedCodepoint = codepoint; return true; + case 'f': *escapedCodepoint = 0x000C; return true; + case 'n': *escapedCodepoint = 0x000A; return true; + case 'r': *escapedCodepoint = 0x000D; return true; + case 't': *escapedCodepoint = 0x0009; return true; + case 'v': *escapedCodepoint = 0x000B; return true; + default: + return false; // Unsupported escape character + } + } + + template + bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) const { + RAPIDJSON_ASSERT(IsValid()); + DecodedStream ds(is); + + state0_.Clear(); + Stack *current = &state0_, *next = &state1_; + const size_t stateSetSize = GetStateSetSize(); + std::memset(stateSet_, 0, stateSetSize); + + bool matched = AddState(*current, root_); + unsigned codepoint; + while (!current->Empty() && (codepoint = ds.Take()) != 0) { + std::memset(stateSet_, 0, stateSetSize); + next->Clear(); + matched = false; + for (const SizeType* s = current->template Bottom(); s != current->template End(); ++s) { + const State& sr = GetState(*s); + if (sr.codepoint == codepoint || + sr.codepoint == kAnyCharacterClass || + (sr.codepoint == kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint))) + { + matched = AddState(*next, sr.out) || matched; + if (!anchorEnd && matched) + return true; + } + if (!anchorBegin) + AddState(*next, root_); + } + internal::Swap(current, next); + } + + return matched; + } + + size_t GetStateSetSize() const { + return (stateCount_ + 31) / 32 * 4; + } + + // Return whether the added states is a match state + bool AddState(Stack& l, SizeType index) const { + RAPIDJSON_ASSERT(index != kRegexInvalidState); + + const State& s = GetState(index); + if (s.out1 != kRegexInvalidState) { // Split + bool matched = AddState(l, s.out); + return AddState(l, s.out1) || matched; + } + else if (!(stateSet_[index >> 5] & (1 << (index & 31)))) { + stateSet_[index >> 5] |= (1 << (index & 31)); + *l.template PushUnsafe() = index; + } + return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation. + } + + bool MatchRange(SizeType rangeIndex, unsigned codepoint) const { + bool yes = (GetRange(rangeIndex).start & kRangeNegationFlag) == 0; + while (rangeIndex != kRegexInvalidRange) { + const Range& r = GetRange(rangeIndex); + if (codepoint >= (r.start & ~kRangeNegationFlag) && codepoint <= r.end) + return yes; + rangeIndex = r.next; + } + return !yes; + } + + Stack states_; + Stack ranges_; + SizeType root_; + SizeType stateCount_; + SizeType rangeCount_; + + static const unsigned kInfinityQuantifier = ~0u; + + // For SearchWithAnchoring() + uint32_t* stateSet_; // allocated by states_.GetAllocator() + mutable Stack state0_; + mutable Stack state1_; + bool anchorBegin_; + bool anchorEnd_; +}; + +typedef GenericRegex > Regex; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_REGEX_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/stack.h b/src/third-party/discord-rpc/include/rapidjson/internal/stack.h new file mode 100644 index 000000000..022c9aab4 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/stack.h @@ -0,0 +1,230 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STACK_H_ +#define RAPIDJSON_INTERNAL_STACK_H_ + +#include "../allocators.h" +#include "swap.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +/////////////////////////////////////////////////////////////////////////////// +// Stack + +//! A type-unsafe stack for storing different types of data. +/*! \tparam Allocator Allocator for allocating stack memory. +*/ +template +class Stack { +public: + // Optimization note: Do not allocate memory for stack_ in constructor. + // Do it lazily when first Push() -> Expand() -> Resize(). + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) { + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack(Stack&& rhs) + : allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + stack_(rhs.stack_), + stackTop_(rhs.stackTop_), + stackEnd_(rhs.stackEnd_), + initialCapacity_(rhs.initialCapacity_) + { + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } +#endif + + ~Stack() { + Destroy(); + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + Stack& operator=(Stack&& rhs) { + if (&rhs != this) + { + Destroy(); + + allocator_ = rhs.allocator_; + ownAllocator_ = rhs.ownAllocator_; + stack_ = rhs.stack_; + stackTop_ = rhs.stackTop_; + stackEnd_ = rhs.stackEnd_; + initialCapacity_ = rhs.initialCapacity_; + + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + rhs.stack_ = 0; + rhs.stackTop_ = 0; + rhs.stackEnd_ = 0; + rhs.initialCapacity_ = 0; + } + return *this; + } +#endif + + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT { + internal::Swap(allocator_, rhs.allocator_); + internal::Swap(ownAllocator_, rhs.ownAllocator_); + internal::Swap(stack_, rhs.stack_); + internal::Swap(stackTop_, rhs.stackTop_); + internal::Swap(stackEnd_, rhs.stackEnd_); + internal::Swap(initialCapacity_, rhs.initialCapacity_); + } + + void Clear() { stackTop_ = stack_; } + + void ShrinkToFit() { + if (Empty()) { + // If the stack is empty, completely deallocate the memory. + Allocator::Free(stack_); + stack_ = 0; + stackTop_ = 0; + stackEnd_ = 0; + } + else + Resize(GetSize()); + } + + // Optimization note: try to minimize the size of this function for force inline. + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function. + template + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) { + // Expand the stack if needed + if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_)) + Expand(count); + } + + template + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) { + Reserve(count); + return PushUnsafe(count); + } + + template + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) { + RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_); + T* ret = reinterpret_cast(stackTop_); + stackTop_ += sizeof(T) * count; + return ret; + } + + template + T* Pop(size_t count) { + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T)); + stackTop_ -= count * sizeof(T); + return reinterpret_cast(stackTop_); + } + + template + T* Top() { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + const T* Top() const { + RAPIDJSON_ASSERT(GetSize() >= sizeof(T)); + return reinterpret_cast(stackTop_ - sizeof(T)); + } + + template + T* End() { return reinterpret_cast(stackTop_); } + + template + const T* End() const { return reinterpret_cast(stackTop_); } + + template + T* Bottom() { return reinterpret_cast(stack_); } + + template + const T* Bottom() const { return reinterpret_cast(stack_); } + + bool HasAllocator() const { + return allocator_ != 0; + } + + Allocator& GetAllocator() { + RAPIDJSON_ASSERT(allocator_); + return *allocator_; + } + + bool Empty() const { return stackTop_ == stack_; } + size_t GetSize() const { return static_cast(stackTop_ - stack_); } + size_t GetCapacity() const { return static_cast(stackEnd_ - stack_); } + +private: + template + void Expand(size_t count) { + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity. + size_t newCapacity; + if (stack_ == 0) { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + newCapacity = initialCapacity_; + } else { + newCapacity = GetCapacity(); + newCapacity += (newCapacity + 1) / 2; + } + size_t newSize = GetSize() + sizeof(T) * count; + if (newCapacity < newSize) + newCapacity = newSize; + + Resize(newCapacity); + } + + void Resize(size_t newCapacity) { + const size_t size = GetSize(); // Backup the current size + stack_ = static_cast(allocator_->Realloc(stack_, GetCapacity(), newCapacity)); + stackTop_ = stack_ + size; + stackEnd_ = stack_ + newCapacity; + } + + void Destroy() { + Allocator::Free(stack_); + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack + } + + // Prohibit copy constructor & assignment operator. + Stack(const Stack&); + Stack& operator=(const Stack&); + + Allocator* allocator_; + Allocator* ownAllocator_; + char *stack_; + char *stackTop_; + char *stackEnd_; + size_t initialCapacity_; +}; + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STACK_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/strfunc.h b/src/third-party/discord-rpc/include/rapidjson/internal/strfunc.h new file mode 100644 index 000000000..2edfae526 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/strfunc.h @@ -0,0 +1,55 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_ +#define RAPIDJSON_INTERNAL_STRFUNC_H_ + +#include "../stream.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom strlen() which works on different character types. +/*! \tparam Ch Character type (e.g. char, wchar_t, short) + \param s Null-terminated input string. + \return Number of characters in the string. + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints. +*/ +template +inline SizeType StrLen(const Ch* s) { + const Ch* p = s; + while (*p) ++p; + return SizeType(p - s); +} + +//! Returns number of code points in a encoded string. +template +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) { + GenericStringStream is(s); + const typename Encoding::Ch* end = s + length; + SizeType count = 0; + while (is.src_ < end) { + unsigned codepoint; + if (!Encoding::Decode(is, &codepoint)) + return false; + count++; + } + *outCount = count; + return true; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/strtod.h b/src/third-party/discord-rpc/include/rapidjson/internal/strtod.h new file mode 100644 index 000000000..289c413b0 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/strtod.h @@ -0,0 +1,269 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRTOD_ +#define RAPIDJSON_STRTOD_ + +#include "ieee754.h" +#include "biginteger.h" +#include "diyfp.h" +#include "pow10.h" + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +inline double FastPath(double significand, int exp) { + if (exp < -308) + return 0.0; + else if (exp >= 0) + return significand * internal::Pow10(exp); + else + return significand / internal::Pow10(-exp); +} + +inline double StrtodNormalPrecision(double d, int p) { + if (p < -308) { + // Prevent expSum < -308, making Pow10(p) = 0 + d = FastPath(d, -308); + d = FastPath(d, p + 308); + } + else + d = FastPath(d, p); + return d; +} + +template +inline T Min3(T a, T b, T c) { + T m = a; + if (m > b) m = b; + if (m > c) m = c; + return m; +} + +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) { + const Double db(b); + const uint64_t bInt = db.IntegerSignificand(); + const int bExp = db.IntegerExponent(); + const int hExp = bExp - 1; + + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0; + + // Adjust for decimal exponent + if (dExp >= 0) { + dS_Exp2 += dExp; + dS_Exp5 += dExp; + } + else { + bS_Exp2 -= dExp; + bS_Exp5 -= dExp; + hS_Exp2 -= dExp; + hS_Exp5 -= dExp; + } + + // Adjust for binary exponent + if (bExp >= 0) + bS_Exp2 += bExp; + else { + dS_Exp2 -= bExp; + hS_Exp2 -= bExp; + } + + // Adjust for half ulp exponent + if (hExp >= 0) + hS_Exp2 += hExp; + else { + dS_Exp2 -= hExp; + bS_Exp2 -= hExp; + } + + // Remove common power of two factor from all three scaled values + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2); + dS_Exp2 -= common_Exp2; + bS_Exp2 -= common_Exp2; + hS_Exp2 -= common_Exp2; + + BigInteger dS = d; + dS.MultiplyPow5(static_cast(dS_Exp5)) <<= static_cast(dS_Exp2); + + BigInteger bS(bInt); + bS.MultiplyPow5(static_cast(bS_Exp5)) <<= static_cast(bS_Exp2); + + BigInteger hS(1); + hS.MultiplyPow5(static_cast(hS_Exp5)) <<= static_cast(hS_Exp2); + + BigInteger delta(0); + dS.Difference(bS, &delta); + + return delta.Compare(hS); +} + +inline bool StrtodFast(double d, int p, double* result) { + // Use fast path for string-to-double conversion if possible + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ + if (p > 22 && p < 22 + 16) { + // Fast Path Cases In Disguise + d *= internal::Pow10(p - 22); + p = 22; + } + + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1 + *result = FastPath(d, p); + return true; + } + else + return false; +} + +// Compute an approximation and see if it is within 1/2 ULP +inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) { + uint64_t significand = 0; + size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999 + for (; i < length; i++) { + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5')) + break; + significand = significand * 10u + static_cast(decimals[i] - '0'); + } + + if (i < length && decimals[i] >= '5') // Rounding + significand++; + + size_t remaining = length - i; + const unsigned kUlpShift = 3; + const unsigned kUlp = 1 << kUlpShift; + int64_t error = (remaining == 0) ? 0 : kUlp / 2; + + DiyFp v(significand, 0); + v = v.Normalize(); + error <<= -v.e; + + const int dExp = static_cast(decimalPosition) - static_cast(i) + exp; + + int actualExp; + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp); + if (actualExp != dExp) { + static const DiyFp kPow10[] = { + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7 + }; + int adjustment = dExp - actualExp - 1; + RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7); + v = v * kPow10[adjustment]; + if (length + static_cast(adjustment)> 19u) // has more digits than decimal digits in 64-bit + error += kUlp / 2; + } + + v = v * cachedPower; + + error += kUlp + (error == 0 ? 0 : 1); + + const int oldExp = v.e; + v = v.Normalize(); + error <<= oldExp - v.e; + + const unsigned effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e); + unsigned precisionSize = 64 - effectiveSignificandSize; + if (precisionSize + kUlpShift >= 64) { + unsigned scaleExp = (precisionSize + kUlpShift) - 63; + v.f >>= scaleExp; + v.e += scaleExp; + error = (error >> scaleExp) + 1 + static_cast(kUlp); + precisionSize -= scaleExp; + } + + DiyFp rounded(v.f >> precisionSize, v.e + static_cast(precisionSize)); + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp; + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp; + if (precisionBits >= halfWay + static_cast(error)) { + rounded.f++; + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340) + rounded.f >>= 1; + rounded.e++; + } + } + + *result = rounded.ToDouble(); + + return halfWay - static_cast(error) >= precisionBits || precisionBits >= halfWay + static_cast(error); +} + +inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) { + const BigInteger dInt(decimals, length); + const int dExp = static_cast(decimalPosition) - static_cast(length) + exp; + Double a(approx); + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp); + if (cmp < 0) + return a.Value(); // within half ULP + else if (cmp == 0) { + // Round towards even + if (a.Significand() & 1) + return a.NextPositiveDouble(); + else + return a.Value(); + } + else // adjustment + return a.NextPositiveDouble(); +} + +inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) { + RAPIDJSON_ASSERT(d >= 0.0); + RAPIDJSON_ASSERT(length >= 1); + + double result; + if (StrtodFast(d, p, &result)) + return result; + + // Trim leading zeros + while (*decimals == '0' && length > 1) { + length--; + decimals++; + decimalPosition--; + } + + // Trim trailing zeros + while (decimals[length - 1] == '0' && length > 1) { + length--; + decimalPosition--; + exp++; + } + + // Trim right-most digits + const int kMaxDecimalDigit = 780; + if (static_cast(length) > kMaxDecimalDigit) { + int delta = (static_cast(length) - kMaxDecimalDigit); + exp += delta; + decimalPosition -= static_cast(delta); + length = kMaxDecimalDigit; + } + + // If too small, underflow to zero + if (int(length) + exp < -324) + return 0.0; + + if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result)) + return result; + + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison + return StrtodBigInteger(result, decimals, length, decimalPosition, exp); +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STRTOD_ diff --git a/src/third-party/discord-rpc/include/rapidjson/internal/swap.h b/src/third-party/discord-rpc/include/rapidjson/internal/swap.h new file mode 100644 index 000000000..666e49f97 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/internal/swap.h @@ -0,0 +1,46 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_INTERNAL_SWAP_H_ +#define RAPIDJSON_INTERNAL_SWAP_H_ + +#include "../rapidjson.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN +namespace internal { + +//! Custom swap() to avoid dependency on C++ header +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only. + \note This has the same semantics as std::swap(). +*/ +template +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT { + T tmp = a; + a = b; + b = tmp; +} + +} // namespace internal +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_INTERNAL_SWAP_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/istreamwrapper.h b/src/third-party/discord-rpc/include/rapidjson/istreamwrapper.h new file mode 100644 index 000000000..f5fe28977 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/istreamwrapper.h @@ -0,0 +1,115 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_ +#define RAPIDJSON_ISTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::istringstream + - \c std::stringstream + - \c std::wistringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wifstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_istream. +*/ + +template +class BasicIStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {} + + Ch Peek() const { + typename StreamType::int_type c = stream_.peek(); + return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast(c) : '\0'; + } + + Ch Take() { + typename StreamType::int_type c = stream_.get(); + if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) { + count_++; + return static_cast(c); + } + else + return '\0'; + } + + // tellg() may return -1 when failed. So we count by ourself. + size_t Tell() const { return count_; } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream. + int i; + bool hasError = false; + for (i = 0; i < 4; ++i) { + typename StreamType::int_type c = stream_.get(); + if (c == StreamType::traits_type::eof()) { + hasError = true; + stream_.clear(); + break; + } + peekBuffer_[i] = static_cast(c); + } + for (--i; i >= 0; --i) + stream_.putback(peekBuffer_[i]); + return !hasError ? peekBuffer_ : 0; + } + +private: + BasicIStreamWrapper(const BasicIStreamWrapper&); + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&); + + StreamType& stream_; + size_t count_; //!< Number of characters read. Note: + mutable Ch peekBuffer_[4]; +}; + +typedef BasicIStreamWrapper IStreamWrapper; +typedef BasicIStreamWrapper WIStreamWrapper; + +#if defined(__clang__) || defined(_MSC_VER) +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_ISTREAMWRAPPER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/license.txt b/src/third-party/discord-rpc/include/rapidjson/license.txt new file mode 100644 index 000000000..7ccc161c8 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/license.txt @@ -0,0 +1,57 @@ +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. +If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. +A copy of the MIT License is included in this file. + +Other dependencies and licenses: + +Open Source Software Licensed Under the BSD License: +-------------------------------------------------------------------- + +The msinttypes r29 +Copyright (c) 2006-2013 Alexander Chemeris +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Open Source Software Licensed Under the JSON License: +-------------------------------------------------------------------- + +json.org +Copyright (c) 2002 JSON.org +All Rights Reserved. + +JSON_checker +Copyright (c) 2002 JSON.org +All Rights Reserved. + + +Terms of the JSON License: +--------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Terms of the MIT License: +-------------------------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/third-party/discord-rpc/include/rapidjson/memorybuffer.h b/src/third-party/discord-rpc/include/rapidjson/memorybuffer.h new file mode 100644 index 000000000..39bee1dec --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/memorybuffer.h @@ -0,0 +1,70 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYBUFFER_H_ +#define RAPIDJSON_MEMORYBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output byte stream. +/*! + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream. + + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file. + + Differences between MemoryBuffer and StringBuffer: + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer. + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator. + + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +struct GenericMemoryBuffer { + typedef char Ch; // byte + + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + + void Put(Ch c) { *stack_.template Push() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { stack_.ShrinkToFit(); } + Ch* Push(size_t count) { return stack_.template Push(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetBuffer() const { + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; +}; + +typedef GenericMemoryBuffer<> MemoryBuffer; + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) { + std::memset(memoryBuffer.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/memorystream.h b/src/third-party/discord-rpc/include/rapidjson/memorystream.h new file mode 100644 index 000000000..1d71d8a4f --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/memorystream.h @@ -0,0 +1,71 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_MEMORYSTREAM_H_ +#define RAPIDJSON_MEMORYSTREAM_H_ + +#include "stream.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(unreachable-code) +RAPIDJSON_DIAG_OFF(missing-noreturn) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory input byte stream. +/*! + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream. + + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file. + + Differences between MemoryStream and StringStream: + 1. StringStream has encoding but MemoryStream is a byte stream. + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source. + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4(). + \note implements Stream concept +*/ +struct MemoryStream { + typedef char Ch; // byte + + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {} + + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; } + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; } + size_t Tell() const { return static_cast(src_ - begin_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + // For encoding detection only. + const Ch* Peek4() const { + return Tell() + 4 <= size_ ? src_ : 0; + } + + const Ch* src_; //!< Current read position. + const Ch* begin_; //!< Original head of the string. + const Ch* end_; //!< End of stream. + size_t size_; //!< Size of the stream. +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_MEMORYBUFFER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/msinttypes/inttypes.h b/src/third-party/discord-rpc/include/rapidjson/msinttypes/inttypes.h new file mode 100644 index 000000000..18111286b --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/msinttypes/inttypes.h @@ -0,0 +1,316 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// miloyip: VC supports inttypes.h since VC2013 +#if _MSC_VER >= 1800 +#include +#else + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + +#endif // _MSC_VER >= 1800 + +#endif // _MSC_INTTYPES_H_ ] diff --git a/src/third-party/discord-rpc/include/rapidjson/msinttypes/stdint.h b/src/third-party/discord-rpc/include/rapidjson/msinttypes/stdint.h new file mode 100644 index 000000000..3d4477b9a --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/msinttypes/stdint.h @@ -0,0 +1,300 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +// The above software in this distribution may have been modified by +// THL A29 Limited ("Tencent Modifications"). +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited. + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010. +#if _MSC_VER >= 1600 // [ +#include + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#else // ] _MSC_VER >= 1700 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we have to wrap include with 'extern "C++" {}' +// or compiler would give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#if defined(__cplusplus) && !defined(_M_ARM) +extern "C" { +#endif +# include +#if defined(__cplusplus) && !defined(_M_ARM) +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/src/third-party/discord-rpc/include/rapidjson/ostreamwrapper.h b/src/third-party/discord-rpc/include/rapidjson/ostreamwrapper.h new file mode 100644 index 000000000..6f4667c08 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/ostreamwrapper.h @@ -0,0 +1,81 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_ +#define RAPIDJSON_OSTREAMWRAPPER_H_ + +#include "stream.h" +#include + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept. +/*! + The classes can be wrapped including but not limited to: + + - \c std::ostringstream + - \c std::stringstream + - \c std::wpstringstream + - \c std::wstringstream + - \c std::ifstream + - \c std::fstream + - \c std::wofstream + - \c std::wfstream + + \tparam StreamType Class derived from \c std::basic_ostream. +*/ + +template +class BasicOStreamWrapper { +public: + typedef typename StreamType::char_type Ch; + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {} + + void Put(Ch c) { + stream_.put(c); + } + + void Flush() { + stream_.flush(); + } + + // Not implemented + char Peek() const { RAPIDJSON_ASSERT(false); return 0; } + char Take() { RAPIDJSON_ASSERT(false); return 0; } + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; } + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; } + +private: + BasicOStreamWrapper(const BasicOStreamWrapper&); + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&); + + StreamType& stream_; +}; + +typedef BasicOStreamWrapper OStreamWrapper; +typedef BasicOStreamWrapper WOStreamWrapper; + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_OSTREAMWRAPPER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/pointer.h b/src/third-party/discord-rpc/include/rapidjson/pointer.h new file mode 100644 index 000000000..0206ac1c8 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/pointer.h @@ -0,0 +1,1358 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_POINTER_H_ +#define RAPIDJSON_POINTER_H_ + +#include "document.h" +#include "internal/itoa.h" + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token + +//! Error code of parsing. +/*! \ingroup RAPIDJSON_ERRORS + \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode +*/ +enum PointerParseErrorCode { + kPointerParseErrorNone = 0, //!< The parse is successful + + kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/' + kPointerParseErrorInvalidEscape, //!< Invalid escape + kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment + kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericPointer + +//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator. +/*! + This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer" + (https://tools.ietf.org/html/rfc6901). + + A JSON pointer is for identifying a specific value in a JSON document + (GenericDocument). It can simplify coding of DOM tree manipulation, because it + can access multiple-level depth of DOM tree with single API call. + + After it parses a string representation (e.g. "/foo/0" or URI fragment + representation (e.g. "#/foo/0") into its internal representation (tokens), + it can be used to resolve a specific value in multiple documents, or sub-tree + of documents. + + Contrary to GenericValue, Pointer can be copy constructed and copy assigned. + Apart from assignment, a Pointer cannot be modified after construction. + + Although Pointer is very convenient, please aware that constructing Pointer + involves parsing and dynamic memory allocation. A special constructor with user- + supplied tokens eliminates these. + + GenericPointer depends on GenericDocument and GenericValue. + + \tparam ValueType The value type of the DOM tree. E.g. GenericValue > + \tparam Allocator The allocator type for allocating memory for internal representation. + + \note GenericPointer uses same encoding of ValueType. + However, Allocator of GenericPointer is independent of Allocator of Value. +*/ +template +class GenericPointer { +public: + typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value + typedef typename ValueType::Ch Ch; //!< Character type from Value + + //! A token is the basic units of internal representation. + /*! + A JSON pointer string representation "/foo/123" is parsed to two tokens: + "foo" and 123. 123 will be represented in both numeric form and string form. + They are resolved according to the actual value type (object or array). + + For token that are not numbers, or the numeric value is out of bound + (greater than limits of SizeType), they are only treated as string form + (i.e. the token's index will be equal to kPointerInvalidIndex). + + This struct is public so that user can create a Pointer without parsing and + allocation, using a special constructor. + */ + struct Token { + const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character. + SizeType length; //!< Length of the name. + SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex. + }; + + //!@name Constructors and destructor. + //@{ + + //! Default constructor. + GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A null-terminated, string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + */ + explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, internal::StrLen(source)); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Constructor that parses a string or URI fragment representation. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. + */ + explicit GenericPointer(const std::basic_string& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source.c_str(), source.size()); + } +#endif + + //! Constructor that parses a string or URI fragment representation, with length of the source string. + /*! + \param source A string or URI fragment representation of JSON pointer. + \param length Length of source. + \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one. + \note Slightly faster than the overload without length. + */ + GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + Parse(source, length); + } + + //! Constructor with user-supplied tokens. + /*! + This constructor let user supplies const array of tokens. + This prevents the parsing process and eliminates allocation. + This is preferred for memory constrained environments. + + \param tokens An constant array of tokens representing the JSON pointer. + \param tokenCount Number of tokens. + + \b Example + \code + #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex } + #define INDEX(i) { #i, sizeof(#i) - 1, i } + + static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) }; + static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0])); + // Equivalent to static const Pointer p("/foo/123"); + + #undef NAME + #undef INDEX + \endcode + */ + GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {} + + //! Copy constructor. + GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) { + *this = rhs; + } + + //! Destructor. + ~GenericPointer() { + if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated. + Allocator::Free(tokens_); + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Assignment operator. + GenericPointer& operator=(const GenericPointer& rhs) { + if (this != &rhs) { + // Do not delete ownAllcator + if (nameBuffer_) + Allocator::Free(tokens_); + + tokenCount_ = rhs.tokenCount_; + parseErrorOffset_ = rhs.parseErrorOffset_; + parseErrorCode_ = rhs.parseErrorCode_; + + if (rhs.nameBuffer_) + CopyFromRaw(rhs); // Normally parsed tokens. + else { + tokens_ = rhs.tokens_; // User supplied const tokens. + nameBuffer_ = 0; + } + } + return *this; + } + + //@} + + //!@name Append token + //@{ + + //! Append a token and return a new Pointer + /*! + \param token Token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Token& token, Allocator* allocator = 0) const { + GenericPointer r; + r.allocator_ = allocator; + Ch *p = r.CopyFromRaw(*this, 1, token.length + 1); + std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch)); + r.tokens_[tokenCount_].name = p; + r.tokens_[tokenCount_].length = token.length; + r.tokens_[tokenCount_].index = token.index; + return r; + } + + //! Append a name token with length, and return a new Pointer + /*! + \param name Name to be appended. + \param length Length of name. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const { + Token token = { name, length, kPointerInvalidIndex }; + return Append(token, allocator); + } + + //! Append a name token without length, and return a new Pointer + /*! + \param name Name (const Ch*) to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr::Type, Ch> >), (GenericPointer)) + Append(T* name, Allocator* allocator = 0) const { + return Append(name, StrLen(name), allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Append a name token, and return a new Pointer + /*! + \param name Name to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const std::basic_string& name, Allocator* allocator = 0) const { + return Append(name.c_str(), static_cast(name.size()), allocator); + } +#endif + + //! Append a index token, and return a new Pointer + /*! + \param index Index to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(SizeType index, Allocator* allocator = 0) const { + char buffer[21]; + char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer); + SizeType length = static_cast(end - buffer); + buffer[length] = '\0'; + + if (sizeof(Ch) == 1) { + Token token = { reinterpret_cast(buffer), length, index }; + return Append(token, allocator); + } + else { + Ch name[21]; + for (size_t i = 0; i <= length; i++) + name[i] = buffer[i]; + Token token = { name, length, index }; + return Append(token, allocator); + } + } + + //! Append a token by value, and return a new Pointer + /*! + \param token token to be appended. + \param allocator Allocator for the newly return Pointer. + \return A new Pointer with appended token. + */ + GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const { + if (token.IsString()) + return Append(token.GetString(), token.GetStringLength(), allocator); + else { + RAPIDJSON_ASSERT(token.IsUint64()); + RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0)); + return Append(static_cast(token.GetUint64()), allocator); + } + } + + //!@name Handling Parse Error + //@{ + + //! Check whether this is a valid pointer. + bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; } + + //! Get the parsing error offset in code unit. + size_t GetParseErrorOffset() const { return parseErrorOffset_; } + + //! Get the parsing error code. + PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; } + + //@} + + //! Get the allocator of this pointer. + Allocator& GetAllocator() { return *allocator_; } + + //!@name Tokens + //@{ + + //! Get the token array (const version only). + const Token* GetTokens() const { return tokens_; } + + //! Get the number of tokens. + size_t GetTokenCount() const { return tokenCount_; } + + //@} + + //!@name Equality/inequality operators + //@{ + + //! Equality operator. + /*! + \note When any pointers are invalid, always returns false. + */ + bool operator==(const GenericPointer& rhs) const { + if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_) + return false; + + for (size_t i = 0; i < tokenCount_; i++) { + if (tokens_[i].index != rhs.tokens_[i].index || + tokens_[i].length != rhs.tokens_[i].length || + (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0)) + { + return false; + } + } + + return true; + } + + //! Inequality operator. + /*! + \note When any pointers are invalid, always returns true. + */ + bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); } + + //@} + + //!@name Stringify + //@{ + + //! Stringify the pointer into string representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + return Stringify(os); + } + + //! Stringify the pointer into URI fragment representation. + /*! + \tparam OutputStream Type of output stream. + \param os The output stream. + */ + template + bool StringifyUriFragment(OutputStream& os) const { + return Stringify(os); + } + + //@} + + //!@name Create value + //@{ + + //! Create a value in a subtree. + /*! + If the value is not exist, it creates all parent values and a JSON Null value. + So it always succeed and return the newly created or existing value. + + Remind that it may change types of parents according to tokens, so it + potentially removes previously stored values. For example, if a document + was an array, and "/foo" is used to create a value, then the document + will be changed to an object, and all existing array elements are lost. + + \param root Root value of a DOM subtree to be resolved. It can be any value other than document root. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created (a JSON Null value), or already exists value. + */ + ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + bool exist = true; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + if (v->IsArray() && t->name[0] == '-' && t->length == 1) { + v->PushBack(ValueType().Move(), allocator); + v = &((*v)[v->Size() - 1]); + exist = false; + } + else { + if (t->index == kPointerInvalidIndex) { // must be object name + if (!v->IsObject()) + v->SetObject(); // Change to Object + } + else { // object name or array index + if (!v->IsArray() && !v->IsObject()) + v->SetArray(); // Change to Array + } + + if (v->IsArray()) { + if (t->index >= v->Size()) { + v->Reserve(t->index + 1, allocator); + while (t->index >= v->Size()) + v->PushBack(ValueType().Move(), allocator); + exist = false; + } + v = &((*v)[t->index]); + } + else { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) { + v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator); + v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end + exist = false; + } + else + v = &m->value; + } + } + } + + if (alreadyExist) + *alreadyExist = exist; + + return *v; + } + + //! Creates a value in a document. + /*! + \param document A document to be resolved. + \param alreadyExist If non-null, it stores whether the resolved value is already exist. + \return The resolved newly created, or already exists value. + */ + template + ValueType& Create(GenericDocument& document, bool* alreadyExist = 0) const { + return Create(document, document.GetAllocator(), alreadyExist); + } + + //@} + + //!@name Query value + //@{ + + //! Query a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token. + \return Pointer to the value if it can be resolved. Otherwise null. + + \note + There are only 3 situations when a value cannot be resolved: + 1. A value in the path is not an array nor object. + 2. An object value does not contain the token. + 3. A token is out of range of an array value. + + Use unresolvedTokenIndex to retrieve the token index. + */ + ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const { + RAPIDJSON_ASSERT(IsValid()); + ValueType* v = &root; + for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + break; + v = &m->value; + } + continue; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + break; + v = &((*v)[t->index]); + continue; + default: + break; + } + + // Error: unresolved token + if (unresolvedTokenIndex) + *unresolvedTokenIndex = static_cast(t - tokens_); + return 0; + } + return v; + } + + //! Query a const value in a const subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Pointer to the value if it can be resolved. Otherwise null. + */ + const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const { + return Get(const_cast(root), unresolvedTokenIndex); + } + + //@} + + //!@name Query a value with default + //@{ + + //! Query a value in a subtree with default value. + /*! + Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value. + So that this function always succeed. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param defaultValue Default value to be cloned if the value was not exists. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.CopyFrom(defaultValue, allocator); + } + + //! Query a value in a subtree with default null-terminated string. + ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a subtree with default std::basic_string. + ValueType& GetWithDefault(ValueType& root, const std::basic_string& defaultValue, typename ValueType::AllocatorType& allocator) const { + bool alreadyExist; + Value& v = Create(root, allocator, &alreadyExist); + return alreadyExist ? v : v.SetString(defaultValue, allocator); + } +#endif + + //! Query a value in a subtree with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const { + return GetWithDefault(root, ValueType(defaultValue).Move(), allocator); + } + + //! Query a value in a document with default value. + template + ValueType& GetWithDefault(GenericDocument& document, const ValueType& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //! Query a value in a document with default null-terminated string. + template + ValueType& GetWithDefault(GenericDocument& document, const Ch* defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Query a value in a document with default std::basic_string. + template + ValueType& GetWithDefault(GenericDocument& document, const std::basic_string& defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } +#endif + + //! Query a value in a document with default primitive value. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + GetWithDefault(GenericDocument& document, T defaultValue) const { + return GetWithDefault(document, defaultValue, document.GetAllocator()); + } + + //@} + + //!@name Set a value + //@{ + + //! Set a value in a subtree, with move semantics. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be set. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = value; + } + + //! Set a value in a subtree, with copy semantics. + ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).CopyFrom(value, allocator); + } + + //! Set a null-terminated string in a subtree. + ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Set a std::basic_string in a subtree. + ValueType& Set(ValueType& root, const std::basic_string& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value, allocator).Move(); + } +#endif + + //! Set a primitive value in a subtree. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator) = ValueType(value).Move(); + } + + //! Set a value in a document, with move semantics. + template + ValueType& Set(GenericDocument& document, ValueType& value) const { + return Create(document) = value; + } + + //! Set a value in a document, with copy semantics. + template + ValueType& Set(GenericDocument& document, const ValueType& value) const { + return Create(document).CopyFrom(value, document.GetAllocator()); + } + + //! Set a null-terminated string in a document. + template + ValueType& Set(GenericDocument& document, const Ch* value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } + +#if RAPIDJSON_HAS_STDSTRING + //! Sets a std::basic_string in a document. + template + ValueType& Set(GenericDocument& document, const std::basic_string& value) const { + return Create(document) = ValueType(value, document.GetAllocator()).Move(); + } +#endif + + //! Set a primitive value in a document. + /*! + \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool + */ + template + RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (ValueType&)) + Set(GenericDocument& document, T value) const { + return Create(document) = value; + } + + //@} + + //!@name Swap a value + //@{ + + //! Swap a value with a value in a subtree. + /*! + It creates all parents if they are not exist or types are different to the tokens. + So this function always succeeds but potentially remove existing values. + + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \param value Value to be swapped. + \param allocator Allocator for creating the values if the specified value or its parents are not exist. + \see Create() + */ + ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const { + return Create(root, allocator).Swap(value); + } + + //! Swap a value with a value in a document. + template + ValueType& Swap(GenericDocument& document, ValueType& value) const { + return Create(document).Swap(value); + } + + //@} + + //! Erase a value in a subtree. + /*! + \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root. + \return Whether the resolved value is found and erased. + + \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false. + */ + bool Erase(ValueType& root) const { + RAPIDJSON_ASSERT(IsValid()); + if (tokenCount_ == 0) // Cannot erase the root + return false; + + ValueType* v = &root; + const Token* last = tokens_ + (tokenCount_ - 1); + for (const Token *t = tokens_; t != last; ++t) { + switch (v->GetType()) { + case kObjectType: + { + typename ValueType::MemberIterator m = v->FindMember(GenericStringRef(t->name, t->length)); + if (m == v->MemberEnd()) + return false; + v = &m->value; + } + break; + case kArrayType: + if (t->index == kPointerInvalidIndex || t->index >= v->Size()) + return false; + v = &((*v)[t->index]); + break; + default: + return false; + } + } + + switch (v->GetType()) { + case kObjectType: + return v->EraseMember(GenericStringRef(last->name, last->length)); + case kArrayType: + if (last->index == kPointerInvalidIndex || last->index >= v->Size()) + return false; + v->Erase(v->Begin() + last->index); + return true; + default: + return false; + } + } + +private: + //! Clone the content from rhs to this. + /*! + \param rhs Source pointer. + \param extraToken Extra tokens to be allocated. + \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated. + \return Start of non-occupied name buffer, for storing extra names. + */ + Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) { + if (!allocator_) // allocator is independently owned. + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens + for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t) + nameBufferSize += t->length; + + tokenCount_ = rhs.tokenCount_ + extraToken; + tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch))); + nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + if (rhs.tokenCount_ > 0) { + std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token)); + } + if (nameBufferSize > 0) { + std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); + } + + // Adjust pointers to name buffer + std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; + for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) + t->name += diff; + + return nameBuffer_ + nameBufferSize; + } + + //! Check whether a character should be percent-encoded. + /*! + According to RFC 3986 2.3 Unreserved Characters. + \param c The character (code unit) to be tested. + */ + bool NeedPercentEncode(Ch c) const { + return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~'); + } + + //! Parse a JSON String or its URI fragment representation into tokens. +#ifndef __clang__ // -Wdocumentation + /*! + \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated. + \param length Length of the source string. + \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped. + */ +#endif + void Parse(const Ch* source, size_t length) { + RAPIDJSON_ASSERT(source != NULL); + RAPIDJSON_ASSERT(nameBuffer_ == 0); + RAPIDJSON_ASSERT(tokens_ == 0); + + // Create own allocator if user did not supply. + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Count number of '/' as tokenCount + tokenCount_ = 0; + for (const Ch* s = source; s != source + length; s++) + if (*s == '/') + tokenCount_++; + + Token* token = tokens_ = static_cast(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch))); + Ch* name = nameBuffer_ = reinterpret_cast(tokens_ + tokenCount_); + size_t i = 0; + + // Detect if it is a URI fragment + bool uriFragment = false; + if (source[i] == '#') { + uriFragment = true; + i++; + } + + if (i != length && source[i] != '/') { + parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus; + goto error; + } + + while (i < length) { + RAPIDJSON_ASSERT(source[i] == '/'); + i++; // consumes '/' + + token->name = name; + bool isNumber = true; + + while (i < length && source[i] != '/') { + Ch c = source[i]; + if (uriFragment) { + // Decoding percent-encoding for URI fragment + if (c == '%') { + PercentDecodeStream is(&source[i], source + length); + GenericInsituStringStream os(name); + Ch* begin = os.PutBegin(); + if (!Transcoder, EncodingType>().Validate(is, os) || !is.IsValid()) { + parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding; + goto error; + } + size_t len = os.PutEnd(begin); + i += is.Tell() - 1; + if (len == 1) + c = *name; + else { + name += len; + isNumber = false; + i++; + continue; + } + } + else if (NeedPercentEncode(c)) { + parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode; + goto error; + } + } + + i++; + + // Escaping "~0" -> '~', "~1" -> '/' + if (c == '~') { + if (i < length) { + c = source[i]; + if (c == '0') c = '~'; + else if (c == '1') c = '/'; + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + i++; + } + else { + parseErrorCode_ = kPointerParseErrorInvalidEscape; + goto error; + } + } + + // First check for index: all of characters are digit + if (c < '0' || c > '9') + isNumber = false; + + *name++ = c; + } + token->length = static_cast(name - token->name); + if (token->length == 0) + isNumber = false; + *name++ = '\0'; // Null terminator + + // Second check for index: more than one digit cannot have leading zero + if (isNumber && token->length > 1 && token->name[0] == '0') + isNumber = false; + + // String to SizeType conversion + SizeType n = 0; + if (isNumber) { + for (size_t j = 0; j < token->length; j++) { + SizeType m = n * 10 + static_cast(token->name[j] - '0'); + if (m < n) { // overflow detection + isNumber = false; + break; + } + n = m; + } + } + + token->index = isNumber ? n : kPointerInvalidIndex; + token++; + } + + RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer + parseErrorCode_ = kPointerParseErrorNone; + return; + + error: + Allocator::Free(tokens_); + nameBuffer_ = 0; + tokens_ = 0; + tokenCount_ = 0; + parseErrorOffset_ = i; + return; + } + + //! Stringify to string or URI fragment representation. + /*! + \tparam uriFragment True for stringifying to URI fragment representation. False for string representation. + \tparam OutputStream type of output stream. + \param os The output stream. + */ + template + bool Stringify(OutputStream& os) const { + RAPIDJSON_ASSERT(IsValid()); + + if (uriFragment) + os.Put('#'); + + for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) { + os.Put('/'); + for (size_t j = 0; j < t->length; j++) { + Ch c = t->name[j]; + if (c == '~') { + os.Put('~'); + os.Put('0'); + } + else if (c == '/') { + os.Put('~'); + os.Put('1'); + } + else if (uriFragment && NeedPercentEncode(c)) { + // Transcode to UTF8 sequence + GenericStringStream source(&t->name[j]); + PercentEncodeStream target(os); + if (!Transcoder >().Validate(source, target)) + return false; + j += source.Tell() - 1; + } + else + os.Put(c); + } + } + return true; + } + + //! A helper stream for decoding a percent-encoded sequence into code unit. + /*! + This stream decodes %XY triplet into code unit (0-255). + If it encounters invalid characters, it sets output code unit as 0 and + mark invalid, and to be checked by IsValid(). + */ + class PercentDecodeStream { + public: + typedef typename ValueType::Ch Ch; + + //! Constructor + /*! + \param source Start of the stream + \param end Past-the-end of the stream. + */ + PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {} + + Ch Take() { + if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet + valid_ = false; + return 0; + } + src_++; + Ch c = 0; + for (int j = 0; j < 2; j++) { + c = static_cast(c << 4); + Ch h = *src_; + if (h >= '0' && h <= '9') c = static_cast(c + h - '0'); + else if (h >= 'A' && h <= 'F') c = static_cast(c + h - 'A' + 10); + else if (h >= 'a' && h <= 'f') c = static_cast(c + h - 'a' + 10); + else { + valid_ = false; + return 0; + } + src_++; + } + return c; + } + + size_t Tell() const { return static_cast(src_ - head_); } + bool IsValid() const { return valid_; } + + private: + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. + const Ch* end_; //!< Past-the-end position. + bool valid_; //!< Whether the parsing is valid. + }; + + //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence. + template + class PercentEncodeStream { + public: + PercentEncodeStream(OutputStream& os) : os_(os) {} + void Put(char c) { // UTF-8 must be byte + unsigned char u = static_cast(c); + static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + os_.Put('%'); + os_.Put(hexDigits[u >> 4]); + os_.Put(hexDigits[u & 15]); + } + private: + OutputStream& os_; + }; + + Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_. + Allocator* ownAllocator_; //!< Allocator owned by this Pointer. + Ch* nameBuffer_; //!< A buffer containing all names in tokens. + Token* tokens_; //!< A list of tokens. + size_t tokenCount_; //!< Number of tokens in tokens_. + size_t parseErrorOffset_; //!< Offset in code unit when parsing fail. + PointerParseErrorCode parseErrorCode_; //!< Parsing error code. +}; + +//! GenericPointer for Value (UTF-8, default allocator). +typedef GenericPointer Pointer; + +//!@name Helper functions for GenericPointer +//@{ + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer& pointer, typename T::AllocatorType& a) { + return pointer.Create(root, a); +} + +template +typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Create(root, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer& pointer) { + return pointer.Create(document); +} + +template +typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Create(document); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType* GetValueByPointer(T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer& pointer, size_t* unresolvedTokenIndex = 0) { + return pointer.Get(root, unresolvedTokenIndex); +} + +template +typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +template +const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) { + return GenericPointer(source, N - 1).Get(root, unresolvedTokenIndex); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const GenericPointer& pointer, T2 defaultValue, typename T::AllocatorType& a) { + return pointer.GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string& defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).GetWithDefault(root, defaultValue, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, const std::basic_string& defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const GenericPointer& pointer, T2 defaultValue) { + return pointer.GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string& defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) { + return GenericPointer(source, N - 1).GetWithDefault(document, defaultValue); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const typename T::Ch* value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const GenericPointer& pointer, const std::basic_string& value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const GenericPointer& pointer, T2 value, typename T::AllocatorType& a) { + return pointer.Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename T::ValueType&)) +SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Set(root, value, a); +} + +// No allocator parameter + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::ValueType& value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const typename DocumentType::Ch* value) { + return pointer.Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer& pointer, const std::basic_string& value) { + return pointer.Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const GenericPointer& pointer, T2 value) { + return pointer.Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +#if RAPIDJSON_HAS_STDSTRING +template +typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string& value) { + return GenericPointer(source, N - 1).Set(document, value); +} +#endif + +template +RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr, internal::IsGenericValue >), (typename DocumentType::ValueType&)) +SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) { + return GenericPointer(source, N - 1).Set(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer& pointer, typename T::ValueType& value, typename T::AllocatorType& a) { + return pointer.Swap(root, value, a); +} + +template +typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) { + return GenericPointer(source, N - 1).Swap(root, value, a); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer& pointer, typename DocumentType::ValueType& value) { + return pointer.Swap(document, value); +} + +template +typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) { + return GenericPointer(source, N - 1).Swap(document, value); +} + +////////////////////////////////////////////////////////////////////////////// + +template +bool EraseValueByPointer(T& root, const GenericPointer& pointer) { + return pointer.Erase(root); +} + +template +bool EraseValueByPointer(T& root, const CharType(&source)[N]) { + return GenericPointer(source, N - 1).Erase(root); +} + +//@} + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_POINTER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/prettywriter.h b/src/third-party/discord-rpc/include/rapidjson/prettywriter.h new file mode 100644 index 000000000..0dcb0fee9 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/prettywriter.h @@ -0,0 +1,255 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_PRETTYWRITER_H_ +#define RAPIDJSON_PRETTYWRITER_H_ + +#include "writer.h" + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Combination of PrettyWriter format flags. +/*! \see PrettyWriter::SetFormatOptions + */ +enum PrettyFormatOptions { + kFormatDefault = 0, //!< Default pretty formatting. + kFormatSingleLineArray = 1 //!< Format arrays on a single line. +}; + +//! Writer with indentation and spacing. +/*! + \tparam OutputStream Type of ouptut os. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class PrettyWriter : public Writer { +public: + typedef Writer Base; + typedef typename Base::Ch Ch; + + //! Constructor + /*! \param os Output stream. + \param allocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {} + + + explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) : + Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {} + + //! Set custom indentation. + /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r'). + \param indentCharCount Number of indent characters for each indentation level. + \note The default indentation is 4 spaces. + */ + PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) { + RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r'); + indentChar_ = indentChar; + indentCharCount_ = indentCharCount; + return *this; + } + + //! Set pretty writer formatting options. + /*! \param options Formatting options. + */ + PrettyWriter& SetFormatOptions(PrettyFormatOptions options) { + formatOptions_ = options; + return *this; + } + + /*! @name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kNumberType); + return Base::WriteString(str, length); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + PrettyPrefix(kStringType); + return Base::WriteString(str, length); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + PrettyPrefix(kObjectType); + new (Base::level_stack_.template Push()) typename Base::Level(false); + return Base::WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + +#if RAPIDJSON_HAS_STDSTRING + bool Key(const std::basic_string& str) { + return Key(str.data(), SizeType(str.size())); + } +#endif + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndObject(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + bool StartArray() { + PrettyPrefix(kArrayType); + new (Base::level_stack_.template Push()) typename Base::Level(true); + return Base::WriteStartArray(); + } + + bool EndArray(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); + RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); + bool empty = Base::level_stack_.template Pop(1)->valueCount == 0; + + if (!empty && !(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + bool ret = Base::WriteEndArray(); + (void)ret; + RAPIDJSON_ASSERT(ret == true); + if (Base::level_stack_.Empty()) // end of json text + Base::os_->Flush(); + return true; + } + + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + \note When using PrettyWriter::RawValue(), the result json may not be indented correctly. + */ + bool RawValue(const Ch* json, size_t length, Type type) { PrettyPrefix(type); return Base::WriteRawValue(json, length); } + +protected: + void PrettyPrefix(Type type) { + (void)type; + if (Base::level_stack_.GetSize() != 0) { // this value is not at root + typename Base::Level* level = Base::level_stack_.template Top(); + + if (level->inArray) { + if (level->valueCount > 0) { + Base::os_->Put(','); // add comma if it is not the first element in array + if (formatOptions_ & kFormatSingleLineArray) + Base::os_->Put(' '); + } + + if (!(formatOptions_ & kFormatSingleLineArray)) { + Base::os_->Put('\n'); + WriteIndent(); + } + } + else { // in object + if (level->valueCount > 0) { + if (level->valueCount % 2 == 0) { + Base::os_->Put(','); + Base::os_->Put('\n'); + } + else { + Base::os_->Put(':'); + Base::os_->Put(' '); + } + } + else + Base::os_->Put('\n'); + + if (level->valueCount % 2 == 0) + WriteIndent(); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. + Base::hasRoot_ = true; + } + } + + void WriteIndent() { + size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_; + PutN(*Base::os_, static_cast(indentChar_), count); + } + + Ch indentChar_; + unsigned indentCharCount_; + PrettyFormatOptions formatOptions_; + +private: + // Prohibit copy constructor & assignment operator. + PrettyWriter(const PrettyWriter&); + PrettyWriter& operator=(const PrettyWriter&); +}; + +RAPIDJSON_NAMESPACE_END + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/rapidjson.h b/src/third-party/discord-rpc/include/rapidjson/rapidjson.h new file mode 100644 index 000000000..053b2ce43 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/rapidjson.h @@ -0,0 +1,615 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_RAPIDJSON_H_ +#define RAPIDJSON_RAPIDJSON_H_ + +/*!\file rapidjson.h + \brief common definitions and configuration + + \see RAPIDJSON_CONFIG + */ + +/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration + \brief Configuration macros for library features + + Some RapidJSON features are configurable to adapt the library to a wide + variety of platforms, environments and usage scenarios. Most of the + features can be configured in terms of overriden or predefined + preprocessor macros at compile-time. + + Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. + + \note These macros should be given on the compiler command-line + (where applicable) to avoid inconsistent values when compiling + different translation units of a single application. + */ + +#include // malloc(), realloc(), free(), size_t +#include // memset(), memcpy(), memmove(), memcmp() + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_VERSION_STRING +// +// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. +// + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +// token stringification +#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) +#define RAPIDJSON_DO_STRINGIFY(x) #x +//!@endcond + +/*! \def RAPIDJSON_MAJOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Major version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_MINOR_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Minor version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_PATCH_VERSION + \ingroup RAPIDJSON_CONFIG + \brief Patch version of RapidJSON in integer. +*/ +/*! \def RAPIDJSON_VERSION_STRING + \ingroup RAPIDJSON_CONFIG + \brief Version of RapidJSON in ".." string format. +*/ +#define RAPIDJSON_MAJOR_VERSION 1 +#define RAPIDJSON_MINOR_VERSION 1 +#define RAPIDJSON_PATCH_VERSION 0 +#define RAPIDJSON_VERSION_STRING \ + RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NAMESPACE_(BEGIN|END) +/*! \def RAPIDJSON_NAMESPACE + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace + + In order to avoid symbol clashes and/or "One Definition Rule" errors + between multiple inclusions of (different versions of) RapidJSON in + a single binary, users can customize the name of the main RapidJSON + namespace. + + In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE + to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple + levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref + RAPIDJSON_NAMESPACE_END need to be defined as well: + + \code + // in some .cpp file + #define RAPIDJSON_NAMESPACE my::rapidjson + #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { + #define RAPIDJSON_NAMESPACE_END } } + #include "rapidjson/..." + \endcode + + \see rapidjson + */ +/*! \def RAPIDJSON_NAMESPACE_BEGIN + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (opening expression) + \see RAPIDJSON_NAMESPACE +*/ +/*! \def RAPIDJSON_NAMESPACE_END + \ingroup RAPIDJSON_CONFIG + \brief provide custom rapidjson namespace (closing expression) + \see RAPIDJSON_NAMESPACE +*/ +#ifndef RAPIDJSON_NAMESPACE +#define RAPIDJSON_NAMESPACE rapidjson +#endif +#ifndef RAPIDJSON_NAMESPACE_BEGIN +#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { +#endif +#ifndef RAPIDJSON_NAMESPACE_END +#define RAPIDJSON_NAMESPACE_END } +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_HAS_STDSTRING + +#ifndef RAPIDJSON_HAS_STDSTRING +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation +#else +#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default +#endif +/*! \def RAPIDJSON_HAS_STDSTRING + \ingroup RAPIDJSON_CONFIG + \brief Enable RapidJSON support for \c std::string + + By defining this preprocessor symbol to \c 1, several convenience functions for using + \ref rapidjson::GenericValue with \c std::string are enabled, especially + for construction and comparison. + + \hideinitializer +*/ +#endif // !defined(RAPIDJSON_HAS_STDSTRING) + +#if RAPIDJSON_HAS_STDSTRING +#include +#endif // RAPIDJSON_HAS_STDSTRING + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_INT64DEFINE + +/*! \def RAPIDJSON_NO_INT64DEFINE + \ingroup RAPIDJSON_CONFIG + \brief Use external 64-bit integer types. + + RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types + to be available at global scope. + + If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to + prevent RapidJSON from defining its own types. +*/ +#ifndef RAPIDJSON_NO_INT64DEFINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 +#include "msinttypes/stdint.h" +#include "msinttypes/inttypes.h" +#else +// Other compilers should have this. +#include +#include +#endif +//!@endcond +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_INT64DEFINE +#endif +#endif // RAPIDJSON_NO_INT64TYPEDEF + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_FORCEINLINE + +#ifndef RAPIDJSON_FORCEINLINE +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#if defined(_MSC_VER) && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) +#define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) +#else +#define RAPIDJSON_FORCEINLINE +#endif +//!@endcond +#endif // RAPIDJSON_FORCEINLINE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ENDIAN +#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine +#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine + +//! Endianness of the machine. +/*! + \def RAPIDJSON_ENDIAN + \ingroup RAPIDJSON_CONFIG + + GCC 4.6 provided macro for detecting endianness of the target machine. But other + compilers may not have this. User can define RAPIDJSON_ENDIAN to either + \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. + + Default detection implemented with reference to + \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html + \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp +*/ +#ifndef RAPIDJSON_ENDIAN +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(_MSC_VER) && defined(_M_ARM) +# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN +# elif defined(RAPIDJSON_DOXYGEN_RUNNING) +# define RAPIDJSON_ENDIAN +# else +# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN. +# endif +#endif // RAPIDJSON_ENDIAN + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_64BIT + +//! Whether using 64-bit architecture +#ifndef RAPIDJSON_64BIT +#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) +#define RAPIDJSON_64BIT 1 +#else +#define RAPIDJSON_64BIT 0 +#endif +#endif // RAPIDJSON_64BIT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ALIGN + +//! Data alignment of the machine. +/*! \ingroup RAPIDJSON_CONFIG + \param x pointer to align + + Some machines require strict data alignment. Currently the default uses 4 bytes + alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms. + User can customize by defining the RAPIDJSON_ALIGN function macro. +*/ +#ifndef RAPIDJSON_ALIGN +#if RAPIDJSON_64BIT == 1 +#define RAPIDJSON_ALIGN(x) (((x) + static_cast(7u)) & ~static_cast(7u)) +#else +#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_UINT64_C2 + +//! Construct a 64-bit literal by a pair of 32-bit integer. +/*! + 64-bit literal with or without ULL suffix is prone to compiler warnings. + UINT64_C() is C macro which cause compilation problems. + Use this macro to define 64-bit constants by a pair of 32-bit integer. +*/ +#ifndef RAPIDJSON_UINT64_C2 +#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast(high32) << 32) | static_cast(low32)) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_48BITPOINTER_OPTIMIZATION + +//! Use only lower 48-bit address for some pointers. +/*! + \ingroup RAPIDJSON_CONFIG + + This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. + The higher 16-bit can be used for storing other data. + \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. +*/ +#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 +#else +#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 +#endif +#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION + +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 +#if RAPIDJSON_64BIT != 1 +#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 +#endif +#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast((reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast(reinterpret_cast(x)))) +#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast(reinterpret_cast(p) & static_cast(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) +#else +#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) +#define RAPIDJSON_GETPOINTER(type, p) (p) +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD + +/*! \def RAPIDJSON_SIMD + \ingroup RAPIDJSON_CONFIG + \brief Enable SSE2/SSE4.2 optimization. + + RapidJSON supports optimized implementations for some parsing operations + based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible + processors. + + To enable these optimizations, two different symbols can be defined; + \code + // Enable SSE2 optimization. + #define RAPIDJSON_SSE2 + + // Enable SSE4.2 optimization. + #define RAPIDJSON_SSE42 + \endcode + + \c RAPIDJSON_SSE42 takes precedence, if both are defined. + + If any of these symbols is defined, RapidJSON defines the macro + \c RAPIDJSON_SIMD to indicate the availability of the optimized code. +*/ +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ + || defined(RAPIDJSON_DOXYGEN_RUNNING) +#define RAPIDJSON_SIMD +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_NO_SIZETYPEDEFINE + +#ifndef RAPIDJSON_NO_SIZETYPEDEFINE +/*! \def RAPIDJSON_NO_SIZETYPEDEFINE + \ingroup RAPIDJSON_CONFIG + \brief User-provided \c SizeType definition. + + In order to avoid using 32-bit size types for indexing strings and arrays, + define this preprocessor symbol and provide the type rapidjson::SizeType + before including RapidJSON: + \code + #define RAPIDJSON_NO_SIZETYPEDEFINE + namespace rapidjson { typedef ::std::size_t SizeType; } + #include "rapidjson/..." + \endcode + + \see rapidjson::SizeType +*/ +#ifdef RAPIDJSON_DOXYGEN_RUNNING +#define RAPIDJSON_NO_SIZETYPEDEFINE +#endif +RAPIDJSON_NAMESPACE_BEGIN +//! Size type (for string lengths, array sizes, etc.) +/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, + instead of using \c size_t. Users may override the SizeType by defining + \ref RAPIDJSON_NO_SIZETYPEDEFINE. +*/ +typedef unsigned SizeType; +RAPIDJSON_NAMESPACE_END +#endif + +// always import std::size_t to rapidjson namespace +RAPIDJSON_NAMESPACE_BEGIN +using std::size_t; +RAPIDJSON_NAMESPACE_END + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_ASSERT + +//! Assertion. +/*! \ingroup RAPIDJSON_CONFIG + By default, rapidjson uses C \c assert() for internal assertions. + User can override it by defining RAPIDJSON_ASSERT(x) macro. + + \note Parsing errors are handled and can be customized by the + \ref RAPIDJSON_ERRORS APIs. +*/ +#ifndef RAPIDJSON_ASSERT +#include +#define RAPIDJSON_ASSERT(x) assert(x) +#endif // RAPIDJSON_ASSERT + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_STATIC_ASSERT + +// Adopt from boost +#ifndef RAPIDJSON_STATIC_ASSERT +#ifndef __clang__ +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#endif +RAPIDJSON_NAMESPACE_BEGIN +template struct STATIC_ASSERTION_FAILURE; +template <> struct STATIC_ASSERTION_FAILURE { enum { value = 1 }; }; +template struct StaticAssertTest {}; +RAPIDJSON_NAMESPACE_END + +#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) +#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) +#define RAPIDJSON_DO_JOIN2(X, Y) X##Y + +#if defined(__GNUC__) +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) +#else +#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif +#ifndef __clang__ +//!@endcond +#endif + +/*! \def RAPIDJSON_STATIC_ASSERT + \brief (Internal) macro to check for conditions at compile-time + \param x compile-time condition + \hideinitializer + */ +#define RAPIDJSON_STATIC_ASSERT(x) \ + typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ + sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE)> \ + RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE +#endif + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY + +//! Compiler branching hint for expression with high probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression likely to be true. +*/ +#ifndef RAPIDJSON_LIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) +#else +#define RAPIDJSON_LIKELY(x) (x) +#endif +#endif + +//! Compiler branching hint for expression with low probability to be true. +/*! + \ingroup RAPIDJSON_CONFIG + \param x Boolean expression unlikely to be true. +*/ +#ifndef RAPIDJSON_UNLIKELY +#if defined(__GNUC__) || defined(__clang__) +#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +#define RAPIDJSON_UNLIKELY(x) (x) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Helpers + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN + +#define RAPIDJSON_MULTILINEMACRO_BEGIN do { +#define RAPIDJSON_MULTILINEMACRO_END \ +} while((void)0, 0) + +// adopted from Boost +#define RAPIDJSON_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF + +#if defined(__GNUC__) +#define RAPIDJSON_GNUC \ + RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) +#endif + +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) + +#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) +#define RAPIDJSON_DIAG_OFF(x) \ + RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) + +// push/pop support in Clang and GCC>=4.6 +#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) +#else // GCC >= 4.2, < 4.6 +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ +#endif + +#elif defined(_MSC_VER) + +// pragma (MSVC specific) +#define RAPIDJSON_PRAGMA(x) __pragma(x) +#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) + +#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) +#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) +#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) + +#else + +#define RAPIDJSON_DIAG_OFF(x) /* ignored */ +#define RAPIDJSON_DIAG_PUSH /* ignored */ +#define RAPIDJSON_DIAG_POP /* ignored */ + +#endif // RAPIDJSON_DIAG_* + +/////////////////////////////////////////////////////////////////////////////// +// C++11 features + +#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS +#if defined(__clang__) +#if __has_feature(cxx_rvalue_references) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) + +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 +#else +#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS + +#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) +// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 +#else +#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 +#endif +#endif +#if RAPIDJSON_HAS_CXX11_NOEXCEPT +#define RAPIDJSON_NOEXCEPT noexcept +#else +#define RAPIDJSON_NOEXCEPT /* noexcept */ +#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT + +// no automatic detection, yet +#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS +#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 +#endif + +#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR +#if defined(__clang__) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) +#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ + (defined(_MSC_VER) && _MSC_VER >= 1700) +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 +#else +#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 +#endif +#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR + +//!@endcond + +/////////////////////////////////////////////////////////////////////////////// +// new/delete + +#ifndef RAPIDJSON_NEW +///! customization point for global \c new +#define RAPIDJSON_NEW(x) new x +#endif +#ifndef RAPIDJSON_DELETE +///! customization point for global \c delete +#define RAPIDJSON_DELETE(x) delete x +#endif + +/////////////////////////////////////////////////////////////////////////////// +// Type + +/*! \namespace rapidjson + \brief main RapidJSON namespace + \see RAPIDJSON_NAMESPACE +*/ +RAPIDJSON_NAMESPACE_BEGIN + +//! Type of JSON value +enum Type { + kNullType = 0, //!< null + kFalseType = 1, //!< false + kTrueType = 2, //!< true + kObjectType = 3, //!< object + kArrayType = 4, //!< array + kStringType = 5, //!< string + kNumberType = 6 //!< number +}; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/reader.h b/src/third-party/discord-rpc/include/rapidjson/reader.h new file mode 100644 index 000000000..19f8849b1 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/reader.h @@ -0,0 +1,1879 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_READER_H_ +#define RAPIDJSON_READER_H_ + +/*! \file reader.h */ + +#include "allocators.h" +#include "stream.h" +#include "encodedstream.h" +#include "internal/meta.h" +#include "internal/stack.h" +#include "internal/strtod.h" +#include + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +RAPIDJSON_DIAG_OFF(4702) // unreachable code +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(old-style-cast) +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(switch-enum) +#endif + +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define RAPIDJSON_NOTHING /* deliberately empty */ +#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ + RAPIDJSON_MULTILINEMACRO_END +#endif +#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) +//!@endcond + +/*! \def RAPIDJSON_PARSE_ERROR_NORETURN + \ingroup RAPIDJSON_ERRORS + \brief Macro to indicate a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + This macros can be used as a customization point for the internal + error handling mechanism of RapidJSON. + + A common usage model is to throw an exception instead of requiring the + caller to explicitly check the \ref rapidjson::GenericReader::Parse's + return value: + + \code + #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ + throw ParseException(parseErrorCode, #parseErrorCode, offset) + + #include // std::runtime_error + #include "rapidjson/error/error.h" // rapidjson::ParseResult + + struct ParseException : std::runtime_error, rapidjson::ParseResult { + ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) + : std::runtime_error(msg), ParseResult(code, offset) {} + }; + + #include "rapidjson/reader.h" + \endcode + + \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse + */ +#ifndef RAPIDJSON_PARSE_ERROR_NORETURN +#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ + SetParseError(parseErrorCode, offset); \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +/*! \def RAPIDJSON_PARSE_ERROR + \ingroup RAPIDJSON_ERRORS + \brief (Internal) macro to indicate and handle a parse error. + \param parseErrorCode \ref rapidjson::ParseErrorCode of the error + \param offset position of the error in JSON input (\c size_t) + + Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. + + \see RAPIDJSON_PARSE_ERROR_NORETURN + \hideinitializer + */ +#ifndef RAPIDJSON_PARSE_ERROR +#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ + RAPIDJSON_MULTILINEMACRO_BEGIN \ + RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ + RAPIDJSON_MULTILINEMACRO_END +#endif + +#include "error/error.h" // ParseErrorCode, ParseResult + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// ParseFlag + +/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kParseDefaultFlags definition. + + User can define this as any \c ParseFlag combinations. +*/ +#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS +#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags +#endif + +//! Combination of parseFlags +/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream + */ +enum ParseFlag { + kParseNoFlags = 0, //!< No flags are set. + kParseInsituFlag = 1, //!< In-situ(destructive) parsing. + kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. + kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. + kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error. + kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). + kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. + kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. + kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. + kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. + kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS +}; + +/////////////////////////////////////////////////////////////////////////////// +// Handler + +/*! \class rapidjson::Handler + \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. +\code +concept Handler { + typename Ch; + + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType length, bool copy); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool Key(const Ch* str, SizeType length, bool copy); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); +}; +\endcode +*/ +/////////////////////////////////////////////////////////////////////////////// +// BaseReaderHandler + +//! Default implementation of Handler. +/*! This can be used as base class of any reader handler. + \note implements Handler concept +*/ +template, typename Derived = void> +struct BaseReaderHandler { + typedef typename Encoding::Ch Ch; + + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) + bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool Key(const Ch* str, SizeType len, bool copy) { return static_cast(*this).String(str, len, copy); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } +}; + +/////////////////////////////////////////////////////////////////////////////// +// StreamLocalCopy + +namespace internal { + +template::copyOptimization> +class StreamLocalCopy; + +//! Do copy optimization. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original), original_(original) {} + ~StreamLocalCopy() { original_ = s; } + + Stream s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; + + Stream& original_; +}; + +//! Keep reference. +template +class StreamLocalCopy { +public: + StreamLocalCopy(Stream& original) : s(original) {} + + Stream& s; + +private: + StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// SkipWhitespace + +//! Skip the JSON white spaces in a stream. +/*! \param is A input stream for skipping white spaces. + \note This function has SSE2/SSE4.2 specialization. +*/ +template +void SkipWhitespace(InputStream& is) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + typename InputStream::Ch c; + while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') + s.Take(); +} + +inline const char* SkipWhitespace(const char* p, const char* end) { + while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + return p; +} + +#ifdef RAPIDJSON_SSE42 +//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The middle of string using SIMD + static const char whitespace[16] = " \n\r\t"; + const __m128i w = _mm_loadu_si128(reinterpret_cast(&whitespace[0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); + if (r != 0) { // some of characters is non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#elif defined(RAPIDJSON_SSE2) + +//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. +inline const char *SkipWhitespace_SIMD(const char* p) { + // Fast return for single non-whitespace + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // 16-byte align to the next boundary + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } +} + +inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { + // Fast return for single non-whitespace + if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) + ++p; + else + return p; + + // The rest of string + #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } + static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; + #undef C16 + + const __m128i w0 = _mm_loadu_si128(reinterpret_cast(&whitespaces[0][0])); + const __m128i w1 = _mm_loadu_si128(reinterpret_cast(&whitespaces[1][0])); + const __m128i w2 = _mm_loadu_si128(reinterpret_cast(&whitespaces[2][0])); + const __m128i w3 = _mm_loadu_si128(reinterpret_cast(&whitespaces[3][0])); + + for (; p <= end - 16; p += 16) { + const __m128i s = _mm_loadu_si128(reinterpret_cast(p)); + __m128i x = _mm_cmpeq_epi8(s, w0); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); + x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); + unsigned short r = static_cast(~_mm_movemask_epi8(x)); + if (r != 0) { // some of characters may be non-whitespace +#ifdef _MSC_VER // Find the index of first non-whitespace + unsigned long offset; + _BitScanForward(&offset, r); + return p + offset; +#else + return p + __builtin_ffs(r) - 1; +#endif + } + } + + return SkipWhitespace(p, end); +} + +#endif // RAPIDJSON_SSE2 + +#ifdef RAPIDJSON_SIMD +//! Template function specialization for InsituStringStream +template<> inline void SkipWhitespace(InsituStringStream& is) { + is.src_ = const_cast(SkipWhitespace_SIMD(is.src_)); +} + +//! Template function specialization for StringStream +template<> inline void SkipWhitespace(StringStream& is) { + is.src_ = SkipWhitespace_SIMD(is.src_); +} + +template<> inline void SkipWhitespace(EncodedInputStream, MemoryStream>& is) { + is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); +} +#endif // RAPIDJSON_SIMD + +/////////////////////////////////////////////////////////////////////////////// +// GenericReader + +//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. +/*! GenericReader parses JSON text from a stream, and send events synchronously to an + object implementing Handler concept. + + It needs to allocate a stack for storing a single decoded string during + non-destructive parsing. + + For in-situ parsing, the decoded string is directly written to the source + text string, no temporary buffer is required. + + A GenericReader object can be reused for parsing multiple JSON text. + + \tparam SourceEncoding Encoding of the input stream. + \tparam TargetEncoding Encoding of the parse output. + \tparam StackAllocator Allocator type for stack. +*/ +template +class GenericReader { +public: + typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type + + //! Constructor. + /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) + \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) + */ + GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} + + //! Parse JSON text. + /*! \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + if (parseFlags & kParseIterativeFlag) + return IterativeParse(is, handler); + + parseResult_.Clear(); + + ClearStackOnExit scope(*this); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + else { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (!(parseFlags & kParseStopWhenDoneFlag)) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + + if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + } + } + + return parseResult_; + } + + //! Parse JSON text (with \ref kParseDefaultFlags) + /*! \tparam InputStream Type of input stream, implementing Stream concept + \tparam Handler Type of handler, implementing Handler concept. + \param is Input stream to be parsed. + \param handler The handler to receive events. + \return Whether the parsing is successful. + */ + template + ParseResult Parse(InputStream& is, Handler& handler) { + return Parse(is, handler); + } + + //! Whether a parse error has occured in the last parsing. + bool HasParseError() const { return parseResult_.IsError(); } + + //! Get the \ref ParseErrorCode of last parsing. + ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } + + //! Get the position of last parsing error in input, 0 otherwise. + size_t GetErrorOffset() const { return parseResult_.Offset(); } + +protected: + void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } + +private: + // Prohibit copy constructor & assignment operator. + GenericReader(const GenericReader&); + GenericReader& operator=(const GenericReader&); + + void ClearStack() { stack_.Clear(); } + + // clear stack on any exit from ParseStream, e.g. due to exception + struct ClearStackOnExit { + explicit ClearStackOnExit(GenericReader& r) : r_(r) {} + ~ClearStackOnExit() { r_.ClearStack(); } + private: + GenericReader& r_; + ClearStackOnExit(const ClearStackOnExit&); + ClearStackOnExit& operator=(const ClearStackOnExit&); + }; + + template + void SkipWhitespaceAndComments(InputStream& is) { + SkipWhitespace(is); + + if (parseFlags & kParseCommentsFlag) { + while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { + if (Consume(is, '*')) { + while (true) { + if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + else if (Consume(is, '*')) { + if (Consume(is, '/')) + break; + } + else + is.Take(); + } + } + else if (RAPIDJSON_LIKELY(Consume(is, '/'))) + while (is.Peek() != '\0' && is.Take() != '\n'); + else + RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); + + SkipWhitespace(is); + } + } + } + + // Parse object: { string : value, ... } + template + void ParseObject(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '{'); + is.Take(); // Skip '{' + + if (RAPIDJSON_UNLIKELY(!handler.StartObject())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, '}')) { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType memberCount = 0;;) { + if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); + + ParseString(is, handler, true); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++memberCount; + + switch (is.Peek()) { + case ',': + is.Take(); + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + break; + case '}': + is.Take(); + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + default: + RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy + } + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == '}') { + if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + // Parse array: [ value, ... ] + template + void ParseArray(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == '['); + is.Take(); // Skip '[' + + if (RAPIDJSON_UNLIKELY(!handler.StartArray())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + + for (SizeType elementCount = 0;;) { + ParseValue(is, handler); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + ++elementCount; + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + + if (Consume(is, ',')) { + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + } + else if (Consume(is, ']')) { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + return; + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); + + if (parseFlags & kParseTrailingCommasFlag) { + if (is.Peek() == ']') { + if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + is.Take(); + return; + } + } + } + } + + template + void ParseNull(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'n'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { + if (RAPIDJSON_UNLIKELY(!handler.Null())) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseTrue(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 't'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + void ParseFalse(InputStream& is, Handler& handler) { + RAPIDJSON_ASSERT(is.Peek() == 'f'); + is.Take(); + + if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { + if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + } + + template + RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { + if (RAPIDJSON_LIKELY(is.Peek() == expect)) { + is.Take(); + return true; + } + else + return false; + } + + // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). + template + unsigned ParseHex4(InputStream& is, size_t escapeOffset) { + unsigned codepoint = 0; + for (int i = 0; i < 4; i++) { + Ch c = is.Peek(); + codepoint <<= 4; + codepoint += static_cast(c); + if (c >= '0' && c <= '9') + codepoint -= '0'; + else if (c >= 'A' && c <= 'F') + codepoint -= 'A' - 10; + else if (c >= 'a' && c <= 'f') + codepoint -= 'a' - 10; + else { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); + } + is.Take(); + } + return codepoint; + } + + template + class StackStream { + public: + typedef CharType Ch; + + StackStream(internal::Stack& stack) : stack_(stack), length_(0) {} + RAPIDJSON_FORCEINLINE void Put(Ch c) { + *stack_.template Push() = c; + ++length_; + } + + RAPIDJSON_FORCEINLINE void* Push(SizeType count) { + length_ += count; + return stack_.template Push(count); + } + + size_t Length() const { return length_; } + + Ch* Pop() { + return stack_.template Pop(length_); + } + + private: + StackStream(const StackStream&); + StackStream& operator=(const StackStream&); + + internal::Stack& stack_; + SizeType length_; + }; + + // Parse string and generate String event. Different code paths for kParseInsituFlag. + template + void ParseString(InputStream& is, Handler& handler, bool isKey = false) { + internal::StreamLocalCopy copy(is); + InputStream& s(copy.s); + + RAPIDJSON_ASSERT(s.Peek() == '\"'); + s.Take(); // Skip '\"' + + bool success = false; + if (parseFlags & kParseInsituFlag) { + typename InputStream::Ch *head = s.PutBegin(); + ParseStringToStream(s, s); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + size_t length = s.PutEnd(head) - 1; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); + } + else { + StackStream stackStream(stack_); + ParseStringToStream(s, stackStream); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + SizeType length = static_cast(stackStream.Length()) - 1; + const typename TargetEncoding::Ch* const str = stackStream.Pop(); + success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); + } + if (RAPIDJSON_UNLIKELY(!success)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); + } + + // Parse string to an output is + // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. + template + RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + static const char escape[256] = { + Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', + Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, + 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, + 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 + }; +#undef Z16 +//!@endcond + + for (;;) { + // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. + if (!(parseFlags & kParseValidateEncodingFlag)) + ScanCopyUnescapedString(is, os); + + Ch c = is.Peek(); + if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape + size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset + is.Take(); + Ch e = is.Peek(); + if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast(e)])) { + is.Take(); + os.Put(static_cast(escape[static_cast(e)])); + } + else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode + is.Take(); + unsigned codepoint = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) { + // Handle UTF-16 surrogate pair + if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + unsigned codepoint2 = ParseHex4(is, escapeOffset); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; + if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) + RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); + codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; + } + TEncoding::Encode(os, codepoint); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); + } + else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote + is.Take(); + os.Put('\0'); // null-terminate the string + return; + } + else if (RAPIDJSON_UNLIKELY(static_cast(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + if (c == '\0') + RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); + else + RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell()); + } + else { + size_t offset = is.Tell(); + if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? + !Transcoder::Validate(is, os) : + !Transcoder::Transcode(is, os)))) + RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); + } + } + } + + template + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { + // Do nothing for generic version + } + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + // StringStream -> StackStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream& os) { + const char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + return; + } + else + os.Put(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType length; + #ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; + #else + length = static_cast(__builtin_ffs(r) - 1); + #endif + char* q = reinterpret_cast(os.Push(length)); + for (size_t i = 0; i < length; i++) + q[i] = p[i]; + + p += length; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); + } + + is.src_ = p; + } + + // InsituStringStream -> InsituStringStream + static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { + RAPIDJSON_ASSERT(&is == &os); + (void)os; + + if (is.src_ == is.dst_) { + SkipUnescapedString(is); + return; + } + + char* p = is.src_; + char *q = is.dst_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + while (p != nextAligned) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = p; + is.dst_ = q; + return; + } + else + *q++ = *p++; + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16, q += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + for (const char* pend = p + length; p != pend; ) + *q++ = *p++; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); + } + + is.src_ = p; + is.dst_ = q; + } + + // When read/write pointers are the same for insitu stream, just skip unescaped characters + static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { + RAPIDJSON_ASSERT(is.src_ == is.dst_); + char* p = is.src_; + + // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + for (; p != nextAligned; p++) + if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast(*p) < 0x20)) { + is.src_ = is.dst_ = p; + return; + } + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (;; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + size_t length; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + length = offset; +#else + length = static_cast(__builtin_ffs(r) - 1); +#endif + p += length; + break; + } + } + + is.src_ = is.dst_ = p; + } +#endif + + template + class NumberStream; + + template + class NumberStream { + public: + typedef typename InputStream::Ch Ch; + + NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } + RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } + RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } + RAPIDJSON_FORCEINLINE void Push(char) {} + + size_t Tell() { return is.Tell(); } + size_t Length() { return 0; } + const char* Pop() { return 0; } + + protected: + NumberStream& operator=(const NumberStream&); + + InputStream& is; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch TakePush() { + stackStream.Put(static_cast(Base::is.Peek())); + return Base::is.Take(); + } + + RAPIDJSON_FORCEINLINE void Push(char c) { + stackStream.Put(c); + } + + size_t Length() { return stackStream.Length(); } + + const char* Pop() { + stackStream.Put('\0'); + return stackStream.Pop(); + } + + private: + StackStream stackStream; + }; + + template + class NumberStream : public NumberStream { + typedef NumberStream Base; + public: + NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} + ~NumberStream() {} + + RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } + }; + + template + void ParseNumber(InputStream& is, Handler& handler) { + internal::StreamLocalCopy copy(is); + NumberStream s(*this, copy.s); + + size_t startOffset = s.Tell(); + double d = 0.0; + bool useNanOrInf = false; + + // Parse minus + bool minus = Consume(s, '-'); + + // Parse int: zero / ( digit1-9 *DIGIT ) + unsigned i = 0; + uint64_t i64 = 0; + bool use64bit = false; + int significandDigit = 0; + if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { + i = 0; + s.TakePush(); + } + else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { + i = static_cast(s.TakePush() - '0'); + + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 + if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 + if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { + i64 = i; + use64bit = true; + break; + } + } + i = i * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + // Parse NaN or Infinity here + else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { + useNanOrInf = true; + if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) { + d = std::numeric_limits::quiet_NaN(); + } + else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { + d = (minus ? -std::numeric_limits::infinity() : std::numeric_limits::infinity()); + if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') + && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); + + // Parse 64bit int + bool useDouble = false; + if (use64bit) { + if (minus) + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + else + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 + if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { + d = static_cast(i64); + useDouble = true; + break; + } + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + significandDigit++; + } + } + + // Force double for big integer + if (useDouble) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0 + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + d = d * 10 + (s.TakePush() - '0'); + } + } + + // Parse frac = decimal-point 1*DIGIT + int expFrac = 0; + size_t decimalPosition; + if (Consume(s, '.')) { + decimalPosition = s.Length(); + + if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); + + if (!useDouble) { +#if RAPIDJSON_64BIT + // Use i64 to store significand in 64-bit architecture + if (!use64bit) + i64 = i; + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path + break; + else { + i64 = i64 * 10 + static_cast(s.TakePush() - '0'); + --expFrac; + if (i64 != 0) + significandDigit++; + } + } + + d = static_cast(i64); +#else + // Use double to store significand in 32-bit architecture + d = static_cast(use64bit ? i64 : i); +#endif + useDouble = true; + } + + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + if (significandDigit < 17) { + d = d * 10.0 + (s.TakePush() - '0'); + --expFrac; + if (RAPIDJSON_LIKELY(d > 0.0)) + significandDigit++; + } + else + s.TakePush(); + } + } + else + decimalPosition = s.Length(); // decimal position at the end of integer. + + // Parse exp = e [ minus / plus ] 1*DIGIT + int exp = 0; + if (Consume(s, 'e') || Consume(s, 'E')) { + if (!useDouble) { + d = static_cast(use64bit ? i64 : i); + useDouble = true; + } + + bool expMinus = false; + if (Consume(s, '+')) + ; + else if (Consume(s, '-')) + expMinus = true; + + if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = static_cast(s.Take() - '0'); + if (expMinus) { + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (exp >= 214748364) { // Issue #313: prevent overflow exponent + while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent + s.Take(); + } + } + } + else { // positive exp + int maxExp = 308 - expFrac; + while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { + exp = exp * 10 + static_cast(s.Take() - '0'); + if (RAPIDJSON_UNLIKELY(exp > maxExp)) + RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); + } + } + } + else + RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); + + if (expMinus) + exp = -exp; + } + + // Finish parsing, call event according to the type of number. + bool cont = true; + + if (parseFlags & kParseNumbersAsStringsFlag) { + if (parseFlags & kParseInsituFlag) { + s.Pop(); // Pop stack no matter if it will be used or not. + typename InputStream::Ch* head = is.PutBegin(); + const size_t length = s.Tell() - startOffset; + RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); + // unable to insert the \0 character here, it will erase the comma after this number + const typename TargetEncoding::Ch* const str = reinterpret_cast(head); + cont = handler.RawNumber(str, SizeType(length), false); + } + else { + SizeType numCharsToCopy = static_cast(s.Length()); + StringStream srcStream(s.Pop()); + StackStream dstStream(stack_); + while (numCharsToCopy--) { + Transcoder, TargetEncoding>::Transcode(srcStream, dstStream); + } + dstStream.Put('\0'); + const typename TargetEncoding::Ch* str = dstStream.Pop(); + const SizeType length = static_cast(dstStream.Length()) - 1; + cont = handler.RawNumber(str, SizeType(length), true); + } + } + else { + size_t length = s.Length(); + const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. + + if (useDouble) { + int p = exp + expFrac; + if (parseFlags & kParseFullPrecisionFlag) + d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); + else + d = internal::StrtodNormalPrecision(d, p); + + cont = handler.Double(minus ? -d : d); + } + else if (useNanOrInf) { + cont = handler.Double(d); + } + else { + if (use64bit) { + if (minus) + cont = handler.Int64(static_cast(~i64 + 1)); + else + cont = handler.Uint64(i64); + } + else { + if (minus) + cont = handler.Int(static_cast(~i + 1)); + else + cont = handler.Uint(i); + } + } + } + if (RAPIDJSON_UNLIKELY(!cont)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); + } + + // Parse any JSON value + template + void ParseValue(InputStream& is, Handler& handler) { + switch (is.Peek()) { + case 'n': ParseNull (is, handler); break; + case 't': ParseTrue (is, handler); break; + case 'f': ParseFalse (is, handler); break; + case '"': ParseString(is, handler); break; + case '{': ParseObject(is, handler); break; + case '[': ParseArray (is, handler); break; + default : + ParseNumber(is, handler); + break; + + } + } + + // Iterative Parsing + + // States + enum IterativeParsingState { + IterativeParsingStartState = 0, + IterativeParsingFinishState, + IterativeParsingErrorState, + + // Object states + IterativeParsingObjectInitialState, + IterativeParsingMemberKeyState, + IterativeParsingKeyValueDelimiterState, + IterativeParsingMemberValueState, + IterativeParsingMemberDelimiterState, + IterativeParsingObjectFinishState, + + // Array states + IterativeParsingArrayInitialState, + IterativeParsingElementState, + IterativeParsingElementDelimiterState, + IterativeParsingArrayFinishState, + + // Single value state + IterativeParsingValueState + }; + + enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 }; + + // Tokens + enum Token { + LeftBracketToken = 0, + RightBracketToken, + + LeftCurlyBracketToken, + RightCurlyBracketToken, + + CommaToken, + ColonToken, + + StringToken, + FalseToken, + TrueToken, + NullToken, + NumberToken, + + kTokenCount + }; + + RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { + +//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN +#define N NumberToken +#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N + // Maps from ASCII to Token + static const unsigned char tokenMap[256] = { + N16, // 00~0F + N16, // 10~1F + N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F + N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F + N16, // 40~4F + N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F + N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F + N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F + N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF + }; +#undef N +#undef N16 +//!@endcond + + if (sizeof(Ch) == 1 || static_cast(c) < 256) + return static_cast(tokenMap[static_cast(c)]); + else + return NumberToken; + } + + RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { + // current state x one lookahead token -> new state + static const char G[cIterativeParsingStateCount][kTokenCount] = { + // Start + { + IterativeParsingArrayInitialState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number + }, + // Finish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Error(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ObjectInitial + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberKey + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingKeyValueDelimiterState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // KeyValueDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) + IterativeParsingErrorState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberValueState, // String + IterativeParsingMemberValueState, // False + IterativeParsingMemberValueState, // True + IterativeParsingMemberValueState, // Null + IterativeParsingMemberValueState // Number + }, + // MemberValue + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingMemberDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // MemberDelimiter + { + IterativeParsingErrorState, // Left bracket + IterativeParsingErrorState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingObjectFinishState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingMemberKeyState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ObjectFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // ArrayInitial + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // Element + { + IterativeParsingErrorState, // Left bracket + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingErrorState, // Left curly bracket + IterativeParsingErrorState, // Right curly bracket + IterativeParsingElementDelimiterState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingErrorState, // String + IterativeParsingErrorState, // False + IterativeParsingErrorState, // True + IterativeParsingErrorState, // Null + IterativeParsingErrorState // Number + }, + // ElementDelimiter + { + IterativeParsingArrayInitialState, // Left bracket(push Element state) + IterativeParsingArrayFinishState, // Right bracket + IterativeParsingObjectInitialState, // Left curly bracket(push Element state) + IterativeParsingErrorState, // Right curly bracket + IterativeParsingErrorState, // Comma + IterativeParsingErrorState, // Colon + IterativeParsingElementState, // String + IterativeParsingElementState, // False + IterativeParsingElementState, // True + IterativeParsingElementState, // Null + IterativeParsingElementState // Number + }, + // ArrayFinish(sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState + } + }; // End of G + + return static_cast(G[state][token]); + } + + // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). + // May return a new state on state pop. + template + RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { + (void)token; + + switch (dst) { + case IterativeParsingErrorState: + return dst; + + case IterativeParsingObjectInitialState: + case IterativeParsingArrayInitialState: + { + // Push the state(Element or MemeberValue) if we are nested in another array or value of member. + // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. + IterativeParsingState n = src; + if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) + n = IterativeParsingElementState; + else if (src == IterativeParsingKeyValueDelimiterState) + n = IterativeParsingMemberValueState; + // Push current state. + *stack_.template Push(1) = n; + // Initialize and push the member/element count. + *stack_.template Push(1) = 0; + // Call handler + bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return dst; + } + } + + case IterativeParsingMemberKeyState: + ParseString(is, handler, true); + if (HasParseError()) + return IterativeParsingErrorState; + else + return dst; + + case IterativeParsingKeyValueDelimiterState: + RAPIDJSON_ASSERT(token == ColonToken); + is.Take(); + return dst; + + case IterativeParsingMemberValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingElementState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return dst; + + case IterativeParsingMemberDelimiterState: + case IterativeParsingElementDelimiterState: + is.Take(); + // Update member/element count. + *stack_.template Top() = *stack_.template Top() + 1; + return dst; + + case IterativeParsingObjectFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); + return IterativeParsingErrorState; + } + // Get member count. + SizeType c = *stack_.template Pop(1); + // If the object is not empty, count the last member. + if (src == IterativeParsingMemberValueState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndObject(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + case IterativeParsingArrayFinishState: + { + // Transit from delimiter is only allowed when trailing commas are enabled + if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); + return IterativeParsingErrorState; + } + // Get element count. + SizeType c = *stack_.template Pop(1); + // If the array is not empty, count the last element. + if (src == IterativeParsingElementState) + ++c; + // Restore the state. + IterativeParsingState n = static_cast(*stack_.template Pop(1)); + // Transit to Finish state if this is the topmost scope. + if (n == IterativeParsingStartState) + n = IterativeParsingFinishState; + // Call handler + bool hr = handler.EndArray(c); + // On handler short circuits the parsing. + if (!hr) { + RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); + return IterativeParsingErrorState; + } + else { + is.Take(); + return n; + } + } + + default: + // This branch is for IterativeParsingValueState actually. + // Use `default:` rather than + // `case IterativeParsingValueState:` is for code coverage. + + // The IterativeParsingStartState is not enumerated in this switch-case. + // It is impossible for that case. And it can be caught by following assertion. + + // The IterativeParsingFinishState is not enumerated in this switch-case either. + // It is a "derivative" state which cannot triggered from Predict() directly. + // Therefore it cannot happen here. And it can be caught by following assertion. + RAPIDJSON_ASSERT(dst == IterativeParsingValueState); + + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + } + } + + template + void HandleError(IterativeParsingState src, InputStream& is) { + if (HasParseError()) { + // Error flag has been set. + return; + } + + switch (src) { + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; + case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; + case IterativeParsingObjectInitialState: + case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; + case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; + case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; + case IterativeParsingKeyValueDelimiterState: + case IterativeParsingArrayInitialState: + case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; + default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; + } + } + + template + ParseResult IterativeParse(InputStream& is, Handler& handler) { + parseResult_.Clear(); + ClearStackOnExit scope(*this); + IterativeParsingState state = IterativeParsingStartState; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + while (is.Peek() != '\0') { + Token t = Tokenize(is.Peek()); + IterativeParsingState n = Predict(state, t); + IterativeParsingState d = Transit(state, t, n, is, handler); + + if (d == IterativeParsingErrorState) { + HandleError(state, is); + break; + } + + state = d; + + // Do not further consume streams if a root JSON has been parsed. + if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) + break; + + SkipWhitespaceAndComments(is); + RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); + } + + // Handle the end of file. + if (state != IterativeParsingFinishState) + HandleError(state, is); + + return parseResult_; + } + + static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. + internal::Stack stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. + ParseResult parseResult_; +}; // class GenericReader + +//! Reader with UTF8 encoding and default allocator. +typedef GenericReader, UTF8<> > Reader; + +RAPIDJSON_NAMESPACE_END + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + + +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_READER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/schema.h b/src/third-party/discord-rpc/include/rapidjson/schema.h new file mode 100644 index 000000000..b182aa27f --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/schema.h @@ -0,0 +1,2006 @@ +// Tencent is pleased to support the open source community by making RapidJSON available-> +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved-> +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License-> You may obtain a copy of the License at +// +// http://opensource->org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied-> See the License for the +// specific language governing permissions and limitations under the License-> + +#ifndef RAPIDJSON_SCHEMA_H_ +#define RAPIDJSON_SCHEMA_H_ + +#include "document.h" +#include "pointer.h" +#include // abs, floor + +#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX) +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0 +#endif + +#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)) +#define RAPIDJSON_SCHEMA_USE_STDREGEX 1 +#else +#define RAPIDJSON_SCHEMA_USE_STDREGEX 0 +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX +#include "internal/regex.h" +#elif RAPIDJSON_SCHEMA_USE_STDREGEX +#include +#endif + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX +#define RAPIDJSON_SCHEMA_HAS_REGEX 1 +#else +#define RAPIDJSON_SCHEMA_HAS_REGEX 0 +#endif + +#ifndef RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_VERBOSE 0 +#endif + +#if RAPIDJSON_SCHEMA_VERBOSE +#include "stringbuffer.h" +#endif + +RAPIDJSON_DIAG_PUSH + +#if defined(__GNUC__) +RAPIDJSON_DIAG_OFF(effc++) +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_OFF(weak-vtables) +RAPIDJSON_DIAG_OFF(exit-time-destructors) +RAPIDJSON_DIAG_OFF(c++98-compat-pedantic) +RAPIDJSON_DIAG_OFF(variadic-macros) +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Verbose Utilities + +#if RAPIDJSON_SCHEMA_VERBOSE + +namespace internal { + +inline void PrintInvalidKeyword(const char* keyword) { + printf("Fail keyword: %s\n", keyword); +} + +inline void PrintInvalidKeyword(const wchar_t* keyword) { + wprintf(L"Fail keyword: %ls\n", keyword); +} + +inline void PrintInvalidDocument(const char* document) { + printf("Fail document: %s\n\n", document); +} + +inline void PrintInvalidDocument(const wchar_t* document) { + wprintf(L"Fail document: %ls\n\n", document); +} + +inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) { + printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d); +} + +inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) { + wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d); +} + +} // namespace internal + +#endif // RAPIDJSON_SCHEMA_VERBOSE + +/////////////////////////////////////////////////////////////////////////////// +// RAPIDJSON_INVALID_KEYWORD_RETURN + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword) +#else +#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) +#endif + +#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + context.invalidKeyword = keyword.GetString();\ + RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\ + return false;\ +RAPIDJSON_MULTILINEMACRO_END + +/////////////////////////////////////////////////////////////////////////////// +// Forward declarations + +template +class GenericSchemaDocument; + +namespace internal { + +template +class Schema; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaValidator + +class ISchemaValidator { +public: + virtual ~ISchemaValidator() {} + virtual bool IsValid() const = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// ISchemaStateFactory + +template +class ISchemaStateFactory { +public: + virtual ~ISchemaStateFactory() {} + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0; + virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0; + virtual void* CreateHasher() = 0; + virtual uint64_t GetHashCode(void* hasher) = 0; + virtual void DestroryHasher(void* hasher) = 0; + virtual void* MallocState(size_t size) = 0; + virtual void FreeState(void* p) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Hasher + +// For comparison of compound value +template +class Hasher { +public: + typedef typename Encoding::Ch Ch; + + Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {} + + bool Null() { return WriteType(kNullType); } + bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); } + bool Int(int i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast(i); return WriteNumber(n); } + bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast(u); return WriteNumber(n); } + bool Double(double d) { + Number n; + if (d < 0) n.u.i = static_cast(d); + else n.u.u = static_cast(d); + n.d = d; + return WriteNumber(n); + } + + bool RawNumber(const Ch* str, SizeType len, bool) { + WriteBuffer(kNumberType, str, len * sizeof(Ch)); + return true; + } + + bool String(const Ch* str, SizeType len, bool) { + WriteBuffer(kStringType, str, len * sizeof(Ch)); + return true; + } + + bool StartObject() { return true; } + bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); } + bool EndObject(SizeType memberCount) { + uint64_t h = Hash(0, kObjectType); + uint64_t* kv = stack_.template Pop(memberCount * 2); + for (SizeType i = 0; i < memberCount; i++) + h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive + *stack_.template Push() = h; + return true; + } + + bool StartArray() { return true; } + bool EndArray(SizeType elementCount) { + uint64_t h = Hash(0, kArrayType); + uint64_t* e = stack_.template Pop(elementCount); + for (SizeType i = 0; i < elementCount; i++) + h = Hash(h, e[i]); // Use hash to achieve element order sensitive + *stack_.template Push() = h; + return true; + } + + bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); } + + uint64_t GetHashCode() const { + RAPIDJSON_ASSERT(IsValid()); + return *stack_.template Top(); + } + +private: + static const size_t kDefaultSize = 256; + struct Number { + union U { + uint64_t u; + int64_t i; + }u; + double d; + }; + + bool WriteType(Type type) { return WriteBuffer(type, 0, 0); } + + bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); } + + bool WriteBuffer(Type type, const void* data, size_t len) { + // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/ + uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type); + const unsigned char* d = static_cast(data); + for (size_t i = 0; i < len; i++) + h = Hash(h, d[i]); + *stack_.template Push() = h; + return true; + } + + static uint64_t Hash(uint64_t h, uint64_t d) { + static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3); + h ^= d; + h *= kPrime; + return h; + } + + Stack stack_; +}; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidationContext + +template +struct SchemaValidationContext { + typedef Schema SchemaType; + typedef ISchemaStateFactory SchemaValidatorFactoryType; + typedef typename SchemaType::ValueType ValueType; + typedef typename ValueType::Ch Ch; + + enum PatternValidatorType { + kPatternValidatorOnly, + kPatternValidatorWithProperty, + kPatternValidatorWithAdditionalProperty + }; + + SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) : + factory(f), + schema(s), + valueSchema(), + invalidKeyword(), + hasher(), + arrayElementHashCodes(), + validators(), + validatorCount(), + patternPropertiesValidators(), + patternPropertiesValidatorCount(), + patternPropertiesSchemas(), + patternPropertiesSchemaCount(), + valuePatternValidatorType(kPatternValidatorOnly), + propertyExist(), + inArray(false), + valueUniqueness(false), + arrayUniqueness(false) + { + } + + ~SchemaValidationContext() { + if (hasher) + factory.DestroryHasher(hasher); + if (validators) { + for (SizeType i = 0; i < validatorCount; i++) + factory.DestroySchemaValidator(validators[i]); + factory.FreeState(validators); + } + if (patternPropertiesValidators) { + for (SizeType i = 0; i < patternPropertiesValidatorCount; i++) + factory.DestroySchemaValidator(patternPropertiesValidators[i]); + factory.FreeState(patternPropertiesValidators); + } + if (patternPropertiesSchemas) + factory.FreeState(patternPropertiesSchemas); + if (propertyExist) + factory.FreeState(propertyExist); + } + + SchemaValidatorFactoryType& factory; + const SchemaType* schema; + const SchemaType* valueSchema; + const Ch* invalidKeyword; + void* hasher; // Only validator access + void* arrayElementHashCodes; // Only validator access this + ISchemaValidator** validators; + SizeType validatorCount; + ISchemaValidator** patternPropertiesValidators; + SizeType patternPropertiesValidatorCount; + const SchemaType** patternPropertiesSchemas; + SizeType patternPropertiesSchemaCount; + PatternValidatorType valuePatternValidatorType; + PatternValidatorType objectPatternValidatorType; + SizeType arrayElementIndex; + bool* propertyExist; + bool inArray; + bool valueUniqueness; + bool arrayUniqueness; +}; + +/////////////////////////////////////////////////////////////////////////////// +// Schema + +template +class Schema { +public: + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename SchemaDocumentType::AllocatorType AllocatorType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef SchemaValidationContext Context; + typedef Schema SchemaType; + typedef GenericValue SValue; + friend class GenericSchemaDocument; + + Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) : + allocator_(allocator), + enum_(), + enumCount_(), + not_(), + type_((1 << kTotalSchemaType) - 1), // typeless + validatorCount_(), + properties_(), + additionalPropertiesSchema_(), + patternProperties_(), + patternPropertyCount_(), + propertyCount_(), + minProperties_(), + maxProperties_(SizeType(~0)), + additionalProperties_(true), + hasDependencies_(), + hasRequired_(), + hasSchemaDependencies_(), + additionalItemsSchema_(), + itemsList_(), + itemsTuple_(), + itemsTupleCount_(), + minItems_(), + maxItems_(SizeType(~0)), + additionalItems_(true), + uniqueItems_(false), + pattern_(), + minLength_(0), + maxLength_(~SizeType(0)), + exclusiveMinimum_(false), + exclusiveMaximum_(false) + { + typedef typename SchemaDocumentType::ValueType ValueType; + typedef typename ValueType::ConstValueIterator ConstValueIterator; + typedef typename ValueType::ConstMemberIterator ConstMemberIterator; + + if (!value.IsObject()) + return; + + if (const ValueType* v = GetMember(value, GetTypeString())) { + type_ = 0; + if (v->IsString()) + AddType(*v); + else if (v->IsArray()) + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) + AddType(*itr); + } + + if (const ValueType* v = GetMember(value, GetEnumString())) + if (v->IsArray() && v->Size() > 0) { + enum_ = static_cast(allocator_->Malloc(sizeof(uint64_t) * v->Size())); + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) { + typedef Hasher > EnumHasherType; + char buffer[256 + 24]; + MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer)); + EnumHasherType h(&hasherAllocator, 256); + itr->Accept(h); + enum_[enumCount_++] = h.GetHashCode(); + } + } + + if (schemaDocument) { + AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document); + AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document); + AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document); + } + + if (const ValueType* v = GetMember(value, GetNotString())) { + schemaDocument->CreateSchema(¬_, p.Append(GetNotString(), allocator_), *v, document); + notValidatorIndex_ = validatorCount_; + validatorCount_++; + } + + // Object + + const ValueType* properties = GetMember(value, GetPropertiesString()); + const ValueType* required = GetMember(value, GetRequiredString()); + const ValueType* dependencies = GetMember(value, GetDependenciesString()); + { + // Gather properties from properties/required/dependencies + SValue allProperties(kArrayType); + + if (properties && properties->IsObject()) + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) + AddUniqueElement(allProperties, itr->name); + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) + AddUniqueElement(allProperties, *itr); + + if (dependencies && dependencies->IsObject()) + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + AddUniqueElement(allProperties, itr->name); + if (itr->value.IsArray()) + for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i) + if (i->IsString()) + AddUniqueElement(allProperties, *i); + } + + if (allProperties.Size() > 0) { + propertyCount_ = allProperties.Size(); + properties_ = static_cast(allocator_->Malloc(sizeof(Property) * propertyCount_)); + for (SizeType i = 0; i < propertyCount_; i++) { + new (&properties_[i]) Property(); + properties_[i].name = allProperties[i]; + properties_[i].schema = GetTypeless(); + } + } + } + + if (properties && properties->IsObject()) { + PointerType q = p.Append(GetPropertiesString(), allocator_); + for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) { + SizeType index; + if (FindPropertyIndex(itr->name, &index)) + schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document); + } + } + + if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) { + PointerType q = p.Append(GetPatternPropertiesString(), allocator_); + patternProperties_ = static_cast(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount())); + patternPropertyCount_ = 0; + + for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) { + new (&patternProperties_[patternPropertyCount_]) PatternProperty(); + patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name); + schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document); + patternPropertyCount_++; + } + } + + if (required && required->IsArray()) + for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr) + if (itr->IsString()) { + SizeType index; + if (FindPropertyIndex(*itr, &index)) { + properties_[index].required = true; + hasRequired_ = true; + } + } + + if (dependencies && dependencies->IsObject()) { + PointerType q = p.Append(GetDependenciesString(), allocator_); + hasDependencies_ = true; + for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) { + SizeType sourceIndex; + if (FindPropertyIndex(itr->name, &sourceIndex)) { + if (itr->value.IsArray()) { + properties_[sourceIndex].dependencies = static_cast(allocator_->Malloc(sizeof(bool) * propertyCount_)); + std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_); + for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) { + SizeType targetIndex; + if (FindPropertyIndex(*targetItr, &targetIndex)) + properties_[sourceIndex].dependencies[targetIndex] = true; + } + } + else if (itr->value.IsObject()) { + hasSchemaDependencies_ = true; + schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document); + properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_; + validatorCount_++; + } + } + } + } + + if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) { + if (v->IsBool()) + additionalProperties_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document); + } + + AssignIfExist(minProperties_, value, GetMinPropertiesString()); + AssignIfExist(maxProperties_, value, GetMaxPropertiesString()); + + // Array + if (const ValueType* v = GetMember(value, GetItemsString())) { + PointerType q = p.Append(GetItemsString(), allocator_); + if (v->IsObject()) // List validation + schemaDocument->CreateSchema(&itemsList_, q, *v, document); + else if (v->IsArray()) { // Tuple validation + itemsTuple_ = static_cast(allocator_->Malloc(sizeof(const Schema*) * v->Size())); + SizeType index = 0; + for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++) + schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document); + } + } + + AssignIfExist(minItems_, value, GetMinItemsString()); + AssignIfExist(maxItems_, value, GetMaxItemsString()); + + if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) { + if (v->IsBool()) + additionalItems_ = v->GetBool(); + else if (v->IsObject()) + schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document); + } + + AssignIfExist(uniqueItems_, value, GetUniqueItemsString()); + + // String + AssignIfExist(minLength_, value, GetMinLengthString()); + AssignIfExist(maxLength_, value, GetMaxLengthString()); + + if (const ValueType* v = GetMember(value, GetPatternString())) + pattern_ = CreatePattern(*v); + + // Number + if (const ValueType* v = GetMember(value, GetMinimumString())) + if (v->IsNumber()) + minimum_.CopyFrom(*v, *allocator_); + + if (const ValueType* v = GetMember(value, GetMaximumString())) + if (v->IsNumber()) + maximum_.CopyFrom(*v, *allocator_); + + AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString()); + AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString()); + + if (const ValueType* v = GetMember(value, GetMultipleOfString())) + if (v->IsNumber() && v->GetDouble() > 0.0) + multipleOf_.CopyFrom(*v, *allocator_); + } + + ~Schema() { + if (allocator_) { + allocator_->Free(enum_); + } + if (properties_) { + for (SizeType i = 0; i < propertyCount_; i++) + properties_[i].~Property(); + AllocatorType::Free(properties_); + } + if (patternProperties_) { + for (SizeType i = 0; i < patternPropertyCount_; i++) + patternProperties_[i].~PatternProperty(); + AllocatorType::Free(patternProperties_); + } + AllocatorType::Free(itemsTuple_); +#if RAPIDJSON_SCHEMA_HAS_REGEX + if (pattern_) { + pattern_->~RegexType(); + allocator_->Free(pattern_); + } +#endif + } + + bool BeginValue(Context& context) const { + if (context.inArray) { + if (uniqueItems_) + context.valueUniqueness = true; + + if (itemsList_) + context.valueSchema = itemsList_; + else if (itemsTuple_) { + if (context.arrayElementIndex < itemsTupleCount_) + context.valueSchema = itemsTuple_[context.arrayElementIndex]; + else if (additionalItemsSchema_) + context.valueSchema = additionalItemsSchema_; + else if (additionalItems_) + context.valueSchema = GetTypeless(); + else + RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString()); + } + else + context.valueSchema = GetTypeless(); + + context.arrayElementIndex++; + } + return true; + } + + RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const { + if (context.patternPropertiesValidatorCount > 0) { + bool otherValid = false; + SizeType count = context.patternPropertiesValidatorCount; + if (context.objectPatternValidatorType != Context::kPatternValidatorOnly) + otherValid = context.patternPropertiesValidators[--count]->IsValid(); + + bool patternValid = true; + for (SizeType i = 0; i < count; i++) + if (!context.patternPropertiesValidators[i]->IsValid()) { + patternValid = false; + break; + } + + if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) { + if (!patternValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) { + if (!patternValid || !otherValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString()); + } + + if (enum_) { + const uint64_t h = context.factory.GetHashCode(context.hasher); + for (SizeType i = 0; i < enumCount_; i++) + if (enum_[i] == h) + goto foundEnum; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString()); + foundEnum:; + } + + if (allOf_.schemas) + for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++) + if (!context.validators[i]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString()); + + if (anyOf_.schemas) { + for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++) + if (context.validators[i]->IsValid()) + goto foundAny; + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString()); + foundAny:; + } + + if (oneOf_.schemas) { + bool oneValid = false; + for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++) + if (context.validators[i]->IsValid()) { + if (oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + else + oneValid = true; + } + if (!oneValid) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString()); + } + + if (not_ && context.validators[notValidatorIndex_]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString()); + + return true; + } + + bool Null(Context& context) const { + if (!(type_ & (1 << kNullSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Bool(Context& context, bool) const { + if (!(type_ & (1 << kBooleanSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + return CreateParallelValidator(context); + } + + bool Int(Context& context, int i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint(Context& context, unsigned u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Int64(Context& context, int64_t i) const { + if (!CheckInt(context, i)) + return false; + return CreateParallelValidator(context); + } + + bool Uint64(Context& context, uint64_t u) const { + if (!CheckUint(context, u)) + return false; + return CreateParallelValidator(context); + } + + bool Double(Context& context, double d) const { + if (!(type_ & (1 << kNumberSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d)) + return false; + + if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d)) + return false; + + if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d)) + return false; + + return CreateParallelValidator(context); + } + + bool String(Context& context, const Ch* str, SizeType length, bool) const { + if (!(type_ & (1 << kStringSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (minLength_ != 0 || maxLength_ != SizeType(~0)) { + SizeType count; + if (internal::CountStringCodePoint(str, length, &count)) { + if (count < minLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString()); + if (count > maxLength_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString()); + } + } + + if (pattern_ && !IsPatternMatch(pattern_, str, length)) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString()); + + return CreateParallelValidator(context); + } + + bool StartObject(Context& context) const { + if (!(type_ & (1 << kObjectSchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (hasDependencies_ || hasRequired_) { + context.propertyExist = static_cast(context.factory.MallocState(sizeof(bool) * propertyCount_)); + std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_); + } + + if (patternProperties_) { // pre-allocate schema array + SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType + context.patternPropertiesSchemas = static_cast(context.factory.MallocState(sizeof(const SchemaType*) * count)); + context.patternPropertiesSchemaCount = 0; + std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count); + } + + return CreateParallelValidator(context); + } + + bool Key(Context& context, const Ch* str, SizeType len, bool) const { + if (patternProperties_) { + context.patternPropertiesSchemaCount = 0; + for (SizeType i = 0; i < patternPropertyCount_; i++) + if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema; + } + + SizeType index; + if (FindPropertyIndex(ValueType(str, len).Move(), &index)) { + if (context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithProperty; + } + else + context.valueSchema = properties_[index].schema; + + if (context.propertyExist) + context.propertyExist[index] = true; + + return true; + } + + if (additionalPropertiesSchema_) { + if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) { + context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_; + context.valueSchema = GetTypeless(); + context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty; + } + else + context.valueSchema = additionalPropertiesSchema_; + return true; + } + else if (additionalProperties_) { + context.valueSchema = GetTypeless(); + return true; + } + + if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties + RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString()); + + return true; + } + + bool EndObject(Context& context, SizeType memberCount) const { + if (hasRequired_) + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].required) + if (!context.propertyExist[index]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString()); + + if (memberCount < minProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString()); + + if (memberCount > maxProperties_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString()); + + if (hasDependencies_) { + for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++) + if (context.propertyExist[sourceIndex]) { + if (properties_[sourceIndex].dependencies) { + for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++) + if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex]) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + else if (properties_[sourceIndex].dependenciesSchema) + if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString()); + } + } + + return true; + } + + bool StartArray(Context& context) const { + if (!(type_ & (1 << kArraySchemaType))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + context.arrayElementIndex = 0; + context.inArray = true; + + return CreateParallelValidator(context); + } + + bool EndArray(Context& context, SizeType elementCount) const { + context.inArray = false; + + if (elementCount < minItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString()); + + if (elementCount > maxItems_) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString()); + + return true; + } + + // Generate functions for string literal according to Ch +#define RAPIDJSON_STRING_(name, ...) \ + static const ValueType& Get##name##String() {\ + static const Ch s[] = { __VA_ARGS__, '\0' };\ + static const ValueType v(s, sizeof(s) / sizeof(Ch) - 1);\ + return v;\ + } + + RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l') + RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n') + RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't') + RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y') + RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g') + RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r') + RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r') + RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e') + RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm') + RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f') + RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f') + RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f') + RAPIDJSON_STRING_(Not, 'n', 'o', 't') + RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd') + RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's') + RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's') + RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's') + RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h') + RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n') + RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm') + RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f') + +#undef RAPIDJSON_STRING_ + +private: + enum SchemaValueType { + kNullSchemaType, + kBooleanSchemaType, + kObjectSchemaType, + kArraySchemaType, + kStringSchemaType, + kNumberSchemaType, + kIntegerSchemaType, + kTotalSchemaType + }; + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + typedef internal::GenericRegex RegexType; +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + typedef std::basic_regex RegexType; +#else + typedef char RegexType; +#endif + + struct SchemaArray { + SchemaArray() : schemas(), count() {} + ~SchemaArray() { AllocatorType::Free(schemas); } + const SchemaType** schemas; + SizeType begin; // begin index of context.validators + SizeType count; + }; + + static const SchemaType* GetTypeless() { + static SchemaType typeless(0, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0); + return &typeless; + } + + template + void AddUniqueElement(V1& a, const V2& v) { + for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) + if (*itr == v) + return; + V1 c(v, *allocator_); + a.PushBack(c, *allocator_); + } + + static const ValueType* GetMember(const ValueType& value, const ValueType& name) { + typename ValueType::ConstMemberIterator itr = value.FindMember(name); + return itr != value.MemberEnd() ? &(itr->value) : 0; + } + + static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsBool()) + out = v->GetBool(); + } + + static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) { + if (const ValueType* v = GetMember(value, name)) + if (v->IsUint64() && v->GetUint64() <= SizeType(~0)) + out = static_cast(v->GetUint64()); + } + + void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) { + if (const ValueType* v = GetMember(value, name)) { + if (v->IsArray() && v->Size() > 0) { + PointerType q = p.Append(name, allocator_); + out.count = v->Size(); + out.schemas = static_cast(allocator_->Malloc(out.count * sizeof(const Schema*))); + memset(out.schemas, 0, sizeof(Schema*)* out.count); + for (SizeType i = 0; i < out.count; i++) + schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document); + out.begin = validatorCount_; + validatorCount_ += out.count; + } + } + } + +#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) { + RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString()); + if (!r->IsValid()) { + r->~RegexType(); + AllocatorType::Free(r); + r = 0; + } + return r; + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) { + return pattern->Search(str); + } +#elif RAPIDJSON_SCHEMA_USE_STDREGEX + template + RegexType* CreatePattern(const ValueType& value) { + if (value.IsString()) + try { + return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript); + } + catch (const std::regex_error&) { + } + return 0; + } + + static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) { + std::match_results r; + return std::regex_search(str, str + length, r, *pattern); + } +#else + template + RegexType* CreatePattern(const ValueType&) { return 0; } + + static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; } +#endif // RAPIDJSON_SCHEMA_USE_STDREGEX + + void AddType(const ValueType& type) { + if (type == GetNullString() ) type_ |= 1 << kNullSchemaType; + else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType; + else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType; + else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType; + else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType; + else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType; + else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType); + } + + bool CreateParallelValidator(Context& context) const { + if (enum_ || context.arrayUniqueness) + context.hasher = context.factory.CreateHasher(); + + if (validatorCount_) { + RAPIDJSON_ASSERT(context.validators == 0); + context.validators = static_cast(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_)); + context.validatorCount = validatorCount_; + + if (allOf_.schemas) + CreateSchemaValidators(context, allOf_); + + if (anyOf_.schemas) + CreateSchemaValidators(context, anyOf_); + + if (oneOf_.schemas) + CreateSchemaValidators(context, oneOf_); + + if (not_) + context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_); + + if (hasSchemaDependencies_) { + for (SizeType i = 0; i < propertyCount_; i++) + if (properties_[i].dependenciesSchema) + context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema); + } + } + + return true; + } + + void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const { + for (SizeType i = 0; i < schemas.count; i++) + context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]); + } + + // O(n) + bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const { + SizeType len = name.GetStringLength(); + const Ch* str = name.GetString(); + for (SizeType index = 0; index < propertyCount_; index++) + if (properties_[index].name.GetStringLength() == len && + (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0)) + { + *outIndex = index; + return true; + } + return false; + } + + bool CheckInt(Context& context, int64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsInt64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsUint64()) { + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64() + } + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsInt64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsUint64()) + /* do nothing */; // i <= max(int64_t) < maximum_.GetUint64() + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (static_cast(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckUint(Context& context, uint64_t i) const { + if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType)))) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString()); + + if (!minimum_.IsNull()) { + if (minimum_.IsUint64()) { + if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + } + else if (minimum_.IsInt64()) + /* do nothing */; // i >= 0 > minimum.Getint64() + else if (!CheckDoubleMinimum(context, static_cast(i))) + return false; + } + + if (!maximum_.IsNull()) { + if (maximum_.IsUint64()) { + if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + } + else if (maximum_.IsInt64()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_ + else if (!CheckDoubleMaximum(context, static_cast(i))) + return false; + } + + if (!multipleOf_.IsNull()) { + if (multipleOf_.IsUint64()) { + if (i % multipleOf_.GetUint64() != 0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + } + else if (!CheckDoubleMultipleOf(context, static_cast(i))) + return false; + } + + return true; + } + + bool CheckDoubleMinimum(Context& context, double d) const { + if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); + return true; + } + + bool CheckDoubleMaximum(Context& context, double d) const { + if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble()) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); + return true; + } + + bool CheckDoubleMultipleOf(Context& context, double d) const { + double a = std::abs(d), b = std::abs(multipleOf_.GetDouble()); + double q = std::floor(a / b); + double r = a - q * b; + if (r > 0.0) + RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString()); + return true; + } + + struct Property { + Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {} + ~Property() { AllocatorType::Free(dependencies); } + SValue name; + const SchemaType* schema; + const SchemaType* dependenciesSchema; + SizeType dependenciesValidatorIndex; + bool* dependencies; + bool required; + }; + + struct PatternProperty { + PatternProperty() : schema(), pattern() {} + ~PatternProperty() { + if (pattern) { + pattern->~RegexType(); + AllocatorType::Free(pattern); + } + } + const SchemaType* schema; + RegexType* pattern; + }; + + AllocatorType* allocator_; + uint64_t* enum_; + SizeType enumCount_; + SchemaArray allOf_; + SchemaArray anyOf_; + SchemaArray oneOf_; + const SchemaType* not_; + unsigned type_; // bitmask of kSchemaType + SizeType validatorCount_; + SizeType notValidatorIndex_; + + Property* properties_; + const SchemaType* additionalPropertiesSchema_; + PatternProperty* patternProperties_; + SizeType patternPropertyCount_; + SizeType propertyCount_; + SizeType minProperties_; + SizeType maxProperties_; + bool additionalProperties_; + bool hasDependencies_; + bool hasRequired_; + bool hasSchemaDependencies_; + + const SchemaType* additionalItemsSchema_; + const SchemaType* itemsList_; + const SchemaType** itemsTuple_; + SizeType itemsTupleCount_; + SizeType minItems_; + SizeType maxItems_; + bool additionalItems_; + bool uniqueItems_; + + RegexType* pattern_; + SizeType minLength_; + SizeType maxLength_; + + SValue minimum_; + SValue maximum_; + SValue multipleOf_; + bool exclusiveMinimum_; + bool exclusiveMaximum_; +}; + +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + *documentStack.template Push() = '/'; + char buffer[21]; + size_t length = static_cast((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer); + for (size_t i = 0; i < length; i++) + *documentStack.template Push() = buffer[i]; + } +}; + +// Partial specialized version for char to prevent buffer copying. +template +struct TokenHelper { + RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) { + if (sizeof(SizeType) == 4) { + char *buffer = documentStack.template Push(1 + 10); // '/' + uint + *buffer++ = '/'; + const char* end = internal::u32toa(index, buffer); + documentStack.template Pop(static_cast(10 - (end - buffer))); + } + else { + char *buffer = documentStack.template Push(1 + 20); // '/' + uint64 + *buffer++ = '/'; + const char* end = internal::u64toa(index, buffer); + documentStack.template Pop(static_cast(20 - (end - buffer))); + } + } +}; + +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// +// IGenericRemoteSchemaDocumentProvider + +template +class IGenericRemoteSchemaDocumentProvider { +public: + typedef typename SchemaDocumentType::Ch Ch; + + virtual ~IGenericRemoteSchemaDocumentProvider() {} + virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0; +}; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaDocument + +//! JSON schema document. +/*! + A JSON schema document is a compiled version of a JSON schema. + It is basically a tree of internal::Schema. + + \note This is an immutable class (i.e. its instance cannot be modified after construction). + \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding. + \tparam Allocator Allocator type for allocating memory of this document. +*/ +template +class GenericSchemaDocument { +public: + typedef ValueT ValueType; + typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProviderType; + typedef Allocator AllocatorType; + typedef typename ValueType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + typedef internal::Schema SchemaType; + typedef GenericPointer PointerType; + friend class internal::Schema; + template + friend class GenericSchemaValidator; + + //! Constructor. + /*! + Compile a JSON document into schema document. + + \param document A JSON document as source. + \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null. + \param allocator An optional allocator instance for allocating memory. Can be null. + */ + explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) : + remoteProvider_(remoteProvider), + allocator_(allocator), + ownAllocator_(), + root_(), + schemaMap_(allocator, kInitialSchemaMapSize), + schemaRef_(allocator, kInitialSchemaRefSize) + { + if (!allocator_) + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); + + // Generate root schema, it will call CreateSchema() to create sub-schemas, + // And call AddRefSchema() if there are $ref. + CreateSchemaRecursive(&root_, PointerType(), document, document); + + // Resolve $ref + while (!schemaRef_.Empty()) { + SchemaRefEntry* refEntry = schemaRef_.template Pop(1); + if (const SchemaType* s = GetSchema(refEntry->target)) { + if (refEntry->schema) + *refEntry->schema = s; + + // Create entry in map if not exist + if (!GetSchema(refEntry->source)) { + new (schemaMap_.template Push()) SchemaEntry(refEntry->source, const_cast(s), false, allocator_); + } + } + refEntry->~SchemaRefEntry(); + } + + RAPIDJSON_ASSERT(root_ != 0); + + schemaRef_.ShrinkToFit(); // Deallocate all memory for ref + } + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + //! Move constructor in C++11 + GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT : + remoteProvider_(rhs.remoteProvider_), + allocator_(rhs.allocator_), + ownAllocator_(rhs.ownAllocator_), + root_(rhs.root_), + schemaMap_(std::move(rhs.schemaMap_)), + schemaRef_(std::move(rhs.schemaRef_)) + { + rhs.remoteProvider_ = 0; + rhs.allocator_ = 0; + rhs.ownAllocator_ = 0; + } +#endif + + //! Destructor + ~GenericSchemaDocument() { + while (!schemaMap_.Empty()) + schemaMap_.template Pop(1)->~SchemaEntry(); + + RAPIDJSON_DELETE(ownAllocator_); + } + + //! Get the root schema. + const SchemaType& GetRoot() const { return *root_; } + +private: + //! Prohibit copying + GenericSchemaDocument(const GenericSchemaDocument&); + //! Prohibit assignment + GenericSchemaDocument& operator=(const GenericSchemaDocument&); + + struct SchemaRefEntry { + SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {} + PointerType source; + PointerType target; + const SchemaType** schema; + }; + + struct SchemaEntry { + SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {} + ~SchemaEntry() { + if (owned) { + schema->~SchemaType(); + Allocator::Free(schema); + } + } + PointerType pointer; + SchemaType* schema; + bool owned; + }; + + void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + if (schema) + *schema = SchemaType::GetTypeless(); + + if (v.GetType() == kObjectType) { + const SchemaType* s = GetSchema(pointer); + if (!s) + CreateSchema(schema, pointer, v, document); + + for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr) + CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document); + } + else if (v.GetType() == kArrayType) + for (SizeType i = 0; i < v.Size(); i++) + CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document); + } + + void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) { + RAPIDJSON_ASSERT(pointer.IsValid()); + if (v.IsObject()) { + if (!HandleRefSchema(pointer, schema, v, document)) { + SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_); + new (schemaMap_.template Push()) SchemaEntry(pointer, s, true, allocator_); + if (schema) + *schema = s; + } + } + } + + bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) { + static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' }; + static const ValueType kRefValue(kRefString, 4); + + typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue); + if (itr == v.MemberEnd()) + return false; + + if (itr->value.IsString()) { + SizeType len = itr->value.GetStringLength(); + if (len > 0) { + const Ch* s = itr->value.GetString(); + SizeType i = 0; + while (i < len && s[i] != '#') // Find the first # + i++; + + if (i > 0) { // Remote reference, resolve immediately + if (remoteProvider_) { + if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i - 1)) { + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) { + if (schema) + *schema = sc; + return true; + } + } + } + } + } + else if (s[i] == '#') { // Local reference, defer resolution + PointerType pointer(&s[i], len - i, allocator_); + if (pointer.IsValid()) { + if (const ValueType* nv = pointer.Get(document)) + if (HandleRefSchema(source, schema, *nv, document)) + return true; + + new (schemaRef_.template Push()) SchemaRefEntry(source, pointer, schema, allocator_); + return true; + } + } + } + } + return false; + } + + const SchemaType* GetSchema(const PointerType& pointer) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (pointer == target->pointer) + return target->schema; + return 0; + } + + PointerType GetPointer(const SchemaType* schema) const { + for (const SchemaEntry* target = schemaMap_.template Bottom(); target != schemaMap_.template End(); ++target) + if (schema == target->schema) + return target->pointer; + return PointerType(); + } + + static const size_t kInitialSchemaMapSize = 64; + static const size_t kInitialSchemaRefSize = 64; + + IRemoteSchemaDocumentProviderType* remoteProvider_; + Allocator *allocator_; + Allocator *ownAllocator_; + const SchemaType* root_; //!< Root schema. + internal::Stack schemaMap_; // Stores created Pointer -> Schemas + internal::Stack schemaRef_; // Stores Pointer from $ref and schema which holds the $ref +}; + +//! GenericSchemaDocument using Value type. +typedef GenericSchemaDocument SchemaDocument; +//! IGenericRemoteSchemaDocumentProvider using SchemaDocument. +typedef IGenericRemoteSchemaDocumentProvider IRemoteSchemaDocumentProvider; + +/////////////////////////////////////////////////////////////////////////////// +// GenericSchemaValidator + +//! JSON Schema Validator. +/*! + A SAX style JSON schema validator. + It uses a \c GenericSchemaDocument to validate SAX events. + It delegates the incoming SAX events to an output handler. + The default output handler does nothing. + It can be reused multiple times by calling \c Reset(). + + \tparam SchemaDocumentType Type of schema document. + \tparam OutputHandler Type of output handler. Default handler does nothing. + \tparam StateAllocator Allocator for storing the internal validation states. +*/ +template < + typename SchemaDocumentType, + typename OutputHandler = BaseReaderHandler, + typename StateAllocator = CrtAllocator> +class GenericSchemaValidator : + public internal::ISchemaStateFactory, + public internal::ISchemaValidator +{ +public: + typedef typename SchemaDocumentType::SchemaType SchemaType; + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename SchemaType::EncodingType EncodingType; + typedef typename EncodingType::Ch Ch; + + //! Constructor without output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Constructor with output handler. + /*! + \param schemaDocument The schema document to conform to. + \param allocator Optional allocator for storing internal validation states. + \param schemaStackCapacity Optional initial capacity of schema path stack. + \param documentStackCapacity Optional initial capacity of document path stack. + */ + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + OutputHandler& outputHandler, + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(schemaDocument.GetRoot()), + outputHandler_(outputHandler), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(0) +#endif + { + } + + //! Destructor. + ~GenericSchemaValidator() { + Reset(); + RAPIDJSON_DELETE(ownStateAllocator_); + } + + //! Reset the internal states. + void Reset() { + while (!schemaStack_.Empty()) + PopSchema(); + documentStack_.Clear(); + valid_ = true; + } + + //! Checks whether the current state is valid. + // Implementation of ISchemaValidator + virtual bool IsValid() const { return valid_; } + + //! Gets the JSON pointer pointed to the invalid schema. + PointerType GetInvalidSchemaPointer() const { + return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema()); + } + + //! Gets the keyword of invalid schema. + const Ch* GetInvalidSchemaKeyword() const { + return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword; + } + + //! Gets the JSON pointer pointed to the invalid value. + PointerType GetInvalidDocumentPointer() const { + return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom(), documentStack_.GetSize() / sizeof(Ch)); + } + +#if RAPIDJSON_SCHEMA_VERBOSE +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \ +RAPIDJSON_MULTILINEMACRO_BEGIN\ + *documentStack_.template Push() = '\0';\ + documentStack_.template Pop(1);\ + internal::PrintInvalidDocument(documentStack_.template Bottom());\ +RAPIDJSON_MULTILINEMACRO_END +#else +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() +#endif + +#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\ + if (!valid_) return false; \ + if (!BeginValue() || !CurrentSchema().method arg1) {\ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\ + return valid_ = false;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\ + for (Context* context = schemaStack_.template Bottom(); context != schemaStack_.template End(); context++) {\ + if (context->hasher)\ + static_cast(context->hasher)->method arg2;\ + if (context->validators)\ + for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\ + static_cast(context->validators[i_])->method arg2;\ + if (context->patternPropertiesValidators)\ + for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\ + static_cast(context->patternPropertiesValidators[i_])->method arg2;\ + } + +#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\ + return valid_ = EndValue() && outputHandler_.method arg2 + +#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \ + RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\ + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\ + RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2) + + bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); } + bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); } + bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); } + bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); } + bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); } + bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); } + bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); } + bool RawNumber(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + bool String(const Ch* str, SizeType length, bool copy) + { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); } + + bool StartObject() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ()); + return valid_ = outputHandler_.StartObject(); + } + + bool Key(const Ch* str, SizeType len, bool copy) { + if (!valid_) return false; + AppendToken(str, len); + if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy)); + return valid_ = outputHandler_.Key(str, len, copy); + } + + bool EndObject(SizeType memberCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount)); + if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount)); + } + + bool StartArray() { + RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext())); + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ()); + return valid_ = outputHandler_.StartArray(); + } + + bool EndArray(SizeType elementCount) { + if (!valid_) return false; + RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount)); + if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false; + RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount)); + } + +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_ +#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_ +#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_ +#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_ + + // Implementation of ISchemaStateFactory + virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) { + return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root, +#if RAPIDJSON_SCHEMA_VERBOSE + depth_ + 1, +#endif + &GetStateAllocator()); + } + + virtual void DestroySchemaValidator(ISchemaValidator* validator) { + GenericSchemaValidator* v = static_cast(validator); + v->~GenericSchemaValidator(); + StateAllocator::Free(v); + } + + virtual void* CreateHasher() { + return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator()); + } + + virtual uint64_t GetHashCode(void* hasher) { + return static_cast(hasher)->GetHashCode(); + } + + virtual void DestroryHasher(void* hasher) { + HasherType* h = static_cast(hasher); + h->~HasherType(); + StateAllocator::Free(h); + } + + virtual void* MallocState(size_t size) { + return GetStateAllocator().Malloc(size); + } + + virtual void FreeState(void* p) { + return StateAllocator::Free(p); + } + +private: + typedef typename SchemaType::Context Context; + typedef GenericValue, StateAllocator> HashCodeArray; + typedef internal::Hasher HasherType; + + GenericSchemaValidator( + const SchemaDocumentType& schemaDocument, + const SchemaType& root, +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth, +#endif + StateAllocator* allocator = 0, + size_t schemaStackCapacity = kDefaultSchemaStackCapacity, + size_t documentStackCapacity = kDefaultDocumentStackCapacity) + : + schemaDocument_(&schemaDocument), + root_(root), + outputHandler_(GetNullHandler()), + stateAllocator_(allocator), + ownStateAllocator_(0), + schemaStack_(allocator, schemaStackCapacity), + documentStack_(allocator, documentStackCapacity), + valid_(true) +#if RAPIDJSON_SCHEMA_VERBOSE + , depth_(depth) +#endif + { + } + + StateAllocator& GetStateAllocator() { + if (!stateAllocator_) + stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator()); + return *stateAllocator_; + } + + bool BeginValue() { + if (schemaStack_.Empty()) + PushSchema(root_); + else { + if (CurrentContext().inArray) + internal::TokenHelper, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex); + + if (!CurrentSchema().BeginValue(CurrentContext())) + return false; + + SizeType count = CurrentContext().patternPropertiesSchemaCount; + const SchemaType** sa = CurrentContext().patternPropertiesSchemas; + typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType; + bool valueUniqueness = CurrentContext().valueUniqueness; + if (CurrentContext().valueSchema) + PushSchema(*CurrentContext().valueSchema); + + if (count > 0) { + CurrentContext().objectPatternValidatorType = patternValidatorType; + ISchemaValidator**& va = CurrentContext().patternPropertiesValidators; + SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount; + va = static_cast(MallocState(sizeof(ISchemaValidator*) * count)); + for (SizeType i = 0; i < count; i++) + va[validatorCount++] = CreateSchemaValidator(*sa[i]); + } + + CurrentContext().arrayUniqueness = valueUniqueness; + } + return true; + } + + bool EndValue() { + if (!CurrentSchema().EndValue(CurrentContext())) + return false; + +#if RAPIDJSON_SCHEMA_VERBOSE + GenericStringBuffer sb; + schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb); + + *documentStack_.template Push() = '\0'; + documentStack_.template Pop(1); + internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom()); +#endif + + uint64_t h = CurrentContext().arrayUniqueness ? static_cast(CurrentContext().hasher)->GetHashCode() : 0; + + PopSchema(); + + if (!schemaStack_.Empty()) { + Context& context = CurrentContext(); + if (context.valueUniqueness) { + HashCodeArray* a = static_cast(context.arrayElementHashCodes); + if (!a) + CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType); + for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr) + if (itr->GetUint64() == h) + RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString()); + a->PushBack(h, GetStateAllocator()); + } + } + + // Remove the last token of document pointer + while (!documentStack_.Empty() && *documentStack_.template Pop(1) != '/') + ; + + return true; + } + + void AppendToken(const Ch* str, SizeType len) { + documentStack_.template Reserve(1 + len * 2); // worst case all characters are escaped as two characters + *documentStack_.template PushUnsafe() = '/'; + for (SizeType i = 0; i < len; i++) { + if (str[i] == '~') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '0'; + } + else if (str[i] == '/') { + *documentStack_.template PushUnsafe() = '~'; + *documentStack_.template PushUnsafe() = '1'; + } + else + *documentStack_.template PushUnsafe() = str[i]; + } + } + + RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push()) Context(*this, &schema); } + + RAPIDJSON_FORCEINLINE void PopSchema() { + Context* c = schemaStack_.template Pop(1); + if (HashCodeArray* a = static_cast(c->arrayElementHashCodes)) { + a->~HashCodeArray(); + StateAllocator::Free(a); + } + c->~Context(); + } + + const SchemaType& CurrentSchema() const { return *schemaStack_.template Top()->schema; } + Context& CurrentContext() { return *schemaStack_.template Top(); } + const Context& CurrentContext() const { return *schemaStack_.template Top(); } + + static OutputHandler& GetNullHandler() { + static OutputHandler nullHandler; + return nullHandler; + } + + static const size_t kDefaultSchemaStackCapacity = 1024; + static const size_t kDefaultDocumentStackCapacity = 256; + const SchemaDocumentType* schemaDocument_; + const SchemaType& root_; + OutputHandler& outputHandler_; + StateAllocator* stateAllocator_; + StateAllocator* ownStateAllocator_; + internal::Stack schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *) + internal::Stack documentStack_; //!< stack to store the current path of validating document (Ch) + bool valid_; +#if RAPIDJSON_SCHEMA_VERBOSE + unsigned depth_; +#endif +}; + +typedef GenericSchemaValidator SchemaValidator; + +/////////////////////////////////////////////////////////////////////////////// +// SchemaValidatingReader + +//! A helper class for parsing with validation. +/*! + This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate(). + + \tparam parseFlags Combination of \ref ParseFlag. + \tparam InputStream Type of input stream, implementing Stream concept. + \tparam SourceEncoding Encoding of the input stream. + \tparam SchemaDocumentType Type of schema document. + \tparam StackAllocator Allocator type for stack. +*/ +template < + unsigned parseFlags, + typename InputStream, + typename SourceEncoding, + typename SchemaDocumentType = SchemaDocument, + typename StackAllocator = CrtAllocator> +class SchemaValidatingReader { +public: + typedef typename SchemaDocumentType::PointerType PointerType; + typedef typename InputStream::Ch Ch; + + //! Constructor + /*! + \param is Input stream. + \param sd Schema document. + */ + SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {} + + template + bool operator()(Handler& handler) { + GenericReader reader; + GenericSchemaValidator validator(sd_, handler); + parseResult_ = reader.template Parse(is_, validator); + + isValid_ = validator.IsValid(); + if (isValid_) { + invalidSchemaPointer_ = PointerType(); + invalidSchemaKeyword_ = 0; + invalidDocumentPointer_ = PointerType(); + } + else { + invalidSchemaPointer_ = validator.GetInvalidSchemaPointer(); + invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword(); + invalidDocumentPointer_ = validator.GetInvalidDocumentPointer(); + } + + return parseResult_; + } + + const ParseResult& GetParseResult() const { return parseResult_; } + bool IsValid() const { return isValid_; } + const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; } + const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; } + const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; } + +private: + InputStream& is_; + const SchemaDocumentType& sd_; + + ParseResult parseResult_; + PointerType invalidSchemaPointer_; + const Ch* invalidSchemaKeyword_; + PointerType invalidDocumentPointer_; + bool isValid_; +}; + +RAPIDJSON_NAMESPACE_END +RAPIDJSON_DIAG_POP + +#endif // RAPIDJSON_SCHEMA_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/stream.h b/src/third-party/discord-rpc/include/rapidjson/stream.h new file mode 100644 index 000000000..fef82c252 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/stream.h @@ -0,0 +1,179 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#include "rapidjson.h" + +#ifndef RAPIDJSON_STREAM_H_ +#define RAPIDJSON_STREAM_H_ + +#include "encodings.h" + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// Stream + +/*! \class rapidjson::Stream + \brief Concept for reading and writing characters. + + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd(). + + For write-only stream, only need to implement Put() and Flush(). + +\code +concept Stream { + typename Ch; //!< Character type of the stream. + + //! Read the current character from stream without moving the read cursor. + Ch Peek() const; + + //! Read the current character from stream and moving the read cursor to next character. + Ch Take(); + + //! Get the current read cursor. + //! \return Number of characters read from start. + size_t Tell(); + + //! Begin writing operation at the current read pointer. + //! \return The begin writer pointer. + Ch* PutBegin(); + + //! Write a character. + void Put(Ch c); + + //! Flush the buffer. + void Flush(); + + //! End the writing operation. + //! \param begin The begin write pointer returned by PutBegin(). + //! \return Number of characters written. + size_t PutEnd(Ch* begin); +} +\endcode +*/ + +//! Provides additional information for stream. +/*! + By using traits pattern, this type provides a default configuration for stream. + For custom stream, this type can be specialized for other configuration. + See TEST(Reader, CustomStringStream) in readertest.cpp for example. +*/ +template +struct StreamTraits { + //! Whether to make local copy of stream for optimization during parsing. + /*! + By default, for safety, streams do not use local copy optimization. + Stream that can be copied fast should specialize this, like StreamTraits. + */ + enum { copyOptimization = 0 }; +}; + +//! Reserve n characters for writing to a stream. +template +inline void PutReserve(Stream& stream, size_t count) { + (void)stream; + (void)count; +} + +//! Write character to a stream, presuming buffer is reserved. +template +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) { + stream.Put(c); +} + +//! Put N copies of a character to a stream. +template +inline void PutN(Stream& stream, Ch c, size_t n) { + PutReserve(stream, n); + for (size_t i = 0; i < n; i++) + PutUnsafe(stream, c); +} + +/////////////////////////////////////////////////////////////////////////////// +// StringStream + +//! Read-only string stream. +/*! \note implements Stream concept +*/ +template +struct GenericStringStream { + typedef typename Encoding::Ch Ch; + + GenericStringStream(const Ch *src) : src_(src), head_(src) {} + + Ch Peek() const { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() const { return static_cast(src_ - head_); } + + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; } + void Put(Ch) { RAPIDJSON_ASSERT(false); } + void Flush() { RAPIDJSON_ASSERT(false); } + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; } + + const Ch* src_; //!< Current read position. + const Ch* head_; //!< Original head of the string. +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! String stream with UTF8 encoding. +typedef GenericStringStream > StringStream; + +/////////////////////////////////////////////////////////////////////////////// +// InsituStringStream + +//! A read-write string stream. +/*! This string stream is particularly designed for in-situ parsing. + \note implements Stream concept +*/ +template +struct GenericInsituStringStream { + typedef typename Encoding::Ch Ch; + + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {} + + // Read + Ch Peek() { return *src_; } + Ch Take() { return *src_++; } + size_t Tell() { return static_cast(src_ - head_); } + + // Write + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; } + + Ch* PutBegin() { return dst_ = src_; } + size_t PutEnd(Ch* begin) { return static_cast(dst_ - begin); } + void Flush() {} + + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; } + void Pop(size_t count) { dst_ -= count; } + + Ch* src_; + Ch* dst_; + Ch* head_; +}; + +template +struct StreamTraits > { + enum { copyOptimization = 1 }; +}; + +//! Insitu string stream with UTF8 encoding. +typedef GenericInsituStringStream > InsituStringStream; + +RAPIDJSON_NAMESPACE_END + +#endif // RAPIDJSON_STREAM_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/stringbuffer.h b/src/third-party/discord-rpc/include/rapidjson/stringbuffer.h new file mode 100644 index 000000000..78f34d209 --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/stringbuffer.h @@ -0,0 +1,117 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_STRINGBUFFER_H_ +#define RAPIDJSON_STRINGBUFFER_H_ + +#include "stream.h" +#include "internal/stack.h" + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS +#include // std::move +#endif + +#include "internal/stack.h" + +#if defined(__clang__) +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(c++98-compat) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +//! Represents an in-memory output stream. +/*! + \tparam Encoding Encoding of the stream. + \tparam Allocator type for allocating memory buffer. + \note implements Stream concept +*/ +template +class GenericStringBuffer { +public: + typedef typename Encoding::Ch Ch; + + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {} + +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {} + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) { + if (&rhs != this) + stack_ = std::move(rhs.stack_); + return *this; + } +#endif + + void Put(Ch c) { *stack_.template Push() = c; } + void PutUnsafe(Ch c) { *stack_.template PushUnsafe() = c; } + void Flush() {} + + void Clear() { stack_.Clear(); } + void ShrinkToFit() { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.ShrinkToFit(); + stack_.template Pop(1); + } + + void Reserve(size_t count) { stack_.template Reserve(count); } + Ch* Push(size_t count) { return stack_.template Push(count); } + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe(count); } + void Pop(size_t count) { stack_.template Pop(count); } + + const Ch* GetString() const { + // Push and pop a null terminator. This is safe. + *stack_.template Push() = '\0'; + stack_.template Pop(1); + + return stack_.template Bottom(); + } + + size_t GetSize() const { return stack_.GetSize(); } + + static const size_t kDefaultCapacity = 256; + mutable internal::Stack stack_; + +private: + // Prohibit copy constructor & assignment operator. + GenericStringBuffer(const GenericStringBuffer&); + GenericStringBuffer& operator=(const GenericStringBuffer&); +}; + +//! String buffer with UTF8 encoding +typedef GenericStringBuffer > StringBuffer; + +template +inline void PutReserve(GenericStringBuffer& stream, size_t count) { + stream.Reserve(count); +} + +template +inline void PutUnsafe(GenericStringBuffer& stream, typename Encoding::Ch c) { + stream.PutUnsafe(c); +} + +//! Implement specialized version of PutN() with memset() for better performance. +template<> +inline void PutN(GenericStringBuffer >& stream, char c, size_t n) { + std::memset(stream.stack_.Push(n), c, n * sizeof(c)); +} + +RAPIDJSON_NAMESPACE_END + +#if defined(__clang__) +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_STRINGBUFFER_H_ diff --git a/src/third-party/discord-rpc/include/rapidjson/writer.h b/src/third-party/discord-rpc/include/rapidjson/writer.h new file mode 100644 index 000000000..94f22dd5f --- /dev/null +++ b/src/third-party/discord-rpc/include/rapidjson/writer.h @@ -0,0 +1,610 @@ +// Tencent is pleased to support the open source community by making RapidJSON available. +// +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. +// +// Licensed under the MIT License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://opensource.org/licenses/MIT +// +// Unless required by applicable law or agreed to in writing, software distributed +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "stream.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include "internal/dtoa.h" +#include "internal/itoa.h" +#include "stringbuffer.h" +#include // placement new + +#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) +#include +#pragma intrinsic(_BitScanForward) +#endif +#ifdef RAPIDJSON_SSE42 +#include +#elif defined(RAPIDJSON_SSE2) +#include +#endif + +#ifdef _MSC_VER +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(padded) +RAPIDJSON_DIAG_OFF(unreachable-code) +#endif + +RAPIDJSON_NAMESPACE_BEGIN + +/////////////////////////////////////////////////////////////////////////////// +// WriteFlag + +/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS + \ingroup RAPIDJSON_CONFIG + \brief User-defined kWriteDefaultFlags definition. + + User can define this as any \c WriteFlag combinations. +*/ +#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS +#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags +#endif + +//! Combination of writeFlags +enum WriteFlag { + kWriteNoFlags = 0, //!< No flags are set. + kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings. + kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN. + kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS +}; + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output os. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam OutputStream Type of output stream. + \tparam SourceEncoding Encoding of source string. + \tparam TargetEncoding Encoding of output stream. + \tparam StackAllocator Type of allocator for allocating memory of stack. + \note implements Handler concept +*/ +template, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags> +class Writer { +public: + typedef typename SourceEncoding::Ch Ch; + + static const int kDefaultMaxDecimalPlaces = 324; + + //! Constructor + /*! \param os Output stream. + \param stackAllocator User supplied allocator. If it is null, it will create a private one. + \param levelDepth Initial capacity of stack. + */ + explicit + Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + explicit + Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {} + + //! Reset the writer with a new stream. + /*! + This function reset the writer with a new stream and default settings, + in order to make a Writer object reusable for output multiple JSONs. + + \param os New output stream. + \code + Writer writer(os1); + writer.StartObject(); + // ... + writer.EndObject(); + + writer.Reset(os2); + writer.StartObject(); + // ... + writer.EndObject(); + \endcode + */ + void Reset(OutputStream& os) { + os_ = &os; + hasRoot_ = false; + level_stack_.Clear(); + } + + //! Checks whether the output is a complete JSON. + /*! + A complete JSON has a complete root object or array. + */ + bool IsComplete() const { + return hasRoot_ && level_stack_.Empty(); + } + + int GetMaxDecimalPlaces() const { + return maxDecimalPlaces_; + } + + //! Sets the maximum number of decimal places for double output. + /*! + This setting truncates the output with specified number of decimal places. + + For example, + + \code + writer.SetMaxDecimalPlaces(3); + writer.StartArray(); + writer.Double(0.12345); // "0.123" + writer.Double(0.0001); // "0.0" + writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent) + writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent) + writer.EndArray(); + \endcode + + The default setting does not truncate any decimal places. You can restore to this setting by calling + \code + writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces); + \endcode + */ + void SetMaxDecimalPlaces(int maxDecimalPlaces) { + maxDecimalPlaces_ = maxDecimalPlaces; + } + + /*!@name Implementation of Handler + \see Handler + */ + //@{ + + bool Null() { Prefix(kNullType); return EndValue(WriteNull()); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); } + bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); } + bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); } + bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); } + + //! Writes the given \c double value to the stream + /*! + \param d The value to be written. + \return Whether it is succeed. + */ + bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); } + + bool RawNumber(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kNumberType); + return EndValue(WriteString(str, length)); + } + + bool String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + return EndValue(WriteString(str, length)); + } + +#if RAPIDJSON_HAS_STDSTRING + bool String(const std::basic_string& str) { + return String(str.data(), SizeType(str.size())); + } +#endif + + bool StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + return WriteStartObject(); + } + + bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } + + bool EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndObject()); + } + + bool StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + return WriteStartArray(); + } + + bool EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + return EndValue(WriteEndArray()); + } + //@} + + /*! @name Convenience extensions */ + //@{ + + //! Simpler but slower overload. + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } + + //@} + + //! Write a raw JSON value. + /*! + For user to write a stringified JSON as a value. + + \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range. + \param length Length of the json. + \param type Type of the root of json. + */ + bool RawValue(const Ch* json, size_t length, Type type) { Prefix(type); return EndValue(WriteRawValue(json, length)); } + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : valueCount(0), inArray(inArray_) {} + size_t valueCount; //!< number of values in this level + bool inArray; //!< true if in array, otherwise in object + }; + + static const size_t kDefaultLevelDepth = 32; + + bool WriteNull() { + PutReserve(*os_, 4); + PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true; + } + + bool WriteBool(bool b) { + if (b) { + PutReserve(*os_, 4); + PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e'); + } + else { + PutReserve(*os_, 5); + PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e'); + } + return true; + } + + bool WriteInt(int i) { + char buffer[11]; + const char* end = internal::i32toa(i, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint(unsigned u) { + char buffer[10]; + const char* end = internal::u32toa(u, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteInt64(int64_t i64) { + char buffer[21]; + const char* end = internal::i64toa(i64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (const char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteUint64(uint64_t u64) { + char buffer[20]; + char* end = internal::u64toa(u64, buffer); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + if (!(writeFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char buffer[25]; + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + PutReserve(*os_, static_cast(end - buffer)); + for (char* p = buffer; p != end; ++p) + PutUnsafe(*os_, static_cast(*p)); + return true; + } + + bool WriteString(const Ch* str, SizeType length) { + static const typename TargetEncoding::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + if (TargetEncoding::supportUnicode) + PutReserve(*os_, 2 + length * 6); // "\uxxxx..." + else + PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..." + + PutUnsafe(*os_, '\"'); + GenericStringStream is(str); + while (ScanWriteUnescapedString(is, length)) { + const Ch c = is.Peek(); + if (!TargetEncoding::supportUnicode && static_cast(c) >= 0x80) { + // Unicode escaping + unsigned codepoint; + if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint))) + return false; + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { + PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(codepoint ) & 15]); + } + else { + RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF); + // Surrogate pair + unsigned s = codepoint - 0x010000; + unsigned lead = (s >> 10) + 0xD800; + unsigned trail = (s & 0x3FF) + 0xDC00; + PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(lead ) & 15]); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, 'u'); + PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]); + PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]); + PutUnsafe(*os_, hexDigits[(trail ) & 15]); + } + } + else if ((sizeof(Ch) == 1 || static_cast(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast(c)])) { + is.Take(); + PutUnsafe(*os_, '\\'); + PutUnsafe(*os_, static_cast(escape[static_cast(c)])); + if (escape[static_cast(c)] == 'u') { + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, '0'); + PutUnsafe(*os_, hexDigits[static_cast(c) >> 4]); + PutUnsafe(*os_, hexDigits[static_cast(c) & 0xF]); + } + } + else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ? + Transcoder::Validate(is, *os_) : + Transcoder::TranscodeUnsafe(is, *os_)))) + return false; + } + PutUnsafe(*os_, '\"'); + return true; + } + + bool ScanWriteUnescapedString(GenericStringStream& is, size_t length) { + return RAPIDJSON_LIKELY(is.Tell() < length); + } + + bool WriteStartObject() { os_->Put('{'); return true; } + bool WriteEndObject() { os_->Put('}'); return true; } + bool WriteStartArray() { os_->Put('['); return true; } + bool WriteEndArray() { os_->Put(']'); return true; } + + bool WriteRawValue(const Ch* json, size_t length) { + PutReserve(*os_, length); + for (size_t i = 0; i < length; i++) { + RAPIDJSON_ASSERT(json[i] != '\0'); + PutUnsafe(*os_, json[i]); + } + return true; + } + + void Prefix(Type type) { + (void)type; + if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + os_->Put(','); // add comma if it is not the first element in array + else // in object + os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else { + RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. + hasRoot_ = true; + } + } + + // Flush the value if it is the top level one. + bool EndValue(bool ret) { + if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text + os_->Flush(); + return ret; + } + + OutputStream* os_; + internal::Stack level_stack_; + int maxDecimalPlaces_; + bool hasRoot_; + +private: + // Prohibit copy constructor & assignment operator. + Writer(const Writer&); + Writer& operator=(const Writer&); +}; + +// Full specialization for StringStream to prevent memory copying + +template<> +inline bool Writer::WriteInt(int i) { + char *buffer = os_->Push(11); + const char* end = internal::i32toa(i, buffer); + os_->Pop(static_cast(11 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint(unsigned u) { + char *buffer = os_->Push(10); + const char* end = internal::u32toa(u, buffer); + os_->Pop(static_cast(10 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteInt64(int64_t i64) { + char *buffer = os_->Push(21); + const char* end = internal::i64toa(i64, buffer); + os_->Pop(static_cast(21 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteUint64(uint64_t u) { + char *buffer = os_->Push(20); + const char* end = internal::u64toa(u, buffer); + os_->Pop(static_cast(20 - (end - buffer))); + return true; +} + +template<> +inline bool Writer::WriteDouble(double d) { + if (internal::Double(d).IsNanOrInf()) { + // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag). + if (!(kWriteDefaultFlags & kWriteNanAndInfFlag)) + return false; + if (internal::Double(d).IsNan()) { + PutReserve(*os_, 3); + PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N'); + return true; + } + if (internal::Double(d).Sign()) { + PutReserve(*os_, 9); + PutUnsafe(*os_, '-'); + } + else + PutReserve(*os_, 8); + PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f'); + PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y'); + return true; + } + + char *buffer = os_->Push(25); + char* end = internal::dtoa(d, buffer, maxDecimalPlaces_); + os_->Pop(static_cast(25 - (end - buffer))); + return true; +} + +#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) +template<> +inline bool Writer::ScanWriteUnescapedString(StringStream& is, size_t length) { + if (length < 16) + return RAPIDJSON_LIKELY(is.Tell() < length); + + if (!RAPIDJSON_LIKELY(is.Tell() < length)) + return false; + + const char* p = is.src_; + const char* end = is.head_ + length; + const char* nextAligned = reinterpret_cast((reinterpret_cast(p) + 15) & static_cast(~15)); + const char* endAligned = reinterpret_cast(reinterpret_cast(end) & static_cast(~15)); + if (nextAligned > end) + return true; + + while (p != nextAligned) + if (*p < 0x20 || *p == '\"' || *p == '\\') { + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); + } + else + os_->PutUnsafe(*p++); + + // The rest of string using SIMD + static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; + static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; + static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; + const __m128i dq = _mm_loadu_si128(reinterpret_cast(&dquote[0])); + const __m128i bs = _mm_loadu_si128(reinterpret_cast(&bslash[0])); + const __m128i sp = _mm_loadu_si128(reinterpret_cast(&space[0])); + + for (; p != endAligned; p += 16) { + const __m128i s = _mm_load_si128(reinterpret_cast(p)); + const __m128i t1 = _mm_cmpeq_epi8(s, dq); + const __m128i t2 = _mm_cmpeq_epi8(s, bs); + const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 + const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); + unsigned short r = static_cast(_mm_movemask_epi8(x)); + if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped + SizeType len; +#ifdef _MSC_VER // Find the index of first escaped + unsigned long offset; + _BitScanForward(&offset, r); + len = offset; +#else + len = static_cast(__builtin_ffs(r) - 1); +#endif + char* q = reinterpret_cast(os_->PushUnsafe(len)); + for (size_t i = 0; i < len; i++) + q[i] = p[i]; + + p += len; + break; + } + _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s); + } + + is.src_ = p; + return RAPIDJSON_LIKELY(is.Tell() < length); +} +#endif // defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) + +RAPIDJSON_NAMESPACE_END + +#ifdef _MSC_VER +RAPIDJSON_DIAG_POP +#endif + +#ifdef __clang__ +RAPIDJSON_DIAG_POP +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/src/third-party/discord-rpc/src/CMakeLists.txt b/src/third-party/discord-rpc/src/CMakeLists.txt index f83a119bc..0db91902c 100644 --- a/src/third-party/discord-rpc/src/CMakeLists.txt +++ b/src/third-party/discord-rpc/src/CMakeLists.txt @@ -80,8 +80,6 @@ if(UNIX) endif (APPLE) endif(UNIX) -target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include) - if (NOT ${ENABLE_IO_THREAD}) target_compile_definitions(discord-rpc PUBLIC -DDISCORD_DISABLE_IO_THREAD) endif (NOT ${ENABLE_IO_THREAD}) From 9125a1ae483c367c869f9e192cca7bc4d5cb1543 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 19:25:02 -0700 Subject: [PATCH 110/429] Qt: Add missing files --- src/platform/qt/DiscordCoordinator.cpp | 95 ++++++++++++++++++++++++++ src/platform/qt/DiscordCoordinator.h | 24 +++++++ 2 files changed, 119 insertions(+) create mode 100644 src/platform/qt/DiscordCoordinator.cpp create mode 100644 src/platform/qt/DiscordCoordinator.h diff --git a/src/platform/qt/DiscordCoordinator.cpp b/src/platform/qt/DiscordCoordinator.cpp new file mode 100644 index 000000000..4ff26fe5b --- /dev/null +++ b/src/platform/qt/DiscordCoordinator.cpp @@ -0,0 +1,95 @@ +/* Copyright (c) 2013-2019 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 "DiscordCoordinator.h" + +#include "CoreController.h" +#include "GBAApp.h" + +#ifdef USE_SQLITE3 +#include "feature/sqlite3/no-intro.h" +#endif + +#include "discord_rpc.h" + +namespace QGBA { + +namespace DiscordCoordinator { + +static bool s_gameRunning = false; +static bool s_inited = false; +static QString s_title; + +static void updatePresence() { + if (!s_inited) { + return; + } + if (s_gameRunning) { + DiscordRichPresence discordPresence{}; + discordPresence.details = s_title.toUtf8().constData(); + discordPresence.instance = 1; + Discord_UpdatePresence(&discordPresence); + } else { + Discord_ClearPresence(); + } +} + +void init() { + if (s_inited) { + return; + } + DiscordEventHandlers handlers{}; + Discord_Initialize("554440738952183828", &handlers, 1, nullptr); + s_inited = true; + updatePresence(); +} + +void deinit() { + if (!s_inited) { + return; + } + Discord_ClearPresence(); + Discord_Shutdown(); + s_inited = false; + s_gameRunning = false; +} + +void gameStarted(std::shared_ptr controller) { + if (s_gameRunning) { + return; + } + s_gameRunning = true; + + CoreController::Interrupter interrupter(controller); + const NoIntroDB* db = GBAApp::app()->gameDB(); + NoIntroGame game{}; + uint32_t crc32 = 0; + controller->thread()->core->checksum(controller->thread()->core, &crc32, CHECKSUM_CRC32); + + char gameTitle[17] = { '\0' }; + mCore* core = controller->thread()->core; + core->getGameTitle(core, gameTitle); + s_title = gameTitle; + +#ifdef USE_SQLITE3 + if (db && crc32 && NoIntroDBLookupGameByCRC(db, crc32, &game)) { + s_title = QLatin1String(game.name); + } +#endif + + updatePresence(); +} + +void gameStopped() { + if (!s_gameRunning) { + return; + } + s_gameRunning = false; + updatePresence(); +} + +} + +} \ No newline at end of file diff --git a/src/platform/qt/DiscordCoordinator.h b/src/platform/qt/DiscordCoordinator.h new file mode 100644 index 000000000..a3bb0e7bd --- /dev/null +++ b/src/platform/qt/DiscordCoordinator.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include + +namespace QGBA { + +class CoreController; + +namespace DiscordCoordinator { + +void init(); +void deinit(); + +void gameStarted(std::shared_ptr); +void gameStopped(); + +} + +} \ No newline at end of file From 8c68d867e61f6227dad735390444ff8e41510f4f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 22:34:31 -0700 Subject: [PATCH 111/429] Third-Party: More Discord fixes --- CMakeLists.txt | 11 +- .../include/mingw-std-threads/LICENSE | 24 + .../include/mingw-std-threads/README.md | 41 ++ .../mingw-std-threads/condition_variable | 549 ++++++++++++++++++ .../include/mingw-std-threads/mutex | 474 +++++++++++++++ .../include/mingw-std-threads/thread | 410 +++++++++++++ .../discord-rpc/src/CMakeLists.txt | 3 + 7 files changed, 1511 insertions(+), 1 deletion(-) create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/LICENSE create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/README.md create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/condition_variable create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/mutex create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/thread diff --git a/CMakeLists.txt b/CMakeLists.txt index 88c280175..b16c084ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1037,7 +1037,15 @@ if(WIN32) endif() # Packaging -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT ${BINARY_NAME}) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/blip_buf.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/inih.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) +if(USE_DISCORD_RPC) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/discord-rpc.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/rapidjson.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) + if(WIN32) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/mingw-std-threads.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) + endif() +endif() if(EXTRA_LICENSES) install(FILES ${EXTRA_LICENSES} DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) endif() @@ -1245,6 +1253,7 @@ if(NOT QUIET) message(STATUS " 7-Zip support: ${USE_LZMA}") message(STATUS " SQLite3 game database: ${USE_SQLITE3}") message(STATUS " ELF loading support: ${USE_ELF}") + message(STATUS " Discord Rich Presence support: ${USE_DISCORD_RPC}") message(STATUS " OpenGL support: ${SUMMARY_GL}") message(STATUS "Frontends:") message(STATUS " Qt: ${BUILD_QT}") diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/LICENSE b/src/third-party/discord-rpc/include/mingw-std-threads/LICENSE new file mode 100644 index 000000000..ac525cf20 --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2016, Mega Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/README.md b/src/third-party/discord-rpc/include/mingw-std-threads/README.md new file mode 100644 index 000000000..198bf07bd --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/README.md @@ -0,0 +1,41 @@ +mingw-std-threads +================= + +Implementation of standard C++11 threading classes, which are currently still missing on MinGW GCC. + +Target Windows version +---------------------- +This implementation should work with Windows XP (regardless of service pack), or newer. +The library automatically detects the version of Windows that is being targeted (at compile time), and selects an implementation that takes advantage of available Windows features. +In MinGW GCC, the target Windows version may optionally be selected by the command-line option `-D _WIN32_WINNT=...`. +Use `0x0600` for Windows Vista, or `0x0601` for Windows 7. +See "[Modifying `WINVER` and `_WIN32_WINNT`](https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt)" for more details. + +Usage +----- + +This is a header-only library. To use, just include the corresponding `mingw.xxx.h file`, where `xxx` would be the name of the standard header that you would normally include. + +For example, `#include "mingw.thread.h"` replaces `#include `. + +Compatibility +------------- + +This code has been tested to work with MinGW-w64 5.3.0, but should work with any other MinGW version that has the `std` threading classes missing, has C++11 support for lambda functions, variadic templates, and has working mutex helper classes in ``. + +Switching from the win32-pthread based implementation +----------------------------------------------------- +It seems that recent versions of MinGW-w64 include a Win32 port of pthreads, and have the `std::thread`, `std::mutex`, etc. classes implemented and working based on that compatibility +layer. +That is a somewhat heavier implementation, as it relies on an abstraction layer, so you may still want to use this implementation for efficiency purposes. +Unfortunately you can't use this library standalone and independent of the system `` headers, as it relies on those headers for `std::unique_lock` and other non-trivial utility classes. +In that case you will need to edit the `c++-config.h` file of your MinGW setup and comment out the definition of _GLIBCXX_HAS_GTHREADS. +This will cause the system headers not to define the actual `thread`, `mutex`, etc. classes, but still define the necessary utility classes. + +Why MinGW has no threading classes +---------------------------------- +It seems that for cross-platform threading implementation, the GCC standard library relies on the gthreads/pthreads library. +If this library is not available, as is the case with MinGW, the classes `std::thread`, `std::mutex`, `std::condition_variable` are not defined. +However, various usable helper classes are still defined in the system headers. +Hence, this implementation does not re-define them, and instead includes those headers. + diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/condition_variable b/src/third-party/discord-rpc/include/mingw-std-threads/condition_variable new file mode 100644 index 000000000..860fdb4fc --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/condition_variable @@ -0,0 +1,549 @@ +/** +* @file condition_variable.h +* @brief std::condition_variable implementation for MinGW +* +* (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef MINGW_CONDITIONAL_VARIABLE_H +#define MINGW_CONDITIONAL_VARIABLE_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif +// Use the standard classes for std::, if available. +#include_next + +#include +#include +#include +#include + +#if (WINVER < _WIN32_WINNT_VISTA) +#include +#endif + +#include +#include + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +namespace mingw_stdthread +{ +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +enum class cv_status { no_timeout, timeout }; +#else +using std::cv_status; +#endif +namespace xp +{ +// Include the XP-compatible condition_variable classes only if actually +// compiling for XP. The XP-compatible classes are slower than the newer +// versions, and depend on features not compatible with Windows Phone 8. +#if (WINVER < _WIN32_WINNT_VISTA) +class condition_variable_any +{ + recursive_mutex mMutex {}; + std::atomic mNumWaiters {0}; + HANDLE mSemaphore; + HANDLE mWakeEvent {}; +public: + using native_handle_type = HANDLE; + native_handle_type native_handle() + { + return mSemaphore; + } + condition_variable_any(const condition_variable_any&) = delete; + condition_variable_any& operator=(const condition_variable_any&) = delete; + condition_variable_any() + : mSemaphore(CreateSemaphore(NULL, 0, 0xFFFF, NULL)) + { + if (mSemaphore == NULL) + throw std::system_error(GetLastError(), std::generic_category()); + mWakeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (mWakeEvent == NULL) + { + CloseHandle(mSemaphore); + throw std::system_error(GetLastError(), std::generic_category()); + } + } + ~condition_variable_any() + { + CloseHandle(mWakeEvent); + CloseHandle(mSemaphore); + } +private: + template + bool wait_impl(M& lock, DWORD timeout) + { + { + lock_guard guard(mMutex); + mNumWaiters++; + } + lock.unlock(); + DWORD ret = WaitForSingleObject(mSemaphore, timeout); + + mNumWaiters--; + SetEvent(mWakeEvent); + lock.lock(); + if (ret == WAIT_OBJECT_0) + return true; + else if (ret == WAIT_TIMEOUT) + return false; +//2 possible cases: +//1)The point in notify_all() where we determine the count to +//increment the semaphore with has not been reached yet: +//we just need to decrement mNumWaiters, but setting the event does not hurt +// +//2)Semaphore has just been released with mNumWaiters just before +//we decremented it. This means that the semaphore count +//after all waiters finish won't be 0 - because not all waiters +//woke up by acquiring the semaphore - we woke up by a timeout. +//The notify_all() must handle this gracefully +// + else + { + using namespace std; + throw system_error(make_error_code(errc::protocol_error)); + } + } +public: + template + void wait(M& lock) + { + wait_impl(lock, INFINITE); + } + template + void wait(M& lock, Predicate pred) + { + while(!pred()) + { + wait(lock); + }; + } + + void notify_all() noexcept + { + lock_guard lock(mMutex); //block any further wait requests until all current waiters are unblocked + if (mNumWaiters.load() <= 0) + return; + + ReleaseSemaphore(mSemaphore, mNumWaiters, NULL); + while(mNumWaiters > 0) + { + auto ret = WaitForSingleObject(mWakeEvent, 1000); + if (ret == WAIT_FAILED || ret == WAIT_ABANDONED) + std::terminate(); + } + assert(mNumWaiters == 0); +//in case some of the waiters timed out just after we released the +//semaphore by mNumWaiters, it won't be zero now, because not all waiters +//woke up by acquiring the semaphore. So we must zero the semaphore before +//we accept waiters for the next event +//See _wait_impl for details + while(WaitForSingleObject(mSemaphore, 0) == WAIT_OBJECT_0); + } + void notify_one() noexcept + { + lock_guard lock(mMutex); + int targetWaiters = mNumWaiters.load() - 1; + if (targetWaiters <= -1) + return; + ReleaseSemaphore(mSemaphore, 1, NULL); + while(mNumWaiters > targetWaiters) + { + auto ret = WaitForSingleObject(mWakeEvent, 1000); + if (ret == WAIT_FAILED || ret == WAIT_ABANDONED) + std::terminate(); + } + assert(mNumWaiters == targetWaiters); + } + template + cv_status wait_for(M& lock, + const std::chrono::duration& rel_time) + { + using namespace std::chrono; + auto timeout = duration_cast(rel_time).count(); + DWORD waittime = (timeout < INFINITE) ? ((timeout < 0) ? 0 : static_cast(timeout)) : (INFINITE - 1); + bool ret = wait_impl(lock, waittime) || (timeout >= INFINITE); + return ret?cv_status::no_timeout:cv_status::timeout; + } + + template + bool wait_for(M& lock, + const std::chrono::duration& rel_time, Predicate pred) + { + return wait_until(lock, std::chrono::steady_clock::now()+rel_time, pred); + } + template + cv_status wait_until (M& lock, + const std::chrono::time_point& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template + bool wait_until (M& lock, + const std::chrono::time_point& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; +class condition_variable: condition_variable_any +{ + using base = condition_variable_any; +public: + using base::native_handle_type; + using base::native_handle; + using base::base; + using base::notify_all; + using base::notify_one; + void wait(unique_lock &lock) + { + base::wait(lock); + } + template + void wait(unique_lock& lock, Predicate pred) + { + base::wait(lock, pred); + } + template + cv_status wait_for(unique_lock& lock, const std::chrono::duration& rel_time) + { + return base::wait_for(lock, rel_time); + } + template + bool wait_for(unique_lock& lock, const std::chrono::duration& rel_time, Predicate pred) + { + return base::wait_for(lock, rel_time, pred); + } + template + cv_status wait_until (unique_lock& lock, const std::chrono::time_point& abs_time) + { + return base::wait_until(lock, abs_time); + } + template + bool wait_until (unique_lock& lock, const std::chrono::time_point& abs_time, Predicate pred) + { + return base::wait_until(lock, abs_time, pred); + } +}; +#endif // Compiling for XP +} // Namespace mingw_stdthread::xp + +#if (WINVER >= _WIN32_WINNT_VISTA) +namespace vista +{ +// If compiling for Vista or higher, use the native condition variable. +class condition_variable +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" + CONDITION_VARIABLE cvariable_ = CONDITION_VARIABLE_INIT; +#pragma GCC diagnostic pop + + friend class condition_variable_any; + +#if STDMUTEX_RECURSION_CHECKS + template + inline static void before_wait (MTX * pmutex) + { + pmutex->mOwnerThread.checkSetOwnerBeforeUnlock(); + } + template + inline static void after_wait (MTX * pmutex) + { + pmutex->mOwnerThread.setOwnerAfterLock(GetCurrentThreadId()); + } +#else + inline static void before_wait (void *) { } + inline static void after_wait (void *) { } +#endif + + bool wait_impl (unique_lock & lock, DWORD time) + { + using mutex_handle_type = typename xp::mutex::native_handle_type; + static_assert(std::is_same::value, + "Native Win32 condition variable requires std::mutex to \ +use native Win32 critical section objects."); + xp::mutex * pmutex = lock.release(); + before_wait(pmutex); + BOOL success = SleepConditionVariableCS(&cvariable_, + pmutex->native_handle(), + time); + after_wait(pmutex); + lock = unique_lock(*pmutex, adopt_lock); + return success; + } + + bool wait_unique (windows7::mutex * pmutex, DWORD time) + { + before_wait(pmutex); + BOOL success = SleepConditionVariableSRW( native_handle(), + pmutex->native_handle(), + time, +// CONDITION_VARIABLE_LOCKMODE_SHARED has a value not specified by +// Microsoft's Dev Center, but is known to be (convertible to) a ULONG. To +// ensure that the value passed to this function is not equal to Microsoft's +// constant, we can either use a static_assert, or simply generate an +// appropriate value. + !CONDITION_VARIABLE_LOCKMODE_SHARED); + after_wait(pmutex); + return success; + } + bool wait_impl (unique_lock & lock, DWORD time) + { + windows7::mutex * pmutex = lock.release(); + bool success = wait_unique(pmutex, time); + lock = unique_lock(*pmutex, adopt_lock); + return success; + } +public: + using native_handle_type = PCONDITION_VARIABLE; + native_handle_type native_handle (void) + { + return &cvariable_; + } + + condition_variable (void) = default; + ~condition_variable (void) = default; + + condition_variable (const condition_variable &) = delete; + condition_variable & operator= (const condition_variable &) = delete; + + void notify_one (void) noexcept + { + WakeConditionVariable(&cvariable_); + } + + void notify_all (void) noexcept + { + WakeAllConditionVariable(&cvariable_); + } + + void wait (unique_lock & lock) + { + wait_impl(lock, INFINITE); + } + + template + void wait (unique_lock & lock, Predicate pred) + { + while (!pred()) + wait(lock); + } + + template + cv_status wait_for(unique_lock& lock, + const std::chrono::duration& rel_time) + { + using namespace std::chrono; + auto timeout = duration_cast(rel_time).count(); + DWORD waittime = (timeout < INFINITE) ? ((timeout < 0) ? 0 : static_cast(timeout)) : (INFINITE - 1); + bool result = wait_impl(lock, waittime) || (timeout >= INFINITE); + return result ? cv_status::no_timeout : cv_status::timeout; + } + + template + bool wait_for(unique_lock& lock, + const std::chrono::duration& rel_time, + Predicate pred) + { + return wait_until(lock, + std::chrono::steady_clock::now() + rel_time, + std::move(pred)); + } + template + cv_status wait_until (unique_lock& lock, + const std::chrono::time_point& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template + bool wait_until (unique_lock& lock, + const std::chrono::time_point& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; + +class condition_variable_any +{ + using native_shared_mutex = windows7::shared_mutex; + + condition_variable internal_cv_ {}; +// When available, the SRW-based mutexes should be faster than the +// CriticalSection-based mutexes. Only try_lock will be unavailable in Vista, +// and try_lock is not used by condition_variable_any. + windows7::mutex internal_mutex_ {}; + + template + bool wait_impl (L & lock, DWORD time) + { + unique_lock internal_lock(internal_mutex_); + lock.unlock(); + bool success = internal_cv_.wait_impl(internal_lock, time); + lock.lock(); + return success; + } +// If the lock happens to be called on a native Windows mutex, skip any extra +// contention. + inline bool wait_impl (unique_lock & lock, DWORD time) + { + return internal_cv_.wait_impl(lock, time); + } +// Some shared_mutex functionality is available even in Vista, but it's not +// until Windows 7 that a full implementation is natively possible. The class +// itself is defined, with missing features, at the Vista feature level. + bool wait_impl (unique_lock & lock, DWORD time) + { + native_shared_mutex * pmutex = lock.release(); + bool success = internal_cv_.wait_unique(pmutex, time); + lock = unique_lock(*pmutex, adopt_lock); + return success; + } + bool wait_impl (shared_lock & lock, DWORD time) + { + native_shared_mutex * pmutex = lock.release(); + BOOL success = SleepConditionVariableSRW(native_handle(), + pmutex->native_handle(), time, + CONDITION_VARIABLE_LOCKMODE_SHARED); + lock = shared_lock(*pmutex, adopt_lock); + return success; + } +public: + using native_handle_type = typename condition_variable::native_handle_type; + + native_handle_type native_handle (void) + { + return internal_cv_.native_handle(); + } + + void notify_one (void) noexcept + { + internal_cv_.notify_one(); + } + + void notify_all (void) noexcept + { + internal_cv_.notify_all(); + } + + condition_variable_any (void) = default; + ~condition_variable_any (void) = default; + + template + void wait (L & lock) + { + wait_impl(lock, INFINITE); + } + + template + void wait (L & lock, Predicate pred) + { + while (!pred()) + wait(lock); + } + + template + cv_status wait_for(L& lock, const std::chrono::duration& period) + { + using namespace std::chrono; + auto timeout = duration_cast(period).count(); + DWORD waittime = (timeout < INFINITE) ? ((timeout < 0) ? 0 : static_cast(timeout)) : (INFINITE - 1); + bool result = wait_impl(lock, waittime) || (timeout >= INFINITE); + return result ? cv_status::no_timeout : cv_status::timeout; + } + + template + bool wait_for(L& lock, const std::chrono::duration& period, + Predicate pred) + { + return wait_until(lock, std::chrono::steady_clock::now() + period, + std::move(pred)); + } + template + cv_status wait_until (L& lock, + const std::chrono::time_point& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template + bool wait_until (L& lock, + const std::chrono::time_point& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; +} // Namespace vista +#endif +#if WINVER < 0x0600 +using xp::condition_variable; +using xp::condition_variable_any; +#else +using vista::condition_variable; +using vista::condition_variable_any; +#endif +} // Namespace mingw_stdthread + +// Push objects into std, but only if they are not already there. +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::cv_status; +using mingw_stdthread::condition_variable; +using mingw_stdthread::condition_variable_any; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} +#endif // MINGW_CONDITIONAL_VARIABLE_H diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/mutex b/src/third-party/discord-rpc/include/mingw-std-threads/mutex new file mode 100644 index 000000000..343698ebf --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/mutex @@ -0,0 +1,474 @@ +/** +* @file mingw.mutex.h +* @brief std::mutex et al implementation for MinGW +** (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef WIN32STDMUTEX_H +#define WIN32STDMUTEX_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif +// Recursion checks on non-recursive locks have some performance penalty, and +// the C++ standard does not mandate them. The user might want to explicitly +// enable or disable such checks. If the user has no preference, enable such +// checks in debug builds, but not in release builds. +#ifdef STDMUTEX_RECURSION_CHECKS +#elif defined(NDEBUG) +#define STDMUTEX_RECURSION_CHECKS 0 +#else +#define STDMUTEX_RECURSION_CHECKS 1 +#endif + +#include +#include +#include +#include_next //need for call_once() + +#if STDMUTEX_RECURSION_CHECKS || !defined(NDEBUG) +#include +#endif + +#include + +// Need for the implementation of invoke +#include + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +namespace mingw_stdthread +{ +// The _NonRecursive class has mechanisms that do not play nice with direct +// manipulation of the native handle. This forward declaration is part of +// a friend class declaration. +#if STDMUTEX_RECURSION_CHECKS +namespace vista +{ +class condition_variable; +} +#endif +// To make this namespace equivalent to the thread-related subset of std, +// pull in the classes and class templates supplied by std but not by this +// implementation. +using std::lock_guard; +using std::unique_lock; +using std::adopt_lock_t; +using std::defer_lock_t; +using std::try_to_lock_t; +using std::adopt_lock; +using std::defer_lock; +using std::try_to_lock; + +class recursive_mutex +{ + CRITICAL_SECTION mHandle; +public: + typedef LPCRITICAL_SECTION native_handle_type; + native_handle_type native_handle() {return &mHandle;} + recursive_mutex() noexcept : mHandle() + { + InitializeCriticalSection(&mHandle); + } + recursive_mutex (const recursive_mutex&) = delete; + recursive_mutex& operator=(const recursive_mutex&) = delete; + ~recursive_mutex() noexcept + { + DeleteCriticalSection(&mHandle); + } + void lock() + { + EnterCriticalSection(&mHandle); + } + void unlock() + { + LeaveCriticalSection(&mHandle); + } + bool try_lock() + { + return (TryEnterCriticalSection(&mHandle)!=0); + } +}; + +#if STDMUTEX_RECURSION_CHECKS +struct _OwnerThread +{ +// If this is to be read before locking, then the owner-thread variable must +// be atomic to prevent a torn read from spuriously causing errors. + std::atomic mOwnerThread; + constexpr _OwnerThread () noexcept : mOwnerThread(0) {} + static void on_deadlock (void) + { + using namespace std; + fprintf(stderr, "FATAL: Recursive locking of non-recursive mutex\ + detected. Throwing system exception\n"); + fflush(stderr); + throw system_error(make_error_code(errc::resource_deadlock_would_occur)); + } + DWORD checkOwnerBeforeLock() const + { + DWORD self = GetCurrentThreadId(); + if (mOwnerThread.load(std::memory_order_relaxed) == self) + on_deadlock(); + return self; + } + void setOwnerAfterLock(DWORD id) + { + mOwnerThread.store(id, std::memory_order_relaxed); + } + void checkSetOwnerBeforeUnlock() + { + DWORD self = GetCurrentThreadId(); + if (mOwnerThread.load(std::memory_order_relaxed) != self) + on_deadlock(); + mOwnerThread.store(0, std::memory_order_relaxed); + } +}; +#endif + +// Though the Slim Reader-Writer (SRW) locks used here are not complete until +// Windows 7, implementing partial functionality in Vista will simplify the +// interaction with condition variables. +#if defined(_WIN32) && (WINVER >= _WIN32_WINNT_VISTA) +namespace windows7 +{ +class mutex +{ + SRWLOCK mHandle; +// Track locking thread for error checking. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef PSRWLOCK native_handle_type; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" + constexpr mutex () noexcept : mHandle(SRWLOCK_INIT) { } +#pragma GCC diagnostic pop + mutex (const mutex&) = delete; + mutex & operator= (const mutex&) = delete; + void lock (void) + { +// Note: Undefined behavior if called recursively. +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + AcquireSRWLockExclusive(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + ReleaseSRWLockExclusive(&mHandle); + } +// TryAcquireSRW functions are a Windows 7 feature. +#if (WINVER >= _WIN32_WINNT_WIN7) + bool try_lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + BOOL ret = TryAcquireSRWLockExclusive(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } +#endif + native_handle_type native_handle (void) + { + return &mHandle; + } +}; +} // Namespace windows7 +#endif // Compiling for Vista +namespace xp +{ +class mutex +{ + CRITICAL_SECTION mHandle; + std::atomic_uchar mState; +// Track locking thread for error checking. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef PCRITICAL_SECTION native_handle_type; + constexpr mutex () noexcept : mHandle(), mState(2) { } + mutex (const mutex&) = delete; + mutex & operator= (const mutex&) = delete; + ~mutex() noexcept + { +// Undefined behavior if the mutex is held (locked) by any thread. +// Undefined behavior if a thread terminates while holding ownership of the +// mutex. + DeleteCriticalSection(&mHandle); + } + void lock (void) + { + unsigned char state = mState.load(std::memory_order_acquire); + while (state) { + if ((state == 2) && mState.compare_exchange_weak(state, 1, std::memory_order_acquire)) + { + InitializeCriticalSection(&mHandle); + mState.store(0, std::memory_order_release); + break; + } + if (state == 1) + { + Sleep(0); + state = mState.load(std::memory_order_acquire); + } + } +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + EnterCriticalSection(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + LeaveCriticalSection(&mHandle); + } + bool try_lock (void) + { + unsigned char state = mState.load(std::memory_order_acquire); + if ((state == 2) && mState.compare_exchange_strong(state, 1, std::memory_order_acquire)) + { + InitializeCriticalSection(&mHandle); + mState.store(0, std::memory_order_release); + } + if (state == 1) + return false; +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + BOOL ret = TryEnterCriticalSection(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } + native_handle_type native_handle (void) + { + return &mHandle; + } +}; +} // Namespace "xp" +#if (WINVER >= _WIN32_WINNT_WIN7) +using windows7::mutex; +#else +using xp::mutex; +#endif + +class recursive_timed_mutex +{ + inline bool try_lock_internal (DWORD ms) noexcept + { + DWORD ret = WaitForSingleObject(mHandle, ms); +#ifndef NDEBUG + if (ret == WAIT_ABANDONED) + { + using namespace std; + fprintf(stderr, "FATAL: Thread terminated while holding a mutex."); + terminate(); + } +#endif + return (ret == WAIT_OBJECT_0) || (ret == WAIT_ABANDONED); + } +protected: + HANDLE mHandle; +// Track locking thread for error checking of non-recursive timed_mutex. For +// standard compliance, this must be defined in same class and at the same +// access-control level as every other variable in the timed_mutex. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef HANDLE native_handle_type; + native_handle_type native_handle() const {return mHandle;} + recursive_timed_mutex(const recursive_timed_mutex&) = delete; + recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; + recursive_timed_mutex(): mHandle(CreateMutex(NULL, FALSE, NULL)) {} + ~recursive_timed_mutex() + { + CloseHandle(mHandle); + } + void lock() + { + DWORD ret = WaitForSingleObject(mHandle, INFINITE); +// If (ret == WAIT_ABANDONED), then the thread that held ownership was +// terminated. Behavior is undefined, but Windows will pass ownership to this +// thread. +#ifndef NDEBUG + if (ret == WAIT_ABANDONED) + { + using namespace std; + fprintf(stderr, "FATAL: Thread terminated while holding a mutex."); + terminate(); + } +#endif + if ((ret != WAIT_OBJECT_0) && (ret != WAIT_ABANDONED)) + { + throw std::system_error(GetLastError(), std::system_category()); + } + } + void unlock() + { + if (!ReleaseMutex(mHandle)) + throw std::system_error(GetLastError(), std::system_category()); + } + bool try_lock() + { + return try_lock_internal(0); + } + template + bool try_lock_for(const std::chrono::duration& dur) + { + using namespace std::chrono; + auto timeout = duration_cast(dur).count(); + while (timeout > 0) + { + constexpr auto kMaxStep = static_cast(INFINITE-1); + auto step = (timeout < kMaxStep) ? timeout : kMaxStep; + if (try_lock_internal(static_cast(step))) + return true; + timeout -= step; + } + return false; + } + template + bool try_lock_until(const std::chrono::time_point& timeout_time) + { + return try_lock_for(timeout_time - Clock::now()); + } +}; + +// Override if, and only if, it is necessary for error-checking. +#if STDMUTEX_RECURSION_CHECKS +class timed_mutex: recursive_timed_mutex +{ +public: + timed_mutex(const timed_mutex&) = delete; + timed_mutex& operator=(const timed_mutex&) = delete; + void lock() + { + DWORD self = mOwnerThread.checkOwnerBeforeLock(); + recursive_timed_mutex::lock(); + mOwnerThread.setOwnerAfterLock(self); + } + void unlock() + { + mOwnerThread.checkSetOwnerBeforeUnlock(); + recursive_timed_mutex::unlock(); + } + template + bool try_lock_for(const std::chrono::duration& dur) + { + DWORD self = mOwnerThread.checkOwnerBeforeLock(); + bool ret = recursive_timed_mutex::try_lock_for(dur); + if (ret) + mOwnerThread.setOwnerAfterLock(self); + return ret; + } + template + bool try_lock_until(const std::chrono::time_point& timeout_time) + { + return try_lock_for(timeout_time - Clock::now()); + } + bool try_lock () + { + return try_lock_for(std::chrono::milliseconds(0)); + } +}; +#else +typedef recursive_timed_mutex timed_mutex; +#endif + +class once_flag +{ +// When available, the SRW-based mutexes should be faster than the +// CriticalSection-based mutexes. Only try_lock will be unavailable in Vista, +// and try_lock is not used by once_flag. +#if (_WIN32_WINNT == _WIN32_WINNT_VISTA) + windows7::mutex mMutex; +#else + mutex mMutex; +#endif + std::atomic_bool mHasRun; + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; + template + friend void call_once(once_flag& once, Callable&& f, Args&&... args); +public: + constexpr once_flag() noexcept: mMutex(), mHasRun(false) {} +}; + +template +void call_once(once_flag& flag, Callable&& func, Args&&... args) +{ + if (flag.mHasRun.load(std::memory_order_acquire)) + return; + lock_guard lock(flag.mMutex); + if (flag.mHasRun.load(std::memory_order_acquire)) + return; + detail::invoke(std::forward(func),std::forward(args)...); + flag.mHasRun.store(true, std::memory_order_release); +} +} // Namespace mingw_stdthread + +// Push objects into std, but only if they are not already there. +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::recursive_mutex; +using mingw_stdthread::mutex; +using mingw_stdthread::recursive_timed_mutex; +using mingw_stdthread::timed_mutex; +using mingw_stdthread::once_flag; +using mingw_stdthread::call_once; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} +#endif // WIN32STDMUTEX_H diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/thread b/src/third-party/discord-rpc/include/mingw-std-threads/thread new file mode 100644 index 000000000..7f2ea728c --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/thread @@ -0,0 +1,410 @@ +/** +* @file mingw.thread.h +* @brief std::thread implementation for MinGW +* (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef WIN32STDTHREAD_H +#define WIN32STDTHREAD_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif + +// Use the standard classes for std::, if available. +#include_next + +#include // For std::size_t +#include // Detect error type. +#include // For std::terminate +#include // For std::system_error +#include // For std::hash +#include // For std::tuple +#include // For sleep timing. +#include // For std::unique_ptr +#include // Stream output for thread ids. +#include // For std::swap, std::forward + +// For the invoke implementation only: +#include // For std::result_of, etc. +//#include // For std::forward +//#include // For std::reference_wrapper + +#include +#include // For _beginthreadex + +#ifndef NDEBUG +#include +#endif + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +// Instead of INVALID_HANDLE_VALUE, _beginthreadex returns 0. +namespace mingw_stdthread +{ +namespace detail +{ +// For compatibility, implement std::invoke for C++11 and C++14 +#if __cplusplus < 201703L + template + struct Invoker + { + template + inline static typename std::result_of::type invoke (F&& f, Args&&... args) + { + return std::forward(f)(std::forward(args)...); + } + }; + template + struct InvokerHelper; + + template<> + struct InvokerHelper + { + template + inline static auto get (T1&& t1) -> decltype(*std::forward(t1)) + { + return *std::forward(t1); + } + + template + inline static auto get (const std::reference_wrapper& t1) -> decltype(t1.get()) + { + return t1.get(); + } + }; + + template<> + struct InvokerHelper + { + template + inline static auto get (T1&& t1) -> decltype(std::forward(t1)) + { + return std::forward(t1); + } + }; + + template<> + struct Invoker + { + template + inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\ + decltype((InvokerHelper::type>::value>::get(std::forward(t1)).*f)(std::forward(args)...)) + { + return (InvokerHelper::type>::value>::get(std::forward(t1)).*f)(std::forward(args)...); + } + }; + + template<> + struct Invoker + { + template + inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\ + decltype(InvokerHelper::type>::value>::get(t1).*f) + { + return InvokerHelper::type>::value>::get(t1).*f; + } + }; + + template + struct InvokeResult + { + typedef Invoker::type>::value, + std::is_member_object_pointer::type>::value && + (sizeof...(Args) == 1)> invoker; + inline static auto invoke (F&& f, Args&&... args) -> decltype(invoker::invoke(std::forward(f), std::forward(args)...)) + { + return invoker::invoke(std::forward(f), std::forward(args)...); + }; + }; + + template + auto invoke (F&& f, Args&&... args) -> decltype(InvokeResult::invoke(std::forward(f), std::forward(args)...)) + { + return InvokeResult::invoke(std::forward(f), std::forward(args)...); + } +#else + using std::invoke; +#endif + + template + struct IntSeq {}; + + template + struct GenIntSeq : GenIntSeq { }; + + template + struct GenIntSeq<0, S...> { typedef IntSeq type; }; + + // We can't define the Call struct in the function - the standard forbids template methods in that case + template + class ThreadFuncCall + { + typedef std::tuple Tuple; + Func mFunc; + Tuple mArgs; + + template + void callFunc(detail::IntSeq) + { + detail::invoke(std::forward(mFunc), std::get(std::forward(mArgs)) ...); + } + public: + ThreadFuncCall(Func&& aFunc, Args&&... aArgs) + :mFunc(std::forward(aFunc)), mArgs(std::forward(aArgs)...){} + + void callFunc() + { + callFunc(typename detail::GenIntSeq::type()); + } + }; + +} // Namespace "detail" + +class thread +{ +public: + class id + { + DWORD mId; + void clear() {mId = 0;} + friend class thread; + friend class std::hash; + public: + explicit id(DWORD aId=0) noexcept : mId(aId){} + friend bool operator==(id x, id y) noexcept {return x.mId == y.mId; } + friend bool operator!=(id x, id y) noexcept {return x.mId != y.mId; } + friend bool operator< (id x, id y) noexcept {return x.mId < y.mId; } + friend bool operator<=(id x, id y) noexcept {return x.mId <= y.mId; } + friend bool operator> (id x, id y) noexcept {return x.mId > y.mId; } + friend bool operator>=(id x, id y) noexcept {return x.mId >= y.mId; } + + template + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __out, id __id) + { + if (__id.mId == 0) + { + return __out << "(invalid std::thread::id)"; + } + else + { + return __out << __id.mId; + } + } + }; +private: + static constexpr HANDLE kInvalidHandle = nullptr; + HANDLE mHandle; + id mThreadId; + + template + static unsigned __stdcall threadfunc(void* arg) + { + std::unique_ptr call(static_cast(arg)); + call->callFunc(); + return 0; + } + + static unsigned int _hardware_concurrency_helper() noexcept + { + SYSTEM_INFO sysinfo; +// This is one of the few functions used by the library which has a nearly- +// equivalent function defined in earlier versions of Windows. Include the +// workaround, just as a reminder that it does exist. +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) + ::GetNativeSystemInfo(&sysinfo); +#else + ::GetSystemInfo(&sysinfo); +#endif + return sysinfo.dwNumberOfProcessors; + } +public: + typedef HANDLE native_handle_type; + id get_id() const noexcept {return mThreadId;} + native_handle_type native_handle() const {return mHandle;} + thread(): mHandle(kInvalidHandle), mThreadId(){} + + thread(thread&& other) + :mHandle(other.mHandle), mThreadId(other.mThreadId) + { + other.mHandle = kInvalidHandle; + other.mThreadId.clear(); + } + + thread(const thread &other)=delete; + + template + explicit thread(Func&& func, Args&&... args) : mHandle(), mThreadId() + { + typedef detail::ThreadFuncCall Call; + auto call = new Call( + std::forward(func), std::forward(args)...); + auto int_handle = _beginthreadex(NULL, 0, threadfunc, + static_cast(call), 0, + reinterpret_cast(&(mThreadId.mId))); + if (int_handle == 0) + { + mHandle = kInvalidHandle; + int errnum = errno; + delete call; +// Note: Should only throw EINVAL, EAGAIN, EACCES + throw std::system_error(errnum, std::generic_category()); + } else + mHandle = reinterpret_cast(int_handle); + } + + bool joinable() const {return mHandle != kInvalidHandle;} + +// Note: Due to lack of synchronization, this function has a race condition +// if called concurrently, which leads to undefined behavior. The same applies +// to all other member functions of this class, but this one is mentioned +// explicitly. + void join() + { + using namespace std; + if (get_id() == id(GetCurrentThreadId())) + throw system_error(make_error_code(errc::resource_deadlock_would_occur)); + if (mHandle == kInvalidHandle) + throw system_error(make_error_code(errc::no_such_process)); + if (!joinable()) + throw system_error(make_error_code(errc::invalid_argument)); + WaitForSingleObject(mHandle, INFINITE); + CloseHandle(mHandle); + mHandle = kInvalidHandle; + mThreadId.clear(); + } + + ~thread() + { + if (joinable()) + { +#ifndef NDEBUG + std::printf("Error: Must join() or detach() a thread before \ +destroying it.\n"); +#endif + std::terminate(); + } + } + thread& operator=(const thread&) = delete; + thread& operator=(thread&& other) noexcept + { + if (joinable()) + { +#ifndef NDEBUG + std::printf("Error: Must join() or detach() a thread before \ +moving another thread to it.\n"); +#endif + std::terminate(); + } + swap(std::forward(other)); + return *this; + } + void swap(thread&& other) noexcept + { + std::swap(mHandle, other.mHandle); + std::swap(mThreadId.mId, other.mThreadId.mId); + } + + static unsigned int hardware_concurrency() noexcept + { + static unsigned int cached = _hardware_concurrency_helper(); + return cached; + } + + void detach() + { + if (!joinable()) + { + using namespace std; + throw system_error(make_error_code(errc::invalid_argument)); + } + if (mHandle != kInvalidHandle) + { + CloseHandle(mHandle); + mHandle = kInvalidHandle; + } + mThreadId.clear(); + } +}; + +namespace this_thread +{ + inline thread::id get_id() noexcept {return thread::id(GetCurrentThreadId());} + inline void yield() noexcept {Sleep(0);} + template< class Rep, class Period > + void sleep_for( const std::chrono::duration& sleep_duration) + { + using namespace std::chrono; + using rep = milliseconds::rep; + rep ms = duration_cast(sleep_duration).count(); + while (ms > 0) + { + constexpr rep kMaxRep = static_cast(INFINITE - 1); + auto sleepTime = (ms < kMaxRep) ? ms : kMaxRep; + Sleep(static_cast(sleepTime)); + ms -= sleepTime; + } + } + template + void sleep_until(const std::chrono::time_point& sleep_time) + { + sleep_for(sleep_time-Clock::now()); + } +} +} // Namespace mingw_stdthread + +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::thread; +// Remove ambiguity immediately, to avoid problems arising from the above. +//using std::thread; +namespace this_thread +{ +using namespace mingw_stdthread::this_thread; +} +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif + +// Specialize hash for this implementation's thread::id, even if the +// std::thread::id already has a hash. +template<> +struct hash +{ + typedef mingw_stdthread::thread::id argument_type; + typedef size_t result_type; + size_t operator() (const argument_type & i) const noexcept + { + return i.mId; + } +}; +} +#endif // WIN32STDTHREAD_H diff --git a/src/third-party/discord-rpc/src/CMakeLists.txt b/src/third-party/discord-rpc/src/CMakeLists.txt index 0db91902c..26411c968 100644 --- a/src/third-party/discord-rpc/src/CMakeLists.txt +++ b/src/third-party/discord-rpc/src/CMakeLists.txt @@ -22,6 +22,9 @@ set(BASE_RPC_SRC if(WIN32) add_definitions(-DDISCORD_WINDOWS) set(BASE_RPC_SRC ${BASE_RPC_SRC} connection_win.cpp discord_register_win.cpp) + if (NOT MSVC) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/mingw-std-threads) + endif() add_library(discord-rpc STATIC ${BASE_RPC_SRC}) if (MSVC) if(USE_STATIC_CRT) From 0292958239166c0e375ecc5f04aa129b6fa51498 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 22:41:53 -0700 Subject: [PATCH 112/429] Third-Party: Add missing file again --- .../include/mingw-std-threads/shared_mutex | 497 ++++++++++++++++++ 1 file changed, 497 insertions(+) create mode 100644 src/third-party/discord-rpc/include/mingw-std-threads/shared_mutex diff --git a/src/third-party/discord-rpc/include/mingw-std-threads/shared_mutex b/src/third-party/discord-rpc/include/mingw-std-threads/shared_mutex new file mode 100644 index 000000000..b49df5b6f --- /dev/null +++ b/src/third-party/discord-rpc/include/mingw-std-threads/shared_mutex @@ -0,0 +1,497 @@ +/// \file mingw.shared_mutex.h +/// \brief Standard-compliant shared_mutex for MinGW +/// +/// (c) 2017 by Nathaniel J. McClatchey, Athens OH, United States +/// \author Nathaniel J. McClatchey +/// +/// \copyright Simplified (2-clause) BSD License. +/// +/// \note This file may become part of the mingw-w64 runtime package. If/when +/// this happens, the appropriate license will be added, i.e. this code will +/// become dual-licensed, and the current BSD 2-clause license will stay. +/// \note Target Windows version is determined by WINVER, which is determined in +/// from _WIN32_WINNT, which can itself be set by the user. + +// Notes on the namespaces: +// - The implementation can be accessed directly in the namespace +// mingw_stdthread. +// - Objects will be brought into namespace std by a using directive. This +// will cause objects declared in std (such as MinGW's implementation) to +// hide this implementation's definitions. +// - To avoid poluting the namespace with implementation details, all objects +// to be pushed into std will be placed in mingw_stdthread::visible. +// The end result is that if MinGW supplies an object, it is automatically +// used. If MinGW does not supply an object, this implementation's version will +// instead be used. + +#ifndef MINGW_SHARED_MUTEX_H_ +#define MINGW_SHARED_MUTEX_H_ + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif + +#include +// For descriptive errors. +#include +// Implementing a shared_mutex without OS support will require atomic read- +// modify-write capacity. +#include +// For timing in shared_lock and shared_timed_mutex. +#include +#include + +// Use MinGW's shared_lock class template, if it's available. Requires C++14. +// If unavailable (eg. because this library is being used in C++11), then an +// implementation of shared_lock is provided by this header. +#if (__cplusplus >= 201402L) +#include_next +#endif + +// For defer_lock_t, adopt_lock_t, and try_to_lock_t +#include +// For this_thread::yield. +#include + +// Might be able to use native Slim Reader-Writer (SRW) locks. +#ifdef _WIN32 +#include +#endif + +namespace mingw_stdthread +{ +// Define a portable atomics-based shared_mutex +namespace portable +{ +class shared_mutex +{ + typedef uint_fast16_t counter_type; + std::atomic mCounter {0}; + static constexpr counter_type kWriteBit = 1 << (std::numeric_limits::digits - 1); + +#if STDMUTEX_RECURSION_CHECKS +// Runtime checker for verifying owner threads. Note: Exclusive mode only. + _OwnerThread mOwnerThread {}; +#endif +public: + typedef shared_mutex * native_handle_type; + + shared_mutex () = default; + +// No form of copying or moving should be allowed. + shared_mutex (const shared_mutex&) = delete; + shared_mutex & operator= (const shared_mutex&) = delete; + + ~shared_mutex () + { +// Terminate if someone tries to destroy an owned mutex. + assert(mCounter.load(std::memory_order_relaxed) == 0); + } + + void lock_shared (void) + { + counter_type expected = mCounter.load(std::memory_order_relaxed); + do + { +// Delay if writing or if too many readers are attempting to read. + if (expected >= kWriteBit - 1) + { + using namespace std; + using namespace this_thread; + yield(); + expected = mCounter.load(std::memory_order_relaxed); + continue; + } + if (mCounter.compare_exchange_weak(expected, + static_cast(expected + 1), + std::memory_order_acquire, + std::memory_order_relaxed)) + break; + } + while (true); + } + + bool try_lock_shared (void) + { + counter_type expected = mCounter.load(std::memory_order_relaxed) & static_cast(~kWriteBit); + if (expected + 1 == kWriteBit) + return false; + else + return mCounter.compare_exchange_strong( expected, + static_cast(expected + 1), + std::memory_order_acquire, + std::memory_order_relaxed); + } + + void unlock_shared (void) + { + using namespace std; +#ifndef NDEBUG + if (!(mCounter.fetch_sub(1, memory_order_release) & static_cast(~kWriteBit))) + throw system_error(make_error_code(errc::operation_not_permitted)); +#else + mCounter.fetch_sub(1, memory_order_release); +#endif + } + +// Behavior is undefined if a lock was previously acquired. + void lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + using namespace std; +// Might be able to use relaxed memory order... +// Wait for the write-lock to be unlocked, then claim the write slot. + counter_type current; + while ((current = mCounter.fetch_or(kWriteBit, std::memory_order_acquire)) & kWriteBit) + this_thread::yield(); +// Wait for readers to finish up. + while (current != kWriteBit) + { + this_thread::yield(); + current = mCounter.load(std::memory_order_acquire); + } +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + + bool try_lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + counter_type expected = 0; + bool ret = mCounter.compare_exchange_strong(expected, kWriteBit, + std::memory_order_acquire, + std::memory_order_relaxed); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } + + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + using namespace std; +#ifndef NDEBUG + if (mCounter.load(memory_order_relaxed) != kWriteBit) + throw system_error(make_error_code(errc::operation_not_permitted)); +#endif + mCounter.store(0, memory_order_release); + } + + native_handle_type native_handle (void) + { + return this; + } +}; + +} // Namespace portable + +// The native shared_mutex implementation primarily uses features of Windows +// Vista, but the features used for try_lock and try_lock_shared were not +// introduced until Windows 7. To allow limited use while compiling for Vista, +// I define the class without try_* functions in that case. +// Only fully-featured implementations will be placed into namespace std. +#if defined(_WIN32) && (WINVER >= _WIN32_WINNT_VISTA) +namespace vista +{ +class condition_variable_any; +} + +namespace windows7 +{ +// We already #include "mingw.mutex.h". May as well reduce redundancy. +class shared_mutex : windows7::mutex +{ +// Allow condition_variable_any (and only condition_variable_any) to treat a +// shared_mutex as its base class. + friend class vista::condition_variable_any; +public: + using windows7::mutex::native_handle_type; + using windows7::mutex::lock; + using windows7::mutex::unlock; + using windows7::mutex::native_handle; + + void lock_shared (void) + { + AcquireSRWLockShared(native_handle()); + } + + void unlock_shared (void) + { + ReleaseSRWLockShared(native_handle()); + } + +// TryAcquireSRW functions are a Windows 7 feature. +#if (WINVER >= _WIN32_WINNT_WIN7) + bool try_lock_shared (void) + { + return TryAcquireSRWLockShared(native_handle()) != 0; + } + + using windows7::mutex::try_lock; +#endif +}; + +} // Namespace windows7 +#endif // Compiling for Vista +#if (defined(_WIN32) && (WINVER >= _WIN32_WINNT_WIN7)) +using windows7::shared_mutex; +#else +using portable::shared_mutex; +#endif + +class shared_timed_mutex : shared_mutex +{ + typedef shared_mutex Base; +public: + using Base::lock; + using Base::try_lock; + using Base::unlock; + using Base::lock_shared; + using Base::try_lock_shared; + using Base::unlock_shared; + + template< class Clock, class Duration > + bool try_lock_until ( const std::chrono::time_point& cutoff ) + { + do + { + if (try_lock()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_for (const std::chrono::duration& rel_time) + { + return try_lock_until(std::chrono::steady_clock::now() + rel_time); + } + + template< class Clock, class Duration > + bool try_lock_shared_until ( const std::chrono::time_point& cutoff ) + { + do + { + if (try_lock_shared()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_shared_for (const std::chrono::duration& rel_time) + { + return try_lock_shared_until(std::chrono::steady_clock::now() + rel_time); + } +}; + +#if __cplusplus >= 201402L +using std::shared_lock; +#else +// If not supplied by shared_mutex (eg. because C++14 is not supported), I +// supply the various helper classes that the header should have defined. +template +class shared_lock +{ + Mutex * mMutex; + bool mOwns; +// Reduce code redundancy + void verify_lockable (void) + { + using namespace std; + if (mMutex == nullptr) + throw system_error(make_error_code(errc::operation_not_permitted)); + if (mOwns) + throw system_error(make_error_code(errc::resource_deadlock_would_occur)); + } +public: + typedef Mutex mutex_type; + + shared_lock (void) noexcept + : mMutex(nullptr), mOwns(false) + { + } + + shared_lock (shared_lock && other) noexcept + : mMutex(other.mutex_), mOwns(other.owns_) + { + other.mMutex = nullptr; + other.mOwns = false; + } + + explicit shared_lock (mutex_type & m) + : mMutex(&m), mOwns(true) + { + mMutex->lock_shared(); + } + + shared_lock (mutex_type & m, defer_lock_t) noexcept + : mMutex(&m), mOwns(false) + { + } + + shared_lock (mutex_type & m, adopt_lock_t) + : mMutex(&m), mOwns(true) + { + } + + shared_lock (mutex_type & m, try_to_lock_t) + : mMutex(&m), mOwns(m.try_lock_shared()) + { + } + + template< class Rep, class Period > + shared_lock( mutex_type& m, const std::chrono::duration& timeout_duration ) + : mMutex(&m), mOwns(m.try_lock_shared_for(timeout_duration)) + { + } + + template< class Clock, class Duration > + shared_lock( mutex_type& m, const std::chrono::time_point& timeout_time ) + : mMutex(&m), mOwns(m.try_lock_shared_until(timeout_time)) + { + } + + shared_lock& operator= (shared_lock && other) noexcept + { + if (&other != this) + { + if (mOwns) + mMutex->unlock_shared(); + mMutex = other.mMutex; + mOwns = other.mOwns; + other.mMutex = nullptr; + other.mOwns = false; + } + return *this; + } + + + ~shared_lock (void) + { + if (mOwns) + mMutex->unlock_shared(); + } + + shared_lock (const shared_lock &) = delete; + shared_lock& operator= (const shared_lock &) = delete; + +// Shared locking + void lock (void) + { + verify_lockable(); + mMutex->lock_shared(); + mOwns = true; + } + + bool try_lock (void) + { + verify_lockable(); + mOwns = mMutex->try_lock_shared(); + return mOwns; + } + + template< class Clock, class Duration > + bool try_lock_until( const std::chrono::time_point& cutoff ) + { + verify_lockable(); + do + { + mOwns = mMutex->try_lock_shared(); + if (mOwns) + return mOwns; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_for (const std::chrono::duration& rel_time) + { + return try_lock_until(std::chrono::steady_clock::now() + rel_time); + } + + void unlock (void) + { + using namespace std; + if (!mOwns) + throw system_error(make_error_code(errc::operation_not_permitted)); + mMutex->unlock_shared(); + mOwns = false; + } + +// Modifiers + void swap (shared_lock & other) noexcept + { + using namespace std; + swap(mMutex, other.mMutex); + swap(mOwns, other.mOwns); + } + + mutex_type * release (void) noexcept + { + mutex_type * ptr = mMutex; + mMutex = nullptr; + mOwns = false; + return ptr; + } +// Observers + mutex_type * mutex (void) const noexcept + { + return mMutex; + } + + bool owns_lock (void) const noexcept + { + return mOwns; + } + + explicit operator bool () const noexcept + { + return owns_lock(); + } +}; + +template< class Mutex > +void swap( shared_lock& lhs, shared_lock& rhs ) noexcept +{ + lhs.swap(rhs); +} +#endif // C++11 +} // Namespace mingw_stdthread + +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if (__cplusplus < 201703L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)) +using mingw_stdthread::shared_mutex; +#endif +#if (__cplusplus < 201402L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)) +using mingw_stdthread::shared_timed_mutex; +using mingw_stdthread::shared_lock; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++ std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} // Namespace std +#endif // MINGW_SHARED_MUTEX_H_ From fd63e3698516d31471eaeecbb06126edd54e805e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 22:47:03 -0700 Subject: [PATCH 113/429] Res: Add missing file --- res/licenses/mingw-std-threads.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 res/licenses/mingw-std-threads.txt diff --git a/res/licenses/mingw-std-threads.txt b/res/licenses/mingw-std-threads.txt new file mode 100644 index 000000000..ac525cf20 --- /dev/null +++ b/res/licenses/mingw-std-threads.txt @@ -0,0 +1,24 @@ +Copyright (c) 2016, Mega Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + From 4cec95c2f1f8d1f263b50d6963ed37290740e23f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 14 Mar 2019 23:02:55 -0700 Subject: [PATCH 114/429] Third-Party: Fix macOS build --- src/third-party/discord-rpc/src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/third-party/discord-rpc/src/CMakeLists.txt b/src/third-party/discord-rpc/src/CMakeLists.txt index 26411c968..ca2659846 100644 --- a/src/third-party/discord-rpc/src/CMakeLists.txt +++ b/src/third-party/discord-rpc/src/CMakeLists.txt @@ -61,6 +61,7 @@ if(UNIX) if (APPLE) add_definitions(-DDISCORD_OSX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") set(BASE_RPC_SRC ${BASE_RPC_SRC} discord_register_osx.m) else (APPLE) add_definitions(-DDISCORD_LINUX) From a41e2dd2253ef1d08b3445a221848c6f849f49f7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 15 Mar 2019 23:09:00 -0700 Subject: [PATCH 115/429] Qt: Fix saved scale not getting set on resize (fixes #1074) --- CHANGES | 1 + src/platform/qt/Window.cpp | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 825ccd81b..08c798468 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Other fixes: - Qt: Fix load recent from archive (fixes mgba.io/i/1325) - LR35902: Fix disassembly of several CB-prefix instructions - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) + - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 8ef5b48e7..e669924bd 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -577,9 +577,8 @@ void Window::resizeEvent(QResizeEvent* event) { if (m_screenWidget->width() % size.width() == 0 && m_screenWidget->height() % size.height() == 0 && m_screenWidget->width() / size.width() == m_screenWidget->height() / size.height()) { factor = m_screenWidget->width() / size.width(); - } else { - m_savedScale = 0; } + m_savedScale = factor; for (QMap::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) { bool enableSignals = iter.value()->blockSignals(true); iter.value()->setChecked(iter.key() == factor); From 1844c26388885986ecd7cb7cdbd02453a342a0f8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 15 Mar 2019 23:21:54 -0700 Subject: [PATCH 116/429] CMake: Add missing link directories (fixes #1358) --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b16c084ac..2649f9f35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -707,6 +707,7 @@ if(USE_EPOXY) add_definitions(-DBUILD_GL -DBUILD_GLES2) list(APPEND FEATURES EPOXY) include_directories(AFTER ${EPOXY_INCLUDE_DIRS}) + link_directories(${EPOXY_LIBRARY_DIRS}) set(OPENGLES2_LIBRARY ${EPOXY_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libepoxy0") endif() @@ -714,6 +715,7 @@ endif() if(USE_SQLITE3) list(APPEND FEATURES SQLITE3) include_directories(AFTER ${SQLITE3_INCLUDE_DIRS}) + link_directories(${SQLITE3_LIBRARY_DIRS}) list(APPEND DEPENDENCY_LIB ${SQLITE3_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libsqlite3-0") list(APPEND FEATURE_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/feature/sqlite3/no-intro.c") @@ -722,6 +724,7 @@ endif() if(USE_ELF) list(APPEND FEATURES ELF) include_directories(AFTER ${LIBELF_INCLUDE_DIRS}) + link_directories(${LIBELF_LIBRARY_DIRS}) list(APPEND DEPENDENCY_LIB ${LIBELF_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libelf1") endif() From c364a6527a83d22bdd79e77286d0b53b0b624746 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 16 Mar 2019 19:37:42 -0700 Subject: [PATCH 117/429] Windows: Fix passing Unicode filenames (fixes #1359) --- CMakeLists.txt | 2 ++ include/mgba-util/common.h | 6 +++++- src/platform/qt/main.cpp | 18 ++++++++++++++++++ src/platform/sdl/main.c | 18 ++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2649f9f35..2628c3e83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,6 +226,8 @@ endif() if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") add_definitions(-D_WIN32_WINNT=0x0600) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") list(APPEND OS_LIB ws2_32 shlwapi) list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/*.c) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 0c20b03ae..c3ce5be12 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -34,12 +34,16 @@ CXX_GUARD_START // WinSock2 gets very angry if it's included too late #include #endif + +#if defined(_MSC_VER) || defined(__cplusplus) +#define restrict __restrict +#endif + #ifdef _MSC_VER #include #include typedef intptr_t ssize_t; #define PATH_MAX MAX_PATH -#define restrict __restrict #define strcasecmp _stricmp #define strncasecmp _strnicmp #define ftruncate _chsize diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index ec6a1b9e8..e3a958038 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -104,3 +104,21 @@ int main(int argc, char* argv[]) { return application.exec(); } + +#ifdef _WIN32 +#include +#include + +extern "C" +int wmain(int argc, wchar_t* argv[]) { + std::vector argv8; + for (int i = 0; i < argc; ++i) { + argv8.push_back(utf16to8(reinterpret_cast(argv[i]), wcslen(argv[i]) * 2)); + } + int ret = main(argc, argv8.data()); + for (char* ptr : argv8) { + free(ptr); + } + return ret; +} +#endif diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index dd20b0397..0da0698b9 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -179,6 +179,24 @@ int main(int argc, char** argv) { return ret; } +#ifdef _WIN32 +#include + +int wmain(int argc, wchar_t** argv) { + char** argv8 = malloc(sizeof(char*) * argc); + int i; + for (i = 0; i < argc; ++i) { + argv8[i] = utf16to8((uint16_t*) argv[i], wcslen(argv[i]) * 2); + } + int ret = main(argc, argv8); + for (i = 0; i < argc; ++i) { + free(argv8[i]); + } + free(argv8); + return ret; +} +#endif + int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { struct mCoreThread thread = { .core = renderer->core From f3caf890b0e0fd69cf66cdfe7552ab6044971328 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 17 Mar 2019 16:40:52 -0700 Subject: [PATCH 118/429] CMake: Fix .deb imagemagick dependencies --- CHANGES | 1 + CMakeLists.txt | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 08c798468..b3c34777e 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - LR35902: Fix disassembly of several CB-prefix instructions - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) + - CMake: Fix .deb imagemagick dependencies Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/CMakeLists.txt b/CMakeLists.txt index 2628c3e83..df3aa8cff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -563,11 +563,11 @@ if(USE_MAGICK) list(APPEND DEPENDENCY_LIB ${MAGICKWAND_LIBRARIES}) string(REGEX MATCH "^[0-9]+\\.[0-9]+" MAGICKWAND_VERSION_PARTIAL ${MagickWand_VERSION}) string(REGEX MATCH "^[0-9]+" MAGICKWAND_VERSION_MAJOR ${MagickWand_VERSION}) - if(${MAGICKWAND_VERSION_PARTIAL} EQUAL "6.7") + if(${MAGICKWAND_VERSION_PARTIAL} STREQUAL "6.7") set(MAGICKWAND_DEB_VERSION "5") - elseif(${MagickWand_VERSION} EQUAL "6.9.10") + elseif(${MagickWand_VERSION} STREQUAL "6.9.10") set(MAGICKWAND_DEB_VERSION "-6.q16-6") - elseif(${MagickWand_VERSION} EQUAL "6.9.7") + elseif(${MagickWand_VERSION} STREQUAL "6.9.7") set(MAGICKWAND_DEB_VERSION "-6.q16-3") else() set(MAGICKWAND_DEB_VERSION "-6.q16-2") From 84a7b6a31690ff5a2b4edea9830807d23555aaaa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Mar 2019 23:05:29 -0700 Subject: [PATCH 119/429] Qt: Fix crash in sprite viewer magnification (fixes #1362) --- CHANGES | 1 + src/platform/qt/TilePainter.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b3c34777e..df6e91594 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) - CMake: Fix .deb imagemagick dependencies + - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index 042d04732..b9417b827 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -62,8 +62,11 @@ void TilePainter::setTileCount(int tiles) { setMinimumSize(m_size, h - (h % m_size)); } else { int w = minimumSize().width() / m_size; + if (!w) { + w = 1; + } int h = (tiles + w - 1) * m_size / w; - setMinimumSize(minimumSize().width(), h - (h % m_size)); + setMinimumSize(w * m_size, h - (h % m_size)); } resizeEvent(nullptr); } From 8796f75fd3374c05d3452e284434c46eb9b178d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 22 Mar 2019 23:54:33 -0700 Subject: [PATCH 120/429] Windows: File handling fixes (fixes #1360) --- src/platform/windows/vfs-w32.c | 18 +++++++++--------- src/util/vfs/vfs-fd.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/platform/windows/vfs-w32.c b/src/platform/windows/vfs-w32.c index 4b9b96e4d..902f937f3 100644 --- a/src/platform/windows/vfs-w32.c +++ b/src/platform/windows/vfs-w32.c @@ -114,7 +114,7 @@ struct VFile* _vdwOpenFile(struct VDir* vd, const char* path, int mode) { const char* dir = vdw->path; size_t size = sizeof(char) * (strlen(path) + strlen(dir) + 2); char* combined = malloc(size); - StringCbPrintf(combined, size, "%s\\%s", dir, path); + StringCbPrintfA(combined, size, "%s\\%s", dir, path); struct VFile* file = VFileOpen(combined, mode); free(combined); @@ -129,7 +129,7 @@ struct VDir* _vdwOpenDir(struct VDir* vd, const char* path) { const char* dir = vdw->path; size_t size = sizeof(char) * (strlen(path) + strlen(dir) + 2); char* combined = malloc(size); - StringCbPrintf(combined, size, "%s\\%s", dir, path); + StringCbPrintfA(combined, size, "%s\\%s", dir, path); struct VDir* vd2 = VDirOpen(combined); if (!vd2) { @@ -144,14 +144,14 @@ bool _vdwDeleteFile(struct VDir* vd, const char* path) { if (!path) { return 0; } - const char* dir = vdw->path; - size_t size = sizeof(char) * (strlen(path) + strlen(dir) + 2); - char* combined = malloc(size); - StringCbPrintf(combined, size, "%s\\%s", dir, path); + wchar_t dir[MAX_PATH + 1]; + wchar_t pathw[MAX_PATH + 1]; + wchar_t combined[MAX_PATH + 1]; + MultiByteToWideChar(CP_UTF8, 0, vdw->path, -1, dir, MAX_PATH); + MultiByteToWideChar(CP_UTF8, 0, path, -1, pathw, MAX_PATH); + StringCchPrintfW(combined, MAX_PATH, L"%ws\\%ws", dir, pathw); - bool ret = DeleteFile(combined); - free(combined); - return ret; + return DeleteFileW(combined); } const char* _vdweName(struct VDirEntry* vde) { diff --git a/src/util/vfs/vfs-fd.c b/src/util/vfs/vfs-fd.c index 4a20eaf79..ed2222551 100644 --- a/src/util/vfs/vfs-fd.c +++ b/src/util/vfs/vfs-fd.c @@ -40,7 +40,7 @@ struct VFile* VFileOpenFD(const char* path, int flags) { flags |= O_BINARY; wchar_t wpath[PATH_MAX]; MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, sizeof(wpath) / sizeof(*wpath)); - int fd = _wopen(wpath, flags, 0666); + int fd = _wopen(wpath, flags, _S_IREAD | _S_IWRITE); #else int fd = open(path, flags, 0666); #endif From 3e178f3dd7d08e6b556167909940411e1f8c3be1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Mar 2019 22:46:58 -0700 Subject: [PATCH 121/429] GB Timer: Fix timing adjustments when writing to TAC (fixes #1340) --- CHANGES | 1 + src/gb/timer.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index df6e91594..4e6a8db8c 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Emulation fixes: - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) + - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gb/timer.c b/src/gb/timer.c index e990b3534..bddb4ad53 100644 --- a/src/gb/timer.c +++ b/src/gb/timer.c @@ -92,6 +92,10 @@ void GBTimerDivReset(struct GBTimer* timer) { uint8_t GBTimerUpdateTAC(struct GBTimer* timer, GBRegisterTAC tac) { if (GBRegisterTACIsRun(tac)) { + timer->nextDiv -= mTimingUntil(&timer->p->timing, &timer->event); + mTimingDeschedule(&timer->p->timing, &timer->event); + _GBTimerDivIncrement(timer, (timer->p->cpu->executionState + 2) & 3); + switch (GBRegisterTACGetClock(tac)) { case 0: timer->timaPeriod = 1024 >> 4; @@ -107,9 +111,6 @@ uint8_t GBTimerUpdateTAC(struct GBTimer* timer, GBRegisterTAC tac) { break; } - timer->nextDiv -= mTimingUntil(&timer->p->timing, &timer->event); - mTimingDeschedule(&timer->p->timing, &timer->event); - _GBTimerDivIncrement(timer, (timer->p->cpu->executionState + 2) & 3); timer->nextDiv += GB_DMG_DIV_PERIOD; mTimingSchedule(&timer->p->timing, &timer->event, timer->nextDiv); } else { From 7e71ce2d425ae7b93cb3aeb274e3eeb905f53477 Mon Sep 17 00:00:00 2001 From: "user.email" <20455421+LinRs@users.noreply.github.com> Date: Fri, 11 Jan 2019 23:59:45 +0800 Subject: [PATCH 122/429] add qt translation for zh_CN (Simplified Chinese) --- src/platform/qt/ts/mgba-zh-cn.ts | 4875 ++++++++++++++++++++++++++++++ 1 file changed, 4875 insertions(+) create mode 100644 src/platform/qt/ts/mgba-zh-cn.ts diff --git a/src/platform/qt/ts/mgba-zh-cn.ts b/src/platform/qt/ts/mgba-zh-cn.ts new file mode 100644 index 000000000..16f9ec4a6 --- /dev/null +++ b/src/platform/qt/ts/mgba-zh-cn.ts @@ -0,0 +1,4875 @@ + + + + + AboutScreen + + + About + 关于 + + + + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> + <a href="http://mgba.io/">主页</a> • <a href="https://forums.mgba.io/">论坛 / 支持</a> • <a href="https://patreon.com/mgba">捐助</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">源代码</a> + + + + Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> + 分支: <tt>{gitBranch}</tt><br/>修订: <tt>{gitCommit}</tt> + + + + {projectName} + {projectName} + + + + {projectName} would like to thank the following patrons from Patreon: + {projectName} 感谢以下来自Patreon平台的赞助者: + + + + © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + © 2013 – 2018 Jeffrey Pfau, 授权基于Mozilla公共授权 MPLv2.0 +Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 + + + + {projectVersion} + {projectVersion} + + + + {logo} + {logo} + + + + {projectName} is an open-source Game Boy Advance emulator + {projectName}是开放源代码的Game Boy Advance模拟器 + + + + {patrons} + {patrons} + + + + ArchiveInspector + + + Open in archive... + 打开记录... + + + + Loading... + 载入中... + + + + AssetTile + + + AssetTile + AssetTile + + + + Tile # + 标题 # + + + + + 0 + 0 + + + + Palette # + 调色板 # + + + + Address + 地址 + + + + 0x06000000 + 0x06000000 + + + + Red + 红色 + + + + Green + 绿色 + + + + Blue + 蓝色 + + + + + + 0x00 (00) + 0x00 (00) + + + + CheatsView + + + Cheats + 作弊码 + + + + Remove + 移除 + + + + Save + 保存 + + + + Load + 载入 + + + + Add New Set + 新建 + + + + Add + 添加 + + + + DebuggerConsole + + + Debugger + 调试器 + + + + Enter command (try `help` for more info) + 输入命令(尝试 `help` 以获取更多信息) + + + + Break + 断点 + + + + GIFView + + + Record GIF + 录制GIF + + + + Start + 开始 + + + + Stop + 停止 + + + + Select File + 选取文件 + + + + Frameskip + 跳帧 + + + + Frame delay (ms) + 帧延迟 (ms) + + + + Automatic + 自动设置帧延迟 + + + + IOViewer + + + I/O Viewer + I/O 查看器 + + + + 0x0000 + 0x0000 + + + + 2 + 2 + + + + 5 + 5 + + + + 4 + 4 + + + + 7 + 7 + + + + 0 + 0 + + + + 9 + 9 + + + + 1 + 1 + + + + 3 + 3 + + + + 8 + 8 + + + + C + C + + + + E + E + + + + 6 + 6 + + + + D + D + + + + F + F + + + + A + A + + + + B + B + + + + LibraryTree + + + Name + 名称 + + + + Location + 位置 + + + + Platform + 平台 + + + + Size + 大小 + + + + CRC32 + CRC32 + + + + LoadSaveState + + + + %1 State + %1 状态 + + + + + + + + + + + + No Save + 不保存 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + LogView + + + Logs + 日志 + + + + Enabled Levels + 启用级别 + + + + Debug + 调试 + + + + Stub + + + + + Info + 信息 + + + + Warning + 警告 + + + + Error + 错误 + + + + Fatal + 致命错误 + + + + Game Error + 游戏错误 + + + + Clear + 清除 + + + + Max Lines + 最大行数 + + + + MapView + + + Maps + 贴图 + + + + × + × + + + + Magnification + 放大率 + + + + Export + 导出 + + + + MemorySearch + + + Memory Search + 内存查找 + + + + Address + 地址 + + + + Current Value + 当前值 + + + + + Type + 类型 + + + + Value + + + + + Numeric + 数字 + + + + Text + 文本 + + + + Width + 位宽 + + + + + Guess + + + + + 1 Byte (8-bit) + + + + + 2 Bytes (16-bit) + + + + + 4 Bytes (32-bit) + + + + + Number type + 数字进制 + + + + Decimal + 十进制 + + + + Hexadecimal + 十六进制 + + + + Compare + 比较 + + + + Equal + 相等 + + + + Greater + 大于 + + + + Less + 小于 + + + + Delta + 相差 + + + + Search + 查找 + + + + Search Within + 在结果中查找 + + + + Open in Memory Viewer + 在内存查看器中打开 + + + + Refresh + 刷新 + + + + MemoryView + + + Memory + 内存 + + + + Inspect Address: + 检查地址: + + + + 0x + + + + + Set Alignment: + 设定对齐单位: + + + + 1 Byte + + + + + 2 Bytes + + + + + 4 Bytes + + + + + Unsigned Integer: + 无符号整数: + + + + Signed Integer: + 有符号整数: + + + + String: + 字符串 : + + + + Load TBL + 载入 TBL + + + + Copy Selection + 复制所选 + + + + Paste + 粘贴 + + + + Save Selection + 保存所选 + + + + Load + 载入 + + + + ObjView + + + Sprites + Sprites + + + + + × + + + + + Magnification + 放大率 + + + + Export + 导出 + + + + Attributes + Attributes + + + + Transform + 转换 + + + + Off + Off + + + + Palette + 调色板 + + + + + + + 0 + 0 + + + + Double Size + Double Size + + + + + + + Return, Ctrl+R + Return, Ctrl+R + + + + Flipped + Flipped + + + + H + H + + + + V + V + + + + Mode + 模式 + + + + Normal + Normal + + + + Mosaic + Mosaic + + + + Enabled + Enabled + + + + Priority + Priority + + + + Tile + 贴图 + + + + Geometry + Geometry + + + + Position + 位置 + + + + , + , + + + + Dimensions + 方向 + + + + + 8 + 8 + + + + Address + 地址 + + + + 0x07000000 + 0x07000000 + + + + OverrideView + + + Game Overrides + + + + + Game Boy Advance + + + + + + + + Autodetect + 自动检测 + + + + Realtime clock + 实时时钟 + + + + Gyroscope + 陀螺仪 + + + + Tilt + 贴图 + + + + Light sensor + 光传感器 + + + + Rumble + 振动 + + + + Save type + 保存类型 + + + + + None + + + + + SRAM + + + + + Flash 512kb + + + + + Flash 1Mb + + + + + EEPROM + + + + + Idle loop + + + + + Game Boy Player features + Game Boy Player 特性 + + + + Game Boy + + + + + Game Boy model + Game Boy 模式 + + + + Game Boy (DMG) + + + + + Super Game Boy (SGB) + + + + + Game Boy Color (CGB) + + + + + Game Boy Advance (AGB) + + + + + Memory bank controller + 内部存储控制器 + + + + MBC1 + + + + + MBC2 + + + + + MBC3 + + + + + MBC3 + RTC + + + + + MBC5 + + + + + MBC5 + Rumble + MBC5 + 振动 + + + + MBC7 + + + + + Pocket Cam + + + + + TAMA5 + + + + + HuC-3 + + + + + Background Colors + 背景颜色 + + + + Sprite Colors 1 + + + + + Sprite Colors 2 + + + + + PaletteView + + + Palette + 调色板 + + + + Background + 背景 + + + + Objects + 对象 + + + + Selection + 选择 + + + + Red + 红色 + + + + Green + 绿色 + + + + Blue + 蓝色 + + + + + + 0x00 (00) + + + + + 16-bit value + 16-bit 值 + + + + Hex code + 十六进制代码 + + + + Palette index + + + + + 0x0000 + + + + + #000000 + + + + + 000 + + + + + Export BG + BG是什么 + 导出 BG + + + + Export OBJ + OBJ是什么 + 导出 OBJ + + + + PlacementControl + + + Adjust placement + 更改部署 + + + + All + 全部 + + + + Offset + 抵消 + + + + X + + + + + Y + + + + + PrinterView + + + Game Boy Printer + + + + + Hurry up! + + + + + Tear off + + + + + QGBA::AssetTile + + + %0%1%2 + + + + + + + 0x%0 (%1) + + + + + QGBA::AudioDevice + + + Can't set format of context-less audio device + + + + + Audio device is missing its core + + + + + Writing data to read-only audio device + + + + + QGBA::AudioProcessorQt + + + Can't start an audio processor without input + + + + + QGBA::AudioProcessorSDL + + + Can't start an audio processor without input + + + + + QGBA::CheatsModel + + + (untitled) + (无标题) + + + + Failed to open cheats file: %1 + 打开作弊码文件失败 : %1 + + + + QGBA::CheatsView + + + + Add GameShark + 添加 GameShark + + + + Add Pro Action Replay + 添加 Pro Action Replay + + + + Add CodeBreaker + 添加 CodeBreaker + + + + Add GameGenie + 添加 Game Génie + + + + + Select cheats file + 选择作弊码文件 + + + + QGBA::CoreController + + + Failed to open save file: %1 + 无法打开存档: %1 + + + + Failed to open game file: %1 + 无法打开游戏文件 : %1 + + + + Failed to open snapshot file for reading: %1 + 无法读取快照文件 : %1 + + + + Failed to open snapshot file for writing: %1 + 无法写入快照文件 : %1 + + + + QGBA::CoreManager + + + Failed to open game file: %1 + 无法打开游戏文件 : %1 + + + + QGBA::GBAKeyEditor + + + Clear Button + 清除按键 + + + + Clear Analog + 清除 Analog + + + + Refresh + 刷新 + + + + Set all + 设置全部 + + + + QGBA::GDBWindow + + + Server settings + + + + + Local port + + + + + Bind address + + + + + Break + + + + + Stop + 停止 + + + + Start + 开始 + + + + Crash + 崩溃 + + + + Could not start GDB server + 无法打开GDB服务端 + + + + QGBA::GIFView + + + Failed to open output GIF file: %1 + 无法打开输出的GIF文件 : %1 + + + + Select output file + 选择输出文件 + + + + Graphics Interchange Format (*.gif) + + + + + QGBA::IOViewer + + + Background mode + 后台模式 + + + + Mode 0: 4 tile layers + + + + + Mode 1: 2 tile layers + 1 rotated/scaled tile layer + + + + + Mode 2: 2 rotated/scaled tile layers + + + + + Mode 3: Full 15-bit bitmap + + + + + Mode 4: Full 8-bit bitmap + + + + + Mode 5: Small 15-bit bitmap + + + + + CGB Mode + + + + + Frame select + 帧选取 + + + + Unlocked HBlank + + + + + Linear OBJ tile mapping + + + + + Force blank screen + 强制清屏 + + + + Enable background 0 + + + + + Enable background 1 + + + + + Enable background 2 + + + + + Enable background 3 + + + + + Enable OBJ + + + + + Enable Window 0 + + + + + Enable Window 1 + + + + + Enable OBJ Window + + + + + Currently in VBlank + + + + + Currently in HBlank + + + + + Currently in VCounter + + + + + Enable VBlank IRQ generation + + + + + Enable HBlank IRQ generation + + + + + Enable VCounter IRQ generation + + + + + VCounter scanline + + + + + Current scanline + + + + + + + + Priority + 优先级 + + + + + + + Tile data base (* 16kB) + + + + + + + + Enable mosaic + + + + + + + + Enable 256-color + 启用256色 + + + + + + + Tile map base (* 2kB) + + + + + + + + Background dimensions + + + + + + Overflow wraps + + + + + + + + Horizontal offset + + + + + + + + Vertical offset + + + + + + + + + + + + + + + + Fractional part + + + + + + + + + + + + Integer part + + + + + + + + Integer part (bottom) + + + + + + + + Integer part (top) + + + + + + End x + + + + + + Start x + + + + + + End y + + + + + + Start y + + + + + Window 0 enable BG 0 + + + + + Window 0 enable BG 1 + + + + + Window 0 enable BG 2 + + + + + Window 0 enable BG 3 + + + + + Window 0 enable OBJ + + + + + Window 0 enable blend + + + + + Window 1 enable BG 0 + + + + + Window 1 enable BG 1 + + + + + Window 1 enable BG 2 + + + + + Window 1 enable BG 3 + + + + + Window 1 enable OBJ + + + + + Window 1 enable blend + + + + + Outside window enable BG 0 + + + + + Outside window enable BG 1 + + + + + Outside window enable BG 2 + + + + + Outside window enable BG 3 + + + + + Outside window enable OBJ + + + + + Outside window enable blend + + + + + OBJ window enable BG 0 + + + + + OBJ window enable BG 1 + + + + + OBJ window enable BG 2 + + + + + OBJ window enable BG 3 + + + + + OBJ window enable OBJ + + + + + OBJ window enable blend + + + + + Background mosaic size vertical + + + + + Background mosaic size horizontal + + + + + Object mosaic size vertical + + + + + Object mosaic size horizontal + + + + + BG 0 target 1 + + + + + BG 1 target 1 + + + + + BG 2 target 1 + + + + + BG 3 target 1 + + + + + OBJ target 1 + + + + + Backdrop target 1 + + + + + Blend mode + + + + + Disabled + 禁用 + + + + Additive blending + + + + + Brighten + + + + + Darken + + + + + BG 0 target 2 + + + + + BG 1 target 2 + + + + + BG 2 target 2 + + + + + BG 3 target 2 + + + + + OBJ target 2 + + + + + Backdrop target 2 + + + + + Blend A (target 1) + + + + + Blend B (target 2) + + + + + Blend Y + + + + + Sweep shifts + + + + + Sweep subtract + + + + + Sweep time (in 1/128s) + + + + + + + + Sound length + + + + + + Duty cycle + + + + + + + Envelope step time + + + + + + + Envelope increase + + + + + + + Initial volume + 音量初始化 + + + + + + Sound frequency + 音频频率 + + + + + + + Timed + + + + + + + + Reset + 重置 + + + + Double-size wave table + + + + + Active wave table + + + + + Enable channel 3 + + + + + Volume + + + + + 0% + + + + + + 100% + + + + + + 50% + + + + + + 25% + + + + + + + + 75% + + + + + Clock divider + + + + + Register stages + + + + + 15 + + + + + 7 + + + + + Shifter frequency + + + + + PSG volume right + + + + + PSG volume left + + + + + Enable channel 1 right + + + + + Enable channel 2 right + + + + + Enable channel 3 right + + + + + Enable channel 4 right + + + + + Enable channel 1 left + + + + + Enable channel 2 left + + + + + Enable channel 3 left + + + + + Enable channel 4 left + + + + + PSG master volume + + + + + Loud channel A + + + + + Loud channel B + + + + + Enable channel A right + + + + + Enable channel A left + + + + + Channel A timer + + + + + + 0 + + + + + + + + + + + + + 1 + + + + + Channel A reset + + + + + Enable channel B right + + + + + Enable channel B left + + + + + Channel B timer + + + + + Channel B reset + + + + + Active channel 1 + + + + + Active channel 2 + + + + + Active channel 3 + + + + + Active channel 4 + + + + + Enable audio + 启用音频 + + + + Bias + + + + + Resolution + 分辨率 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sample + + + + + + + + + + + + Address (bottom) + + + + + + + + + + + + Address (top) + + + + + + + + Word count + + + + + + + + Destination offset + + + + + + + + + + + + Increment + + + + + + + + + + + + Decrement + + + + + + + + + + + + Fixed + + + + + + + + Increment and reload + + + + + + + + Source offset + + + + + + + + Repeat + + + + + + + + 32-bit + + + + + + + + Start timing + + + + + + + + Immediate + + + + + + + + + + VBlank + + + + + + + + + + HBlank + + + + + + + + + + + + + IRQ + + + + + + + + + + + + Enable + + + + + + + Audio FIFO + + + + + Video Capture + + + + + DRQ + + + + + + + + Value + + + + + + + + Scale + + + + + + + + 1/64 + + + + + + + + 1/256 + + + + + + + + 1/1024 + + + + + + + Cascade + + + + + + A + + + + + + B + + + + + + Select + 选择 + + + + + Start + 开始 + + + + + Right + + + + + + Left + + + + + + Up + + + + + + Down + + + + + + R + + + + + + L + + + + + Condition + + + + + SC + + + + + SD + + + + + SI + + + + + SO + + + + + + VCounter + + + + + + Timer 0 + + + + + + Timer 1 + + + + + + Timer 2 + + + + + + Timer 3 + + + + + + SIO + + + + + + DMA 0 + + + + + + DMA 1 + + + + + + DMA 2 + + + + + + DMA 3 + + + + + + Keypad + + + + + + Gamepak + + + + + SRAM wait + + + + + + + + + 4 + + + + + + + + 3 + + + + + + + + + 2 + + + + + + + + + 8 + + + + + Cart 0 non-sequential + + + + + Cart 0 sequential + + + + + Cart 1 non-sequential + + + + + Cart 1 sequential + + + + + Cart 2 non-sequential + + + + + Cart 2 sequential + + + + + PHI terminal + + + + + Disable + 禁用 + + + + 4.19MHz + + + + + 8.38MHz + + + + + 16.78MHz + + + + + Gamepak prefetch + + + + + Enable IRQs + + + + + QGBA::KeyEditor + + + + --- + + + + + QGBA::LoadSaveState + + + Load State + 载入快照 + + + + Save State + 存档 + + + + Empty + + + + + Corrupted + + + + + Slot %1 + + + + + QGBA::LogController + + + DEBUG + + + + + STUB + + + + + INFO + + + + + WARN + + + + + ERROR + + + + + FATAL + + + + + GAME ERROR + + + + + QGBA::MapView + + + Map Addr. + + + + + Mirror + + + + + None + + + + + Both + + + + + Horizontal + + + + + Vertical + + + + + Export map + + + + + Portable Network Graphics (*.png) + + + + + Failed to open output PNG file: %1 + 输出PNG文件开启失败: %1 + + + + QGBA::MemoryModel + + + Copy selection + 复制所选 + + + + Save selection + 保存所选 + + + + Paste + 粘贴 + + + + Load + 载入 + + + + + All + 全部 + + + + Load TBL + 载入 TBL + + + + Save selected memory + 保存所选内存 + + + + Failed to open output file: %1 + 无法打开输出文件 : %1 + + + + Load memory + 载入内存 + + + + Failed to open input file: %1 + 无法打开输入文件 : %1 + + + + TBL + + + + + ISO-8859-1 + + + + + QGBA::MemorySearch + + + (%0/%1×) + + + + + (⅟%0×) + + + + + (%0×) + + + + + %1 byte%2 + + + + + QGBA::ObjView + + + + 0x%0 + + + + + Off + + + + + Normal + + + + + Trans + + + + + OBJWIN + + + + + Invalid + 无效 + + + + + N/A + + + + + Export sprite + + + + + Portable Network Graphics (*.png) + + + + + Failed to open output PNG file: %1 + 无法打开输出的PNG文件: %1 + + + + QGBA::PaletteView + + + #%0 + + + + + 0x%0 + + + + + %0 + + + + + + + 0x%0 (%1) + + + + + Export palette + 导出 调色板 + + + + Windows PAL (*.pal);;Adobe Color Table (*.act) + + + + + Failed to open output palette file: %1 + 已输出的调色板文件打开失败: %1 + + + + QGBA::PrinterView + + + Save Printout + 保存输出 + + + + Portable Network Graphics (*.png) + + + + + QGBA::ROMInfo + + + + + + + (unknown) + (未知) + + + + + bytes + + + + + (no database present) + + + + + QGBA::SettingsView + + + + Qt Multimedia + + + + + SDL + + + + + Software (Qt) + + + + + OpenGL + + + + + OpenGL (force version 1.x) + + + + + None (Still Image) + + + + + Keyboard + 键盘 + + + + Controllers + 控制器 + + + + Shortcuts + 快捷键 + + + + + Shaders + 着色器 + + + + Select BIOS + 选择BIOS + + + + QGBA::ShaderSelector + + + No shader active + 无活动的着色器 + + + + Load shader + 载入着色器 + + + + No shader loaded + 未载入任何着色器 + + + + by %1 + + + + + Preprocessing + 预处理 + + + + Pass %1 + 进行 %1 + + + + QGBA::ShortcutController + + + Action + + + + + Keyboard + 键盘 + + + + Gamepad + 游戏手柄 + + + + QGBA::VideoView + + + Failed to open output video file: %1 + 无法代开输出的视频文件 : %1 + + + + Native (%0x%1) + + + + + Select output file + 选取输出文件 + + + + QGBA::Window + + + Game Boy Advance ROMs (%1) + + + + + Game Boy ROMs (%1) + + + + + All ROMs (%1) + + + + + %1 Video Logs (*.mvl) + %1 视频日志 (*.mvl) + + + + Archives (%1) + + + + + + + Select ROM + 选择ROM + + + + Select folder + 选择文件夹 + + + + Game Boy Advance save files (%1) + Game Boy Advance 保存文件 (%1) + + + + + + Select save + 选取存档 + + + + Select patch + 选择 patch + + + + Patches (*.ips *.ups *.bps) + + + + + Select image + 选取图片 + + + + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + 图片文件 (*.png *.gif *.jpg *.jpeg);;Tous les fichiers (*) + + + + + GameShark saves (*.sps *.xps) + GameShark存档 (*.sps *.xps) + + + + Select video log + 选择视频日志 + + + + Video logs (*.mvl) + 视频日志 (*.mvl) + + + + Crash + 崩溃 + + + + The game has crashed with the following error: + +%1 + 游戏因以下错误而崩溃: + +%1 + + + + Couldn't Load + 无法载入 + + + + Could not load game. Are you sure it's in the correct format? + 无法载入游戏. 是否确认游戏格式无误 ? + + + + Unimplemented BIOS call + 未实现的BIOS调用 + + + + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. + 该游戏使用了尚未实现的BIOS调用。请使用官方BIOS以获得最佳的游戏体验。 + + + + Really make portable? + 确定进行便携化 ? + + + + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? + + + + + Restart needed + 需要重启 + + + + Some changes will not take effect until the emulator is restarted. + 一些更改将在模拟器下次启动时生效。 + + + + - Player %1 of %2 + + + + + %1 - %2 + + + + + %1 - %2 - %3 + + + + + %1 - %2 (%3 fps) - %4 + + + + + &File + 文件(&F) + + + + Load &ROM... + 载入 &ROM... + + + + Load ROM in archive... + 从目录中载入ROM... + + + + Add folder to library... + 在库中添加文件夹... + + + + Load alternate save... + 读取其他的存档... + + + + Load temporary save... + 读取临时存档... + + + + Load &patch... + 载入&patch文件... + + + + Boot BIOS + + + + + Replace ROM... + 替换ROM... + + + + ROM &info... + ROM信息(&I)... + + + + Recent + + + + + Make portable + 便携化 + + + + &Load state + (&L)读取存档 + + + + F10 + + + + + &Save state + &S存档 + + + + Shift+F10 + + + + + Quick load + 快速读档 + + + + Quick save + 快速存档 + + + + Load recent + 载入最近的存档 + + + + Save recent + 保存最近的状态 + + + + Undo load state + 撤消读档操作 + + + + F11 + + + + + Undo save state + 撤消存档 + + + + Shift+F11 + + + + + + State &%1 + + + + + F%1 + + + + + Shift+F%1 + + + + + Load camera image... + 读取相机图片... + + + + Import GameShark Save + 导入GameShark存档 + + + + Export GameShark Save + 导出GameShark存档 + + + + New multiplayer window + 新多人游戏窗口 + + + + About + 关于 + + + + E&xit + 退出&x + + + + &Emulation + &E模拟 + + + + &Reset + &R复位 + + + + Ctrl+R + + + + + Sh&utdown + 关闭&u + + + + Yank game pak + + + + + &Pause + 暂停&P + + + + Ctrl+P + + + + + &Next frame + 下一帧&N + + + + Ctrl+N + + + + + Fast forward (held) + 快进 (held) + + + + &Fast forward + 快进&F + + + + Shift+Tab + + + + + Fast forward speed + 快进速度 + + + + Unbounded + 不限制 + + + + %0x + + + + + Rewind (held) + 回退 (held) + + + + Re&wind + 回退&w + + + + ~ + + + + + Step backwards + 后退 + + + + Ctrl+B + + + + + Sync to &video + 视频同步&v + + + + Sync to &audio + 音频同步&a + + + + Solar sensor + 日光传感器 + + + + Increase solar level + 增加日光级别 + + + + Decrease solar level + 降低日光级别 + + + + Brightest solar level + 日光级别为最亮 + + + + Darkest solar level + 日光级别为最暗 + + + + Brightness %1 + 亮度 %1 + + + + Audio/&Video + 音频/视频&V + + + + Frame size + 帧率 + + + + %1x + + + + + Toggle fullscreen + 切换全屏 + + + + Lock aspect ratio + 锁定纵横比 + + + + Force integer scaling + 强制整数缩放 + + + + Bilinear filtering + 双线性过滤 + + + + Frame&skip + 跳帧&s + + + + Mute + 静音 + + + + FPS target + 最高FPS + + + + 15 + + + + + 30 + + + + + 45 + + + + + Native (59.7) + + + + + 60 + + + + + 90 + + + + + 120 + + + + + 240 + + + + + Take &screenshot + 生成截图&s + + + + F12 + + + + + Record output... + 录制导出... + + + + Record GIF... + 录制GIF... + + + + Record video log... + 记录视频日志... + + + + Stop video log + 停止记录视频日志 + + + + Game Boy Printer... + + + + + Video layers + + + + + Audio channels + 音频 + + + + Adjust layer placement... + + + + + &Tools + 工具&T + + + + View &logs... + 查看日志&l... + + + + Game &overrides... + 覆盖游戏&o... + + + + Game &Pak sensors... + + + + + &Cheats... + 作弊码&C... + + + + Settings... + 设置... + + + + Open debugger console... + 打开调试终端... + + + + Start &GDB server... + 打开&GDB服务端... + + + + View &palette... + 查看调色板&p... + + + + View &sprites... + + + + + View &tiles... + + + + + View &map... + 不译 + + + + + View memory... + 查看内存... + + + + Search memory... + 查看内存... + + + + View &I/O registers... + registers 翻译存疑 + 查看&I/O注册器... + + + + Exit fullscreen + 退出全屏 + + + + GameShark Button (held) + GameShark 键 (held) + + + + Autofire + 自动开火 + + + + Autofire A + 自动开火 A + + + + Autofire B + 自动开火 B + + + + Autofire L + 自动开火 L + + + + Autofire R + 自动开火 R + + + + Autofire Start + 自动开火 开始 + + + + Autofire Select + 自动开火 选择 + + + + Autofire Up + 自动开火 上 + + + + Autofire Right + 自动开火 右 + + + + Autofire Down + 自动开火 下 + + + + Autofire Left + 自动开火 左 + + + + QObject + + + GBA + + + + + GB + + + + + ? + + + + + ROMInfo + + + ROM Info + ROM 信息 + + + + Game name: + 游戏名 : + + + + {NAME} + {NAME} + + + + Internal name: + 内部名 : + + + + {TITLE} + {TITLE} + + + + Game ID: + 游戏ID : + + + + {ID} + {ID} + + + + File size: + 文件大小 : + + + + {SIZE} + {SIZE} + + + + CRC32: + CRC32 : + + + + {CRC} + + + + + SensorView + + + Sensors + 传感器 + + + + Realtime clock + 实时时钟 + + + + Fixed time + 定时 + + + + System time + 系统时间 + + + + Start time at + 起始时间 + + + + Now + 现在 + + + + MM/dd/yy hh:mm:ss AP + + + + + Light sensor + 光传感器 + + + + Brightness + 亮度 + + + + Tilt sensor + 倾角传感器 + + + + + Set Y + 设定 Y + + + + + Set X + 设定 X + + + + Gyroscope + 陀螺仪 + + + + Sensitivity + 灵敏度 + + + + SettingsView + + + Settings + 设置 + + + + Audio/Video + 音频/视频 + + + + Interface + 用户界面 + + + + Emulation + 模拟器 + + + + BIOS + + + + + Paths + 路径 + + + + Game Boy + + + + + Audio driver: + 音频驱动 : + + + + Audio buffer: + 音频缓冲: + + + + + 1536 + + + + + 512 + + + + + 768 + + + + + 1024 + + + + + 2048 + + + + + 3072 + + + + + 4096 + + + + + samples + 采样 + + + + Sample rate: + 采样率: + + + + + 44100 + + + + + 22050 + + + + + 32000 + + + + + 48000 + + + + + Hz + + + + + Volume: + 音量 : + + + + Mute + 静音 + + + + Display driver: + 显示驱动 : + + + + Frameskip: + 跳帧 : + + + + Skip every + 每间隔 + + + + + frames + + + + + FPS target: + 最高FPS : + + + + frames per second + 帧每秒 + + + + Sync: + 同步 : + + + + Video + 视频 + + + + Audio + 音频 + + + + Lock aspect ratio + 锁定纵横比 + + + + Bilinear filtering + 双线性过滤 + + + + Force integer scaling + 强制整数缩放 + + + + Language + 语言 + + + + English + 英语 + + + + Library: + 库 : + + + + List view + 列表查看 + + + + Tree view + 树状查看 + + + + Show when no game open + 在无游戏打开时显示 + + + + Clear cache + 清除缓存 + + + + Allow opposing input directions + 允许逆向输入 + + + + Suspend screensaver + 停用休眠 + + + + Pause when inactive + 不活动时暂停 + + + + Show FPS in title bar + 在标题栏显示FPS + + + + Automatically save cheats + 自动保存作弊码 + + + + Automatically load cheats + 自动载入作弊码 + + + + Automatically save state + 自动存档 + + + + Automatically load state + 自动读档 + + + + Fast forward speed: + 快进速度 : + + + + × + + + + + Unbounded + 不限制 + + + + Enable rewind + 启用回退 + + + + Rewind history: + 回退历史 : + + + + Idle loops: + + + + + Run all + 运行所有 + + + + Remove known + 移除选定 + + + + Detect and remove + 检测并移除 + + + + Savestate extra data: + 存档时的额外数据 : + + + + + Screenshot + 截图 + + + + + Save data + 保存数据 + + + + + Cheat codes + 作弊码 + + + + Load extra data: + 读档时载入额外数据: + + + + Rewind affects save data + 影响保存数据时回退 + + + + Preload entire ROM into memory + 预加载全部ROM到内存 + + + + Autofire interval: + 自动开火间隔 : + + + + GB BIOS file: + GB BIOS 文件: + + + + + + + + + + + + Browse + 浏览 + + + + Use BIOS file if found + 当可用时使用BIOS文件 + + + + Skip BIOS intro + 跳过BIOS载入 + + + + GBA BIOS file: + GBA BIOS 文件: + + + + GBC BIOS file: + GBC BIOS 文件: + + + + SGB BIOS file: + SGB BIOS 文件: + + + + Save games + 已保存的游戏 + + + + + + + + Same directory as the ROM + 保存在ROM所在目录 + + + + Save states + 保存快照 + + + + Screenshots + 截图 + + + + Patches + 补丁 + + + + Cheats + 作弊码 + + + + Game Boy model + + + + + + + Autodetect + 自动检测 + + + + + + Game Boy (DMG) + + + + + + + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + + + + + + + Game Boy Advance (AGB) + + + + + Super Game Boy model + + + + + Game Boy Color model + + + + + Default BG colors: + 默认 BG 颜色: + + + + Super Game Boy borders + + + + + Camera driver: + 相机驱动 : + + + + Default sprite colors 1: + + + + + Default sprite colors 2: + + + + + ShaderSelector + + + Shaders + 着色器 + + + + Active Shader: + 主动着色器 : + + + + Name + 名称 + + + + Author + 作者 + + + + Description + 描述 + + + + Unload Shader + 未载入 着色器 + + + + Load New Shader + 载入新着色器 + + + + ShortcutView + + + Edit Shortcuts + 编辑快捷键 + + + + Keyboard + 键盘 + + + + Gamepad + 游戏手柄 + + + + Clear + 清除 + + + + TileView + + + Tiles + 贴图 + + + + 256 colors + + + + + × + + + + + Magnification + 放大率 + + + + VideoView + + + Record Video + 录制视频 + + + + Start + 开始 + + + + Stop + 停止 + + + + Select File + 选取文件 + + + + Presets + 预置 + + + + High Quality + 高质量 + + + + YouTube + + + + + + WebM + + + + + Lossless + 无损 + + + + 1080p + + + + + 720p + + + + + 480p + + + + + Native + 原生 + + + + Format + 格式 + + + + MKV + + + + + AVI + + + + + MP4 + + + + + h.264 + + + + + h.264 (NVENC) + + + + + HEVC + + + + + VP8 + + + + + FFV1 + + + + + FLAC + + + + + Opus + + + + + Vorbis + + + + + MP3 + + + + + AAC + + + + + Uncompressed + 未压缩 + + + + Bitrate (kbps) + + + + + VBR + + + + + ABR + + + + + Dimensions + 方向 + + + + : + + + + + × + + + + + Lock aspect ratio + 锁定纵横比 + + + + Show advanced + 显示高级选项 + + + From 8ec2c5bc64e009588daee19c2121ad45827be7ea Mon Sep 17 00:00:00 2001 From: DDinghoya Date: Mon, 25 Mar 2019 14:07:05 +0900 Subject: [PATCH 123/429] Create mgba-kr.ts Korean language create --- src/platform/qt/ts/mgba-kr.ts | 4994 +++++++++++++++++++++++++++++++++ 1 file changed, 4994 insertions(+) create mode 100644 src/platform/qt/ts/mgba-kr.ts diff --git a/src/platform/qt/ts/mgba-kr.ts b/src/platform/qt/ts/mgba-kr.ts new file mode 100644 index 000000000..684a88b39 --- /dev/null +++ b/src/platform/qt/ts/mgba-kr.ts @@ -0,0 +1,4994 @@ + + + + + AboutScreen + + + About + 관하여 + + + + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> + + + + {projectName} + {projectName} + + + + {projectName} would like to thank the following patrons from Patreon: + {projectName}은 Patreon의 다음 고객에게 감사드립니다: + + + © 2013 – 2016 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + © 2013 - 2016 Jeffrey Pfau, 모질라 공식 라이센스 버전 2.0에 따라 사용 허가되었습니다. +Game Boy Advance는 Nintendo Co., Ltd.의 등록 상표입니다. + + + + {patrons} + {patrons} + + + + {projectVersion} + {projectVersion} + + + + © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + © 2013 - 2016 Jeffrey Pfau, 모질라 공식 라이센스 버전 2.0에 따라 사용 허가되었습니다. +Game Boy Advance는 Nintendo Co., Ltd.의 등록 상표입니다. + + + + {logo} + {logo} + + + + {projectName} is an open-source Game Boy Advance emulator + {projectName}은 오픈 소스 Game Boy Advance 에뮬레이터입니다. + + + + Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> + Branch: <tt>{gitBranch}</tt><br/>리비전: <tt>{gitCommit}</tt> + + + + ArchiveInspector + + + Open in archive... + 아카이브에서 파일 열기... + + + + Loading... + 로딩 중... + + + + AssetTile + + + AssetTile + AssetTile + + + + Tile # + 타일 # + + + + + 0 + 0 + + + + Palette # + 팔레트 # + + + + Address + 주소 + + + + 0x06000000 + 0x06000000 + + + + Red + 빨간색 + + + + Green + 초록색 + + + + Blue + 파란색 + + + + + + 0x00 (00) + 0x00 (00) + + + + CheatsView + + + Cheats + 치트 + + + + Remove + 삭제 + + + + Save + 저장 + + + + Load + 로드 + + + + Add New Set + 새로운 설정 추가 + + + + Add + 추가 + + + + DebuggerConsole + + + Debugger + 디버거 + + + + Enter command (try `help` for more info) + 명령을 입력하십시오 (자세한 내용은 'help'를 시도하십시오) + + + + Break + 중단 + + + + GIFView + + + Record GIF + GIF 기록 + + + + Start + 시작 + + + + Stop + 정지 + + + + Select File + 파일 선택 + + + + Frameskip + 프레임 건너뛰기 + + + + Frame delay (ms) + 프레임 지연 (ms) + + + + Automatic + 자동 + + + + IOViewer + + + I/O Viewer + I/O 뷰어 + + + + 0x0000 + 0x0000 + + + + 2 + 2 + + + + 5 + 5 + + + + 4 + 4 + + + + 7 + 7 + + + + 0 + 0 + + + + 9 + 9 + + + + 1 + 1 + + + + 3 + 3 + + + + 8 + 8 + + + + C + C + + + + E + E + + + + 6 + 6 + + + + D + D + + + + F + F + + + + A + A + + + + B + B + + + + LibraryTree + + + Name + 이름 + + + + Location + 장소 + + + + Platform + 플랫폼 + + + + Size + 크기 + + + + CRC32 + CRC32 + + + + LibraryView + + Library + 라이브러리 + + + + LoadSaveState + + + + %1 State + %1 캡처 상태 + + + + + + + + + + + + No Save + 저장 안함 + + + + 1 + 1 + + + + 2 + 2 + + + + 3 + 3 + + + + 4 + 4 + + + + 5 + 5 + + + + 6 + 6 + + + + 7 + 7 + + + + 8 + 8 + + + + 9 + 9 + + + + LogView + + + Logs + 로그 + + + + Enabled Levels + 레벨 활성화 + + + + Debug + 디버그 + + + + Stub + 매트릭스 + + + + Info + 정보 + + + + Warning + 경고 + + + + Error + 오류 + + + + Fatal + 치명적 + + + + Game Error + 게임 오류 + + + + Clear + 정리 + + + + Max Lines + 최대 라인 + + + + MapView + + + Maps + 지도 + + + + × + × + + + + Magnification + 확대 + + + + Export + 내보내기 + + + + MemorySearch + + + Memory Search + 메모리 검색 + + + + Address + 주소 + + + + Current Value + 현재 값 + + + + + Type + 형식 + + + + Value + + + + + Numeric + 숫자 + + + + Text + 문자 + + + + Width + + + + + + Guess + 추측 + + + + 1 Byte (8-bit) + 1 바이트 (8 비트) + + + + 2 Bytes (16-bit) + 2 바이트 (16 비트) + + + + 4 Bytes (32-bit) + 4 바이트 (32 비트) + + + + Number type + 숫자 유형 + + + + Decimal + 소수 + + + + Hexadecimal + 16 진수 + + + + Compare + 비교 + + + + Equal + 같은 + + + + Greater + + + + + Less + 적은 + + + + Delta + 델타 + + + + Search + 검색 + + + + Search Within + 내부 검색 + + + + Open in Memory Viewer + 메모리 뷰어에서 열기 + + + + Refresh + 새로 고침 + + + + MemoryView + + + Memory + 메모리 + + + + Inspect Address: + 주소 검사: + + + + 0x + 0x + + + + Set Alignment: + 정렬 설정: + + + + 1 Byte + 1 바이트 + + + + 2 Bytes + 2 바이트 + + + + 4 Bytes + 4 바이트 + + + + Signed Integer: + 전체 표시: + + + + String: + 문자열: + + + + Load TBL + 테이블 로드 + + + + Copy Selection + 선택 항목 복사 + + + + Paste + 붙여넣기 + + + + Save Selection + 선택 항목 저장 + + + + Load + 로드 + + + + Unsigned Integer: + 표시되지 않은 정수: + + + + ObjView + + + Sprites + 스프라이트 + + + + + × + × + + + + Magnification + 확대 + + + + Export + 내보내기 + + + + Attributes + 속성 + + + + Transform + 변환 + + + + Off + + + + + Palette + 팔레트 + + + + + + + 0 + 0 + + + + Double Size + 2배 크기 + + + + + + + Return, Ctrl+R + 뒤로가기, Ctrl+R + + + + Flipped + 뒤집힌 + + + + H + H + + + + V + V + + + + Mode + 모드 + + + + Normal + 보통 + + + + Mosaic + 모자이크 + + + + Enabled + 활성화 + + + + Priority + 우선 순위 + + + + Tile + 타일 + + + + Geometry + 기하 + + + + Position + 위치 + + + + , + , + + + + Dimensions + 크기 + + + + + 8 + 8 + + + + Address + 주소 + + + + 0x07000000 + 0x07000000 + + + + OverrideView + + + Game Overrides + 게임의 특정 값 + + + + Game Boy Advance + 게임 보이 어드밴스 + + + + + + + Autodetect + 자동 감지 + + + + Realtime clock + 실시간 시계 + + + + Gyroscope + 자이로스코프 + + + + Tilt + 기울기 + + + + Light sensor + 광 센서 + + + + Rumble + 진동 + + + + Save type + 저장 유형 + + + + + None + 없음 + + + + SRAM + SRAM + + + + Flash 512kb + 플래쉬 512kb + + + + Flash 1Mb + 플래쉬 1Mb + + + + EEPROM + EEPROM + + + + Idle loop + 유휴 루프 + + + + Game Boy Player features + 게임 보이 플레이어 기능 + + + + Game Boy + 게임 보이 + + + + Game Boy model + 게이 보이 모델 + + + + Game Boy (DMG) + 게임 보이 (DMG) + + + + Super Game Boy (SGB) + 슈퍼 게임 보이 (SGB) + + + + Game Boy Color (CGB) + 게임 보이 컬러 (CGB) + + + + Game Boy Advance (AGB) + 게임 보이 어드밴스 (AGB) + + + + Memory bank controller + 메모리 뱅크 컨트롤러 + + + + MBC1 + MBC1 + + + + MBC2 + MBC2 + + + + MBC3 + MBC3 + + + + MBC3 + RTC + MBC3 + RTC + + + + MBC5 + MBC5 + + + + MBC5 + Rumble + MBC5 + 진동 + + + + MBC7 + MBC7 + + + + Pocket Cam + 포켓 캠 + + + + TAMA5 + TAMA5 + + + + HuC-3 + HuC-3 + + + + Background Colors + 배경색 + + + + Sprite Colors 1 + 스프라이트 색상 1 + + + + Sprite Colors 2 + 스프라이트 색상 2 + + + + PaletteView + + + Palette + 팔레트 + + + + Background + 배경 + + + + Objects + 보트 타기 + + + + Selection + 선택 + + + + Red + 빨간색 + + + + Green + 초록색 + + + + Blue + 파란색 + + + + + + 0x00 (00) + 0x00 (00) + + + + 16-bit value + 16 비트 값 + + + + Hex code + 16 진수 코드 + + + + Palette index + 팔레트 색인 + + + + 0x0000 + 0x0000 + + + + #000000 + #000000 + + + + 000 + 000 + + + + Export BG + 배경 내보내기 + + + + Export OBJ + 보트 타기 내보내기 + + + + PlacementControl + + + Adjust placement + 위치 조정 + + + + All + 전체 + + + + Offset + 오프셋 + + + + X + X + + + + Y + Y + + + + PrinterView + + + Game Boy Printer + 게임 보이 프린터 + + + + Hurry up! + 서두르세요! + + + + Tear off + 찢음 + + + + QGBA::AssetTile + + + %0%1%2 + %0%1%2 + + + + + + 0x%0 (%1) + 0x%0 (%1) + + + + QGBA::AudioDevice + + + Can't set format of context-less audio device + 오디오 장치 형식을 설정할 수 없습니다. + + + + Audio device is missing its core + 오디오 장치에는 코어가 없습니다. + + + + Writing data to read-only audio device + 읽기 전용 오디오 장치에 대한 데이터 쓰기 + + + + QGBA::AudioProcessorQt + + + Can't start an audio processor without input + 입력없이 오디오 프로세서를 시작할 수 없습니다. + + + + QGBA::AudioProcessorSDL + + + Can't start an audio processor without input + 입력없이 오디오 프로세서를 시작할 수 없습니다. + + + + QGBA::CheatsModel + + + (untitled) + (제목 없음) + + + + Failed to open cheats file: %1 + 치트 파일을 열 수 없습니다: %1 + + + + QGBA::CheatsView + + + + Add GameShark + 게임샤크 추가 + + + + Add Pro Action Replay + 프로 액션 리플레이 추가 + + + + Add CodeBreaker + 코드브레이커 추가 + + + + Add GameGenie + 게임지니 추가 + + + + + Select cheats file + 치트 파일 선택 + + + + QGBA::CoreController + + + Failed to open save file: %1 + 저장 파일을 열지 못했습니다: %1 + + + + Failed to open game file: %1 + 게임 파일을 열지 못했습니다: %1 + + + + Failed to open snapshot file for reading: %1 + 읽기 용 스냅샷 파일을 열지 못했습니다: %1 + + + + Failed to open snapshot file for writing: %1 + 쓰기 용 스냅샷 파일을 열지 못했습니다: %1 + + + + QGBA::CoreManager + + + Failed to open game file: %1 + 게임 파일을 열지 못했습니다: %1 + + + + QGBA::GBAKeyEditor + + + Clear Button + 버튼 정리 + + + + Clear Analog + 아날로그 정리 + + + + Refresh + 새로 고침 + + + + Set all + 모두 설정 + + + + QGBA::GDBWindow + + + Server settings + 서버 설정 + + + + Local port + 로컬 포트 + + + + Bind address + 주소 바인딩 + + + + Break + 중단 + + + + Stop + 정지 + + + + Start + 시작 + + + + Crash + 오류 + + + + Could not start GDB server + GDB 서버를 시작할 수 없습니다. + + + + QGBA::GIFView + + + Failed to open output GIF file: %1 + 출력 GIF 파일을 열지 못했습니다: %1 + + + + Select output file + 출력 파일 선택 + + + + Graphics Interchange Format (*.gif) + 그래픽 호환 형식 (*.gif) + + + + QGBA::GameController + + Failed to open game file: %1 + 게임 파일을 열지 못했습니다: %1 + + + Failed to open save file: %1 + 저장 파일을 열지 못했습니다: %1 + + + Failed to open snapshot file for reading: %1 + 읽기 용 스냅샷 파일을 열지 못했습니다: %1 + + + Failed to open snapshot file for writing: %1 + 쓰기 용 스냅샷 파일을 열지 못했습니다: %1 + + + Failed to start audio processor + 오디오 프로세서를 시작하지 못했습니다. + + + + QGBA::IOViewer + + + Background mode + 배경 모드 + + + + Mode 0: 4 tile layers + Modalità 0: 4 타일 레이어 + + + + Mode 1: 2 tile layers + 1 rotated/scaled tile layer + Modalità 1: 2 타일 레이어 + 1 회전/축소 타일 레이어 + + + + Mode 2: 2 rotated/scaled tile layers + Modalità 2: 2 회전/축소 타일 레이어 + + + + Mode 3: Full 15-bit bitmap + 모드 3: 완전한 15 비트 비트맵 + + + + Mode 4: Full 8-bit bitmap + 모드 4: 완전한 8 비트 비트맵 + + + + Mode 5: Small 15-bit bitmap + 모드 5: 낮은 15 비트 비트맵 + + + + CGB Mode + CGB 모드 + + + + Frame select + 프레임 선택 + + + + Unlocked HBlank + HBlank 잠금 해제 + + + + Linear OBJ tile mapping + 선형 OBJ 타일 맵핑 + + + + Force blank screen + 빈 화면 강제 설정 + + + + Enable background 0 + 배경 0 활성화 + + + + Enable background 1 + 배경 1 활성화 + + + + Enable background 2 + 배경 2 활성화 + + + + Enable background 3 + 배경 3 활성화 + + + + Enable OBJ + OBJ 활성화 + + + + Enable Window 0 + 창 0 활성화 + + + + Enable Window 1 + 창 1 활성화 + + + + Enable OBJ Window + OBJ 창 활성화 + + + + Currently in VBlank + 현재 VBlank에 있음 + + + + Currently in HBlank + 현재 HBlank에 있음 + + + + Currently in VCounter + 현재 VCounter에 있음 + + + + Enable VBlank IRQ generation + VBlank IRQ 생성 활성화 + + + + Enable HBlank IRQ generation + HBlank IRQ 생성 활성화 + + + + Enable VCounter IRQ generation + VCounter IRQ 생성 활성화 + + + + VCounter scanline + VCounter 스캔라인 + + + + Current scanline + 현재 스캔라인 + + + + + + + Priority + 우선 순위 + + + + + + + Tile data base (* 16kB) + 타일 데이터 베이스 (* 16kB) + + + + + + + Enable mosaic + 모자이크 활성화 + + + + + + + Enable 256-color + 256 컬러 활성화 + + + + + + + Tile map base (* 2kB) + 타일 맵 베이스 (* 2kB) + + + + + + + Background dimensions + 배경 크기 + + + + + Overflow wraps + 오버플로우 랩 + + + + + + + Horizontal offset + 수평 오프셋 + + + + + + + Vertical offset + 수직 오프셋 + + + + + + + + + + + + + + + Fractional part + 분수부 + + + + + + + + + + + Integer part + 정수부 + + + + + + + Integer part (bottom) + 정수부 (하단) + + + + + + + Integer part (top) + 정수부 (상단) + + + + + End x + x 끝 + + + + + Start x + x 시작 + + + + + End y + y 끝 + + + + + Start y + y 시작 + + + + Window 0 enable BG 0 + 창 0 배경 0 + + + + Window 0 enable BG 1 + 창 0 배경 1 + + + + Window 0 enable BG 2 + Window 0 BG 2 + + + + Window 0 enable BG 3 + 창 0 배경 3 + + + + Window 0 enable OBJ + 창 0 보트 타기 + + + + Window 0 enable blend + 창 0 혼합 + + + + Window 1 enable BG 0 + 창 1 배경 0 + + + + Window 1 enable BG 1 + 창 1 배경 1 + + + + Window 1 enable BG 2 + 창 1 배경 2 + + + + Window 1 enable BG 3 + 창 1 배경 3 + + + + Window 1 enable OBJ + 창 1 보트 타기 + + + + Window 1 enable blend + 창 1 혼합 + + + + Outside window enable BG 0 + 외부 창 배경 0 + + + + Outside window enable BG 1 + 외부 창 배경 1 + + + + Outside window enable BG 2 + 외부 창 배경 2 + + + + Outside window enable BG 3 + 외부 창 배경 3 + + + + Outside window enable OBJ + 외부 창 보트 타기 + + + + Outside window enable blend + 외부 창 혼합 + + + + OBJ window enable BG 0 + 보트 타기 창 배경 0 + + + + OBJ window enable BG 1 + 보트 타기 창 배경 1 + + + + OBJ window enable BG 2 + 보트 타기 창 배경 2 + + + + OBJ window enable BG 3 + 보트 타기 창 배경 3 + + + + OBJ window enable OBJ + 보트 타기 창 보트 타기 + + + + OBJ window enable blend + 보트 타기 창 혼합 + + + + Background mosaic size vertical + 세로 모자이크 배경 + + + + Background mosaic size horizontal + 가로 모자이크 배경 + + + + Object mosaic size vertical + 세로 보트 타기 모자이크 배경 + + + + Object mosaic size horizontal + 가로 보트 타기 모자이크 배경 + + + + BG 0 target 1 + 배경 0 타겟 1 + + + + BG 1 target 1 + 배경 1 타겟 1 + + + + BG 2 target 1 + 배경 2 타겟 1 + + + + BG 3 target 1 + 배경 3 타겟 1 + + + + OBJ target 1 + 객체 타겟 1 + + + + Backdrop target 1 + 배경 타켓 1 + + + + Blend mode + 혼합 모드 + + + + Disabled + 비활성화 + + + + Additive blending + 첨가 혼합 + + + + 밝음 + Illumina + + + + 어두움 + Oscura + + + + BG 0 target 2 + 배경 0 타켓 2 + + + + BG 1 target 2 + 배경 1 타겟 2 + + + + BG 2 target 2 + 배경 2 타켓 2 + + + + BG 3 target 2 + 배경 3 타켓 2 + + + + OBJ target 2 + 객체 타켓 2 + + + + Backdrop target 2 + 배경 타겟 2 + + + + Blend A (target 1) + 혼합 A (타겟 1) + + + + Blend B (target 2) + 혼합 B (타켓 2) + + + + Blend Y + 혼합 Y + + + + Sweep shifts + 스윕 시프트 + + + + Sweep subtract + 스윕 서브트랙 + + + + Sweep time (in 1/128s) + 스윕 시간 (1/128초) + + + + + + + Sound length + 소리 길이 + + + + + Duty cycle + 작동 주기 + + + + + + Envelope step time + 엔빌로프 단계 시간 + + + + + + Envelope increase + 엔빌로프 증가 + + + + + + Initial volume + 초기 볼륨 + + + + + + Sound frequency + 소리 빈도 + + + + + + + Timed + 시한 + + + + + + + Reset + 재설정 + + + + Double-size wave table + 2배 음파 테이블 + + + + Active wave table + 음파 테이블 활성 + + + + Enable channel 3 + 채널 3 활성화 + + + + Volume + 볼륨 + + + + 0% + 0% + + + + + 100% + 100% + + + + + 50% + 50% + + + + + 25% + 25% + + + + + + + 75% + 75% + + + + Clock divider + 클럭 분배기 + + + + Register stages + 녹음 단계 + + + + 15 + 15 + + + + 7 + 7 + + + + Shifter frequency + 빈도 변화 + + + + PSG volume right + PSG 오른쪽 볼륨 + + + + PSG volume left + PSG 왼쪽 볼륨 + + + + Enable channel 1 right + 채널 1 오른쪽 활성화 + + + + Enable channel 2 right + 채널 2 오른쪽 활성화 + + + + Enable channel 3 right + 채널 3 오른쪽 활성화 + + + + Enable channel 4 right + 채널 4 오른쪽 활성화 + + + + Enable channel 1 left + 채널 1 왼쪽 활성화 + + + + Enable channel 2 left + 채널 2 왼쪽 활성화 + + + + Enable channel 3 left + 채널 3 왼쪽 활성화 + + + + Enable channel 4 left + 채널 4 왼쪽 활성화 + + + + PSG master volume + PSG 마스터 볼륨 + + + + Loud channel A + 큰 소리 채널 A + + + + Loud channel B + 큰 소리 채널 B + + + + Enable channel A right + 채널 A 오른쪽 활성화 + + + + Enable channel A left + 채널 A 왼쪽 활성화 + + + + Channel A timer + 채널 A 타이머 + + + + + 0 + 0 + + + + + + + + + + + + 1 + 1 + + + + Channel A reset + 채널 A 재설정 + + + + Enable channel B right + 채널 B 오른쪽 활성화 + + + + Enable channel B left + 채널 B 왼쪽 활성화 + + + + Channel B timer + 채널 B 타이머 + + + + Channel B reset + 채널 B 재설정 + + + + Active channel 1 + 채널 1 활성 + + + + Active channel 2 + 채널 2 활성 + + + + Active channel 3 + 채널 3 활성 + + + + Active channel 4 + 채널 4 활성 + + + + Enable audio + 오디오 활성화 + + + + Bias + 편광 + + + + Resolution + 해상도 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sample + 샘플 + + + + + + + + + + + Address (bottom) + 주소 (하단) + + + + + + + + + + + Address (top) + 주소 (상단) + + + + + + + Word count + 단어 수 + + + + + + + Destination offset + 도착 오프셋 + + + + + + + + + + + Increment + 증가 + + + + + + + + + + + Decrement + 감소 + + + + + + + + + + + Fixed + 수정 + + + + + + + Increment and reload + 증가 및 다시 로드 + + + + + + + Source offset + 소스 오프셋 + + + + + + + Repeat + 반복 + + + + + + + 32-bit + 32 비트 + + + + + + + Start timing + 시작 타이밍 + + + + + + + Immediate + 즉시 + + + + + + + + + VBlank + VBlank + + + + + + + + + HBlank + HBlank + + + + + + + + + + + + IRQ + IRQ + + + + + + + + + + + Enable + 활성화 + + + + + + Audio FIFO + 오디오 FIFO + + + + Video Capture + 비디오 캡쳐 + + + + DRQ + DRQ + + + + + + + Value + + + + + + + + Scale + 스케일 + + + + + + + 1/64 + 1/64 + + + + + + + 1/256 + 1/256 + + + + + + + 1/1024 + 1/1024 + + + + + + Cascade + 연속 + + + + + A + A + + + + + B + B + + + + + Select + 선택 + + + + + Start + 시작 + + + + + Right + 오른쪽 + + + + + Left + 왼쪽 + + + + + Up + + + + + + Down + 아래 + + + + + R + R + + + + + L + L + + + + Condition + 조건 + + + + SC + SC + + + + SD + SD + + + + SI + SI + + + + SO + SO + + + + + VCounter + VCounter + + + + + Timer 0 + 타이머 0 + + + + + Timer 1 + 타이머 1 + + + + + Timer 2 + 타이머 2 + + + + + Timer 3 + 타이머 3 + + + + + SIO + SIO + + + + + DMA 0 + DMA 0 + + + + + DMA 1 + DMA 1 + + + + + DMA 2 + DMA 2 + + + + + DMA 3 + DMA 3 + + + + + Keypad + 키패드 + + + + + Gamepak + 게임팩 + + + + SRAM wait + 대기중인 SRAM + + + + + + + + 4 + 4 + + + + + + + 3 + 3 + + + + + + + + 2 + 2 + + + + + + + + 8 + 8 + + + + Cart 0 non-sequential + 카트 0 미순차 + + + + Cart 0 sequential + 카트 0 순차 + + + + Cart 1 non-sequential + 카트 1 미순차 + + + + Cart 1 sequential + 카트 1 순차 + + + + Cart 2 non-sequential + 카트 2 미순차 + + + + Cart 2 sequential + 카트 2 순차 + + + + PHI terminal + PHI 단말기 + + + + Disable + 비활성화 + + + + 4.19MHz + 4.19MHz + + + + 8.38MHz + 8.38MHz + + + + 16.78MHz + 16.78MHz + + + + Gamepak prefetch + 게임팩 사전 추출 + + + + Enable IRQs + IRQ 활성화 + + + + QGBA::KeyEditor + + + + --- + --- + + + + QGBA::LibraryModel + + Name + 이름 + + + Filename + 파일이름 + + + Size + 크기 + + + Platform + 플랫폼 + + + GBA + GBA + + + GB + GB + + + ? + ? + + + Location + 장소 + + + CRC32 + CRC32 + + + + QGBA::LoadSaveState + + + Load State + 로드 상태 + + + + Save State + 저장 상태 + + + + Empty + + + + + Corrupted + 손상 + + + + Slot %1 + 슬롯 %1 + + + + QGBA::LogController + + + DEBUG + 디버그 + + + + STUB + 스텁 + + + + INFO + 정보 + + + + WARN + 경고 + + + + ERROR + 오류 + + + + FATAL + 치명적 + + + + GAME ERROR + 게임 오류 + + + + QGBA::MapView + + + Map Addr. + 맵 주소 + + + + Mirror + 미러링 + + + + None + 없음 + + + + Both + 둘 다 + + + + Horizontal + 수평 + + + + Vertical + 수직 + + + + Export map + 맵 내보내기 + + + + Portable Network Graphics (*.png) + 휴대용 네트워크 그래픽 (*.png) + + + + Failed to open output PNG file: %1 + 출력 PNG 파일을 열지 못했습니다: %1 + + + + QGBA::MemoryModel + + + Copy selection + 선택 항목 복사 + + + + Save selection + 선택 항목 저장 + + + + Paste + 붙여넣기 + + + + Load + 로드 + + + + + All + 모두 + + + + Load TBL + 테이블 로드 + + + + Save selected memory + 선택한 메모리 저장 + + + + Failed to open output file: %1 + 출력 파일을 열지 못했습니다: %1 + + + + Load memory + 메모리 로드 + + + + Failed to open input file: %1 + 입력 파일을 열지 못했습니다: %1 + + + + TBL + 테이블 + + + + ISO-8859-1 + ISO-8859-1 + + + + QGBA::MemorySearch + + + (%0/%1×) + (%0/%1×) + + + + (⅟%0×) + (⅟%0×) + + + + (%0×) + (%0×) + + + + %1 byte%2 + %1 바이트%2 + + + + QGBA::ObjView + + + + 0x%0 + 0x%0 + + + + Off + + + + + Normal + 보통 + + + + Trans + 트랜스 + + + + OBJWIN + OBJWIN + + + + Invalid + 잘못된 + + + + + N/A + N/A + + + + Export sprite + 스프라이트 내보내기 + + + + Portable Network Graphics (*.png) + 휴대용 네트워크 그래픽 (*.png) + + + + Failed to open output PNG file: %1 + 출력 PNG 파일을 열지 못했습니다: %1 + + + + QGBA::PaletteView + + + #%0 + #%0 + + + + 0x%0 + 0x%0 + + + + %0 + %0 + + + + + + 0x%0 (%1) + 0x%0 (%1) + + + + Export palette + 팔레트 내보내기 + + + + Windows PAL (*.pal);;Adobe Color Table (*.act) + 창 PAL (*.pal);;어도비 컬러 테이블 (*.act) + + + + Failed to open output palette file: %1 + 출력 팔레트 파일을 열지 못했습니다: %1 + + + + QGBA::PrinterView + + + Save Printout + 인쇄물 저장 + + + + Portable Network Graphics (*.png) + 휴대용 네트워크 그래픽 (*.png) + + + + QGBA::ROMInfo + + + + + + + (unknown) + (미확인) + + + + + bytes + 바이트 + + + + (no database present) + (데이터베이스 없음) + + + + QGBA::SettingsView + + + + Qt Multimedia + Qt 멀티미디어 + + + + SDL + SDL + + + + Software (Qt) + 소프트웨어 (Qt) + + + + OpenGL + 오픈GL + + + + OpenGL (force version 1.x) + 오픈GL (버전 1.x 강제) + + + + None (Still Image) + 없음 (정지 이미지) + + + + Keyboard + 키보드 + + + + Controllers + 컨트롤러 + + + + Shortcuts + 단축키 + + + + + Shaders + 쉐이더 + + + + Select BIOS + 바이오스 선택 + + + + QGBA::ShaderSelector + + + No shader active + 활성 셰이더 없음 + + + + Load shader + 쉐이더 로드 + + + %1 Shader (%.shader) + %1 쉐이터 (%.쉐이더) + + + + No shader loaded + 셰이더가 로드되지 않았습니다. + + + + by %1 + %1에 의해 + + + + Preprocessing + 전처리 + + + + Pass %1 + %1 패스 + + + + QGBA::ShortcutController + + + Action + 동작 + + + + Keyboard + 키보드 + + + + Gamepad + 게임패드 + + + + QGBA::VideoView + + + Failed to open output video file: %1 + 출력 비디오 파일을 열지 못했습니다: %1 + + + + Native (%0x%1) + 기본 (%0x%1) + + + + Select output file + 출력 파일 선택 + + + + QGBA::Window + + + Game Boy Advance ROMs (%1) + 게임 보이 어드밴스 롬 (%1) + + + + Game Boy ROMs (%1) + 게임 보이 (%1) + + + + All ROMs (%1) + 모든 롬 (%1) + + + + %1 Video Logs (*.mvl) + %1 비디오 로그 (*.mvl) + + + + Archives (%1) + 아카이브 (%1) + + + + + + Select ROM + 롬 선택 + + + + Game Boy Advance save files (%1) + 게임 보이 어드밴스 저장 파일 (%1) + + + + + + Select save + 저장 파일 선택 + + + + Select patch + 패치 선택 + + + + Patches (*.ips *.ups *.bps) + 패치 (*.ips *.ups *.bps) + + + + Select image + 이미지 선택 + + + + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + 이미지 파일 (*.png *.gif *.jpg *.jpeg);;모든 파일 (*) + + + + + GameShark saves (*.sps *.xps) + 게임샤크 저장 파일 (*.sps *.xps) + + + + Select video log + 비디오 로그 선택 + + + + Video logs (*.mvl) + 비디오 로그 (*.mvl) + + + + Crash + 치명적인 오류 + + + + The game has crashed with the following error: + +%1 + 게임이 다음 오류로 인해 충돌했습니다: + +%1 + + + + Couldn't Load + 로드할 수 없습니다. + + + + Could not load game. Are you sure it's in the correct format? + 게임을 로드할 수 없습니다. 올바른 형식인지 확인하십시오. + + + + Unimplemented BIOS call + 구현되지 않은 바이오스 호출 + + + + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. + 이 게임은 구현되지 않은 바이오스 호출을 사용합니다. 최상의 성능을 얻으려면 공식 바이오스를 사용하십시오. + + + + Really make portable? + 정말로 휴대용을 만듭니까? + + + + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? + 이렇게하면 에뮬레이터가 실행 파일과 동일한 디렉토리에서 구성을 로드하게됩니다. 계속 하시겠습니까? + + + + Restart needed + 재시작 필요 + + + + Some changes will not take effect until the emulator is restarted. + 일부 변경 사항은 에뮬레이터가 다시 시작될 때까지 적용되지 않습니다. + + + + - Player %1 of %2 + - 플레이어 %1 의 %2 + + + + %1 - %2 + %1 - %2 + + + + %1 - %2 - %3 + %1 - %2 - %3 + + + + %1 - %2 (%3 fps) - %4 + %1 - %2 (%3 fps) - %4 + + + + &File + &파일 + + + + Load &ROM... + 로드 &롬... + + + + Load ROM in archive... + 롬을 아카이브에 로드... + + + + Load alternate save... + 대체 저장 로드... + + + + Load temporary save... + 임시 저장 로드... + + + + Load &patch... + 로드 &패치... + + + + Boot BIOS + BIOS 부팅 + + + + Replace ROM... + 롬 교체... + + + + ROM &info... + 롬 &정보... + + + + Recent + 최근 실행 + + + + Make portable + 휴대용 만들기 + + + + &Load state + &로드 파일 상태 + + + + F10 + F10 + + + + &Save state + &저장 파일 상태 + + + + Shift+F10 + DO NOT TRANSLATE + Shift+F10 + + + + Quick load + 빠른 로드 + + + + Quick save + 빠른 저장 + + + + Load recent + 최근 실행 로드 + + + + Save recent + 최근 실행 저장 + + + + Undo load state + 로드 파일 상태 복원 + + + + F11 + DO NOT TRANSLATE + F11 + + + + Undo save state + 저장 파일 상태 복원 + + + + Shift+F11 + DO NOT TRANSLATE + Shift+F11 + + + + + State &%1 + 상태 &%1 + + + + F%1 + F%1 + + + + Shift+F%1 + DO NOT TRANSLATE + Shift+F%1 + + + + Load camera image... + 카메라 이미지 로드... + + + + Import GameShark Save + 게임샤크 저장 파일 가져오기 + + + + Export GameShark Save + 게임샤크 저장 파일 내보내기 + + + + New multiplayer window + 새로운 멀티 플레이어 창 + + + + About + 관하여 + + + + E&xit + 종&료 + + + + &Emulation + &에뮬레이션 + + + + &Reset + &재설정 + + + + Ctrl+R + Ctrl+R + + + + Sh&utdown + 종&료 + + + + Yank game pak + 양키 게임 팩 + + + + &Pause + &정지 + + + + Ctrl+P + Ctrl+P + + + + &Next frame + &다음 프레임 + + + + Ctrl+N + Ctrl+N + + + + Fast forward (held) + 빨리 감기 (누름) + + + + &Fast forward + &빨리 감기 + + + + Shift+Tab + Shift+Tab + + + + Fast forward speed + 빨리 감기 속도 + + + + Unbounded + 무제한 + + + + %0x + %0x + + + + Rewind (held) + 되김기 (누름) + + + + Re&wind + 리&와인드 + + + + ~ + ~ + + + + Step backwards + 돌아가기 + + + + Ctrl+B + Ctrl+B + + + + Sync to &video + 비디오 &동기화 + + + + Sync to &audio + 오디오 &동기화 + + + + 태양 센서 + Sensore solare + + + + 태양 수준 증가 + Aumenta il livello solare + + + + 태양 수준 감소 + Riduce il livello solare + + + + Brightest solar level + 가장 밝은 태양 수준 + + + + Darkest solar level + 가장 어두운 태양 수준 + + + + Brightness %1 + 밝기 %1 + + + + Audio/&Video + 오디오/&비디오 + + + + Frame size + 프레임 크기 + + + + %1x + %1x + + + + Toggle fullscreen + 전체화면 전환 + + + + Lock aspect ratio + 화면비 잠금 + + + Resample video + 리샘플 비디오 + + + + Frame&skip + 프레임&건너뛰기 + + + Shader options... + 쉐이더 옵션... + + + + Mute + 무음 + + + + FPS target + FPS 대상 + + + + 15 + 15 + + + + 30 + 30 + + + + 45 + 45 + + + + Native (59.7) + Nativo (59.7) + + + + 60 + 60 + + + + 90 + 90 + + + + 120 + 120 + + + + 240 + 240 + + + + Take &screenshot + 스크린샷 &찍기 + + + + F12 + F12 + + + + Record output... + 출력 기록... + + + + Record GIF... + GIF 기록... + + + + Video layers + 비디오 레이어 + + + Background %0 + 배경 %0 + + + OBJ (sprites) + 객체 (스프라이트) + + + + Audio channels + 오디오 채널 + + + Channel %0 + 채널 %0 + + + Channel A + 채널 A + + + Channel B + 채널 B + + + + &Tools + &도구 + + + + View &logs... + 로그 &보기... + + + + Game &overrides... + 게임 &오버라이드... + + + + Game &Pak sensors... + 게임 &팩 센서... + + + + &Cheats... + &치트.. + + + + Open debugger console... + 디버거 콘솔 열기... + + + + Start &GDB server... + GDB 서버 &시작... + + + + Settings... + 설정... + + + + Select folder + 폴더 선택 + + + + Add folder to library... + 라이브러리에 폴더 추가... + + + + Force integer scaling + 정수 스케일링 강제 수행 + + + + Bilinear filtering + 이중선형 필터링 + + + + Record video log... + 비디오 로그 기록... + + + + Stop video log + 비디오 로그 정지 + + + + Game Boy Printer... + 게임 보이 프린터... + + + + Adjust layer placement... + 레이어 배치 조정... + + + + View &palette... + 팔레트 &보기... + + + + View &sprites... + 스프라이트 &보기... + + + + View &tiles... + 타일 &보기... + + + + View &map... + 지도 &보기... + + + + View memory... + 메모리 보기... + + + + Search memory... + 메모리 검색... + + + + View &I/O registers... + I/O 레지스터 &보기... + + + + Exit fullscreen + 전체화면 종료 + + + + GameShark Button (held) + 게임샤크 버튼 (누름) + + + + Autofire + 연사 + + + + Autofire A + 연사 A + + + + Autofire B + 연사 B + + + + Autofire L + 연사 L + + + + Autofire R + 연사 R + + + + Autofire Start + 연사 시작 + + + + 연사 선택 + Autofire Select + + + + Autofire Up + 연사 위쪽 + + + + Autofire Right + 연사 오른쪽 + + + + Autofire Down + 연사 아래쪽 + + + + Autofire Left + 연사 왼쪽 + + + + QObject + + + GBA + GBA + + + + GB + GB + + + + ? + ? + + + + ROMInfo + + + ROM Info + 롬 정보 + + + + Game name: + 게임 이름: + + + + {NAME} + {이름} + + + + Internal name: + 내부 이름: + + + + {TITLE} + {제목} + + + + Game ID: + 게임 ID: + + + + {ID} + {ID} + + + + File size: + 파일 크기: + + + + {SIZE} + {크기} + + + + CRC32: + CRC32: + + + + {CRC} + {CRC} + + + + SensorView + + + Sensors + 센서 + + + + Realtime clock + 실시간 시계 + + + + Fixed time + 수정된 시간 + + + + System time + 시스템 시간 + + + + Start time at + 시작 시간 + + + + Now + 지금 + + + + MM/dd/yy hh:mm:ss AP + gg/MM/aa OO:mm:ss + + + + Light sensor + 광센서 + + + + Brightness + 밝기 + + + + Tilt sensor + 기울기 센서 + + + + + Set Y + Y 설정 + + + + + Set X + X 설정 + + + + Gyroscope + 자이로스코프 + + + + Sensitivity + 감광도 + + + + SettingsView + + + Settings + 설정 + + + + Audio/Video + 오디오/비디오 + + + + Interface + 인터페이스 + + + + Emulation + 에뮬레이션 + + + + Paths + 경로 + + + + Game Boy + 게임 보이 + + + + Audio driver: + 오디오 드라이버: + + + + Audio buffer: + 오디오 버퍼: + + + + + 1536 + 1536 + + + + 512 + 512 + + + + 768 + 768 + + + + 1024 + 1024 + + + + 2048 + 2048 + + + + 3072 + 3072 + + + + 4096 + 4096 + + + + samples + 샘플 + + + + Sample rate: + 샘플 속도: + + + + + 44100 + 44100 + + + + 22050 + 22050 + + + + 32000 + 32000 + + + + 48000 + 48000 + + + + Hz + Hz + + + + Volume: + 볼륨: + + + + Mute + 무음 + + + + Display driver: + 디스플레이 드라이버: + + + + Frameskip: + 프레임 건너뛰기: + + + + Skip every + 모두 무시 + + + + + frames + 프레임 + + + + FPS target: + FPS 대상: + + + + frames per second + frame al secondo + + + + Sync: + 동기화: + + + + Video + 비디오 + + + + Audio + 오디오 + + + + Lock aspect ratio + 화면비 잠금 + + + + Cheats + 치트 + + + + Game Boy model + 게임 보이 모델 + + + + + + Autodetect + 자동 감지 + + + + + + Game Boy (DMG) + 게임 보이 (DMG) + + + + + + Super Game Boy (SGB) + 슈퍼 게임 보이 (SGB) + + + + + + Game Boy Color (CGB) + 게임 보이 컬러 (CGB) + + + + + + Game Boy Advance (AGB) + 게임 보이 어드밴스 (AGB) + + + + Super Game Boy model + 슈퍼 게임 보이 모델 + + + + Game Boy Color model + 게임 보이 컬러 모델 + + + + Default BG colors: + 기본 배경 색상: + + + + Super Game Boy borders + 슈퍼 게임 보이 테두리 + + + + Camera driver: + 카메라 드라이버: + + + + Default sprite colors 1: + 기본 스프라이트 색상 1: + + + + Default sprite colors 2: + 기본 스프라이트 색상 2: + + + Resample video + 리샘플 비디오 + + + + Library: + 라이브러리: + + + + Show when no game open + 게임이 없을 떄 표시 + + + + Clear cache + 캐시 지우기 + + + + Fast forward speed: + 빨리 감기 속도: + + + + + + + + + + + + Browse + 브라우저 + + + + Use BIOS file if found + 발견되면 바이오스 파일 사용 + + + + Skip BIOS intro + 바이오스 소개 건너 뛰기 + + + + × + × + + + + Unbounded + 무제한 + + + + Suspend screensaver + 화면 보호기 일시 중지 + + + + BIOS + 바이오스 + + + + Pause when inactive + 비활성 일 때 일시 중지 + + + + Run all + 모두 실행 + + + + Remove known + 알려진 것 제거 + + + + Detect and remove + 감지 및 제거 + + + + Allow opposing input directions + 반대 방향 입력 허용 + + + + + Screenshot + 스크린샷 + + + + + Save data + 저장 데이터 + + + + + Cheat codes + 치트 코드 + + + + Enable rewind + Abilita riavvolgimento + + + + Bilinear filtering + 이중선형 필터링/translation> + + + + Force integer scaling + 정수 스케일링 강제 수행 + + + + Language + 언어 + + + + English + 영어 + + + + List view + 목록 보기 + + + + Tree view + 트리 보기 + + + + Show FPS in title bar + 제목 표시 줄에 FPS 표시 + + + + Automatically save cheats + 자동 치트 저장 + + + + Automatically load cheats + 자동 치트 로드 + + + + Automatically save state + 자동 상태 저장 + + + + Automatically load state + 자동 상태 로드 + + + + Rewind history: + 되감기 기록: + + + + Idle loops: + Idle loops: + + + + Savestate extra data: + 추가 데이터 저장상태: + + + + Load extra data: + 추가 데이터 로드: + + + + Rewind affects save data + 되감기는 데이터 저장에 영향을 줍니다. + + + + Preload entire ROM into memory + 전체 롬을 메모리에 미리 로드하십시오. + + + + Autofire interval: + Intervallo Autofire: + + + + GB BIOS file: + GB 바이오스 파일: + + + + GBA BIOS file: + GBA 바이오스 파일: + + + + GBC BIOS file: + GBC 바이오스 파일: + + + + SGB BIOS file: + SGB 바이오스 파일: + + + + Save games + 게임 저장 + + + + + + + + Same directory as the ROM + 롬과 같은 디렉토리 + + + + Save states + 저장 파일 상태 + + + + Screenshots + 스크린샷 + + + + Patches + 패치 + + + + ShaderSelector + + + Shaders + 쉐이더 + + + + Active Shader: + 활성 쉐이더: + + + + Name + 이름 + + + + Author + 제작자 + + + + Description + 기술 + + + + Unload Shader + 쉐이더 로드 안함 + + + + Load New Shader + 새로운 쉐이더 로드 + + + + ShortcutView + + + Edit Shortcuts + 단축키 수정 + + + + Keyboard + 키보드 + + + + Gamepad + 게임패드 + + + + Clear + 정리 + + + + TileView + + + Tiles + 타일 + + + + 256 colors + 256 색상 + + + + × + × + + + + Magnification + 확대 + + + + VideoView + + + Record Video + 비디오 녹화 + + + + Start + 시작 + + + + Stop + 정지 + + + + Select File + 파일 선택 + + + + Presets + 프리셋 + + + + High Quality + 고품질 + + + + YouTube + 유튜브 + + + + + WebM + WebM + + + + Lossless + 무손실 + + + + 1080p + 1080p + + + + 720p + 720p + + + + 480p + 480p + + + + Native + 네이티브 + + + + Format + 형식 + + + + MKV + MKV + + + + AVI + AVI + + + + MP4 + MP4 + + + PNG + PNG + + + + h.264 + h.264 + + + + h.264 (NVENC) + h.264 (NVENC) + + + + HEVC + HEVC + + + + VP8 + VP8 + + + Xvid + Xvid + + + + FFV1 + FFV1 + + + + FLAC + FLAC + + + + Opus + 오푸스 + + + + Vorbis + 보비스 + + + + MP3 + MP3 + + + + AAC + AAC + + + + Uncompressed + 미압축 + + + + Bitrate (kbps) + 전송률 (kbps) + + + + VBR + VBR + + + + ABR + ABR + + + + Dimensions + 크기 + + + + : + : + + + + × + × + + + + Lock aspect ratio + 화면비 잠금 + + + + Show advanced + 고급 보기 + + + From bced52c7c0382d6a1b26e6f42b64748ba2e8e1da Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2019 22:56:45 -0700 Subject: [PATCH 124/429] Qt: Fix mismatched tags in kr translation --- src/platform/qt/ts/mgba-kr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/ts/mgba-kr.ts b/src/platform/qt/ts/mgba-kr.ts index 684a88b39..2eeb9313f 100644 --- a/src/platform/qt/ts/mgba-kr.ts +++ b/src/platform/qt/ts/mgba-kr.ts @@ -3971,7 +3971,7 @@ Game Boy Advance는 Nintendo Co., Ltd.의 등록 상표입니다. View &map... - 지도 &보기... + 지도 &보기... @@ -4578,7 +4578,7 @@ Game Boy Advance는 Nintendo Co., Ltd.의 등록 상표입니다. Bilinear filtering - 이중선형 필터링/translation> + 이중선형 필터링 From 0f7327ea44518acb20874c3a7766443336146408 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 24 Mar 2019 23:07:35 -0700 Subject: [PATCH 125/429] Qt: Rename language files properly --- src/platform/qt/ts/{mgba-kr.ts => mgba-ko.ts} | 0 src/platform/qt/ts/{mgba-zh-cn.ts => mgba-zh_CN.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/platform/qt/ts/{mgba-kr.ts => mgba-ko.ts} (100%) rename src/platform/qt/ts/{mgba-zh-cn.ts => mgba-zh_CN.ts} (100%) diff --git a/src/platform/qt/ts/mgba-kr.ts b/src/platform/qt/ts/mgba-ko.ts similarity index 100% rename from src/platform/qt/ts/mgba-kr.ts rename to src/platform/qt/ts/mgba-ko.ts diff --git a/src/platform/qt/ts/mgba-zh-cn.ts b/src/platform/qt/ts/mgba-zh_CN.ts similarity index 100% rename from src/platform/qt/ts/mgba-zh-cn.ts rename to src/platform/qt/ts/mgba-zh_CN.ts From 782742a731c20f146888d28b97ed8fe666c2f6be Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2019 00:20:21 -0700 Subject: [PATCH 126/429] Qt: Only include qtbase translations if present --- src/platform/qt/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index a910a97c8..f467b4f85 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -268,7 +268,10 @@ if(Qt5LinguistTools_FOUND) foreach(TS ${TS_FILES}) get_filename_component(TS ${TS} NAME) string(REGEX REPLACE "${BINARY_NAME}-(.*).ts$" "qtbase_\\1.qm" QT_QM "${TS}") - list(APPEND QT_QM_FILES "${QT_QM_LOCATION}/${QT_QM}") + set(QT_QM "${QT_QM_LOCATION}/${QT_QM}") + if(EXISTS "${QT_QM}") + list(APPEND QT_QM_FILES "${QT_QM}") + endif() endforeach() list(APPEND TRANSLATION_FILES ${QT_QM_FILES}) endif() From 029d0e169b154dd60e02a0134da25328f8719de1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2019 21:39:57 -0700 Subject: [PATCH 127/429] Vita: Improved frame drawing speed --- CHANGES | 1 + src/platform/psp2/main.c | 1 - src/platform/psp2/psp2-context.c | 5 ++++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 4e6a8db8c..4d295c873 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Misc: - Qt: Improve camera initialization - Qt: Support switching webcams - Core: Add keysRead callback + - Vita: Improved frame drawing speed 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index f5843a911..4dad587d8 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -36,7 +36,6 @@ static void _drawStart(void) { static void _drawEnd(void) { vita2d_end_drawing(); - vita2d_wait_rendering_done(); vita2d_swap_buffers(); } diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 98f44934c..f5d8b1254 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -324,7 +324,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { tex = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); screenshot = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); - outputBuffer = vita2d_texture_get_datap(tex); + outputBuffer = anonymousMemoryMap(256 * toPow2(height) * 4); runner->core->setVideoBuffer(runner->core, outputBuffer, 256); runner->core->setAudioBufferSize(runner->core, PSP2_SAMPLES); @@ -458,6 +458,7 @@ void mPSP2Teardown(struct mGUIRunner* runner) { CircleBufferDeinit(&rumble.history); vita2d_free_texture(tex); vita2d_free_texture(screenshot); + mappedMemoryFree(outputBuffer, 256 * 256 * 4); frameLimiter = true; } @@ -525,6 +526,8 @@ void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded) { void mPSP2Draw(struct mGUIRunner* runner, bool faded) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); + void* texpixels = vita2d_texture_get_datap(tex); + memcpy(texpixels, outputBuffer, 256 * height * 4); _drawTex(tex, width, height, faded); } From 45ec6e50e23532b02c492657f781c26221698464 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 25 Mar 2019 22:01:56 -0700 Subject: [PATCH 128/429] Qt: Use filename for Discord if database lookup fails (fixes #1368) --- src/platform/qt/DiscordCoordinator.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/platform/qt/DiscordCoordinator.cpp b/src/platform/qt/DiscordCoordinator.cpp index 4ff26fe5b..8948cdd50 100644 --- a/src/platform/qt/DiscordCoordinator.cpp +++ b/src/platform/qt/DiscordCoordinator.cpp @@ -63,17 +63,15 @@ void gameStarted(std::shared_ptr controller) { s_gameRunning = true; CoreController::Interrupter interrupter(controller); + mCore *core = controller->thread()->core; + s_title = core->dirs.baseName; + +#ifdef USE_SQLITE3 const NoIntroDB* db = GBAApp::app()->gameDB(); NoIntroGame game{}; uint32_t crc32 = 0; - controller->thread()->core->checksum(controller->thread()->core, &crc32, CHECKSUM_CRC32); + core->checksum(core, &crc32, CHECKSUM_CRC32); - char gameTitle[17] = { '\0' }; - mCore* core = controller->thread()->core; - core->getGameTitle(core, gameTitle); - s_title = gameTitle; - -#ifdef USE_SQLITE3 if (db && crc32 && NoIntroDBLookupGameByCRC(db, crc32, &game)) { s_title = QLatin1String(game.name); } From 73cb853ae48afac00f36f2a49902b458c90b660b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 29 Mar 2019 22:17:09 -0700 Subject: [PATCH 129/429] ARM: Simplify addition OverflowFrom --- include/mgba/internal/arm/isa-inlines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mgba/internal/arm/isa-inlines.h b/include/mgba/internal/arm/isa-inlines.h index a73c157b4..6bb825c91 100644 --- a/include/mgba/internal/arm/isa-inlines.h +++ b/include/mgba/internal/arm/isa-inlines.h @@ -34,7 +34,7 @@ #define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31)) #define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N))) #define ARM_BORROW_FROM_CARRY(M, N, D, C) (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t) (C)) -#define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))) && (ARM_SIGN((N) ^ (D)))) +#define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D)))) #define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D)))) #define ARM_WAIT_MUL(R) \ From 62aa70cca800bf8f320980b1f71947973d08ec3a Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Sat, 30 Mar 2019 17:31:30 +0100 Subject: [PATCH 130/429] Qt: Update German GUI translation regarding the Discord integration --- src/platform/qt/ts/mgba-de.ts | 463 +++++++++++++++++----------------- 1 file changed, 238 insertions(+), 225 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index ea9bab6b6..d410f9102 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -1317,6 +1317,14 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Fehler beim Öffnen der Spieldatei: %1 + + QGBA::GBAApp + + + Enable Discord Rich Presence + Discord-Integration aktivieren + + QGBA::GBAKeyEditor @@ -3277,103 +3285,103 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) - - - + + + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3382,633 +3390,633 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + F10 F10 - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Shift+F10 Umschalt+F10 - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + F11 F11 - + Undo save state Speichern des Savestate rückgängig machen - + Shift+F11 Umschalt+F11 - - + + State &%1 Savestate &%1 - + F%1 F%1 - + Shift+F%1 Umschalt+F%1 - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Ctrl+R Strg+R - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + Ctrl+P Strg+P - + &Next frame &Nächstes Bild - + Ctrl+N Strg+N - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Shift+Tab Umschalt+Tab - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + ~ ~ - + Step backwards Schrittweiser Rücklauf - + Ctrl+B Strg+B - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Solar-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + %1x %1x - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Record output... Ausgabe aufzeichen... - + Record GIF... GIF aufzeichen... - + Record video log... Video-Log aufzeichnen... - + Stop video log Video-Log beenden - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + Game &Pak sensors... Game &Pak-Sensoren... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... - + Select folder Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + About... Über... - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -4316,7 +4324,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + frames Bild(er) @@ -4402,107 +4410,112 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Zustand (Savestate) automatisch laden - + + Enable Discord Rich Presence + Discord-Integration aktivieren + + + Cheats Cheats - + Log to file In Datei protokollieren - + Log to console Auf die Konsole protokollieren - + Select Log File Protokoll-Datei auswählen - + Camera: Kamera: - - - + + + Autodetect Automatisch erkennen - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + Use GBC colors in GB games Verwende GBC-Farben in GB-Spielen - + Super Game Boy borders Super Game Boy-Rahmen - + Game Boy model: Game Boy-Modell: - + Super Game Boy model: Super Game Boy-Modell: - + Game Boy Color model: Game Boy Color-Modell: - + Camera driver: Kamera-Treiber: @@ -4522,47 +4535,47 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - - + + + + + + + + + Browse Durchsuchen - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - + × × - + Unbounded unbegrenzt @@ -4582,17 +4595,17 @@ wenn vorhanden Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen @@ -4602,25 +4615,25 @@ wenn vorhanden Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren @@ -4630,76 +4643,76 @@ wenn vorhanden Bilineare Filterung - + Rewind history: Rücklauf-Verlauf: - + Idle loops: Leerlaufprozesse: - + Savestate extra data: Zusätzliche Savestate-Daten: - + Load extra data: Lade zusätzliche Daten: - + Autofire interval: Autofeuer-Intervall: - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches From da8fee9da163401fc82ff00bf6f9da7a1c181d45 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 30 Mar 2019 23:33:26 -0700 Subject: [PATCH 131/429] 3DS: Ensure core 2 can be used for threaded renderer (fixes #1371) --- CHANGES | 1 + src/platform/3ds/main.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 4d295c873..0072e33c2 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Other fixes: - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) - CMake: Fix .deb imagemagick dependencies - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) + - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 1f3d496a5..288dc029f 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -104,6 +104,7 @@ static C3D_RenderTarget* upscaleBuffer; static C3D_Tex upscaleBufferTex; static aptHookCookie cookie; +static bool core2; extern bool allocateRomBuffer(void); @@ -258,9 +259,7 @@ static void _resetCamera(struct m3DSImageSource* imageSource) { } static void _setup(struct mGUIRunner* runner) { - bool n3ds = false; - APT_CheckNew3DS(&n3ds); - if (n3ds) { + if (core2) { mCoreConfigSetDefaultIntValue(&runner->config, "threadedVideo", 1); mCoreLoadForeignConfig(runner->core, &runner->config); } @@ -752,6 +751,10 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig } } +THREAD_ENTRY _core2Test(void* context) { + UNUSED(context); +} + int main() { rotation.d.sample = _sampleRotation; rotation.d.readTiltX = _readTiltX; @@ -952,6 +955,12 @@ int main() { APT_SetAppCpuTimeLimit(20); runner.autosave.thread = threadCreate(mGUIAutosaveThread, &runner.autosave, 0x4000, 0x1F, 1, true); + Thread thread2; + if (ThreadCreate(&thread2, _core2Test, NULL) == 0) { + core2 = true; + ThreadJoin(thread2); + } + mGUIInit(&runner, "3ds"); _map3DSKey(&runner.params.keyMap, KEY_X, GUI_INPUT_CANCEL); From e18f275aaa0e702233d267e83559a4fdaa37cec6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 31 Mar 2019 11:31:14 -0700 Subject: [PATCH 132/429] 3DS: Re-enable LTO --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df3aa8cff..6cf2a6113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,8 +197,7 @@ list(APPEND UTIL_SRC ${CMAKE_CURRENT_BINARY_DIR}/version.c) source_group("Generated sources" FILES ${CMAKE_CURRENT_BINARY_DIR}/version.c) # Advanced settings -if(NOT DEFINED 3DS AND NOT (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.5")) - # LTO appears to make 3DS binary slower +if(NOT (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.5")) set(DEFAULT_LTO ON) else() set(DEFAULT_LTO OFF) From bf8c1d1b4b52d45cd84590dc7bd7d40b0dffc7bd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 31 Mar 2019 11:59:18 -0700 Subject: [PATCH 133/429] ARM: Remove need for CPSR load in some flag calculations --- include/mgba/internal/arm/arm.h | 14 ++++++++++++++ src/arm/isa-arm.c | 2 ++ src/arm/isa-thumb.c | 2 ++ 3 files changed, 18 insertions(+) diff --git a/include/mgba/internal/arm/arm.h b/include/mgba/internal/arm/arm.h index 7bc1328bf..55e847c7f 100644 --- a/include/mgba/internal/arm/arm.h +++ b/include/mgba/internal/arm/arm.h @@ -93,6 +93,20 @@ union PSR { #endif }; + struct { +#if defined(__BIG_ENDIAN__) + uint8_t flags; + uint8_t status; + uint8_t extension; + uint8_t control; +#else + uint8_t control; + uint8_t extension; + uint8_t status; + uint8_t flags; +#endif + }; + int32_t packed; }; diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 901174b75..ae8d61820 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -185,6 +185,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) { // Beware pre-processor antics ATTRIBUTE_NOINLINE static void _additionS(struct ARMCore* cpu, int32_t m, int32_t n, int32_t d) { + cpu->cpsr.flags = 0; cpu->cpsr.n = ARM_SIGN(d); cpu->cpsr.z = !d; cpu->cpsr.c = ARM_CARRY_FROM(m, n, d); @@ -192,6 +193,7 @@ ATTRIBUTE_NOINLINE static void _additionS(struct ARMCore* cpu, int32_t m, int32_ } ATTRIBUTE_NOINLINE static void _subtractionS(struct ARMCore* cpu, int32_t m, int32_t n, int32_t d) { + cpu->cpsr.flags = 0; cpu->cpsr.n = ARM_SIGN(d); cpu->cpsr.z = !d; cpu->cpsr.c = ARM_BORROW_FROM(m, n, d); diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index ad72bffb9..ede7ba368 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -12,12 +12,14 @@ // Beware pre-processor insanity #define THUMB_ADDITION_S(M, N, D) \ + cpu->cpsr.flags = 0; \ cpu->cpsr.n = ARM_SIGN(D); \ cpu->cpsr.z = !(D); \ cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \ cpu->cpsr.v = ARM_V_ADDITION(M, N, D); #define THUMB_SUBTRACTION_S(M, N, D) \ + cpu->cpsr.flags = 0; \ cpu->cpsr.n = ARM_SIGN(D); \ cpu->cpsr.z = !(D); \ cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \ From 9424cd54ef24f51e0ab3e3b8154313020d132e0e Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Thu, 11 Apr 2019 10:45:59 +0200 Subject: [PATCH 134/429] Qt: Add stub for Turkish GUI translation --- src/platform/qt/ts/mgba-tr.ts | 5002 +++++++++++++++++++++++++++++++++ 1 file changed, 5002 insertions(+) create mode 100644 src/platform/qt/ts/mgba-tr.ts diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts new file mode 100644 index 000000000..0a05c277c --- /dev/null +++ b/src/platform/qt/ts/mgba-tr.ts @@ -0,0 +1,5002 @@ + + + + + AboutScreen + + + About + + + + + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> + + + + + Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> + + + + + {projectName} + + + + + {projectName} would like to thank the following patrons from Patreon: + + + + + © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + + + + + {projectVersion} + + + + + {logo} + + + + + {projectName} is an open-source Game Boy Advance emulator + + + + + {patrons} + + + + + ArchiveInspector + + + Open in archive... + + + + + Loading... + + + + + AssetTile + + + AssetTile + + + + + Tile # + + + + + + 0 + + + + + Palette # + + + + + Address + + + + + 0x06000000 + + + + + Red + + + + + Green + + + + + Blue + + + + + + + 0x00 (00) + + + + + BattleChipView + + + BattleChip Gate + + + + + Chip name + + + + + Insert + + + + + Save + + + + + Load + + + + + Add + + + + + Remove + + + + + Gate type + + + + + Ba&ttleChip Gate + + + + + Progress &Gate + + + + + Beast &Link Gate + + + + + Inserted + + + + + Chip ID + + + + + Update Chip data + + + + + Show advanced + + + + + CheatsView + + + Cheats + + + + + Remove + + + + + Save + + + + + Load + + + + + Add New Set + + + + + Add + + + + + DebuggerConsole + + + Debugger + + + + + Enter command (try `help` for more info) + + + + + Break + + + + + GIFView + + + Record GIF + + + + + Start + + + + + Stop + + + + + Select File + + + + + Frameskip + + + + + Frame delay (ms) + + + + + Automatic + + + + + IOViewer + + + I/O Viewer + + + + + 0x0000 + + + + + 2 + + + + + 5 + + + + + 4 + + + + + 7 + + + + + 0 + + + + + 9 + + + + + 1 + + + + + 3 + + + + + 8 + + + + + C + + + + + E + + + + + 6 + + + + + D + + + + + F + + + + + A + + + + + B + + + + + LibraryTree + + + Name + + + + + Location + + + + + Platform + + + + + Size + + + + + CRC32 + + + + + LoadSaveState + + + + %1 State + + + + + + + + + + + + + No Save + + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + LogView + + + Logs + + + + + Enabled Levels + + + + + Debug + + + + + Stub + + + + + Info + + + + + Warning + + + + + Error + + + + + Fatal + + + + + Game Error + + + + + Clear + + + + + Max Lines + + + + + MapView + + + Maps + + + + + × + + + + + Magnification + + + + + Export + + + + + MemorySearch + + + Memory Search + + + + + Address + + + + + Current Value + + + + + + Type + + + + + Value + + + + + Numeric + + + + + Text + + + + + Width + + + + + + Guess + + + + + 1 Byte (8-bit) + + + + + 2 Bytes (16-bit) + + + + + 4 Bytes (32-bit) + + + + + Number type + + + + + Decimal + + + + + Hexadecimal + + + + + Compare + + + + + Equal + + + + + Greater + + + + + Less + + + + + Delta + + + + + Search + + + + + Search Within + + + + + Open in Memory Viewer + + + + + Refresh + + + + + MemoryView + + + Memory + + + + + Inspect Address: + + + + + 0x + + + + + Set Alignment: + + + + + &1 Byte + + + + + &2 Bytes + + + + + &4 Bytes + + + + + Unsigned Integer: + + + + + Signed Integer: + + + + + String: + + + + + Load TBL + + + + + Copy Selection + + + + + Paste + + + + + Save Selection + + + + + Load + + + + + ObjView + + + Sprites + + + + + + × + + + + + Magnification + + + + + Export + + + + + Attributes + + + + + Transform + + + + + Off + + + + + Palette + + + + + + + + 0 + + + + + Double Size + + + + + + + + Return, Ctrl+R + + + + + Flipped + + + + + H + + + + + V + + + + + Mode + + + + + Normal + + + + + Mosaic + + + + + Enabled + + + + + Priority + + + + + Tile + + + + + Geometry + + + + + Position + + + + + , + + + + + Dimensions + + + + + + 8 + + + + + Address + + + + + 0x07000000 + + + + + OverrideView + + + Game Overrides + + + + + Game Boy Advance + + + + + + + + Autodetect + + + + + Realtime clock + + + + + Gyroscope + + + + + Tilt + + + + + Light sensor + + + + + Rumble + + + + + Save type + + + + + + None + + + + + SRAM + + + + + Flash 512kb + + + + + Flash 1Mb + + + + + EEPROM + + + + + Idle loop + + + + + Game Boy Player features + + + + + Game Boy + + + + + Game Boy model + + + + + Game Boy (DMG) + + + + + Super Game Boy (SGB) + + + + + Game Boy Color (CGB) + + + + + Game Boy Advance (AGB) + + + + + Memory bank controller + + + + + MBC1 + + + + + MBC2 + + + + + MBC3 + + + + + MBC3 + RTC + + + + + MBC5 + + + + + MBC5 + Rumble + + + + + MBC7 + + + + + Pocket Cam + + + + + TAMA5 + + + + + HuC-3 + + + + + Background Colors + + + + + Sprite Colors 1 + + + + + Sprite Colors 2 + + + + + PaletteView + + + Palette + + + + + Background + + + + + Objects + + + + + Selection + + + + + Red + + + + + Green + + + + + Blue + + + + + + + 0x00 (00) + + + + + 16-bit value + + + + + Hex code + + + + + Palette index + + + + + 0x0000 + + + + + #000000 + + + + + 000 + + + + + Export BG + + + + + Export OBJ + + + + + PlacementControl + + + Adjust placement + + + + + All + + + + + Offset + + + + + X + + + + + Y + + + + + PrinterView + + + Game Boy Printer + + + + + Hurry up! + + + + + Tear off + + + + + QGBA::AssetTile + + + %0%1%2 + + + + + + + 0x%0 (%1) + + + + + QGBA::CheatsModel + + + (untitled) + + + + + Failed to open cheats file: %1 + + + + + QGBA::CheatsView + + + + Add GameShark + + + + + Add Pro Action Replay + + + + + Add CodeBreaker + + + + + Add GameGenie + + + + + + Select cheats file + + + + + QGBA::CoreController + + + Failed to open save file: %1 + + + + + Failed to open game file: %1 + + + + + Failed to open snapshot file for reading: %1 + + + + + Failed to open snapshot file for writing: %1 + + + + + QGBA::CoreManager + + + Failed to open game file: %1 + + + + + QGBA::GBAApp + + + Enable Discord Rich Presence + + + + + QGBA::GBAKeyEditor + + + Clear Button + + + + + Clear Analog + + + + + Refresh + + + + + Set all + + + + + QGBA::GDBWindow + + + Server settings + + + + + Local port + + + + + Bind address + + + + + Break + + + + + Stop + + + + + Start + + + + + Crash + + + + + Could not start GDB server + + + + + QGBA::GIFView + + + Failed to open output GIF file: %1 + + + + + Select output file + + + + + Graphics Interchange Format (*.gif) + + + + + QGBA::IOViewer + + + Background mode + + + + + Mode 0: 4 tile layers + + + + + Mode 1: 2 tile layers + 1 rotated/scaled tile layer + + + + + Mode 2: 2 rotated/scaled tile layers + + + + + Mode 3: Full 15-bit bitmap + + + + + Mode 4: Full 8-bit bitmap + + + + + Mode 5: Small 15-bit bitmap + + + + + CGB Mode + + + + + Frame select + + + + + Unlocked HBlank + + + + + Linear OBJ tile mapping + + + + + Force blank screen + + + + + Enable background 0 + + + + + Enable background 1 + + + + + Enable background 2 + + + + + Enable background 3 + + + + + Enable OBJ + + + + + Enable Window 0 + + + + + Enable Window 1 + + + + + Enable OBJ Window + + + + + Currently in VBlank + + + + + Currently in HBlank + + + + + Currently in VCounter + + + + + Enable VBlank IRQ generation + + + + + Enable HBlank IRQ generation + + + + + Enable VCounter IRQ generation + + + + + VCounter scanline + + + + + Current scanline + + + + + + + + Priority + + + + + + + + Tile data base (* 16kB) + + + + + + + + Enable mosaic + + + + + + + + Enable 256-color + + + + + + + + Tile map base (* 2kB) + + + + + + + + Background dimensions + + + + + + Overflow wraps + + + + + + + + Horizontal offset + + + + + + + + Vertical offset + + + + + + + + + + + + + + + + Fractional part + + + + + + + + + + + + Integer part + + + + + + + + Integer part (bottom) + + + + + + + + Integer part (top) + + + + + + End x + + + + + + Start x + + + + + + End y + + + + + + Start y + + + + + Window 0 enable BG 0 + + + + + Window 0 enable BG 1 + + + + + Window 0 enable BG 2 + + + + + Window 0 enable BG 3 + + + + + Window 0 enable OBJ + + + + + Window 0 enable blend + + + + + Window 1 enable BG 0 + + + + + Window 1 enable BG 1 + + + + + Window 1 enable BG 2 + + + + + Window 1 enable BG 3 + + + + + Window 1 enable OBJ + + + + + Window 1 enable blend + + + + + Outside window enable BG 0 + + + + + Outside window enable BG 1 + + + + + Outside window enable BG 2 + + + + + Outside window enable BG 3 + + + + + Outside window enable OBJ + + + + + Outside window enable blend + + + + + OBJ window enable BG 0 + + + + + OBJ window enable BG 1 + + + + + OBJ window enable BG 2 + + + + + OBJ window enable BG 3 + + + + + OBJ window enable OBJ + + + + + OBJ window enable blend + + + + + Background mosaic size vertical + + + + + Background mosaic size horizontal + + + + + Object mosaic size vertical + + + + + Object mosaic size horizontal + + + + + BG 0 target 1 + + + + + BG 1 target 1 + + + + + BG 2 target 1 + + + + + BG 3 target 1 + + + + + OBJ target 1 + + + + + Backdrop target 1 + + + + + Blend mode + + + + + Disabled + + + + + Additive blending + + + + + Brighten + + + + + Darken + + + + + BG 0 target 2 + + + + + BG 1 target 2 + + + + + BG 2 target 2 + + + + + BG 3 target 2 + + + + + OBJ target 2 + + + + + Backdrop target 2 + + + + + Blend A (target 1) + + + + + Blend B (target 2) + + + + + Blend Y + + + + + Sweep shifts + + + + + Sweep subtract + + + + + Sweep time (in 1/128s) + + + + + + + + Sound length + + + + + + Duty cycle + + + + + + + Envelope step time + + + + + + + Envelope increase + + + + + + + Initial volume + + + + + + + Sound frequency + + + + + + + + Timed + + + + + + + + Reset + + + + + Double-size wave table + + + + + Active wave table + + + + + Enable channel 3 + + + + + Volume + + + + + 0% + + + + + + 100% + + + + + + 50% + + + + + + 25% + + + + + + + + 75% + + + + + Clock divider + + + + + Register stages + + + + + 15 + + + + + 7 + + + + + Shifter frequency + + + + + PSG volume right + + + + + PSG volume left + + + + + Enable channel 1 right + + + + + Enable channel 2 right + + + + + Enable channel 3 right + + + + + Enable channel 4 right + + + + + Enable channel 1 left + + + + + Enable channel 2 left + + + + + Enable channel 3 left + + + + + Enable channel 4 left + + + + + PSG master volume + + + + + Loud channel A + + + + + Loud channel B + + + + + Enable channel A right + + + + + Enable channel A left + + + + + Channel A timer + + + + + + 0 + + + + + + + + + + + + + 1 + + + + + Channel A reset + + + + + Enable channel B right + + + + + Enable channel B left + + + + + Channel B timer + + + + + Channel B reset + + + + + Active channel 1 + + + + + Active channel 2 + + + + + Active channel 3 + + + + + Active channel 4 + + + + + Enable audio + + + + + Bias + + + + + Resolution + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sample + + + + + + + + + + + + Address (bottom) + + + + + + + + + + + + Address (top) + + + + + + + + Word count + + + + + + + + Destination offset + + + + + + + + + + + + Increment + + + + + + + + + + + + Decrement + + + + + + + + + + + + Fixed + + + + + + + + Increment and reload + + + + + + + + Source offset + + + + + + + + Repeat + + + + + + + + 32-bit + + + + + + + + Start timing + + + + + + + + Immediate + + + + + + + + + + VBlank + + + + + + + + + + HBlank + + + + + + + + + + + + + IRQ + + + + + + + + + + + + Enable + + + + + + + Audio FIFO + + + + + Video Capture + + + + + DRQ + + + + + + + + Value + + + + + + + + Scale + + + + + + + + 1/64 + + + + + + + + 1/256 + + + + + + + + 1/1024 + + + + + + + Cascade + + + + + + A + + + + + + B + + + + + + Select + + + + + + Start + + + + + + Right + + + + + + Left + + + + + + Up + + + + + + Down + + + + + + R + + + + + + L + + + + + Condition + + + + + SC + + + + + SD + + + + + SI + + + + + SO + + + + + + VCounter + + + + + + Timer 0 + + + + + + Timer 1 + + + + + + Timer 2 + + + + + + Timer 3 + + + + + + SIO + + + + + + DMA 0 + + + + + + DMA 1 + + + + + + DMA 2 + + + + + + DMA 3 + + + + + + Keypad + + + + + + Gamepak + + + + + SRAM wait + + + + + + + + + 4 + + + + + + + + 3 + + + + + + + + + 2 + + + + + + + + + 8 + + + + + Cart 0 non-sequential + + + + + Cart 0 sequential + + + + + Cart 1 non-sequential + + + + + Cart 1 sequential + + + + + Cart 2 non-sequential + + + + + Cart 2 sequential + + + + + PHI terminal + + + + + Disable + + + + + 4.19MHz + + + + + 8.38MHz + + + + + 16.78MHz + + + + + Gamepak prefetch + + + + + Enable IRQs + + + + + QGBA::KeyEditor + + + + --- + + + + + QGBA::LoadSaveState + + + Load State + + + + + Save State + + + + + Empty + + + + + Corrupted + + + + + Slot %1 + + + + + QGBA::LogConfigModel + + + + Default + + + + + Fatal + + + + + Error + + + + + Warning + + + + + Info + + + + + Debug + + + + + Stub + + + + + Game Error + + + + + QGBA::LogController + + + [%1] %2: %3 + + + + + DEBUG + + + + + STUB + + + + + INFO + + + + + WARN + + + + + ERROR + + + + + FATAL + + + + + GAME ERROR + + + + + QGBA::MapView + + + Map Addr. + + + + + Mirror + + + + + None + + + + + Both + + + + + Horizontal + + + + + Vertical + + + + + Export map + + + + + Portable Network Graphics (*.png) + + + + + Failed to open output PNG file: %1 + + + + + QGBA::MemoryModel + + + Copy selection + + + + + Save selection + + + + + Paste + + + + + Load + + + + + All + + + + + Load TBL + + + + + Save selected memory + + + + + Failed to open output file: %1 + + + + + Load memory + + + + + Failed to open input file: %1 + + + + + TBL + + + + + ISO-8859-1 + + + + + QGBA::MemorySearch + + + (%0/%1×) + + + + + (⅟%0×) + + + + + (%0×) + + + + + %1 byte%2 + + + + + QGBA::ObjView + + + + 0x%0 + + + + + Off + + + + + Normal + + + + + Trans + + + + + OBJWIN + + + + + Invalid + + + + + + N/A + + + + + Export sprite + + + + + Portable Network Graphics (*.png) + + + + + Failed to open output PNG file: %1 + + + + + QGBA::PaletteView + + + #%0 + + + + + 0x%0 + + + + + %0 + + + + + + + 0x%0 (%1) + + + + + Export palette + + + + + Windows PAL (*.pal);;Adobe Color Table (*.act) + + + + + Failed to open output palette file: %1 + + + + + QGBA::ROMInfo + + + + + + + (unknown) + + + + + + bytes + + + + + (no database present) + + + + + QGBA::SettingsView + + + + Qt Multimedia + + + + + SDL + + + + + Software (Qt) + + + + + OpenGL + + + + + OpenGL (force version 1.x) + + + + + None (Still Image) + + + + + Keyboard + + + + + Controllers + + + + + Shortcuts + + + + + + Shaders + + + + + Select BIOS + + + + + QGBA::ShaderSelector + + + No shader active + + + + + Load shader + + + + + No shader loaded + + + + + by %1 + + + + + Preprocessing + + + + + Pass %1 + + + + + QGBA::ShortcutController + + + Action + + + + + Keyboard + + + + + Gamepad + + + + + QGBA::VideoView + + + Failed to open output video file: %1 + + + + + Native (%0x%1) + + + + + Select output file + + + + + QGBA::Window + + + Game Boy Advance ROMs (%1) + + + + + Game Boy ROMs (%1) + + + + + All ROMs (%1) + + + + + %1 Video Logs (*.mvl) + + + + + Archives (%1) + + + + + + + Select ROM + + + + + Select folder + + + + + Game Boy Advance save files (%1) + + + + + + + Select save + + + + + mGBA savestate files (%1) + + + + + + Select savestate + + + + + Select patch + + + + + Patches (*.ips *.ups *.bps) + + + + + Select image + + + + + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) + + + + + + GameShark saves (*.sps *.xps) + + + + + Select video log + + + + + Video logs (*.mvl) + + + + + Crash + + + + + The game has crashed with the following error: + +%1 + + + + + Couldn't Load + + + + + Could not load game. Are you sure it's in the correct format? + + + + + Unimplemented BIOS call + + + + + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. + + + + + Really make portable? + + + + + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? + + + + + Restart needed + + + + + Some changes will not take effect until the emulator is restarted. + + + + + - Player %1 of %2 + + + + + %1 - %2 + + + + + %1 - %2 - %3 + + + + + %1 - %2 (%3 fps) - %4 + + + + + &File + + + + + Load &ROM... + + + + + Load ROM in archive... + + + + + Add folder to library... + + + + + Load alternate save... + + + + + Load temporary save... + + + + + Load &patch... + + + + + Boot BIOS + + + + + Replace ROM... + + + + + ROM &info... + + + + + Recent + + + + + Make portable + + + + + &Load state + + + + + F10 + + + + + Load state file... + + + + + &Save state + + + + + Shift+F10 + + + + + Save state file... + + + + + Quick load + + + + + Quick save + + + + + Load recent + + + + + Save recent + + + + + Undo load state + + + + + F11 + + + + + Undo save state + + + + + Shift+F11 + + + + + + State &%1 + + + + + F%1 + + + + + Shift+F%1 + + + + + Load camera image... + + + + + Import GameShark Save + + + + + Export GameShark Save + + + + + New multiplayer window + + + + + About... + + + + + E&xit + + + + + &Emulation + + + + + &Reset + + + + + Ctrl+R + + + + + Sh&utdown + + + + + Yank game pak + + + + + &Pause + + + + + Ctrl+P + + + + + &Next frame + + + + + Ctrl+N + + + + + Fast forward (held) + + + + + &Fast forward + + + + + Shift+Tab + + + + + Fast forward speed + + + + + Unbounded + + + + + %0x + + + + + Rewind (held) + + + + + Re&wind + + + + + ~ + + + + + Step backwards + + + + + Ctrl+B + + + + + Sync to &video + + + + + Sync to &audio + + + + + Solar sensor + + + + + Increase solar level + + + + + Decrease solar level + + + + + Brightest solar level + + + + + Darkest solar level + + + + + Brightness %1 + + + + + Game Boy Printer... + + + + + BattleChip Gate... + + + + + Audio/&Video + + + + + Frame size + + + + + %1x + + + + + Toggle fullscreen + + + + + Lock aspect ratio + + + + + Force integer scaling + + + + + Bilinear filtering + + + + + Frame&skip + + + + + Mute + + + + + FPS target + + + + + Native (59.7275) + + + + + Take &screenshot + + + + + F12 + + + + + Record output... + + + + + Record GIF... + + + + + Record video log... + + + + + Stop video log + + + + + Video layers + + + + + Audio channels + + + + + Adjust layer placement... + + + + + &Tools + + + + + View &logs... + + + + + Game &overrides... + + + + + Game &Pak sensors... + + + + + &Cheats... + + + + + Settings... + + + + + Open debugger console... + + + + + Start &GDB server... + + + + + View &palette... + + + + + View &sprites... + + + + + View &tiles... + + + + + View &map... + + + + + View memory... + + + + + Search memory... + + + + + View &I/O registers... + + + + + Exit fullscreen + + + + + GameShark Button (held) + + + + + Autofire + + + + + Autofire A + + + + + Autofire B + + + + + Autofire L + + + + + Autofire R + + + + + Autofire Start + + + + + Autofire Select + + + + + Autofire Up + + + + + Autofire Right + + + + + Autofire Down + + + + + Autofire Left + + + + + QObject + + + GBA + + + + + GB + + + + + ? + + + + + ROMInfo + + + ROM Info + + + + + Game name: + + + + + {NAME} + + + + + Internal name: + + + + + {TITLE} + + + + + Game ID: + + + + + {ID} + + + + + File size: + + + + + {SIZE} + + + + + CRC32: + + + + + {CRC} + + + + + SensorView + + + Sensors + + + + + Realtime clock + + + + + Fixed time + + + + + System time + + + + + Start time at + + + + + Now + + + + + MM/dd/yy hh:mm:ss AP + + + + + Light sensor + + + + + Brightness + + + + + Tilt sensor + + + + + + Set Y + + + + + + Set X + + + + + Gyroscope + + + + + Sensitivity + + + + + SettingsView + + + Settings + + + + + Audio/Video + + + + + Interface + + + + + Emulation + + + + + BIOS + + + + + Paths + + + + + Logging + + + + + Game Boy + + + + + Audio driver: + + + + + Audio buffer: + + + + + + 1536 + + + + + 512 + + + + + 768 + + + + + 1024 + + + + + 2048 + + + + + 3072 + + + + + 4096 + + + + + samples + + + + + Sample rate: + + + + + + 44100 + + + + + 22050 + + + + + 32000 + + + + + 48000 + + + + + Hz + + + + + Volume: + + + + + + Mute + + + + + Fast forward volume: + + + + + Display driver: + + + + + Frameskip: + + + + + Skip every + + + + + + frames + + + + + FPS target: + + + + + frames per second + + + + + Sync: + + + + + Video + + + + + Audio + + + + + Lock aspect ratio + + + + + Force integer scaling + + + + + Bilinear filtering + + + + + Language + + + + + English + + + + + Library: + + + + + List view + + + + + Tree view + + + + + Show when no game open + + + + + Clear cache + + + + + Allow opposing input directions + + + + + Suspend screensaver + + + + + Pause when inactive + + + + + Show FPS in title bar + + + + + Automatically save cheats + + + + + Automatically load cheats + + + + + Automatically save state + + + + + Automatically load state + + + + + Enable Discord Rich Presence + + + + + Fast forward speed: + + + + + × + + + + + Unbounded + + + + + Autofire interval: + + + + + Enable rewind + + + + + Rewind history: + + + + + Idle loops: + + + + + Run all + + + + + Remove known + + + + + Detect and remove + + + + + Preload entire ROM into memory + + + + + Savestate extra data: + + + + + + Screenshot + + + + + + Save data + + + + + + Cheat codes + + + + + Load extra data: + + + + + GB BIOS file: + + + + + + + + + + + + + Browse + + + + + Use BIOS file if found + + + + + Skip BIOS intro + + + + + GBA BIOS file: + + + + + GBC BIOS file: + + + + + SGB BIOS file: + + + + + Save games + + + + + + + + + Same directory as the ROM + + + + + Save states + + + + + Screenshots + + + + + Patches + + + + + Cheats + + + + + Log to file + + + + + Log to console + + + + + Select Log File + + + + + Game Boy model: + + + + + + + Autodetect + + + + + + + Game Boy (DMG) + + + + + + + Super Game Boy (SGB) + + + + + + + Game Boy Color (CGB) + + + + + + + Game Boy Advance (AGB) + + + + + Super Game Boy model: + + + + + Game Boy Color model: + + + + + Default BG colors: + + + + + Super Game Boy borders + + + + + Camera driver: + + + + + Default sprite colors 1: + + + + + Default sprite colors 2: + + + + + Use GBC colors in GB games + + + + + Camera: + + + + + ShaderSelector + + + Shaders + + + + + Active Shader: + + + + + Name + + + + + Author + + + + + Description + + + + + Unload Shader + + + + + Load New Shader + + + + + ShortcutView + + + Edit Shortcuts + + + + + Keyboard + + + + + Gamepad + + + + + Clear + + + + + TileView + + + Tiles + + + + + 256 colors + + + + + × + + + + + Magnification + + + + + Tiles per row + + + + + Fit to window + + + + + VideoView + + + Record Video + + + + + Start + + + + + Stop + + + + + Select File + + + + + Presets + + + + + High &Quality + + + + + &YouTube + + + + + + WebM + + + + + &Lossless + + + + + &1080p + + + + + &720p + + + + + &480p + + + + + &Native + + + + + Format + + + + + MKV + + + + + AVI + + + + + MP4 + + + + + h.264 + + + + + h.264 (NVENC) + + + + + HEVC + + + + + HEVC (NVENC) + + + + + VP8 + + + + + VP9 + + + + + FFV1 + + + + + FLAC + + + + + Opus + + + + + Vorbis + + + + + MP3 + + + + + AAC + + + + + Uncompressed + + + + + Bitrate (kbps) + + + + + VBR + + + + + ABR + + + + + Dimensions + + + + + : + + + + + × + + + + + Lock aspect ratio + + + + + Show advanced + + + + From 64f42590a725a3887c130b2245e4443d6f1e4716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mercan=20K=C3=B6m=C3=BCr?= Date: Tue, 16 Apr 2019 22:36:02 +0300 Subject: [PATCH 135/429] Turkish language (#1387) Fully translated Turkish language --- src/platform/qt/ts/mgba-tr.ts | 1799 +++++++++++++++++---------------- 1 file changed, 901 insertions(+), 898 deletions(-) diff --git a/src/platform/qt/ts/mgba-tr.ts b/src/platform/qt/ts/mgba-tr.ts index 0a05c277c..af7604d05 100644 --- a/src/platform/qt/ts/mgba-tr.ts +++ b/src/platform/qt/ts/mgba-tr.ts @@ -6,53 +6,54 @@ About - + Hakkında <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> - + Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> - + {projectName} - + {projectName} would like to thank the following patrons from Patreon: - + {projectName} Patreon'daki kullanıcılara teşekkür etmek istiyorum: © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - + © 2013 - 2019 Mozilla Public License, 2.0 sürümünde lisanslı Jeffrey Pfau +Game Boy Advance, Nintendo Co., Ltd.'nin tescilli ticari markasıdır. {projectVersion} - + {logo} - + {projectName} is an open-source Game Boy Advance emulator - + {patrons} - + @@ -60,12 +61,12 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Open in archive... - + Arşivi açmak için... Loading... - + Bekleniyor... @@ -73,55 +74,55 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. AssetTile - + Tile # - + Desen 0 - + Palette # - + Palet Address - + Adres 0x06000000 - + Red - + Kırmızı Green - + Yeşil Blue - + Mavi 0x00 (00) - + @@ -129,77 +130,77 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. BattleChip Gate - + Chip name - + Chip ismi Insert - + Ekle Save - + Kaydet Load - + Yükle Add - + Ekle Remove - + Kaldır Gate type - + Ba&ttleChip Gate - + Progress &Gate - + Beast &Link Gate - + Inserted - + Eklenen Chip ID - + Update Chip data - + Chip verilerini güncelle Show advanced - + Gelişmişi göster @@ -207,32 +208,32 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Cheats - + Hileler Remove - + Kaldır Save - + Kaydet Load - + Yükle Add New Set - + Yeni set ekle Add - + Ekle @@ -240,17 +241,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Debugger - + Enter command (try `help` for more info) - + Komutu girin (daha fazla bilgi için `yardım` ı deneyin) Break - + @@ -258,37 +259,37 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Record GIF - + GIF kaydet Start - + Başlat Stop - + Durdur Select File - + Dosya Seç Frameskip - + Kare atlama Frame delay (ms) - + Kare geçkimesi (ms) Automatic - + Otomatik @@ -296,92 +297,92 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. I/O Viewer - + 0x0000 - + 2 - + 5 - + 4 - + 7 - + 0 - + 9 - + 1 - + 3 - + 8 - + C - + E - + 6 - + D - + F - + A - + B - + @@ -389,27 +390,27 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Name - + İsim Location - + Konum Platform - + Platform Size - + Boyut CRC32 - + @@ -418,7 +419,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. %1 State - + @@ -431,52 +432,52 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. No Save - + Kayıt yok 1 - + 2 - + 3 - + 4 - + 5 - + 6 - + 7 - + 8 - + 9 - + @@ -484,57 +485,57 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Logs - + Enabled Levels - + Seçenekler Debug - + Stub - + Info - + Bilgi Warning - + Uyarılar Error - + Hata Fatal - + Game Error - + Clear - + Temizle Max Lines - + Maksiumum satır @@ -542,22 +543,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Maps - + Haritalar × - + Magnification - + Büyüt Export - + Dışarı aktar @@ -565,124 +566,124 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Memory Search - + Address - + Current Value - + Mevcut değer Type - + Tip Value - + Değer Numeric - + Sayısal Text - + Yazı Width - + Genişlik Guess - + Tahmini 1 Byte (8-bit) - + 2 Bytes (16-bit) - + 4 Bytes (32-bit) - + Number type - + Numara tipi Decimal - + Ondalık Hexadecimal - + Onaltılık Compare - + Karşılaştır Equal - + Eşittir Greater - + Büyüktür Less - + Küçüktür Delta - + Search - + Ara Search Within - + Aralığında ara Open in Memory Viewer - + Memory Viewer'da aç Refresh - + Yenile @@ -690,77 +691,77 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Memory - + Inspect Address: - + Kontrol edilecek adres: 0x - + Set Alignment: - + Hizalamayı Ayarla: &1 Byte - + &2 Bytes - + &4 Bytes - + Unsigned Integer: - + İşaretsiz tam sayı: Signed Integer: - + İşaretlenmiş tam sayı: String: - + Sicim: Load TBL - + TBL yükle Copy Selection - + Seçilenleri kopyala Paste - + Yapıştır Save Selection - + Seçilenleri kaydet Load - + Yükle @@ -768,43 +769,43 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Sprites - + × - + Magnification - + Büyüklük Export - + Dışa aktar Attributes - + Değerler Transform - + Dönüştür Off - + Kapalı Palette - + Palet @@ -812,12 +813,12 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 0 - + Double Size - + Çift taraf @@ -825,88 +826,88 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Return, Ctrl+R - + Flipped - + Çevirilmiş H - + V - + Mode - + Mod Normal - + Normal Mosaic - + Mozaik Enabled - + Aktifleştir Priority - + Öncelik Tile - + Geometry - + Geometri Position - + Pozisyon , - + Dimensions - + Boyutlar 8 - + Address - + Adres 0x07000000 - + @@ -914,12 +915,12 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Game Overrides - + Oyun üzerine yazmaları Game Boy Advance - + @@ -927,173 +928,173 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Autodetect - + Otomatik tespit Realtime clock - + Gyroscope - + Jiroskop Tilt - + Eğiim Light sensor - + Rumble - + Save type - + Kayıt tipi None - + Hiçbiri SRAM - + Flash 512kb - + Flash 1Mb - + EEPROM - + Idle loop - + Game Boy Player features - + Game Boy - + Game Boy model - + Game Boy modeli Game Boy (DMG) - + Super Game Boy (SGB) - + Game Boy Color (CGB) - + Game Boy Advance (AGB) - + Memory bank controller - + MBC1 - + MBC2 - + MBC3 - + MBC3 + RTC - + MBC5 - + MBC5 + Rumble - + MBC7 - + Pocket Cam - + TAMA5 - + HuC-3 - + Background Colors - + Arkaplan renkleri Sprite Colors 1 - + Sprite Renkleri 1 Sprite Colors 2 - + Sprite Renkleri 2 @@ -1101,84 +1102,84 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Palette - + Palet Background - + Arkaplan Objects - + Objeler Selection - + Seçim Red - + Kırmızı Green - + Yeşil Blue - + Mavi 0x00 (00) - + 16-bit value - + 16-bit değeri Hex code - + Hex kodu Palette index - + 0x0000 - + #000000 - + 000 - + Export BG - + Arkaplan dışarı aktar Export OBJ - + OBJ dışarı aktar @@ -1186,27 +1187,27 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Adjust placement - + Yerleşimi ayarla All - + Hepsi Offset - + Çıkıntı X - + Y - + @@ -1214,17 +1215,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Game Boy Printer - + Hurry up! - + Tear off - + @@ -1232,14 +1233,14 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. %0%1%2 - + 0x%0 (%1) - + @@ -1247,12 +1248,12 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. (untitled) - + (Başlıksız) Failed to open cheats file: %1 - + Hileleri dosyasını açamadı:%1 @@ -1261,28 +1262,28 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Add GameShark - + GameShark ekle Add Pro Action Replay - + Pro Action Replay ekle Add CodeBreaker - + CodeBreaker ekle Add GameGenie - + GameGenie ekle Select cheats file - + Oyun hileleri seçin @@ -1290,22 +1291,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open save file: %1 - + Kayıt dosyası açılamadı: %1 Failed to open game file: %1 - + Oyun dosyası açılamadı: %1 Failed to open snapshot file for reading: %1 - + Anlık görüntü dosyası okuma için açılamadı: %1 Failed to open snapshot file for writing: %1 - + Anlık görüntü dosyası yazma için açılamadı: %1 @@ -1313,7 +1314,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open game file: %1 - + Oyun dosyası açılamadı: %1 @@ -1321,7 +1322,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Enable Discord Rich Presence - + Discord etkinliğini etkinleştir @@ -1329,22 +1330,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Clear Button - + Clear Analog - + Refresh - + Yenile Set all - + Tümüne ayarla @@ -1352,42 +1353,42 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Server settings - + Sunucu ayarları Local port - + Yerel port Bind address - + Adresi bağla Break - + Stop - + Durdur Start - + Başlat Crash - + Could not start GDB server - + GDB sunucusu başlatılamadı @@ -1395,17 +1396,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open output GIF file: %1 - + Çıkış GIF dosyası açılamadı:%1 Select output file - + Çıktı dosyasını seçin Graphics Interchange Format (*.gif) - + Grafik Değişim Biçimi (* .gif) @@ -1413,142 +1414,142 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Background mode - + Arkaplan modu Mode 0: 4 tile layers - + Mod 0: 4 döşeme katmanları Mode 1: 2 tile layers + 1 rotated/scaled tile layer - + Mod 1: 2 döşeme katmanı + 1 döndürülmüş/ölçeklendirilmiş döşeme katmanı Mode 2: 2 rotated/scaled tile layers - + Mod 2: 2 döndürülmüş/ölçeklenmiş döşeme katmanları Mode 3: Full 15-bit bitmap - + Mod 3: Tam 15-bit bitmap Mode 4: Full 8-bit bitmap - + Mod 4: Tam 8-bit bitmap Mode 5: Small 15-bit bitmap - + Mod 5: Küçük 15-bit bitmap CGB Mode - + Frame select - + Kare seçme Unlocked HBlank - + Linear OBJ tile mapping - + Doğrusal OBJ desen döşeme Force blank screen - + Boş ekrana zorla Enable background 0 - + Arkaplan 0'ı etkinleştir Enable background 1 - + Arkaplan 1'i etkinleştir Enable background 2 - + Arkaplan 2'yi etkinleştir Enable background 3 - + Arkaplan 3'ü etkinleştir Enable OBJ - + OBJ etkinleştir Enable Window 0 - + Pencere 0'ı etkinleştir Enable Window 1 - + Pencere 1'i etkinleştir Enable OBJ Window - + OBJ Penceresini etkinleştir Currently in VBlank - + Şuanda VBlankda Currently in HBlank - + Şuanda HBlankda Currently in VCounter - + Şuanda VCounter'da Enable VBlank IRQ generation - + VBlank IRQ generation etkinleştir Enable HBlank IRQ generation - + HBlank IRQ jenerasyonunu etkinleştir Enable VCounter IRQ generation - + VCounter IRQ generation etkinleştir VCounter scanline - + Current scanline - + Anlık scanline @@ -1556,7 +1557,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Priority - + Öncelik @@ -1564,7 +1565,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Tile data base (* 16kB) - + @@ -1572,7 +1573,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Enable mosaic - + Mozaik'i etkinleştir @@ -1580,7 +1581,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Enable 256-color - + 256-renklerini etkinleştir @@ -1588,7 +1589,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Tile map base (* 2kB) - + @@ -1596,13 +1597,13 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Background dimensions - + Arkaplan boyutları Overflow wraps - + @@ -1610,7 +1611,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Horizontal offset - + Dikey ofset @@ -1618,7 +1619,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Vertical offset - + Dikey ofset @@ -1634,7 +1635,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Fractional part - + @@ -1646,7 +1647,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Integer part - + @@ -1654,7 +1655,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Integer part (bottom) - + @@ -1662,286 +1663,286 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Integer part (top) - + End x - + Start x - + End y - + Start y - + Window 0 enable BG 0 - + Pencere 0, BG 0'ı etkinleştirir Window 0 enable BG 1 - + Pencere 0, BG 1'i etkinleştirir Window 0 enable BG 2 - + Pencere 0, BG 2'yi etkinleştirir Window 0 enable BG 3 - + Pencere 0, BG 3'ü etkinleştirir Window 0 enable OBJ - + Pencere 0, OBJ'yi etkinleştirir Window 0 enable blend - + Pencere 0, karışımı etkinleştir Window 1 enable BG 0 - + Pencere 1, BG 0'ı etkinleştirir Window 1 enable BG 1 - + Pencere 1, BG 1'i etkinleştirir Window 1 enable BG 2 - + Pencere 1, BG 2'yi etkinleştirir Window 1 enable BG 3 - + Pencere 1, BG 3'ü etkinleştirir Window 1 enable OBJ - + Pencere 1 OBJ'yi etkinleştir Window 1 enable blend - + Pencere 1, karışımı etkinleştir Outside window enable BG 0 - + Dış pencere BG0'ı etkinleştirir Outside window enable BG 1 - + Dış pencere BG1'i etkinleştirir Outside window enable BG 2 - + Dış pencere BG2'yi etkinleştirir Outside window enable BG 3 - + Dış pencere BG3'ü etkinleştirir Outside window enable OBJ - + Dış pencere OBJ etkinleştirir Outside window enable blend - + Dış pencere karışı etkinleştirir OBJ window enable BG 0 - + OBJ penceresi BG0'ı etkinleştir OBJ window enable BG 1 - + OBJ penceresi BG1'i etkinleştir OBJ window enable BG 2 - + OBJ penceresi BG2'yi etkinleştir OBJ window enable BG 3 - + OBJ penceresi BG3'ü etkinleştir OBJ window enable OBJ - + OBJ penceresi OBJ'yi etkinleştir OBJ window enable blend - + OBJ penceresi karışımıi etkinleştir Background mosaic size vertical - + Arka plan dikey mozaik boyutu Background mosaic size horizontal - + Arka plan yatay mozaik boyutu Object mosaic size vertical - + Nesne mozaik dikey boyutu Object mosaic size horizontal - + Nesne mozaik yatay boyutu BG 0 target 1 - + BG 1 target 1 - + BG 2 target 1 - + BG 3 target 1 - + OBJ target 1 - + Backdrop target 1 - + Blend mode - + Karışım modu Disabled - + Devredışı Additive blending - + Brighten - + Darken - + BG 0 target 2 - + BG 1 target 2 - + BG 2 target 2 - + BG 3 target 2 - + OBJ target 2 - + Backdrop target 2 - + Blend A (target 1) - + Blend B (target 2) - + Blend Y - + Sweep shifts - + Sweep subtract - + Sweep time (in 1/128s) - + @@ -1949,41 +1950,41 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Sound length - + Ses uzunluğu Duty cycle - + Envelope step time - + Envelope increase - + Initial volume - + İlk ses Sound frequency - + Ses frekansı @@ -1991,7 +1992,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Timed - + @@ -1999,50 +2000,50 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Reset - + Reset Double-size wave table - + Çift boyutlu dalga tablosu Active wave table - + Enable channel 3 - + Volume - + Ses Kuvveti 0% - + 100% - + 50% - + 25% - + @@ -2050,118 +2051,118 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 75% - + Clock divider - + Register stages - + 15 - + 7 - + Shifter frequency - + Değiştirici frekansı PSG volume right - + PSG sağ ses seviyesi PSG volume left - + PSG sol ses seviyesi Enable channel 1 right - + Enable channel 2 right - + Enable channel 3 right - + Enable channel 4 right - + Enable channel 1 left - + Enable channel 2 left - + Enable channel 3 left - + Enable channel 4 left - + PSG master volume - + PSG ana ses seviyesi Loud channel A - + Loud channel B - + Enable channel A right - + Enable channel A left - + Channel A timer - + 0 - + @@ -2174,67 +2175,67 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 1 - + Channel A reset - + Enable channel B right - + Enable channel B left - + Channel B timer - + Channel B reset - + Active channel 1 - + Active channel 2 - + Active channel 3 - + Active channel 4 - + Enable audio - + Ses'i etkinleştir Bias - + Resolution - + Çözünürlük @@ -2278,7 +2279,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Sample - + Örnek @@ -2290,7 +2291,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Address (bottom) - + @@ -2302,7 +2303,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Address (top) - + @@ -2310,7 +2311,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Word count - + Sözcük sayısı @@ -2318,7 +2319,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Destination offset - + Hedef ofset @@ -2330,7 +2331,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Increment - + Artırma @@ -2342,7 +2343,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Decrement - + Azalma @@ -2354,7 +2355,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Fixed - + Sabit @@ -2362,7 +2363,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Increment and reload - + Artırma ve yeniden yükleme @@ -2370,7 +2371,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Source offset - + Kaynak ofseti @@ -2378,7 +2379,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Repeat - + Tekrarla @@ -2386,7 +2387,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 32-bit - + @@ -2394,7 +2395,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Start timing - + Zamanlamayı başlat @@ -2402,7 +2403,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Immediate - + Hemen @@ -2412,7 +2413,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. VBlank - + @@ -2422,7 +2423,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. HBlank - + @@ -2435,7 +2436,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. IRQ - + @@ -2447,24 +2448,24 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Enable - + Etkinleştir Audio FIFO - + Video Capture - + Video Yakalama DRQ - + @@ -2472,7 +2473,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Value - + Değer @@ -2480,7 +2481,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Scale - + Ölçek @@ -2488,7 +2489,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 1/64 - + @@ -2496,7 +2497,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 1/256 - + @@ -2504,176 +2505,176 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 1/1024 - + Cascade - + A - + B - + Select - + Start - + Right - + Left - + Up - + Yukarı Down - + R - + L - + Condition - + SC - + SD - + SI - + SO - + VCounter - + Timer 0 - + Timer 1 - + Timer 2 - + Timer 3 - + SIO - + DMA 0 - + DMA 1 - + DMA 2 - + DMA 3 - + Keypad - + Gamepak - + SRAM wait - + @@ -2682,7 +2683,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 4 - + @@ -2690,7 +2691,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 3 - + @@ -2699,7 +2700,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 2 - + @@ -2708,72 +2709,72 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 8 - + Cart 0 non-sequential - + Cart 0 sequential - + Cart 1 non-sequential - + Cart 1 sequential - + Cart 2 non-sequential - + Cart 2 sequential - + PHI terminal - + Disable - + Devredışı 4.19MHz - + 8.38MHz - + 16.78MHz - + Gamepak prefetch - + Enable IRQs - + IRQleri etkinleştir @@ -2782,7 +2783,7 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. --- - + @@ -2790,27 +2791,27 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Load State - + Konum yükle Save State - + Konumu kaydet Empty - + Boş Corrupted - + Bozulmuş Slot %1 - + @@ -2819,42 +2820,42 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Default - + Varsayılan Fatal - + Kritik Error - + Hata Warning - + Uyarı Info - + Bilgi Debug - + Stub - + Game Error - + Oyun hatası @@ -2862,42 +2863,42 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. [%1] %2: %3 - + DEBUG - + STUB - + INFO - + WARN - + ERROR - + FATAL - + GAME ERROR - + @@ -2905,47 +2906,47 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Map Addr. - + Mirror - + None - + Hiçbiri Both - + Horizontal - + Yatay Vertical - + Dikey Export map - + Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 - + PNG dosyası açılamadı:%1 @@ -2953,62 +2954,62 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Copy selection - + Seçileni kopyala Save selection - + Seçilenleri kaydet Paste - + Yapıştır Load - + Yükle All - + Hepsi Load TBL - + TBL yükle Save selected memory - + Seçilen memory'i kaydet Failed to open output file: %1 - + Çıkış dosyası açılamadı:%1 Load memory - + Memory yükle Failed to open input file: %1 - + Giriş dosyası açılamadı:%1 TBL - + ISO-8859-1 - + @@ -3016,22 +3017,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. (%0/%1×) - + (⅟%0×) - + (%0×) - + %1 byte%2 - + @@ -3040,53 +3041,53 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. 0x%0 - + Off - + Normal - + Trans - + OBJWIN - + Invalid - + Geçersiz N/A - + Export sprite - + Sprite dışarı aktar Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 - + PNG dosyası açılamadı:%1 @@ -3094,39 +3095,39 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. #%0 - + 0x%0 - + %0 - + 0x%0 (%1) - + Export palette - + Paleti dışarı aktar Windows PAL (*.pal);;Adobe Color Table (*.act) - + Failed to open output palette file: %1 - + Çıkış paleti dosyası açılamadı:%1 @@ -3138,18 +3139,18 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. (unknown) - + (bilinmeyen) bytes - + (no database present) - + (veritabanı yok) @@ -3158,58 +3159,58 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Qt Multimedia - + SDL - + Software (Qt) - + Yazılım OpenGL - + OpenGL (force version 1.x) - + None (Still Image) - + Keyboard - + Klavye Controllers - + Shortcuts - + Kısayollar Shaders - + Gölgelendiricler Select BIOS - + BIOS seç @@ -3217,32 +3218,32 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. No shader active - + Hiçbir Gölgelendirici aktif değil Load shader - + Gölgelendirici yükle No shader loaded - + Gölgelendirici yüklenmedi by %1 - + Preprocessing - + İşleniyor Pass %1 - + @@ -3250,17 +3251,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Action - + Keyboard - + Klavye Gamepad - + @@ -3268,17 +3269,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Failed to open output video file: %1 - + Çıkış video dosyası açılamadı:%1 Native (%0x%1) - + Select output file - + Çıkış dosyasını seç @@ -3286,736 +3287,738 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Game Boy Advance ROMs (%1) - + Game Boy Advance ROMları (%1) Game Boy ROMs (%1) - + Game Boy ROMları (%1) All ROMs (%1) - + Bütün ROMlar (%1) %1 Video Logs (*.mvl) - + Archives (%1) - + Arşivler (%1) Select ROM - + ROM seç Select folder - + Klasör seç Game Boy Advance save files (%1) - + Game Boy Advance kayıt dosyaları (%1) Select save - + Kayıt seç mGBA savestate files (%1) - + mGBA kaydedilmiş konu kayıtları (%1) Select savestate - + Konumkaydedici seç Select patch - + Yama seç Patches (*.ips *.ups *.bps) - + Yamalar (*.ips *.ups *.bps) Select image - + Resim seç Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - + Resim dosyası (*.png *.gif *.jpg *.jpeg);;All files (*) GameShark saves (*.sps *.xps) - + GameShark kayıtları (*.sps *.xps) Select video log - + Video günlüğü seç Video logs (*.mvl) - + Video günlükleri (*.mvl) Crash - + Çökme The game has crashed with the following error: %1 - + Oyun aşağıdaki hatalarla çöktü: + +%1 Couldn't Load - + Yüklenemedi Could not load game. Are you sure it's in the correct format? - + Oyun yüklenemedi. Doğru formatta olduğundan emin misin? Unimplemented BIOS call - + Uygulanmamış BIOS girişi This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Oyun BIOS dosyasına ihtiyacı var. Lütfen en iyi deneyim için resmi BIOS'u kullanın. Really make portable? - + Taşınabilir yapılsın mı? This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Emülatörün yapılandırmasını yürütülebilir dosya ile aynı dizinden yüklemesini sağlar. Devam etmek istiyor musun? Restart needed - + Yeniden başlatma gerekli Some changes will not take effect until the emulator is restarted. - + Bazı değişiklikler emülatör yeniden başlatılıncaya kadar etkili olmaz. - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + &ROM yükle... Load ROM in archive... - + ROM'u arşivden yükle ... Add folder to library... - + Kütüphaneye klasör ekle ... Load alternate save... - + Alternatif kaydetme yükle ... Load temporary save... - + Geçici kaydetmeyi yükle ... Load &patch... - + &Patch yükle... Boot BIOS - + BIOS boot et Replace ROM... - + ROM değişti... ROM &info... - + ROM &info... Recent - + Son kullanılanlar Make portable - + Portatif yap &Load state - + &Kaydedilmiş konum yükle F10 - + Load state file... - + Kaydedilmiş konum dosyası yükle... &Save state - + &Konumu kaydet Shift+F10 - + Save state file... - + Konum dosyasını kaydet... Quick load - + Hızlı Yükle Quick save - + Hızlı kaydet Load recent - + En son yükle Save recent - + Hızlı kaydet Undo load state - + Kaydedilen konum yüklemeyi geri al F11 - + Undo save state - + Konum kaydetmeyi geri al Shift+F11 - + State &%1 - + Konum &%1 F%1 - + Shift+F%1 - + Load camera image... - + Kamera resmini yükle ... Import GameShark Save - + GameShark kaydını içe aktarın Export GameShark Save - + GameShark oyun kaydını dışarı aktar New multiplayer window - + Yeni çokoyunculu ekranı About... - + Hakkında... E&xit - + Çıkış &Emulation - + Emülasyon &Reset - + &Reset Ctrl+R - + Sh&utdown - + Kapat Yank game pak - + &Pause - + &Durdur Ctrl+P - + &Next frame - + &Sonraki kare Ctrl+N - + Fast forward (held) - + İleriye sar(basılı tutun) &Fast forward - + &İleriye sar Shift+Tab - + Fast forward speed - + İleriye sarma hızı Unbounded - + %0x - + Rewind (held) - + Geri sar (basılı tutun) Re&wind - + Geri sar ~ - + Step backwards - + Geriye doğru adım Ctrl+B - + Sync to &video - + &Videoya eşitle Sync to &audio - + &Sese eşitle Solar sensor - + Increase solar level - + Solar seviyesini arttır Decrease solar level - + Solar seviyesini düşür Brightest solar level - + En parlak solar seviyesi Darkest solar level - + En karanlık solar seviyesi Brightness %1 - + Parlaklık:%1 Game Boy Printer... - + Game Boy yazıcısı... BattleChip Gate... - + Audio/&Video - + Ses/&Video Frame size - + Çerçeve boyutu %1x - + Toggle fullscreen - + Tamekranı aç/kapa Lock aspect ratio - + En boy oranını kilitle Force integer scaling - + Tamsayılı ölçeklendirmeyi zorla Bilinear filtering - + Bilinear filtreleme Frame&skip - + Kare atlama Mute - + Sessiz FPS target - + FPS hedefi Native (59.7275) - + Take &screenshot - + Ekran görüntüsü al F12 - + Record output... - + Video kaydetme... Record GIF... - + GIF kaydet... Record video log... - + Video günlüğünü kaydet... Stop video log - + Video günlüğünü durdur Video layers - + Audio channels - + Ses kanalları Adjust layer placement... - + Katman yerleşimini ayarlayın... &Tools - + &Araçlar View &logs... - + Kayıtları görüntüle... Game &overrides... - + Oyunların üzerine yazılanlar Game &Pak sensors... - + &Pa sensörleri... &Cheats... - + &Hileler... Settings... - + Ayarlar... Open debugger console... - + Hata ayıklayıcı konsolunu aç ... Start &GDB server... - + &GDB sunucusunu başlat... View &palette... - + &Renk Paletini gör... View &sprites... - + &Spriteları gör... View &tiles... - + &Desenleri gör... View &map... - + &Haritayı gör View memory... - + Hafıza gör... Search memory... - + Hafızada ara... View &I/O registers... - + &I/O kayıtlarını görüntüle Exit fullscreen - + Tam ekrandan çık GameShark Button (held) - + GameShark Butonu (basılı tutun) Autofire - + Otomatik basma Autofire A - + Otomatik basma A Autofire B - + Otomatik basma B Autofire L - + Otomatik basma L Autofire R - + Otomatik basma R Autofire Start - + Otomatik basma Start Autofire Select - + Otomatik basma Select Autofire Up - + Otomatik basma Up Autofire Right - + Otomatik basma Right Autofire Down - + Otomatik basma Down Autofire Left - + Otomatik basma Sol @@ -4023,17 +4026,17 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. GBA - + GB - + ? - + @@ -4041,57 +4044,57 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. ROM Info - + ROM bilgisi Game name: - + Oyun adı: {NAME} - + Internal name: - + Dahili İsim: {TITLE} - + Game ID: - + {ID} - + File size: - + Dosya boyutu: {SIZE} - + CRC32: - + {CRC} - + @@ -4099,74 +4102,74 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Sensors - + Sensörler Realtime clock - + Gerçek zaman saati Fixed time - + Sabit zaman System time - + Sistem zamanı Start time at - + Başlangıç zamanı Now - + Şimdi MM/dd/yy hh:mm:ss AP - + Light sensor - + Brightness - + Parlaklık Tilt sensor - + Eğim sensörü Set Y - + Set X - + Gyroscope - + Jiroskop Sensitivity - + Hassaslık @@ -4174,369 +4177,369 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Settings - + Ayarlar Audio/Video - + Ses/Video Interface - + Arayüz Emulation - + Emülasyon BIOS - + Paths - + Dizinler Logging - + Günlükler Game Boy - + Audio driver: - + Ses sürücüsü: Audio buffer: - + Ses arttırma: 1536 - + 512 - + 768 - + 1024 - + 2048 - + 3072 - + 4096 - + samples - + değerler Sample rate: - + Değer oranı 44100 - + 22050 - + 32000 - + 48000 - + Hz - + Volume: - + Ses Mute - + Sessiz Fast forward volume: - + Hızlı sarma ses seviyesi: Display driver: - + Görüntü sürücüsü: Frameskip: - + Kare atlama: Skip every - + Hepsini atla frames - + Kare FPS target: - + Hedef FPS: frames per second - + Saniye başına kare Sync: - + Eşitle Video - + Video Audio - + Ses Lock aspect ratio - + En boy oranını kilitle Force integer scaling - + Tamsayılı ölçeklendirmeyi zorla Bilinear filtering - + Bilinear filtreleme Language - + Dil English - + İngilizce Library: - + Kütüphane List view - + Liste görünümü Tree view - + Sıralı görünüm Show when no game open - + Oyun açılmadığında göster Clear cache - + Ön belleği temizle Allow opposing input directions - + Karşıt giriş yönlerine izin ver Suspend screensaver - + Ekran koruyucuyu askıya alın Pause when inactive - + Etkin değilken duraklat Show FPS in title bar - + FPS'i başlık çubuğunda göster Automatically save cheats - + Otomatik hile kaydedici Automatically load cheats - + Otomatik hile yükleyici Automatically save state - + Otomatik konum kaydedici Automatically load state - + Otomatik konum yükleyici Enable Discord Rich Presence - + Discord etkinliğini etkinleştir Fast forward speed: - + Hızlı sarma hızı: × - + Unbounded - + Sınırsız Autofire interval: - + Otomatik ateşleme aralığı: Enable rewind - + Geri sarmayı etkinleştir Rewind history: - + Geri alma tarihi: Idle loops: - + Run all - + Hepsini çalıştır Remove known - + Bilinenleri kaldır Detect and remove - + Algıla ve kaldır Preload entire ROM into memory - + Tüm ROM'u belleğe önceden yükle Savestate extra data: - + Konum kaydedici kaydeder: Screenshot - + Ekran görüntüsü Save data - + Verileri kaydet Cheat codes - + Hile kodları Load extra data: - + Ekstra veri yükle: GB BIOS file: - + GB BIOS dosyası: @@ -4549,37 +4552,37 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Browse - + Gözat Use BIOS file if found - + Varsa BIOS dosyasını kullan Skip BIOS intro - + BIOS girişini atla GBA BIOS file: - + GBA BIOS dosyası: GBC BIOS file: - + GBC BIOS dosyası: SGB BIOS file: - + SGB BIOS dosyası: Save games - + Oyunları kaydet @@ -4588,127 +4591,127 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Same directory as the ROM - + ROM ile aynı dizin Save states - + Konum kaydedici Screenshots - + Ekran görüntüleri: Patches - + Yamalar Cheats - + Hileler Log to file - + Dosyaya günlüğünü gir Log to console - + Konsola günlüğünü gir Select Log File - + Günlük Dosyasını Seç Game Boy model: - + Game Boy modeli: Autodetect - + Otomatik tespit Game Boy (DMG) - + Super Game Boy (SGB) - + Game Boy Color (CGB) - + Game Boy Advance (AGB) - + Super Game Boy model: - + Super Game Boy modeli: Game Boy Color model: - + Game Boy Color modeli: Default BG colors: - + Super Game Boy borders - + Super Game Boy sınırları Camera driver: - + Kamera sürücüsü: Default sprite colors 1: - + Varsayılan sprite renkleri 1: Default sprite colors 2: - + Varsayılan sprite renkleri 2: Use GBC colors in GB games - + GB oyunlarında GBC renklerini kullan Camera: - + Kamera @@ -4716,37 +4719,37 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Shaders - + Gölgelendiriciler Active Shader: - + Aktif Gölgelendirici: Name - + İsim Author - + Yaratıcı Description - + Açıklama Unload Shader - + Gölgelendiriciyi kaldır Load New Shader - + Yeni gölgendirici yükle @@ -4754,22 +4757,22 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Edit Shortcuts - + Kısayolları düzenle Keyboard - + Klavye Gamepad - + Clear - + Temizle @@ -4777,32 +4780,32 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Tiles - + 256 colors - + 256 renkleri × - + Magnification - + Büyütme Tiles per row - + Fit to window - + Pencereye sığdır @@ -4810,193 +4813,193 @@ Game Boy Advance is a registered trademark of Nintendo Co., Ltd. Record Video - + Video kaydetme Start - + Başlat Stop - + Durdur Select File - + Dosya seç Presets - + Hazır ayarlar High &Quality - + &YouTube - + WebM - + &Lossless - + &1080p - + &720p - + &480p - + &Native - + Format - + Format MKV - + AVI - + MP4 - + h.264 - + h.264 (NVENC) - + HEVC - + HEVC (NVENC) - + VP8 - + VP9 - + FFV1 - + FLAC - + Opus - + Vorbis - + MP3 - + AAC - + Uncompressed - + Sıkıştırılmamış Bitrate (kbps) - + VBR - + ABR - + Dimensions - + Boyutlar : - + × - + Lock aspect ratio - + En boy oranını kilitle Show advanced - + Gelişmişi göster From 9ec3b15f47bf54defaa3d3e17731cc3cf9d23335 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2019 12:18:06 -0700 Subject: [PATCH 136/429] GB Core: Fix toggling WIN and OBJ being swapped --- CHANGES | 1 + src/gb/core.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 0072e33c2..35422cef7 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Other fixes: - CMake: Fix .deb imagemagick dependencies - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) + - GB Core: Fix toggling WIN and OBJ being swapped Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/core.c b/src/gb/core.c index 1671a1142..99f11029d 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -803,10 +803,10 @@ static void _GBCoreEnableVideoLayer(struct mCore* core, size_t id, bool enable) gb->video.renderer->disableBG = !enable; break; case 1: - gb->video.renderer->disableOBJ = !enable; + gb->video.renderer->disableWIN = !enable; break; case 2: - gb->video.renderer->disableWIN = !enable; + gb->video.renderer->disableOBJ = !enable; break; default: break; From d7c86f5ab3f865394444979a33da7a92cc50608f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2019 12:24:33 -0700 Subject: [PATCH 137/429] Travis: Build for Ubuntu Disco --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index c35d58b3b..b071734b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - DOCKER_TAG=ubuntu:xenial - DOCKER_TAG=ubuntu:bionic - DOCKER_TAG=ubuntu:cosmic +- DOCKER_TAG=ubuntu:disco - DOCKER_TAG=3ds - DOCKER_TAG=wii - DOCKER_TAG=vita From 38cbe08be97e7e697724a8844fe0b45c85f8eb8e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2019 12:57:58 -0700 Subject: [PATCH 138/429] Tools: Fix and update sanitize-deb script --- tools/sanitize-deb.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/sanitize-deb.sh b/tools/sanitize-deb.sh index cf1fee221..d400f0489 100755 --- a/tools/sanitize-deb.sh +++ b/tools/sanitize-deb.sh @@ -17,7 +17,7 @@ adddep() { while [ $# -gt 0 ]; do DEB=$1 dpkg-deb -R $DEB deb-temp - PKG=`head -n1 deb-temp/DEBIAN/control | cut -f2 -d ' '` + PKG=`grep Package deb-temp/DEBIAN/control | cut -f2 -d ' '` echo Found package $PKG case $PKG in @@ -30,9 +30,12 @@ while [ $# -gt 0 ]; do PKG=$BINARY-qt rmdep libav rmdep libedit + rmdep libelf rmdep libpng rmdep libzip rmdep libmagickwand + rmdep libsqlite3 + rmdep libswresample rmdep libswscale rmdep zlib adddep lib$BINARY @@ -41,10 +44,13 @@ while [ $# -gt 0 ]; do PKG=$BINARY-sdl rmdep libav rmdep libedit + rmdep libelf rmdep libpng rmdep qt rmdep libzip rmdep libmagickwand + rmdep libsqlite3 + rmdep libswresample rmdep libswscale rmdep zlib adddep lib$BINARY From 04f85979423433b2f892abbce4c73fe984213f42 Mon Sep 17 00:00:00 2001 From: BenjaminSiskoo Date: Mon, 22 Apr 2019 22:06:12 +0200 Subject: [PATCH 139/429] Updated french language by Benjamin Siskoo... (#1393) Thanks Sewef and RunisDauphin for reporting typos and improvements. --- src/platform/qt/ts/mgba-fr.ts | 666 +++++++++++++++++----------------- 1 file changed, 333 insertions(+), 333 deletions(-) diff --git a/src/platform/qt/ts/mgba-fr.ts b/src/platform/qt/ts/mgba-fr.ts index ff38cea79..e3f541e38 100644 --- a/src/platform/qt/ts/mgba-fr.ts +++ b/src/platform/qt/ts/mgba-fr.ts @@ -11,17 +11,17 @@ <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> - + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> - + Branche : <tt>{gitBranch}</tt><br/>Révision : <tt>{gitCommit}</tt> {projectName} - + {projectName} @@ -38,12 +38,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {projectVersion} - + {projectVersion} {logo} - + {logo} @@ -53,7 +53,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {patrons} - + {patrons} @@ -74,23 +74,23 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. AssetTile - + AssetTile Tile # - + Tile # 0 - + 0 Palette # - + Palette # @@ -100,7 +100,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x06000000 - + 0x06000000 @@ -122,7 +122,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x00 (00) - + 0x00 (00) @@ -196,7 +196,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Select File - Chsoiir un fichier + Choisir un fichier @@ -224,87 +224,87 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x0000 - + 0x0000 2 - + 2 5 - + 5 4 - + 4 7 - + 7 0 - + 0 9 - + 9 1 - + 1 3 - + 3 8 - + 8 C - + C E - + E 6 - + 6 D - + D F - + F A - + A B - + B @@ -332,7 +332,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. CRC32 - + CRC32 @@ -359,47 +359,47 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1 - + 1 2 - + 2 3 - + 3 4 - + 4 5 - + 5 6 - + 6 7 - + 7 8 - + 8 9 - + 9 @@ -422,12 +422,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Stub - + Talon Info - + Info @@ -442,7 +442,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Fatal - + Fatal @@ -470,12 +470,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. × - + × Magnification - + Agrandissement @@ -504,7 +504,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Type - + Type @@ -535,17 +535,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1 Byte (8-bit) - + 1 Byte (8-bit) 2 Bytes (16-bit) - + 2 Bytes (16-bit) 4 Bytes (32-bit) - + 4 Bytes (32-bit) @@ -585,7 +585,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Delta - + Delta @@ -623,7 +623,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x - + 0x @@ -633,17 +633,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1 Byte - + 1 Byte 2 Bytes - + 2 Bytes 4 Bytes - + 4 Bytes @@ -691,18 +691,18 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Sprites - + Sprites × - + × Magnification - + Agrandissement @@ -722,12 +722,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Off - + Off Palette - + Palette @@ -735,7 +735,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0 - + 0 @@ -748,7 +748,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Return, Ctrl+R - + Entrée, Ctrl+R @@ -758,22 +758,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. H - + H V - + V Mode - + Mode Normal - + Normal @@ -793,7 +793,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Tile - + Tile @@ -803,23 +803,23 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Position - + Position , - + , Dimensions - + Dimensions 8 - + 8 @@ -829,7 +829,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x07000000 - + 0x07000000 @@ -842,7 +842,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Game Boy Advance - + Game Boy Advance @@ -860,12 +860,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Gyroscope - + Gyroscope Tilt - + Tilt @@ -891,27 +891,27 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. SRAM - + SRAM Flash 512kb - + Flash 512kb Flash 1Mb - + Flash 1Mb EEPROM - + EEPROM Idle loop - + Boucle de veille @@ -921,7 +921,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Game Boy - + Game Boy @@ -931,22 +931,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Game Boy (DMG) - + Game Boy (DMG) Super Game Boy (SGB) - + Super Game Boy (SGB) Game Boy Color (CGB) - + Game Boy Color (CGB) Game Boy Advance (AGB) - + Game Boy Advance (AGB) @@ -956,27 +956,27 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. MBC1 - + MBC1 MBC2 - + MBC2 MBC3 - + MBC3 MBC3 + RTC - + MBC3 + RTC MBC5 - + MBC5 @@ -986,22 +986,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. MBC7 - + MBC7 Pocket Cam - + Pocket Cam TAMA5 - + TAMA5 HuC-3 - + HuC-3 @@ -1024,7 +1024,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Palette - + Palette @@ -1061,7 +1061,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x00 (00) - + 0x00 (00) @@ -1081,17 +1081,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x0000 - + >0x0000 #000000 - + #000000 000 - + 000 @@ -1109,7 +1109,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Adjust placement - + Ajuster la disposition @@ -1119,17 +1119,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Offset - + Offset X - + X Y - + Y @@ -1147,7 +1147,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Tear off - + Tear off @@ -1155,14 +1155,14 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. %0%1%2 - + %0%1%2 0x%0 (%1) - + 0x%0 (%1) @@ -1170,17 +1170,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Can't set format of context-less audio device - + Ne peut pas choisir le format d'un dispositif audio sans contexte Audio device is missing its core - + Il manque le noyau du périphérique audio Writing data to read-only audio device - + Ecrire les données en lecture seule sur le périphérique audio @@ -1188,7 +1188,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Can't start an audio processor without input - + Ne peut pas démarrer le processeur audio sans entrée @@ -1196,7 +1196,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Can't start an audio processor without input - + Ne peut pas démarrer le processeur audio sans entrée @@ -1301,17 +1301,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Server settings - + Paramètres du serveur Local port - + Port local Bind address - + Lier l'adresse @@ -1336,7 +1336,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Could not start GDB server - + Ne peut pas démarrer le serveur GDB @@ -1354,7 +1354,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Graphics Interchange Format (*.gif) - + Graphics Interchange Format (*.gif) @@ -1551,7 +1551,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Overflow wraps - + Enveloppe de dépassement @@ -1559,7 +1559,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Horizontal offset - + Offset horizontal @@ -1567,7 +1567,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Vertical offset - + Offset vertical @@ -1583,7 +1583,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Fractional part - + Composant fractionné @@ -1595,7 +1595,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Integer part - + Composant entier @@ -1603,7 +1603,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Integer part (bottom) - + Composant entier (en bas) @@ -1611,7 +1611,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Integer part (top) - + Composant entier (en haut) @@ -1875,22 +1875,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Blend Y - + Blend Y Sweep shifts - + Dépalcement de balayage Sweep subtract - + Soustraire le balayage Sweep time (in 1/128s) - + Temps de balayage (in 1/128s) @@ -1911,7 +1911,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Envelope step time - + Temps d'étape d'enveloppe @@ -1968,30 +1968,30 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Volume - + Volume 0% - + 0 100% - + 100% 50% - + 50% 25% - + 25% @@ -1999,7 +1999,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 75% - + 75% @@ -2009,22 +2009,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Register stages - + Etapes du registre 15 - + 15 7 - + 7 Shifter frequency - + Fréquence de déplacement @@ -2110,7 +2110,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0 - + 0 @@ -2123,12 +2123,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1 - + 1 Channel A reset - Redémarrer la canal A + Redémarrer le canal A @@ -2178,7 +2178,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Bias - + Bias @@ -2267,7 +2267,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Destination offset - + Destination de l'offset @@ -2319,7 +2319,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Source offset - + Source de l'offser @@ -2335,7 +2335,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 32-bit - + 32-bit @@ -2361,7 +2361,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. VBlank - + VBlank @@ -2371,7 +2371,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. HBlank - + HBlank @@ -2384,7 +2384,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. IRQ - + IRQ @@ -2403,7 +2403,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Audio FIFO - + Audio FIFO @@ -2413,7 +2413,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. DRQ - + DRQ @@ -2437,7 +2437,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1/64 - + 1/64 @@ -2445,7 +2445,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1/256 - + 1/256 @@ -2453,32 +2453,32 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1/1024 - + 1/1024 Cascade - + Cascade A - + A B - + B Select - + Select @@ -2514,115 +2514,115 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. R - + R L - + L Condition - + Condition SC - + SC SD - + SD SI - + SI SO - + SO VCounter - + VCounter Timer 0 - + Compteur 0 Timer 1 - + >Compteur 1 Timer 2 - + >Compteur 2 Timer 3 - + >Compteur 3 SIO - + SIO DMA 0 - + DMA 0 DMA 1 - + DMA 1 DMA 2 - + DMA 2 DMA 3 - + DMA 3 Keypad - + Clavier à touche Gamepak - + Gamepak SRAM wait - + Attente de la SRAM @@ -2631,7 +2631,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 4 - + 4 @@ -2639,7 +2639,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 3 - + 3 @@ -2648,7 +2648,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 2 - + 2 @@ -2657,7 +2657,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 8 - + 8 @@ -2692,7 +2692,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. PHI terminal - + Terminal PHI @@ -2702,22 +2702,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 4.19MHz - + 4.19MHz 8.38MHz - + 8.38MHz 16.78MHz - + 16.78MHz Gamepak prefetch - + Pré recherche du Gamepak @@ -2731,7 +2731,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. --- - + --- @@ -2767,17 +2767,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. DEBUG - + DEBUG STUB - + TALON INFO - + INFO @@ -2792,7 +2792,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. FATAL - + FATAL @@ -2825,12 +2825,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Horizontal - + Horizontal Vertical - + Vertical @@ -2840,7 +2840,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -2904,12 +2904,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. TBL - + TBL ISO-8859-1 - + ISO-8859-1 @@ -2917,22 +2917,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. (%0/%1×) - + (%0/%1×) (⅟%0×) - + (⅟%0×) (%0×) - + (%0×) %1 byte%2 - + %1 byte%2 @@ -2941,27 +2941,27 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 0x%0 - + 0x%0 Off - + Off Normal - + Normal Trans - + Trans OBJWIN - + OBJWIN @@ -2972,7 +2972,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. N/A - + N/A @@ -2982,7 +2982,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -2995,24 +2995,24 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. #%0 - + #%0 0x%0 - + 0x%0 %0 - + %0 0x%0 (%1) - + 0x%0 (%1) @@ -3022,7 +3022,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Windows PAL (*.pal);;Adobe Color Table (*.act) - + Windows PAL (*.pal);;Adobe Color Table (*.act) @@ -3040,7 +3040,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -3058,7 +3058,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. bytes - + bytes @@ -3072,27 +3072,27 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Qt Multimedia - + Qt Multimédia SDL - + SDL Software (Qt) - + Software (Qt) OpenGL - + OpenGL OpenGL (force version 1.x) - + OpenGL (forcer la version 1.x) @@ -3118,7 +3118,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Shaders - + Shaders @@ -3164,7 +3164,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Action - + Action @@ -3187,7 +3187,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Native (%0x%1) - + Natif (%0x%1) @@ -3220,7 +3220,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Archives (%1) - + Archives (%1) @@ -3254,7 +3254,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Patches (*.ips *.ups *.bps) - + Patches (*.ips *.ups *.bps) @@ -3344,17 +3344,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. %1 - %2 - + %1 - %2 %1 - %2 - %3 - + %1 - %2 - %3 %1 - %2 (%3 fps) - %4 - + %1 - %2 (%3 fps) - %4 @@ -3379,7 +3379,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Load alternate save... - + Charger une sauvegarde alternative... @@ -3424,7 +3424,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. F10 - + F10 @@ -3434,7 +3434,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Shift+F10 - + Shift+F10 @@ -3459,22 +3459,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Undo load state - Undo le chargement d'état + Défaire le chargement d'état F11 - + F11 Undo save state - Undo la sauvegarde d'état + Défaire la sauvegarde d'état Shift+F11 - + Shift+F11 @@ -3485,12 +3485,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. F%1 - + F%1 Shift+F%1 - + Shift+F%1 @@ -3525,7 +3525,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. &Emulation - + &Emulation @@ -3535,7 +3535,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Ctrl+R - + Ctrl+R @@ -3545,17 +3545,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Yank game pak - + Extraire game pak &Pause - + &Pause Ctrl+P - + Ctrl+P @@ -3565,7 +3565,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Ctrl+N - + Ctrl+N @@ -3580,7 +3580,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Shift+Tab - + Shift+Tab @@ -3595,7 +3595,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. %0x - + %0x @@ -3610,22 +3610,22 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. ~ - + ~ Step backwards - + Retour en Arrière Ctrl+B - + Ctrl+B Sync to &video - Synchro &vidéo + Synchro &vidéo @@ -3675,7 +3675,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. %1x - + %1x @@ -3715,42 +3715,42 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 15 - + 15 30 - + 30 45 - + 45 Native (59.7) - + Natif (59.7) 60 - + 60 90 - + 90 120 - + 120 240 - + 240 @@ -3760,7 +3760,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. F12 - + F12 @@ -3770,12 +3770,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Record GIF... - Enregistrer le GIF... + Enregistrer un GIF... Record video log... - Enregistrer l'enregsitrement vidéo... + Enregistrer l'enregistrement vidéo... @@ -3800,7 +3800,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Adjust layer placement... - + Ajuster la disposition de la Couche @@ -3905,7 +3905,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Autofire L - Autofire LL + Tir Auto L @@ -3948,17 +3948,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. GBA - + GBA GB - + GB ? - + ? @@ -3976,7 +3976,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {NAME} - + {NAME} @@ -3986,7 +3986,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {TITLE} - + {TITLE} @@ -3996,7 +3996,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {ID} - + {ID} @@ -4006,7 +4006,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {SIZE} - + {SIZE} @@ -4016,7 +4016,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. {CRC} - + {CRC} @@ -4054,7 +4054,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. MM/dd/yy hh:mm:ss AP - + MM/dd/yy hh:mm:ss AP @@ -4086,7 +4086,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Gyroscope - + Gyroscope @@ -4109,17 +4109,17 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Interface - + Interface Emulation - + Emulation BIOS - + BIOS @@ -4129,7 +4129,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Game Boy - + Game Boy @@ -4145,37 +4145,37 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 1536 - + 1536 512 - + 512 768 - + 768 1024 - + 1024 2048 - + 2048 3072 - + 3072 4096 - + 4096 @@ -4191,27 +4191,27 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. 44100 - + 44100 22050 - + 22050 32000 - + 32000 48000 - + 48000 Hz - + Hz @@ -4252,7 +4252,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. frames per second - imaes par secondes + images par secondes @@ -4267,7 +4267,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Audio - + Audio @@ -4312,7 +4312,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Show when no game open - Afficher quand aucun jeu est ouvert + Afficher quand aucun jeu n'est ouvert @@ -4367,7 +4367,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. × - + × @@ -4407,7 +4407,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Savestate extra data: - Donnée supplèm. Sauve. Etat : + Donnée supplém. Sauve. Etat : @@ -4430,7 +4430,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Load extra data: - Charger les données supplèm. : + Charger les données supplém. : @@ -4507,7 +4507,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Save states - Sauve. Etat + Sauvegarder les Etats @@ -4517,7 +4517,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Patches - + Patches @@ -4541,38 +4541,38 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Game Boy (DMG) - + Game Boy (DMG) Super Game Boy (SGB) - + Super Game Boy (SGB) Game Boy Color (CGB) - + Game Boy Color (CGB) Game Boy Advance (AGB) - + Game Boy Advance (AGB) Super Game Boy model - + Modèle de la Super Game Boy Game Boy Color model - + Modèle de la Game Boy Color @@ -4605,12 +4605,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Shaders - + Shaders Active Shader: - Sahder actif : + Shader actif : @@ -4625,7 +4625,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Description - + Description @@ -4666,7 +4666,7 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Tiles - + Tiles @@ -4676,12 +4676,12 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. × - + × Magnification - + Agrandissement @@ -4719,33 +4719,33 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. YouTube - + YouTube WebM - + WebM Lossless - + Sans perte 1080p - + 1080p 720p - + 720p 480p - + 480p @@ -4755,72 +4755,72 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Format - + Format MKV - + MKV AVI - + AVI MP4 - + MP4 h.264 - + h.264 h.264 (NVENC) - + h.264 (NVENC) HEVC - + HEVC VP8 - + VP8 FFV1 - + FFV1 FLAC - + FLAC Opus - + Opus Vorbis - + Vorbis MP3 - + MP3 AAC - + AAC @@ -4830,32 +4830,32 @@ Game Boy Advance est une marque de fabrique enregistré par Nintendo Co., Ltd. Bitrate (kbps) - + Bitrate (kbps) VBR - + VBR ABR - + ABR Dimensions - + Dimensions : - + : × - + × From a32cb5cc5e4fa0f1590725036ca58a490d0f1164 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2019 13:59:39 -0700 Subject: [PATCH 140/429] All: Fix several memory leaks --- CHANGES | 1 + src/core/cheats.c | 1 + src/debugger/test/parser.c | 28 ++++----- src/feature/gui/gui-runner.c | 2 + src/gb/test/core.c | 4 ++ src/gb/test/mbc.c | 1 + src/gb/test/memory.c | 1 + src/gb/test/rtc.c | 1 + src/gba/test/cheats.c | 90 ++++++++++++++--------------- src/platform/libretro/libretro.c | 1 + src/platform/openemu/mGBAGameCore.m | 1 + src/platform/sdl/main.c | 1 + src/platform/test/fuzz-main.c | 1 + 13 files changed, 74 insertions(+), 59 deletions(-) diff --git a/CHANGES b/CHANGES index 35422cef7..d20924cce 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Other fixes: - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) - GB Core: Fix toggling WIN and OBJ being swapped + - All: Fix several memory leaks Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/core/cheats.c b/src/core/cheats.c index d0ed72508..0abcbd537 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -90,6 +90,7 @@ void mCheatSetDeinit(struct mCheatSet* set) { if (set->name) { free(set->name); } + StringListDeinit(&set->lines); set->deinit(set); free(set); } diff --git a/src/debugger/test/parser.c b/src/debugger/test/parser.c index a2635f4fb..c1c2840d2 100644 --- a/src/debugger/test/parser.c +++ b/src/debugger/test/parser.c @@ -21,16 +21,16 @@ struct LPTest { struct ParseTree* tree = &lp->tree; \ parseLexedExpression(tree, &lp->lv) -M_TEST_SUITE_SETUP(Parser) { +static int parseSetup(void** state) { struct LPTest* lp = malloc(sizeof(struct LPTest)); LexVectorInit(&lp->lv, 0); *state = lp; return 0; } -M_TEST_SUITE_TEARDOWN(Parser) { +static int parseTeardown(void** state) { struct LPTest* lp = *state; - parseFree(&lp->tree); \ + parseFree(&lp->tree); lexFree(&lp->lv); LexVectorDeinit(&lp->lv); free(lp); @@ -135,14 +135,14 @@ M_TEST_DEFINE(parseUnaryChainedOperator) { assert_int_equal(tree->rhs->rhs->token.uintValue, 2); } -M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Parser, - cmocka_unit_test(parseEmpty), - cmocka_unit_test(parseInt), - cmocka_unit_test(parseLexError), - cmocka_unit_test(parseError), - cmocka_unit_test(parseSimpleExpression), - cmocka_unit_test(parseAddMultplyExpression), - cmocka_unit_test(parseParentheticalExpression), - cmocka_unit_test(parseParentheticalAddMultplyExpression), - cmocka_unit_test(parseIsolatedOperator), - cmocka_unit_test(parseUnaryChainedOperator)) +M_TEST_SUITE_DEFINE(Parser, + cmocka_unit_test_setup_teardown(parseEmpty, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseInt, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseLexError, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseError, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseSimpleExpression, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseAddMultplyExpression, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseParentheticalExpression, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseParentheticalAddMultplyExpression, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseIsolatedOperator, parseSetup, parseTeardown), + cmocka_unit_test_setup_teardown(parseUnaryChainedOperator, parseSetup, parseTeardown)) diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 50c9dea42..128160cad 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -362,6 +362,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { found = mCoreLoadFile(runner->core, path); if (!found) { mLOG(GUI_RUNNER, WARN, "Failed to load %s!", path); + mCoreConfigDeinit(&runner->core->config); runner->core->deinit(runner->core); } } @@ -606,6 +607,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { } mInputMapDeinit(&runner->core->inputMap); mLOG(GUI_RUNNER, DEBUG, "Deinitializing core..."); + mCoreConfigDeinit(&runner->core->config); runner->core->deinit(runner->core); runner->core = NULL; diff --git a/src/gb/test/core.c b/src/gb/test/core.c index a8638012b..1d0b3416a 100644 --- a/src/gb/test/core.c +++ b/src/gb/test/core.c @@ -31,6 +31,7 @@ M_TEST_DEFINE(reset) { assert_true(core->init(core)); mCoreInitConfig(core, NULL); core->reset(core); + mCoreConfigDeinit(&core->config); core->deinit(core); } @@ -41,6 +42,7 @@ M_TEST_DEFINE(loadNullROM) { mCoreInitConfig(core, NULL); assert_false(core->loadROM(core, NULL)); core->reset(core); + mCoreConfigDeinit(&core->config); core->deinit(core); } @@ -51,7 +53,9 @@ M_TEST_DEFINE(isROM) { struct mCore* core = mCoreFindVF(vf); assert_non_null(core); assert_int_equal(core->platform(core), PLATFORM_GB); + vf->close(vf); assert_true(core->init(core)); + core->deinit(core); } diff --git a/src/gb/test/mbc.c b/src/gb/test/mbc.c index 5498d004d..7bcfcd248 100644 --- a/src/gb/test/mbc.c +++ b/src/gb/test/mbc.c @@ -27,6 +27,7 @@ M_TEST_SUITE_TEARDOWN(GBMBC) { return 0; } struct mCore* core = *state; + mCoreConfigDeinit(&core->config); core->deinit(core); return 0; } diff --git a/src/gb/test/memory.c b/src/gb/test/memory.c index 01a4b398f..ab64598ff 100644 --- a/src/gb/test/memory.c +++ b/src/gb/test/memory.c @@ -27,6 +27,7 @@ M_TEST_SUITE_TEARDOWN(GBMemory) { return 0; } struct mCore* core = *state; + mCoreConfigDeinit(&core->config); core->deinit(core); return 0; } diff --git a/src/gb/test/rtc.c b/src/gb/test/rtc.c index 71d06ced2..6ac03feb5 100644 --- a/src/gb/test/rtc.c +++ b/src/gb/test/rtc.c @@ -69,6 +69,7 @@ M_TEST_SUITE_TEARDOWN(GBRTC) { return 0; } struct GBRTCTest* test = *state; + mCoreConfigDeinit(&test->core->config); test->core->deinit(test->core); free(test); return 0; diff --git a/src/gba/test/cheats.c b/src/gba/test/cheats.c index a18e77c5e..6f4b8cb4c 100644 --- a/src/gba/test/cheats.c +++ b/src/gba/test/cheats.c @@ -13,7 +13,7 @@ #include "gba/cheats/parv3.h" #include "gba/cheats/gameshark.h" -M_TEST_SUITE_SETUP(GBACheats) { +static int cheatsSetup(void** state) { struct mCore* core = GBACoreCreate(); core->init(core); core->cheatDevice(core); @@ -21,7 +21,7 @@ M_TEST_SUITE_SETUP(GBACheats) { return 0; } -M_TEST_SUITE_TEARDOWN(GBACheats) { +static int cheatsTeardown(void** state) { if (!*state) { return 0; } @@ -36,7 +36,7 @@ M_TEST_DEFINE(createSet) { assert_non_null(device); struct mCheatSet* set = device->createSet(device, NULL); assert_non_null(set); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(addRawPARv3) { @@ -48,7 +48,7 @@ M_TEST_DEFINE(addRawPARv3) { GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); assert_true(set->addLine(set, "80000000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); assert_false(set->addLine(set, "43000000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3Assign) { @@ -72,7 +72,7 @@ M_TEST_DEFINE(doPARv3Assign) { assert_int_equal(core->rawRead16(core, 0x03000002, -1), 0x5678); assert_int_equal(core->rawRead32(core, 0x03000004, -1), 0x12345678); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3Slide1) { @@ -101,7 +101,7 @@ M_TEST_DEFINE(doPARv3Slide1) { assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3Slide2) { @@ -130,7 +130,7 @@ M_TEST_DEFINE(doPARv3Slide2) { assert_int_equal(core->rawRead16(core, 0x03000008, -1), 0); assert_int_equal(core->rawRead16(core, 0x0300000A, -1), 0); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3Slide4) { @@ -159,7 +159,7 @@ M_TEST_DEFINE(doPARv3Slide4) { assert_int_equal(core->rawRead16(core, 0x03000010, -1), 0); assert_int_equal(core->rawRead16(core, 0x03000014, -1), 0); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3If1) { @@ -188,7 +188,7 @@ M_TEST_DEFINE(doPARv3If1) { assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3If1x1) { @@ -243,7 +243,7 @@ M_TEST_DEFINE(doPARv3If1x1) { assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3If2) { @@ -277,7 +277,7 @@ M_TEST_DEFINE(doPARv3If2) { assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3If2x2) { @@ -345,7 +345,7 @@ M_TEST_DEFINE(doPARv3If2x2) { assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3If2Contain1) { @@ -392,7 +392,7 @@ M_TEST_DEFINE(doPARv3If2Contain1) { assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfX) { @@ -421,7 +421,7 @@ M_TEST_DEFINE(doPARv3IfX) { mCheatRefresh(device, set); assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXxX) { @@ -484,7 +484,7 @@ M_TEST_DEFINE(doPARv3IfXxX) { assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXElse) { @@ -519,7 +519,7 @@ M_TEST_DEFINE(doPARv3IfXElse) { assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXElsexX) { @@ -590,7 +590,7 @@ M_TEST_DEFINE(doPARv3IfXElsexX) { assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXElsexXElse) { @@ -668,7 +668,7 @@ M_TEST_DEFINE(doPARv3IfXElsexXElse) { assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXContain1) { @@ -730,7 +730,7 @@ M_TEST_DEFINE(doPARv3IfXContain1) { assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXContain1Else) { @@ -800,7 +800,7 @@ M_TEST_DEFINE(doPARv3IfXContain1Else) { assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXElseContain1) { @@ -870,7 +870,7 @@ M_TEST_DEFINE(doPARv3IfXElseContain1) { assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfXContain1ElseContain1) { @@ -1016,7 +1016,7 @@ M_TEST_DEFINE(doPARv3IfXContain1ElseContain1) { assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x82); - set->deinit(set); + mCheatSetDeinit(set); } M_TEST_DEFINE(doPARv3IfButton) { @@ -1046,28 +1046,28 @@ M_TEST_DEFINE(doPARv3IfButton) { core->rawWrite8(core, 0x03000000, -1, 0); mCheatRefresh(device, set); assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); - set->deinit(set); + mCheatSetDeinit(set); } -M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(GBACheats, - cmocka_unit_test(createSet), - cmocka_unit_test(addRawPARv3), - cmocka_unit_test(doPARv3Assign), - cmocka_unit_test(doPARv3Slide1), - cmocka_unit_test(doPARv3Slide2), - cmocka_unit_test(doPARv3Slide4), - cmocka_unit_test(doPARv3If1), - cmocka_unit_test(doPARv3If1x1), - cmocka_unit_test(doPARv3If2), - cmocka_unit_test(doPARv3If2x2), - cmocka_unit_test(doPARv3If2Contain1), - cmocka_unit_test(doPARv3IfX), - cmocka_unit_test(doPARv3IfXxX), - cmocka_unit_test(doPARv3IfXElse), - cmocka_unit_test(doPARv3IfXElsexX), - cmocka_unit_test(doPARv3IfXElsexXElse), - cmocka_unit_test(doPARv3IfXContain1), - cmocka_unit_test(doPARv3IfXContain1Else), - cmocka_unit_test(doPARv3IfXElseContain1), - cmocka_unit_test(doPARv3IfXContain1ElseContain1), - cmocka_unit_test(doPARv3IfButton)) +M_TEST_SUITE_DEFINE(GBACheats, + cmocka_unit_test_setup_teardown(createSet, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(addRawPARv3, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3Assign, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3Slide1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3Slide2, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3Slide4, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3If1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3If1x1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3If2, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3If2x2, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3If2Contain1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfX, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXxX, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXElse, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXElsexX, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXElsexXElse, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXContain1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXContain1Else, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXElseContain1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfXContain1ElseContain1, cheatsSetup, cheatsTeardown), + cmocka_unit_test_setup_teardown(doPARv3IfButton, cheatsSetup, cheatsTeardown)) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 6caa5d866..29dbc9033 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -562,6 +562,7 @@ void retro_unload_game(void) { if (!core) { return; } + mCoreConfigDeinit(&core->config); core->deinit(core); mappedMemoryFree(data, dataSize); data = 0; diff --git a/src/platform/openemu/mGBAGameCore.m b/src/platform/openemu/mGBAGameCore.m index 9b2b93b05..2612ddef4 100644 --- a/src/platform/openemu/mGBAGameCore.m +++ b/src/platform/openemu/mGBAGameCore.m @@ -76,6 +76,7 @@ - (void)dealloc { + mCoreConfigDeinit(&core->config); core->deinit(core); [cheatSets release]; free(outputBuffer); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 0da0698b9..450e1868a 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -143,6 +143,7 @@ int main(int argc, char** argv) { if (!mSDLInit(&renderer)) { freeArguments(&args); + mCoreConfigDeinit(&renderer.core->config); renderer.core->deinit(renderer.core); return 1; } diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index 044450099..b167a1443 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -165,6 +165,7 @@ loadError: if (outputBuffer) { free(outputBuffer); } + mCoreConfigDeinit(&core->config); core->deinit(core); return !cleanExit; From 6af4ddefdd3b242e38ac50d780b1e5a5d99e9539 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 26 Apr 2019 14:53:47 -0700 Subject: [PATCH 141/429] Qt: Cap window size to monitor size --- CHANGES | 1 + src/platform/qt/Window.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d20924cce..4ea93c5c0 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ Misc: - Qt: Support switching webcams - Core: Add keysRead callback - Vita: Improved frame drawing speed + - Qt: Cap window size on start to monitor size 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index e669924bd..acf56669e 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -5,14 +5,15 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Window.h" -#include #include #include #include #include #include #include +#include #include +#include #ifdef USE_SQLITE3 #include "ArchiveInspector.h" @@ -200,6 +201,15 @@ void Window::argumentsPassed(mArguments* args) { void Window::resizeFrame(const QSize& size) { QSize newSize(size); + if (windowHandle()) { + QRect geom = windowHandle()->screen()->availableGeometry(); + if (newSize.width() > geom.width()) { + newSize.setWidth(geom.width()); + } + if (newSize.height() > geom.height()) { + newSize.setHeight(geom.height()); + } + } m_screenWidget->setSizeHint(newSize); newSize -= m_screenWidget->size(); newSize += this->size(); @@ -595,7 +605,7 @@ void Window::showEvent(QShowEvent* event) { m_wasOpened = true; resizeFrame(m_screenWidget->sizeHint()); QVariant windowPos = m_config->getQtOption("windowPos"); - QRect geom = QApplication::desktop()->availableGeometry(this); + QRect geom = windowHandle()->screen()->availableGeometry(); if (!windowPos.isNull() && geom.contains(windowPos.toPoint())) { move(windowPos.toPoint()); } else { From 223be49e7845327997a5258338cf6eb6190b475f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2019 11:52:04 -0700 Subject: [PATCH 142/429] GBA BIOS: Add timings for HLE BIOS math functions (fixes #1396) --- CHANGES | 1 + src/gba/bios.c | 110 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 4ea93c5c0..6957c5484 100644 --- a/CHANGES +++ b/CHANGES @@ -42,6 +42,7 @@ Misc: - Core: Add keysRead callback - Vita: Improved frame drawing speed - Qt: Cap window size on start to monitor size + - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/gba/bios.c b/src/gba/bios.c index 186c1d1b6..a264354eb 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -10,6 +10,7 @@ #include #include #include +#include const uint32_t GBA_BIOS_CHECKSUM = 0xBAAE187F; const uint32_t GBA_DS_BIOS_CHECKSUM = 0xBAAE1880; @@ -22,6 +23,18 @@ static void _unRl(struct GBA* gba, int width); static void _unFilter(struct GBA* gba, int inwidth, int outwidth); static void _unBitPack(struct GBA* gba); +static int _mulWait(int32_t r) { + if ((r & 0xFFFFFF00) == 0xFFFFFF00 || !(r & 0xFFFFFF00)) { + return 1; + } else if ((r & 0xFFFF0000) == 0xFFFF0000 || !(r & 0xFFFF0000)) { + return 2; + } else if ((r & 0xFF000000) == 0xFF000000 || !(r & 0xFF000000)) { + return 3; + } else { + return 4; + } +} + static void _SoftReset(struct GBA* gba) { struct ARMCore* cpu = gba->cpu; ARMSetPrivilegeMode(cpu, MODE_IRQ); @@ -273,16 +286,30 @@ static void _Div(struct GBA* gba, int32_t num, int32_t denom) { cpu->gprs[1] = 0; cpu->gprs[3] = INT32_MIN; } + int loops = clz32(denom) - clz32(num); + if (loops < 1) { + loops = 1; + } + cpu->cycles += 4 /* prologue */ + 13 * loops + 7 /* epilogue */; } -static int16_t _ArcTan(int32_t i, int32_t* r1, int32_t* r3) { +static int16_t _ArcTan(int32_t i, int32_t* r1, int32_t* r3, int32_t* cycles) { + int currentCycles = 37; + currentCycles += _mulWait(i * i); int32_t a = -((i * i) >> 14); + currentCycles += _mulWait(0xA9 * a); int32_t b = ((0xA9 * a) >> 14) + 0x390; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0x91C; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0xFB6; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0x16AA; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0x2081; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0x3651; + currentCycles += _mulWait(b * a); b = ((b * a) >> 14) + 0xA2F9; if (r1) { *r1 = a; @@ -290,10 +317,11 @@ static int16_t _ArcTan(int32_t i, int32_t* r1, int32_t* r3) { if (r3) { *r3 = b; } + *cycles += currentCycles; return (i * b) >> 16; } -static int16_t _ArcTan2(int32_t x, int32_t y, int32_t* r1) { +static int16_t _ArcTan2(int32_t x, int32_t y, int32_t* r1, int32_t* cycles) { if (!y) { if (x >= 0) { return 0; @@ -309,24 +337,77 @@ static int16_t _ArcTan2(int32_t x, int32_t y, int32_t* r1) { if (y >= 0) { if (x >= 0) { if (x >= y) { - return _ArcTan((y << 14) / x, r1, NULL); + return _ArcTan((y << 14) / x, r1, NULL, cycles); } } else if (-x >= y) { - return _ArcTan((y << 14) / x, r1, NULL) + 0x8000; + return _ArcTan((y << 14) / x, r1, NULL, cycles) + 0x8000; } - return 0x4000 - _ArcTan((x << 14) / y, r1, NULL); + return 0x4000 - _ArcTan((x << 14) / y, r1, NULL, cycles); } else { if (x <= 0) { if (-x > -y) { - return _ArcTan((y << 14) / x, r1, NULL) + 0x8000; + return _ArcTan((y << 14) / x, r1, NULL, cycles) + 0x8000; } } else if (x >= -y) { - return _ArcTan((y << 14) / x, r1, NULL) + 0x10000; + return _ArcTan((y << 14) / x, r1, NULL, cycles) + 0x10000; } - return 0xC000 - _ArcTan((x << 14) / y, r1, NULL); + return 0xC000 - _ArcTan((x << 14) / y, r1, NULL, cycles); } } +static int32_t _Sqrt(uint32_t x, int32_t* cycles) { + if (!x) { + *cycles += 53; + return 0; + } + int32_t currentCycles = 15; + uint32_t lower; + uint32_t upper = x; + uint32_t bound = 1; + while (bound < upper) { + upper >>= 1; + bound <<= 1; + currentCycles += 6; + } + while (true) { + currentCycles += 6; + upper = x; + uint32_t accum = 0; + lower = bound; + while (true) { + currentCycles += 5; + uint32_t oldLower = lower; + if (lower <= upper >> 1) { + lower <<= 1; + } + if (oldLower >= upper >> 1) { + break; + } + } + while (true) { + currentCycles += 8; + accum <<= 1; + if (upper >= lower) { + ++accum; + upper -= lower; + } + if (lower == bound) { + break; + } + lower >>= 1; + } + uint32_t oldBound = bound; + bound += accum; + bound >>= 1; + if (bound >= oldBound) { + bound = oldBound; + break; + } + } + *cycles += currentCycles; + return bound; +} + void GBASwi16(struct ARMCore* cpu, int immediate) { struct GBA* gba = (struct GBA*) cpu->master; mLOG(GBA_BIOS, DEBUG, "SWI: %02X r0: %08X r1: %08X r2: %08X r3: %08X", @@ -369,13 +450,13 @@ void GBASwi16(struct ARMCore* cpu, int immediate) { _Div(gba, cpu->gprs[1], cpu->gprs[0]); break; case 0x8: - cpu->gprs[0] = sqrt((uint32_t) cpu->gprs[0]); + cpu->gprs[0] = _Sqrt(cpu->gprs[0], &cpu->cycles); break; case 0x9: - cpu->gprs[0] = _ArcTan(cpu->gprs[0], &cpu->gprs[1], &cpu->gprs[3]); + cpu->gprs[0] = _ArcTan(cpu->gprs[0], &cpu->gprs[1], &cpu->gprs[3], &cpu->cycles); break; case 0xA: - cpu->gprs[0] = (uint16_t) _ArcTan2(cpu->gprs[0], cpu->gprs[1], &cpu->gprs[1]); + cpu->gprs[0] = (uint16_t) _ArcTan2(cpu->gprs[0], cpu->gprs[1], &cpu->gprs[1], &cpu->cycles); cpu->gprs[3] = 0x170; break; case 0xB: @@ -497,6 +578,13 @@ void GBASwi16(struct ARMCore* cpu, int immediate) { default: mLOG(GBA_BIOS, STUB, "Stub software interrupt: %02X", immediate); } + gba->cpu->cycles += 45 + cpu->memory.activeNonseqCycles16 /* 8 bit load for SWI # */; + // Return cycles + if (gba->cpu->executionMode == MODE_ARM) { + gba->cpu->cycles += cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32; + } else { + gba->cpu->cycles += cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16; + } gba->memory.biosPrefetch = 0xE3A02004; } From a898c1b7558023580efb0919c7cdd70c6eea7737 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 28 Apr 2019 13:13:04 -0700 Subject: [PATCH 143/429] Debugger: Make tracing compatible with breakpoints/watchpoints --- CHANGES | 1 + include/mgba/internal/debugger/cli-debugger.h | 2 + src/debugger/cli-debugger.c | 50 +++++++++++++------ src/gb/debugger/cli.c | 2 +- src/gba/debugger/cli.c | 2 +- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 6957c5484..2ef909c91 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,7 @@ Misc: - Vita: Improved frame drawing speed - Qt: Cap window size on start to monitor size - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) + - Debugger: Make tracing compatible with breakpoints/watchpoints 0.7.1: (2019-02-24) Bugfixes: diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 7a03d1df0..60ec00fa4 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -74,6 +74,8 @@ struct CLIDebugger { struct CLIDebuggerSystem* system; struct CLIDebuggerBackend* backend; + + int traceRemaining; }; void CLIDebuggerCreate(struct CLIDebugger*); diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 1cdfc20e8..d2a93aa30 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -29,6 +29,7 @@ const char* ERROR_OVERFLOW = "Arguments overflow"; const char* ERROR_INVALID_ARGS = "Invalid arguments"; static struct ParseTree* _parseTree(const char** string); +static bool _doTrace(struct CLIDebugger* debugger); #if !defined(NDEBUG) && !defined(_WIN32) static void _breakInto(struct CLIDebugger*, struct CLIDebugVector*); @@ -147,7 +148,7 @@ static void _breakInto(struct CLIDebugger* debugger, struct CLIDebugVector* dv) static void _continue(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { UNUSED(dv); - debugger->d.state = DEBUGGER_RUNNING; + debugger->d.state = debugger->traceRemaining != 0 ? DEBUGGER_CUSTOM : DEBUGGER_RUNNING; } static void _next(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { @@ -645,19 +646,31 @@ static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { return; } + debugger->traceRemaining = dv->intValue; + if (debugger->traceRemaining == 0) { + return; + } + if (_doTrace(debugger)) { + debugger->d.state = DEBUGGER_CUSTOM; + } else { + debugger->system->printStatus(debugger->system); + } +} + +static bool _doTrace(struct CLIDebugger* debugger) { char trace[1024]; trace[sizeof(trace) - 1] = '\0'; - - int i; - for (i = 0; i < dv->intValue; ++i) { - debugger->d.core->step(debugger->d.core); - size_t traceSize = sizeof(trace) - 1; - debugger->d.platform->trace(debugger->d.platform, trace, &traceSize); - if (traceSize + 1 < sizeof(trace)) { - trace[traceSize + 1] = '\0'; - } - debugger->backend->printf(debugger->backend, "%s\n", trace); + debugger->d.core->step(debugger->d.core); + size_t traceSize = sizeof(trace) - 1; + debugger->d.platform->trace(debugger->d.platform, trace, &traceSize); + if (traceSize + 1 < sizeof(trace)) { + trace[traceSize + 1] = '\0'; } + debugger->backend->printf(debugger->backend, "%s\n", trace); + if (debugger->traceRemaining > 0) { + --debugger->traceRemaining; + } + return debugger->traceRemaining != 0; } static void _printStatus(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { @@ -889,6 +902,9 @@ static void _commandLine(struct mDebugger* debugger) { static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; + if (cliDebugger->traceRemaining > 0) { + cliDebugger->traceRemaining = 0; + } switch (reason) { case DEBUGGER_ENTER_MANUAL: case DEBUGGER_ENTER_ATTACHED: @@ -923,6 +939,7 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r static void _cliDebuggerInit(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; + cliDebugger->traceRemaining = 0; cliDebugger->backend->init(cliDebugger->backend); } @@ -943,12 +960,17 @@ static void _cliDebuggerDeinit(struct mDebugger* debugger) { static void _cliDebuggerCustom(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; - bool retain = false; + bool retain = true; + enum mDebuggerState next = DEBUGGER_RUNNING; + if (cliDebugger->traceRemaining) { + retain = _doTrace(cliDebugger) && retain; + next = DEBUGGER_PAUSED; + } if (cliDebugger->system) { - retain = cliDebugger->system->custom(cliDebugger->system); + retain = cliDebugger->system->custom(cliDebugger->system) && retain; } if (!retain && debugger->state == DEBUGGER_CUSTOM) { - debugger->state = DEBUGGER_RUNNING; + debugger->state = next; } } diff --git a/src/gb/debugger/cli.c b/src/gb/debugger/cli.c index a051ea577..2d86b12ec 100644 --- a/src/gb/debugger/cli.c +++ b/src/gb/debugger/cli.c @@ -60,7 +60,7 @@ static bool _GBCLIDebuggerCustom(struct CLIDebuggerSystem* debugger) { gbDebugger->inVblank = GBRegisterSTATGetMode(((struct GB*) gbDebugger->core->board)->memory.io[REG_STAT]) == 1; return true; } - return false; + return true; } static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { diff --git a/src/gba/debugger/cli.c b/src/gba/debugger/cli.c index 4eb13b0f3..c9f8bf2b7 100644 --- a/src/gba/debugger/cli.c +++ b/src/gba/debugger/cli.c @@ -59,7 +59,7 @@ static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem* debugger) { gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[REG_DISPSTAT >> 1]); return true; } - return false; + return true; } static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { From 1d6d4a5377ef0c9b1b1ed261e2ba852f082b0998 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 28 Apr 2019 13:27:10 -0700 Subject: [PATCH 144/429] Debugger: Add tracing to file --- CHANGES | 1 + include/mgba/internal/debugger/cli-debugger.h | 2 ++ src/debugger/cli-debugger.c | 27 ++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 2ef909c91..6d5c5c83a 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Features: - Debugger: Add unary operators and memory dereferencing - GB: Expose platform information to CLI debugger - Support Discord Rich Presence + - Debugger: Add tracing to file Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 60ec00fa4..0409ffe8e 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -17,6 +17,7 @@ extern const char* ERROR_OVERFLOW; extern const char* ERROR_INVALID_ARGS; struct CLIDebugger; +struct VFile; struct CLIDebugVector { struct CLIDebugVector* next; @@ -76,6 +77,7 @@ struct CLIDebugger { struct CLIDebuggerBackend* backend; int traceRemaining; + struct VFile* traceVf; }; void CLIDebuggerCreate(struct CLIDebugger*); diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index d2a93aa30..965e57f5a 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -11,6 +11,7 @@ #include #include #include +#include #if ENABLE_SCRIPTING #include @@ -100,7 +101,7 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "r/2", _readHalfword, "I", "Read a halfword from a specified offset" }, { "r/4", _readWord, "I", "Read a word from a specified offset" }, { "status", _printStatus, "", "Print the current status" }, - { "trace", _trace, "I", "Trace a fixed number of instructions" }, + { "trace", _trace, "Is", "Trace a number of instructions" }, { "w", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, @@ -647,9 +648,16 @@ static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { } debugger->traceRemaining = dv->intValue; + if (debugger->traceVf) { + debugger->traceVf->close(debugger->traceVf); + debugger->traceVf = NULL; + } if (debugger->traceRemaining == 0) { return; } + if (dv->next && dv->next->charValue) { + debugger->traceVf = VFileOpen(dv->next->charValue, O_CREAT | O_WRONLY | O_APPEND); + } if (_doTrace(debugger)) { debugger->d.state = DEBUGGER_CUSTOM; } else { @@ -661,12 +669,17 @@ static bool _doTrace(struct CLIDebugger* debugger) { char trace[1024]; trace[sizeof(trace) - 1] = '\0'; debugger->d.core->step(debugger->d.core); - size_t traceSize = sizeof(trace) - 1; + size_t traceSize = sizeof(trace) - 2; debugger->d.platform->trace(debugger->d.platform, trace, &traceSize); - if (traceSize + 1 < sizeof(trace)) { + if (traceSize + 1 <= sizeof(trace)) { + trace[traceSize] = '\n'; trace[traceSize + 1] = '\0'; } - debugger->backend->printf(debugger->backend, "%s\n", trace); + if (debugger->traceVf) { + debugger->traceVf->write(debugger->traceVf, trace, traceSize + 1); + } else { + debugger->backend->printf(debugger->backend, "%s", trace); + } if (debugger->traceRemaining > 0) { --debugger->traceRemaining; } @@ -940,11 +953,17 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r static void _cliDebuggerInit(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; cliDebugger->traceRemaining = 0; + cliDebugger->traceVf = NULL; cliDebugger->backend->init(cliDebugger->backend); } static void _cliDebuggerDeinit(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; + if (cliDebugger->traceVf) { + cliDebugger->traceVf->close(cliDebugger->traceVf); + cliDebugger->traceVf = NULL; + } + if (cliDebugger->system) { if (cliDebugger->system->deinit) { cliDebugger->system->deinit(cliDebugger->system); From 1deff07aa1b0d3d4b6b15e875fbeb0cc8eff0926 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 28 Apr 2019 13:37:51 -0700 Subject: [PATCH 145/429] Debugger: Print breakpoint/watchpoint number when inserting --- CHANGES | 1 + include/mgba/internal/debugger/cli-debugger.h | 2 ++ src/arm/debugger/cli-debugger.c | 14 ++++++++++---- src/debugger/cli-debugger.c | 12 ++++++++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 6d5c5c83a..a0af8727d 100644 --- a/CHANGES +++ b/CHANGES @@ -45,6 +45,7 @@ Misc: - Qt: Cap window size on start to monitor size - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) - Debugger: Make tracing compatible with breakpoints/watchpoints + - Debugger: Print breakpoint/watchpoint number when inserting 0.7.1: (2019-02-24) Bugfixes: diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 0409ffe8e..35a1a936a 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -15,6 +15,8 @@ CXX_GUARD_START extern const char* ERROR_MISSING_ARGS; extern const char* ERROR_OVERFLOW; extern const char* ERROR_INVALID_ARGS; +extern const char* INFO_BREAKPOINT_ADDED; +extern const char* INFO_WATCHPOINT_ADDED; struct CLIDebugger; struct VFile; diff --git a/src/arm/debugger/cli-debugger.c b/src/arm/debugger/cli-debugger.c index fe1265a11..d458ad4aa 100644 --- a/src/arm/debugger/cli-debugger.c +++ b/src/arm/debugger/cli-debugger.c @@ -147,21 +147,27 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { static void _setBreakpointARM(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { - be->printf(be, "%s\n", ERROR_MISSING_ARGS); + be->printf(be, "%s", ERROR_MISSING_ARGS); return; } uint32_t address = dv->intValue; - ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_ARM); + ssize_t id = ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_ARM); + if (id > 0) { + debugger->backend->printf(debugger->backend, INFO_BREAKPOINT_ADDED, id); + } } static void _setBreakpointThumb(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { - be->printf(be, "%s\n", ERROR_MISSING_ARGS); + be->printf(be, "%s", ERROR_MISSING_ARGS); return; } uint32_t address = dv->intValue; - ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_THUMB); + ssize_t id = ARMDebuggerSetSoftwareBreakpoint(debugger->d.platform, address, MODE_THUMB); + if (id > 0) { + debugger->backend->printf(debugger->backend, INFO_BREAKPOINT_ADDED, id); + } } void ARMCLIDebuggerCreate(struct CLIDebuggerSystem* debugger) { diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 965e57f5a..64d431297 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -28,6 +28,8 @@ const char* ERROR_MISSING_ARGS = "Arguments missing"; // TODO: share const char* ERROR_OVERFLOW = "Arguments overflow"; const char* ERROR_INVALID_ARGS = "Invalid arguments"; +const char* INFO_BREAKPOINT_ADDED = "Added breakpoint #%" PRIz "i\n"; +const char* INFO_WATCHPOINT_ADDED = "Added watchpoint #%" PRIz "i\n"; static struct ParseTree* _parseTree(const char** string); static bool _doTrace(struct CLIDebugger* debugger); @@ -553,7 +555,10 @@ static void _setBreakpoint(struct CLIDebugger* debugger, struct CLIDebugVector* return; } } - debugger->d.platform->setBreakpoint(debugger->d.platform, &breakpoint); + ssize_t id = debugger->d.platform->setBreakpoint(debugger->d.platform, &breakpoint); + if (id > 0) { + debugger->backend->printf(debugger->backend, INFO_BREAKPOINT_ADDED, id); + } } static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv, enum mWatchpointType type) { @@ -579,7 +584,10 @@ static void _setWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* return; } } - debugger->d.platform->setWatchpoint(debugger->d.platform, &watchpoint); + ssize_t id = debugger->d.platform->setWatchpoint(debugger->d.platform, &watchpoint); + if (id > 0) { + debugger->backend->printf(debugger->backend, INFO_WATCHPOINT_ADDED, id); + } } static void _setReadWriteWatchpoint(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { From 19a42a387a4a9316e5626c8079bed4d989d9c3ac Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 29 Apr 2019 12:16:41 -0700 Subject: [PATCH 146/429] LR35902: Fix trailing whitespace in disassembly --- CHANGES | 1 + src/lr35902/decoder.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index a0af8727d..37d9bdb00 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Other fixes: - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) - GB Core: Fix toggling WIN and OBJ being swapped - All: Fix several memory leaks + - LR35902: Fix trailing whitespace in disassembly Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/lr35902/decoder.c b/src/lr35902/decoder.c index 089b52c69..af7a605e6 100644 --- a/src/lr35902/decoder.c +++ b/src/lr35902/decoder.c @@ -504,6 +504,9 @@ static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, i return 0; } + strncpy(buffer, " ", blen - 1); + ADVANCE(1); + if (op.flags & LR35902_OP_FLAG_MEMORY) { strncpy(buffer, "[", blen - 1); ADVANCE(1); @@ -545,16 +548,16 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* b int total = 0; const char* cond = _lr35902Conditions[info->condition]; - written = snprintf(buffer, blen - 1, "%s ", mnemonic); + written = snprintf(buffer, blen - 1, "%s", mnemonic); ADVANCE(written); if (cond) { - written = snprintf(buffer, blen - 1, "%s", cond); + written = snprintf(buffer, blen - 1, " %s", cond); ADVANCE(written); if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) { - strncpy(buffer, ", ", blen - 1); - ADVANCE(2); + strncpy(buffer, ",", blen - 1); + ADVANCE(1); } } @@ -565,8 +568,8 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* b if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) { if (written) { - strncpy(buffer, ", ", blen - 1); - ADVANCE(2); + strncpy(buffer, ",", blen - 1); + ADVANCE(1); } written = _decodeOperand(info->op2, pc, buffer, blen); ADVANCE(written); From fbe375fab992cb4bb2fbc005ed26bc488ccb3389 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Apr 2019 17:44:56 -0700 Subject: [PATCH 147/429] Core: Add support for caching bitmapped modes --- CHANGES | 1 + include/mgba/core/bitmap-cache.h | 64 +++++++++++ include/mgba/core/cache-set.h | 5 +- src/core/bitmap-cache.c | 182 +++++++++++++++++++++++++++++++ src/core/cache-set.c | 20 +++- src/gb/renderers/cache-set.c | 5 +- src/gba/renderers/cache-set.c | 52 +++++++-- src/platform/qt/MapView.cpp | 43 ++++++-- src/platform/qt/MapView.h | 1 + 9 files changed, 347 insertions(+), 26 deletions(-) create mode 100644 include/mgba/core/bitmap-cache.h create mode 100644 src/core/bitmap-cache.c diff --git a/CHANGES b/CHANGES index 37d9bdb00..76c9d07ee 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Features: - GB: Expose platform information to CLI debugger - Support Discord Rich Presence - Debugger: Add tracing to file + - Map viewer supports bitmapped GBA modes Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/core/bitmap-cache.h b/include/mgba/core/bitmap-cache.h new file mode 100644 index 000000000..d8bd416e9 --- /dev/null +++ b/include/mgba/core/bitmap-cache.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2013-2019 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/. */ +#ifndef M_BITMAP_CACHE_H +#define M_BITMAP_CACHE_H + +#include + +CXX_GUARD_START + +#include + +DECL_BITFIELD(mBitmapCacheConfiguration, uint32_t); +DECL_BIT(mBitmapCacheConfiguration, ShouldStore, 0); + +DECL_BITFIELD(mBitmapCacheSystemInfo, uint32_t); +DECL_BITS(mBitmapCacheSystemInfo, EntryBPP, 0, 3); +DECL_BIT(mBitmapCacheSystemInfo, UsesPalette, 3); +DECL_BITS(mBitmapCacheSystemInfo, Width, 4, 10); +DECL_BITS(mBitmapCacheSystemInfo, Height, 14, 10); +DECL_BITS(mBitmapCacheSystemInfo, Buffers, 24, 2); + +struct mBitmapCacheEntry { + uint32_t paletteVersion; + uint32_t vramVersion; + uint8_t vramClean; +}; + +struct mBitmapCache { + color_t* cache; + struct mBitmapCacheEntry* status; + + uint32_t globalPaletteVersion; + + uint8_t* vram; + color_t* palette; + + uint32_t bitsSize; + uint32_t bitsStart[2]; + uint32_t stride; + uint8_t buffer; + + mBitmapCacheConfiguration config; + mBitmapCacheSystemInfo sysConfig; + + void* context; +}; + +void mBitmapCacheInit(struct mBitmapCache* cache); +void mBitmapCacheDeinit(struct mBitmapCache* cache); +void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config); +void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config); +void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address); +void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color); + +void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y); +bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y); +const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y); + +CXX_GUARD_END + +#endif diff --git a/include/mgba/core/cache-set.h b/include/mgba/core/cache-set.h index 8fed166a9..5749c0e64 100644 --- a/include/mgba/core/cache-set.h +++ b/include/mgba/core/cache-set.h @@ -10,19 +10,22 @@ CXX_GUARD_START +#include #include #include #include DECLARE_VECTOR(mMapCacheSet, struct mMapCache); +DECLARE_VECTOR(mBitmapCacheSet, struct mBitmapCache); DECLARE_VECTOR(mTileCacheSet, struct mTileCache); struct mCacheSet { struct mMapCacheSet maps; + struct mBitmapCacheSet bitmaps; struct mTileCacheSet tiles; }; -void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nTiles); +void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nBitmaps, size_t nTiles); void mCacheSetDeinit(struct mCacheSet*); void mCacheSetAssignVRAM(struct mCacheSet*, void* vram); diff --git a/src/core/bitmap-cache.c b/src/core/bitmap-cache.c new file mode 100644 index 000000000..c86768e45 --- /dev/null +++ b/src/core/bitmap-cache.c @@ -0,0 +1,182 @@ +/* Copyright (c) 2013-2019 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 + +#include + +void mBitmapCacheInit(struct mBitmapCache* cache) { + // TODO: Reconfigurable cache for space savings + cache->cache = NULL; + cache->config = mBitmapCacheConfigurationFillShouldStore(0); + cache->status = NULL; + cache->palette = NULL; + cache->buffer = 0; +} + +static void _freeCache(struct mBitmapCache* cache) { + size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); + mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + mappedMemoryFree(cache->status, size * sizeof(*cache->status)); + if (cache->palette) { + free(cache->palette); + } + cache->cache = NULL; + cache->status = NULL; + cache->palette = NULL; +} + +static void _redoCacheSize(struct mBitmapCache* cache) { + if (!mBitmapCacheConfigurationIsShouldStore(cache->config)) { + return; + } + + size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); + cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + cache->status = anonymousMemoryMap(size * sizeof(*cache->status)); + if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { + cache->palette = malloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))) * sizeof(color_t)); + } else { + cache->palette = NULL; + } +} + +void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config) { + if (config == cache->config) { + return; + } + _freeCache(cache); + cache->config = config; + _redoCacheSize(cache); +} + +void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config) { + if (config == cache->sysConfig) { + return; + } + _freeCache(cache); + cache->sysConfig = config; + _redoCacheSize(cache); + + size_t stride = mBitmapCacheSystemInfoGetWidth(cache->sysConfig); + size_t size = stride * mBitmapCacheSystemInfoGetHeight(cache->sysConfig); + size_t bpe = mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig); + if (bpe > 3) { + size <<= bpe - 3; + stride <<= bpe - 3; + } else { + size >>= 3 - bpe; + stride >>= 3 - bpe; + } + cache->bitsSize = size; + cache->stride = stride; +} + +void mBitmapCacheDeinit(struct mBitmapCache* cache) { + _freeCache(cache); +} + +void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address) { + size_t i; + for (i = 0; i < mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); ++i) { + if (address < cache->bitsStart[i]) { + continue; + } + uint32_t offset = address - cache->bitsStart[i]; + if (offset >= cache->bitsSize) { + continue; + } + offset /= cache->stride; + offset *= mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); + offset += cache->buffer; + cache->status[offset].vramClean = 0; + ++cache->status[offset].vramVersion; + } +} + +void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color) { + if (!mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { + return; + } + size_t maxEntry = 1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig)); + if (entry >= maxEntry) { + return; + } + cache->palette[entry] = color; + ++cache->globalPaletteVersion; +} + +uint32_t _lookupEntry8(void* vram, uint32_t offset) { + return ((uint8_t*) vram)[offset]; +} + +uint32_t _lookupEntry15(void* vram, uint32_t offset) { + return mColorFrom555(((uint16_t*) vram)[offset]); +} + +void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y) { + color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; + size_t location = cache->buffer + mBitmapCacheSystemInfoGetBuffers(cache->sysConfig) * y; + struct mBitmapCacheEntry* status = &cache->status[location]; + struct mBitmapCacheEntry desiredStatus = { + .paletteVersion = cache->globalPaletteVersion, + .vramVersion = entry->vramVersion, + .vramClean = 1 + }; + + if (entry) { + entry[location] = desiredStatus; + } + + if (!mBitmapCacheConfigurationIsShouldStore(cache->config) || !memcmp(status, &desiredStatus, sizeof(*entry))) { + return; + } + + size_t offset = cache->bitsStart[cache->buffer] + y * mBitmapCacheSystemInfoGetWidth(cache->sysConfig); + void* vram; + int bpe = mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig); + uint32_t (*lookupEntry)(void*, uint32_t); + switch (bpe) { + case 3: + lookupEntry = _lookupEntry8; + vram = &cache->vram[offset]; + break; + case 4: + lookupEntry = _lookupEntry15; + vram = &cache->vram[offset << 1]; + break; + default: + abort(); + break; + } + + size_t x; + if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { + for (x = 0; x < mBitmapCacheSystemInfoGetWidth(cache->sysConfig); ++x) { + row[x] = cache->palette[lookupEntry(vram, x)]; + } + } else { + for (x = 0; x < mBitmapCacheSystemInfoGetWidth(cache->sysConfig); ++x) { + row[x] = lookupEntry(vram, x); + } + } + *status = desiredStatus; +} + +bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y) { + size_t location = cache->buffer + mBitmapCacheSystemInfoGetBuffers(cache->sysConfig) * y; + struct mBitmapCacheEntry desiredStatus = { + .paletteVersion = cache->globalPaletteVersion, + .vramVersion = entry->vramVersion, + .vramClean = 1 + }; + + return memcmp(&entry[location], &desiredStatus, sizeof(*entry)) == 0; +} + +const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) { + color_t* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; + return row; +} \ No newline at end of file diff --git a/src/core/cache-set.c b/src/core/cache-set.c index 7561981e3..a638c786e 100644 --- a/src/core/cache-set.c +++ b/src/core/cache-set.c @@ -6,11 +6,14 @@ #include DEFINE_VECTOR(mMapCacheSet, struct mMapCache); +DEFINE_VECTOR(mBitmapCacheSet, struct mBitmapCache); DEFINE_VECTOR(mTileCacheSet, struct mTileCache); -void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nTiles) { +void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nBitmaps, size_t nTiles) { mMapCacheSetInit(&cache->maps, nMaps); mMapCacheSetResize(&cache->maps, nMaps); + mBitmapCacheSetInit(&cache->bitmaps, nBitmaps); + mBitmapCacheSetResize(&cache->bitmaps, nBitmaps); mTileCacheSetInit(&cache->tiles, nTiles); mTileCacheSetResize(&cache->tiles, nTiles); @@ -18,6 +21,9 @@ void mCacheSetInit(struct mCacheSet* cache, size_t nMaps, size_t nTiles) { for (i = 0; i < nMaps; ++i) { mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, i)); } + for (i = 0; i < nBitmaps; ++i) { + mBitmapCacheInit(mBitmapCacheSetGetPointer(&cache->bitmaps, i)); + } for (i = 0; i < nTiles; ++i) { mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, i)); } @@ -28,6 +34,9 @@ void mCacheSetDeinit(struct mCacheSet* cache) { for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) { mMapCacheDeinit(mMapCacheSetGetPointer(&cache->maps, i)); } + for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { + mBitmapCacheDeinit(mBitmapCacheSetGetPointer(&cache->bitmaps, i)); + } for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) { mTileCacheDeinit(mTileCacheSetGetPointer(&cache->tiles, i)); } @@ -38,6 +47,9 @@ void mCacheSetAssignVRAM(struct mCacheSet* cache, void* vram) { for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) { mMapCacheSetGetPointer(&cache->maps, i)->vram = vram; } + for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { + mBitmapCacheSetGetPointer(&cache->bitmaps, i)->vram = vram; + } for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) { struct mTileCache* tileCache = mTileCacheSetGetPointer(&cache->tiles, i); tileCache->vram = (void*) ((uintptr_t) vram + tileCache->tileBase); @@ -49,6 +61,9 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) { for (i = 0; i < mMapCacheSetSize(&cache->maps); ++i) { mMapCacheWriteVRAM(mMapCacheSetGetPointer(&cache->maps, i), address); } + for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { + mBitmapCacheWriteVRAM(mBitmapCacheSetGetPointer(&cache->bitmaps, i), address); + } for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) { mTileCacheWriteVRAM(mTileCacheSetGetPointer(&cache->tiles, i), address); } @@ -56,6 +71,9 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) { void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, color_t color) { size_t i; + for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { + mBitmapCacheWritePalette(mBitmapCacheSetGetPointer(&cache->bitmaps, i), entry, color); + } for (i = 0; i < mTileCacheSetSize(&cache->tiles); ++i) { mTileCacheWritePalette(mTileCacheSetGetPointer(&cache->tiles, i), entry, color); } diff --git a/src/gb/renderers/cache-set.c b/src/gb/renderers/cache-set.c index 741d043cd..9703c09c1 100644 --- a/src/gb/renderers/cache-set.c +++ b/src/gb/renderers/cache-set.c @@ -11,16 +11,13 @@ #include void GBVideoCacheInit(struct mCacheSet* cache) { - mCacheSetInit(cache, 2, 1); + mCacheSetInit(cache, 2, 0, 1); mTileCacheConfiguration config = 0; config = mTileCacheSystemInfoSetPaletteBPP(config, 1); // 2^(2^1) = 4 entries config = mTileCacheSystemInfoSetPaletteCount(config, 4); // 16 palettes config = mTileCacheSystemInfoSetMaxTiles(config, 1024); - mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 0)); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), config, 0, 0); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 0)); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 1)); mMapCacheSetGetPointer(&cache->maps, 0)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0); mMapCacheSetGetPointer(&cache->maps, 1)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 0); } diff --git a/src/gba/renderers/cache-set.c b/src/gba/renderers/cache-set.c index dae92b675..71a4b8617 100644 --- a/src/gba/renderers/cache-set.c +++ b/src/gba/renderers/cache-set.c @@ -11,35 +11,45 @@ #include void GBAVideoCacheInit(struct mCacheSet* cache) { - mCacheSetInit(cache, 4, 4); + mCacheSetInit(cache, 4, 2, 4); mTileCacheSystemInfo sysconfig = 0; mTileCacheConfiguration config = mTileCacheConfigurationFillShouldStore(0); sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 2); // 2^(2^2) = 16 entries sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 4); // 16 palettes sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048); - mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 0)); mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 0), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 0), sysconfig, 0, 0); sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024); - mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 2)); mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 2), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 2), sysconfig, 0x10000, 0x100); sysconfig = mTileCacheSystemInfoSetPaletteBPP(sysconfig, 3); // 2^(2^3) = 256 entries sysconfig = mTileCacheSystemInfoSetPaletteCount(sysconfig, 0); // 1 palettes sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 2048); - mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 1)); mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 1), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 1), sysconfig, 0, 0); sysconfig = mTileCacheSystemInfoSetMaxTiles(sysconfig, 1024); - mTileCacheInit(mTileCacheSetGetPointer(&cache->tiles, 3)); mTileCacheConfigure(mTileCacheSetGetPointer(&cache->tiles, 3), config); mTileCacheConfigureSystem(mTileCacheSetGetPointer(&cache->tiles, 3), sysconfig, 0x10000, 0x100); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 0)); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 1)); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 2)); - mMapCacheInit(mMapCacheSetGetPointer(&cache->maps, 3)); + mBitmapCacheSystemInfo bitConfig; + bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4); + bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig); + bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160); + bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240); + bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 1); + mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig); + mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->bitsStart[0] = 0; + mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->bitsStart[1] = 0xA000; + + bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 3); + bitConfig = mBitmapCacheSystemInfoFillUsesPalette(bitConfig); + bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160); + bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240); + bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 2); + mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 1), bitConfig); + mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[0] = 0; + mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->bitsStart[1] = 0xA000; } void GBAVideoCacheAssociate(struct mCacheSet* cache, struct GBAVideo* video) { @@ -77,6 +87,8 @@ static void mapParser2(struct mMapCache* cache, struct mMapCacheEntry* entry, vo } static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) { + mBitmapCacheSetGetPointer(&cache->bitmaps, 1)->buffer = GBARegisterDISPCNTGetFrameSelect(value); + switch (GBARegisterDISPCNTGetMode(value)) { case 0: default: @@ -110,6 +122,28 @@ static void GBAVideoCacheWriteDISPCNT(struct mCacheSet* cache, uint16_t value) { mMapCacheSetGetPointer(&cache->maps, 3)->tileCache = mTileCacheSetGetPointer(&cache->tiles, 1); break; } + + mBitmapCacheSystemInfo bitConfig; + switch (GBARegisterDISPCNTGetMode(value)) { + case 3: + bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4); + bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig); + bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 160); + bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 240); + bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 1); + mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig); + mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->buffer = 0; + break; + case 5: + bitConfig = mBitmapCacheSystemInfoSetEntryBPP(0, 4); + bitConfig = mBitmapCacheSystemInfoClearUsesPalette(bitConfig); + bitConfig = mBitmapCacheSystemInfoSetHeight(bitConfig, 128); + bitConfig = mBitmapCacheSystemInfoSetWidth(bitConfig, 160); + bitConfig = mBitmapCacheSystemInfoSetBuffers(bitConfig, 2); + mBitmapCacheConfigureSystem(mBitmapCacheSetGetPointer(&cache->bitmaps, 0), bitConfig); + mBitmapCacheSetGetPointer(&cache->bitmaps, 0)->buffer = GBARegisterDISPCNTGetFrameSelect(value); + break; + } } static void GBAVideoCacheWriteBGCNT(struct mCacheSet* cache, size_t bg, uint16_t value) { diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index e4d970e5f..a0232c50b 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -12,7 +12,10 @@ #include #include #ifdef M_CORE_GBA +#include +#include #include +#include #endif #ifdef M_CORE_GB #include @@ -139,17 +142,36 @@ bool MapView::eventFilter(QObject* obj, QEvent* event) { void MapView::updateTilesGBA(bool force) { { CoreController::Interrupter interrupter(m_controller); - mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); - int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig); - int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig); - m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32); - uchar* bgBits = m_rawMap.bits(); - for (int j = 0; j < tilesH; ++j) { - for (int i = 0; i < tilesW; ++i) { - mMapCacheCleanTile(mapCache, m_mapStatus, i, j); + int bitmap = -1; + if (m_controller->platform() == PLATFORM_GBA) { + int mode = GBARegisterDISPCNTGetMode(static_cast(m_controller->thread()->core->board)->memory.io[REG_DISPCNT]); + if (m_map == 2 && mode > 2) { + bitmap = mode == 4 ? 1 : 0; } - for (int i = 0; i < 8; ++i) { - memcpy(static_cast(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32); + } + if (bitmap >= 0) { + mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap); + int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig); + int height = mBitmapCacheSystemInfoGetHeight(bitmapCache->sysConfig); + m_rawMap = QImage(QSize(width, height), QImage::Format_ARGB32); + uchar* bgBits = m_rawMap.bits(); + for (int j = 0; j < height; ++j) { + mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j); + memcpy(static_cast(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4); + } + } else { + mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); + int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig); + int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig); + m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32); + uchar* bgBits = m_rawMap.bits(); + for (int j = 0; j < tilesH; ++j) { + for (int i = 0; i < tilesW; ++i) { + mMapCacheCleanTile(mapCache, m_mapStatus, i, j); + } + for (int i = 0; i < 8; ++i) { + memcpy(static_cast(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32); + } } } } @@ -181,7 +203,6 @@ void MapView::exportMap() { png_structp png = PNGWriteOpen(vf); png_infop info = PNGWriteHeaderA(png, m_rawMap.width(), m_rawMap.height()); - mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); QImage map = m_rawMap.rgbSwapped(); PNGWritePixelsA(png, map.width(), map.height(), map.bytesPerLine() / 4, static_cast(map.constBits())); PNGWriteClose(png, info); diff --git a/src/platform/qt/MapView.h b/src/platform/qt/MapView.h index c8aa0867a..4b39dcd7a 100644 --- a/src/platform/qt/MapView.h +++ b/src/platform/qt/MapView.h @@ -45,6 +45,7 @@ private: std::shared_ptr m_controller; mMapCacheEntry m_mapStatus[128 * 128] = {}; // TODO: Correct size + mBitmapCacheEntry m_bitmapStatus[512 * 2] = {}; // TODO: Correct size int m_map = 0; QImage m_rawMap; int m_boundary; From 0f9c4bbe60d4c30e10ac0d15d5c653297c51e034 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Apr 2019 17:45:38 -0700 Subject: [PATCH 148/429] GBA Memory: Fix writing to OBJ memory in modes 3 and 5 --- CHANGES | 1 + src/gba/memory.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 76c9d07ee..d5d08b3e5 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Emulation fixes: - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) + - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gba/memory.c b/src/gba/memory.c index 32d707c60..46aecae5b 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -938,7 +938,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo GBAStore16(cpu, address & ~1, ((uint8_t) value) | ((uint8_t) value << 8), cycleCounter); break; case REGION_VRAM: - if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) == 4) ? 0x00014000 : 0x00010000)) { + if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) { // TODO: check BG mode mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address); break; From 37a564da4c34ec84f95a1224e5f5fc1161176184 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Apr 2019 18:16:44 -0700 Subject: [PATCH 149/429] Qt: Fix adjusting magnification in tile viewer when not fitting to window --- CHANGES | 1 + src/platform/qt/TileView.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d5d08b3e5..049717040 100644 --- a/CHANGES +++ b/CHANGES @@ -33,6 +33,7 @@ Other fixes: - GB Core: Fix toggling WIN and OBJ being swapped - All: Fix several memory leaks - LR35902: Fix trailing whitespace in disassembly + - Qt: Fix adjusting magnification in tile viewer when not fitting to window Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp index bc7381f7a..01673c9df 100644 --- a/src/platform/qt/TileView.cpp +++ b/src/platform/qt/TileView.cpp @@ -65,7 +65,10 @@ TileView::TileView(std::shared_ptr controller, QWidget* parent) } updateTiles(true); }); - connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), [this]() { + connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), [this](int mag) { + if (!m_ui.tileFit->isChecked()) { + m_ui.tiles->setMinimumSize(mag * 8 * m_ui.tilesPerRow->value(), m_ui.tiles->minimumSize().height()); + } updateTiles(true); }); From 43e2a6ab5d32d1a1165bc37699bcf9dfc6e1992e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 1 May 2019 21:59:39 -0700 Subject: [PATCH 150/429] GBA: Move VIDEO_*_PIXELS to public interface --- include/mgba/gba/interface.h | 5 ++ .../internal/gba/renderers/video-software.h | 7 +- include/mgba/internal/gba/video.h | 2 - src/feature/ffmpeg/ffmpeg-encoder.c | 12 ++-- .../imagemagick/imagemagick-gif-encoder.c | 6 +- src/gba/core.c | 6 +- src/gba/dma.c | 2 +- src/gba/extra/proxy.c | 2 +- src/gba/renderers/software-bg.c | 8 +-- src/gba/renderers/software-mode0.c | 6 +- src/gba/renderers/software-obj.c | 8 +-- src/gba/renderers/video-software.c | 68 +++++++++---------- src/gba/video.c | 8 +-- src/platform/3ds/main.c | 6 +- src/platform/qt/MessagePainter.cpp | 6 +- src/platform/qt/Window.cpp | 16 ++--- src/platform/qt/main.cpp | 4 +- src/platform/sdl/pandora-sdl.c | 20 +++--- 18 files changed, 98 insertions(+), 94 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index e620c108e..930faa925 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -13,6 +13,11 @@ CXX_GUARD_START #include #include +enum { + GBA_VIDEO_HORIZONTAL_PIXELS = 240, + GBA_VIDEO_VERTICAL_PIXELS = 160, +}; + enum GBASIOMode { SIO_NORMAL_8 = 0, SIO_NORMAL_32 = 1, diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index d7831c5ac..8bfc3da9b 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -11,6 +11,7 @@ CXX_GUARD_START #include +#include #include #include @@ -122,8 +123,8 @@ struct GBAVideoSoftwareRenderer { GBARegisterDISPCNT dispcnt; - uint32_t row[VIDEO_HORIZONTAL_PIXELS]; - uint32_t spriteLayer[VIDEO_HORIZONTAL_PIXELS]; + uint32_t row[GBA_VIDEO_HORIZONTAL_PIXELS]; + uint32_t spriteLayer[GBA_VIDEO_HORIZONTAL_PIXELS]; int32_t spriteCyclesRemaining; // BLDCNT @@ -169,7 +170,7 @@ struct GBAVideoSoftwareRenderer { struct ScanlineCache { uint16_t io[REG_SOUND1CNT_LO]; int32_t scale[2][2]; - } cache[VIDEO_VERTICAL_PIXELS]; + } cache[GBA_VIDEO_VERTICAL_PIXELS]; int nextY; int start; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 265cb89aa..15e3a4381 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -16,13 +16,11 @@ CXX_GUARD_START mLOG_DECLARE_CATEGORY(GBA_VIDEO); enum { - VIDEO_HORIZONTAL_PIXELS = 240, VIDEO_HBLANK_PIXELS = 68, VIDEO_HDRAW_LENGTH = 1006, VIDEO_HBLANK_LENGTH = 226, VIDEO_HORIZONTAL_LENGTH = 1232, - VIDEO_VERTICAL_PIXELS = 160, VIDEO_VBLANK_PIXELS = 68, VIDEO_VERTICAL_TOTAL_PIXELS = 228, diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index c1c6439b4..c17bc5b8c 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -6,7 +6,7 @@ #include "ffmpeg-encoder.h" #include -#include +#include #include #include @@ -48,9 +48,9 @@ void FFmpegEncoderInit(struct FFmpegEncoder* encoder) { FFmpegEncoderSetAudio(encoder, "flac", 0); FFmpegEncoderSetVideo(encoder, "png", 0); FFmpegEncoderSetContainer(encoder, "matroska"); - FFmpegEncoderSetDimensions(encoder, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); - encoder->iwidth = VIDEO_HORIZONTAL_PIXELS; - encoder->iheight = VIDEO_VERTICAL_PIXELS; + FFmpegEncoderSetDimensions(encoder, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + encoder->iwidth = GBA_VIDEO_HORIZONTAL_PIXELS; + encoder->iheight = GBA_VIDEO_VERTICAL_PIXELS; encoder->resampleContext = 0; encoder->absf = 0; encoder->context = 0; @@ -175,8 +175,8 @@ bool FFmpegEncoderSetContainer(struct FFmpegEncoder* encoder, const char* contai } void FFmpegEncoderSetDimensions(struct FFmpegEncoder* encoder, int width, int height) { - encoder->width = width > 0 ? width : VIDEO_HORIZONTAL_PIXELS; - encoder->height = height > 0 ? height : VIDEO_VERTICAL_PIXELS; + encoder->width = width > 0 ? width : GBA_VIDEO_HORIZONTAL_PIXELS; + encoder->height = height > 0 ? height : GBA_VIDEO_VERTICAL_PIXELS; } bool FFmpegEncoderVerifyContainer(struct FFmpegEncoder* encoder) { diff --git a/src/feature/imagemagick/imagemagick-gif-encoder.c b/src/feature/imagemagick/imagemagick-gif-encoder.c index 1e0ddb6e6..8d8ebcb5c 100644 --- a/src/feature/imagemagick/imagemagick-gif-encoder.c +++ b/src/feature/imagemagick/imagemagick-gif-encoder.c @@ -6,7 +6,7 @@ #include "imagemagick-gif-encoder.h" #include -#include +#include #include static void _magickPostVideoFrame(struct mAVStream*, const color_t* pixels, size_t stride); @@ -23,8 +23,8 @@ void ImageMagickGIFEncoderInit(struct ImageMagickGIFEncoder* encoder) { encoder->frameskip = 2; encoder->delayMs = -1; - encoder->iwidth = VIDEO_HORIZONTAL_PIXELS; - encoder->iheight = VIDEO_VERTICAL_PIXELS; + encoder->iwidth = GBA_VIDEO_HORIZONTAL_PIXELS; + encoder->iheight = GBA_VIDEO_VERTICAL_PIXELS; } void ImageMagickGIFEncoderSetParams(struct ImageMagickGIFEncoder* encoder, int frameskip, int delayMs) { diff --git a/src/gba/core.c b/src/gba/core.c index 7d00f963c..8966fbe37 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -254,8 +254,8 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { UNUSED(core); - *width = VIDEO_HORIZONTAL_PIXELS; - *height = VIDEO_VERTICAL_PIXELS; + *width = GBA_VIDEO_HORIZONTAL_PIXELS; + *height = GBA_VIDEO_VERTICAL_PIXELS; } static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { @@ -311,7 +311,7 @@ static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) { struct GBA* gba = core->board; gba->stream = stream; if (stream && stream->videoDimensionsChanged) { - stream->videoDimensionsChanged(stream, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + stream->videoDimensionsChanged(stream, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); } } diff --git a/src/gba/dma.c b/src/gba/dma.c index bb13350a9..765358da1 100644 --- a/src/gba/dma.c +++ b/src/gba/dma.c @@ -182,7 +182,7 @@ void _dmaEvent(struct mTiming* timing, void* context, uint32_t cyclesLate) { dma->nextCount = 0; bool noRepeat = !GBADMARegisterIsRepeat(dma->reg); noRepeat |= GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_NOW; - noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM && gba->video.vcount == VIDEO_VERTICAL_PIXELS + 1; + noRepeat |= memory->activeDMA == 3 && GBADMARegisterGetTiming(dma->reg) == GBA_DMA_TIMING_CUSTOM && gba->video.vcount == GBA_VIDEO_VERTICAL_PIXELS + 1; if (noRepeat) { dma->reg = GBADMARegisterClearEnable(dma->reg); diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index d7092f30c..deeec5603 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -151,7 +151,7 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD } break; case DIRTY_SCANLINE: - if (item->address < VIDEO_VERTICAL_PIXELS) { + if (item->address < GBA_VIDEO_VERTICAL_PIXELS) { proxyRenderer->backend->drawScanline(proxyRenderer->backend, item->address); } break; diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index 9655166e1..db4b33e71 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -98,10 +98,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode3(struct GBAVideoSoftwareRenderer int outX; uint32_t* pixel; for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { - BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + BACKGROUND_BITMAP_ITERATE(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); if (!mosaicWait) { - LOAD_16(color, ((localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram); + LOAD_16(color, ((localX >> 8) + (localY >> 8) * GBA_VIDEO_HORIZONTAL_PIXELS) << 1, renderer->d.vram); color = mColorFrom555(color); mosaicWait = mosaicH; } else { @@ -137,10 +137,10 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer int outX; uint32_t* pixel; for (outX = renderer->start, pixel = &renderer->row[outX]; outX < renderer->end; ++outX, ++pixel) { - BACKGROUND_BITMAP_ITERATE(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + BACKGROUND_BITMAP_ITERATE(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); if (!mosaicWait) { - color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * VIDEO_HORIZONTAL_PIXELS]; + color = ((uint8_t*)renderer->d.vram)[offset + (localX >> 8) + (localY >> 8) * GBA_VIDEO_HORIZONTAL_PIXELS]; mosaicWait = mosaicH; } else { diff --git a/src/gba/renderers/software-mode0.c b/src/gba/renderers/software-mode0.c index 944232068..df5626c4b 100644 --- a/src/gba/renderers/software-mode0.c +++ b/src/gba/renderers/software-mode0.c @@ -378,7 +378,7 @@ if (background->mosaic && GBAMosaicControlGetBgH(renderer->mosaic)) { \ int mosaicH = GBAMosaicControlGetBgH(renderer->mosaic) + 1; \ int x; \ - int mosaicWait = (mosaicH - outX + VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \ + int mosaicWait = (mosaicH - outX + GBA_VIDEO_HORIZONTAL_PIXELS * mosaicH) % mosaicH; \ int carryData = 0; \ paletteData = 0; /* Quiets compiler warning */ \ DRAW_BACKGROUND_MODE_0_MOSAIC_ ## BPP (BLEND, OBJWIN) \ @@ -417,7 +417,7 @@ /*! TODO: Make sure these lines can be removed */ \ /*!*/ pixel = &renderer->row[outX]; \ outX += (tileEnd - tileX) * 8; \ - /*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \ + /*!*/ if (VIDEO_CHECKS && UNLIKELY(outX > GBA_VIDEO_HORIZONTAL_PIXELS)) { \ /*!*/ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw would occur!"); \ /*!*/ return; \ /*!*/ } \ @@ -440,7 +440,7 @@ if (VIDEO_CHECKS && UNLIKELY(&renderer->row[outX] != pixel)) { \ mLOG(GBA_VIDEO, FATAL, "Background draw ended in the wrong place! Diff: %" PRIXPTR, &renderer->row[outX] - pixel); \ } \ - if (VIDEO_CHECKS && UNLIKELY(outX > VIDEO_HORIZONTAL_PIXELS)) { \ + if (VIDEO_CHECKS && UNLIKELY(outX > GBA_VIDEO_HORIZONTAL_PIXELS)) { \ mLOG(GBA_VIDEO, FATAL, "Out of bounds background draw occurred!"); \ return; \ } diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index ad846ace0..cb7441666 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -261,8 +261,8 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re SPRITE_TRANSFORMED_LOOP(256, NORMAL); } } - if (end == VIDEO_HORIZONTAL_PIXELS && x + totalWidth > VIDEO_HORIZONTAL_PIXELS) { - renderer->spriteCyclesRemaining -= (x + totalWidth - VIDEO_HORIZONTAL_PIXELS) * 2; + if (end == GBA_VIDEO_HORIZONTAL_PIXELS && x + totalWidth > GBA_VIDEO_HORIZONTAL_PIXELS) { + renderer->spriteCyclesRemaining -= (x + totalWidth - GBA_VIDEO_HORIZONTAL_PIXELS) * 2; } } else { int outX = x >= start ? x : start; @@ -321,8 +321,8 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re SPRITE_NORMAL_LOOP(256, NORMAL); } } - if (end == VIDEO_HORIZONTAL_PIXELS && x + width > VIDEO_HORIZONTAL_PIXELS) { - renderer->spriteCyclesRemaining -= x + width - VIDEO_HORIZONTAL_PIXELS; + if (end == GBA_VIDEO_HORIZONTAL_PIXELS && x + width > GBA_VIDEO_HORIZONTAL_PIXELS) { + renderer->spriteCyclesRemaining -= x + width - GBA_VIDEO_HORIZONTAL_PIXELS; } } return 1; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 6c4853bab..951febc5e 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -72,10 +72,10 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; int y; - for (y = 0; y < VIDEO_VERTICAL_PIXELS; ++y) { + for (y = 0; y < GBA_VIDEO_VERTICAL_PIXELS; ++y) { color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; int x; - for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { + for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { row[x] = GBA_COLOR_WHITE; } } @@ -315,52 +315,52 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender case REG_WIN0H: softwareRenderer->winN[0].h.end = value; softwareRenderer->winN[0].h.start = value >> 8; - if (softwareRenderer->winN[0].h.start > VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end) { + if (softwareRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[0].h.start > softwareRenderer->winN[0].h.end) { softwareRenderer->winN[0].h.start = 0; } - if (softwareRenderer->winN[0].h.end > VIDEO_HORIZONTAL_PIXELS) { - softwareRenderer->winN[0].h.end = VIDEO_HORIZONTAL_PIXELS; - if (softwareRenderer->winN[0].h.start > VIDEO_HORIZONTAL_PIXELS) { - softwareRenderer->winN[0].h.start = VIDEO_HORIZONTAL_PIXELS; + if (softwareRenderer->winN[0].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + softwareRenderer->winN[0].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (softwareRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + softwareRenderer->winN[0].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; } } break; case REG_WIN1H: softwareRenderer->winN[1].h.end = value; softwareRenderer->winN[1].h.start = value >> 8; - if (softwareRenderer->winN[1].h.start > VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end) { + if (softwareRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && softwareRenderer->winN[1].h.start > softwareRenderer->winN[1].h.end) { softwareRenderer->winN[1].h.start = 0; } - if (softwareRenderer->winN[1].h.end > VIDEO_HORIZONTAL_PIXELS) { - softwareRenderer->winN[1].h.end = VIDEO_HORIZONTAL_PIXELS; - if (softwareRenderer->winN[1].h.start > VIDEO_HORIZONTAL_PIXELS) { - softwareRenderer->winN[1].h.start = VIDEO_HORIZONTAL_PIXELS; + if (softwareRenderer->winN[1].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + softwareRenderer->winN[1].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (softwareRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + softwareRenderer->winN[1].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; } } break; case REG_WIN0V: softwareRenderer->winN[0].v.end = value; softwareRenderer->winN[0].v.start = value >> 8; - if (softwareRenderer->winN[0].v.start > VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end) { + if (softwareRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[0].v.start > softwareRenderer->winN[0].v.end) { softwareRenderer->winN[0].v.start = 0; } - if (softwareRenderer->winN[0].v.end > VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[0].v.end = VIDEO_VERTICAL_PIXELS; - if (softwareRenderer->winN[0].v.start > VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[0].v.start = VIDEO_VERTICAL_PIXELS; + if (softwareRenderer->winN[0].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + softwareRenderer->winN[0].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (softwareRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + softwareRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; } } break; case REG_WIN1V: softwareRenderer->winN[1].v.end = value; softwareRenderer->winN[1].v.start = value >> 8; - if (softwareRenderer->winN[1].v.start > VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end) { + if (softwareRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && softwareRenderer->winN[1].v.start > softwareRenderer->winN[1].v.end) { softwareRenderer->winN[1].v.start = 0; } - if (softwareRenderer->winN[1].v.end > VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[1].v.end = VIDEO_VERTICAL_PIXELS; - if (softwareRenderer->winN[1].v.start > VIDEO_VERTICAL_PIXELS) { - softwareRenderer->winN[1].v.start = VIDEO_VERTICAL_PIXELS; + if (softwareRenderer->winN[1].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + softwareRenderer->winN[1].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (softwareRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + softwareRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; } } break; @@ -436,10 +436,10 @@ static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, stru } else if (y >= win->v.end && y < win->v.start) { return; } - if (win->h.end > VIDEO_HORIZONTAL_PIXELS || win->h.end < win->h.start) { + if (win->h.end > GBA_VIDEO_HORIZONTAL_PIXELS || win->h.end < win->h.start) { struct WindowN splits[2] = { *win, *win }; splits[0].h.start = 0; - splits[1].h.end = VIDEO_HORIZONTAL_PIXELS; + splits[1].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; _breakWindowInner(softwareRenderer, &splits[0]); _breakWindowInner(softwareRenderer, &splits[1]); } else { @@ -511,7 +511,7 @@ static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) { if (GBAObjAttributesAIsTransformed(obj.a)) { height <<= GBAObjAttributesAGetDoubleSize(obj.a); } - if (GBAObjAttributesAGetY(obj.a) < VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) { + if (GBAObjAttributesAGetY(obj.a) < GBA_VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) { int y = GBAObjAttributesAGetY(obj.a) + renderer->objOffsetY; renderer->sprites[oamMax].y = y; renderer->sprites[oamMax].endY = y + height; @@ -527,7 +527,7 @@ static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) { static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; - if (y == VIDEO_VERTICAL_PIXELS - 1) { + if (y == GBA_VIDEO_VERTICAL_PIXELS - 1) { softwareRenderer->nextY = 0; } else { softwareRenderer->nextY = y + 1; @@ -567,21 +567,21 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { int x; - for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; ++x) { + for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { row[x] = GBA_COLOR_WHITE; } return; } int x; - for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; x += 4) { + for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) { softwareRenderer->spriteLayer[x] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 1] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 2] = FLAG_UNWRITTEN; softwareRenderer->spriteLayer[x + 3] = FLAG_UNWRITTEN; } - softwareRenderer->windows[0].endX = VIDEO_HORIZONTAL_PIXELS; + softwareRenderer->windows[0].endX = GBA_VIDEO_HORIZONTAL_PIXELS; softwareRenderer->nWindows = 1; if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; @@ -676,14 +676,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render } #ifdef COLOR_16_BIT - for (x = 0; x < VIDEO_HORIZONTAL_PIXELS; x += 4) { + for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) { row[x] = softwareRenderer->row[x]; row[x + 1] = softwareRenderer->row[x + 1]; row[x + 2] = softwareRenderer->row[x + 2]; row[x + 3] = softwareRenderer->row[x + 3]; } #else - memcpy(row, softwareRenderer->row, VIDEO_HORIZONTAL_PIXELS * sizeof(*row)); + memcpy(row, softwareRenderer->row, GBA_VIDEO_HORIZONTAL_PIXELS * sizeof(*row)); #endif } @@ -692,7 +692,7 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere softwareRenderer->nextY = 0; if (softwareRenderer->temporaryBuffer) { - mappedMemoryFree(softwareRenderer->temporaryBuffer, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4); + mappedMemoryFree(softwareRenderer->temporaryBuffer, GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4); softwareRenderer->temporaryBuffer = 0; } softwareRenderer->bg[2].sx = softwareRenderer->bg[2].refx; @@ -725,8 +725,8 @@ static void GBAVideoSoftwareRendererPutPixels(struct GBAVideoRenderer* renderer, const color_t* colorPixels = pixels; unsigned i; - for (i = 0; i < VIDEO_VERTICAL_PIXELS; ++i) { - memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); + for (i = 0; i < GBA_VIDEO_VERTICAL_PIXELS; ++i) { + memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], GBA_VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); } } diff --git a/src/gba/video.c b/src/gba/video.c index ee9a8306c..e75d255b1 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -145,7 +145,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { case 0: GBAFrameStarted(video->p); break; - case VIDEO_VERTICAL_PIXELS: + case GBA_VIDEO_VERTICAL_PIXELS: video->p->memory.io[REG_DISPSTAT >> 1] = GBARegisterDISPSTATFillInVblank(dispstat); if (video->frameskipCounter <= 0) { video->renderer->finishFrame(video->renderer); @@ -177,14 +177,14 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) { // Begin Hblank dispstat = GBARegisterDISPSTATFillInHblank(dispstat); - if (video->vcount < VIDEO_VERTICAL_PIXELS && video->frameskipCounter <= 0) { + if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS && video->frameskipCounter <= 0) { video->renderer->drawScanline(video->renderer, video->vcount); } - if (video->vcount < VIDEO_VERTICAL_PIXELS) { + if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) { GBADMARunHblank(video->p, -cyclesLate); } - if (video->vcount >= 2 && video->vcount < VIDEO_VERTICAL_PIXELS + 2) { + if (video->vcount >= 2 && video->vcount < GBA_VIDEO_VERTICAL_PIXELS + 2) { GBADMARunDisplayStart(video->p, -cyclesLate); } if (GBARegisterDISPSTATIsHblankIRQ(dispstat)) { diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 288dc029f..8167b2b27 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -8,9 +8,9 @@ #include #include #ifdef M_CORE_GBA +#include #include #include -#include #endif #ifdef M_CORE_GB #include @@ -550,9 +550,9 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { UNUSED(runner); C3D_Tex* tex = &outputTexture; - GSPGPU_FlushDataCache(outputBuffer, 256 * VIDEO_VERTICAL_PIXELS * 2); + GSPGPU_FlushDataCache(outputBuffer, 256 * GBA_VIDEO_VERTICAL_PIXELS * 2); C3D_SyncDisplayTransfer( - (u32*) outputBuffer, GX_BUFFER_DIM(256, VIDEO_VERTICAL_PIXELS), + (u32*) outputBuffer, GX_BUFFER_DIM(256, GBA_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) | diff --git a/src/platform/qt/MessagePainter.cpp b/src/platform/qt/MessagePainter.cpp index e62afe8f4..de24ade24 100644 --- a/src/platform/qt/MessagePainter.cpp +++ b/src/platform/qt/MessagePainter.cpp @@ -9,7 +9,7 @@ #include -#include +#include using namespace QGBA; @@ -39,9 +39,9 @@ void MessagePainter::resize(const QSize& size, bool lockAspectRatio, qreal scale } } m_world.reset(); - m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS); + m_world.scale(qreal(drawW) / GBA_VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / GBA_VIDEO_VERTICAL_PIXELS); m_scaleFactor = scaleFactor; - m_local = QPoint(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1); + m_local = QPoint(1, GBA_VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1); m_local = m_world.map(m_local); m_local += QPoint((w - drawW) / 2, (h - drawH) / 2); m_pixmapBuffer = QPixmap(drawW * m_scaleFactor, diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index acf56669e..300d7d95c 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -65,8 +65,8 @@ #include #endif #ifdef M_CORE_GBA +#include #include -#include #endif #include #include "feature/sqlite3/no-intro.h" @@ -131,7 +131,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi }); #endif #if defined(M_CORE_GBA) - resizeFrame(QSize(VIDEO_HORIZONTAL_PIXELS * i, VIDEO_VERTICAL_PIXELS * i)); + resizeFrame(QSize(GBA_VIDEO_HORIZONTAL_PIXELS * i, GBA_VIDEO_VERTICAL_PIXELS * i)); #elif defined(M_CORE_GB) resizeFrame(QSize(GB_VIDEO_HORIZONTAL_PIXELS * i, GB_VIDEO_VERTICAL_PIXELS * i)); #endif @@ -580,7 +580,7 @@ void Window::resizeEvent(QResizeEvent* event) { } int factor = 0; - QSize size(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); if (m_controller) { size = m_controller->screenDimensions(); } @@ -625,8 +625,8 @@ void Window::closeEvent(QCloseEvent* event) { m_config->setQtOption("windowPos", pos()); if (m_savedScale > 0) { - m_config->setOption("height", VIDEO_VERTICAL_PIXELS * m_savedScale); - m_config->setOption("width", VIDEO_HORIZONTAL_PIXELS * m_savedScale); + m_config->setOption("height", GBA_VIDEO_VERTICAL_PIXELS * m_savedScale); + m_config->setOption("width", GBA_VIDEO_HORIZONTAL_PIXELS * m_savedScale); } saveConfig(); m_display.reset(); @@ -805,7 +805,7 @@ void Window::gameStopped() { #ifdef M_CORE_GB m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); #elif defined(M_CORE_GBA) - m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); #endif } @@ -909,7 +909,7 @@ void Window::reloadDisplayDriver() { #ifdef M_CORE_GB m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); #elif defined(M_CORE_GBA) - m_display->setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); #endif } } @@ -1410,7 +1410,7 @@ void Window::setupMenu(QMenuBar* menubar) { } connect(setSize, &QAction::triggered, [this, i, setSize]() { showNormal(); - QSize size(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); + QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); if (m_controller) { size = m_controller->screenDimensions(); } diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index e3a958038..9c3fa5072 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -12,7 +12,7 @@ #include "Window.h" #include -#include +#include #include #include @@ -94,7 +94,7 @@ int main(int argc, char* argv[]) { freeArguments(&args); if (graphicsOpts.multiplier) { - w->resizeFrame(QSize(VIDEO_HORIZONTAL_PIXELS * graphicsOpts.multiplier, VIDEO_VERTICAL_PIXELS * graphicsOpts.multiplier)); + w->resizeFrame(QSize(GBA_VIDEO_HORIZONTAL_PIXELS * graphicsOpts.multiplier, GBA_VIDEO_VERTICAL_PIXELS * graphicsOpts.multiplier)); } if (graphicsOpts.fullscreen) { w->enterFullScreen(); diff --git a/src/platform/sdl/pandora-sdl.c b/src/platform/sdl/pandora-sdl.c index ee3f33631..673d419b6 100644 --- a/src/platform/sdl/pandora-sdl.c +++ b/src/platform/sdl/pandora-sdl.c @@ -55,7 +55,7 @@ bool mSDLInit(struct SDLSoftwareRenderer* renderer) { ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); } - mem.size = VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4; + mem.size = GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4; ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); plane.enabled = 1; @@ -67,19 +67,19 @@ bool mSDLInit(struct SDLSoftwareRenderer* renderer) { struct fb_var_screeninfo info; ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - info.xres = VIDEO_HORIZONTAL_PIXELS; - info.yres = VIDEO_VERTICAL_PIXELS; - info.xres_virtual = VIDEO_HORIZONTAL_PIXELS; - info.yres_virtual = VIDEO_VERTICAL_PIXELS * 2; + info.xres = GBA_VIDEO_HORIZONTAL_PIXELS; + info.yres = GBA_VIDEO_VERTICAL_PIXELS; + info.xres_virtual = GBA_VIDEO_HORIZONTAL_PIXELS; + info.yres_virtual = GBA_VIDEO_VERTICAL_PIXELS * 2; info.bits_per_pixel = 16; ioctl(renderer->fb, FBIOPUT_VSCREENINFO, &info); renderer->odd = 0; - renderer->base[0] = mmap(0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4, PROT_READ | PROT_WRITE, MAP_SHARED, renderer->fb, 0); - renderer->base[1] = (uint16_t*) renderer->base[0] + VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS; + renderer->base[0] = mmap(0, GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4, PROT_READ | PROT_WRITE, MAP_SHARED, renderer->fb, 0); + renderer->base[1] = (uint16_t*) renderer->base[0] + GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS; renderer->d.outputBuffer = renderer->base[0]; - renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; + renderer->d.outputBufferStride = GBA_VIDEO_HORIZONTAL_PIXELS; return true; } @@ -94,7 +94,7 @@ void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer if (mCoreSyncWaitFrameStart(&context->sync)) { struct fb_var_screeninfo info; ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - info.yoffset = VIDEO_VERTICAL_PIXELS * renderer->odd; + info.yoffset = GBA_VIDEO_VERTICAL_PIXELS * renderer->odd; ioctl(renderer->fb, FBIOPAN_DISPLAY, &info); int arg = 0; @@ -108,7 +108,7 @@ void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer } void mSDLDeinit(struct SDLSoftwareRenderer* renderer) { - munmap(renderer->base[0], VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4); + munmap(renderer->base[0], GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4); struct omapfb_plane_info plane; struct omapfb_mem_info mem; From 98a368daadf32aa8287ee6c7c2ada113d9afe524 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 1 May 2019 22:01:44 -0700 Subject: [PATCH 151/429] CMake: DISABLE_DEPS should disable Discord RPC --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cf2a6113..dc17f1e06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -499,6 +499,7 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") if(DISABLE_DEPS) set(USE_GDB_STUB OFF) + set(USE_DISCORD_RPC OFF) endif() if(USE_EDITLINE) From ba6c00637afd1e0b218c3e5585e65f21e5f21df7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 16:20:49 -0700 Subject: [PATCH 152/429] GBA: Fix RTC on non-standard sized ROMs (fixes #1400) --- CHANGES | 1 + src/gba/gba.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 049717040..b45c44b86 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Emulation fixes: - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 + - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gba/gba.c b/src/gba/gba.c index e144ce45a..4434fc526 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -405,8 +405,6 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->memory.mirroring = false; gba->romCrc32 = doCrc32(gba->memory.rom, gba->memory.romSize); - GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); - GBAVFameDetect(&gba->memory.vfame, gba->memory.rom, gba->memory.romSize); if (popcount32(gba->memory.romSize) != 1) { // This ROM is either a bad dump or homebrew. Emulate flash cart behavior. #ifndef FIXED_ROM_BUFFER @@ -421,6 +419,8 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { if (gba->cpu && gba->memory.activeRegion >= REGION_CART0) { gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); } + GBAHardwareInit(&gba->memory.hw, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); + GBAVFameDetect(&gba->memory.vfame, gba->memory.rom, gba->memory.romSize); // TODO: error check return true; } From 4b3297f9e3352ff111d65783db2d9b44b2e78383 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 16:28:10 -0700 Subject: [PATCH 153/429] CMake: Minor fixes, import fixes --- CMakeLists.txt | 10 ++++++++-- src/platform/qt/CMakeLists.txt | 1 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc17f1e06..90dd400fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -500,6 +500,9 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") if(DISABLE_DEPS) set(USE_GDB_STUB OFF) set(USE_DISCORD_RPC OFF) + set(USE_SQLITE3 OFF) + set(USE_PNG OFF) + set(USE_ZLIB OFF) endif() if(USE_EDITLINE) @@ -868,6 +871,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC}) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) + target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(${BINARY_NAME}-static PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") install(TARGETS ${BINARY_NAME}-static DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) add_dependencies(${BINARY_NAME}-static version-info) @@ -876,8 +880,9 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() - add_dependencies(${BINARY_NAME} version-info) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") + add_dependencies(${BINARY_NAME} version-info) target_link_libraries(${BINARY_NAME} ${DEBUGGER_LIB} ${DEPENDENCY_LIB} ${OS_LIB}) install(TARGETS ${BINARY_NAME} LIBRARY DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME} NAMELINK_SKIP ARCHIVE DESTINATION ${LIBDIR} RUNTIME DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) @@ -929,7 +934,8 @@ endif() if(BUILD_LIBRETRO) file(GLOB RETRO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/libretro/*.c) add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC}) - set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") + add_dependencies(${BINARY_NAME} version-info) + set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) if(MSVC) install(TARGETS ${BINARY_NAME}_libretro RUNTIME DESTINATION ${LIBRETRO_LIBDIR} COMPONENT ${BINARY_NAME}_libretro) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index f467b4f85..a13cd5424 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -215,7 +215,6 @@ if(USE_SQLITE3) endif() if(USE_DISCORD_RPC) - message(STATUS What) list(APPEND QT_LIBRARIES discord-rpc) list(APPEND SOURCE_FILES DiscordCoordinator.cpp) endif() From d5721a26b627cab59804f26b3a046f50b92bd04d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 17:45:04 -0700 Subject: [PATCH 154/429] CMake: More minor import fixes, make sure disabling deps disables building deps too --- CMakeLists.txt | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90dd400fd..12073d165 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -460,6 +460,15 @@ if(BUILD_GLES3) set(BUILD_GLES3 OFF CACHE BOOL "OpenGL|ES 3 not found" FORCE) endif() endif() + +if(DISABLE_DEPS) + set(USE_GDB_STUB OFF) + set(USE_DISCORD_RPC OFF) + set(USE_SQLITE3 OFF) + set(USE_PNG OFF) + set(USE_ZLIB OFF) +endif() + set(WANT_ZLIB ${USE_ZLIB}) set(WANT_PNG ${USE_PNG}) set(WANT_LIBZIP ${USE_LIBZIP}) @@ -497,14 +506,6 @@ file(GLOB DEBUGGER_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/test/*.c) set(FEATURE_SRC) set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") -if(DISABLE_DEPS) - set(USE_GDB_STUB OFF) - set(USE_DISCORD_RPC OFF) - set(USE_SQLITE3 OFF) - set(USE_PNG OFF) - set(USE_ZLIB OFF) -endif() - if(USE_EDITLINE) list(APPEND FEATURES EDITLINE) include_directories(AFTER ${LIBEDIT_INCLUDE_DIRS}) @@ -871,7 +872,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC}) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) - target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) set_target_properties(${BINARY_NAME}-static PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") install(TARGETS ${BINARY_NAME}-static DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) add_dependencies(${BINARY_NAME}-static version-info) @@ -880,7 +881,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() - target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}3) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) From da4f8b7816b728044e935770eba38cfd08f00a6b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 17:52:39 -0700 Subject: [PATCH 155/429] CMake: Grumble, fix typo --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12073d165..072f6d9b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -881,7 +881,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() - target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}3) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) From 3a2215a3469ff2a5cdfb71a25df3728c20f6b343 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 18:27:28 -0700 Subject: [PATCH 156/429] CMake: Fix up installing --- CMakeLists.txt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 072f6d9b6..66c2a4a30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -471,7 +471,6 @@ endif() set(WANT_ZLIB ${USE_ZLIB}) set(WANT_PNG ${USE_PNG}) -set(WANT_LIBZIP ${USE_LIBZIP}) set(WANT_SQLITE3 ${USE_SQLITE3}) set(USE_CMOCKA ${BUILD_SUITE}) @@ -584,11 +583,8 @@ endif() if(WANT_ZLIB AND NOT USE_ZLIB) set(SKIP_INSTALL_ALL ON) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib zlib) - set_property(TARGET zlibstatic PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/zlib;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib) - set_property(TARGET zlib PROPERTY EXCLUDE_FROM_ALL ON) - set_property(TARGET example PROPERTY EXCLUDE_FROM_ALL ON) - set_property(TARGET minigzip PROPERTY EXCLUDE_FROM_ALL ON) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib zlib EXCLUDE_FROM_ALL) + set_target_properties(zlibstatic PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/zlib;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib" POSITION_INDEPENDENT_CODE ON) set(ZLIB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib ${CMAKE_CURRENT_BINARY_DIR}/zlib) set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib ${CMAKE_CURRENT_BINARY_DIR}/zlib) set(ZLIB_LIBRARY zlibstatic) @@ -620,8 +616,8 @@ if(WANT_PNG AND USE_ZLIB AND NOT USE_PNG) if (SWITCH) set(PNG_ARM_NEON "off" CACHE STRING "" FORCE) endif() - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng libpng) - set_property(TARGET png_static PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng libpng EXCLUDE_FROM_ALL) + set_target_properties(png_static PROPERTIES INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/libpng;${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng;${ZLIB_INCLUDE_DIRS}" POSITION_INDEPENDENT_CODE ON) set(PNG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/libpng ${CMAKE_CURRENT_BINARY_DIR}/libpng) list(APPEND DEPENDENCY_LIB png_static) set(USE_PNG ON) @@ -736,7 +732,7 @@ if(USE_ELF) endif() if (USE_DISCORD_RPC) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/discord-rpc discord-rpc) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/discord-rpc discord-rpc EXCLUDE_FROM_ALL) list(APPEND FEATURES DISCORD_RPC) include_directories(AFTER ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/discord-rpc/include) endif() @@ -872,7 +868,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC}) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) - target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) set_target_properties(${BINARY_NAME}-static PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") install(TARGETS ${BINARY_NAME}-static DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) add_dependencies(${BINARY_NAME}-static version-info) @@ -881,7 +877,7 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() - target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) @@ -1025,8 +1021,11 @@ if(BUILD_EXAMPLE) endif() endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/core/flags.h.in ${CMAKE_CURRENT_BINARY_DIR}/flags.h) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT lib${BINARY_NAME}) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/core/flags.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba-util DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT ${BINARY_NAME}-dev) if(WIN32) set(BIN_DIR ".\\") @@ -1172,6 +1171,7 @@ if(BUILD_SHARED) elseif(BUILD_STATIC) cpack_add_component(lib${BINARY_NAME} GROUP dev) endif() +cpack_add_component(${BINARY_NAME}-dev GROUP dev) if(3DS) cpack_add_component(${BINARY_NAME}-3ds GROUP base) From c0ee3cac6662fe161af2d655f09d731cdcf0efe4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 18:33:04 -0700 Subject: [PATCH 157/429] Python: Fix build --- src/platform/python/_builder.h | 2 +- src/platform/python/_builder.py | 2 +- src/platform/python/lib.h | 2 +- src/platform/python/sio.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index 9a0d2b624..7c37e4a18 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -33,7 +33,7 @@ void free(void*); #include -#include "flags.h" +#include #include #include diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 45518fa4f..43bcddc19 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -18,7 +18,7 @@ cppflags.extend(["-I" + incdir, "-I" + srcdir, "-I" + bindir]) ffi.set_source("mgba._pylib", """ #define static #define inline -#include "flags.h" +#include #define OPAQUE_THREADING #include #include diff --git a/src/platform/python/lib.h b/src/platform/python/lib.h index 9c6046a51..0dd8754ed 100644 --- a/src/platform/python/lib.h +++ b/src/platform/python/lib.h @@ -1,4 +1,4 @@ -#include "flags.h" +#include struct VFile; diff --git a/src/platform/python/sio.c b/src/platform/python/sio.c index ab8dd47bd..fbb407831 100644 --- a/src/platform/python/sio.c +++ b/src/platform/python/sio.c @@ -3,7 +3,7 @@ * 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 "flags.h" +#include #define CREATE_SHIM(PLAT, NAME, RETURN) \ RETURN _py ## PLAT ## SIOPythonDriver ## NAME (void* driver); \ From 6f31fca58f019ebfd83a8232c6805cc8b3c05bd7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 19:15:49 -0700 Subject: [PATCH 158/429] CMake: Improved library-style building --- CMakeLists.txt | 107 +++++++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66c2a4a30..283598a91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,48 +18,67 @@ if(NOT MSVC) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146") endif() -set(USE_DEBUGGERS ON CACHE BOOL "Whether or not to enable the debugging infrastructure") -if (NOT WIN32) - set(USE_EDITLINE ON CACHE BOOL "Whether or not to enable the CLI-mode debugger") + +if(NOT DEFINED LIBMGBA_ONLY) + get_directory_property(LIBMGBA_ONLY EXCLUDE_FROM_ALL) endif() -set(USE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger") -set(USE_FFMPEG ON CACHE BOOL "Whether or not to enable FFmpeg support") -set(USE_ZLIB ON CACHE BOOL "Whether or not to enable zlib support") -set(USE_MINIZIP ON CACHE BOOL "Whether or not to enable external minizip support") -set(USE_PNG ON CACHE BOOL "Whether or not to enable PNG support") -set(USE_LIBZIP ON CACHE BOOL "Whether or not to enable LIBZIP support") -set(USE_MAGICK ON CACHE BOOL "Whether or not to enable ImageMagick support") -set(USE_SQLITE3 ON CACHE BOOL "Whether or not to enable SQLite3 support") -set(USE_ELF ON CACHE BOOL "Whether or not to enable ELF support") -set(M_CORE_GBA ON CACHE BOOL "Build Game Boy Advance core") -set(M_CORE_GB ON CACHE BOOL "Build Game Boy core") -set(USE_LZMA ON CACHE BOOL "Whether or not to enable 7-Zip support") -set(USE_DISCORD_RPC ON CACHE BOOL "Whether or not to enable Discord RPC support") -set(ENABLE_SCRIPTING ON CACHE BOOL "Whether or not to enable scripting support") -set(BUILD_QT ON CACHE BOOL "Build Qt frontend") -set(BUILD_SDL ON CACHE BOOL "Build SDL frontend") -set(BUILD_LIBRETRO OFF CACHE BOOL "Build libretro core") -if(APPLE) - set(BUILD_OPENEMU OFF CACHE BOOL "Build OpenEmu core") -endif() -set(BUILD_PERF OFF CACHE BOOL "Build performance profiling tool") -set(BUILD_TEST OFF CACHE BOOL "Build testing harness") -set(BUILD_SUITE OFF CACHE BOOL "Build test suite") -set(BUILD_EXAMPLE OFF CACHE BOOL "Build example frontends") -set(BUILD_PYTHON OFF CACHE BOOL "Build Python bindings") -set(BUILD_STATIC OFF CACHE BOOL "Build a static library") -set(BUILD_SHARED ON CACHE BOOL "Build a shared library") -set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") -set(BUILD_GL ON CACHE BOOL "Build with OpenGL") -set(BUILD_GLES2 OFF CACHE BOOL "Build with OpenGL|ES 2") -set(BUILD_GLES3 OFF CACHE BOOL "Build with OpenGL|ES 3") -set(USE_EPOXY ON CACHE STRING "Build with libepoxy") -set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") -set(DISTBUILD OFF CACHE BOOL "Build distribution packages") -if(WIN32) - set(WIN32_UNIX_PATHS OFF CACHE BOOL "Use Unix-like paths") - mark_as_advanced(WIN32_UNIX_PATHS) + +if(NOT LIBMGBA_ONLY) + set(USE_DEBUGGERS ON CACHE BOOL "Whether or not to enable the debugging infrastructure") + if (NOT WIN32) + set(USE_EDITLINE ON CACHE BOOL "Whether or not to enable the CLI-mode debugger") + endif() + set(USE_GDB_STUB ON CACHE BOOL "Whether or not to enable the GDB stub ARM debugger") + set(USE_FFMPEG ON CACHE BOOL "Whether or not to enable FFmpeg support") + set(USE_ZLIB ON CACHE BOOL "Whether or not to enable zlib support") + set(USE_MINIZIP ON CACHE BOOL "Whether or not to enable external minizip support") + set(USE_PNG ON CACHE BOOL "Whether or not to enable PNG support") + set(USE_LIBZIP ON CACHE BOOL "Whether or not to enable LIBZIP support") + set(USE_MAGICK ON CACHE BOOL "Whether or not to enable ImageMagick support") + set(USE_SQLITE3 ON CACHE BOOL "Whether or not to enable SQLite3 support") + set(USE_ELF ON CACHE BOOL "Whether or not to enable ELF support") + set(M_CORE_GBA ON CACHE BOOL "Build Game Boy Advance core") + set(M_CORE_GB ON CACHE BOOL "Build Game Boy core") + set(USE_LZMA ON CACHE BOOL "Whether or not to enable 7-Zip support") + set(USE_DISCORD_RPC ON CACHE BOOL "Whether or not to enable Discord RPC support") + set(ENABLE_SCRIPTING ON CACHE BOOL "Whether or not to enable scripting support") + set(BUILD_QT ON CACHE BOOL "Build Qt frontend") + set(BUILD_SDL ON CACHE BOOL "Build SDL frontend") + set(BUILD_LIBRETRO OFF CACHE BOOL "Build libretro core") + if(APPLE) + set(BUILD_OPENEMU OFF CACHE BOOL "Build OpenEmu core") + endif() + set(BUILD_PERF OFF CACHE BOOL "Build performance profiling tool") + set(BUILD_TEST OFF CACHE BOOL "Build testing harness") + set(BUILD_SUITE OFF CACHE BOOL "Build test suite") + set(BUILD_EXAMPLE OFF CACHE BOOL "Build example frontends") + set(BUILD_PYTHON OFF CACHE BOOL "Build Python bindings") + set(BUILD_STATIC OFF CACHE BOOL "Build a static library") + set(BUILD_SHARED ON CACHE BOOL "Build a shared library") + set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") + set(BUILD_GL ON CACHE BOOL "Build with OpenGL") + set(BUILD_GLES2 OFF CACHE BOOL "Build with OpenGL|ES 2") + set(BUILD_GLES3 OFF CACHE BOOL "Build with OpenGL|ES 3") + set(USE_EPOXY ON CACHE STRING "Build with libepoxy") + set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") + set(DISTBUILD OFF CACHE BOOL "Build distribution packages") + if(WIN32) + set(WIN32_UNIX_PATHS OFF CACHE BOOL "Use Unix-like paths") + mark_as_advanced(WIN32_UNIX_PATHS) + endif() +else() + set(DISABLE_FRONTENDS ON) + set(DISABLE_DEPS ON) + set(BUILD_STATIC ON) + set(BUILD_SHARED OFF) + if(NOT DEFINED M_CORE_GBA) + set(M_CORE_GBA ON) + endif() + if(NOT DEFINED M_CORE_GB) + set(M_CORE_GB ON) + endif() endif() + file(GLOB ARM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/*.c) file(GLOB ARM_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/test/*.c) file(GLOB LR35902_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/*.c) @@ -91,7 +110,7 @@ source_group("GBA board" FILES ${GBA_SRC} ${GBA_RENDERER_SRC} ${GBA_SIO_SRC}) source_group("GBA extra" FILES ${GBA_CHEATS_SRC} ${GBA_RR_SRC}) source_group("GB board" FILES ${GB_SRC} ${GB_SIO_SRC}) source_group("Utilities" FILES ${UTIL_SRC}) -include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/include) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type (e.g. Release, RelWithDebInfo, or Debug)" FORCE) @@ -341,7 +360,9 @@ endif() check_include_files("xlocale.h" HAVE_XLOCALE) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") check_function_exists(snprintf_l HAVE_SNPRINTF_L) - if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + if(ANDROID AND ANDROID_NDK_MAJOR GREATER_EQUAL 14) + set(HAVE_STRTOF_L ON) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") # The strtof_l on Linux not actually exposed nor actually strtof_l set(HAVE_STRTOF_L OFF) else() @@ -1247,7 +1268,7 @@ else() set(SUMMARY_ZIP OFF) endif() -if(NOT QUIET) +if(NOT QUIET AND NOT LIBMGBA_ONLY) message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Platforms:") message(STATUS " Game Boy Advance: ${M_CORE_GBA}") From 3a6756b3991dab1de69cafde92f196c0adddac44 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 2 May 2019 19:23:02 -0700 Subject: [PATCH 159/429] CMake: Fix build on CMake < 3.7 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 283598a91..63171dfd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,7 +360,7 @@ endif() check_include_files("xlocale.h" HAVE_XLOCALE) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") check_function_exists(snprintf_l HAVE_SNPRINTF_L) - if(ANDROID AND ANDROID_NDK_MAJOR GREATER_EQUAL 14) + if(ANDROID AND ANDROID_NDK_MAJOR GREATER 13) set(HAVE_STRTOF_L ON) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") # The strtof_l on Linux not actually exposed nor actually strtof_l From 36ad461ee002b199111baa68b57122679c443894 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 4 May 2019 22:41:52 +0100 Subject: [PATCH 160/429] SDL: Support resizing the window when using the SDL1 GL renderer --- src/platform/sdl/gl-common.c | 4 ++-- src/platform/sdl/gl-sdl.c | 8 ++++++-- src/platform/sdl/gles2-sdl.c | 8 ++++++-- src/platform/sdl/sdl-events.c | 6 ++++++ src/platform/sdl/sdl-events.h | 5 ++++- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 2ec8227ca..e4d400b29 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -51,9 +51,9 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) { #else SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); #ifdef COLOR_16_BIT - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | (SDL_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->fullscreen)); #else - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | (SDL_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->fullscreen)); #endif SDL_WM_SetCaption(projectName, ""); #endif diff --git a/src/platform/sdl/gl-sdl.c b/src/platform/sdl/gl-sdl.c index de572db41..38e0a2164 100644 --- a/src/platform/sdl/gl-sdl.c +++ b/src/platform/sdl/gl-sdl.c @@ -52,14 +52,18 @@ void mSDLGLRunloop(struct mSDLRenderer* renderer, void* user) { while (mCoreThreadIsActive(context)) { while (SDL_PollEvent(&event)) { mSDLHandleEvent(context, &renderer->player, &event); -#if SDL_VERSION_ATLEAST(2, 0, 0) // Event handling can change the size of the screen if (renderer->player.windowUpdated) { +#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); +#else + renderer->viewportWidth = renderer->player.newWidth; + renderer->viewportHeight = renderer->player.newHeight; + mSDLGLCommonInit(renderer); +#endif mSDLGLDoViewport(renderer->viewportWidth, renderer->viewportHeight, v); renderer->player.windowUpdated = 0; } -#endif } renderer->core->desiredVideoDimensions(renderer->core, &renderer->width, &renderer->height); if (renderer->width != v->width || renderer->height != v->height) { diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 409e94183..582df9f9b 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -128,14 +128,18 @@ void mSDLGLES2Runloop(struct mSDLRenderer* renderer, void* user) { while (mCoreThreadIsActive(context)) { while (SDL_PollEvent(&event)) { mSDLHandleEvent(context, &renderer->player, &event); -#if SDL_VERSION_ATLEAST(2, 0, 0) // Event handling can change the size of the screen if (renderer->player.windowUpdated) { +#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); +#else + renderer->viewportWidth = renderer->player.newWidth; + renderer->viewportHeight = renderer->player.newHeight; + mSDLGLCommonInit(renderer); +#endif mSDLGLDoViewport(renderer->viewportWidth, renderer->viewportHeight, v); renderer->player.windowUpdated = 0; } -#endif } if (mCoreSyncWaitFrameStart(&context->impl->sync)) { diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 9f4b218b2..93243a1db 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -601,6 +601,12 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, case SDL_WINDOWEVENT: _mSDLHandleWindowEvent(sdlContext, &event->window); break; +#else + case SDL_VIDEORESIZE: + sdlContext->newWidth = event->resize.w; + sdlContext->newHeight = event->resize.h; + sdlContext->windowUpdated = 1; + break; #endif case SDL_KEYDOWN: case SDL_KEYUP: diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index c9d7b386f..7df0672c3 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -63,10 +63,10 @@ struct mSDLPlayer { size_t playerId; struct mInputMap* bindings; struct SDL_JoystickCombo* joystick; + int windowUpdated; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Window* window; int fullscreen; - int windowUpdated; struct mSDLRumble { struct mRumble d; @@ -76,6 +76,9 @@ struct mSDLPlayer { float activeLevel; struct CircleBuffer history; } rumble; +#else + int newWidth; + int newHeight; #endif struct mSDLRotation { From 46c135b4f90d2ad312f5129db15fbbac7bf083d7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 May 2019 15:49:38 -0700 Subject: [PATCH 161/429] FFmpeg: Improve initialization reliability and cleanup --- CHANGES | 1 + src/feature/ffmpeg/ffmpeg-encoder.c | 224 ++++++++++++++++------------ 2 files changed, 132 insertions(+), 93 deletions(-) diff --git a/CHANGES b/CHANGES index b45c44b86..d8d768e2d 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Other fixes: - All: Fix several memory leaks - LR35902: Fix trailing whitespace in disassembly - Qt: Fix adjusting magnification in tile viewer when not fitting to window + - FFmpeg: Improve initialization reliability and cleanup Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index c17bc5b8c..6fae174e6 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -42,19 +42,25 @@ void FFmpegEncoderInit(struct FFmpegEncoder* encoder) { encoder->d.postAudioFrame = _ffmpegPostAudioFrame; encoder->d.postAudioBuffer = 0; - encoder->audioCodec = 0; - encoder->videoCodec = 0; - encoder->containerFormat = 0; + encoder->audioCodec = NULL; + encoder->videoCodec = NULL; + encoder->containerFormat = NULL; FFmpegEncoderSetAudio(encoder, "flac", 0); FFmpegEncoderSetVideo(encoder, "png", 0); FFmpegEncoderSetContainer(encoder, "matroska"); FFmpegEncoderSetDimensions(encoder, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); encoder->iwidth = GBA_VIDEO_HORIZONTAL_PIXELS; encoder->iheight = GBA_VIDEO_VERTICAL_PIXELS; - encoder->resampleContext = 0; - encoder->absf = 0; - encoder->context = 0; + encoder->resampleContext = NULL; + encoder->absf = NULL; + encoder->context = NULL; encoder->scaleContext = NULL; + encoder->audioStream = NULL; + encoder->audioFrame = NULL; + encoder->audioBuffer = NULL; + encoder->postaudioBuffer = NULL; + encoder->videoStream = NULL; + encoder->videoFrame = NULL; } bool FFmpegEncoderSetAudio(struct FFmpegEncoder* encoder, const char* acodec, unsigned abr) { @@ -198,7 +204,11 @@ bool FFmpegEncoderVerifyContainer(struct FFmpegEncoder* encoder) { bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec); AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec); - if ((encoder->audioCodec && !acodec) || !vcodec || !FFmpegEncoderVerifyContainer(encoder)) { + if ((encoder->audioCodec && !acodec) || (encoder->videoCodec && !vcodec) || !FFmpegEncoderVerifyContainer(encoder)) { + return false; + } + + if (encoder->context) { return false; } @@ -238,8 +248,12 @@ bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { encoder->audio->flags |= CODEC_FLAG_GLOBAL_HEADER; #endif } - avcodec_open2(encoder->audio, acodec, &opts); + int res = avcodec_open2(encoder->audio, acodec, &opts); av_dict_free(&opts); + if (res < 0) { + FFmpegEncoderClose(encoder); + return false; + } #if LIBAVCODEC_VERSION_MAJOR >= 55 encoder->audioFrame = av_frame_alloc(); #else @@ -289,127 +303,151 @@ bool FFmpegEncoderOpen(struct FFmpegEncoder* encoder, const char* outfile) { #endif } + if (vcodec) { #ifdef FFMPEG_USE_CODECPAR - encoder->videoStream = avformat_new_stream(encoder->context, NULL); - encoder->video = avcodec_alloc_context3(vcodec); + encoder->videoStream = avformat_new_stream(encoder->context, NULL); + encoder->video = avcodec_alloc_context3(vcodec); #else - encoder->videoStream = avformat_new_stream(encoder->context, vcodec); - encoder->video = encoder->videoStream->codec; + encoder->videoStream = avformat_new_stream(encoder->context, vcodec); + encoder->video = encoder->videoStream->codec; #endif - encoder->video->bit_rate = encoder->videoBitrate; - encoder->video->width = encoder->width; - encoder->video->height = encoder->height; - encoder->video->time_base = (AVRational) { VIDEO_TOTAL_LENGTH, GBA_ARM7TDMI_FREQUENCY }; - encoder->video->framerate = (AVRational) { GBA_ARM7TDMI_FREQUENCY, VIDEO_TOTAL_LENGTH }; - encoder->video->pix_fmt = encoder->pixFormat; - encoder->video->gop_size = 60; - encoder->video->max_b_frames = 3; - if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { + encoder->video->bit_rate = encoder->videoBitrate; + encoder->video->width = encoder->width; + encoder->video->height = encoder->height; + encoder->video->time_base = (AVRational) { VIDEO_TOTAL_LENGTH, GBA_ARM7TDMI_FREQUENCY }; + encoder->video->framerate = (AVRational) { GBA_ARM7TDMI_FREQUENCY, VIDEO_TOTAL_LENGTH }; + encoder->video->pix_fmt = encoder->pixFormat; + encoder->video->gop_size = 60; + encoder->video->max_b_frames = 3; + if (encoder->context->oformat->flags & AVFMT_GLOBALHEADER) { #ifdef AV_CODEC_FLAG_GLOBAL_HEADER - encoder->video->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + encoder->video->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; #else - encoder->video->flags |= CODEC_FLAG_GLOBAL_HEADER; + encoder->video->flags |= CODEC_FLAG_GLOBAL_HEADER; #endif - } - - if (encoder->video->codec->id == AV_CODEC_ID_H264 && - (strcasecmp(encoder->containerFormat, "mp4") || - strcasecmp(encoder->containerFormat, "m4v") || - strcasecmp(encoder->containerFormat, "mov"))) { - // QuickTime and a few other things require YUV420 - encoder->video->pix_fmt = AV_PIX_FMT_YUV420P; - } - - if (strcmp(vcodec->name, "libx264") == 0) { - // Try to adaptively figure out when you can use a slower encoder - if (encoder->width * encoder->height > 1000000) { - av_opt_set(encoder->video->priv_data, "preset", "superfast", 0); - } else if (encoder->width * encoder->height > 500000) { - av_opt_set(encoder->video->priv_data, "preset", "veryfast", 0); - } else { - av_opt_set(encoder->video->priv_data, "preset", "faster", 0); } - if (encoder->videoBitrate == 0) { - av_opt_set(encoder->video->priv_data, "crf", "0", 0); + + if (encoder->video->codec->id == AV_CODEC_ID_H264 && + (strcasecmp(encoder->containerFormat, "mp4") || + strcasecmp(encoder->containerFormat, "m4v") || + strcasecmp(encoder->containerFormat, "mov"))) { + // QuickTime and a few other things require YUV420 + encoder->video->pix_fmt = AV_PIX_FMT_YUV420P; + } + + if (strcmp(vcodec->name, "libx264") == 0) { + // Try to adaptively figure out when you can use a slower encoder + if (encoder->width * encoder->height > 1000000) { + av_opt_set(encoder->video->priv_data, "preset", "superfast", 0); + } else if (encoder->width * encoder->height > 500000) { + av_opt_set(encoder->video->priv_data, "preset", "veryfast", 0); + } else { + av_opt_set(encoder->video->priv_data, "preset", "faster", 0); + } + if (encoder->videoBitrate == 0) { + av_opt_set(encoder->video->priv_data, "crf", "0", 0); + encoder->video->pix_fmt = AV_PIX_FMT_YUV444P; + } + } + if (strcmp(vcodec->name, "libvpx-vp9") == 0 && encoder->videoBitrate == 0) { + av_opt_set(encoder->video->priv_data, "lossless", "1", 0); encoder->video->pix_fmt = AV_PIX_FMT_YUV444P; } - } - if (strcmp(vcodec->name, "libvpx-vp9") == 0 && encoder->videoBitrate == 0) { - av_opt_set(encoder->video->priv_data, "lossless", "1", 0); - encoder->video->pix_fmt = AV_PIX_FMT_YUV444P; - } - avcodec_open2(encoder->video, vcodec, 0); + if (avcodec_open2(encoder->video, vcodec, 0) < 0) { + FFmpegEncoderClose(encoder); + return false; + } #if LIBAVCODEC_VERSION_MAJOR >= 55 - encoder->videoFrame = av_frame_alloc(); + encoder->videoFrame = av_frame_alloc(); #else - encoder->videoFrame = avcodec_alloc_frame(); + encoder->videoFrame = avcodec_alloc_frame(); #endif - encoder->videoFrame->format = encoder->video->pix_fmt; - encoder->videoFrame->width = encoder->video->width; - encoder->videoFrame->height = encoder->video->height; - encoder->videoFrame->pts = 0; - _ffmpegSetVideoDimensions(&encoder->d, encoder->iwidth, encoder->iheight); - av_image_alloc(encoder->videoFrame->data, encoder->videoFrame->linesize, encoder->video->width, encoder->video->height, encoder->video->pix_fmt, 32); + encoder->videoFrame->format = encoder->video->pix_fmt; + encoder->videoFrame->width = encoder->video->width; + encoder->videoFrame->height = encoder->video->height; + encoder->videoFrame->pts = 0; + _ffmpegSetVideoDimensions(&encoder->d, encoder->iwidth, encoder->iheight); + av_image_alloc(encoder->videoFrame->data, encoder->videoFrame->linesize, encoder->video->width, encoder->video->height, encoder->video->pix_fmt, 32); #ifdef FFMPEG_USE_CODECPAR - avcodec_parameters_from_context(encoder->videoStream->codecpar, encoder->video); + avcodec_parameters_from_context(encoder->videoStream->codecpar, encoder->video); #endif + } - if (avio_open(&encoder->context->pb, outfile, AVIO_FLAG_WRITE) < 0) { + if (avio_open(&encoder->context->pb, outfile, AVIO_FLAG_WRITE) < 0 || avformat_write_header(encoder->context, 0) < 0) { + FFmpegEncoderClose(encoder); return false; } - return avformat_write_header(encoder->context, 0) >= 0; + return true; } void FFmpegEncoderClose(struct FFmpegEncoder* encoder) { - if (!encoder->context) { - return; + if (encoder->context && encoder->context->pb) { + av_write_trailer(encoder->context); + avio_close(encoder->context->pb); } - av_write_trailer(encoder->context); - avio_close(encoder->context->pb); - if (encoder->audioCodec) { + if (encoder->postaudioBuffer) { av_free(encoder->postaudioBuffer); - if (encoder->audioBuffer) { - av_free(encoder->audioBuffer); - } + encoder->postaudioBuffer = NULL; + } + if (encoder->audioBuffer) { + av_free(encoder->audioBuffer); + encoder->audioBuffer = NULL; + } + + if (encoder->audioFrame) { #if LIBAVCODEC_VERSION_MAJOR >= 55 av_frame_free(&encoder->audioFrame); #else avcodec_free_frame(&encoder->audioFrame); #endif + } + if (encoder->audio) { avcodec_close(encoder->audio); - - if (encoder->resampleContext) { -#ifdef USE_LIBAVRESAMPLE - avresample_close(encoder->resampleContext); -#else - swr_free(&encoder->resampleContext); -#endif - } - - if (encoder->absf) { -#ifdef FFMPEG_USE_NEW_BSF - av_bsf_free(&encoder->absf); -#else - av_bitstream_filter_close(encoder->absf); - encoder->absf = 0; -#endif - } + encoder->audio = NULL; } -#if LIBAVCODEC_VERSION_MAJOR >= 55 - av_frame_free(&encoder->videoFrame); + if (encoder->resampleContext) { +#ifdef USE_LIBAVRESAMPLE + avresample_close(encoder->resampleContext); + encoder->resampleContext = NULL; #else - avcodec_free_frame(&encoder->videoFrame); + swr_free(&encoder->resampleContext); #endif - avcodec_close(encoder->video); + } - sws_freeContext(encoder->scaleContext); - encoder->scaleContext = NULL; + if (encoder->absf) { +#ifdef FFMPEG_USE_NEW_BSF + av_bsf_free(&encoder->absf); +#else + av_bitstream_filter_close(encoder->absf); + encoder->absf = NULL; +#endif + } - avformat_free_context(encoder->context); - encoder->context = 0; + if (encoder->videoFrame) { +#if LIBAVCODEC_VERSION_MAJOR >= 55 + av_frame_free(&encoder->videoFrame); +#else + avcodec_free_frame(&encoder->videoFrame); +#endif + } + + if (encoder->video) { + avcodec_close(encoder->video); + encoder->video = NULL; + } + + if (encoder->scaleContext) { + sws_freeContext(encoder->scaleContext); + encoder->scaleContext = NULL; + } + + if (encoder->context) { + avformat_free_context(encoder->context); + encoder->context = NULL; + } } bool FFmpegEncoderIsOpen(struct FFmpegEncoder* encoder) { From 4dbebe870295b1d222f9df9672c2aa614ebda418 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 May 2019 16:03:18 -0700 Subject: [PATCH 162/429] Qt: Open a message box for Qt frontend errors --- CHANGES | 1 + src/platform/qt/LogController.cpp | 9 +++++++++ src/platform/qt/LogController.h | 1 + 3 files changed, 11 insertions(+) diff --git a/CHANGES b/CHANGES index d8d768e2d..4cd280434 100644 --- a/CHANGES +++ b/CHANGES @@ -52,6 +52,7 @@ Misc: - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) - Debugger: Make tracing compatible with breakpoints/watchpoints - Debugger: Print breakpoint/watchpoint number when inserting + - Qt: Open a message box for Qt frontend errors 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/LogController.cpp b/src/platform/qt/LogController.cpp index 5ad220ad6..e6f80e0b1 100644 --- a/src/platform/qt/LogController.cpp +++ b/src/platform/qt/LogController.cpp @@ -5,11 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "LogController.h" +#include + #include "ConfigController.h" using namespace QGBA; LogController LogController::s_global(mLOG_ALL); +int LogController::s_qtCat{-1}; LogController::LogController(int levels, QObject* parent) : QObject(parent) @@ -18,6 +21,7 @@ LogController::LogController(int levels, QObject* parent) mLogFilterSet(&m_filter, "gba.bios", mLOG_STUB | mLOG_FATAL); mLogFilterSet(&m_filter, "core.status", mLOG_ALL & ~mLOG_DEBUG); m_filter.defaultLevels = levels; + s_qtCat = mLogCategoryById("platform.qt"); if (this != &s_global) { connect(&s_global, &LogController::logPosted, this, &LogController::postLog); @@ -65,6 +69,11 @@ void LogController::postLog(int level, int category, const QString& string) { *m_logStream << line << endl; } } + if (category == s_qtCat && level == mLOG_ERROR && this == &s_global) { + QMessageBox* dialog = new QMessageBox(QMessageBox::Critical, tr("An error occurred"), string, QMessageBox::Ok); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + } emit logPosted(level, category, string); } diff --git a/src/platform/qt/LogController.h b/src/platform/qt/LogController.h index a06f7bf47..548be8b4d 100644 --- a/src/platform/qt/LogController.h +++ b/src/platform/qt/LogController.h @@ -85,6 +85,7 @@ private: std::unique_ptr m_logStream; static LogController s_global; + static int s_qtCat; }; #define LOG(C, L) (*LogController::global())(mLOG_ ## L, _mLOG_CAT_ ## C) From 609d5314ec8090c5ede27cb07d0d1569463a570a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 May 2019 19:18:11 -0700 Subject: [PATCH 163/429] Wii: Fix aspect ratio (fixes #500) --- CHANGES | 1 + src/platform/wii/main.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 4cd280434..8a78e543f 100644 --- a/CHANGES +++ b/CHANGES @@ -36,6 +36,7 @@ Other fixes: - LR35902: Fix trailing whitespace in disassembly - Qt: Fix adjusting magnification in tile viewer when not fitting to window - FFmpeg: Improve initialization reliability and cleanup + - Wii: Fix aspect ratio (fixes mgba.io/i/500) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index dbdb467a9..5ab370bbf 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -102,7 +102,7 @@ static struct mRotationSource rotation; static GXRModeObj* vmode; static float wAdjust; static float hAdjust; -static float wStretch = 1.0f; +static float wStretch = 0.9f; static float hStretch = 0.9f; static float guiScale = GUI_SCALE; static Mtx model, view, modelview; @@ -195,6 +195,9 @@ static void reconfigureScreen(struct mGUIRunner* runner) { break; } + vmode->viWidth = 704; + vmode->viXOrigin = 8; + VIDEO_SetBlack(true); VIDEO_Configure(vmode); @@ -319,7 +322,7 @@ int main(int argc, char* argv[]) { struct mGUIRunner runner = { .params = { - 720, 480, + 640, 480, font, "", _drawStart, _drawEnd, _pollInput, _pollCursor, From bf8fde59c62cd6cec4a6d37e25f226bf5d40173e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2019 14:22:10 -0700 Subject: [PATCH 164/429] Qt: Revamp actions --- src/platform/qt/Action.cpp | 106 ++++ src/platform/qt/Action.h | 73 +++ src/platform/qt/ActionMapper.cpp | 162 +++++ src/platform/qt/ActionMapper.h | 85 +++ src/platform/qt/CMakeLists.txt | 3 + src/platform/qt/ConfigController.cpp | 71 +-- src/platform/qt/ConfigController.h | 17 +- src/platform/qt/ShortcutController.cpp | 470 +++++---------- src/platform/qt/ShortcutController.h | 166 +++--- src/platform/qt/ShortcutModel.cpp | 138 +++++ src/platform/qt/ShortcutModel.h | 50 ++ src/platform/qt/ShortcutView.cpp | 41 +- src/platform/qt/ShortcutView.h | 2 + src/platform/qt/Window.cpp | 787 ++++++++++--------------- src/platform/qt/Window.h | 23 +- 15 files changed, 1243 insertions(+), 951 deletions(-) create mode 100644 src/platform/qt/Action.cpp create mode 100644 src/platform/qt/Action.h create mode 100644 src/platform/qt/ActionMapper.cpp create mode 100644 src/platform/qt/ActionMapper.h create mode 100644 src/platform/qt/ShortcutModel.cpp create mode 100644 src/platform/qt/ShortcutModel.h diff --git a/src/platform/qt/Action.cpp b/src/platform/qt/Action.cpp new file mode 100644 index 000000000..0fe4be787 --- /dev/null +++ b/src/platform/qt/Action.cpp @@ -0,0 +1,106 @@ +/* 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/. */ +#include "Action.h" + +using namespace QGBA; + +Action::Action(QObject* parent) + : QObject(parent) +{ +} + +Action::Action(Function function, const QString& name, const QString& visibleName, QObject* parent) + : QObject(parent) + , m_function(function) + , m_name(name) + , m_visibleName(visibleName) +{ +} + +Action::Action(Action::BooleanFunction function, const QString& name, const QString& visibleName, QObject* parent) + : QObject(parent) + , m_booleanFunction(function) + , m_name(name) + , m_visibleName(visibleName) +{ +} + +Action::Action(const QString& name, const QString& visibleName, QObject* parent) + : QObject(parent) + , m_name(name) + , m_visibleName(visibleName) +{ +} + +Action::Action(const Action& other) + : QObject(other.parent()) + , m_enabled(other.m_enabled) + , m_active(other.m_active) + , m_function(other.m_function) + , m_booleanFunction(other.m_booleanFunction) + , m_name(other.m_name) + , m_visibleName(other.m_visibleName) +{ +} + +Action::Action(Action& other) + : QObject(other.parent()) + , m_enabled(other.m_enabled) + , m_active(other.m_active) + , m_function(other.m_function) + , m_booleanFunction(other.m_booleanFunction) + , m_name(other.m_name) + , m_visibleName(other.m_visibleName) +{ +} + +void Action::connect(Function func) { + m_booleanFunction = {}; + m_function = func; +} + +void Action::trigger(bool active) { + if (!m_enabled) { + return; + } + + if (m_function && active) { + m_function(); + } + if (m_booleanFunction) { + m_booleanFunction(active); + } + + m_active = active; + emit activated(active); +} + +void Action::setEnabled(bool e) { + if (m_enabled == e) { + return; + } + m_enabled = e; + emit enabled(e); +} + +void Action::setActive(bool a) { + if (m_active == a) { + return; + } + m_active = a; + emit activated(a); +} + +Action& Action::operator=(const Action& other) { + setParent(other.parent()); + m_enabled = other.m_enabled; + m_active = other.m_active; + m_function = other.m_function; + m_booleanFunction = other.m_booleanFunction; + m_name = other.m_name; + m_visibleName = other.m_visibleName; + return *this; +} diff --git a/src/platform/qt/Action.h b/src/platform/qt/Action.h new file mode 100644 index 000000000..3d1e24c5f --- /dev/null +++ b/src/platform/qt/Action.h @@ -0,0 +1,73 @@ +/* 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/. */ +#pragma once + +#include + +#include + +namespace QGBA { + +class Action : public QObject { +Q_OBJECT + +public: + typedef std::function Function; + typedef std::function BooleanFunction; + + Action(Function, const QString& name, const QString& visibleName, QObject* parent = nullptr); + Action(BooleanFunction, const QString& name, const QString& visibleName, QObject* parent = nullptr); + Action(const QString& name, const QString& visibleName, QObject* parent = nullptr); + + Action(QObject* parent = nullptr); + Action(Action&); + Action(const Action&); + + Function action() const { return m_function; } + BooleanFunction booleanAction() const { return m_booleanFunction; } + + const QString& name() const { return m_name; } + const QString& visibleName() const { return m_visibleName; } + + bool operator==(const Action& other) const { + if (m_name.isNull()) { + return this == &other; + } + return m_name == other.m_name; + } + + void connect(Function); + + bool isEnabled() const { return m_enabled; } + bool isActive() const { return m_active; } + bool isExclusive() const { return m_exclusive; } + + void setExclusive(bool exclusive = true) { m_exclusive = exclusive; } + + Action& operator=(const Action&); + +public slots: + void trigger(bool = true); + void setEnabled(bool = true); + void setActive(bool = true); + +signals: + void enabled(bool); + void activated(bool); + +private: + bool m_enabled = true; + bool m_active = false; + bool m_exclusive = false; + + Function m_function; + BooleanFunction m_booleanFunction; + + QString m_name; + QString m_visibleName; +}; + +} diff --git a/src/platform/qt/ActionMapper.cpp b/src/platform/qt/ActionMapper.cpp new file mode 100644 index 000000000..e03c4dd1a --- /dev/null +++ b/src/platform/qt/ActionMapper.cpp @@ -0,0 +1,162 @@ +/* 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/. */ +#include "ActionMapper.h" + +#include "ConfigController.h" +#include "ShortcutController.h" + +#include +#include + +using namespace QGBA; + +void ActionMapper::addMenu(const QString& visibleName, const QString& name, const QString& parent) { + QString mname(QString(".%1").arg(name)); + m_menus[parent].append(mname); + m_reverseMenus[mname] = parent; + m_menuNames[name] = visibleName; +} + +void ActionMapper::addHiddenMenu(const QString& visibleName, const QString& name, const QString& parent) { + m_hiddenActions.insert(QString(".%1").arg(name)); + addMenu(visibleName, name, parent); +} + +void ActionMapper::clearMenu(const QString& name) { + m_menus[name].clear(); + emit menuCleared(name); +} + +void ActionMapper::rebuildMenu(QMenuBar* menubar, const ShortcutController& shortcuts) { + menubar->clear(); + for (const QString& m : m_menus[{}]) { + if (m_hiddenActions.contains(m)) { + continue; + } + QString menu = m.mid(1); + QMenu* qmenu = menubar->addMenu(m_menuNames[menu]); + + rebuildMenu(menu, qmenu, shortcuts); + } +} + +void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, const ShortcutController& shortcuts) { + for (const QString& actionName : m_menus[menu]) { + if (actionName.isNull()) { + qmenu->addSeparator(); + continue; + } + if (m_hiddenActions.contains(actionName)) { + continue; + } + if (actionName[0] == '.') { + QString name = actionName.mid(1); + QMenu* newMenu = qmenu->addMenu(m_menuNames[name]); + rebuildMenu(name, newMenu, shortcuts); + continue; + } + Action* action = &m_actions[actionName]; + QAction* qaction = qmenu->addAction(action->visibleName()); + qaction->setEnabled(action->isEnabled()); + if (action->isExclusive() || action->booleanAction()) { + qaction->setCheckable(true); + } + if (action->isActive()) { + qaction->setChecked(true); + } + const Shortcut* shortcut = shortcuts.shortcut(actionName); + if (shortcut && shortcut->shortcut() > 0) { + qaction->setShortcut(QKeySequence(shortcut->shortcut())); + } else if (!m_defaultShortcuts[actionName].isEmpty()) { + qaction->setShortcut(m_defaultShortcuts[actionName][0]); + } + QObject::connect(qaction, &QAction::triggered, [qaction, action](bool enabled) { + if (qaction->isCheckable()) { + action->trigger(enabled); + } else { + action->trigger(); + } + }); + QObject::connect(action, &Action::enabled, qaction, &QAction::setEnabled); + QObject::connect(action, &Action::activated, qaction, &QAction::setChecked); + QObject::connect(action, &Action::destroyed, qaction, &QAction::deleteLater); + if (shortcut) { + QObject::connect(shortcut, &Shortcut::shortcutChanged, qaction, [qaction](int shortcut) { + qaction->setShortcut(QKeySequence(shortcut)); + }); + } + } +} + +void ActionMapper::addSeparator(const QString& menu) { + m_menus[menu].append(QString{}); +} + +Action* ActionMapper::addAction(const Action& act, const QString& name, const QString& menu, const QKeySequence& shortcut) { + m_actions.insert(name, act); + m_reverseMenus[name] = menu; + m_menus[menu].append(name); + if (!shortcut.isEmpty()) { + m_defaultShortcuts[name] = shortcut; + } + emit actionAdded(name); + + return &m_actions[name]; +} + +Action* ActionMapper::addAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu, const QKeySequence& shortcut) { + return addAction(Action(action, name, visibleName), name, menu, shortcut); +} + +Action* ActionMapper::addAction(const QString& visibleName, ConfigOption* option, const QVariant& variant, const QString& menu) { + return addAction(Action([option, variant]() { + option->setValue(variant); + }, option->name(), visibleName), QString("%1.%2").arg(option->name()).arg(variant.toString()), menu, {}); +} + +Action* ActionMapper::addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu, const QKeySequence& shortcut) { + return addAction(Action(action, name, visibleName), name, menu, shortcut); +} + +Action* ActionMapper::addBooleanAction(const QString& visibleName, ConfigOption* option, const QString& menu) { + return addAction(Action([option](bool value) { + option->setValue(value); + }, option->name(), visibleName), option->name(), menu, {}); +} + +Action* ActionMapper::addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu, const QKeySequence& shortcut) { + m_hiddenActions.insert(name); + m_heldActions.insert(name); + return addBooleanAction(visibleName, name, action, menu, shortcut); +} + +Action* ActionMapper::addHiddenAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu, const QKeySequence& shortcut) { + m_hiddenActions.insert(name); + return addAction(visibleName, name, action, menu, shortcut); +} + +QStringList ActionMapper::menuItems(const QString& menu) const { + return m_menus[menu]; +} + +QString ActionMapper::menuFor(const QString& menu) const { + return m_reverseMenus[menu]; +} + +QString ActionMapper::menuName(const QString& menu) const { + if (!menu.isNull() && menu[0] == '.') { + return m_menuNames[menu.mid(1)]; + } + return m_menuNames[menu]; +} + +Action* ActionMapper::getAction(const QString& itemName) { + return &m_actions[itemName]; +} + +QKeySequence ActionMapper::defaultShortcut(const QString& itemName) { + return m_defaultShortcuts[itemName]; +} \ No newline at end of file diff --git a/src/platform/qt/ActionMapper.h b/src/platform/qt/ActionMapper.h new file mode 100644 index 000000000..1ffcda2a2 --- /dev/null +++ b/src/platform/qt/ActionMapper.h @@ -0,0 +1,85 @@ +/* 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/. */ +#pragma once + +#include "Action.h" + +#include +#include +#include +#include + +#include + +class QMenu; +class QMenuBar; + +namespace QGBA { + +class ConfigOption; +class ShortcutController; + +class ActionMapper : public QObject { +Q_OBJECT + +public: + void addMenu(const QString& visibleName, const QString& name, const QString& parent = {}); + void addHiddenMenu(const QString& visibleName, const QString& name, const QString& parent = {}); + void clearMenu(const QString& name); + void rebuildMenu(QMenuBar*, const ShortcutController&); + + void addSeparator(const QString& menu); + + Action* addAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu = {}, const QKeySequence& = {}); + template Action* addAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu = {}, const QKeySequence& = {}); + Action* addAction(const QString& visibleName, ConfigOption* option, const QVariant& variant, const QString& menu = {}); + + Action* addBooleanAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu = {}, const QKeySequence& = {}); + Action* addBooleanAction(const QString& visibleName, ConfigOption* option, const QString& menu = {}); + + Action* addHeldAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu = {}, const QKeySequence& = {}); + + Action* addHiddenAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu = {}, const QKeySequence& = {}); + template Action* addHiddenAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu = {}, const QKeySequence& = {}); + + bool isHeld(const QString& name) const { return m_heldActions.contains(name); } + + QStringList menuItems(const QString& menu = QString()) const; + QString menuFor(const QString& action) const; + QString menuName(const QString& menu) const; + + Action* getAction(const QString& action); + QKeySequence defaultShortcut(const QString& action); + +signals: + void actionAdded(const QString& name); + void menuCleared(const QString& name); + +private: + void rebuildMenu(const QString& menu, QMenu* qmenu, const ShortcutController&); + Action* addAction(const Action& act, const QString& name, const QString& menu, const QKeySequence& shortcut); + + QHash m_actions; + QHash m_menus; + QHash m_reverseMenus; + QHash m_menuNames; + QHash m_defaultShortcuts; + QSet m_hiddenActions; + QSet m_heldActions; +}; + +template +Action* ActionMapper::addAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu, const QKeySequence& shortcut) { + return addAction(visibleName, name, std::bind(method, obj), menu, shortcut); +} + +template +Action* ActionMapper::addHiddenAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu, const QKeySequence& shortcut) { + m_hiddenActions.insert(name); + return addAction(visibleName, name, obj, method, menu, shortcut); +} + +} diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index a13cd5424..76d21a241 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -67,6 +67,8 @@ endif() set(SOURCE_FILES AboutScreen.cpp AbstractUpdater.cpp + Action.cpp + ActionMapper.cpp AssetTile.cpp AssetView.cpp AudioProcessor.cpp @@ -111,6 +113,7 @@ set(SOURCE_FILES SettingsView.cpp ShaderSelector.cpp ShortcutController.cpp + ShortcutModel.cpp ShortcutView.cpp Swatch.cpp TilePainter.cpp diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index b31528c11..969f0609f 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -5,9 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ConfigController.h" +#include "ActionMapper.h" #include "CoreController.h" -#include #include #include @@ -15,51 +15,58 @@ using namespace QGBA; -ConfigOption::ConfigOption(QObject* parent) +ConfigOption::ConfigOption(const QString& name, QObject* parent) : QObject(parent) + , m_name(name) { } void ConfigOption::connect(std::function slot, QObject* parent) { m_slots[parent] = slot; - QObject::connect(parent, &QAction::destroyed, [this, slot, parent]() { + QObject::connect(parent, &QObject::destroyed, [this, slot, parent]() { m_slots.remove(parent); }); } -QAction* ConfigOption::addValue(const QString& text, const QVariant& value, QMenu* parent) { - QAction* action = new QAction(text, parent); - action->setCheckable(true); - QObject::connect(action, &QAction::triggered, [this, value]() { +Action* ConfigOption::addValue(const QString& text, const QVariant& value, ActionMapper* actions, const QString& menu) { + Action* action; + auto function = [this, value]() { emit valueChanged(value); - }); - if (parent) { - QObject::connect(parent, &QAction::destroyed, [this, action, value]() { - m_actions.removeAll(qMakePair(action, value)); - }); - parent->addAction(action); + }; + QString name = QString("%1.%2").arg(m_name).arg(value.toString()); + if (actions) { + action = actions->addAction(text, name, function, menu); + } else { + action = new Action(function, name, text); } - m_actions.append(qMakePair(action, value)); + action->setExclusive(); + QObject::connect(action, &QObject::destroyed, [this, action, value]() { + m_actions.removeAll(std::make_pair(action, value)); + }); + m_actions.append(std::make_pair(action, value)); return action; } -QAction* ConfigOption::addValue(const QString& text, const char* value, QMenu* parent) { - return addValue(text, QString(value), parent); +Action* ConfigOption::addValue(const QString& text, const char* value, ActionMapper* actions, const QString& menu) { + return addValue(text, QString(value), actions, menu); } -QAction* ConfigOption::addBoolean(const QString& text, QMenu* parent) { - QAction* action = new QAction(text, parent); - action->setCheckable(true); - QObject::connect(action, &QAction::triggered, [this, action]() { - emit valueChanged(action->isChecked()); - }); - if (parent) { - QObject::connect(parent, &QAction::destroyed, [this, action]() { - m_actions.removeAll(qMakePair(action, 1)); - }); - parent->addAction(action); +Action* ConfigOption::addBoolean(const QString& text, ActionMapper* actions, const QString& menu) { + Action* action; + auto function = [this](bool value) { + emit valueChanged(value); + }; + if (actions) { + action = actions->addBooleanAction(text, m_name, function, menu); + } else { + action = new Action(function, m_name, text); } - m_actions.append(qMakePair(action, 1)); + + QObject::connect(action, &QObject::destroyed, [this, action]() { + m_actions.removeAll(std::make_pair(action, 1)); + }); + m_actions.append(std::make_pair(action, 1)); + return action; } @@ -80,10 +87,8 @@ void ConfigOption::setValue(const char* value) { } void ConfigOption::setValue(const QVariant& value) { - for (QPair& action : m_actions) { - bool signalsEnabled = action.first->blockSignals(true); - action.first->setChecked(value == action.second); - action.first->blockSignals(signalsEnabled); + for (std::pair& action : m_actions) { + action.first->setActive(value == action.second); } for (std::function& slot : m_slots.values()) { slot(value); @@ -142,7 +147,7 @@ ConfigOption* ConfigController::addOption(const char* key) { if (m_optionSet.contains(optionName)) { return m_optionSet[optionName]; } - ConfigOption* newOption = new ConfigOption(this); + ConfigOption* newOption = new ConfigOption(optionName, this); m_optionSet[optionName] = newOption; connect(newOption, &ConfigOption::valueChanged, [this, key](const QVariant& value) { setOption(key, value); diff --git a/src/platform/qt/ConfigController.h b/src/platform/qt/ConfigController.h index e21fbade5..0d77f8946 100644 --- a/src/platform/qt/ConfigController.h +++ b/src/platform/qt/ConfigController.h @@ -18,7 +18,6 @@ #include #include -class QAction; class QMenu; struct mArguments; @@ -26,17 +25,22 @@ struct GBACartridgeOverride; namespace QGBA { +class Action; +class ActionMapper; + class ConfigOption : public QObject { Q_OBJECT public: - ConfigOption(QObject* parent = nullptr); + ConfigOption(const QString& name, QObject* parent = nullptr); void connect(std::function, QObject* parent = nullptr); - QAction* addValue(const QString& text, const QVariant& value, QMenu* parent = nullptr); - QAction* addValue(const QString& text, const char* value, QMenu* parent = nullptr); - QAction* addBoolean(const QString& text, QMenu* parent = nullptr); + Action* addValue(const QString& text, const QVariant& value, ActionMapper* actions = nullptr, const QString& menu = {}); + Action* addValue(const QString& text, const char* value, ActionMapper* actions = nullptr, const QString& menu = {}); + Action* addBoolean(const QString& text, ActionMapper* actions = nullptr, const QString& menu = {}); + + QString name() const { return m_name; } public slots: void setValue(bool value); @@ -50,7 +54,8 @@ signals: private: QMap> m_slots; - QList> m_actions; + QList> m_actions; + QString m_name; }; class ConfigController : public QObject { diff --git a/src/platform/qt/ShortcutController.cpp b/src/platform/qt/ShortcutController.cpp index a8364c4af..2b37fc014 100644 --- a/src/platform/qt/ShortcutController.cpp +++ b/src/platform/qt/ShortcutController.cpp @@ -12,11 +12,12 @@ #include #include #include +#include using namespace QGBA; ShortcutController::ShortcutController(QObject* parent) - : QAbstractItemModel(parent) + : QObject(parent) { } @@ -24,202 +25,27 @@ void ShortcutController::setConfigController(ConfigController* controller) { m_config = controller; } -QVariant ShortcutController::data(const QModelIndex& index, int role) const { - if (role != Qt::DisplayRole || !index.isValid()) { - return QVariant(); - } - int row = index.row(); - const ShortcutItem* item = static_cast(index.internalPointer()); - switch (index.column()) { - case 0: - return item->visibleName(); - case 1: - return QKeySequence(item->shortcut()).toString(QKeySequence::NativeText); - case 2: - if (item->button() >= 0) { - return item->button(); - } - if (item->axis() >= 0) { - char d = '\0'; - if (item->direction() == GamepadAxisEvent::POSITIVE) { - d = '+'; - } - if (item->direction() == GamepadAxisEvent::NEGATIVE) { - d = '-'; - } - return QString("%1%2").arg(d).arg(item->axis()); - } - break; - } - return QVariant(); +void ShortcutController::setActionMapper(ActionMapper* actions) { + m_actions = actions; + connect(actions, &ActionMapper::actionAdded, this, &ShortcutController::generateItem); + connect(actions, &ActionMapper::menuCleared, this, &ShortcutController::menuCleared); + rebuildItems(); } -QVariant ShortcutController::headerData(int section, Qt::Orientation orientation, int role) const { - if (role != Qt::DisplayRole) { - return QAbstractItemModel::headerData(section, orientation, role); - } - if (orientation == Qt::Horizontal) { - switch (section) { - case 0: - return tr("Action"); - case 1: - return tr("Keyboard"); - case 2: - return tr("Gamepad"); - } - } - return section; -} - -QModelIndex ShortcutController::index(int row, int column, const QModelIndex& parent) const { - const ShortcutItem* pmenu = &m_rootMenu; - if (parent.isValid()) { - pmenu = static_cast(parent.internalPointer()); - } - return createIndex(row, column, const_cast(&pmenu->items()[row])); -} - -QModelIndex ShortcutController::parent(const QModelIndex& index) const { - if (!index.isValid() || !index.internalPointer()) { - return QModelIndex(); - } - ShortcutItem* item = static_cast(index.internalPointer()); - if (!item->parent() || !item->parent()->parent()) { - return QModelIndex(); - } - return createIndex(item->parent()->parent()->items().indexOf(*item->parent()), 0, item->parent()); -} - -int ShortcutController::columnCount(const QModelIndex& index) const { - return 3; -} - -int ShortcutController::rowCount(const QModelIndex& index) const { - if (!index.isValid()) { - return m_rootMenu.items().count(); - } - const ShortcutItem* item = static_cast(index.internalPointer()); - return item->items().count(); -} - -void ShortcutController::addAction(QMenu* menu, QAction* action, const QString& name) { - ShortcutItem* smenu = m_menuMap[menu]; - if (!smenu) { - return; - } - ShortcutItem* pmenu = smenu->parent(); - int row = pmenu->items().indexOf(*smenu); - QModelIndex parent = createIndex(row, 0, smenu); - beginInsertRows(parent, smenu->items().count(), smenu->items().count()); - smenu->addAction(action, name); - endInsertRows(); - ShortcutItem* item = &smenu->items().last(); - if (m_config) { - loadShortcuts(item); - } - emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), - createIndex(smenu->items().count() - 1, 2, item)); -} - -void ShortcutController::addFunctions(QMenu* menu, std::function press, std::function release, - int shortcut, const QString& visibleName, const QString& name) { - ShortcutItem* smenu = m_menuMap[menu]; - if (!smenu) { - return; - } - ShortcutItem* pmenu = smenu->parent(); - int row = pmenu->items().indexOf(*smenu); - QModelIndex parent = createIndex(row, 0, smenu); - beginInsertRows(parent, smenu->items().count(), smenu->items().count()); - smenu->addFunctions(qMakePair(press, release), shortcut, visibleName, name); - endInsertRows(); - ShortcutItem* item = &smenu->items().last(); - bool loadedShortcut = false; - if (m_config) { - loadedShortcut = loadShortcuts(item); - } - if (!loadedShortcut && !m_heldKeys.contains(shortcut)) { - m_heldKeys[shortcut] = item; - } - emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), - createIndex(smenu->items().count() - 1, 2, item)); -} - -void ShortcutController::addFunctions(QMenu* menu, std::function press, std::function release, - const QKeySequence& shortcut, const QString& visibleName, const QString& name) { - addFunctions(menu, press, release, shortcut[0], visibleName, name); -} - -void ShortcutController::addMenu(QMenu* menu, QMenu* parentMenu) { - ShortcutItem* smenu = m_menuMap[parentMenu]; - if (!smenu) { - smenu = &m_rootMenu; - } - QModelIndex parent; - ShortcutItem* pmenu = smenu->parent(); - if (pmenu) { - int row = pmenu->items().indexOf(*smenu); - parent = createIndex(row, 0, smenu); - } - beginInsertRows(parent, smenu->items().count(), smenu->items().count()); - smenu->addSubmenu(menu); - endInsertRows(); - ShortcutItem* item = &smenu->items().last(); - emit dataChanged(createIndex(smenu->items().count() - 1, 0, item), - createIndex(smenu->items().count() - 1, 2, item)); - m_menuMap[menu] = item; -} - -ShortcutController::ShortcutItem* ShortcutController::itemAt(const QModelIndex& index) { - if (!index.isValid()) { - return nullptr; - } - return static_cast(index.internalPointer()); -} - -const ShortcutController::ShortcutItem* ShortcutController::itemAt(const QModelIndex& index) const { - if (!index.isValid()) { - return nullptr; - } - return static_cast(index.internalPointer()); -} - -int ShortcutController::shortcutAt(const QModelIndex& index) const { - const ShortcutItem* item = itemAt(index); +void ShortcutController::updateKey(const QString& name, int keySequence) { + auto item = m_items[name]; if (!item) { - return 0; - } - return item->shortcut(); -} - -bool ShortcutController::isMenuAt(const QModelIndex& index) const { - const ShortcutItem* item = itemAt(index); - if (!item) { - return false; - } - return item->menu(); -} - -void ShortcutController::updateKey(const QModelIndex& index, int keySequence) { - if (!index.isValid()) { return; } - const QModelIndex& parent = index.parent(); - if (!parent.isValid()) { - return; - } - ShortcutItem* item = itemAt(index); updateKey(item, keySequence); if (m_config) { m_config->setQtOption(item->name(), QKeySequence(keySequence).toString(), KEY_SECTION); } - emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), - createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::updateKey(ShortcutItem* item, int keySequence) { +void ShortcutController::updateKey(std::shared_ptr item, int keySequence) { int oldShortcut = item->shortcut(); - if (item->functions().first) { + if (m_actions->isHeld(item->name())) { if (oldShortcut > 0) { m_heldKeys.take(oldShortcut); } @@ -231,51 +57,41 @@ void ShortcutController::updateKey(ShortcutItem* item, int keySequence) { item->setShortcut(keySequence); } -void ShortcutController::updateButton(const QModelIndex& index, int button) { - if (!index.isValid()) { +void ShortcutController::updateButton(const QString& name, int button) { + auto item = m_items[name]; + if (!item) { return; } - const QModelIndex& parent = index.parent(); - if (!parent.isValid()) { - return; - } - ShortcutItem* item = itemAt(index); int oldButton = item->button(); if (oldButton >= 0) { m_buttons.take(oldButton); } - updateAxis(index, -1, GamepadAxisEvent::NEUTRAL); item->setButton(button); if (button >= 0) { + clearAxis(name); m_buttons[button] = item; } if (m_config) { - m_config->setQtOption(item->name(), button, BUTTON_SECTION); + m_config->setQtOption(name, button, BUTTON_SECTION); if (!m_profileName.isNull()) { - m_config->setQtOption(item->name(), button, BUTTON_PROFILE_SECTION + m_profileName); + m_config->setQtOption(name, button, BUTTON_PROFILE_SECTION + m_profileName); } } - emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), - createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction) { - if (!index.isValid()) { +void ShortcutController::updateAxis(const QString& name, int axis, GamepadAxisEvent::Direction direction) { + auto item = m_items[name]; + if (!item) { return; } - const QModelIndex& parent = index.parent(); - if (!parent.isValid()) { - return; - } - ShortcutItem* item = itemAt(index); int oldAxis = item->axis(); GamepadAxisEvent::Direction oldDirection = item->direction(); if (oldAxis >= 0) { - m_axes.take(qMakePair(oldAxis, oldDirection)); + m_axes.take(std::make_pair(oldAxis, oldDirection)); } if (axis >= 0 && direction != GamepadAxisEvent::NEUTRAL) { - updateButton(index, -1); - m_axes[qMakePair(axis, direction)] = item; + clearButton(name); + m_axes[std::make_pair(axis, direction)] = item; } item->setAxis(axis, direction); if (m_config) { @@ -286,21 +102,31 @@ void ShortcutController::updateAxis(const QModelIndex& index, int axis, GamepadA if (direction == GamepadAxisEvent::NEGATIVE) { d = '-'; } - m_config->setQtOption(item->name(), QString("%1%2").arg(d).arg(axis), AXIS_SECTION); + m_config->setQtOption(name, QString("%1%2").arg(d).arg(axis), AXIS_SECTION); if (!m_profileName.isNull()) { - m_config->setQtOption(item->name(), QString("%1%2").arg(d).arg(axis), AXIS_PROFILE_SECTION + m_profileName); + m_config->setQtOption(name, QString("%1%2").arg(d).arg(axis), AXIS_PROFILE_SECTION + m_profileName); } } - emit dataChanged(createIndex(index.row(), 0, index.internalPointer()), - createIndex(index.row(), 2, index.internalPointer())); } -void ShortcutController::clearKey(const QModelIndex& index) { - updateKey(index, 0); +void ShortcutController::clearKey(const QString& name) { + updateKey(name, 0); } -void ShortcutController::clearButton(const QModelIndex& index) { - updateButton(index, -1); +void ShortcutController::clearButton(const QString& name) { + updateButton(name, -1); +} + +void ShortcutController::clearAxis(const QString& name) { + updateAxis(name, -1, GamepadAxisEvent::NEUTRAL); +} + +void ShortcutController::rebuildItems() { + m_items.clear(); + m_buttons.clear(); + m_axes.clear(); + m_heldKeys.clear(); + onSubitems({}, std::bind(&ShortcutController::generateItem, this, std::placeholders::_1)); } bool ShortcutController::eventFilter(QObject*, QEvent* event) { @@ -317,16 +143,8 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) { } auto item = m_heldKeys.find(key); if (item != m_heldKeys.end()) { - ShortcutItem::Functions pair = item.value()->functions(); - if (event->type() == QEvent::KeyPress) { - if (pair.first) { - pair.first(); - } - } else { - if (pair.second) { - pair.second(); - } - } + Action::BooleanFunction fn = item.value()->action()->booleanAction(); + fn(event->type() == QEvent::KeyPress); event->accept(); return true; } @@ -336,14 +154,10 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) { if (item == m_buttons.end()) { return false; } - QAction* action = item.value()->action(); - if (action && action->isEnabled()) { + Action* action = item.value()->action(); + if (action) { action->trigger(); } - ShortcutItem::Functions pair = item.value()->functions(); - if (pair.first) { - pair.first(); - } event->accept(); return true; } @@ -352,34 +166,22 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) { if (item == m_buttons.end()) { return false; } - ShortcutItem::Functions pair = item.value()->functions(); - if (pair.second) { - pair.second(); + Action* action = item.value()->action(); + if (action) { + action->trigger(false); } event->accept(); return true; } if (event->type() == GamepadAxisEvent::Type()) { GamepadAxisEvent* gae = static_cast(event); - auto item = m_axes.find(qMakePair(gae->axis(), gae->direction())); + auto item = m_axes.find(std::make_pair(gae->axis(), gae->direction())); if (item == m_axes.end()) { return false; } - if (gae->isNew()) { - QAction* action = item.value()->action(); - if (action && action->isEnabled()) { - action->trigger(); - } - } - ShortcutItem::Functions pair = item.value()->functions(); - if (gae->isNew()) { - if (pair.first) { - pair.first(); - } - } else { - if (pair.second) { - pair.second(); - } + Action* action = item.value()->action(); + if (action) { + action->trigger(gae->isNew()); } event->accept(); return true; @@ -387,7 +189,20 @@ bool ShortcutController::eventFilter(QObject*, QEvent* event) { return false; } -bool ShortcutController::loadShortcuts(ShortcutItem* item) { +void ShortcutController::generateItem(const QString& itemName) { + if (itemName.isNull() || itemName[0] == '.') { + return; + } + Action* action = m_actions->getAction(itemName); + if (action) { + std::shared_ptr item = std::make_shared(action); + m_items[itemName] = item; + loadShortcuts(item); + } + emit shortcutAdded(itemName); +} + +bool ShortcutController::loadShortcuts(std::shared_ptr item) { if (item->name().isNull()) { return false; } @@ -400,11 +215,17 @@ bool ShortcutController::loadShortcuts(ShortcutItem* item) { updateKey(item, QKeySequence(shortcut.toString())[0]); } return true; + } else { + QKeySequence defaultShortcut = m_actions->defaultShortcut(item->name()); + if (!defaultShortcut.isEmpty()) { + updateKey(item, defaultShortcut[0]); + return true; + } } return false; } -void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) { +void ShortcutController::loadGamepadShortcuts(std::shared_ptr item) { if (item->name().isNull()) { return; } @@ -429,7 +250,7 @@ void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) { int oldAxis = item->axis(); GamepadAxisEvent::Direction oldDirection = item->direction(); if (oldAxis >= 0) { - m_axes.take(qMakePair(oldAxis, oldDirection)); + m_axes.take(std::make_pair(oldAxis, oldDirection)); item->setAxis(-1, GamepadAxisEvent::NEUTRAL); } if (axis.isNull() && m_profile) { @@ -453,7 +274,7 @@ void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) { int axis = axisDesc.mid(1).toInt(&ok); if (ok) { item->setAxis(axis, direction); - m_axes[qMakePair(axis, direction)] = item; + m_axes[std::make_pair(axis, direction)] = item; } } } @@ -462,15 +283,29 @@ void ShortcutController::loadGamepadShortcuts(ShortcutItem* item) { void ShortcutController::loadProfile(const QString& profile) { m_profileName = profile; m_profile = InputProfile::findProfile(profile); - onSubitems(&m_rootMenu, [this](ShortcutItem* item) { + onSubitems({}, [this](std::shared_ptr item) { loadGamepadShortcuts(item); }); } -void ShortcutController::onSubitems(ShortcutItem* item, std::function func) { - for (ShortcutItem& subitem : item->items()) { - func(&subitem); - onSubitems(&subitem, func); +void ShortcutController::onSubitems(const QString& menu, std::function)> func) { + for (const QString& subitem : m_actions->menuItems(menu)) { + auto item = m_items[subitem]; + if (item) { + func(item); + } + if (subitem.size() && subitem[0] == '.') { + onSubitems(subitem.mid(1), func); + } + } +} + +void ShortcutController::onSubitems(const QString& menu, std::function func) { + for (const QString& subitem : m_actions->menuItems(menu)) { + func(subitem); + if (subitem.size() && subitem[0] == '.') { + onSubitems(subitem.mid(1), func); + } } } @@ -534,62 +369,83 @@ int ShortcutController::toModifierKey(int key) { } -ShortcutController::ShortcutItem::ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent) +const Shortcut* ShortcutController::shortcut(const QString& action) const { + return m_items[action].get(); +} + +QString ShortcutController::name(int index, const QString& parent) const { + QStringList menu = m_actions->menuItems(parent.isNull() || parent[0] != '.' ? parent : parent.mid(1)); + menu.removeAll({}); + if (index >= menu.size()) { + return {}; + } + + return menu[index]; +} + +QString ShortcutController::parent(const QString& action) const { + return QString(".%1").arg(m_actions->menuFor(action)); +} + +QString ShortcutController::visibleName(const QString& action) const { + if (action.isNull()) { + return {}; + } + QString name; + if (action[0] == '.') { + name = m_actions->menuName(action.mid(1)); + } else { + name = m_actions->getAction(action)->visibleName(); + } + return name.replace(QRegularExpression("&(.)"), "\\1"); +} + +int ShortcutController::indexIn(const QString& action) const { + QString name = m_actions->menuFor(action); + QStringList menu = m_actions->menuItems(name); + menu.removeAll({}); + return menu.indexOf(action); +} + +int ShortcutController::count(const QString& name) const { + QStringList menu; + if (name.isNull()) { + menu = m_actions->menuItems(); + } else if (name[0] != '.') { + return 0; + } else { + menu = m_actions->menuItems(name.mid(1)); + } + menu.removeAll({}); + return menu.count(); +} + +Shortcut::Shortcut(Action* action) : m_action(action) - , m_shortcut(action->shortcut().isEmpty() ? 0 : action->shortcut()[0]) - , m_name(name) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) -{ - m_visibleName = action->text() - .remove(QRegExp("&(?!&)")) - .remove("..."); -} - -ShortcutController::ShortcutItem::ShortcutItem(ShortcutController::ShortcutItem::Functions functions, int shortcut, const QString& visibleName, const QString& name, ShortcutItem* parent) - : m_shortcut(shortcut) - , m_functions(functions) - , m_name(name) - , m_visibleName(visibleName) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) { } -ShortcutController::ShortcutItem::ShortcutItem(QMenu* menu, ShortcutItem* parent) - : m_menu(menu) - , m_direction(GamepadAxisEvent::NEUTRAL) - , m_parent(parent) -{ - if (menu) { - m_visibleName = menu->title() - .remove(QRegExp("&(?!&)")) - .remove("..."); +void Shortcut::setShortcut(int shortcut) { + if (m_shortcut == shortcut) { + return; } -} - -void ShortcutController::ShortcutItem::addAction(QAction* action, const QString& name) { - m_items.append(ShortcutItem(action, name, this)); -} - -void ShortcutController::ShortcutItem::addFunctions(ShortcutController::ShortcutItem::Functions functions, - int shortcut, const QString& visibleName, - const QString& name) { - m_items.append(ShortcutItem(functions, shortcut, visibleName, name, this)); -} - -void ShortcutController::ShortcutItem::addSubmenu(QMenu* menu) { - m_items.append(ShortcutItem(menu, this)); -} - -void ShortcutController::ShortcutItem::setShortcut(int shortcut) { m_shortcut = shortcut; - if (m_action) { - m_action->setShortcut(QKeySequence(shortcut)); - } + emit shortcutChanged(shortcut); } -void ShortcutController::ShortcutItem::setAxis(int axis, GamepadAxisEvent::Direction direction) { +void Shortcut::setButton(int button) { + if (m_button == button) { + return; + } + m_button = button; + emit buttonChanged(button); +} + +void Shortcut::setAxis(int axis, GamepadAxisEvent::Direction direction) { + if (m_axis == axis && m_direction == direction) { + return; + } m_axis = axis; m_direction = direction; + emit axisChanged(axis, direction); } diff --git a/src/platform/qt/ShortcutController.h b/src/platform/qt/ShortcutController.h index 219188da1..ef90d3eaf 100644 --- a/src/platform/qt/ShortcutController.h +++ b/src/platform/qt/ShortcutController.h @@ -5,23 +5,60 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once +#include "ActionMapper.h" #include "GamepadAxisEvent.h" -#include +#include +#include +#include -#include +#include -class QAction; class QKeyEvent; -class QMenu; -class QString; namespace QGBA { class ConfigController; class InputProfile; -class ShortcutController : public QAbstractItemModel { +class Shortcut : public QObject { +Q_OBJECT + +public: + Shortcut(Action* action); + + Action* action() { return m_action; } + const Action* action() const { return m_action; } + const int shortcut() const { return m_shortcut; } + QString visibleName() const { return m_action ? m_action->visibleName() : QString(); } + QString name() const { return m_action ? m_action->name() : QString(); } + int button() const { return m_button; } + int axis() const { return m_axis; } + GamepadAxisEvent::Direction direction() const { return m_direction; } + + bool operator==(const Shortcut& other) const { + return m_action == other.m_action; + } + +public slots: + void setShortcut(int sequence); + void setButton(int button); + void setAxis(int axis, GamepadAxisEvent::Direction direction); + +signals: + void shortcutChanged(int sequence); + void buttonChanged(int button); + void axisChanged(int axis, GamepadAxisEvent::Direction direction); + +private: + Action* m_action = nullptr; + int m_shortcut = 0; + int m_button = -1; + int m_axis = -1; + GamepadAxisEvent::Direction m_direction; +}; + +class ShortcutController : public QObject { Q_OBJECT private: @@ -31,112 +68,57 @@ private: constexpr static const char* const BUTTON_PROFILE_SECTION = "shortcutProfileButton."; constexpr static const char* const AXIS_PROFILE_SECTION = "shortcutProfileAxis."; - class ShortcutItem { - public: - typedef QPair, std::function> Functions; - - ShortcutItem(QAction* action, const QString& name, ShortcutItem* parent = nullptr); - ShortcutItem(Functions functions, int shortcut, const QString& visibleName, const QString& name, - ShortcutItem* parent = nullptr); - ShortcutItem(QMenu* action, ShortcutItem* parent = nullptr); - - QAction* action() { return m_action; } - const QAction* action() const { return m_action; } - const int shortcut() const { return m_shortcut; } - Functions functions() const { return m_functions; } - QMenu* menu() { return m_menu; } - const QMenu* menu() const { return m_menu; } - const QString& visibleName() const { return m_visibleName; } - const QString& name() const { return m_name; } - QList& items() { return m_items; } - const QList& items() const { return m_items; } - ShortcutItem* parent() { return m_parent; } - const ShortcutItem* parent() const { return m_parent; } - void addAction(QAction* action, const QString& name); - void addFunctions(Functions functions, int shortcut, const QString& visibleName, - const QString& name); - void addSubmenu(QMenu* menu); - int button() const { return m_button; } - void setShortcut(int sequence); - void setButton(int button) { m_button = button; } - int axis() const { return m_axis; } - GamepadAxisEvent::Direction direction() const { return m_direction; } - void setAxis(int axis, GamepadAxisEvent::Direction direction); - - bool operator==(const ShortcutItem& other) const { - return m_menu == other.m_menu && m_action == other.m_action; - } - - private: - QAction* m_action = nullptr; - int m_shortcut = 0; - QMenu* m_menu = nullptr; - Functions m_functions; - QString m_name; - QString m_visibleName; - int m_button = -1; - int m_axis = -1; - GamepadAxisEvent::Direction m_direction; - QList m_items; - ShortcutItem* m_parent; - }; - public: ShortcutController(QObject* parent = nullptr); void setConfigController(ConfigController* controller); + void setActionMapper(ActionMapper* actionMapper); + void setProfile(const QString& profile); - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + void updateKey(const QString& action, int keySequence); + void updateButton(const QString& action, int button); + void updateAxis(const QString& action, int axis, GamepadAxisEvent::Direction direction); - virtual QModelIndex index(int row, int column, const QModelIndex& parent) const override; - virtual QModelIndex parent(const QModelIndex& index) const override; - - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; - - void addAction(QMenu* menu, QAction* action, const QString& name); - void addFunctions(QMenu* menu, std::function press, std::function release, - int shortcut, const QString& visibleName, const QString& name); - void addFunctions(QMenu* menu, std::function press, std::function release, - const QKeySequence& shortcut, const QString& visibleName, const QString& name); - void addMenu(QMenu* menu, QMenu* parent = nullptr); - - QAction* getAction(const QString& name); - int shortcutAt(const QModelIndex& index) const; - bool isMenuAt(const QModelIndex& index) const; - - void updateKey(const QModelIndex& index, int keySequence); - void updateButton(const QModelIndex& index, int button); - void updateAxis(const QModelIndex& index, int axis, GamepadAxisEvent::Direction direction); - - void clearKey(const QModelIndex& index); - void clearButton(const QModelIndex& index); + void clearKey(const QString& action); + void clearButton(const QString& action); + void clearAxis(const QString& action); static int toModifierShortcut(const QString& shortcut); static bool isModifierKey(int key); static int toModifierKey(int key); + const Shortcut* shortcut(const QString& action) const; + int indexIn(const QString& action) const; + int count(const QString& menu = {}) const; + QString parent(const QString& action) const; + QString name(int index, const QString& parent = {}) const; + QString visibleName(const QString& item) const; + +signals: + void shortcutAdded(const QString& name); + void menuCleared(const QString& name); + public slots: void loadProfile(const QString& profile); + void rebuildItems(); protected: bool eventFilter(QObject*, QEvent*) override; private: - ShortcutItem* itemAt(const QModelIndex& index); - const ShortcutItem* itemAt(const QModelIndex& index) const; - bool loadShortcuts(ShortcutItem*); - void loadGamepadShortcuts(ShortcutItem*); - void onSubitems(ShortcutItem*, std::function func); - void updateKey(ShortcutItem* item, int keySequence); + void generateItem(const QString& itemName); + bool loadShortcuts(std::shared_ptr); + void loadGamepadShortcuts(std::shared_ptr); + void onSubitems(const QString& menu, std::function)> func); + void onSubitems(const QString& menu, std::function func); + void updateKey(std::shared_ptr item, int keySequence); - ShortcutItem m_rootMenu{nullptr}; - QMap m_menuMap; - QMap m_buttons; - QMap, ShortcutItem*> m_axes; - QMap m_heldKeys; + QHash> m_items; + QHash> m_buttons; + QHash, std::shared_ptr> m_axes; + QHash> m_heldKeys; + ActionMapper* m_actions = nullptr; ConfigController* m_config = nullptr; QString m_profileName; const InputProfile* m_profile = nullptr; diff --git a/src/platform/qt/ShortcutModel.cpp b/src/platform/qt/ShortcutModel.cpp new file mode 100644 index 000000000..aa37bff90 --- /dev/null +++ b/src/platform/qt/ShortcutModel.cpp @@ -0,0 +1,138 @@ +/* Copyright (c) 2013-2019 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 "ShortcutModel.h" + +#include "ShortcutController.h" + +using namespace QGBA; + +ShortcutModel::ShortcutModel(QObject* parent) + : QAbstractItemModel(parent) +{ +} + +void ShortcutModel::setController(ShortcutController* controller) { + beginResetModel(); + m_controller = controller; + m_cache.clear(); + connect(controller, &ShortcutController::shortcutAdded, this, &ShortcutModel::addRowNamed); + connect(controller, &ShortcutController::menuCleared, this, &ShortcutModel::clearMenu); + endResetModel(); +} + +QVariant ShortcutModel::data(const QModelIndex& index, int role) const { + if (role != Qt::DisplayRole || !index.isValid()) { + return QVariant(); + } + int row = index.row(); + const Item* item = static_cast(index.internalPointer()); + const Shortcut* shortcut = item->shortcut; + switch (index.column()) { + case 0: + return m_controller->visibleName(item->name); + case 1: + return shortcut ? QKeySequence(shortcut->shortcut()).toString(QKeySequence::NativeText) : QVariant(); + case 2: + if (!shortcut) { + return QVariant(); + } + if (shortcut->button() >= 0) { + return shortcut->button(); + } + if (shortcut->axis() >= 0) { + char d = '\0'; + if (shortcut->direction() == GamepadAxisEvent::POSITIVE) { + d = '+'; + } + if (shortcut->direction() == GamepadAxisEvent::NEGATIVE) { + d = '-'; + } + return QString("%1%2").arg(d).arg(shortcut->axis()); + } + break; + } + return QVariant(); +} + +QVariant ShortcutModel::headerData(int section, Qt::Orientation orientation, int role) const { + if (role != Qt::DisplayRole) { + return QAbstractItemModel::headerData(section, orientation, role); + } + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: + return tr("Action"); + case 1: + return tr("Keyboard"); + case 2: + return tr("Gamepad"); + } + } + return section; +} + +QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const { + QString pmenu; + if (parent.isValid()) { + pmenu = static_cast(parent.internalPointer())->name; + } + QString name = m_controller->name(row, pmenu); + Item* item = &(*const_cast*>(&m_cache))[name]; + item->name = name; + item->shortcut = m_controller->shortcut(name); + return createIndex(row, column, item); +} + +QModelIndex ShortcutModel::parent(const QModelIndex& index) const { + if (!index.isValid() || !index.internalPointer()) { + return QModelIndex(); + } + Item* item = static_cast(index.internalPointer()); + QString parent = m_controller->parent(item->name); + if (parent.isNull()) { + return QModelIndex(); + } + Item* pitem = &(*const_cast*>(&m_cache))[parent]; + pitem->name = parent; + pitem->shortcut = m_controller->shortcut(parent); + return createIndex(m_controller->indexIn(parent), 0, pitem); +} + +int ShortcutModel::columnCount(const QModelIndex& index) const { + return 3; +} + +int ShortcutModel::rowCount(const QModelIndex& index) const { + if (!index.isValid()) { + return m_controller->count(); + } + Item* item = static_cast(index.internalPointer()); + return m_controller->count(item->name); +} + +QString ShortcutModel::name(const QModelIndex& index) const { + if (!index.isValid()) { + return {}; + } + Item* item = static_cast(index.internalPointer()); + return item->name; +} + +void ShortcutModel::addRowNamed(const QString& name) { + QString parent = m_controller->parent(name); + Item* item = &m_cache[parent]; + item->name = parent; + item->shortcut = m_controller->shortcut(parent); + int index = m_controller->indexIn(name); + beginInsertRows(createIndex(m_controller->indexIn(parent), 0, item), index, index + 1); + endInsertRows(); +} + +void ShortcutModel::clearMenu(const QString& name) { + // TODO + beginResetModel(); + endResetModel(); +} \ No newline at end of file diff --git a/src/platform/qt/ShortcutModel.h b/src/platform/qt/ShortcutModel.h new file mode 100644 index 000000000..69893ef9c --- /dev/null +++ b/src/platform/qt/ShortcutModel.h @@ -0,0 +1,50 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include + +namespace QGBA { + +class ShortcutController; +class Shortcut; + +class ShortcutModel : public QAbstractItemModel { +Q_OBJECT + +public: + ShortcutModel(QObject* parent = nullptr); + + void setController(ShortcutController* controller); + + virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + + virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + virtual QModelIndex parent(const QModelIndex& index) const override; + + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override; + virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override; + + QString name(const QModelIndex&) const; + +private slots: + void addRowNamed(const QString&); + void clearMenu(const QString&); + +private: + ShortcutController* m_controller = nullptr; + + struct Item { + QString name; + const Shortcut* shortcut = nullptr; + }; + + QHash m_cache; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/ShortcutView.cpp b/src/platform/qt/ShortcutView.cpp index d9ef44e95..5f2c42065 100644 --- a/src/platform/qt/ShortcutView.cpp +++ b/src/platform/qt/ShortcutView.cpp @@ -8,6 +8,7 @@ #include "GamepadButtonEvent.h" #include "InputController.h" #include "ShortcutController.h" +#include "ShortcutModel.h" #include @@ -41,7 +42,9 @@ ShortcutView::~ShortcutView() { void ShortcutView::setController(ShortcutController* controller) { m_controller = controller; - m_ui.shortcutTable->setModel(controller); + m_model = new ShortcutModel(this); + m_model->setController(controller); + m_ui.shortcutTable->setModel(m_model); } void ShortcutView::setInputController(InputController* controller) { @@ -56,10 +59,12 @@ void ShortcutView::load(const QModelIndex& index) { if (!m_controller) { return; } - if (m_controller->isMenuAt(index)) { + QString name = m_model->name(index); + const Shortcut* item = m_controller->shortcut(name); + if (!item->action()) { return; } - int shortcut = m_controller->shortcutAt(index); + int shortcut = item->shortcut(); if (index.column() == 1) { m_ui.keyboardButton->click(); } else if (index.column() == 2) { @@ -80,35 +85,47 @@ void ShortcutView::clear() { return; } QModelIndex index = m_ui.shortcutTable->selectionModel()->currentIndex(); - if (m_controller->isMenuAt(index)) { + QString name = m_model->name(index); + const Shortcut* item = m_controller->shortcut(name); + if (!item->action()) { return; } if (m_ui.gamepadButton->isChecked()) { - m_controller->clearButton(index); + m_controller->clearButton(name); + m_controller->clearAxis(name); m_ui.keyEdit->setValueButton(-1); } else { - m_controller->clearKey(index); + m_controller->clearKey(name); m_ui.keyEdit->setValueKey(-1); } } void ShortcutView::updateButton(int button) { - if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) { + if (!m_controller) { + return; + } + QString name = m_model->name(m_ui.shortcutTable->selectionModel()->currentIndex()); + const Shortcut* item = m_controller->shortcut(name); + if (!item->action()) { return; } if (m_ui.gamepadButton->isChecked()) { - m_controller->updateButton(m_ui.shortcutTable->selectionModel()->currentIndex(), button); + m_controller->updateButton(name, button); } else { - m_controller->updateKey(m_ui.shortcutTable->selectionModel()->currentIndex(), button); + m_controller->updateKey(name, button); } } void ShortcutView::updateAxis(int axis, int direction) { - if (!m_controller || m_controller->isMenuAt(m_ui.shortcutTable->selectionModel()->currentIndex())) { + if (!m_controller) { return; } - m_controller->updateAxis(m_ui.shortcutTable->selectionModel()->currentIndex(), axis, - static_cast(direction)); + QString name = m_model->name(m_ui.shortcutTable->selectionModel()->currentIndex()); + const Shortcut* item = m_controller->shortcut(name); + if (!item->action()) { + return; + } + m_controller->updateAxis(name, axis, static_cast(direction)); } void ShortcutView::closeEvent(QCloseEvent*) { diff --git a/src/platform/qt/ShortcutView.h b/src/platform/qt/ShortcutView.h index 434cd82c3..340541640 100644 --- a/src/platform/qt/ShortcutView.h +++ b/src/platform/qt/ShortcutView.h @@ -15,6 +15,7 @@ namespace QGBA { class InputController; class ShortcutController; +class ShortcutModel; class ShortcutView : public QWidget { Q_OBJECT @@ -40,6 +41,7 @@ private: Ui::ShortcutView m_ui; ShortcutController* m_controller = nullptr; + ShortcutModel* m_model = nullptr; InputController* m_input = nullptr; }; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 300d7d95c..b8c686fe8 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -152,6 +152,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi m_focusCheck.setInterval(200); m_shortcutController->setConfigController(m_config); + m_shortcutController->setActionMapper(&m_actions); setupMenu(menuBar()); } @@ -404,8 +405,8 @@ void Window::multiplayerChanged() { if (multiplayer) { attached = multiplayer->attached(); } - for (QAction* action : m_nonMpActions) { - action->setDisabled(attached > 1); + for (Action* action : m_nonMpActions) { + action->setEnabled(attached < 2); } } @@ -589,9 +590,9 @@ void Window::resizeEvent(QResizeEvent* event) { factor = m_screenWidget->width() / size.width(); } m_savedScale = factor; - for (QMap::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) { + for (QMap::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) { bool enableSignals = iter.value()->blockSignals(true); - iter.value()->setChecked(iter.key() == factor); + iter.value()->setActive(iter.key() == factor); iter.value()->blockSignals(enableSignals); } @@ -703,14 +704,12 @@ void Window::toggleFullScreen() { } void Window::gameStarted() { - for (QAction* action : m_gameActions) { - action->setDisabled(false); + for (Action* action : m_gameActions) { + action->setEnabled(true); } -#ifdef M_CORE_GBA - for (QAction* action : m_gbaActions) { - action->setDisabled(m_controller->platform() != PLATFORM_GBA); + for (auto action = m_platformActions.begin(); action != m_platformActions.end(); ++action) { + action.value()->setEnabled(m_controller->platform() == action.key()); } -#endif QSize size = m_controller->screenDimensions(); m_screenWidget->setDimensions(size.width(), size.height()); m_config->updateOption("lockIntegerScaling"); @@ -748,8 +747,8 @@ void Window::gameStarted() { CoreController::Interrupter interrupter(m_controller, true); mCore* core = m_controller->thread()->core; - m_videoLayers->clear(); - m_audioChannels->clear(); + m_actions.clearMenu("videoLayers"); + m_actions.clearMenu("audioChannels"); const mCoreChannelInfo* videoLayers; const mCoreChannelInfo* audioChannels; size_t nVideo = core->listVideoLayers(core, &videoLayers); @@ -757,26 +756,22 @@ void Window::gameStarted() { if (nVideo) { for (size_t i = 0; i < nVideo; ++i) { - QAction* action = new QAction(videoLayers[i].visibleName, m_videoLayers); - action->setCheckable(true); - action->setChecked(true); - connect(action, &QAction::triggered, [this, videoLayers, i](bool enable) { + Action* action = m_actions.addBooleanAction(videoLayers[i].visibleName, QString("videoLayer.%1").arg(videoLayers[i].internalName), [this, videoLayers, i](bool enable) { m_controller->thread()->core->enableVideoLayer(m_controller->thread()->core, videoLayers[i].id, enable); - }); - m_videoLayers->addAction(action); + }, "videoLayers"); + action->setActive(true); } } if (nAudio) { for (size_t i = 0; i < nAudio; ++i) { - QAction* action = new QAction(audioChannels[i].visibleName, m_audioChannels); - action->setCheckable(true); - action->setChecked(true); - connect(action, &QAction::triggered, [this, audioChannels, i](bool enable) { - m_controller->thread()->core->enableAudioChannel(m_controller->thread()->core, audioChannels[i].id, enable); - }); - m_audioChannels->addAction(action); + Action* action = m_actions.addBooleanAction(audioChannels[i].visibleName, QString("audioChannel.%1").arg(audioChannels[i].internalName), [this, audioChannels, i](bool enable) { + m_controller->thread()->core->enableVideoLayer(m_controller->thread()->core, audioChannels[i].id, enable); + }, "audioChannels"); + action->setActive(true); } } + m_actions.rebuildMenu(menuBar(), *m_shortcutController); + #ifdef USE_DISCORD_RPC DiscordCoordinator::gameStarted(m_controller); @@ -786,12 +781,12 @@ void Window::gameStarted() { void Window::gameStopped() { m_controller.reset(); #ifdef M_CORE_GBA - for (QAction* action : m_gbaActions) { - action->setDisabled(false); + for (Action* action : m_platformActions) { + action->setEnabled(true); } #endif - for (QAction* action : m_gameActions) { - action->setDisabled(true); + for (Action* action : m_gameActions) { + action->setEnabled(false); } setWindowFilePath(QString()); updateTitle(); @@ -809,8 +804,8 @@ void Window::gameStopped() { #endif } - m_videoLayers->clear(); - m_audioChannels->clear(); + m_actions.clearMenu("videoLayers"); + m_actions.clearMenu("audioChannels"); m_fpsTimer.stop(); m_focusCheck.stop(); @@ -992,12 +987,12 @@ void Window::updateTitle(float fps) { MultiplayerController* multiplayer = m_controller->multiplayerController(); if (multiplayer && multiplayer->attached() > 1) { title += tr(" - Player %1 of %2").arg(multiplayer->playerId(m_controller.get()) + 1).arg(multiplayer->attached()); - for (QAction* action : m_nonMpActions) { - action->setDisabled(true); + for (Action* action : m_nonMpActions) { + action->setEnabled(false); } } else { - for (QAction* action : m_nonMpActions) { - action->setDisabled(false); + for (Action* action : m_nonMpActions) { + action->setEnabled(true); } } } @@ -1041,374 +1036,255 @@ void Window::openStateWindow(LoadSave ls) { } void Window::setupMenu(QMenuBar* menubar) { - menubar->clear(); - QMenu* fileMenu = menubar->addMenu(tr("&File")); - m_shortcutController->addMenu(fileMenu); installEventFilter(m_shortcutController); - addControlledAction(fileMenu, fileMenu->addAction(tr("Load &ROM..."), this, SLOT(selectROM()), QKeySequence::Open), - "loadROM"); + + menubar->clear(); + m_actions.addMenu(tr("&File"), "file"); + + m_actions.addAction(tr("Load &ROM..."), "loadROM", this, &Window::selectROM, "file", QKeySequence::Open); + #ifdef USE_SQLITE3 - addControlledAction(fileMenu, fileMenu->addAction(tr("Load ROM in archive..."), this, SLOT(selectROMInArchive())), - "loadROMInArchive"); - addControlledAction(fileMenu, fileMenu->addAction(tr("Add folder to library..."), this, SLOT(addDirToLibrary())), - "addDirToLibrary"); + m_actions.addAction(tr("Load ROM in archive..."), "loadROMInArchive", this, &Window::selectROMInArchive, "file"); + m_actions.addAction(tr("Add folder to library..."), "addDirToLibrary", this, &Window::addDirToLibrary, "file"); #endif - QAction* loadAlternateSave = new QAction(tr("Load alternate save..."), fileMenu); - connect(loadAlternateSave, &QAction::triggered, [this]() { this->selectSave(false); }); - m_gameActions.append(loadAlternateSave); - addControlledAction(fileMenu, loadAlternateSave, "loadAlternateSave"); + addGameAction(tr("Load alternate save..."), "loadAlternateSave", [this]() { + this->selectSave(false); + }, "file"); + addGameAction(tr("Load temporary save..."), "loadTemporarySave", [this]() { + this->selectSave(true); + }, "file"); - QAction* loadTemporarySave = new QAction(tr("Load temporary save..."), fileMenu); - connect(loadTemporarySave, &QAction::triggered, [this]() { this->selectSave(true); }); - m_gameActions.append(loadTemporarySave); - addControlledAction(fileMenu, loadTemporarySave, "loadTemporarySave"); - - addControlledAction(fileMenu, fileMenu->addAction(tr("Load &patch..."), this, SLOT(selectPatch())), "loadPatch"); + m_actions.addAction(tr("Load &patch..."), "loadPatch", this, &Window::selectPatch, "file"); #ifdef M_CORE_GBA - QAction* bootBIOS = new QAction(tr("Boot BIOS"), fileMenu); - connect(bootBIOS, &QAction::triggered, [this]() { + Action* bootBIOS = m_actions.addAction(tr("Boot BIOS"), "bootBIOS", [this]() { setController(m_manager->loadBIOS(PLATFORM_GBA, m_config->getOption("gba.bios")), QString()); - }); - addControlledAction(fileMenu, bootBIOS, "bootBIOS"); + }, "file"); #endif - addControlledAction(fileMenu, fileMenu->addAction(tr("Replace ROM..."), this, SLOT(replaceROM())), "replaceROM"); + m_actions.addAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file"); - QAction* romInfo = new QAction(tr("ROM &info..."), fileMenu); - connect(romInfo, &QAction::triggered, openControllerTView()); - m_gameActions.append(romInfo); - addControlledAction(fileMenu, romInfo, "romInfo"); + Action* romInfo = addGameAction(tr("ROM &info..."), "romInfo", openControllerTView(), "file"); - m_mruMenu = fileMenu->addMenu(tr("Recent")); + m_actions.addMenu(tr("Recent"), "mru", "file"); + m_actions.addSeparator("file"); - fileMenu->addSeparator(); + m_actions.addAction(tr("Make portable"), "makePortable", this, &Window::tryMakePortable, "file"); + m_actions.addSeparator("file"); - addControlledAction(fileMenu, fileMenu->addAction(tr("Make portable"), this, SLOT(tryMakePortable())), "makePortable"); - - fileMenu->addSeparator(); - - QAction* loadState = new QAction(tr("&Load state"), fileMenu); - loadState->setShortcut(tr("F10")); - connect(loadState, &QAction::triggered, [this]() { this->openStateWindow(LoadSave::LOAD); }); - m_gameActions.append(loadState); + Action* loadState = addGameAction(tr("&Load state"), "loadState", [this]() { + this->openStateWindow(LoadSave::LOAD); + }, "file", QKeySequence("F10")); m_nonMpActions.append(loadState); - addControlledAction(fileMenu, loadState, "loadState"); - QAction* loadStateFile = new QAction(tr("Load state file..."), fileMenu); - connect(loadStateFile, &QAction::triggered, [this]() { this->selectState(true); }); - m_gameActions.append(loadStateFile); + Action* loadStateFile = addGameAction(tr("Load state file..."), "loadStateFile", [this]() { + this->selectState(true); + }, "file"); m_nonMpActions.append(loadStateFile); - addControlledAction(fileMenu, loadStateFile, "loadStateFile"); - QAction* saveState = new QAction(tr("&Save state"), fileMenu); - saveState->setShortcut(tr("Shift+F10")); - connect(saveState, &QAction::triggered, [this]() { this->openStateWindow(LoadSave::SAVE); }); - m_gameActions.append(saveState); + Action* saveState = addGameAction(tr("&Save state"), "saveState", [this]() { + this->openStateWindow(LoadSave::SAVE); + }, "file", QKeySequence("Shift+F10")); m_nonMpActions.append(saveState); - addControlledAction(fileMenu, saveState, "saveState"); - QAction* saveStateFile = new QAction(tr("Save state file..."), fileMenu); - connect(saveStateFile, &QAction::triggered, [this]() { this->selectState(false); }); - m_gameActions.append(saveStateFile); + Action* saveStateFile = addGameAction(tr("Save state file..."), "saveStateFile", [this]() { + this->selectState(false); + }, "file"); m_nonMpActions.append(saveStateFile); - addControlledAction(fileMenu, saveStateFile, "saveStateFile"); - QMenu* quickLoadMenu = fileMenu->addMenu(tr("Quick load")); - QMenu* quickSaveMenu = fileMenu->addMenu(tr("Quick save")); - m_shortcutController->addMenu(quickLoadMenu); - m_shortcutController->addMenu(quickSaveMenu); + m_actions.addMenu(tr("Quick load"), "quickLoad", "file"); + m_actions.addMenu(tr("Quick save"), "quickSave", "file"); - QAction* quickLoad = new QAction(tr("Load recent"), quickLoadMenu); - connect(quickLoad, &QAction::triggered, [this] { + Action* quickLoad = addGameAction(tr("Load recent"), "quickLoad", [this] { m_controller->loadState(); - }); - m_gameActions.append(quickLoad); + }, "quickLoad"); m_nonMpActions.append(quickLoad); - addControlledAction(quickLoadMenu, quickLoad, "quickLoad"); - QAction* quickSave = new QAction(tr("Save recent"), quickSaveMenu); - connect(quickSave, &QAction::triggered, [this] { + Action* quickSave = addGameAction(tr("Save recent"), "quickSave", [this] { m_controller->saveState(); - }); - m_gameActions.append(quickSave); + }, "quickSave"); m_nonMpActions.append(quickSave); - addControlledAction(quickSaveMenu, quickSave, "quickSave"); - quickLoadMenu->addSeparator(); - quickSaveMenu->addSeparator(); + m_actions.addSeparator("quickLoad"); + m_actions.addSeparator("quickSave"); - QAction* undoLoadState = new QAction(tr("Undo load state"), quickLoadMenu); - undoLoadState->setShortcut(tr("F11")); - connect(undoLoadState, &QAction::triggered, [this]() { + Action* undoLoadState = addGameAction(tr("Undo load state"), "undoLoadState", [this]() { m_controller->loadBackupState(); - }); - m_gameActions.append(undoLoadState); + }, "quickLoad", QKeySequence("F11")); m_nonMpActions.append(undoLoadState); - addControlledAction(quickLoadMenu, undoLoadState, "undoLoadState"); - QAction* undoSaveState = new QAction(tr("Undo save state"), quickSaveMenu); - undoSaveState->setShortcut(tr("Shift+F11")); - connect(undoSaveState, &QAction::triggered, [this]() { + Action* undoSaveState = addGameAction(tr("Undo save state"), "undoSaveState", [this]() { m_controller->saveBackupState(); - }); - m_gameActions.append(undoSaveState); + }, "quickSave", QKeySequence("Shift+F11")); m_nonMpActions.append(undoSaveState); - addControlledAction(quickSaveMenu, undoSaveState, "undoSaveState"); - quickLoadMenu->addSeparator(); - quickSaveMenu->addSeparator(); + m_actions.addSeparator("quickLoad"); + m_actions.addSeparator("quickSave"); - int i; - for (i = 1; i < 10; ++i) { - quickLoad = new QAction(tr("State &%1").arg(i), quickLoadMenu); - quickLoad->setShortcut(tr("F%1").arg(i)); - connect(quickLoad, &QAction::triggered, [this, i]() { + for (int i = 1; i < 10; ++i) { + Action* quickLoad = addGameAction(tr("State &%1").arg(i), QString("quickLoad.%1").arg(i), [this, i]() { m_controller->loadState(i); - }); - m_gameActions.append(quickLoad); + }, "quickLoad", QString("F%1").arg(i)); m_nonMpActions.append(quickLoad); - addControlledAction(quickLoadMenu, quickLoad, QString("quickLoad.%1").arg(i)); - quickSave = new QAction(tr("State &%1").arg(i), quickSaveMenu); - quickSave->setShortcut(tr("Shift+F%1").arg(i)); - connect(quickSave, &QAction::triggered, [this, i]() { + Action* quickSave = addGameAction(tr("State &%1").arg(i), QString("quickSave.%1").arg(i), [this, i]() { m_controller->saveState(i); - }); - m_gameActions.append(quickSave); + }, "quickSave", QString("Shift+F%1").arg(i)); m_nonMpActions.append(quickSave); - addControlledAction(quickSaveMenu, quickSave, QString("quickSave.%1").arg(i)); } - fileMenu->addSeparator(); - QAction* camImage = new QAction(tr("Load camera image..."), fileMenu); - connect(camImage, &QAction::triggered, this, &Window::loadCamImage); - addControlledAction(fileMenu, camImage, "loadCamImage"); + m_actions.addSeparator("file"); + m_actions.addAction(tr("Load camera image..."), "loadCamImage", this, &Window::loadCamImage, "file"); #ifdef M_CORE_GBA - fileMenu->addSeparator(); - QAction* importShark = new QAction(tr("Import GameShark Save"), fileMenu); - connect(importShark, &QAction::triggered, this, &Window::importSharkport); - m_gameActions.append(importShark); - m_gbaActions.append(importShark); - addControlledAction(fileMenu, importShark, "importShark"); + m_actions.addSeparator("file"); + Action* importShark = addGameAction(tr("Import GameShark Save"), "importShark", this, &Window::importSharkport, "file"); + m_platformActions.insert(PLATFORM_GBA, importShark); - QAction* exportShark = new QAction(tr("Export GameShark Save"), fileMenu); - connect(exportShark, &QAction::triggered, this, &Window::exportSharkport); - m_gameActions.append(exportShark); - m_gbaActions.append(exportShark); - addControlledAction(fileMenu, exportShark, "exportShark"); + Action* exportShark = addGameAction(tr("Export GameShark Save"), "exportShark", this, &Window::exportSharkport, "file"); + m_platformActions.insert(PLATFORM_GBA, exportShark); #endif - fileMenu->addSeparator(); - m_multiWindow = new QAction(tr("New multiplayer window"), fileMenu); - connect(m_multiWindow, &QAction::triggered, [this]() { + m_actions.addSeparator("file"); + m_multiWindow = m_actions.addAction(tr("New multiplayer window"), "multiWindow", [this]() { GBAApp::app()->newWindow(); - }); - addControlledAction(fileMenu, m_multiWindow, "multiWindow"); + }, "file"); #ifndef Q_OS_MAC - fileMenu->addSeparator(); + m_actions.addSeparator("file"); #endif - QAction* about = new QAction(tr("About..."), fileMenu); - connect(about, &QAction::triggered, openTView()); - fileMenu->addAction(about); + m_actions.addAction(tr("About..."), "about", openTView(), "file"); #ifndef Q_OS_MAC - addControlledAction(fileMenu, fileMenu->addAction(tr("E&xit"), this, SLOT(close()), QKeySequence::Quit), "quit"); + m_actions.addAction(tr("E&xit"), "quit", static_cast(this), &QWidget::close, "file", QKeySequence::Quit); #endif - QMenu* emulationMenu = menubar->addMenu(tr("&Emulation")); - m_shortcutController->addMenu(emulationMenu); - QAction* reset = new QAction(tr("&Reset"), emulationMenu); - reset->setShortcut(tr("Ctrl+R")); - connect(reset, &QAction::triggered, [this]() { + m_actions.addMenu(tr("&Emulation"), "emu"); + addGameAction(tr("&Reset"), "reset", [this]() { m_controller->reset(); - }); - m_gameActions.append(reset); - addControlledAction(emulationMenu, reset, "reset"); + }, "emu", QKeySequence("Ctrl+R")); - QAction* shutdown = new QAction(tr("Sh&utdown"), emulationMenu); - connect(shutdown, &QAction::triggered, [this]() { + addGameAction(tr("Sh&utdown"), "shutdown", [this]() { m_controller->stop(); - }); - m_gameActions.append(shutdown); - addControlledAction(emulationMenu, shutdown, "shutdown"); + }, "emu"); #ifdef M_CORE_GBA - QAction* yank = new QAction(tr("Yank game pak"), emulationMenu); - connect(yank, &QAction::triggered, [this]() { + Action* yank = addGameAction(tr("Yank game pak"), "yank", [this]() { m_controller->yankPak(); - }); - m_gameActions.append(yank); - m_gbaActions.append(yank); - addControlledAction(emulationMenu, yank, "yank"); + }, "emu"); + m_platformActions.insert(PLATFORM_GBA, yank); #endif - emulationMenu->addSeparator(); + m_actions.addSeparator("emu"); - QAction* pause = new QAction(tr("&Pause"), emulationMenu); - pause->setChecked(false); - pause->setCheckable(true); - pause->setShortcut(tr("Ctrl+P")); - connect(pause, &QAction::triggered, [this](bool paused) { + Action* pause = m_actions.addBooleanAction(tr("&Pause"), "pause", [this](bool paused) { if (m_controller) { m_controller->setPaused(paused); } else { m_pendingPause = paused; } - }); - connect(this, &Window::paused, [pause](bool paused) { - pause->setChecked(paused); - }); - addControlledAction(emulationMenu, pause, "pause"); + }, "emu", QKeySequence("Ctrl+P")); + connect(this, &Window::paused, pause, &Action::setActive); - QAction* frameAdvance = new QAction(tr("&Next frame"), emulationMenu); - frameAdvance->setShortcut(tr("Ctrl+N")); - connect(frameAdvance, &QAction::triggered, [this]() { + addGameAction(tr("&Next frame"), "frameAdvance", [this]() { m_controller->frameAdvance(); - }); - m_gameActions.append(frameAdvance); - addControlledAction(emulationMenu, frameAdvance, "frameAdvance"); + }, "emu", QKeySequence("Ctrl+N")); - emulationMenu->addSeparator(); + m_actions.addSeparator("emu"); - m_shortcutController->addFunctions(emulationMenu, [this]() { + m_actions.addHeldAction(tr("Fast forward (held)"), "holdFastForward", [this](bool held) { if (m_controller) { - m_controller->setFastForward(true); + m_controller->setFastForward(held); } - }, [this]() { - if (m_controller) { - m_controller->setFastForward(false); - } - }, QKeySequence(Qt::Key_Tab), tr("Fast forward (held)"), "holdFastForward"); + }, "emu", QKeySequence(Qt::Key_Tab)); - QAction* turbo = new QAction(tr("&Fast forward"), emulationMenu); - turbo->setCheckable(true); - turbo->setChecked(false); - turbo->setShortcut(tr("Shift+Tab")); - connect(turbo, &QAction::triggered, [this](bool value) { + addGameAction(tr("&Fast forward"), "fastForward", [this](bool value) { m_controller->forceFastForward(value); - }); - addControlledAction(emulationMenu, turbo, "fastForward"); - m_gameActions.append(turbo); + }, "emu", QKeySequence("Shift+Tab")); - QMenu* ffspeedMenu = emulationMenu->addMenu(tr("Fast forward speed")); + m_actions.addMenu(tr("Fast forward speed"), "fastForwardSpeed", "emu"); ConfigOption* ffspeed = m_config->addOption("fastForwardRatio"); ffspeed->connect([this](const QVariant& value) { reloadConfig(); }, this); - ffspeed->addValue(tr("Unbounded"), -1.0f, ffspeedMenu); + ffspeed->addValue(tr("Unbounded"), -1.0f, &m_actions, "fastForwardSpeed"); ffspeed->setValue(QVariant(-1.0f)); - ffspeedMenu->addSeparator(); - for (i = 2; i < 11; ++i) { - ffspeed->addValue(tr("%0x").arg(i), i, ffspeedMenu); + m_actions.addSeparator("fastForwardSpeed"); + for (int i = 2; i < 11; ++i) { + ffspeed->addValue(tr("%0x").arg(i), i, &m_actions, "fastForwardSpeed"); } m_config->updateOption("fastForwardRatio"); - m_shortcutController->addFunctions(emulationMenu, [this]() { + Action* rewindHeld = m_actions.addHeldAction(tr("Rewind (held)"), "holdRewind", [this](bool held) { if (m_controller) { - m_controller->setRewinding(true); + m_controller->setRewinding(held); } - }, [this]() { - if (m_controller) { - m_controller->setRewinding(false); - } - }, QKeySequence("`"), tr("Rewind (held)"), "holdRewind"); + }, "emu", QKeySequence("`")); + m_nonMpActions.append(rewindHeld); - QAction* rewind = new QAction(tr("Re&wind"), emulationMenu); - rewind->setShortcut(tr("~")); - connect(rewind, &QAction::triggered, [this]() { + Action* rewind = addGameAction(tr("Re&wind"), "rewind", [this]() { m_controller->rewind(); - }); - m_gameActions.append(rewind); + }, "emu", QKeySequence("~")); m_nonMpActions.append(rewind); - addControlledAction(emulationMenu, rewind, "rewind"); - QAction* frameRewind = new QAction(tr("Step backwards"), emulationMenu); - frameRewind->setShortcut(tr("Ctrl+B")); - connect(frameRewind, &QAction::triggered, [this] () { + Action* frameRewind = addGameAction(tr("Step backwards"), "frameRewind", [this] () { m_controller->rewind(1); - }); - m_gameActions.append(frameRewind); + }, "emu", QKeySequence("Ctrl+B")); m_nonMpActions.append(frameRewind); - addControlledAction(emulationMenu, frameRewind, "frameRewind"); ConfigOption* videoSync = m_config->addOption("videoSync"); - videoSync->addBoolean(tr("Sync to &video"), emulationMenu); + videoSync->addBoolean(tr("Sync to &video"), &m_actions, "emu"); videoSync->connect([this](const QVariant& value) { reloadConfig(); }, this); m_config->updateOption("videoSync"); ConfigOption* audioSync = m_config->addOption("audioSync"); - audioSync->addBoolean(tr("Sync to &audio"), emulationMenu); + audioSync->addBoolean(tr("Sync to &audio"), &m_actions, "emu"); audioSync->connect([this](const QVariant& value) { reloadConfig(); }, this); m_config->updateOption("audioSync"); - emulationMenu->addSeparator(); + m_actions.addSeparator("emu"); - QMenu* solarMenu = emulationMenu->addMenu(tr("Solar sensor")); - m_shortcutController->addMenu(solarMenu); - QAction* solarIncrease = new QAction(tr("Increase solar level"), solarMenu); - connect(solarIncrease, &QAction::triggered, &m_inputController, &InputController::increaseLuminanceLevel); - addControlledAction(solarMenu, solarIncrease, "increaseLuminanceLevel"); + m_actions.addMenu(tr("Solar sensor"), "solar", "emu"); + m_actions.addAction(tr("Increase solar level"), "increaseLuminanceLevel", &m_inputController, &InputController::increaseLuminanceLevel, "solar"); + m_actions.addAction(tr("Decrease solar level"), "decreaseLuminanceLevel", &m_inputController, &InputController::decreaseLuminanceLevel, "solar"); + m_actions.addAction(tr("Brightest solar level"), "maxLuminanceLevel", [this]() { + m_inputController.setLuminanceLevel(10); + }, "solar"); + m_actions.addAction(tr("Darkest solar level"), "minLuminanceLevel", [this]() { + m_inputController.setLuminanceLevel(0); + }, "solar"); - QAction* solarDecrease = new QAction(tr("Decrease solar level"), solarMenu); - connect(solarDecrease, &QAction::triggered, &m_inputController, &InputController::decreaseLuminanceLevel); - addControlledAction(solarMenu, solarDecrease, "decreaseLuminanceLevel"); - - QAction* maxSolar = new QAction(tr("Brightest solar level"), solarMenu); - connect(maxSolar, &QAction::triggered, [this]() { m_inputController.setLuminanceLevel(10); }); - addControlledAction(solarMenu, maxSolar, "maxLuminanceLevel"); - - QAction* minSolar = new QAction(tr("Darkest solar level"), solarMenu); - connect(minSolar, &QAction::triggered, [this]() { m_inputController.setLuminanceLevel(0); }); - addControlledAction(solarMenu, minSolar, "minLuminanceLevel"); - - solarMenu->addSeparator(); + m_actions.addSeparator("solar"); for (int i = 0; i <= 10; ++i) { - QAction* setSolar = new QAction(tr("Brightness %1").arg(QString::number(i)), solarMenu); - connect(setSolar, &QAction::triggered, [this, i]() { + m_actions.addAction(tr("Brightness %1").arg(QString::number(i)), QString("luminanceLevel.%1").arg(QString::number(i)), [this, i]() { m_inputController.setLuminanceLevel(i); - }); - addControlledAction(solarMenu, setSolar, QString("luminanceLevel.%1").arg(QString::number(i))); + }, "solar"); } #ifdef M_CORE_GB - QAction* gbPrint = new QAction(tr("Game Boy Printer..."), emulationMenu); - connect(gbPrint, &QAction::triggered, [this]() { + Action* gbPrint = addGameAction(tr("Game Boy Printer..."), "gbPrint", [this]() { PrinterView* view = new PrinterView(m_controller); openView(view); m_controller->attachPrinter(); - - }); - addControlledAction(emulationMenu, gbPrint, "gbPrint"); - m_gameActions.append(gbPrint); + }, "emu"); + m_platformActions.insert(PLATFORM_GB, gbPrint); #endif #ifdef M_CORE_GBA - QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu); - connect(bcGate, &QAction::triggered, openControllerTView(this)); - addControlledAction(emulationMenu, bcGate, "bcGate"); - m_gbaActions.append(bcGate); - m_gameActions.append(bcGate); + Action* bcGate = addGameAction(tr("BattleChip Gate..."), "bcGate", openControllerTView(this), "emu"); + m_platformActions.insert(PLATFORM_GBA, bcGate); #endif - QMenu* avMenu = menubar->addMenu(tr("Audio/&Video")); - m_shortcutController->addMenu(avMenu); - QMenu* frameMenu = avMenu->addMenu(tr("Frame size")); - m_shortcutController->addMenu(frameMenu, avMenu); + m_actions.addMenu(tr("Audio/&Video"), "av"); + m_actions.addMenu(tr("Frame size"), "frame", "av"); for (int i = 1; i <= 6; ++i) { - QAction* setSize = new QAction(tr("%1x").arg(QString::number(i)), avMenu); - setSize->setCheckable(true); - if (m_savedScale == i) { - setSize->setChecked(true); - } - connect(setSize, &QAction::triggered, [this, i, setSize]() { + Action* setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { + Action* setSize = m_frameSizes[i]; showNormal(); QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); if (m_controller) { @@ -1419,11 +1295,14 @@ void Window::setupMenu(QMenuBar* menubar) { m_config->setOption("scaleMultiplier", i); // TODO: Port to other resizeFrame(size); bool enableSignals = setSize->blockSignals(true); - setSize->setChecked(true); + setSize->setActive(true); setSize->blockSignals(enableSignals); - }); + }, "frame"); + setSize->setExclusive(true); + if (m_savedScale == i) { + setSize->setActive(true); + } m_frameSizes[i] = setSize; - addControlledAction(frameMenu, setSize, QString("frame%1x").arg(QString::number(i))); } QKeySequence fullscreenKeys; #ifdef Q_OS_WIN @@ -1431,10 +1310,10 @@ void Window::setupMenu(QMenuBar* menubar) { #else fullscreenKeys = QKeySequence("Ctrl+F"); #endif - addControlledAction(frameMenu, frameMenu->addAction(tr("Toggle fullscreen"), this, SLOT(toggleFullScreen()), fullscreenKeys), "fullscreen"); + m_actions.addAction(tr("Toggle fullscreen"), "fullscreen", this, &Window::toggleFullScreen, "frame", fullscreenKeys); ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio"); - lockAspectRatio->addBoolean(tr("Lock aspect ratio"), avMenu); + lockAspectRatio->addBoolean(tr("Lock aspect ratio"), &m_actions, "av"); lockAspectRatio->connect([this](const QVariant& value) { if (m_display) { m_display->lockAspectRatio(value.toBool()); @@ -1446,7 +1325,7 @@ void Window::setupMenu(QMenuBar* menubar) { m_config->updateOption("lockAspectRatio"); ConfigOption* lockIntegerScaling = m_config->addOption("lockIntegerScaling"); - lockIntegerScaling->addBoolean(tr("Force integer scaling"), avMenu); + lockIntegerScaling->addBoolean(tr("Force integer scaling"), &m_actions, "av"); lockIntegerScaling->connect([this](const QVariant& value) { if (m_display) { m_display->lockIntegerScaling(value.toBool()); @@ -1458,7 +1337,7 @@ void Window::setupMenu(QMenuBar* menubar) { m_config->updateOption("lockIntegerScaling"); ConfigOption* resampleVideo = m_config->addOption("resampleVideo"); - resampleVideo->addBoolean(tr("Bilinear filtering"), avMenu); + resampleVideo->addBoolean(tr("Bilinear filtering"), &m_actions, "av"); resampleVideo->connect([this](const QVariant& value) { if (m_display) { m_display->filter(value.toBool()); @@ -1466,103 +1345,76 @@ void Window::setupMenu(QMenuBar* menubar) { }, this); m_config->updateOption("resampleVideo"); - QMenu* skipMenu = avMenu->addMenu(tr("Frame&skip")); + m_actions.addMenu(tr("Frame&skip"),"skip", "av"); ConfigOption* skip = m_config->addOption("frameskip"); skip->connect([this](const QVariant& value) { reloadConfig(); }, this); for (int i = 0; i <= 10; ++i) { - skip->addValue(QString::number(i), i, skipMenu); + skip->addValue(QString::number(i), i, &m_actions, "skip"); } m_config->updateOption("frameskip"); - avMenu->addSeparator(); + m_actions.addSeparator("av"); ConfigOption* mute = m_config->addOption("mute"); - QAction* muteAction = mute->addBoolean(tr("Mute"), avMenu); + mute->addBoolean(tr("Mute"), &m_actions, "av"); mute->connect([this](const QVariant& value) { reloadConfig(); }, this); m_config->updateOption("mute"); - addControlledAction(avMenu, muteAction, "mute"); - QMenu* target = avMenu->addMenu(tr("FPS target")); + m_actions.addMenu(tr("FPS target"),"target", "av"); ConfigOption* fpsTargetOption = m_config->addOption("fpsTarget"); - QMap fpsTargets; + QMap fpsTargets; for (int fps : {15, 30, 45, 60, 90, 120, 240}) { - fpsTargets[fps] = fpsTargetOption->addValue(QString::number(fps), fps, target); + fpsTargets[fps] = fpsTargetOption->addValue(QString::number(fps), fps, &m_actions, "target"); } - target->addSeparator(); + m_actions.addSeparator("target"); double nativeGB = double(GBA_ARM7TDMI_FREQUENCY) / double(VIDEO_TOTAL_LENGTH); - fpsTargets[nativeGB] = fpsTargetOption->addValue(tr("Native (59.7275)"), nativeGB, target); + fpsTargets[nativeGB] = fpsTargetOption->addValue(tr("Native (59.7275)"), nativeGB, &m_actions, "target"); fpsTargetOption->connect([this, fpsTargets](const QVariant& value) { reloadConfig(); for (auto iter = fpsTargets.begin(); iter != fpsTargets.end(); ++iter) { bool enableSignals = iter.value()->blockSignals(true); - iter.value()->setChecked(abs(iter.key() - value.toDouble()) < 0.001); + iter.value()->setActive(abs(iter.key() - value.toDouble()) < 0.001); iter.value()->blockSignals(enableSignals); } }, this); m_config->updateOption("fpsTarget"); - avMenu->addSeparator(); + m_actions.addSeparator("av"); #ifdef USE_PNG - QAction* screenshot = new QAction(tr("Take &screenshot"), avMenu); - screenshot->setShortcut(tr("F12")); - connect(screenshot, &QAction::triggered, [this]() { + addGameAction(tr("Take &screenshot"), "screenshot", [this]() { m_controller->screenshot(); - }); - m_gameActions.append(screenshot); - addControlledAction(avMenu, screenshot, "screenshot"); + }, "av", tr("F12")); #endif #ifdef USE_FFMPEG - QAction* recordOutput = new QAction(tr("Record output..."), avMenu); - connect(recordOutput, &QAction::triggered, this, &Window::openVideoWindow); - addControlledAction(avMenu, recordOutput, "recordOutput"); - m_gameActions.append(recordOutput); + addGameAction(tr("Record output..."), "recordOutput", this, &Window::openVideoWindow, "av"); #endif #ifdef USE_MAGICK - QAction* recordGIF = new QAction(tr("Record GIF..."), avMenu); - connect(recordGIF, &QAction::triggered, this, &Window::openGIFWindow); - addControlledAction(avMenu, recordGIF, "recordGIF"); + addGameAction(tr("Record GIF..."), "recordGIF", this, &Window::openGIFWindow, "av"); #endif - QAction* recordVL = new QAction(tr("Record video log..."), avMenu); - connect(recordVL, &QAction::triggered, this, &Window::startVideoLog); - addControlledAction(avMenu, recordVL, "recordVL"); - m_gameActions.append(recordVL); - - QAction* stopVL = new QAction(tr("Stop video log"), avMenu); - connect(stopVL, &QAction::triggered, [this]() { + addGameAction(tr("Record video log..."), "recordVL", this, &Window::startVideoLog, "av"); + addGameAction(tr("Stop video log"), "stopVL", [this]() { m_controller->endVideoLog(); - }); - addControlledAction(avMenu, stopVL, "stopVL"); - m_gameActions.append(stopVL); + }, "av"); - avMenu->addSeparator(); - m_videoLayers = avMenu->addMenu(tr("Video layers")); - m_shortcutController->addMenu(m_videoLayers, avMenu); + m_actions.addSeparator("av"); + m_actions.addMenu(tr("Video layers"), "videoLayers", "av"); + m_actions.addMenu(tr("Audio channels"), "audioChannels", "av"); - m_audioChannels = avMenu->addMenu(tr("Audio channels")); - m_shortcutController->addMenu(m_audioChannels, avMenu); + addGameAction(tr("Adjust layer placement..."), "placementControl", openControllerTView(), "av"); - QAction* placementControl = new QAction(tr("Adjust layer placement..."), avMenu); - connect(placementControl, &QAction::triggered, openControllerTView()); - m_gameActions.append(placementControl); - addControlledAction(avMenu, placementControl, "placementControl"); + m_actions.addMenu(tr("&Tools"), "tools"); + m_actions.addAction(tr("View &logs..."), "viewLogs", static_cast(m_logView), &QWidget::show, "tools"); - QMenu* toolsMenu = menubar->addMenu(tr("&Tools")); - m_shortcutController->addMenu(toolsMenu); - QAction* viewLogs = new QAction(tr("View &logs..."), toolsMenu); - connect(viewLogs, &QAction::triggered, m_logView, &QWidget::show); - addControlledAction(toolsMenu, viewLogs, "viewLogs"); - - QAction* overrides = new QAction(tr("Game &overrides..."), toolsMenu); - connect(overrides, &QAction::triggered, [this]() { + m_actions.addAction(tr("Game &overrides..."), "overrideWindow", [this]() { if (!m_overrideView) { m_overrideView = std::move(std::make_unique(m_config)); if (m_controller) { @@ -1572,11 +1424,9 @@ void Window::setupMenu(QMenuBar* menubar) { } m_overrideView->show(); m_overrideView->recheck(); - }); - addControlledAction(toolsMenu, overrides, "overrideWindow"); + }, "tools"); - QAction* sensors = new QAction(tr("Game &Pak sensors..."), toolsMenu); - connect(sensors, &QAction::triggered, [this]() { + m_actions.addAction(tr("Game &Pak sensors..."), "sensorWindow", [this]() { if (!m_sensorView) { m_sensorView = std::move(std::make_unique(&m_inputController)); if (m_controller) { @@ -1585,71 +1435,33 @@ void Window::setupMenu(QMenuBar* menubar) { connect(this, &Window::shutdown, m_sensorView.get(), &QWidget::close); } m_sensorView->show(); - }); - addControlledAction(toolsMenu, sensors, "sensorWindow"); + }, "tools"); - QAction* cheats = new QAction(tr("&Cheats..."), toolsMenu); - connect(cheats, &QAction::triggered, openControllerTView()); - m_gameActions.append(cheats); - addControlledAction(toolsMenu, cheats, "cheatsWindow"); + addGameAction(tr("&Cheats..."), "cheatsWindow", openControllerTView(), "tools"); - toolsMenu->addSeparator(); - addControlledAction(toolsMenu, toolsMenu->addAction(tr("Settings..."), this, SLOT(openSettingsWindow())), - "settings"); - - toolsMenu->addSeparator(); + m_actions.addSeparator("tools"); + m_actions.addAction(tr("Settings..."), "settings", this, &Window::openSettingsWindow, "tools"); #ifdef USE_DEBUGGERS - QAction* consoleWindow = new QAction(tr("Open debugger console..."), toolsMenu); - connect(consoleWindow, &QAction::triggered, this, &Window::consoleOpen); - addControlledAction(toolsMenu, consoleWindow, "debuggerWindow"); -#endif - + m_actions.addSeparator("tools"); + m_actions.addAction(tr("Open debugger console..."), "debuggerWindow", this, &Window::consoleOpen, "tools"); #ifdef USE_GDB_STUB - QAction* gdbWindow = new QAction(tr("Start &GDB server..."), toolsMenu); - connect(gdbWindow, &QAction::triggered, this, &Window::gdbOpen); - m_gbaActions.append(gdbWindow); - m_gameActions.append(gdbWindow); - addControlledAction(toolsMenu, gdbWindow, "gdbWindow"); + Action* gdbWindow = addGameAction(tr("Start &GDB server..."), "gdbWindow", this, &Window::gdbOpen, "tools"); + m_platformActions.insert(PLATFORM_GBA, gdbWindow); #endif - toolsMenu->addSeparator(); +#endif + m_actions.addSeparator("tools"); - QAction* paletteView = new QAction(tr("View &palette..."), toolsMenu); - connect(paletteView, &QAction::triggered, openControllerTView()); - m_gameActions.append(paletteView); - addControlledAction(toolsMenu, paletteView, "paletteWindow"); - - QAction* objView = new QAction(tr("View &sprites..."), toolsMenu); - connect(objView, &QAction::triggered, openControllerTView()); - m_gameActions.append(objView); - addControlledAction(toolsMenu, objView, "spriteWindow"); - - QAction* tileView = new QAction(tr("View &tiles..."), toolsMenu); - connect(tileView, &QAction::triggered, openControllerTView()); - m_gameActions.append(tileView); - addControlledAction(toolsMenu, tileView, "tileWindow"); - - QAction* mapView = new QAction(tr("View &map..."), toolsMenu); - connect(mapView, &QAction::triggered, openControllerTView()); - m_gameActions.append(mapView); - addControlledAction(toolsMenu, mapView, "mapWindow"); - - QAction* memoryView = new QAction(tr("View memory..."), toolsMenu); - connect(memoryView, &QAction::triggered, openControllerTView()); - m_gameActions.append(memoryView); - addControlledAction(toolsMenu, memoryView, "memoryView"); - - QAction* memorySearch = new QAction(tr("Search memory..."), toolsMenu); - connect(memorySearch, &QAction::triggered, openControllerTView()); - m_gameActions.append(memorySearch); - addControlledAction(toolsMenu, memorySearch, "memorySearch"); + addGameAction(tr("View &palette..."), "paletteWindow", openControllerTView(), "tools"); + addGameAction(tr("View &sprites..."), "spriteWindow", openControllerTView(), "tools"); + addGameAction(tr("View &tiles..."), "tileWindow", openControllerTView(), "tools"); + addGameAction(tr("View &map..."), "mapWindow", openControllerTView(), "tools"); + addGameAction(tr("View memory..."), "memoryView", openControllerTView(), "tools"); + addGameAction(tr("Search memory..."), "memorySearch", openControllerTView(), "tools"); #ifdef M_CORE_GBA - QAction* ioViewer = new QAction(tr("View &I/O registers..."), toolsMenu); - connect(ioViewer, &QAction::triggered, openControllerTView()); - m_gameActions.append(ioViewer); - m_gbaActions.append(ioViewer); - addControlledAction(toolsMenu, ioViewer, "ioViewer"); + Action* ioViewer = addGameAction(tr("View &I/O registers..."), "ioViewer", openControllerTView(), "tools"); + m_platformActions.insert(PLATFORM_GBA, ioViewer); #endif ConfigOption* skipBios = m_config->addOption("skipBios"); @@ -1729,87 +1541,72 @@ void Window::setupMenu(QMenuBar* menubar) { } }, this); - QAction* exitFullScreen = new QAction(tr("Exit fullscreen"), frameMenu); - connect(exitFullScreen, &QAction::triggered, this, &Window::exitFullScreen); - exitFullScreen->setShortcut(QKeySequence("Esc")); - addHiddenAction(frameMenu, exitFullScreen, "exitFullScreen"); + m_actions.addHiddenAction(tr("Exit fullscreen"), "exitFullScreen", this, &Window::exitFullScreen, "frame", QKeySequence("Esc")); - m_shortcutController->addFunctions(toolsMenu, [this]() { + m_actions.addHeldAction(tr("GameShark Button (held)"), "holdGSButton", [this](bool held) { if (m_controller) { - mCheatPressButton(m_controller->cheatDevice(), true); + mCheatPressButton(m_controller->cheatDevice(), held); } - }, [this]() { + }, "tools", QKeySequence(Qt::Key_Apostrophe)); + + m_actions.addHiddenMenu(tr("Autofire"), "autofire"); + m_actions.addHeldAction(tr("Autofire A"), "autofireA", [this](bool held) { if (m_controller) { - mCheatPressButton(m_controller->cheatDevice(), false); + m_controller->setAutofire(GBA_KEY_A, held); } - }, QKeySequence(Qt::Key_Apostrophe), tr("GameShark Button (held)"), "holdGSButton"); + }, "autofire"); + m_actions.addHeldAction(tr("Autofire B"), "autofireB", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_B, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire L"), "autofireL", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_L, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire R"), "autofireR", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_R, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Start"), "autofireStart", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_START, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Select"), "autofireSelect", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_SELECT, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Up"), "autofireUp", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_UP, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Right"), "autofireRight", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_RIGHT, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Down"), "autofireDown", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_DOWN, held); + } + }, "autofire"); + m_actions.addHeldAction(tr("Autofire Left"), "autofireLeft", [this](bool held) { + if (m_controller) { + m_controller->setAutofire(GBA_KEY_LEFT, held); + } + }, "autofire"); - QMenu* autofireMenu = new QMenu(tr("Autofire"), this); - m_shortcutController->addMenu(autofireMenu); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_A, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_A, false); - }, QKeySequence(), tr("Autofire A"), "autofireA"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_B, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_B, false); - }, QKeySequence(), tr("Autofire B"), "autofireB"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_L, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_L, false); - }, QKeySequence(), tr("Autofire L"), "autofireL"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_R, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_R, false); - }, QKeySequence(), tr("Autofire R"), "autofireR"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_START, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_START, false); - }, QKeySequence(), tr("Autofire Start"), "autofireStart"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_SELECT, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_SELECT, false); - }, QKeySequence(), tr("Autofire Select"), "autofireSelect"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_UP, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_UP, false); - }, QKeySequence(), tr("Autofire Up"), "autofireUp"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_RIGHT, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_RIGHT, false); - }, QKeySequence(), tr("Autofire Right"), "autofireRight"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_DOWN, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_DOWN, false); - }, QKeySequence(), tr("Autofire Down"), "autofireDown"); - - m_shortcutController->addFunctions(autofireMenu, [this]() { - m_controller->setAutofire(GBA_KEY_LEFT, true); - }, [this]() { - m_controller->setAutofire(GBA_KEY_LEFT, false); - }, QKeySequence(), tr("Autofire Left"), "autofireLeft"); - - for (QAction* action : m_gameActions) { - action->setDisabled(true); + for (Action* action : m_gameActions) { + action->setEnabled(false); } + + m_shortcutController->rebuildItems(); + m_actions.rebuildMenu(menubar, *m_shortcutController); } void Window::attachWidget(QWidget* widget) { @@ -1835,38 +1632,46 @@ void Window::appendMRU(const QString& fname) { } void Window::updateMRU() { - if (!m_mruMenu) { - return; - } - for (QAction* action : m_mruMenu->actions()) { - delete action; - } - m_mruMenu->clear(); + m_actions.clearMenu("mru"); int i = 0; for (const QString& file : m_mruFiles) { - QAction* item = new QAction(QDir::toNativeSeparators(file).replace("&", "&&"), m_mruMenu); - item->setShortcut(QString("Ctrl+%1").arg(i)); - connect(item, &QAction::triggered, [this, file]() { + QString displayName(QDir::toNativeSeparators(file).replace("&", "&&")); + m_actions.addAction(displayName, QString("mru.%1").arg(QString::number(i)), [this, file]() { setController(m_manager->loadGame(file), file); - }); - m_mruMenu->addAction(item); + }, "mru", QString("Ctrl+%1").arg(i)); ++i; } m_config->setMRU(m_mruFiles); m_config->write(); - m_mruMenu->setEnabled(i > 0); + m_actions.rebuildMenu(menuBar(), *m_shortcutController); } -QAction* Window::addControlledAction(QMenu* menu, QAction* action, const QString& name) { - addHiddenAction(menu, action, name); - menu->addAction(action); +Action* Window::addGameAction(const QString& visibleName, const QString& name, Action::Function function, const QString& menu, const QKeySequence& shortcut) { + Action* action = m_actions.addAction(visibleName, name, [this, function]() { + if (m_controller) { + function(); + } + }, menu, shortcut); + m_gameActions.append(action); return action; } -QAction* Window::addHiddenAction(QMenu* menu, QAction* action, const QString& name) { - m_shortcutController->addAction(menu, action, name); - action->setShortcutContext(Qt::WidgetShortcut); - addAction(action); +template +Action* Window::addGameAction(const QString& visibleName, const QString& name, T* obj, V (T::*method)(), const QString& menu, const QKeySequence& shortcut) { + return addGameAction(visibleName, name, [this, obj, method]() { + if (m_controller) { + (obj->*method)(); + } + }, menu, shortcut); +} + +Action* Window::addGameAction(const QString& visibleName, const QString& name, Action::BooleanFunction function, const QString& menu, const QKeySequence& shortcut) { + Action* action = m_actions.addBooleanAction(visibleName, name, [this, function](bool value) { + if (m_controller) { + function(value); + } + }, menu, shortcut); + m_gameActions.append(action); return action; } diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index f30e524af..01d036d32 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -15,8 +15,10 @@ #include #include +#include #include +#include "ActionMapper.h" #include "InputController.h" #include "LoadSaveState.h" #include "LogController.h" @@ -156,8 +158,9 @@ private: template std::function openTView(A... arg); template std::function openControllerTView(A... arg); - QAction* addControlledAction(QMenu* menu, QAction* action, const QString& name); - QAction* addHiddenAction(QMenu* menu, QAction* action, const QString& name); + Action* addGameAction(const QString& visibleName, const QString& name, Action::Function action, const QString& menu = {}, const QKeySequence& = {}); + template Action* addGameAction(const QString& visibleName, const QString& name, T* obj, V (T::*action)(), const QString& menu = {}, const QKeySequence& = {}); + Action* addGameAction(const QString& visibleName, const QString& name, Action::BooleanFunction action, const QString& menu = {}, const QKeySequence& = {}); void updateTitle(float fps = -1); @@ -170,14 +173,17 @@ private: std::unique_ptr m_display; int m_savedScale; + // TODO: Move these to a new class - QList m_gameActions; - QList m_nonMpActions; + ActionMapper m_actions; + QList m_gameActions; + QList m_nonMpActions; #ifdef M_CORE_GBA - QList m_gbaActions; + QMultiMap m_platformActions; #endif - QAction* m_multiWindow; - QMap m_frameSizes; + Action* m_multiWindow; + QMap m_frameSizes; + LogController m_log{0}; LogView* m_logView; #ifdef USE_DEBUGGERS @@ -192,9 +198,6 @@ private: QElapsedTimer m_frameTimer; QTimer m_fpsTimer; QList m_mruFiles; - QMenu* m_mruMenu = nullptr; - QMenu* m_videoLayers; - QMenu* m_audioChannels; ShortcutController* m_shortcutController; #if defined(BUILD_GL) || defined(BUILD_GLES2) std::unique_ptr m_shaderView; From 62b801c851cfac59718a60f47480e9545c9a01e4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 May 2019 14:15:44 -0700 Subject: [PATCH 165/429] Qt: Clarify recording options --- src/platform/qt/Window.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index b8c686fe8..0e56194b3 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1393,18 +1393,13 @@ void Window::setupMenu(QMenuBar* menubar) { #endif #ifdef USE_FFMPEG - addGameAction(tr("Record output..."), "recordOutput", this, &Window::openVideoWindow, "av"); + addGameAction(tr("Record A/V..."), "recordOutput", this, &Window::openVideoWindow, "av"); #endif #ifdef USE_MAGICK addGameAction(tr("Record GIF..."), "recordGIF", this, &Window::openGIFWindow, "av"); #endif - addGameAction(tr("Record video log..."), "recordVL", this, &Window::startVideoLog, "av"); - addGameAction(tr("Stop video log"), "stopVL", [this]() { - m_controller->endVideoLog(); - }, "av"); - m_actions.addSeparator("av"); m_actions.addMenu(tr("Video layers"), "videoLayers", "av"); m_actions.addMenu(tr("Audio channels"), "audioChannels", "av"); @@ -1464,6 +1459,12 @@ void Window::setupMenu(QMenuBar* menubar) { m_platformActions.insert(PLATFORM_GBA, ioViewer); #endif + m_actions.addSeparator("tools"); + addGameAction(tr("Record debug video log..."), "recordVL", this, &Window::startVideoLog, "tools"); + addGameAction(tr("Stop debug video log"), "stopVL", [this]() { + m_controller->endVideoLog(); + }, "tools"); + ConfigOption* skipBios = m_config->addOption("skipBios"); skipBios->connect([this](const QVariant& value) { reloadConfig(); From 58684d8cda98a33d03297e01be1345c6e4a60231 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 4 May 2019 19:45:21 -0700 Subject: [PATCH 166/429] Qt: Fix build --- src/platform/qt/ShortcutController.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/ShortcutController.h b/src/platform/qt/ShortcutController.h index ef90d3eaf..3a82f034d 100644 --- a/src/platform/qt/ShortcutController.h +++ b/src/platform/qt/ShortcutController.h @@ -9,6 +9,7 @@ #include "GamepadAxisEvent.h" #include +#include #include #include @@ -116,7 +117,7 @@ private: QHash> m_items; QHash> m_buttons; - QHash, std::shared_ptr> m_axes; + QMap, std::shared_ptr> m_axes; QHash> m_heldKeys; ActionMapper* m_actions = nullptr; ConfigController* m_config = nullptr; From 88006148c983235522766ffdba04f23ce639653f Mon Sep 17 00:00:00 2001 From: EmpyreusX <36258024+EmpyreusX@users.noreply.github.com> Date: Sun, 5 May 2019 15:26:34 +0800 Subject: [PATCH 167/429] Update mgba-zh_CN.ts Fully retranslated and re-aligned zh-CN lang file (again, with all strings fixed). --- src/platform/qt/ts/mgba-zh_CN.ts | 2323 ++++++++++++++++-------------- 1 file changed, 1250 insertions(+), 1073 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 16f9ec4a6..b60a570ad 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -11,12 +11,12 @@ <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> - <a href="http://mgba.io/">主页</a> • <a href="https://forums.mgba.io/">论坛 / 支持</a> • <a href="https://patreon.com/mgba">捐助</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">源代码</a> + <a href="http://mgba.io/">网站</a> • <a href="https://forums.mgba.io/">论坛、支持</a> • <a href="https://patreon.com/mgba">捐助</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">源代码</a> Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> - 分支: <tt>{gitBranch}</tt><br/>修订: <tt>{gitCommit}</tt> + 分支: <tt>{gitBranch}</tt><br/>修订版: <tt>{gitCommit}</tt> @@ -32,8 +32,8 @@ © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 – 2018 Jeffrey Pfau, 授权基于Mozilla公共授权 MPLv2.0 -Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 + © 2013 – 2018 Jeffrey Pfau,基于Mozilla公共许可证(版本 2.0)授权 +Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标。 @@ -61,7 +61,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Open in archive... - 打开记录... + 在压缩文件中打开... @@ -125,6 +125,84 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 0x00 (00) + + BattleChipView + + + BattleChip Gate + BattleChip Gate + + + + Chip name + 晶片名称 + + + + Insert + 插入 + + + + Save + 保存 + + + + Load + 载入 + + + + Add + 添加 + + + + Remove + 移除 + + + + Gate type + 装置类型 + + + + Ba&ttleChip Gate + BattleChip Gate(&T) + + + + Progress &Gate + Progress Gate(&G) + + + + Beast &Link Gate + Beast Link(&L) + + + + Inserted + 已插入 + + + + Chip ID + 晶片ID + + + + Update Chip data + 更新晶片数据 + + + + Show advanced + 显示高级选项 + + CheatsView @@ -168,7 +246,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Enter command (try `help` for more info) - 输入命令(尝试 `help` 以获取更多信息) + 输入命令(尝试输入 `help` 以获取更多信息) @@ -181,7 +259,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Record GIF - 录制GIF + 录制 GIF @@ -196,7 +274,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Select File - 选取文件 + 选择文件 @@ -211,7 +289,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Automatic - 自动设置帧延迟 + 自动设置 @@ -341,7 +419,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 %1 State - %1 状态 + %1 即时存档 @@ -359,47 +437,47 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 1 - + 1 2 - + 2 3 - + 3 4 - + 4 5 - + 5 6 - + 6 7 - + 7 8 - + 8 9 - + 9 @@ -422,7 +500,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Stub - + 桩件 @@ -530,22 +608,22 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Guess - + 猜测 1 Byte (8-bit) - + 1 字节 (8 位) 2 Bytes (16-bit) - + 2 字节 (16 位) 4 Bytes (32-bit) - + 4 字节 (32 位) @@ -570,7 +648,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Equal - 相等 + 等于 @@ -623,7 +701,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 0x - + 0 @@ -632,56 +710,56 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 - 1 Byte - + &1 Byte + 1 字节(&1) - 2 Bytes - + &2 Bytes + 2 字节(&2) - 4 Bytes - + &4 Bytes + 4 字节(&4) - + Unsigned Integer: 无符号整数: - + Signed Integer: 有符号整数: - + String: - 字符串 : + 字符串: - + Load TBL 载入 TBL - + Copy Selection 复制所选 - + Paste 粘贴 - + Save Selection 保存所选 - + Load 载入 @@ -691,18 +769,18 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Sprites - Sprites + 精灵图 × - + × Magnification - 放大率 + 缩放率 @@ -712,7 +790,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Attributes - Attributes + 属性 @@ -722,7 +800,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Off - Off + @@ -740,7 +818,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Double Size - Double Size + 双倍大小 @@ -748,22 +826,22 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Return, Ctrl+R - Return, Ctrl+R + 回车键、Ctrl+R Flipped - Flipped + 已翻转 H - H + 水平 V - V + 垂直 @@ -773,22 +851,22 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Normal - Normal + 普通 Mosaic - Mosaic + 马赛克 Enabled - Enabled + 已启用 Priority - Priority + 优先级 @@ -798,7 +876,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Geometry - Geometry + 几何图像 @@ -807,8 +885,8 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 - , - , + , + , @@ -837,12 +915,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Game Overrides - + 游戏覆盖 Game Boy Advance - + Game Boy Advance @@ -865,12 +943,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Tilt - 贴图 + 图块 Light sensor - 光传感器 + 光线传感器 @@ -891,92 +969,92 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 SRAM - + SRAM Flash 512kb - + Flash 512kb Flash 1Mb - + Flash 1Mb EEPROM - + EEPROM Idle loop - + 空循环 Game Boy Player features - Game Boy Player 特性 + Game Boy Player 功能 Game Boy - + Game Boy Game Boy model - Game Boy 模式 + Game Boy 模型 Game Boy (DMG) - + Game Boy (DMG) Super Game Boy (SGB) - + Super Game Boy (SGB) Game Boy Color (CGB) - + Game Boy Color (CGB) Game Boy Advance (AGB) - + Game Boy Advance (AGB) Memory bank controller - 内部存储控制器 + 内存 bank 控制器 MBC1 - + MBC1 MBC2 - + MBC2 MBC3 - + MBC3 MBC3 + RTC - + MBC3 + RTC MBC5 - + MBC5 @@ -986,22 +1064,22 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 MBC7 - + MBC7 Pocket Cam - + Pocket Cam TAMA5 - + TAMA5 HuC-3 - + HuC-3 @@ -1011,12 +1089,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Sprite Colors 1 - + 精灵图颜色 1 Sprite Colors 2 - + 精灵图颜色 2 @@ -1061,12 +1139,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 0x00 (00) - + 0x00 (00) 16-bit value - 16-bit 值 + 16 位数值 @@ -1076,33 +1154,31 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Palette index - + 调色板索引 0x0000 - + 0x0000 #000000 - + #000000 000 - + 000 Export BG - BG是什么 - 导出 BG + 导出背景 Export OBJ - OBJ是什么 导出 OBJ @@ -1111,7 +1187,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Adjust placement - 更改部署 + 更改布局 @@ -1121,17 +1197,17 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Offset - 抵消 + 偏移 X - + X Y - + Y @@ -1139,17 +1215,17 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Game Boy Printer - + Game Boy 打印机 Hurry up! - + Hurry up! Tear off - + Tear off @@ -1157,14 +1233,14 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 %0%1%2 - + %0%1%2 0x%0 (%1) - + 0x%0 (%1) @@ -1172,17 +1248,17 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Can't set format of context-less audio device - + 无法设置无上下文音频设备的格式 Audio device is missing its core - + 音频设备缺少核心 Writing data to read-only audio device - + 正在将数据写入只读音频设备 @@ -1190,7 +1266,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Can't start an audio processor without input - + 无法在无输入的情况下启动音频处理器 @@ -1198,7 +1274,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Can't start an audio processor without input - + 无法在无输入的情况下启动音频处理器 @@ -1211,7 +1287,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Failed to open cheats file: %1 - 打开作弊码文件失败 : %1 + 打开作弊码文件失败: %1 @@ -1247,24 +1323,24 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 QGBA::CoreController - + Failed to open save file: %1 无法打开存档: %1 - + Failed to open game file: %1 - 无法打开游戏文件 : %1 + 无法打开游戏文件: %1 - + Failed to open snapshot file for reading: %1 - 无法读取快照文件 : %1 + 无法读取快照文件: %1 - + Failed to open snapshot file for writing: %1 - 无法写入快照文件 : %1 + 无法写入快照文件: %1 @@ -1272,7 +1348,15 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Failed to open game file: %1 - 无法打开游戏文件 : %1 + 无法打开游戏文件: %1 + + + + QGBA::GBAApp + + + Enable Discord Rich Presence + 启用 Discord Rich Presence @@ -1285,7 +1369,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Clear Analog - 清除 Analog + 清除模拟控制 @@ -1303,22 +1387,22 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Server settings - + 服务器设置 Local port - + 本地端口 Bind address - + 绑定地址 Break - + 断点 @@ -1338,7 +1422,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Could not start GDB server - 无法打开GDB服务端 + 无法打开 GDB 服务端 @@ -1346,7 +1430,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Failed to open output GIF file: %1 - 无法打开输出的GIF文件 : %1 + 无法打开输出的 GIF 文件: %1 @@ -1356,7 +1440,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Graphics Interchange Format (*.gif) - + 图形交换格式 (*.gif) @@ -1369,37 +1453,37 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Mode 0: 4 tile layers - + 模式0: 4个图块层 Mode 1: 2 tile layers + 1 rotated/scaled tile layer - + 模式 1: 2个图块层 + 1个已旋转/缩放图块层 Mode 2: 2 rotated/scaled tile layers - + 模式 2: 2个已旋转/缩放图块层 Mode 3: Full 15-bit bitmap - + 模式 3: 完整15位位图 Mode 4: Full 8-bit bitmap - + 模式 4: 完整8位位图 Mode 5: Small 15-bit bitmap - + 模式 5: 15位小位图 CGB Mode - + CGB 模式 @@ -1409,12 +1493,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Unlocked HBlank - + 已解锁 HBlank Linear OBJ tile mapping - + 线性 OBJ 图块映射 @@ -1424,82 +1508,82 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Enable background 0 - + 启用背景 0 Enable background 1 - + 启用背景 1 Enable background 2 - + 启用背景 2 Enable background 3 - + 启用背景 3 Enable OBJ - + 启用 OBJ Enable Window 0 - + 启用窗口 0 Enable Window 1 - + 启用窗口 1 Enable OBJ Window - + 启用 OBJ 窗口 Currently in VBlank - + 当前 (VBlank) Currently in HBlank - + 当前 (HBlank) Currently in VCounter - + 当前 (VCounter) Enable VBlank IRQ generation - + 启用 VBlank IRQ 生成 Enable HBlank IRQ generation - + 启用 HBlank IRQ 生成 Enable VCounter IRQ generation - + 启用 VCounter IRQ 生成 VCounter scanline - + VCounter 扫描线 Current scanline - + 当前扫描线 @@ -1515,7 +1599,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Tile data base (* 16kB) - + 图块数据基 (* 16kB) @@ -1523,7 +1607,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Enable mosaic - + 启用马赛克 @@ -1531,7 +1615,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Enable 256-color - 启用256色 + 启用 256 色 @@ -1539,7 +1623,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Tile map base (* 2kB) - + 图块映射基 (* 2kB) @@ -1547,13 +1631,13 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Background dimensions - + 背景维度 Overflow wraps - + 溢出包装 @@ -1561,7 +1645,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Horizontal offset - + 水平偏移量 @@ -1569,7 +1653,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Vertical offset - + 垂直偏移量 @@ -1585,7 +1669,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Fractional part - + 分数部分 @@ -1597,7 +1681,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Integer part - + 整数部分 @@ -1605,7 +1689,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Integer part (bottom) - + 整数部分 (低位) @@ -1613,286 +1697,286 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Integer part (top) - + 整数部分 (高位) End x - + 结束 x 轴 Start x - + 起始 x 轴 End y - + 结束 y 轴 Start y - + 起始 y 轴 Window 0 enable BG 0 - + 窗口 0 启用背景 0 Window 0 enable BG 1 - + 窗口 0 启用背景 1 Window 0 enable BG 2 - + 窗口 0 启用背景 2 Window 0 enable BG 3 - + 窗口 0 启用背景 3 Window 0 enable OBJ - + 窗口 0 启用 OBJ Window 0 enable blend - + Windows 0 启用叠加 Window 1 enable BG 0 - + 窗口 1 启用背景 0 Window 1 enable BG 1 - + 窗口 1 启用背景 1 Window 1 enable BG 2 - + 窗口 1 启用背景 2 Window 1 enable BG 3 - + 窗口 1 启用背景 3 Window 1 enable OBJ - + 窗口 1 启用 OBJ Window 1 enable blend - + 窗口 1 启用叠加 Outside window enable BG 0 - + 外部窗口启用背景 0 Outside window enable BG 1 - + 外部窗口启用背景 1 Outside window enable BG 2 - + 外部窗口启用背景 2 Outside window enable BG 3 - + 外部窗口启用背景 3 Outside window enable OBJ - + 外部窗口启用 OBJ Outside window enable blend - + 外部窗口启用叠加 OBJ window enable BG 0 - + OBJ 窗口启用背景 0 OBJ window enable BG 1 - + OBJ 窗口启用背景 1 OBJ window enable BG 2 - + OBJ 窗口启用背景 2 OBJ window enable BG 3 - + OBJ 窗口启用背景 3 OBJ window enable OBJ - + OBJ 窗口启用 OBJ OBJ window enable blend - + OBJ 窗口启用叠加 Background mosaic size vertical - + 背景马赛克垂直大小 Background mosaic size horizontal - + 背景马赛克水平大小 Object mosaic size vertical - + 对象马赛克垂直大小 Object mosaic size horizontal - + 对象马赛克水平大小 BG 0 target 1 - + 背景 0 目标 1 BG 1 target 1 - + 背景 1 目标 1 BG 2 target 1 - + 背景 2 目标 1 BG 3 target 1 - + 背景 3 目标 1 OBJ target 1 - + OBJ 目标 1 Backdrop target 1 - + 背景目标 1 Blend mode - + 叠加模式 Disabled - 禁用 + 已禁用 Additive blending - + 加性叠加 Brighten - + 增加亮度 Darken - + 降低亮度 BG 0 target 2 - + 背景 0 目标 2 BG 1 target 2 - + 背景 1 目标 2 BG 2 target 2 - + 背景 2 目标 2 BG 3 target 2 - + 背景 3 目标 2 OBJ target 2 - + OBJ 目标 2 Backdrop target 2 - + 背景目标 2 Blend A (target 1) - + 叠加 A (目标 1) Blend B (target 2) - + 叠加 B (目标 2) Blend Y - + 叠加 Y Sweep shifts - + 扫描 shifts Sweep subtract - + 扫描 subtract Sweep time (in 1/128s) - + 扫描时间 (1/128秒) @@ -1900,27 +1984,27 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Sound length - + 声音长度 Duty cycle - + 占空比 Envelope step time - + 包络步进时间 Envelope increase - + 增加包络 @@ -1942,7 +2026,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Timed - + 已时控 @@ -1955,45 +2039,45 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Double-size wave table - + 双尺寸波形表 Active wave table - + 激活波形表 Enable channel 3 - + 启用通道 3 Volume - + 音量 0% - + 0% 100% - + 100% 50% - + 50% 25% - + 25% @@ -2001,118 +2085,118 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 75% - + 75% Clock divider - + 时钟分频器 Register stages - + 寄存器阶段 15 - + 15 7 - + 7 Shifter frequency - + 移位器频率 PSG volume right - + PSG 右侧音量 PSG volume left - + PSG 左侧音量 Enable channel 1 right - + 启用右侧通道 1 Enable channel 2 right - + 启用右侧通道 2 Enable channel 3 right - + 启用右侧通道 3 Enable channel 4 right - + 启用右侧通道 4 Enable channel 1 left - + 启用左侧通道 1 Enable channel 2 left - + 启用左侧通道 2 Enable channel 3 left - + 启用左侧通道 3 Enable channel 4 left - + 启用左侧通道 4 PSG master volume - + PSG 主音量 Loud channel A - + 响音通道 A Loud channel B - + 响音通道 B Enable channel A right - + 启用右侧通道 A Enable channel A left - + 启用右侧通道 A Channel A timer - + 通道 A 时控器 0 - + 0 @@ -2125,52 +2209,52 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 1 - + 1 Channel A reset - + 通道 A 重置 Enable channel B right - + 启用右侧通道 B Enable channel B left - + 启用左侧通道 B Channel B timer - + 通道 B 时控器 Channel B reset - + 通道 B 重置 Active channel 1 - + 激活通道 1 Active channel 2 - + 激活通道 2 Active channel 3 - + 激活通道 3 Active channel 4 - + 激活通道 4 @@ -2180,7 +2264,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Bias - + 偏差 @@ -2229,7 +2313,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Sample - + 采样 @@ -2241,7 +2325,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Address (bottom) - + 地址 (低位) @@ -2253,7 +2337,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Address (top) - + 地址 (高位) @@ -2261,7 +2345,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Word count - + 字数 @@ -2269,7 +2353,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Destination offset - + 目标偏移 @@ -2281,7 +2365,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Increment - + 增量 @@ -2293,7 +2377,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Decrement - + 减量 @@ -2305,7 +2389,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Fixed - + 固定 @@ -2313,7 +2397,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Increment and reload - + 增量并重新加载 @@ -2321,7 +2405,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Source offset - + 源偏移 @@ -2329,7 +2413,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Repeat - + 重复 @@ -2337,7 +2421,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 32-bit - + 32 位 @@ -2345,7 +2429,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Start timing - + 开始定时 @@ -2353,7 +2437,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Immediate - + 立即 @@ -2363,7 +2447,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 VBlank - + VBlank @@ -2373,7 +2457,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 HBlank - + HBlank @@ -2386,7 +2470,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 IRQ - + IRQ @@ -2398,24 +2482,24 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Enable - + 启用 Audio FIFO - + 音频 FIFO Video Capture - + 视频截取 DRQ - + DRQ @@ -2423,7 +2507,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Value - + @@ -2431,7 +2515,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Scale - + 比例 @@ -2439,7 +2523,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 1/64 - + 1/64 @@ -2447,7 +2531,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 1/256 - + 1/256 @@ -2455,38 +2539,38 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 1/1024 - + 1/1024 Cascade - + 级联 A - + A B - + B Select - 选择 + Select Start - 开始 + Start @@ -2516,115 +2600,115 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 R - + R L - + L Condition - + 状态 SC - + SC SD - + SD SI - + SI SO - + SO VCounter - + VCounter Timer 0 - + Timer 0 Timer 1 - + Timer 1 Timer 2 - + Timer 2 Timer 3 - + Timer 3 SIO - + SIO DMA 0 - + DMA 0 DMA 1 - + DMA 1 DMA 2 - + DMA 2 DMA 3 - + DMA 3 Keypad - + 键盘 Gamepak - + 游戏卡带 SRAM wait - + SRAM 等待 @@ -2633,7 +2717,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 4 - + 4 @@ -2641,7 +2725,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 3 - + 3 @@ -2650,7 +2734,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 2 - + 2 @@ -2659,42 +2743,42 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 8 - + 8 Cart 0 non-sequential - + Cart 0 (非顺序) Cart 0 sequential - + Cart 0 (顺序) Cart 1 non-sequential - + Cart 1 (非顺序) Cart 1 sequential - + Cart 1 (顺序) Cart 2 non-sequential - + Cart 2 (非顺序) Cart 2 sequential - + Cart 2 (顺序) PHI terminal - + PHI 终端 @@ -2704,27 +2788,27 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 4.19MHz - + 4.19MHz 8.38MHz - + 8.38MHz 16.78MHz - + 16.78MHz Gamepak prefetch - + 游戏卡带预读取 Enable IRQs - + 启用 IRQ @@ -2733,73 +2817,122 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 --- - + --- QGBA::LoadSaveState - + Load State - 载入快照 + 载入即时存档 - + Save State - 存档 + 即时存档 - + Empty - + - + Corrupted - + 已损坏 - + Slot %1 - + 插槽 %1 + + + + QGBA::LogConfigModel + + + + Default + 默认 + + + + Fatal + 致命错误 + + + + Error + 错误 + + + + Warning + 警告 + + + + Info + 信息 + + + + Debug + 调试 + + + + Stub + 桩位 + + + + Game Error + 游戏错误 QGBA::LogController - + + [%1] %2: %3 + [%1] %2: %3 + + + DEBUG - + DEBUG - + STUB - + STUB - + INFO - + INFO - + WARN - + WARN - + ERROR - + ERROR - + FATAL - + FATAL - + GAME ERROR - + GAME ERROR @@ -2807,47 +2940,47 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Map Addr. - + 映射地址 Mirror - + 镜像 None - + Both - + 两者 Horizontal - + 水平 Vertical - + 垂直 Export map - + 导出映射 Portable Network Graphics (*.png) - + 便携式网络图形 (*.png) Failed to open output PNG file: %1 - 输出PNG文件开启失败: %1 + 打开输出 PNG 文件失败: %1 @@ -2874,7 +3007,6 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 - All 全部 @@ -2884,34 +3016,34 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 载入 TBL - + Save selected memory 保存所选内存 - + Failed to open output file: %1 - 无法打开输出文件 : %1 + 无法打开输出文件: %1 - + Load memory 载入内存 - + Failed to open input file: %1 - 无法打开输入文件 : %1 + 无法打开输入文件: %1 - + TBL - + TBL - + ISO-8859-1 - + ISO-8859-1 @@ -2919,77 +3051,77 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 (%0/%1×) - + (%0/%1×) (⅟%0×) - + (⅟%0×) (%0×) - + (%0×) %1 byte%2 - + %1 字节%2 QGBA::ObjView - - + + 0x%0 - + 0x%0 - + Off - - - - - Normal - + - Trans - + Normal + 一般 - OBJWIN - + Trans + Trans + OBJWIN + OBJWIN + + + Invalid 无效 - - + + N/A - + - + Export sprite - - - - - Portable Network Graphics (*.png) - + 导出精灵图 + Portable Network Graphics (*.png) + 便携式网络图形 (*.png) + + + Failed to open output PNG file: %1 - 无法打开输出的PNG文件: %1 + 无法打开输出的 PNG 文件: %1 @@ -2997,39 +3129,39 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 #%0 - + #%0 0x%0 - + 0x%0 %0 - + %0 0x%0 (%1) - + 0x%0 (%1) Export palette - 导出 调色板 + 导出调色板 Windows PAL (*.pal);;Adobe Color Table (*.act) - + Windows PAL (*.pal);;Adobe 颜色表 (*.act) Failed to open output palette file: %1 - 已输出的调色板文件打开失败: %1 + 打开输出调色板文件失败: %1 @@ -3042,7 +3174,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Portable Network Graphics (*.png) - + 便携式网络图形 (*.png) @@ -3060,72 +3192,72 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 bytes - + 字节 (no database present) - + (无现存数据库) QGBA::SettingsView - - + + Qt Multimedia - - - - - SDL - - - - - Software (Qt) - + Qt Multimedia + SDL + SDL + + + + Software (Qt) + 软件渲染 (Qt) + + + OpenGL - + OpenGL - + OpenGL (force version 1.x) - + OpenGL (强制版本 1.x) - + None (Still Image) - + 无 (静止图像) - + Keyboard 键盘 - + Controllers 控制器 - + Shortcuts 快捷键 - - + + Shaders 着色器 - + Select BIOS - 选择BIOS + 选择 BIOS @@ -3148,7 +3280,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 by %1 - + by %1 @@ -3158,7 +3290,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Pass %1 - 进行 %1 + Pass %1 @@ -3166,7 +3298,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Action - + 动作 @@ -3182,17 +3314,17 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 QGBA::VideoView - + Failed to open output video file: %1 - 无法代开输出的视频文件 : %1 + 无法打开输出的视频文件: %1 - + Native (%0x%1) - + 原生 (%0x%1) - + Select output file 选取输出文件 @@ -3200,97 +3332,108 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 QGBA::Window - + Game Boy Advance ROMs (%1) - + Game Boy Advance ROM (%1) - + Game Boy ROMs (%1) - + Game Boy ROM (%1) - + All ROMs (%1) - + 所有 ROM (%1) - + %1 Video Logs (*.mvl) %1 视频日志 (*.mvl) - + Archives (%1) - + 压缩文件 (%1) - - - + + + Select ROM - 选择ROM + 选择 ROM - + Select folder 选择文件夹 - + Game Boy Advance save files (%1) - Game Boy Advance 保存文件 (%1) + Game Boy Advance 存档文件 (%1) - - - + + + Select save - 选取存档 + 选择存档 + + mGBA savestate files (%1) + mGBA 即时存档文件 (%1) + + + + Select savestate + 选择即时存档 + + + Select patch - 选择 patch + 选择补丁 - + Patches (*.ips *.ups *.bps) - + 补丁文件 (*.ips *.ups *.bps) - + Select image - 选取图片 + 选择图片 - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) - 图片文件 (*.png *.gif *.jpg *.jpeg);;Tous les fichiers (*) + 图像文件 (*.png *.gif *.jpg *.jpeg);;所有文件 (*) - - + + GameShark saves (*.sps *.xps) - GameShark存档 (*.sps *.xps) + GameShark 存档 (*.sps *.xps) - + Select video log 选择视频日志 - + Video logs (*.mvl) 视频日志 (*.mvl) - + Crash 崩溃 - + The game has crashed with the following error: %1 @@ -3299,652 +3442,630 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 %1 - + Couldn't Load 无法载入 - + Could not load game. Are you sure it's in the correct format? - 无法载入游戏. 是否确认游戏格式无误 ? + 无法载入游戏。请确认游戏格式是否无误 - + Unimplemented BIOS call - 未实现的BIOS调用 + 未实现的 BIOS 调用 - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - 该游戏使用了尚未实现的BIOS调用。请使用官方BIOS以获得最佳的游戏体验。 + 该游戏使用了尚未实现的 BIOS 调用。请使用官方 BIOS 以获得最佳游戏体验。 - + Really make portable? - 确定进行便携化 ? + 确定进行程序便携化? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + 进行此操作后,模拟器将从模拟器可执行文件所在目录内加载模拟器配置。您想继续吗? - + Restart needed - 需要重启 + 需要重新启动 - + Some changes will not take effect until the emulator is restarted. - 一些更改将在模拟器下次启动时生效。 + 更改将在模拟器下次启动时生效。 - + - Player %1 of %2 - + - 玩家 %1 共 %2 - + %1 - %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + %1 - %2 (%3 fps) - %4 - + &File 文件(&F) - + Load &ROM... - 载入 &ROM... + 载入 ROM(&R)... - + Load ROM in archive... - 从目录中载入ROM... + 从压缩文件中载入 ROM... - + Add folder to library... - 在库中添加文件夹... + 将文件夹添加到库中... - + Load alternate save... 读取其他的存档... - + Load temporary save... 读取临时存档... - - - Load &patch... - 载入&patch文件... - - - - Boot BIOS - - - - - Replace ROM... - 替换ROM... - - - - ROM &info... - ROM信息(&I)... - - - - Recent - - - - - Make portable - 便携化 - - - - &Load state - (&L)读取存档 - - - - F10 - - - - - &Save state - &S存档 - - Shift+F10 - + Load &patch... + 载入补丁文件(&P)... - + + Boot BIOS + 引导 BIOS + + + + Replace ROM... + 替换 ROM... + + + + ROM &info... + ROM 信息(&I)... + + + + Recent + 最近打开的游戏 + + + + Make portable + 程序便携化 + + + + &Load state + 读取即时存档(&L) + + + + F10 + F10 + + + + Load state file... + 载入即时存档文件... + + + + &Save state + 保存即时存档(&S) + + + + Shift+F10 + Shift+F10 + + + + Save state file... + 保存即时存档文件... + + + Quick load 快速读档 - + Quick save 快速存档 - + Load recent - 载入最近的存档 + 载入最近的即时存档 - + Save recent - 保存最近的状态 + 保存最近的即时存档 - + Undo load state - 撤消读档操作 + 撤消读档 - + F11 - + F11 - + Undo save state 撤消存档 - + Shift+F11 - + Shift+F11 - - + + State &%1 - + 即时存档 1(&1) - + F%1 - + F%1 - + Shift+F%1 - + Shift+F%1 - + Load camera image... 读取相机图片... - + Import GameShark Save - 导入GameShark存档 + 导入 GameShark 存档 - + Export GameShark Save - 导出GameShark存档 + 导出 GameShark 存档 - + New multiplayer window - 新多人游戏窗口 + 新建多人游戏窗口 - - About - 关于 + + About... + 关于... - + E&xit - 退出&x - - - - &Emulation - &E模拟 - - - - &Reset - &R复位 - - - - Ctrl+R - - - - - Sh&utdown - 关闭&u - - - - Yank game pak - - - - - &Pause - 暂停&P - - - - Ctrl+P - - - - - &Next frame - 下一帧&N + 退出(&X) + &Emulation + 模拟(&E) + + + + &Reset + 复位(&R) + + + + Ctrl+R + Ctrl+R + + + + Sh&utdown + 关机(&U) + + + + Yank game pak + 快速抽出游戏卡带 + + + + &Pause + 暂停(&P) + + + + Ctrl+P + Ctrl+P + + + + &Next frame + 下一帧(&N) + + + Ctrl+N - + Ctrl+N - + Fast forward (held) - 快进 (held) + 快进 (长按) - + &Fast forward - 快进&F + 快进(&F) - + Shift+Tab - + Shift+Tab - + Fast forward speed 快进速度 - + Unbounded 不限制 - + %0x - + %0x - + Rewind (held) - 回退 (held) + 回退 (长按) - + Re&wind - 回退&w + 回退(&W) - + ~ - + ~ - + Step backwards 后退 - + Ctrl+B - + Ctrl+B - + Sync to &video - 视频同步&v + 视频同步(&V) - + Sync to &audio - 音频同步&a + 音频同步(&A) - + Solar sensor - 日光传感器 + 光线传感器 - + Increase solar level - 增加日光级别 + 增加光线级别 - + Decrease solar level - 降低日光级别 + 降低光线级别 - + Brightest solar level - 日光级别为最亮 + 光线级别为最亮 - + Darkest solar level - 日光级别为最暗 + 光线级别为最暗 - + Brightness %1 亮度 %1 - - Audio/&Video - 音频/视频&V + + Game Boy Printer... + Game Boy 打印机.. - + + BattleChip Gate... + BattleChip Gate... + + + + Audio/&Video + 音频/视频(&V) + + + Frame size 帧率 - + %1x - + %1x - + Toggle fullscreen 切换全屏 - + Lock aspect ratio 锁定纵横比 - + Force integer scaling 强制整数缩放 - + Bilinear filtering 双线性过滤 - + Frame&skip - 跳帧&s + 跳帧(&S) - + Mute 静音 - + FPS target - 最高FPS - - - - 15 - - - - - 30 - - - - - 45 - + 目标 FPS - Native (59.7) - + Native (59.7275) + 原生 (59.7275) - - 60 - - - - - 90 - - - - - 120 - - - - - 240 - - - - + Take &screenshot - 生成截图&s + 截图(&S) - + F12 - + F12 - + Record output... 录制导出... - + Record GIF... - 录制GIF... + 录制 GIF... - + Record video log... 记录视频日志... - + Stop video log 停止记录视频日志 - - Game Boy Printer... - - - - + Video layers - + 视频图层 - + Audio channels - 音频 + 音频通道 - + Adjust layer placement... - + 调整图层布局 - + &Tools - 工具&T + 工具(&T) - + View &logs... - 查看日志&l... + 查看日志(&L)... - + Game &overrides... - 覆盖游戏&o... + 覆盖游戏(&O)... - + Game &Pak sensors... - + 游戏卡带传感器(&P)... - + &Cheats... - 作弊码&C... + 作弊码(&C)... - + Settings... 设置... - + Open debugger console... - 打开调试终端... + 打开调试器控制台... - + Start &GDB server... - 打开&GDB服务端... + 打开 GDB 服务器(&G)... - + View &palette... - 查看调色板&p... + 查看调色板(&P)... - + View &sprites... - + 查看精灵图(&S) - + View &tiles... - + 查看图块(&T) - + View &map... - 不译 - + 查看映射(&M) - + View memory... 查看内存... - + Search memory... - 查看内存... + 搜索内存... - + View &I/O registers... - registers 翻译存疑 - 查看&I/O注册器... + 查看 I/O 寄存器(&I)... - + Exit fullscreen 退出全屏 - + GameShark Button (held) - GameShark 键 (held) + GameShark 键 (长按) - + Autofire - 自动开火 + 连发 - + Autofire A - 自动开火 A + 连发 A - + Autofire B - 自动开火 B + 连发 B - + Autofire L - 自动开火 L + 连发 L - + Autofire R - 自动开火 R + 连发 R - + Autofire Start - 自动开火 开始 + 连发 Start - + Autofire Select - 自动开火 选择 + 连发 Select - + Autofire Up - 自动开火 上 + 连发 上 - + Autofire Right - 自动开火 右 + 连发 右 - + Autofire Down - 自动开火 下 + 连发 下 - + Autofire Left - 自动开火 左 + 连发 左 @@ -3952,17 +4073,17 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 GBA - + GBA GB - + GB ? - + ? @@ -3975,7 +4096,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Game name: - 游戏名 : + 游戏名称: @@ -3985,7 +4106,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Internal name: - 内部名 : + 内部名称: @@ -3995,7 +4116,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Game ID: - 游戏ID : + 游戏 ID: @@ -4005,7 +4126,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 File size: - 文件大小 : + 文件大小: @@ -4015,12 +4136,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 CRC32: - CRC32 : + CRC32: {CRC} - + {CRC} @@ -4058,12 +4179,12 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 MM/dd/yy hh:mm:ss AP - + yy/MM/dd hh:mm:ss AP Light sensor - 光传感器 + 光线传感器 @@ -4073,19 +4194,19 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Tilt sensor - 倾角传感器 + 倾斜传感器 Set Y - 设定 Y + 设定 Y 轴 Set X - 设定 X + 设定 X 轴 @@ -4106,502 +4227,538 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 设置 - + Audio/Video 音频/视频 - + Interface 用户界面 - + Emulation 模拟器 - + BIOS - + BIOS - + Paths 路径 - + + Logging + 日志记录 + + + Game Boy - + Game Boy - + Audio driver: - 音频驱动 : + 音频驱动: - + Audio buffer: 音频缓冲: - - + + 1536 - - - - - 512 - + 1536 - 768 - + 512 + 512 - 1024 - + 768 + 768 - - 2048 - + + 1024 + 1024 - 3072 - + 2048 + 2048 - 4096 - + 3072 + 3072 - + + 4096 + 4096 + + + samples 采样 - + Sample rate: 采样率: - - + + 44100 - - - - - 22050 - + 44100 + 22050 + 22050 + + + 32000 - + 32000 - + 48000 - + 48000 - + Hz - + Hz - + Volume: - 音量 : + 音量: - + + Mute 静音 - + + Fast forward volume: + 快进音量: + + + Display driver: - 显示驱动 : + 显示驱动: - + Frameskip: - 跳帧 : + 跳帧: - + Skip every 每间隔 - - + + frames - + FPS target: - 最高FPS : + 目标 FPS: - + frames per second 帧每秒 - + Sync: - 同步 : + 同步: - + Video 视频 - + Audio 音频 - + Lock aspect ratio 锁定纵横比 - - Bilinear filtering - 双线性过滤 - - - + Force integer scaling 强制整数缩放 - + + Bilinear filtering + 双线性过滤 + + + Language 语言 - + English 英语 - + Library: - 库 : + 库: - + List view 列表查看 - + Tree view 树状查看 - + Show when no game open - 在无游戏打开时显示 + 未打开游戏时显示 - + Clear cache 清除缓存 - + Allow opposing input directions 允许逆向输入 - + Suspend screensaver - 停用休眠 + 停用屏幕保护程序 - + Pause when inactive - 不活动时暂停 + 非活动时暂停 - + Show FPS in title bar - 在标题栏显示FPS + 在标题栏显示 FPS - + Automatically save cheats 自动保存作弊码 - + Automatically load cheats 自动载入作弊码 - + Automatically save state 自动存档 - + Automatically load state 自动读档 + + + + Enable Discord Rich Presence + 启用 Enable Discord Rich Presence - + Fast forward speed: - 快进速度 : + 快进速度: - + × - + × - + Unbounded 不限制 - + + Autofire interval: + 连发间隔: + + + Enable rewind 启用回退 - + Rewind history: - 回退历史 : + 回退历史: - + Idle loops: - + 空循环: - + Run all 运行所有 - + Remove known 移除选定 - + Detect and remove 检测并移除 - - Savestate extra data: - 存档时的额外数据 : + + Preload entire ROM into memory + 将整个 ROM 预加载到内存中 - - + + Savestate extra data: + 即时存档额外数据: + + + + Screenshot 截图 - - + + Save data 保存数据 - - + + Cheat codes 作弊码 - + Load extra data: 读档时载入额外数据: - - Rewind affects save data - 影响保存数据时回退 - - - - Preload entire ROM into memory - 预加载全部ROM到内存 - - - - Autofire interval: - 自动开火间隔 : - - - + GB BIOS file: GB BIOS 文件: - - - - - - - - - + + + + + + + + + Browse 浏览 - + Use BIOS file if found - 当可用时使用BIOS文件 + 当可用时使用 BIOS 文件 - + Skip BIOS intro - 跳过BIOS载入 + 跳过 BIOS 启动画面 - + GBA BIOS file: GBA BIOS 文件: - + GBC BIOS file: GBC BIOS 文件: - + SGB BIOS file: SGB BIOS 文件: - + Save games 已保存的游戏 - - - - - + + + + + Same directory as the ROM - 保存在ROM所在目录 + 保存在 ROM 所在目录 - + Save states - 保存快照 + 保存即时存档 - + Screenshots 截图 - + Patches 补丁 - + Cheats 作弊码 - - Game Boy model - + + Log to file + 记录日志到文件 - - - + + Log to console + 记录日志到控制台 + + + + Select Log File + 选择日志文件 + + + + Game Boy model + Game Boy 模型 + + + + + Autodetect 自动检测 - - - + + + Game Boy (DMG) - + Game Boy (DMG) - - - + + + Super Game Boy (SGB) - + Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) - + Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) - + Game Boy Advance (AGB) - - Super Game Boy model - + + Super Game Boy model: + Super Game Boy 模型: - - Game Boy Color model - + + Game Boy Color model: + Game Boy Color 模型: - + Default BG colors: - 默认 BG 颜色: + 默认背景颜色: - + Super Game Boy borders - + Super Game Boy 边框 - + Camera driver: - 相机驱动 : + 相机驱动: - + Default sprite colors 1: - + 默认精灵图颜色 1: - + Default sprite colors 2: - + 默认精灵图颜色 2: + + + + Use GBC colors in GB games + 在 GB 游戏中使用 GBC 颜色 + + + + Camera: + 相机 @@ -4614,7 +4771,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Active Shader: - 主动着色器 : + 活动着色器: @@ -4634,7 +4791,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Unload Shader - 未载入 着色器 + 未载入着色器 @@ -4670,22 +4827,32 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Tiles - 贴图 + 图块 - + 256 colors - + 256 色 - + × - + × - + Magnification - 放大率 + 缩放率 + + + + Tiles per row + 每行图块 + + + + Fit to window + 自适应窗口 @@ -4708,7 +4875,7 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 Select File - 选取文件 + 选择文件 @@ -4717,44 +4884,44 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 - High Quality - 高质量 + High &Quality + 高质量(&Q) - YouTube - + &YouTube + YouTube(&Y) WebM - + WebM - Lossless - 无损 + &Lossless + 无损(&L) - 1080p - + &1080p + 1080p(&1) - 720p - + &720p + 720p(&7) - 480p - + &480p + 480p(&4) - Native - 原生 + &Native + 原生(&N) @@ -4764,110 +4931,120 @@ Game Boy Advance 是 Nintendo Co., Ltd. 的注册商标。 MKV - + MKV AVI - + AVI MP4 - + MP4 h.264 - + h.264 h.264 (NVENC) - + h.264 (NVENC) HEVC - + HEVC - VP8 - + HEVC (NVENC) + HEVC (NVENC) + VP8 + VP8 + + + + VP9 + VP9 + + + FFV1 - - - - - FLAC - - - - - Opus - + FFV1 - Vorbis - + FLAC + FLAC - MP3 - + Opus + Opus - AAC - + Vorbis + Vorbis + MP3 + MP3 + + + + AAC + AAC + + + Uncompressed 未压缩 - - Bitrate (kbps) - + + Bitrate (kbps) + 比特率 (kbps) - - VBR - + + VBR + VBR - + ABR - + ABR - + Dimensions - 方向 - - - - : - + 维度 - × - + : + : - + + × + × + + + Lock aspect ratio 锁定纵横比 - + Show advanced 显示高级选项 From af35438aaab9307f0451f358a678644d4d9336ba Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sun, 5 May 2019 13:10:55 +0100 Subject: [PATCH 168/429] SDL: Move Raspberry Pi initialisation code to a separate file --- src/platform/sdl/CMakeLists.txt | 2 +- src/platform/sdl/gles2-sdl.c | 88 +++++---------------------------- src/platform/sdl/main.h | 8 +-- src/platform/sdl/rpi-common.c | 84 +++++++++++++++++++++++++++++++ src/platform/sdl/rpi-common.h | 20 ++++++++ 5 files changed, 121 insertions(+), 81 deletions(-) create mode 100644 src/platform/sdl/rpi-common.c create mode 100644 src/platform/sdl/rpi-common.h diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index b2f9df308..aa4c6cca5 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -60,7 +60,7 @@ set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/main.c) if(BUILD_RASPI) add_definitions(-DBUILD_RASPI) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) + list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/rpi-common.c) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gles2-sdl.c) set(OPENGLES2_LIBRARY "-lEGL -lGLESv2 -lbcm_host") set(BUILD_GLES2 ON CACHE BOOL "Using OpenGL|ES 2" FORCE) diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 582df9f9b..6cc046769 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -6,6 +6,9 @@ #include "main.h" #include "gl-common.h" +#ifdef BUILD_RASPI +#include "rpi-common.h" +#endif #include #include @@ -26,74 +29,7 @@ void mSDLGLES2Create(struct mSDLRenderer* renderer) { bool mSDLGLES2Init(struct mSDLRenderer* renderer) { #ifdef BUILD_RASPI - bcm_host_init(); - renderer->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - int major, minor; - if (EGL_FALSE == eglInitialize(renderer->display, &major, &minor)) { - printf("Failed to initialize EGL"); - return false; - } - - if (EGL_FALSE == eglBindAPI(EGL_OPENGL_ES_API)) { - printf("Failed to get GLES API"); - return false; - } - - const EGLint requestConfig[] = { - EGL_RED_SIZE, 5, - EGL_GREEN_SIZE, 5, - EGL_BLUE_SIZE, 5, - EGL_ALPHA_SIZE, 1, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_NONE - }; - - EGLConfig config; - EGLint numConfigs; - - if (EGL_FALSE == eglChooseConfig(renderer->display, requestConfig, &config, 1, &numConfigs)) { - printf("Failed to choose EGL config\n"); - return false; - } - - const EGLint contextAttributes[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - int dispWidth = 240, dispHeight = 160, adjWidth; - renderer->context = eglCreateContext(renderer->display, config, EGL_NO_CONTEXT, contextAttributes); - graphics_get_display_size(0, &dispWidth, &dispHeight); - adjWidth = dispHeight / 2 * 3; - - DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0); - DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); - - VC_RECT_T destRect = { - .x = (dispWidth - adjWidth) / 2, - .y = 0, - .width = adjWidth, - .height = dispHeight - }; - - VC_RECT_T srcRect = { - .x = 0, - .y = 0, - .width = 240 << 16, - .height = 160 << 16 - }; - - DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, 0); - vc_dispmanx_update_submit_sync(update); - - renderer->window.element = element; - renderer->window.width = dispWidth; - renderer->window.height = dispHeight; - - renderer->surface = eglCreateWindowSurface(renderer->display, config, &renderer->window, 0); - if (EGL_FALSE == eglMakeCurrent(renderer->display, renderer->surface, renderer->surface, renderer->context)) { - return false; - } + mRPIGLCommonInit(renderer); #else mSDLGLCommonInit(renderer); #endif @@ -112,7 +48,11 @@ bool mSDLGLES2Init(struct mSDLRenderer* renderer) { renderer->gl2.d.lockAspectRatio = renderer->lockAspectRatio; renderer->gl2.d.lockIntegerScaling = renderer->lockIntegerScaling; renderer->gl2.d.filter = renderer->filter; +#ifdef BUILD_RASPI + renderer->gl2.d.swap = mRPIGLCommonSwap; +#else renderer->gl2.d.swap = mSDLGLCommonSwap; +#endif renderer->gl2.d.init(&renderer->gl2.d, 0); renderer->gl2.d.setDimensions(&renderer->gl2.d, renderer->width, renderer->height); @@ -147,11 +87,7 @@ void mSDLGLES2Runloop(struct mSDLRenderer* renderer, void* user) { } mCoreSyncWaitFrameEnd(&context->impl->sync); v->drawFrame(v); -#ifdef BUILD_RASPI - eglSwapBuffers(renderer->display, renderer->surface); -#else v->swap(v); -#endif } } @@ -160,10 +96,10 @@ void mSDLGLES2Deinit(struct mSDLRenderer* renderer) { renderer->gl2.d.deinit(&renderer->gl2.d); } #ifdef BUILD_RASPI - eglMakeCurrent(renderer->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroySurface(renderer->display, renderer->surface); - eglDestroyContext(renderer->display, renderer->context); - eglTerminate(renderer->display); + eglMakeCurrent(renderer->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroySurface(renderer->eglDisplay, renderer->eglSurface); + eglDestroyContext(renderer->eglDisplay, renderer->eglContext); + eglTerminate(renderer->eglDisplay); bcm_host_deinit(); #elif SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_DeleteContext(renderer->glCtx); diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index eb435a1c7..bd4f2cecc 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -81,10 +81,10 @@ struct mSDLRenderer { #endif #ifdef BUILD_RASPI - EGLDisplay display; - EGLSurface surface; - EGLContext context; - EGL_DISPMANX_WINDOW_T window; + EGLDisplay eglDisplay; + EGLSurface eglSurface; + EGLContext eglContext; + EGL_DISPMANX_WINDOW_T eglWindow; #endif #ifdef BUILD_PANDORA diff --git a/src/platform/sdl/rpi-common.c b/src/platform/sdl/rpi-common.c new file mode 100644 index 000000000..be141718e --- /dev/null +++ b/src/platform/sdl/rpi-common.c @@ -0,0 +1,84 @@ +/* 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 + +void mRPIGLCommonSwap(struct VideoBackend* context) { + struct mSDLRenderer* renderer = (struct mSDLRenderer*) context->user; + eglSwapBuffers(renderer->eglDisplay, renderer->eglSurface); +} + +void mRPIGLCommonInit(struct mSDLRenderer* renderer) { + bcm_host_init(); + renderer->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + int major, minor; + if (EGL_FALSE == eglInitialize(renderer->eglDisplay, &major, &minor)) { + printf("Failed to initialize EGL"); + return false; + } + + if (EGL_FALSE == eglBindAPI(EGL_OPENGL_ES_API)) { + printf("Failed to get GLES API"); + return false; + } + + const EGLint requestConfig[] = { + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 5, + EGL_BLUE_SIZE, 5, + EGL_ALPHA_SIZE, 1, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + EGLConfig config; + EGLint numConfigs; + + if (EGL_FALSE == eglChooseConfig(renderer->eglDisplay, requestConfig, &config, 1, &numConfigs)) { + printf("Failed to choose EGL config\n"); + return false; + } + + const EGLint contextAttributes[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + int dispWidth = 240, dispHeight = 160, adjWidth; + renderer->eglContext = eglCreateContext(renderer->eglDisplay, config, EGL_NO_CONTEXT, contextAttributes); + graphics_get_display_size(0, &dispWidth, &dispHeight); + adjWidth = dispHeight / 2 * 3; + + DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0); + DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); + + VC_RECT_T destRect = { + .x = (dispWidth - adjWidth) / 2, + .y = 0, + .width = adjWidth, + .height = dispHeight + }; + + VC_RECT_T srcRect = { + .x = 0, + .y = 0, + .width = 240 << 16, + .height = 160 << 16 + }; + + DISPMANX_ELEMENT_HANDLE_T element = vc_dispmanx_element_add(update, display, 0, &destRect, 0, &srcRect, DISPMANX_PROTECTION_NONE, 0, 0, 0); + vc_dispmanx_update_submit_sync(update); + + renderer->eglWindow.element = element; + renderer->eglWindow.width = dispWidth; + renderer->eglWindow.height = dispHeight; + + renderer->eglSurface = eglCreateWindowSurface(renderer->eglDisplay, config, &renderer->eglWindow, 0); + if (EGL_FALSE == eglMakeCurrent(renderer->eglDisplay, renderer->eglSurface, renderer->eglSurface, renderer->eglContext)) { + return false; + } +} diff --git a/src/platform/sdl/rpi-common.h b/src/platform/sdl/rpi-common.h new file mode 100644 index 000000000..b58532de5 --- /dev/null +++ b/src/platform/sdl/rpi-common.h @@ -0,0 +1,20 @@ +/* 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/. */ +#ifndef SDL_RPI_COMMON_H +#define SDL_RPI_COMMON_H + +#include + +CXX_GUARD_START + +#include "main.h" + +void mRPIGLCommonSwap(struct VideoBackend* context); +void mRPIGLCommonInit(struct mSDLRenderer* renderer); + +CXX_GUARD_END + +#endif From db8bb29c5a7b7efcd4d086ee383870a2565792e2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 6 May 2019 17:28:32 -0700 Subject: [PATCH 169/429] GB Video: Fix regression when disabling window mid-frame (fixes #1394) --- cinema/gb/window/kdt-battle/baseline_0000.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0001.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0002.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0003.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0004.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0005.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0006.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0007.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0008.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/baseline_0009.png | Bin 0 -> 3717 bytes cinema/gb/window/kdt-battle/test.mvl | Bin 0 -> 7086 bytes src/gb/renderers/software.c | 2 +- 12 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 cinema/gb/window/kdt-battle/baseline_0000.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0001.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0002.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0003.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0004.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0005.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0006.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0007.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0008.png create mode 100644 cinema/gb/window/kdt-battle/baseline_0009.png create mode 100644 cinema/gb/window/kdt-battle/test.mvl diff --git a/cinema/gb/window/kdt-battle/baseline_0000.png b/cinema/gb/window/kdt-battle/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0001.png b/cinema/gb/window/kdt-battle/baseline_0001.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0002.png b/cinema/gb/window/kdt-battle/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0003.png b/cinema/gb/window/kdt-battle/baseline_0003.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0004.png b/cinema/gb/window/kdt-battle/baseline_0004.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0005.png b/cinema/gb/window/kdt-battle/baseline_0005.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0006.png b/cinema/gb/window/kdt-battle/baseline_0006.png new file mode 100644 index 0000000000000000000000000000000000000000..2ba1aa28bbbecc1782b8696a8f1813ce2bb6d1ab GIT binary patch literal 3717 zcmc&%XEdCRwtmMjN*Ez}FVP9U2!p{8y|?H>M6?LPh?eL{^cpP$QKIMjB2h-dj1V=W zM;##;z9E01k+xo@Bnl(9IXK=`yl%SPSuOh0kny&g8x!Dk zGDZXgV-gC0B@-iH3kCzS%irSL1*L}~eVjVk}?aSMTHbd9wPlyWeS z=tt7~TXI@cc07#wcM(DL(|f2UZL2GH@V^k7B2jIs_*&4XW>0M!54kdyDH$DG$|uE_OB1X=^VvyEhy1(ZOk)h0gHK zrC7TDo4kitY|np#9htcL)2+!lIA+D2`NV?Q7)uwpYG9+2>htjiro!&G6!8*_8ar-hJ#Q<C84d0-CgZ-JgHBl1ZX>o0^(+LK&za@=Tj8}aTgT~K;L~yhzYsGUiW8_ajx{u zYf)l@3k@4ij`17)2IcB8J89x~Op#o2LcIZ#qS$`%SjeHaZ61KcarLRpF9ZCIa zxpgU}Sr1)&yh(v-9dmk_{4*W%Am#Wco->^nIGc~y@4D{Ydc{GIA!NNulN z_*Y&dR9$&v*JRv6<(IZ|9c0O?Giu8j8Vi)xNpy`rIK2FNhcZTdI8AX&ei9pvnvI02669exkwTw_G+yT%j^k)qC5vE)aQg(YSK(m#2O;A4gBSC_UlMg4=#^TemU5K8(|!CyqkCX zfaB6j9?<$uzZP+Q3ObNGX%*vLuEJNm3kj;Wz_V>$KJSt}WcphvSkF2X-P=@!Uc@;p zsC+Oj5MstavgzO~`V*t6^@V+c2s+Q`BvH!^Pm{m}M2|LG{tlGM2+aIS3Na+V{U^5h?y};|-B%Cq z09rrPyZg9aHj5>PSRfwJHxfWK#INEq>VH$(xikw~B1+TsrNS}ugrTIMFX-11+1&7& zI4B*CYRWj^{rvM)esLLwvpM=?B`S($m&0L4^{P@!DhI~G5Nvti*03PmZz^?pe!IX< z9iy^61Mm@Rqz**fFOG8d8Zxsnc?@ZnViOc=Qeuujy!k3fVCNcVho0AlzJsWB(^%Hg z!1Ry4Gt3U%I*LLZJ*-Q#j{RB|6+pX9u2JJIf%$+=Usxn&H;24`q2b^)(1gDC_ox)} zL8W@K9T5c7>YzZ%j><7}BjPfd)FG8IMFR+x>|e%*#YB?%<0DQN);toR^d+i2O1x2EG?9ZQkLm}r{<*L$A- zX%K}V2|*9nL9iv8j6nyTg2PVuBh@~`is7wkQvYjfu5u|Znthu2pwz>zT)!7<72z?US;y4uvAkoK{f};aB0>QH7Kt|TWFOprtNl2+*n6n+ zX?UjbC-EccYC{V)>t^&B;Fj(P(=FSvc{ZH1s4rER}tskDm%1;J7&_Mg!1 z*E_h*2C&JJ{P;B{BUIoke^%Y0s%cGRd7Beb=~P0!H}L7bm-#)${09k@-_hV;%8R-) zwDonw@y>XN)KL2G%!9D}v;1>-tgK>2nzhXdH_N*#C8=k4!+V|1i5k@FXpwQNOYXX& zLSfpbT7%p!%CB01z$k`n+;8O!$TuSee|7Z^XdLdPK#%&ZaQ64^jO(EJNsA5n?tu*| z&qS+oNEM6(qM`yHpKJxe9Q5q%?K|NNKBEC`TV$4zw6IFV)hDN{qnxKSTl-$I4Gj$o z3k&#QloP({TEctxwuL6Ui<(S$xk!TSaGE7rn+`dWMX+!9wz?|HpUJx53PWke#*yUd z>d7Y-$&bokXy@NMEzV(C3o5k3g6czHe9ni90na%wqwa8lkDDqAn4%tm<1=#D(&&E1 z6l0dw6~;rb*z90XmZqiN3(2AFJ}Z zwgHw7Ybm`?4@ACh1*J%bUkl>}#i#-r6QP2DGGN5g$SefrZF6)lkIrK2W)#Xx_Y)|& z1XAl}|1(|;5&vO_+8$23N$VS*tWeIw1=K9wW4-i^2+ z$k^q2vXbSNGedk|H9~vt<#_jNK%2=`DoDEU;p)OjL(V|6g<&-DboK=F>$p0A1>2K&s_Jdj(hxn0gXzsm;e9( literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0007.png b/cinema/gb/window/kdt-battle/baseline_0007.png new file mode 100644 index 0000000000000000000000000000000000000000..2491849a8d329889cfe9d6db2b1529dea4399306 GIT binary patch literal 3717 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0008.png b/cinema/gb/window/kdt-battle/baseline_0008.png new file mode 100644 index 0000000000000000000000000000000000000000..2491849a8d329889cfe9d6db2b1529dea4399306 GIT binary patch literal 3717 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/baseline_0009.png b/cinema/gb/window/kdt-battle/baseline_0009.png new file mode 100644 index 0000000000000000000000000000000000000000..2491849a8d329889cfe9d6db2b1529dea4399306 GIT binary patch literal 3717 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/kdt-battle/test.mvl b/cinema/gb/window/kdt-battle/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..f665f969c58563f7f3c616e1a435e4430f393dfb GIT binary patch literal 7086 zcmb_=2UL^G*0x7HQluyf)J4|0@6EC zLQ#+oA}ulWo&X^Ur2TNtU3cAkzw>?T`~UT?z20|bo|!#+X7ByHYu@p5FhBC!kt6^1 zJUMv)`~wS}+{osEoLP9&jh%p3zv}D1B2yl>RR@`mv9GVF?fE4ToDo8PHbIWChXYY=x&v?jvGq{B2f#!EEG+Mr4%Bf^~2 zO3t3>^S|N1i0s*cX3XsM?X>N*>}5Rwh@4JWpQy!_XIJg-oo)0k%G>C=DYYzCH1}2Y z%z}7wF@u0pGp(w=mINB*Kb|{wZ*L1=urnMQ=}nKrkTJQ(n$%;<^-952>!K^zjZnCC zkkTpfG{2v{;ut+tHu@;$Ctj)r**j&`S5kTryUN2KJl}uy4v0>^ULvmYGmAvHTm9PQ zq}bj9{ep-W!#iGnKOQt^`+HyGR5)DF*sW36c;Z=SBd2@{-_;LQfO7V+y*2Cn1U6|R zMfI8*R?vk@_SB=Y&l$S6?Q(SQlOhVfYJ+B#M5;D`&jtg3I7aw}^AfdVN_S3b2+}iZ zq9$-c9tHNqt{7;NZ418w{7#ju?D&sXHUCq!aW&Lhvx@maKBQAQio(J6l>;e za`6twszH2yl9#EhB<6dThITK9Mth%LXx`(LhTC#ns-U{(*tAKBBHOYbRV*6)uaYFD z*QIZ%8=R@%V4oyEzc&1Aa72`EiNiVDp}WfGTCV`>qiJu7VyL)I6kxlK!yA|?VIzJl z%~{VhcgY-brFeXN)I5CY_36Tk@E@RXBa-z^jfiz!MG}T3Ce-p5sGj4;l&7!0P<#W_Rm-&) zifGb7drt;DvTT0H%VDCPTFry+O)BFIN()LWd&TcVJ^31X3iY(*C`mQ#MFG_`1RM;$ zVEn{5f!FA)Q}INYWYfd>TXGwwffLUy*^IgyclAmfqVwi1*;u}JjLJibo+@?_n@bTj z`H&A5nP@9IlkTA?%{rt~#bU2A!2xF~pX^o4MgwmQ+{;<;NQx8&qsn(YranC z#Ph-=p7VL#&FSka8#cESP!|_2HjPQ&s=u`bmP>kavNcEF?JV2xkDjMSx``Nr3phPW z0(H5b*;o5yw^+L*er+31?>$i)tPg*)yM3cCqDg2bAy_I{=+x00S%WV$U9?=rdwM5- zq&kRfQ)xQ&E!J8E38gf_?~OtA1zM9Ow&TJDfBXoH2Nfj%p$ zWWrooi@~RGZ*5I9p6A#z-62tD3BCJ_^yp`YEMG#I{jWmd>ExP$K2O(qq3xnLF9XSvXy)vLw#N z-WwwtzkcwZUH+2uTyFr?-lSwDUw+~t&lPjSE{pOT1J$|d`3oLberk|@HE{Rd#(dd+ z60V(1T3OOd%&x7Aef@MA}7&N(ZC-ngSq z*o(40V1E62(e)}vhV{v_w(+mxKQ{PjO9nS>cUuVqG=*w zUrSz0#RYnde?Iac?|9@G?Wgz@=|cT6i={ZLyFRzL%zAUh_(DUAi&SxA-q}AF~MRt+66CE6V8@lzB{a=zqbx&O6=SE!v#4PAQ9))LSdhyijkRqZ#S^Y^;I1B9BEJ@sl39dt3`R zEXihoX>RF#bgdsP7?P@fcg^FJu9Mn1o8boiGKD($3ewvvn@gUpFO}gO1j!2Y33us6 zR2B9Z4p_FV_dQU?Xh!lQw~}(b#Dpsqn@xl~9_5k4AWigJR4t+EEU$XIS=YS))#Ix$ z>gMU+8^yb(b5tejf;uZ$>YK|g8zFCR6ShzL@+J6-vK$w;RCnL~kuowJ58d^z0O@V{ z_QgGt#U!i=)~oRe(P3n)eu7<`Aj*z8AEnq^AL4aK8T6}0uGi3ctdquD!*EP<5Ki~G z-K=_{(f7;qX<`j|iMbkLM6jXJ&TH-y_B5X*`okKBT>z_dH$|8inp@`xQ}Q|Qe_z-> zqB@%Ocwn1^MLOv~)F3Q(avr zC%2ql0~cf)YpMO#NNHQ&V(`e`V}0e9$!Q^*0l$8P4HT#m2+u#}h#F)aHG?msW zgCRG?-4Z(iuK0J95~*3oAIC(K0ndiiAH5qoHzr{5M5#}ahyCm2x4hv?5&m(@*2OQ( zspf?{y*=*#|hrk(iy%+;F4^%P(lYCX8)h(ep{ZoJx-R^~rEB!)l6BvEm zKuu*m?ZN%!0mTU24UoM$zoenp!_8LNV0^1lqL&x9 zh_JR>TtU8mUgfR%@cbWnMk~9241wthLf702E$z$e_~I-O2_pNO6;;FcK75$0mDOtg z^s4`ty!PPkaxIKT`TqUq8gsYlIz%eqC*hP@{L3YgjEi3-I=2LQU6oAI&!J%5E>ldx zqTtl*o*h+2(9wU_#;C;N`2Ji;y@z$8kBQCb=B=o)yxqa@%`g zv}>ornZ6$23u_}`=k~_6neFh8%mIG2j-7G(Y`P$Dzk&(V$bpZ@qV|zM=Hl4+?4BBv zv@6e~HkYALqjLjIVWZ0~{zA&C30h7o^y8O0c4S)*PB#4#f1U9E_5DlW^KIy;QhKHf z|Dwz4I0>!xjYodj1;Y@B?{4|+0u_<~Ty2`I*m2?ex}WVke>{{k;2bV}C-YP=DMIe_ zbNq}c_}2sxblruj-kxYNtXG$@{QqZiB?sbY-f ztuDA&cofjVEdC&`|JG+%(tJpG?*oofFj*U zvAh#I(uT^$daQ!mvFGLd@2ey$*xb!gPk+b}C0bqhaIep`rde-SWg%oqfeZD%Re;8r$`_?1K`W+9Md1B`3^sF3`&RQ z@DU83XXptGzcsWLGt+;kmZOqALE`tIfyrM{F7|v1L03fGKXx@ts)t_5 zOK!av=dAam*!Pi*ja7m~a^%gApbbOhgXY2C=Ft2B51w}^m*j3uv(Y1!DDDcx8@u__ z?@y-my!0xc-AQ}tRK5G+`*RvV#@$3@F{@njo$O`(O^Iq5B|GyBE1gZb$FeIggw4(V z*tGBbuJ2${WU2aKEFZ0FBqGLG;X#b_Wf+mY>r2VLCpaDy?5^WaWGaN@By&TR#BVc1 zx=JNG0kcLD`qEX*OnOfsV|MT3Hs|p;pp@$;&HZrtQ{nEJ9qPb!TT$Bbm>GvJTi}{N zbVivwt9!$ZK&v-ET^Qq~4$(HXIY4ZNQ)8H;oVk4|Q-1Ep_lA$iX@4YaZ%*OJk+!{Q zbMVo#i0V4|A-^6j_WBK$b&+r8F`Dq}77=%zf19S8^fCFEufK z&%%Xe9`R!Wu!2dsp%*o`^TwxOGuoidPofLI%M6WM`_$wap0|E2P}XM%PW2dFOZxKY zak@us-)qYg&97xxO2>2O=Y3mQm-`R?eV>~Bn!WTP6Es%IBg%TF72<|xYW;E+(S`0h>BI+iagyI$bz5!ugyBWM#3G5)(Dv*YZ1;kW5A1%a@!9bE7`jEC8daN$*CK zIQx7|lz9X`jxT?0${Ekv_2L?acWMrt4{c3I-*GeE&)KEyhCSY$*$GaqsPDgtZ>-Kg z={cby8C_wX8Ex+n zwS8{DOW@-r?UZDh>!yyf>+ zsjzd(Lfz+=BnokZwu<+l!g@IBHLNHu$Giy1V|AQj`n6pdQz-kgy6LlxA@2j8TY+ZmVh$?hArx{ z&gW;QTGRyMyL8S4VH>G2d7bDSt(|ogu%GLm=RHrAO$)%Rh?(|uqRtLvOcp&5mGva= zjWqIGE4JYqSD-IIsYvuT$%pu;-KtzbU`Ld^Bb?ZmB)$c|By0+$r&N|yVCxktb%NI$ zw7L^oF|fOHz7^Rz&{aD<^c&^)_$_*7CJSp%5BG)Qk_S-B1Y5zZjxytX+Pc12C7}1^ z=ZSCk_aeEX+i}Uslaq^!9h!=Y7ZffRmz9+Uyp>-=3XgyvIw8}Ney(9!-(9@W-y5Lt zMOscyUS38(OZ6n%aWm5k-jLp7k-657A3HcS2M^sJ%(gCW(j?7%&R$*Z>7h_hY_Vl# zK9e6AJp;dPVG&mOz@NLb>v3ilO9YKp?m8zTE7vkOfT0UKZ-_~u?8lbzG#fpEwreM^ zInIbT`UfV?H+?&3c#)0Em8ZoU`wsxk-UHzF0TA9`^u%>h_*+nRxWu^hz?iGijJRLo z7XJ2kCPRUwqUt{bCj4U1r7YiS-$lsCT(Z&$t12!I!O!n-#gu+{_T`Z}tohxq`EQiH ziL@uBxt{Y}qWE0ZV@@0TIqleui)wk`%N4in1n7^o4 ztzhC;_X;|aG2cDFSdQsNZcQ>bKrnhKkTJUi*qMZHMFVu0F<9oNMg<+!MoR~v0=KQC zT1bL!8qifFlS0K_ud`K9be2*M0%SB$Oy5+er^r)n3oWzUuH9YyI1#YepM|=E6Ke#~ zsbg{JqjIiwkj@_a((#Y3j#MO(PI6i@e~!=4$^5#{wJWIRhncNK1x=BJv_dv8bG6L6 zdeq#vkhZlM{MICviXpc$Swv`qIu&%f2;-{}fV5==8TMt`A{pPk0p!so)UR4*ry_Lk zvt!$SZ3Sv*2@C)HSvN9BwY40K_VS21+ z?-NKrNx3M7G`fxt^Zq|hOJZPmDd=z(jH96}fZF9zX9FP%VwD7{gr?*!Lqybq-} z8Z}LDWP?ZJD$X!W(J|3Hf(#j4g%WM79q32#Zx2z1L=b*QpbRO#oLE=NCIT-C;X(6r z0Pj*h^jk3lCk0hv_ zgXI&%xqxDjSRCjK!w{Xw3rod;co~<_iF~jc9EgwMg-+)H`cRZ`y_`S=NF%PB4bVln z8!h5XdEB0;Obf+z3o`g{psTd9cB~I&Dhky{INR=cjuDIlsnL$%%CJ0EXJGGfve6YP zG@*8^J4GuRH9`nsho|H4d<=gyR-C4dKsi#vx!_0w`8)%L!>iF)+5vYctkLj60uMX$ z6;6sB@QuK8g82z2a*A;Z4UnPbA&_#kduYHV+Fb<5AGjRyKt&bC)vp_$?w1z>4}QcjdJWefonrwO1d&ce!Yjfa2PYSEBjjLIh!ngm4>(!;AO|<&McFojmfcBcAHOqzktywLaM&lpT>( zh6#f`!JhaLmIFwswF(sD_QvhagK9mz*@2XXgMl+6)YTk}BbnINR74)rZmrl{fd*Oq zOPAUT)*LU0>c5V~)T92=JJdbUramW}LjO~Je=ekBE`;+?6+mudu3_;*r$saXMMY~SyA@*R3SPy*w_QY}@I$^{s29tgu|33Y{ZTTNv7W--=)UJw={(7>|`XF`q zpR%eW2I(ODbKwk%&=y7L&=U-sP3Vfnip59_CKZ#qwKJGCoCQV-FCRcF7Emo>A+gXr zONhZxtoYx0-;vzX2KpZygcCg zv9?WU-+AA;u&=*>M27!0(cd|F4BALoK>SDQVe^Z~1qWhrkd`a|8S>VOfn{hI6nkQi zstxu4&k_%F>oC?G#E!#QdjNMkEQlTEJ%`Dr>=(TJ=O+Hv_TQ!Z-@4~7Lj1XBFt&bp zZSQdI|8KdSlJjRqsvVdv{7*{mwjJ=gfV{xOu3!%+Wi?_|#6wr1s~k`YS%^HO)B!YN mbwH`2m7@PWr9k`iq5q!vOh7o6c{IJ|717VZJoI0W!~X{mbKS@Q literal 0 HcmV?d00001 diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index 4960b395c..93b2d3085 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -508,7 +508,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy == y && wx <= endX) { softwareRenderer->hasWindow = true; } - if (softwareRenderer->hasWindow && wx <= endX) { + if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && softwareRenderer->hasWindow && wx <= endX) { if (wx > 0 && !softwareRenderer->d.disableBG) { GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, wx, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); } From 11b18311b7ae40b75098aef7be65da709358e635 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 6 May 2019 17:30:48 -0700 Subject: [PATCH 170/429] All: Fix some warnings --- src/core/cheats.c | 2 +- src/core/core.c | 4 ++-- src/core/library.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/cheats.c b/src/core/cheats.c index 0abcbd537..464ebfc39 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -230,7 +230,7 @@ bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { char directive[64]; ssize_t len = snprintf(directive, sizeof(directive) - 1, "!%s\n", *StringListGetPointer(&directives, d)); if (len > 1) { - vf->write(vf, directive, (size_t) len > sizeof(directive) ? sizeof(directive) : len); + vf->write(vf, directive, (size_t) len > sizeof(directive) ? sizeof(directive) : (size_t) len); } } diff --git a/src/core/core.c b/src/core/core.c index 343e11ce8..57c2dd811 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -217,13 +217,13 @@ bool mCoreLoadState(struct mCore* core, int slot, int flags) { } struct VFile* mCoreGetState(struct mCore* core, int slot, bool write) { - char name[PATH_MAX]; + char name[PATH_MAX + 14]; // Quash warning snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot); return core->dirs.state->openFile(core->dirs.state, name, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); } void mCoreDeleteState(struct mCore* core, int slot) { - char name[PATH_MAX]; + char name[PATH_MAX + 14]; // Quash warning snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot); core->dirs.state->deleteFile(core->dirs.state, name); } diff --git a/src/core/library.c b/src/core/library.c index 632496e99..60e16592f 100644 --- a/src/core/library.c +++ b/src/core/library.c @@ -341,7 +341,7 @@ static void _mLibraryDeleteEntry(struct mLibrary* library, struct mLibraryEntry* } void mLibraryClear(struct mLibrary* library) { - int result = sqlite3_exec(library->db, + sqlite3_exec(library->db, " BEGIN TRANSACTION;" "\n DELETE FROM roots;" "\n DELETE FROM roms;" From e991b3092675b29c0f9f0ac77278e4a9e22faca2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2019 16:18:27 -0700 Subject: [PATCH 171/429] 3DS, Wii, Switch: Unify CMakeToolchain logic --- src/platform/3ds/CMakeToolchain.txt | 43 +++---------------------- src/platform/cmake/devkitPro.cmake | 41 ++++++++++++++++++++++++ src/platform/switch/CMakeToolchain.txt | 44 +++----------------------- src/platform/wii/CMakeToolchain.txt | 43 +++---------------------- 4 files changed, 56 insertions(+), 115 deletions(-) create mode 100644 src/platform/cmake/devkitPro.cmake diff --git a/src/platform/3ds/CMakeToolchain.txt b/src/platform/3ds/CMakeToolchain.txt index 2da8df26a..cccfb6a78 100644 --- a/src/platform/3ds/CMakeToolchain.txt +++ b/src/platform/3ds/CMakeToolchain.txt @@ -1,14 +1,4 @@ -if(DEFINED ENV{DEVKITPRO}) - set(DEVKITPRO $ENV{DEVKITPRO}) -else() - message(FATAL_ERROR "Could not find DEVKITPRO in environment") -endif() - -if(DEFINED ENV{DEVKITARM}) - set(DEVKITARM $ENV{DEVKITARM}) -else() - set(DEVKITARM ${DEVKITPRO}/devkitARM) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/devkitPro.cmake) if(DEFINED ENV{CTRULIB}) set(CTRULIB $ENV{CTRULIB}) @@ -16,40 +6,17 @@ else() set(CTRULIB ${DEVKITPRO}/libctru) endif() -set(extension) -if (CMAKE_HOST_WIN32) - set(extension .exe) -endif() - -set(CMAKE_PROGRAM_PATH ${DEVKITARM}/bin) set(cross_prefix arm-none-eabi-) set(arch_flags "-march=armv6k -mtune=mpcore -mfloat-abi=hard -ffunction-sections") set(inc_flags "-I${CTRULIB}/include ${arch_flags} -mword-relocations") set(link_flags "-L${CTRULIB}/lib -lctru -specs=3dsx.specs ${arch_flags} -Wl,--gc-sections") -set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") set(CMAKE_SYSTEM_PROCESSOR arm CACHE INTERNAL "processor") set(CMAKE_LIBRARY_ARCHITECTURE arm-none-eabi CACHE INTERNAL "abi") -find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) -find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) -find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) -find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) -set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") -set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") -set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") - -set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") -set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") -set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") - -set(CMAKE_FIND_ROOT_PATH ${DEVKITARM}/arm-none-eabi ${DEVKITPRO}/portlibs/3ds) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") -set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) - set(3DS ON) add_definitions(-D_3DS -DARM11) + +create_devkit(ARM) + +set(CMAKE_FIND_ROOT_PATH ${DEVKITARM}/${CMAKE_LIBRARY_ARCHITECTURE} ${DEVKITPRO}/portlibs/3ds) diff --git a/src/platform/cmake/devkitPro.cmake b/src/platform/cmake/devkitPro.cmake new file mode 100644 index 000000000..23f20cc28 --- /dev/null +++ b/src/platform/cmake/devkitPro.cmake @@ -0,0 +1,41 @@ +if(DEFINED ENV{DEVKITPRO}) + set(DEVKITPRO $ENV{DEVKITPRO}) +else() + message(FATAL_ERROR "Could not find DEVKITPRO in environment") +endif() + +set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") + +function(create_devkit DEVKIT) + if(DEFINED ENV{DEVKIT${DEVKIT}}) + set(DEVKIT${DEVKIT} $ENV{DEVKIT${DEVKIT}} PARENT_SCOPE) + else() + set(DEVKIT${DEVKIT} ${DEVKITPRO}/devkit${DEVKIT} PARENT_SCOPE) + endif() + + set(CMAKE_PROGRAM_PATH ${DEVKIT${DEVKIT}}/bin CACHE INTERNAL "program path") + + set(extension) + if (CMAKE_HOST_WIN32) + set(extension .exe) + endif() + + find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) + find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) + find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) + find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) + find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) + find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) + set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") + set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") + set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") + + set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") + set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") + set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") + + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") + set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) +endfunction() \ No newline at end of file diff --git a/src/platform/switch/CMakeToolchain.txt b/src/platform/switch/CMakeToolchain.txt index 3dbc1ad87..38c4ff943 100644 --- a/src/platform/switch/CMakeToolchain.txt +++ b/src/platform/switch/CMakeToolchain.txt @@ -1,14 +1,4 @@ -if(DEFINED ENV{DEVKITPRO}) - set(DEVKITPRO $ENV{DEVKITPRO}) -else() - message(FATAL_ERROR "Could not find DEVKITPRO in environment") -endif() - -if(DEFINED ENV{DEVKITA64}) - set(DEVKITA64 $ENV{DEVKITA64}) -else() - set(DEVKITA64 ${DEVKITPRO}/devkitA64) -endif() +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/devkitPro.cmake) if(DEFINED ENV{LIBNX}) set(LIBNX $ENV{LIBNX}) @@ -16,41 +6,17 @@ else() set(LIBNX ${DEVKITPRO}/libnx) endif() -set(extension) -if (CMAKE_HOST_WIN32) - set(extension .exe) -endif() - -set(CMAKE_PROGRAM_PATH ${DEVKITA64}/bin) set(cross_prefix aarch64-none-elf-) set(arch_flags "-mtune=cortex-a57 -ffunction-sections -march=armv8-a -mtp=soft -fPIC -ftls-model=local-exec") set(inc_flags "-I${LIBNX}/include ${arch_flags}") set(link_flags "-L${LIBNX}/lib -lnx -specs=${LIBNX}/switch.specs ${arch_flags}") -set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") set(CMAKE_SYSTEM_PROCESSOR aarch64 CACHE INTERNAL "processor") set(CMAKE_LIBRARY_ARCHITECTURE aarch64-none-elf CACHE INTERNAL "abi") -find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) -find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) -find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) -find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) -set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") -set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") -set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") -SET(CMAKE_ASM_COMPILE_OBJECT " -o -c ") - -set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") -set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") -set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") - -set(CMAKE_FIND_ROOT_PATH ${DEVKITARM}/aarch64-none-elf ${DEVKITPRO}/portlibs/switch) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") -set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) - set(SWITCH ON) add_definitions(-D__SWITCH__) + +create_devkit(A64) + +set(CMAKE_FIND_ROOT_PATH ${DEVKITA64}/${CMAKE_LIBRARY_ARCHITECTURE} ${DEVKITPRO}/portlibs/switch) diff --git a/src/platform/wii/CMakeToolchain.txt b/src/platform/wii/CMakeToolchain.txt index 652cbb098..887efd669 100644 --- a/src/platform/wii/CMakeToolchain.txt +++ b/src/platform/wii/CMakeToolchain.txt @@ -1,49 +1,16 @@ -if(DEFINED ENV{DEVKITPRO}) - set(DEVKITPRO $ENV{DEVKITPRO}) -else() - message(FATAL_ERROR "Could not find DEVKITPRO in environment") -endif() +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/devkitPro.cmake) -if(DEFINED ENV{DEVKITPPC}) - set(DEVKITPPC $ENV{DEVKITPPC}) -else() - set(DEVKITPPC ${DEVKITPRO}/devkitPPC) -endif() - -set(extension) -if (CMAKE_HOST_WIN32) - set(extension .exe) -endif() - -set(CMAKE_PROGRAM_PATH ${DEVKITPPC}/bin) set(cross_prefix powerpc-eabi-) set(arch_flags "-mrvl -mcpu=750 -meabi -mhard-float -g") set(inc_flags "-I${DEVKITPRO}/libogc/include ${arch_flags}") set(link_flags "-L${DEVKITPRO}/libogc/lib/wii ${arch_flags}") -set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name") set(CMAKE_SYSTEM_PROCESSOR powerpc CACHE INTERNAL "processor") set(CMAKE_LIBRARY_ARCHITECTURE powerpc-none-eabi CACHE INTERNAL "abi") -find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension}) -find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension}) -find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension}) -find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension}) -find_program(CMAKE_LINKER ${cross_prefix}ld${extension}) -set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags") -set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags") -set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags") - -set(CMAKE_EXE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "exe link flags") -set(CMAKE_MODULE_LINKER_FLAGS ${link_flags} CACHE INTERNAL "module link flags") -set(CMAKE_SHARED_LINKER_FLAGS ${link_flags} CACHE INTERNAL "shared link flags") - -set(CMAKE_FIND_ROOT_PATH ${DEVKITPPC}/powerpc-eabi ${DEVKITPRO}/portlibs/ppc) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY CACHE INTERNAL "") -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY CACHE INTERNAL "") -set(PKG_CONFIG_EXECUTABLE "/dev/null" CACHE INTERNAL "" FORCE) - set(WII ON) add_definitions(-DGEKKO) + +create_devkit(PPC) + +set(CMAKE_FIND_ROOT_PATH ${DEVKITPPC}/powerpc-eabi ${DEVKITPRO}/portlibs/ppc) From f39ab5b35372ed57299ee65d5fb7c20830dabfb8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 11:22:10 -0700 Subject: [PATCH 172/429] ARM, LR35902: Const correctness --- include/mgba/internal/arm/arm.h | 2 +- include/mgba/internal/lr35902/lr35902.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba/internal/arm/arm.h b/include/mgba/internal/arm/arm.h index 55e847c7f..a1f040c8b 100644 --- a/include/mgba/internal/arm/arm.h +++ b/include/mgba/internal/arm/arm.h @@ -124,7 +124,7 @@ struct ARMMemory { uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction, int* cycleCounter); - uint32_t* activeRegion; + const uint32_t* activeRegion; uint32_t activeMask; uint32_t activeSeqCycles32; uint32_t activeSeqCycles16; diff --git a/include/mgba/internal/lr35902/lr35902.h b/include/mgba/internal/lr35902/lr35902.h index c5bfd1381..4f2a29c71 100644 --- a/include/mgba/internal/lr35902/lr35902.h +++ b/include/mgba/internal/lr35902/lr35902.h @@ -56,7 +56,7 @@ struct LR35902Memory { int (*currentSegment)(struct LR35902Core*, uint16_t address); - uint8_t* activeRegion; + const uint8_t* activeRegion; uint16_t activeMask; uint16_t activeRegionEnd; void (*setActiveRegion)(struct LR35902Core*, uint16_t address); From 7ea054ee01d0203fd9e50bc6263344d185cb6176 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 11:25:31 -0700 Subject: [PATCH 173/429] All: More warning fixing --- src/core/timing.c | 1 + src/gba/extra/battlechip.c | 1 + src/util/test/suite.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/timing.c b/src/core/timing.c index 7059659ea..88bcf2743 100644 --- a/src/core/timing.c +++ b/src/core/timing.c @@ -14,6 +14,7 @@ void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextE } void mTimingDeinit(struct mTiming* timing) { + UNUSED(timing); } void mTimingClear(struct mTiming* timing) { diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index b76247cd0..fb411eef5 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -94,6 +94,7 @@ void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { } void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cyclesLate) { + UNUSED(timing); struct GBASIOBattlechipGate* gate = user; if (gate->d.p->mode == SIO_NORMAL_32) { diff --git a/src/util/test/suite.h b/src/util/test/suite.h index 5fc85938a..fb9d87468 100644 --- a/src/util/test/suite.h +++ b/src/util/test/suite.h @@ -18,7 +18,7 @@ #define M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(NAME, ...) M_TEST_SUITE_DEFINE_EX(NAME, _testSuite_setup_ ## NAME, _testSuite_teardown_ ## NAME, __VA_ARGS__) #define M_TEST_SUITE_DEFINE_EX(NAME, SETUP, TEARDOWN, ...) \ int main(void) { \ - const static struct CMUnitTest tests[] = { \ + static const struct CMUnitTest tests[] = { \ __VA_ARGS__ \ }; \ return cmocka_run_group_tests_name(# NAME, tests, SETUP, TEARDOWN); \ From 6562e1cfecca7e0927e1a065b80131eb8c5e6f30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 12:49:15 -0700 Subject: [PATCH 174/429] SQLite: Fix memory leaks in No-Intro DB --- src/feature/sqlite3/no-intro.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index d2b9e23a5..7a1b60091 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -263,6 +263,8 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { free((void*) dbType); free((void*) dbVersion); + sqlite3_finalize(gamedbTable); + sqlite3_finalize(gamedbDrop); sqlite3_finalize(gameTable); sqlite3_finalize(romTable); @@ -275,6 +277,7 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { } void NoIntroDBDestroy(struct NoIntroDB* db) { + sqlite3_finalize(db->crc32); sqlite3_close(db->db); free(db); } From e6f34e01f1961b02fbfc2fe670a9749a1941d4cc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 13:50:30 -0700 Subject: [PATCH 175/429] Qt: Fix some Qt display driver race conditions --- CHANGES | 1 + src/platform/qt/DisplayGL.cpp | 4 ++++ src/platform/qt/DisplayGL.h | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8a78e543f..a79bda912 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Other fixes: - Qt: Fix adjusting magnification in tile viewer when not fitting to window - FFmpeg: Improve initialization reliability and cleanup - Wii: Fix aspect ratio (fixes mgba.io/i/500) + - Qt: Fix some Qt display driver race conditions Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index a07da6c7f..62166ec5d 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -37,6 +37,7 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) m_painter = new PainterGL(format.majorVersion() < 2 ? 1 : m_gl->format().majorVersion(), m_gl); m_gl->setMouseTracking(true); m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work? + setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions } DisplayGL::~DisplayGL() { @@ -219,6 +220,9 @@ PainterGL::PainterGL(int majorVersion, QGLWidget* parent) #endif m_backend->swap = [](VideoBackend* v) { PainterGL* painter = static_cast(v->user); + if (!painter->m_gl->isVisible()) { + return; + } painter->m_gl->swapBuffers(); }; diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 85d4ee08e..fbf44a547 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -32,7 +32,7 @@ public: EmptyGLWidget(const QGLFormat& format, QWidget* parent) : QGLWidget(format, parent) { setAutoBufferSwap(false); } protected: - void paintEvent(QPaintEvent*) override {} + void paintEvent(QPaintEvent* event) override { event->ignore(); } void resizeEvent(QResizeEvent*) override {} void mouseMoveEvent(QMouseEvent* event) override { event->ignore(); } }; From 0126330530a157caab4f3483ef061515f4685cf1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 16:38:30 -0700 Subject: [PATCH 176/429] GBA Memory: Prevent writing to mirrored BG VRAM (fixes #743) --- CHANGES | 1 + src/gba/memory.c | 82 ++++++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index a79bda912..371781222 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Emulation fixes: - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) + - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gba/memory.c b/src/gba/memory.c index 46aecae5b..3f037567c 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -390,11 +390,15 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) { wait += waitstatesRegion[REGION_PALETTE_RAM]; #define LOAD_VRAM \ - if ((address & 0x0001FFFF) < SIZE_VRAM) { \ - LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ - } else { \ - LOAD_32(value, address & 0x00017FFC, gba->video.vram); \ + if ((address & 0x0001FFFF) >= SIZE_VRAM) { \ + if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \ + mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load32: 0x%08X", address); \ + value = 0; \ + break; \ + } \ + address &= 0x00017FFC; \ } \ + LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ wait += waitstatesRegion[REGION_VRAM]; #define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw); @@ -520,11 +524,15 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { LOAD_16(value, address & (SIZE_PALETTE_RAM - 2), gba->video.palette); break; case REGION_VRAM: - if ((address & 0x0001FFFF) < SIZE_VRAM) { - LOAD_16(value, address & 0x0001FFFE, gba->video.vram); - } else { - LOAD_16(value, address & 0x00017FFE, gba->video.vram); + if ((address & 0x0001FFFF) >= SIZE_VRAM) { + if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { + mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load16: 0x%08X", address); + value = 0; + break; + } + address &= 0x00017FFE; } + LOAD_16(value, address & 0x0001FFFE, gba->video.vram); break; case REGION_OAM: LOAD_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw); @@ -631,11 +639,15 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { value = ((uint8_t*) gba->video.palette)[address & (SIZE_PALETTE_RAM - 1)]; break; case REGION_VRAM: - if ((address & 0x0001FFFF) < SIZE_VRAM) { - value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; - } else { - value = ((uint8_t*) gba->video.vram)[address & 0x00017FFF]; + if ((address & 0x0001FFFF) >= SIZE_VRAM) { + if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { + mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Load8: 0x%08X", address); + value = 0; + break; + } + address &= 0x00017FFF; } + value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; break; case REGION_OAM: value = ((uint8_t*) gba->video.oam.raw)[address & (SIZE_OAM - 1)]; @@ -717,20 +729,18 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { wait += waitstatesRegion[REGION_PALETTE_RAM]; #define STORE_VRAM \ - if ((address & 0x0001FFFF) < SIZE_VRAM) { \ - LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram); \ - if (oldValue != value) { \ - STORE_32(value, address & 0x0001FFFC, gba->video.vram); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \ - } \ - } else { \ - LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram); \ - if (oldValue != value) { \ - STORE_32(value, address & 0x00017FFC, gba->video.vram); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC) + 2); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC)); \ + if ((address & 0x0001FFFF) >= SIZE_VRAM) { \ + if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { \ + mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store32: 0x%08X", address); \ + break; \ } \ + address &= 0x00017FFC; \ + } \ + LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram); \ + if (oldValue != value) { \ + STORE_32(value, address & 0x0001FFFC, gba->video.vram); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \ } \ wait += waitstatesRegion[REGION_VRAM]; @@ -840,18 +850,17 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle } break; case REGION_VRAM: - if ((address & 0x0001FFFF) < SIZE_VRAM) { - LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram); - if (value != oldValue) { - STORE_16(value, address & 0x0001FFFE, gba->video.vram); - gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); - } - } else { - LOAD_16(oldValue, address & 0x00017FFE, gba->video.vram); - if (value != oldValue) { - STORE_16(value, address & 0x00017FFE, gba->video.vram); - gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE); + if ((address & 0x0001FFFF) >= SIZE_VRAM) { + if ((address & (SIZE_VRAM | 0x00014000)) == SIZE_VRAM && (GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3)) { + mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store16: 0x%08X", address); + break; } + address &= 0x00017FFE; + } + LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram); + if (value != oldValue) { + STORE_16(value, address & 0x0001FFFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } break; case REGION_OAM: @@ -939,7 +948,6 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo break; case REGION_VRAM: if ((address & 0x0001FFFF) >= ((GBARegisterDISPCNTGetMode(gba->memory.io[REG_DISPCNT >> 1]) >= 3) ? 0x00014000 : 0x00010000)) { - // TODO: check BG mode mLOG(GBA_MEM, GAME_ERROR, "Cannot Store8 to OBJ: 0x%08X", address); break; } From b176516c36fdadb7e068e0624ec5afc5fad7fdec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 11:24:23 -0700 Subject: [PATCH 177/429] Qt: Only attempt to paint message when there is one --- src/platform/qt/MessagePainter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/MessagePainter.cpp b/src/platform/qt/MessagePainter.cpp index de24ade24..379fc7bdf 100644 --- a/src/platform/qt/MessagePainter.cpp +++ b/src/platform/qt/MessagePainter.cpp @@ -79,7 +79,9 @@ void MessagePainter::redraw() { } void MessagePainter::paint(QPainter* painter) { - painter->drawPixmap(m_local, m_pixmap); + if (!m_message.text().isEmpty()) { + painter->drawPixmap(m_local, m_pixmap); + } } From 459eaefcfcf75a177ddecab65e7896279109f7c5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2019 15:27:14 -0700 Subject: [PATCH 178/429] GBA Video: Clean up dead code in sprite rendering loop --- CHANGES | 1 + src/gba/renderers/software-obj.c | 36 +++++++++----------------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index 371781222..e3808c37f 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,7 @@ Misc: - Debugger: Make tracing compatible with breakpoints/watchpoints - Debugger: Print breakpoint/watchpoint number when inserting - Qt: Open a message box for Qt frontend errors + - GBA Video: Clean up dead code in sprite rendering loop 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index cb7441666..e8a474c0a 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -62,25 +62,17 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags) { \ - if (tileData) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ - } else if (current != FLAG_UNWRITTEN) { \ - renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ - } \ + if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ } #define SPRITE_DRAW_PIXEL_16_NORMAL_OBJWIN(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags) { \ - if (tileData) { \ - unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ - renderer->spriteLayer[outX] = color | flags; \ - } else if (current != FLAG_UNWRITTEN) { \ - renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ - } \ + if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | flags; \ } #define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \ @@ -97,25 +89,17 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags) { \ - if (tileData) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ - } else if (current != FLAG_UNWRITTEN) { \ - renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ - } \ + if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ } #define SPRITE_DRAW_PIXEL_256_NORMAL_OBJWIN(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags) { \ - if (tileData) { \ - unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ - renderer->spriteLayer[outX] = color | flags; \ - } else if (current != FLAG_UNWRITTEN) { \ - renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ - } \ + if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | flags; \ } #define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \ From 9f3c68cb6ab310343e736b17e4b2f230c5e272e2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2019 15:31:24 -0700 Subject: [PATCH 179/429] Qt: Fix frame size check marks --- src/platform/qt/Window.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 0e56194b3..f6e960240 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -591,9 +591,7 @@ void Window::resizeEvent(QResizeEvent* event) { } m_savedScale = factor; for (QMap::iterator iter = m_frameSizes.begin(); iter != m_frameSizes.end(); ++iter) { - bool enableSignals = iter.value()->blockSignals(true); iter.value()->setActive(iter.key() == factor); - iter.value()->blockSignals(enableSignals); } m_config->setOption("fullscreen", isFullScreen()); @@ -1294,9 +1292,7 @@ void Window::setupMenu(QMenuBar* menubar) { m_savedScale = i; m_config->setOption("scaleMultiplier", i); // TODO: Port to other resizeFrame(size); - bool enableSignals = setSize->blockSignals(true); setSize->setActive(true); - setSize->blockSignals(enableSignals); }, "frame"); setSize->setExclusive(true); if (m_savedScale == i) { From fd7989e748c7b90b79d41156aa30332e6e874124 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2019 16:05:21 -0700 Subject: [PATCH 180/429] Qt: Fix events in fullscreen --- src/platform/qt/ActionMapper.cpp | 13 +++++++++---- src/platform/qt/ActionMapper.h | 4 ++-- src/platform/qt/Window.cpp | 7 ++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/platform/qt/ActionMapper.cpp b/src/platform/qt/ActionMapper.cpp index e03c4dd1a..13c059b4c 100644 --- a/src/platform/qt/ActionMapper.cpp +++ b/src/platform/qt/ActionMapper.cpp @@ -30,8 +30,11 @@ void ActionMapper::clearMenu(const QString& name) { emit menuCleared(name); } -void ActionMapper::rebuildMenu(QMenuBar* menubar, const ShortcutController& shortcuts) { +void ActionMapper::rebuildMenu(QMenuBar* menubar, QWidget* context, const ShortcutController& shortcuts) { menubar->clear(); + for (QAction* action : context->actions()) { + context->removeAction(action); + } for (const QString& m : m_menus[{}]) { if (m_hiddenActions.contains(m)) { continue; @@ -39,11 +42,11 @@ void ActionMapper::rebuildMenu(QMenuBar* menubar, const ShortcutController& shor QString menu = m.mid(1); QMenu* qmenu = menubar->addMenu(m_menuNames[menu]); - rebuildMenu(menu, qmenu, shortcuts); + rebuildMenu(menu, qmenu, context, shortcuts); } } -void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, const ShortcutController& shortcuts) { +void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, QWidget* context, const ShortcutController& shortcuts) { for (const QString& actionName : m_menus[menu]) { if (actionName.isNull()) { qmenu->addSeparator(); @@ -55,12 +58,13 @@ void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, const Shortcut if (actionName[0] == '.') { QString name = actionName.mid(1); QMenu* newMenu = qmenu->addMenu(m_menuNames[name]); - rebuildMenu(name, newMenu, shortcuts); + rebuildMenu(name, newMenu, context, shortcuts); continue; } Action* action = &m_actions[actionName]; QAction* qaction = qmenu->addAction(action->visibleName()); qaction->setEnabled(action->isEnabled()); + qaction->setShortcutContext(Qt::WidgetShortcut); if (action->isExclusive() || action->booleanAction()) { qaction->setCheckable(true); } @@ -88,6 +92,7 @@ void ActionMapper::rebuildMenu(const QString& menu, QMenu* qmenu, const Shortcut qaction->setShortcut(QKeySequence(shortcut)); }); } + context->addAction(qaction); } } diff --git a/src/platform/qt/ActionMapper.h b/src/platform/qt/ActionMapper.h index 1ffcda2a2..f99290bd2 100644 --- a/src/platform/qt/ActionMapper.h +++ b/src/platform/qt/ActionMapper.h @@ -29,7 +29,7 @@ public: void addMenu(const QString& visibleName, const QString& name, const QString& parent = {}); void addHiddenMenu(const QString& visibleName, const QString& name, const QString& parent = {}); void clearMenu(const QString& name); - void rebuildMenu(QMenuBar*, const ShortcutController&); + void rebuildMenu(QMenuBar*, QWidget* context, const ShortcutController&); void addSeparator(const QString& menu); @@ -59,7 +59,7 @@ signals: void menuCleared(const QString& name); private: - void rebuildMenu(const QString& menu, QMenu* qmenu, const ShortcutController&); + void rebuildMenu(const QString& menu, QMenu* qmenu, QWidget* context, const ShortcutController&); Action* addAction(const Action& act, const QString& name, const QString& menu, const QKeySequence& shortcut); QHash m_actions; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index f6e960240..d6821795c 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -617,6 +617,7 @@ void Window::showEvent(QShowEvent* event) { m_fullscreenOnStart = false; } reloadDisplayDriver(); + setFocus(); } void Window::closeEvent(QCloseEvent* event) { @@ -768,7 +769,7 @@ void Window::gameStarted() { action->setActive(true); } } - m_actions.rebuildMenu(menuBar(), *m_shortcutController); + m_actions.rebuildMenu(menuBar(), this, *m_shortcutController); #ifdef USE_DISCORD_RPC @@ -1603,7 +1604,7 @@ void Window::setupMenu(QMenuBar* menubar) { } m_shortcutController->rebuildItems(); - m_actions.rebuildMenu(menubar, *m_shortcutController); + m_actions.rebuildMenu(menuBar(), this, *m_shortcutController); } void Window::attachWidget(QWidget* widget) { @@ -1640,7 +1641,7 @@ void Window::updateMRU() { } m_config->setMRU(m_mruFiles); m_config->write(); - m_actions.rebuildMenu(menuBar(), *m_shortcutController); + m_actions.rebuildMenu(menuBar(), this, *m_shortcutController); } Action* Window::addGameAction(const QString& visibleName, const QString& name, Action::Function function, const QString& menu, const QKeySequence& shortcut) { From 3e86eeda7004757be9926876224af026a07f7eca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 14:25:20 -0700 Subject: [PATCH 181/429] FFmpeg: Support audio-only recording --- CHANGES | 1 + src/feature/ffmpeg/ffmpeg-encoder.c | 17 ++++++++++++++--- src/platform/qt/VideoView.cpp | 6 +++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index e3808c37f..5b8d2554a 100644 --- a/CHANGES +++ b/CHANGES @@ -57,6 +57,7 @@ Misc: - Debugger: Print breakpoint/watchpoint number when inserting - Qt: Open a message box for Qt frontend errors - GBA Video: Clean up dead code in sprite rendering loop + - FFmpeg: Support audio-only recording 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 6fae174e6..890ca25b5 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -55,10 +55,12 @@ void FFmpegEncoderInit(struct FFmpegEncoder* encoder) { encoder->absf = NULL; encoder->context = NULL; encoder->scaleContext = NULL; + encoder->audio = NULL; encoder->audioStream = NULL; encoder->audioFrame = NULL; encoder->audioBuffer = NULL; encoder->postaudioBuffer = NULL; + encoder->video = NULL; encoder->videoStream = NULL; encoder->videoFrame = NULL; } @@ -146,6 +148,12 @@ bool FFmpegEncoderSetVideo(struct FFmpegEncoder* encoder, const char* vcodec, un { AV_PIX_FMT_YUV444P, 5 }, { AV_PIX_FMT_YUV420P, 6 } }; + + if (!vcodec) { + encoder->videoCodec = 0; + return true; + } + AVCodec* codec = avcodec_find_encoder_by_name(vcodec); if (!codec) { return false; @@ -189,13 +197,13 @@ bool FFmpegEncoderVerifyContainer(struct FFmpegEncoder* encoder) { AVOutputFormat* oformat = av_guess_format(encoder->containerFormat, 0, 0); AVCodec* acodec = avcodec_find_encoder_by_name(encoder->audioCodec); AVCodec* vcodec = avcodec_find_encoder_by_name(encoder->videoCodec); - if ((encoder->audioCodec && !acodec) || !vcodec || !oformat) { + if ((encoder->audioCodec && !acodec) || (encoder->videoCodec && !vcodec) || !oformat) { return false; } if (encoder->audioCodec && !avformat_query_codec(oformat, acodec->id, FF_COMPLIANCE_EXPERIMENTAL)) { return false; } - if (!avformat_query_codec(oformat, vcodec->id, FF_COMPLIANCE_EXPERIMENTAL)) { + if (encoder->videoCodec && !avformat_query_codec(oformat, vcodec->id, FF_COMPLIANCE_EXPERIMENTAL)) { return false; } return true; @@ -562,7 +570,7 @@ void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) { struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream; - if (!encoder->context) { + if (!encoder->context || !encoder->videoCodec) { return; } stride *= BYTES_PER_PIXEL; @@ -606,6 +614,9 @@ void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size static void _ffmpegSetVideoDimensions(struct mAVStream* stream, unsigned width, unsigned height) { struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream; + if (!encoder->context || !encoder->videoCodec) { + return; + } encoder->iwidth = width; encoder->iheight = height; if (encoder->scaleContext) { diff --git a/src/platform/qt/VideoView.cpp b/src/platform/qt/VideoView.cpp index a1aeee61b..9ef896423 100644 --- a/src/platform/qt/VideoView.cpp +++ b/src/platform/qt/VideoView.cpp @@ -275,7 +275,11 @@ void VideoView::setAudioCodec(const QString& codec, bool manual) { void VideoView::setVideoCodec(const QString& codec, bool manual) { free(m_videoCodecCstr); m_videoCodec = sanitizeCodec(codec, s_vcodecMap); - m_videoCodecCstr = strdup(m_videoCodec.toUtf8().constData()); + if (m_videoCodec == "none") { + m_videoCodecCstr = nullptr; + } else { + m_videoCodecCstr = strdup(m_videoCodec.toUtf8().constData()); + } if (!FFmpegEncoderSetVideo(&m_encoder, m_videoCodecCstr, m_vbr)) { free(m_videoCodecCstr); m_videoCodecCstr = nullptr; From bb7f41e8cca003d57f7470293a9951d9e027a8a5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 May 2019 22:30:48 -0700 Subject: [PATCH 182/429] FFmpeg: Fix audio conversion producing gaps --- CHANGES | 1 + src/feature/ffmpeg/ffmpeg-encoder.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 5b8d2554a..250a7dcd4 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,7 @@ Other fixes: - FFmpeg: Improve initialization reliability and cleanup - Wii: Fix aspect ratio (fixes mgba.io/i/500) - Qt: Fix some Qt display driver race conditions + - FFmpeg: Fix audio conversion producing gaps Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 890ca25b5..42ed5e3e2 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -499,7 +499,7 @@ void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right #if LIBAVCODEC_VERSION_MAJOR >= 55 av_frame_make_writable(encoder->audioFrame); #endif - if (swr_get_out_samples(encoder->resampleContext, encoder->audioBufferSize / 4) < encoder->audioFrame->nb_samples) { + if (swr_get_out_samples(encoder->resampleContext, 1) < encoder->audioFrame->nb_samples) { swr_convert(encoder->resampleContext, NULL, 0, (const uint8_t**) &encoder->audioBuffer, encoder->audioBufferSize / 4); return; } From 42813bb197dee028b64ba70b0a9b63aea2cf264c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 11:12:24 -0700 Subject: [PATCH 183/429] Qt: Add VideoProxy --- include/mgba/core/core.h | 1 + src/gba/core.c | 10 +++- src/platform/qt/CMakeLists.txt | 1 + src/platform/qt/Display.h | 2 + src/platform/qt/DisplayGL.cpp | 18 +++++-- src/platform/qt/DisplayGL.h | 7 ++- src/platform/qt/VideoProxy.cpp | 97 ++++++++++++++++++++++++++++++++++ src/platform/qt/VideoProxy.h | 68 ++++++++++++++++++++++++ src/platform/qt/Window.cpp | 12 +++-- 9 files changed, 207 insertions(+), 9 deletions(-) create mode 100644 src/platform/qt/VideoProxy.cpp create mode 100644 src/platform/qt/VideoProxy.h diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 569b55f82..fe08ae0cd 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -47,6 +47,7 @@ struct mCore { struct mTiming* timing; struct mDebugger* debugger; struct mDebuggerSymbols* symbolTable; + struct mVideoLogger* videoLogger; #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 struct mDirectorySet dirs; diff --git a/src/gba/core.c b/src/gba/core.c index 8966fbe37..95d217ac6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -151,6 +151,7 @@ static bool _GBACoreInit(struct mCore* core) { core->timing = &gba->timing; core->debugger = NULL; core->symbolTable = NULL; + core->videoLogger = NULL; gbacore->overrides = NULL; gbacore->debuggerPlatform = NULL; gbacore->cheatDevice = NULL; @@ -392,11 +393,16 @@ static void _GBACoreReset(struct mCore* core) { #ifndef DISABLE_THREADING int fakeBool; if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { - gbacore->proxyRenderer.logger = &gbacore->threadProxy.d; + if (!core->videoLogger) { + core->videoLogger = &gbacore->threadProxy.d; + } + } +#endif + if (core->videoLogger) { + gbacore->proxyRenderer.logger = core->videoLogger; GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); renderer = &gbacore->proxyRenderer.d; } -#endif GBAVideoAssociateRenderer(&gba->video, renderer); } diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 76d21a241..9b3eb63f0 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -121,6 +121,7 @@ set(SOURCE_FILES utils.cpp Window.cpp VFileDevice.cpp + VideoProxy.cpp VideoView.cpp) set(UI_FILES diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index 76816ec47..de8c03648 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -19,6 +19,7 @@ struct VideoShader; namespace QGBA { class CoreController; +class VideoProxy; class Display : public QWidget { Q_OBJECT @@ -47,6 +48,7 @@ public: virtual bool isDrawing() const = 0; virtual bool supportsShaders() const = 0; virtual VideoShader* shaders() = 0; + virtual VideoProxy* videoProxy() { return nullptr; } signals: void showCursor(); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 62166ec5d..b7af84b25 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -34,10 +34,12 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) // This can spontaneously re-enter into this->resizeEvent before creation is done, so we // need to make sure it's initialized to nullptr before we assign the new object to it m_gl = new EmptyGLWidget(format, this); - m_painter = new PainterGL(format.majorVersion() < 2 ? 1 : m_gl->format().majorVersion(), m_gl); + m_painter = new PainterGL(format.majorVersion() < 2 ? 1 : m_gl->format().majorVersion(), &m_videoProxy, m_gl); m_gl->setMouseTracking(true); m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work? setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions + + connect(&m_videoProxy, &VideoProxy::dataAvailable, &m_videoProxy, &VideoProxy::processData); } DisplayGL::~DisplayGL() { @@ -74,6 +76,7 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { m_gl->context()->doneCurrent(); m_gl->context()->moveToThread(m_drawThread); m_painter->moveToThread(m_drawThread); + m_videoProxy.moveToThread(m_drawThread); connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start); m_drawThread->start(); @@ -184,8 +187,16 @@ void DisplayGL::resizePainter() { } } -PainterGL::PainterGL(int majorVersion, QGLWidget* parent) +VideoProxy* DisplayGL::videoProxy() { + if (supportsShaders()) { + return &m_videoProxy; + } + return nullptr; +} + +PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) : m_gl(parent) + , m_videoProxy(proxy) { #ifdef BUILD_GL mGLContext* glBackend; @@ -347,7 +358,7 @@ void PainterGL::draw() { m_backend->swap(m_backend); if (!m_delayTimer.isValid()) { m_delayTimer.start(); - } else { + } else if (m_gl->format().swapInterval()) { while (m_delayTimer.elapsed() < 15) { QThread::usleep(100); } @@ -382,6 +393,7 @@ void PainterGL::stop() { m_gl->context()->moveToThread(m_gl->thread()); m_context.reset(); moveToThread(m_gl->thread()); + m_videoProxy->moveToThread(m_gl->thread()); } void PainterGL::pause() { diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index fbf44a547..8ef6f9e1c 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -23,6 +23,8 @@ #include #include +#include "VideoProxy.h" + #include "platform/video-backend.h" namespace QGBA { @@ -49,6 +51,7 @@ public: bool isDrawing() const override { return m_isDrawing; } bool supportsShaders() const override; VideoShader* shaders() override; + VideoProxy* videoProxy() override; public slots: void stopDrawing() override; @@ -75,13 +78,14 @@ private: PainterGL* m_painter; QThread* m_drawThread = nullptr; std::shared_ptr m_context; + VideoProxy m_videoProxy; }; class PainterGL : public QObject { Q_OBJECT public: - PainterGL(int majorVersion, QGLWidget* parent); + PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent); ~PainterGL(); void setContext(std::shared_ptr); @@ -126,6 +130,7 @@ private: QSize m_size; MessagePainter* m_messagePainter = nullptr; QElapsedTimer m_delayTimer; + VideoProxy* m_videoProxy; }; } diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp new file mode 100644 index 000000000..0c378f59c --- /dev/null +++ b/src/platform/qt/VideoProxy.cpp @@ -0,0 +1,97 @@ +/* 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/. */ +#include "VideoProxy.h" + +#include "CoreController.h" + +using namespace QGBA; + +VideoProxy::VideoProxy() { + mVideoLoggerRendererCreate(&m_logger.d, false); + m_logger.d.block = true; + + m_logger.d.init = &cbind<&VideoProxy::init>; + m_logger.d.reset = &cbind<&VideoProxy::reset>; + m_logger.d.deinit = &cbind<&VideoProxy::deinit>; + m_logger.d.lock = &cbind<&VideoProxy::lock>; + m_logger.d.unlock = &cbind<&VideoProxy::unlock>; + m_logger.d.wait = &cbind<&VideoProxy::wait>; + m_logger.d.wake = &callback::func<&VideoProxy::wake>; + + m_logger.d.writeData = &callback::func<&VideoProxy::writeData>; + m_logger.d.readData = &callback::func<&VideoProxy::readData>; +} + +void VideoProxy::attach(CoreController* controller) { + CoreController::Interrupter interrupter(controller); + controller->thread()->core->videoLogger = &m_logger.d; +} + +void VideoProxy::processData() { + mVideoLoggerRendererRun(&m_logger.d, false); + m_fromThreadCond.wakeAll(); +} + +void VideoProxy::init() { + RingFIFOInit(&m_dirtyQueue, 0x80000); +} + +void VideoProxy::reset() { + RingFIFOClear(&m_dirtyQueue); +} + +void VideoProxy::deinit() { + RingFIFODeinit(&m_dirtyQueue); +} + +bool VideoProxy::writeData(const void* data, size_t length) { + while (!RingFIFOWrite(&m_dirtyQueue, data, length)) { + emit dataAvailable(); + m_mutex.lock(); + m_toThreadCond.wakeAll(); + m_fromThreadCond.wait(&m_mutex); + m_mutex.unlock(); + } + emit dataAvailable(); + return true; +} + +bool VideoProxy::readData(void* data, size_t length, bool block) { + bool read = false; + while (true) { + read = RingFIFORead(&m_dirtyQueue, data, length); + if (!block || read) { + break; + } + m_mutex.lock(); + m_fromThreadCond.wakeAll(); + m_toThreadCond.wait(&m_mutex); + m_mutex.unlock(); + } + return read; +} + +void VideoProxy::lock() { + m_mutex.lock(); +} + +void VideoProxy::unlock() { + m_mutex.unlock(); +} + +void VideoProxy::wait() { + while (RingFIFOSize(&m_dirtyQueue)) { + emit dataAvailable(); + m_toThreadCond.wakeAll(); + m_fromThreadCond.wait(&m_mutex, 1); + } +} + +void VideoProxy::wake(int y) { + if ((y & 15) == 15) { + m_toThreadCond.wakeAll(); + } +} diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h new file mode 100644 index 000000000..d686478c0 --- /dev/null +++ b/src/platform/qt/VideoProxy.h @@ -0,0 +1,68 @@ +/* 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/. */ +#pragma once + +#include +#include +#include + +#include +#include + +namespace QGBA { + +class CoreController; + +class VideoProxy : public QObject { +Q_OBJECT + +public: + VideoProxy(); + + void attach(CoreController*); + +signals: + void dataAvailable(); + +public slots: + void processData(); + +private: + void init(); + void reset(); + void deinit(); + + bool writeData(const void* data, size_t length); + bool readData(void* data, size_t length, bool block); + + void lock(); + void unlock(); + void wait(); + void wake(int y); + + template struct callback { + using type = T (VideoProxy::*)(A...); + + template static T func(mVideoLogger* logger, A... args) { + VideoProxy* proxy = reinterpret_cast(logger)->p; + return (proxy->*F)(args...); + } + }; + + template static void cbind(mVideoLogger* logger) { callback::func(logger); } + + struct Logger { + mVideoLogger d; + VideoProxy* p; + } m_logger = {{}, this}; + + RingFIFO m_dirtyQueue; + QMutex m_mutex; + QWaitCondition m_toThreadCond; + QWaitCondition m_fromThreadCond; +}; + +} \ No newline at end of file diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d6821795c..379f5cecb 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -52,6 +52,7 @@ #include "ShaderSelector.h" #include "ShortcutController.h" #include "TileView.h" +#include "VideoProxy.h" #include "VideoView.h" #ifdef USE_DISCORD_RPC @@ -716,9 +717,6 @@ void Window::gameStarted() { if (m_savedScale > 0) { resizeFrame(size * m_savedScale); } - if (!m_display) { - reloadDisplayDriver(); - } attachWidget(m_display.get()); m_display->setMinimumSize(size); setFocus(); @@ -1713,6 +1711,14 @@ void Window::setController(CoreController* controller, const QString& fname) { appendMRU(fname); } + if (!m_display) { + reloadDisplayDriver(); + } + + if (m_display->videoProxy()) { + m_display->videoProxy()->attach(controller); + } + m_controller = std::shared_ptr(controller); m_inputController.recalibrateAxes(); m_controller->setInputController(&m_inputController); From 82ef919ee27e93f684d260dd147f71f601806b64 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 11:13:21 -0700 Subject: [PATCH 184/429] Feature: More video logging plumbing --- include/mgba/feature/thread-proxy.h | 1 + include/mgba/feature/video-logger.h | 9 +++++++ src/feature/thread-proxy.c | 27 ++++++++++++++++----- src/gba/extra/proxy.c | 37 ++++++++++++++++++++++++++--- src/platform/qt/DisplayGL.cpp | 1 + src/platform/qt/VideoProxy.cpp | 9 +++++++ src/platform/qt/VideoProxy.h | 3 +++ 7 files changed, 78 insertions(+), 9 deletions(-) diff --git a/include/mgba/feature/thread-proxy.h b/include/mgba/feature/thread-proxy.h index cb663d506..36f432b03 100644 --- a/include/mgba/feature/thread-proxy.h +++ b/include/mgba/feature/thread-proxy.h @@ -29,6 +29,7 @@ struct mVideoThreadProxy { Condition toThreadCond; Mutex mutex; enum mVideoThreadProxyState threadState; + enum mVideoLoggerEvent event; struct RingFIFO dirtyQueue; }; diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index f194433a2..bae94157a 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -27,6 +27,13 @@ enum mVideoLoggerDirtyType { DIRTY_BUFFER, }; +enum mVideoLoggerEvent { + LOGGER_EVENT_NONE = 0, + LOGGER_EVENT_INIT, + LOGGER_EVENT_DEINIT, + LOGGER_EVENT_RESET, +}; + struct mVideoLoggerDirtyInfo { enum mVideoLoggerDirtyType type; uint32_t address; @@ -38,6 +45,7 @@ struct VFile; struct mVideoLogger { bool (*writeData)(struct mVideoLogger* logger, const void* data, size_t length); bool (*readData)(struct mVideoLogger* logger, void* data, size_t length, bool block); + void (*postEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event); void* dataContext; bool block; @@ -52,6 +60,7 @@ struct mVideoLogger { void* context; bool (*parsePacket)(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); + void (*handleEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event); uint16_t* (*vramBlock)(struct mVideoLogger* logger, uint32_t address); size_t vramSize; diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index d00da8cd8..7a67dbedd 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -18,6 +18,7 @@ static THREAD_ENTRY _proxyThread(void* renderer); static bool _writeData(struct mVideoLogger* logger, const void* data, size_t length); static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bool block); +static void _postEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent); static void _lock(struct mVideoLogger* logger); static void _unlock(struct mVideoLogger* logger); @@ -38,6 +39,7 @@ void mVideoThreadProxyCreate(struct mVideoThreadProxy* renderer) { renderer->d.writeData = _writeData; renderer->d.readData = _readData; + renderer->d.postEvent = _postEvent; } void mVideoThreadProxyInit(struct mVideoLogger* logger) { @@ -131,6 +133,14 @@ static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bo return read; } +static void _postEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) { + struct mVideoThreadProxy* proxyRenderer = (struct mVideoThreadProxy*) logger; + MutexLock(&proxyRenderer->mutex); + proxyRenderer->event = event; + ConditionWake(&proxyRenderer->toThreadCond); + MutexUnlock(&proxyRenderer->mutex); +} + static void _lock(struct mVideoLogger* logger) { struct mVideoThreadProxy* proxyRenderer = (struct mVideoThreadProxy*) logger; MutexLock(&proxyRenderer->mutex); @@ -172,13 +182,18 @@ static THREAD_ENTRY _proxyThread(void* logger) { break; } proxyRenderer->threadState = PROXY_THREAD_BUSY; - MutexUnlock(&proxyRenderer->mutex); - if (!mVideoLoggerRendererRun(&proxyRenderer->d, false)) { - // FIFO was corrupted - proxyRenderer->threadState = PROXY_THREAD_STOPPED; - mLOG(GBA_VIDEO, ERROR, "Proxy thread queue got corrupted!"); + if (proxyRenderer->event) { + proxyRenderer->d.handleEvent(&proxyRenderer->d, proxyRenderer->event); + proxyRenderer->event = 0; + } else { + MutexUnlock(&proxyRenderer->mutex); + if (!mVideoLoggerRendererRun(&proxyRenderer->d, false)) { + // FIFO was corrupted + proxyRenderer->threadState = PROXY_THREAD_STOPPED; + mLOG(GBA_VIDEO, ERROR, "Proxy thread queue got corrupted!"); + } + MutexLock(&proxyRenderer->mutex); } - MutexLock(&proxyRenderer->mutex); ConditionWake(&proxyRenderer->fromThreadCond); if (proxyRenderer->threadState != PROXY_THREAD_STOPPED) { proxyRenderer->threadState = PROXY_THREAD_IDLE; diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index deeec5603..ea884db3b 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -21,6 +21,7 @@ static void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer); static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBAVideoProxyRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels); +static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event); static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); @@ -45,6 +46,7 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->logger->context = renderer; renderer->logger->parsePacket = _parsePacket; + renderer->logger->handleEvent = _handleEvent; renderer->logger->vramBlock = _vramBlock; renderer->logger->paletteSize = SIZE_PALETTE_RAM; renderer->logger->vramSize = SIZE_VRAM; @@ -105,7 +107,11 @@ void GBAVideoProxyRendererInit(struct GBAVideoRenderer* renderer) { _init(proxyRenderer); _reset(proxyRenderer); - proxyRenderer->backend->init(proxyRenderer->backend); + if (!proxyRenderer->logger->block) { + proxyRenderer->backend->init(proxyRenderer->backend); + } else { + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_INIT); + } } void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer) { @@ -113,17 +119,42 @@ void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer) { _reset(proxyRenderer); - proxyRenderer->backend->reset(proxyRenderer->backend); + if (!proxyRenderer->logger->block) { + proxyRenderer->backend->reset(proxyRenderer->backend); + } else { + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_RESET); + } } void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; - proxyRenderer->backend->deinit(proxyRenderer->backend); + if (!proxyRenderer->logger->block) { + proxyRenderer->backend->deinit(proxyRenderer->backend); + } else { + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_DEINIT); + } mVideoLoggerRendererDeinit(proxyRenderer->logger); } +static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) { + struct GBAVideoProxyRenderer* proxyRenderer = logger->context; + switch (event) { + default: + break; + case LOGGER_EVENT_INIT: + proxyRenderer->backend->init(proxyRenderer->backend); + break; + case LOGGER_EVENT_DEINIT: + proxyRenderer->backend->deinit(proxyRenderer->backend); + break; + case LOGGER_EVENT_RESET: + proxyRenderer->backend->reset(proxyRenderer->backend); + break; + } +} + static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* item) { struct GBAVideoProxyRenderer* proxyRenderer = logger->context; switch (item->type) { diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index b7af84b25..c7374f274 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -40,6 +40,7 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions connect(&m_videoProxy, &VideoProxy::dataAvailable, &m_videoProxy, &VideoProxy::processData); + connect(&m_videoProxy, &VideoProxy::eventPosted, &m_videoProxy, &VideoProxy::handleEvent); } DisplayGL::~DisplayGL() { diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 0c378f59c..a6c673207 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -23,6 +23,7 @@ VideoProxy::VideoProxy() { m_logger.d.writeData = &callback::func<&VideoProxy::writeData>; m_logger.d.readData = &callback::func<&VideoProxy::readData>; + m_logger.d.postEvent = &callback::func<&VideoProxy::postEvent>; } void VideoProxy::attach(CoreController* controller) { @@ -74,6 +75,14 @@ bool VideoProxy::readData(void* data, size_t length, bool block) { return read; } +void VideoProxy::postEvent(enum mVideoLoggerEvent event) { + emit eventPosted(event); +} + +void VideoProxy::handleEvent(int event) { + m_logger.d.handleEvent(&m_logger.d, static_cast(event)); +} + void VideoProxy::lock() { m_mutex.lock(); } diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h index d686478c0..7f778a605 100644 --- a/src/platform/qt/VideoProxy.h +++ b/src/platform/qt/VideoProxy.h @@ -26,9 +26,11 @@ public: signals: void dataAvailable(); + void eventPosted(int); public slots: void processData(); + void handleEvent(int); private: void init(); @@ -37,6 +39,7 @@ private: bool writeData(const void* data, size_t length); bool readData(void* data, size_t length, bool block); + void postEvent(enum mVideoLoggerEvent event); void lock(); void unlock(); From 618ddac38731b79933b7d39d4c1b50342d011d73 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 11:14:37 -0700 Subject: [PATCH 185/429] GBA Video: Start GL renderer --- src/gba/core.c | 9 +++- src/gba/renderers/gl.c | 90 +++++++++++++++++++++++++++++++++++ src/platform/qt/DisplayGL.cpp | 36 ++++++++------ 3 files changed, 120 insertions(+), 15 deletions(-) create mode 100644 src/gba/renderers/gl.c diff --git a/src/gba/core.c b/src/gba/core.c index 95d217ac6..358b9882e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -17,6 +17,7 @@ #ifndef DISABLE_THREADING #include #endif +#include #include #include #include @@ -123,6 +124,7 @@ struct mVideoLogContext; struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; + struct GBAVideoGLRenderer glRenderer; struct GBAVideoProxyRenderer proxyRenderer; struct mVideoLogContext* logContext; struct mCoreCallbacks logCallbacks; @@ -166,6 +168,7 @@ static bool _GBACoreInit(struct mCore* core) { gba->rtcSource = &core->rtc.d; GBAVideoSoftwareRendererCreate(&gbacore->renderer); + GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->renderer.outputBuffer = NULL; #ifndef DISABLE_THREADING @@ -251,6 +254,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con #ifndef DISABLE_THREADING mCoreConfigCopyValue(&core->config, config, "threadedVideo"); #endif + mCoreConfigCopyValue(&core->config, config, "hwaccelVideo"); } static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { @@ -390,14 +394,17 @@ static void _GBACoreReset(struct mCore* core) { struct GBA* gba = (struct GBA*) core->board; if (gbacore->renderer.outputBuffer) { struct GBAVideoRenderer* renderer = &gbacore->renderer.d; -#ifndef DISABLE_THREADING int fakeBool; +#ifndef DISABLE_THREADING if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { if (!core->videoLogger) { core->videoLogger = &gbacore->threadProxy.d; } } #endif + if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { + renderer = &gbacore->glRenderer.d; + } if (core->videoLogger) { gbacore->proxyRenderer.logger = core->videoLogger; GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c new file mode 100644 index 000000000..54fb85a1f --- /dev/null +++ b/src/gba/renderers/gl.c @@ -0,0 +1,90 @@ +/* Copyright (c) 2013-2019 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 + +#include +#include +#include +#include + +static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); +static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); +static void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer); +static void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); +static void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); +static void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); +static uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); +static void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); +static void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer); +static void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels); +static void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels); + +void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { + renderer->d.init = GBAVideoGLRendererInit; + renderer->d.reset = GBAVideoGLRendererReset; + renderer->d.deinit = GBAVideoGLRendererDeinit; + renderer->d.writeVideoRegister = GBAVideoGLRendererWriteVideoRegister; + renderer->d.writeVRAM = GBAVideoGLRendererWriteVRAM; + renderer->d.writeOAM = GBAVideoGLRendererWriteOAM; + renderer->d.writePalette = GBAVideoGLRendererWritePalette; + renderer->d.drawScanline = GBAVideoGLRendererDrawScanline; + renderer->d.finishFrame = GBAVideoGLRendererFinishFrame; + renderer->d.getPixels = GBAVideoGLRendererGetPixels; + renderer->d.putPixels = GBAVideoGLRendererPutPixels; + + renderer->d.disableBG[0] = false; + renderer->d.disableBG[1] = false; + renderer->d.disableBG[2] = false; + renderer->d.disableBG[3] = false; + renderer->d.disableOBJ = false; + + renderer->temporaryBuffer = 0; +} + +void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { + +} + +void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { + +} + +void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { + +} + +void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { + +} + +void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) { + +} + +void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + +} + +uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + +} + +void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { + +} + +void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { + +} + +void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { + +} + +void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) { + +} + diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index c7374f274..722359255 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -287,13 +287,18 @@ void PainterGL::resizeContext() { return; } - m_gl->makeCurrent(); + if (!m_active) { + m_gl->makeCurrent(); #if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); + epoxy_handle_external_wglMakeCurrent(); #endif + } + QSize size = m_context->screenDimensions(); m_backend->setDimensions(m_backend, size.width(), size.height()); - m_gl->doneCurrent(); + if (!m_active) { + m_gl->doneCurrent(); + } } void PainterGL::setMessagePainter(MessagePainter* messagePainter) { @@ -340,7 +345,6 @@ void PainterGL::start() { } #endif - m_gl->doneCurrent(); m_active = true; m_started = true; } @@ -383,10 +387,6 @@ void PainterGL::forceDraw() { void PainterGL::stop() { m_active = false; m_started = false; - m_gl->makeCurrent(); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif dequeueAll(); m_backend->clear(m_backend); m_backend->swap(m_backend); @@ -463,11 +463,13 @@ void PainterGL::setShaders(struct VDir* dir) { if (!supportsShaders()) { return; } + if (!m_active) { #if !defined(_WIN32) || defined(USE_EPOXY) - m_gl->makeCurrent(); + m_gl->makeCurrent(); #if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); + epoxy_handle_external_wglMakeCurrent(); #endif + } if (m_shader.passes) { mGLES2ShaderDetach(reinterpret_cast(m_backend)); mGLES2ShaderFree(&m_shader); @@ -476,7 +478,9 @@ void PainterGL::setShaders(struct VDir* dir) { if (m_started) { mGLES2ShaderAttach(reinterpret_cast(m_backend), static_cast(m_shader.passes), m_shader.nPasses); } - m_gl->doneCurrent(); + if (!m_active) { + m_gl->doneCurrent(); + } #endif } @@ -484,16 +488,20 @@ void PainterGL::clearShaders() { if (!supportsShaders()) { return; } + if (!m_active) { #if !defined(_WIN32) || defined(USE_EPOXY) - m_gl->makeCurrent(); + m_gl->makeCurrent(); #if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); + epoxy_handle_external_wglMakeCurrent(); #endif + } if (m_shader.passes) { mGLES2ShaderDetach(reinterpret_cast(m_backend)); mGLES2ShaderFree(&m_shader); } - m_gl->doneCurrent(); + if (!m_active) { + m_gl->doneCurrent(); + } #endif } From f5d9e9ec5bcca9f5c8fbc573f14f7005efb4f81e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2019 20:43:55 -0700 Subject: [PATCH 186/429] GBA Video: Begin fleshing out GL renderer --- src/gba/core.c | 2 + src/gba/renderers/gl.c | 109 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 5 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 358b9882e..0edd73b85 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -267,6 +267,8 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.outputBuffer = buffer; gbacore->renderer.outputBufferStride = stride; + gbacore->glRenderer.outputBuffer = buffer; + gbacore->glRenderer.outputBufferStride = stride; memset(gbacore->renderer.scanlineDirty, 0xFFFFFFFF, sizeof(gbacore->renderer.scanlineDirty)); } diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 54fb85a1f..4a7fab348 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -22,6 +22,35 @@ static void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels); +static const GLchar* const _gl3Header = + "#version 120\n"; + +static const char* const _vertexShader = + "attribute vec4 position;\n" + "varying vec2 texCoord;\n" + + "void main() {\n" + " gl_Position = position;\n" + " texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.5, 0.5);\n" + "}"; + +static const char* const _fragmentShader = + "varying vec2 texCoord;\n" + "uniform sampler2D tex;\n" + + "void main() {\n" + " vec4 color = texture2D(tex, texCoord);\n" + " color.a = 1.;\n" + " gl_FragColor = color;\n" + "}"; + +static const GLfloat _vertices[] = { + -1.f, -1.f, + -1.f, 1.f, + 1.f, 1.f, + 1.f, -1.f, +}; + void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->d.init = GBAVideoGLRendererInit; renderer->d.reset = GBAVideoGLRendererReset; @@ -40,20 +69,67 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; - - renderer->temporaryBuffer = 0; } void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glGenFramebuffers(6, glRenderer->fbo); + glGenTextures(6, glRenderer->layers); + glGenTextures(1, &glRenderer->paletteTex); + + glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + GBAVideoGLRendererReset(renderer); } void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { - + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glDeleteFramebuffers(6, glRenderer->fbo); + glDeleteTextures(6, glRenderer->layers); + glDeleteTextures(1, &glRenderer->paletteTex); } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[5]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[5], 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glRenderer->compositeProgram = glCreateProgram(); + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + + const GLchar* shaderBuffer[2]; + const GLubyte* version = glGetString(GL_VERSION); + shaderBuffer[0] = _gl3Header; + shaderBuffer[1] = _vertexShader; + glShaderSource(vs, 2, shaderBuffer, 0); + shaderBuffer[1] = _fragmentShader; + glShaderSource(fs, 2, shaderBuffer, 0); + + glAttachShader(glRenderer->compositeProgram, vs); + glAttachShader(glRenderer->compositeProgram, fs); + char log[1024]; + + glCompileShader(fs); + glGetShaderInfoLog(fs, 1024, 0, log); + + glCompileShader(vs); + glGetShaderInfoLog(vs, 1024, 0, log); + + glLinkProgram(glRenderer->compositeProgram); + glGetProgramInfoLog(glRenderer->compositeProgram, 1024, 0, log); + + glRenderer->paletteDirty = false; } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { @@ -65,7 +141,8 @@ void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) } void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { - + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->paletteDirty = true; } uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { @@ -73,11 +150,33 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, } void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + if (glRenderer->paletteDirty) { + glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 256, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); + glRenderer->paletteDirty = false; + } + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUseProgram(glRenderer->compositeProgram); + glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); + glUniform1i(0, 0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { - + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glFinish(); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); + glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); + glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); + glClearColor(1.f, 1.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { From e99cd34b668d0b0449dd8e2062cc7dad918f6aeb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 9 May 2019 13:32:51 -0700 Subject: [PATCH 187/429] GBA Video: Move video registers and structs into common file --- .../internal/gba/renderers/video-software.h | 23 +---------------- include/mgba/internal/gba/video.h | 25 +++++++++++++++++-- src/gba/renderers/video-software.c | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 8bfc3da9b..3012cc10f 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -49,13 +49,6 @@ struct GBAVideoSoftwareBackground { int32_t offsetY; }; -enum BlendEffect { - BLEND_NONE = 0, - BLEND_ALPHA = 1, - BLEND_BRIGHTEN = 2, - BLEND_DARKEN = 3 -}; - enum { #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 @@ -87,20 +80,6 @@ struct WindowRegion { uint8_t start; }; -DECL_BITFIELD(GBAWindowControl, uint8_t); -DECL_BIT(GBAWindowControl, Bg0Enable, 0); -DECL_BIT(GBAWindowControl, Bg1Enable, 1); -DECL_BIT(GBAWindowControl, Bg2Enable, 2); -DECL_BIT(GBAWindowControl, Bg3Enable, 3); -DECL_BIT(GBAWindowControl, ObjEnable, 4); -DECL_BIT(GBAWindowControl, BlendEnable, 5); - -DECL_BITFIELD(GBAMosaicControl, uint16_t); -DECL_BITS(GBAMosaicControl, BgH, 0, 4); -DECL_BITS(GBAMosaicControl, BgV, 4, 4); -DECL_BITS(GBAMosaicControl, ObjH, 8, 4); -DECL_BITS(GBAMosaicControl, ObjV, 12, 4); - struct WindowControl { GBAWindowControl packed; int8_t priority; @@ -133,7 +112,7 @@ struct GBAVideoSoftwareRenderer { unsigned target2Obj; unsigned target2Bd; bool blendDirty; - enum BlendEffect blendEffect; + enum GBAVideoBlendEffect blendEffect; color_t normalPalette[512]; color_t variantPalette[512]; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 15e3a4381..699d2f238 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -32,18 +32,25 @@ enum { BASE_TILE = 0x00010000 }; -enum ObjMode { +enum GBAVideoObjMode { OBJ_MODE_NORMAL = 0, OBJ_MODE_SEMITRANSPARENT = 1, OBJ_MODE_OBJWIN = 2 }; -enum ObjShape { +enum GBAVideoObjShape { OBJ_SHAPE_SQUARE = 0, OBJ_SHAPE_HORIZONTAL = 1, OBJ_SHAPE_VERTICAL = 2 }; +enum GBAVideoBlendEffect { + BLEND_NONE = 0, + BLEND_ALPHA = 1, + BLEND_BRIGHTEN = 2, + BLEND_DARKEN = 3 +}; + DECL_BITFIELD(GBAObjAttributesA, uint16_t); DECL_BITS(GBAObjAttributesA, Y, 0, 8); DECL_BIT(GBAObjAttributesA, Transformed, 8); @@ -144,6 +151,20 @@ DECL_BIT(GBARegisterBLDCNT, Target2Bg3, 11); DECL_BIT(GBARegisterBLDCNT, Target2Obj, 12); DECL_BIT(GBARegisterBLDCNT, Target2Bd, 13); +DECL_BITFIELD(GBAWindowControl, uint8_t); +DECL_BIT(GBAWindowControl, Bg0Enable, 0); +DECL_BIT(GBAWindowControl, Bg1Enable, 1); +DECL_BIT(GBAWindowControl, Bg2Enable, 2); +DECL_BIT(GBAWindowControl, Bg3Enable, 3); +DECL_BIT(GBAWindowControl, ObjEnable, 4); +DECL_BIT(GBAWindowControl, BlendEnable, 5); + +DECL_BITFIELD(GBAMosaicControl, uint16_t); +DECL_BITS(GBAMosaicControl, BgH, 0, 4); +DECL_BITS(GBAMosaicControl, BgV, 4, 4); +DECL_BITS(GBAMosaicControl, ObjH, 8, 4); +DECL_BITS(GBAMosaicControl, ObjV, 12, 4); + struct GBAVideoRenderer { void (*init)(struct GBAVideoRenderer* renderer); void (*reset)(struct GBAVideoRenderer* renderer); diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 951febc5e..46f6cb958 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -787,7 +787,7 @@ static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackgroun } static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value) { - enum BlendEffect oldEffect = renderer->blendEffect; + enum GBAVideoBlendEffect oldEffect = renderer->blendEffect; renderer->bg[0].target1 = GBARegisterBLDCNTGetTarget1Bg0(value); renderer->bg[1].target1 = GBARegisterBLDCNTGetTarget1Bg1(value); From bb997f9b461019cb9a75449987817e97295ef1ae Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 9 May 2019 15:15:16 -0700 Subject: [PATCH 188/429] GBA Video: Start mode 0 GL renderer --- include/mgba/internal/gba/renderers/gl.h | 103 ++++++ src/gba/renderers/gl.c | 411 +++++++++++++++++++++-- 2 files changed, 482 insertions(+), 32 deletions(-) create mode 100644 include/mgba/internal/gba/renderers/gl.h diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h new file mode 100644 index 000000000..d7ea02c6f --- /dev/null +++ b/include/mgba/internal/gba/renderers/gl.h @@ -0,0 +1,103 @@ +/* Copyright (c) 2013-2019 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/. */ +#ifndef VIDEO_GL_H +#define VIDEO_GL_H + +#include + +CXX_GUARD_START + +#include +#include +#include +#include + +#ifdef USE_EPOXY +#include +#elif defined(BUILD_GL) +#ifdef __APPLE__ +#include +#else +#define GL_GLEXT_PROTOTYPES +#include +#include +#endif +#else +#include +#endif + +struct GBAVideoGLBackground { + GLuint fbo; + GLuint tex; + GLuint program; + + unsigned index; + int enabled; + unsigned priority; + uint32_t charBase; + int mosaic; + int multipalette; + uint32_t screenBase; + int overflow; + int size; + int target1; + int target2; + uint16_t x; + uint16_t y; + int32_t refx; + int32_t refy; + int16_t dx; + int16_t dmx; + int16_t dy; + int16_t dmy; + int32_t sx; + int32_t sy; +}; + +struct GBAVideoGLRenderer { + struct GBAVideoRenderer d; + + struct GBAVideoGLBackground bg[4]; + + GLuint fbo[2]; + GLuint layers[2]; + + color_t* outputBuffer; + int outputBufferStride; + + GLuint paletteTex; + bool paletteDirty; + + GLuint oamTex; + bool oamDirty; + + GLuint vramTex; + unsigned vramDirty; + + GLuint bgPrograms[6]; + GLuint objProgram; + + GLuint compositeProgram; + + GBARegisterDISPCNT dispcnt; + + unsigned target1Obj; + unsigned target1Bd; + unsigned target2Obj; + unsigned target2Bd; + enum GBAVideoBlendEffect blendEffect; + uint16_t blda; + uint16_t bldb; + uint16_t bldy; + + GBAMosaicControl mosaic; +}; + +void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer); + +CXX_GUARD_END + +#endif \ No newline at end of file diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 4a7fab348..b87701d8c 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -22,33 +22,73 @@ static void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels); +static void GBAVideoGLRendererUpdateDISPCNT(struct GBAVideoGLRenderer* renderer); +static void GBAVideoGLRendererWriteBGCNT(struct GBAVideoGLBackground* bg, uint16_t value); +static void GBAVideoGLRendererWriteBGX_LO(struct GBAVideoGLBackground* bg, uint16_t value); +static void GBAVideoGLRendererWriteBGX_HI(struct GBAVideoGLBackground* bg, uint16_t value); +static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint16_t value); +static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value); +static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value); + static const GLchar* const _gl3Header = - "#version 120\n"; + "#version 130\n"; static const char* const _vertexShader = - "attribute vec4 position;\n" + "attribute vec2 position;\n" + "uniform int y;\n" + "const ivec2 maxPos = ivec2(240, 160);\n" "varying vec2 texCoord;\n" "void main() {\n" - " gl_Position = position;\n" - " texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.5, 0.5);\n" + " vec2 local = (position + vec2(0, y)) / vec2(1., maxPos.y);\n" + " gl_Position = vec4(local * 2. - 1., 0., 1.);\n" + " texCoord = local * maxPos;\n" "}"; -static const char* const _fragmentShader = +static const char* const _renderTile16 = + "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord) {\n" + " int address = tileBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" + " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" + " int entry = int(halfrow[3 - (localCoord.x & 3)] * 16.);\n" + " vec4 color = texelFetch(palette, ivec2(entry, paletteId), 0);\n" + " if (entry > 0) {\n" + " color.a = 1.;\n" + " } else {\n" + " color.a = 0.;\n" + " }\n" + " return color;\n" + "}"; + +static const char* const _renderMode0 = "varying vec2 texCoord;\n" - "uniform sampler2D tex;\n" + "uniform sampler2D vram;\n" + "uniform sampler2D palette;\n" + "uniform int screenBase;\n" + "uniform int charBase;\n" + "uniform ivec2 offset;\n" + + "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " vec4 color = texture2D(tex, texCoord);\n" - " color.a = 1.;\n" - " gl_FragColor = color;\n" + " ivec2 coord = ivec2(texCoord) + offset;\n" + " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" + " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" + " int flags = int(map.g * 15.9);\n" + " if ((flags & 4) == 4) {\n" + " coord.x ^= 7;\n" + " }\n" + " if ((flags & 8) == 8) {\n" + " coord.y ^= 7;\n" + " }\n" + " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (flags & 0x3) * 256;\n" + " gl_FragColor = renderTile(tile, charBase, int(map.r * 15.9), coord & 7);\n" "}"; -static const GLfloat _vertices[] = { - -1.f, -1.f, - -1.f, 1.f, - 1.f, 1.f, - 1.f, -1.f, +static const GLint _vertices[] = { + 0, 0, + 0, 1, + 1, 1, + 1, 0, }; void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { @@ -73,8 +113,8 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glGenFramebuffers(6, glRenderer->fbo); - glGenTextures(6, glRenderer->layers); + glGenFramebuffers(2, glRenderer->fbo); + glGenTextures(2, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); @@ -82,39 +122,48 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glGenTextures(1, &glRenderer->vramTex); + + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + GBAVideoGLRendererReset(renderer); } void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glDeleteFramebuffers(6, glRenderer->fbo); - glDeleteTextures(6, glRenderer->layers); + glDeleteFramebuffers(2, glRenderer->fbo); + glDeleteTextures(2, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); + glDeleteTextures(1, &glRenderer->vramTex); + glDeleteTextures(1, &glRenderer->oamTex); } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[5]); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[5], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[1], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); glRenderer->compositeProgram = glCreateProgram(); GLuint vs = glCreateShader(GL_VERTEX_SHADER); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); - const GLchar* shaderBuffer[2]; + const GLchar* shaderBuffer[3]; const GLubyte* version = glGetString(GL_VERSION); shaderBuffer[0] = _gl3Header; shaderBuffer[1] = _vertexShader; glShaderSource(vs, 2, shaderBuffer, 0); - shaderBuffer[1] = _fragmentShader; - glShaderSource(fs, 2, shaderBuffer, 0); + shaderBuffer[1] = _renderMode0; + shaderBuffer[2] = _renderTile16; + glShaderSource(fs, 3, shaderBuffer, 0); glAttachShader(glRenderer->compositeProgram, vs); glAttachShader(glRenderer->compositeProgram, fs); @@ -122,46 +171,294 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { glCompileShader(fs); glGetShaderInfoLog(fs, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Fragment shader compilation failure: %s", log); + } glCompileShader(vs); glGetShaderInfoLog(vs, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Vertex shader compilation failure: %s", log); + } glLinkProgram(glRenderer->compositeProgram); glGetProgramInfoLog(glRenderer->compositeProgram, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); + } - glRenderer->paletteDirty = false; + glRenderer->paletteDirty = true; + glRenderer->vramDirty = 0xFFFFFF; + + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { - + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->vramDirty |= 1 << (address >> 12); } void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) { - + UNUSED(oam); + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->oamDirty = true; } void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + UNUSED(address); + UNUSED(value); struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glRenderer->paletteDirty = true; } uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + if (renderer->cache) { + GBAVideoCacheWriteVideoRegister(renderer->cache, address, value); + } + switch (address) { + case REG_DISPCNT: + value &= 0xFFF7; + glRenderer->dispcnt = value; + //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + break; + case REG_BG0CNT: + value &= 0xDFFF; + GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[0], value); + //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + break; + case REG_BG1CNT: + value &= 0xDFFF; + GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[1], value); + //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + break; + case REG_BG2CNT: + value &= 0xFFFF; + GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[2], value); + //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + break; + case REG_BG3CNT: + value &= 0xFFFF; + GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[3], value); + //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + break; + case REG_BG0HOFS: + value &= 0x01FF; + glRenderer->bg[0].x = value; + break; + case REG_BG0VOFS: + value &= 0x01FF; + glRenderer->bg[0].y = value; + break; + case REG_BG1HOFS: + value &= 0x01FF; + glRenderer->bg[1].x = value; + break; + case REG_BG1VOFS: + value &= 0x01FF; + glRenderer->bg[1].y = value; + break; + case REG_BG2HOFS: + value &= 0x01FF; + glRenderer->bg[2].x = value; + break; + case REG_BG2VOFS: + value &= 0x01FF; + glRenderer->bg[2].y = value; + break; + case REG_BG3HOFS: + value &= 0x01FF; + glRenderer->bg[3].x = value; + break; + case REG_BG3VOFS: + value &= 0x01FF; + glRenderer->bg[3].y = value; + break; + case REG_BG2PA: + glRenderer->bg[2].dx = value; + break; + case REG_BG2PB: + glRenderer->bg[2].dmx = value; + break; + case REG_BG2PC: + glRenderer->bg[2].dy = value; + break; + case REG_BG2PD: + glRenderer->bg[2].dmy = value; + break; + case REG_BG2X_LO: + GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value); + break; + case REG_BG2X_HI: + GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[2], value); + break; + case REG_BG2Y_LO: + GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[2], value); + break; + case REG_BG2Y_HI: + GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value); + break; + case REG_BG3PA: + glRenderer->bg[3].dx = value; + break; + case REG_BG3PB: + glRenderer->bg[3].dmx = value; + break; + case REG_BG3PC: + glRenderer->bg[3].dy = value; + break; + case REG_BG3PD: + glRenderer->bg[3].dmy = value; + break; + case REG_BG3X_LO: + GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value); + break; + case REG_BG3X_HI: + GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[3], value); + break; + case REG_BG3Y_LO: + GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[3], value); + break; + case REG_BG3Y_HI: + GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[3], value); + break; + case REG_BLDCNT: + GBAVideoGLRendererWriteBLDCNT(glRenderer, value); + value &= 0x3FFF; + break; + case REG_BLDALPHA: + glRenderer->blda = value & 0x1F; + if (glRenderer->blda > 0x10) { + glRenderer->blda = 0x10; + } + glRenderer->bldb = (value >> 8) & 0x1F; + if (glRenderer->bldb > 0x10) { + glRenderer->bldb = 0x10; + } + value &= 0x1F1F; + break; + case REG_BLDY: + value &= 0x1F; + if (value > 0x10) { + value = 0x10; + } + if (glRenderer->bldy != value) { + glRenderer->bldy = value; + } + break; + case REG_WIN0H: + /*glRenderer->winN[0].h.end = value; + glRenderer->winN[0].h.start = value >> 8; + if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h.start > glRenderer->winN[0].h.end) { + glRenderer->winN[0].h.start = 0; + } + if (glRenderer->winN[0].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + } + }*/ + break; + case REG_WIN1H: + /*glRenderer->winN[1].h.end = value; + glRenderer->winN[1].h.start = value >> 8; + if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h.start > glRenderer->winN[1].h.end) { + glRenderer->winN[1].h.start = 0; + } + if (glRenderer->winN[1].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + } + }*/ + break; + case REG_WIN0V: + /*glRenderer->winN[0].v.end = value; + glRenderer->winN[0].v.start = value >> 8; + if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[0].v.start > glRenderer->winN[0].v.end) { + glRenderer->winN[0].v.start = 0; + } + if (glRenderer->winN[0].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[0].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; + } + }*/ + break; + case REG_WIN1V: + /*glRenderer->winN[1].v.end = value; + glRenderer->winN[1].v.start = value >> 8; + if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[1].v.start > glRenderer->winN[1].v.end) { + glRenderer->winN[1].v.start = 0; + } + if (glRenderer->winN[1].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[1].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; + } + }*/ + break; + case REG_WININ: + value &= 0x3F3F; + //glRenderer->winN[0].control.packed = value; + //glRenderer->winN[1].control.packed = value >> 8; + break; + case REG_WINOUT: + value &= 0x3F3F; + //glRenderer->winout.packed = value; + //glRenderer->objwin.packed = value >> 8; + break; + case REG_MOSAIC: + glRenderer->mosaic = value; + break; + case REG_GREENSWP: + mLOG(GBA_VIDEO, STUB, "Stub video register write: 0x%03X", address); + break; + default: + mLOG(GBA_VIDEO, GAME_ERROR, "Invalid video register: 0x%03X", address); + } + return value; } void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; if (glRenderer->paletteDirty) { glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 256, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); glRenderer->paletteDirty = false; } - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); + if (glRenderer->oamDirty) { + glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 4, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, glRenderer->d.oam); + glRenderer->oamDirty = false; + } + int i; + for (i = 0; i < 24; ++i) { + if (!(glRenderer->vramDirty & (1 << i))) { + continue; + } + // TODO: PBOs + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * i, 256, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * i]); + } + glRenderer->vramDirty = 0; + + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUseProgram(glRenderer->compositeProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); - glUniform1i(0, 0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, _vertices); + glUniform1i(0, y); + glUniform1i(1, 0); + glUniform1i(2, 1); + glUniform1i(3, glRenderer->bg[0].screenBase); + glUniform1i(4, glRenderer->bg[0].charBase); + glUniform2i(5, glRenderer->bg[0].x, glRenderer->bg[0].y); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -171,7 +468,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glFinish(); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[5]); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); glClearColor(1.f, 1.f, 0.f, 1.f); @@ -187,3 +484,53 @@ void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t strid } +static void GBAVideoGLRendererWriteBGCNT(struct GBAVideoGLBackground* bg, uint16_t value) { + bg->priority = GBARegisterBGCNTGetPriority(value); + bg->charBase = GBARegisterBGCNTGetCharBase(value) << 13; + bg->mosaic = GBARegisterBGCNTGetMosaic(value); + bg->multipalette = GBARegisterBGCNTGet256Color(value); + bg->screenBase = GBARegisterBGCNTGetScreenBase(value) << 10; + bg->overflow = GBARegisterBGCNTGetOverflow(value); + bg->size = GBARegisterBGCNTGetSize(value); +} + +static void GBAVideoGLRendererWriteBGX_LO(struct GBAVideoGLBackground* bg, uint16_t value) { + bg->refx = (bg->refx & 0xFFFF0000) | value; + bg->sx = bg->refx; +} + +static void GBAVideoGLRendererWriteBGX_HI(struct GBAVideoGLBackground* bg, uint16_t value) { + bg->refx = (bg->refx & 0x0000FFFF) | (value << 16); + bg->refx <<= 4; + bg->refx >>= 4; + bg->sx = bg->refx; +} + +static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint16_t value) { + bg->refy = (bg->refy & 0xFFFF0000) | value; + bg->sy = bg->refy; +} + +static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value) { + bg->refy = (bg->refy & 0x0000FFFF) | (value << 16); + bg->refy <<= 4; + bg->refy >>= 4; + bg->sy = bg->refy; +} + +static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value) { + renderer->bg[0].target1 = GBARegisterBLDCNTGetTarget1Bg0(value); + renderer->bg[1].target1 = GBARegisterBLDCNTGetTarget1Bg1(value); + renderer->bg[2].target1 = GBARegisterBLDCNTGetTarget1Bg2(value); + renderer->bg[3].target1 = GBARegisterBLDCNTGetTarget1Bg3(value); + renderer->bg[0].target2 = GBARegisterBLDCNTGetTarget2Bg0(value); + renderer->bg[1].target2 = GBARegisterBLDCNTGetTarget2Bg1(value); + renderer->bg[2].target2 = GBARegisterBLDCNTGetTarget2Bg2(value); + renderer->bg[3].target2 = GBARegisterBLDCNTGetTarget2Bg3(value); + + renderer->blendEffect = GBARegisterBLDCNTGetEffect(value); + renderer->target1Obj = GBARegisterBLDCNTGetTarget1Obj(value); + renderer->target1Bd = GBARegisterBLDCNTGetTarget1Bd(value); + renderer->target2Obj = GBARegisterBLDCNTGetTarget2Obj(value); + renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); +} \ No newline at end of file From b86857696a32a0c28fc542d6fda7071836b4cd39 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 00:32:48 -0700 Subject: [PATCH 189/429] GBA Video: Mostly functional mode 0 GL renderer --- include/mgba/internal/gba/renderers/gl.h | 5 +- src/gba/renderers/gl.c | 330 +++++++++++++++++------ 2 files changed, 252 insertions(+), 83 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index d7ea02c6f..254ba743d 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -32,7 +32,6 @@ CXX_GUARD_START struct GBAVideoGLBackground { GLuint fbo; GLuint tex; - GLuint program; unsigned index; int enabled; @@ -63,7 +62,7 @@ struct GBAVideoGLRenderer { struct GBAVideoGLBackground bg[4]; GLuint fbo[2]; - GLuint layers[2]; + GLuint layers[4]; color_t* outputBuffer; int outputBufferStride; @@ -77,7 +76,7 @@ struct GBAVideoGLRenderer { GLuint vramTex; unsigned vramDirty; - GLuint bgPrograms[6]; + GLuint bgProgram[6]; GLuint objProgram; GLuint compositeProgram; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index b87701d8c..7ae958a0e 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -30,17 +30,25 @@ static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint1 static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value); static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value); +static void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); + +#define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority + static const GLchar* const _gl3Header = "#version 130\n"; static const char* const _vertexShader = "attribute vec2 position;\n" - "uniform int y;\n" + "uniform ivec2 loc;\n" "const ivec2 maxPos = ivec2(240, 160);\n" "varying vec2 texCoord;\n" "void main() {\n" - " vec2 local = (position + vec2(0, y)) / vec2(1., maxPos.y);\n" + " vec2 local = (position + vec2(0, loc.y)) / vec2(1., maxPos.y);\n" " gl_Position = vec4(local * 2. - 1., 0., 1.);\n" " texCoord = local * maxPos;\n" "}"; @@ -49,9 +57,24 @@ static const char* const _renderTile16 = "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord) {\n" " int address = tileBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" - " int entry = int(halfrow[3 - (localCoord.x & 3)] * 16.);\n" + " int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, paletteId), 0);\n" - " if (entry > 0) {\n" + " if (entry == 0) {\n" + " color.a = 0;\n" + " } else {\n" + " color.a = 1;\n" + " }\n" + " return color;\n" + "}"; + +static const char* const _renderTile256 = + "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord) {\n" + " int address = tileBase + tile * 32 + (localCoord.x >> 1) + (localCoord.y << 2);\n" + " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" + " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" + " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" + " vec4 color = texelFetch(palette, ivec2(entry, pal2 + (paletteId & 16)), 0);\n" + " if (pal2 > 0 || entry > 0) {\n" " color.a = 1.;\n" " } else {\n" " color.a = 0.;\n" @@ -70,7 +93,7 @@ static const char* const _renderMode0 = "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " ivec2 coord = ivec2(texCoord) + offset;\n" + " ivec2 coord = (ivec2(texCoord) + offset) & 255;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int flags = int(map.g * 15.9);\n" @@ -84,6 +107,18 @@ static const char* const _renderMode0 = " gl_FragColor = renderTile(tile, charBase, int(map.r * 15.9), coord & 7);\n" "}"; +static const char* const _composite = + "varying vec2 texCoord;\n" + "uniform sampler2D layer;\n" + + "void main() {\n" + " vec4 color = texelFetch(layer, ivec2(texCoord), 0);\n" + " if (color.a == 0) {\n" + " discard;\n" + " }\n" + " gl_FragColor = color;\n" + "}"; + static const GLint _vertices[] = { 0, 0, 0, 1, @@ -111,22 +146,114 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->d.disableOBJ = false; } +void _compileBackground(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + glAttachShader(program, vs); + glAttachShader(program, fs); + glShaderSource(fs, shaderBufferLines, shaderBuffer, 0); + glCompileShader(fs); + glGetShaderInfoLog(fs, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Fragment shader compilation failure: %s", log); + } + glLinkProgram(program); + glGetProgramInfoLog(program, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); + } + glDeleteShader(fs); +} + void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(2, glRenderer->fbo); - glGenTextures(2, glRenderer->layers); + glGenTextures(4, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); - glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glGenTextures(1, &glRenderer->vramTex); - glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); + + glGenTextures(1, &glRenderer->oamTex); + glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[2], 0); + + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[3], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + int i; + for (i = 0; i < 4; ++i) { + glRenderer->bg[i].index = i; + glGenFramebuffers(1, &glRenderer->bg[i].fbo); + glGenTextures(1, &glRenderer->bg[i].tex); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); + glBindTexture(GL_TEXTURE_2D, glRenderer->bg[i].tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->bg[i].tex, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + glRenderer->compositeProgram = glCreateProgram(); + glRenderer->objProgram = glCreateProgram(); + glRenderer->bgProgram[0] = glCreateProgram(); + glRenderer->bgProgram[1] = glCreateProgram(); + glRenderer->bgProgram[2] = glCreateProgram(); + glRenderer->bgProgram[3] = glCreateProgram(); + glRenderer->bgProgram[4] = glCreateProgram(); + glRenderer->bgProgram[5] = glCreateProgram(); + + char log[1024]; + const GLchar* shaderBuffer[8]; + shaderBuffer[0] = _gl3Header; + + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + shaderBuffer[1] = _vertexShader; + glShaderSource(vs, 2, shaderBuffer, 0); + glCompileShader(vs); + glGetShaderInfoLog(vs, 1024, 0, log); + if (log[0]) { + mLOG(GBA_VIDEO, ERROR, "Vertex shader compilation failure: %s", log); + } + + shaderBuffer[1] = _renderMode0; + + shaderBuffer[2] = _renderTile16; + _compileBackground(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); + + shaderBuffer[2] = _renderTile256; + _compileBackground(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); + + shaderBuffer[1] = _composite; + _compileBackground(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); + + glDeleteShader(vs); GBAVideoGLRendererReset(renderer); } @@ -134,7 +261,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glDeleteFramebuffers(2, glRenderer->fbo); - glDeleteTextures(2, glRenderer->layers); + glDeleteTextures(4, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); glDeleteTextures(1, &glRenderer->oamTex); @@ -142,56 +269,9 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[1]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[1], 0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glRenderer->compositeProgram = glCreateProgram(); - GLuint vs = glCreateShader(GL_VERTEX_SHADER); - GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); - - const GLchar* shaderBuffer[3]; - const GLubyte* version = glGetString(GL_VERSION); - shaderBuffer[0] = _gl3Header; - shaderBuffer[1] = _vertexShader; - glShaderSource(vs, 2, shaderBuffer, 0); - shaderBuffer[1] = _renderMode0; - shaderBuffer[2] = _renderTile16; - glShaderSource(fs, 3, shaderBuffer, 0); - - glAttachShader(glRenderer->compositeProgram, vs); - glAttachShader(glRenderer->compositeProgram, fs); - char log[1024]; - - glCompileShader(fs); - glGetShaderInfoLog(fs, 1024, 0, log); - if (log[0]) { - mLOG(GBA_VIDEO, ERROR, "Fragment shader compilation failure: %s", log); - } - - glCompileShader(vs); - glGetShaderInfoLog(vs, 1024, 0, log); - if (log[0]) { - mLOG(GBA_VIDEO, ERROR, "Vertex shader compilation failure: %s", log); - } - - glLinkProgram(glRenderer->compositeProgram); - glGetProgramInfoLog(glRenderer->compositeProgram, 1024, 0, log); - if (log[0]) { - mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); - } glRenderer->paletteDirty = true; glRenderer->vramDirty = 0xFFFFFF; - - glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { @@ -222,27 +302,23 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, case REG_DISPCNT: value &= 0xFFF7; glRenderer->dispcnt = value; - //GBAVideoGLRendererUpdateDISPCNT(glRenderer); + GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG0CNT: value &= 0xDFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[0], value); - //GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG1CNT: value &= 0xDFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[1], value); - //GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG2CNT: value &= 0xFFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[2], value); - //GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG3CNT: value &= 0xFFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[3], value); - //GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG0HOFS: value &= 0x01FF; @@ -445,24 +521,51 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->vramDirty = 0; - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUseProgram(glRenderer->compositeProgram); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); - glUniform1i(0, y); - glUniform1i(1, 0); - glUniform1i(2, 1); - glUniform1i(3, glRenderer->bg[0].screenBase); - glUniform1i(4, glRenderer->bg[0].charBase); - glUniform2i(5, glRenderer->bg[0].x, glRenderer->bg[0].y); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + unsigned priority; + for (priority = 0; priority < 4; ++priority) { + if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[0], y); + } + if (TEST_LAYER_ENABLED(1) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[1], y); + } + if (TEST_LAYER_ENABLED(2)) { + switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { + case 0: + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[2], y); + break; + case 1: + case 2: + //GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); + break; + case 3: + //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); + break; + case 4: + //GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); + break; + case 5: + //GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); + break; + } + } + if (TEST_LAYER_ENABLED(3)) { + switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { + case 0: + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[3], y); + break; + case 2: + //GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[3], y); + break; + } + } + } + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + glRenderer->bg[2].sx += glRenderer->bg[2].dmx; + glRenderer->bg[2].sy += glRenderer->bg[2].dmy; + glRenderer->bg[3].sx += glRenderer->bg[3].dmx; + glRenderer->bg[3].sy += glRenderer->bg[3].dmy; + } } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { @@ -471,7 +574,15 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); - glClearColor(1.f, 1.f, 0.f, 1.f); + glClearColor(1.f, 1.f, 1.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[0].fbo); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[1].fbo); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[2].fbo); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[3].fbo); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -484,6 +595,28 @@ void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t strid } +static void _enableBg(struct GBAVideoGLRenderer* renderer, int bg, bool active) { + int wasActive = renderer->bg[bg].enabled; + if (!active) { + renderer->bg[bg].enabled = 0; + } else if (!wasActive && active) { + /*if (renderer->nextY == 0 || GBARegisterDISPCNTGetMode(renderer->dispcnt) > 2) { + // TODO: Investigate in more depth how switching background works in different modes + renderer->bg[bg].enabled = 4; + } else { + renderer->bg[bg].enabled = 1; + }*/ + renderer->bg[bg].enabled = 4; + } +} + +static void GBAVideoGLRendererUpdateDISPCNT(struct GBAVideoGLRenderer* renderer) { + _enableBg(renderer, 0, GBARegisterDISPCNTGetBg0Enable(renderer->dispcnt)); + _enableBg(renderer, 1, GBARegisterDISPCNTGetBg1Enable(renderer->dispcnt)); + _enableBg(renderer, 2, GBARegisterDISPCNTGetBg2Enable(renderer->dispcnt)); + _enableBg(renderer, 3, GBARegisterDISPCNTGetBg3Enable(renderer->dispcnt)); +} + static void GBAVideoGLRendererWriteBGCNT(struct GBAVideoGLBackground* bg, uint16_t value) { bg->priority = GBARegisterBGCNTGetPriority(value); bg->charBase = GBARegisterBGCNTGetCharBase(value) << 13; @@ -533,4 +666,41 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target1Bd = GBARegisterBLDCNTGetTarget1Bd(value); renderer->target2Obj = GBARegisterBLDCNTGetTarget2Obj(value); renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); +} + +void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glScissor(0, 1, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glUseProgram(renderer->bgProgram[background->multipalette ? 1 : 0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->vramTex); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); + glUniform2i(0, 0, y); + glUniform1i(1, 0); + glUniform1i(2, 1); + glUniform1i(3, background->screenBase); + glUniform1i(4, background->charBase); + glUniform2i(5, background->x, background->y); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glScissor(0, 1, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glUseProgram(renderer->compositeProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, background->tex); + glUniform2i(0, (background->priority << 3) + (background->index << 1) + 1, y); + glUniform1i(1, 0); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisable(GL_DEPTH_TEST); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); } \ No newline at end of file From 1a04532d4b00a33fa6adef638290a2f9632badfb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 11:10:21 -0700 Subject: [PATCH 190/429] GBA Video: Finish GL mode 0 renderer --- src/gba/renderers/gl.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 7ae958a0e..ac026dc68 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -88,12 +88,17 @@ static const char* const _renderMode0 = "uniform sampler2D palette;\n" "uniform int screenBase;\n" "uniform int charBase;\n" + "uniform int size;\n" "uniform ivec2 offset;\n" "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " ivec2 coord = (ivec2(texCoord) + offset) & 255;\n" + " ivec2 coord = ivec2(texCoord) + offset;\n" + " if ((size & 1) == 1) {\n" + " coord.y += coord.x & 256;\n" + " }\n" + " coord.x &= 255;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int flags = int(map.g * 15.9);\n" @@ -521,6 +526,14 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->vramDirty = 0; + uint32_t backdrop = M_RGB5_TO_RGB8(renderer->palette[0]); + glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); + glEnable(GL_SCISSOR_TEST); + glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + unsigned priority; for (priority = 0; priority < 4; ++priority) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -574,16 +587,6 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); - glClearColor(1.f, 1.f, 1.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[0].fbo); - glClear(GL_COLOR_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[1].fbo); - glClear(GL_COLOR_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[2].fbo); - glClear(GL_COLOR_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[3].fbo); - glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -669,9 +672,16 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u } void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + int inY = y + background->y; + int yBase = inY & 0xFF; + if (background->size == 2) { + yBase += inY & 0x100; + } else if (background->size == 3) { + yBase += (inY & 0x100) << 1; + } glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, 1, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); glUseProgram(renderer->bgProgram[background->multipalette ? 1 : 0]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); @@ -682,14 +692,15 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform1i(2, 1); glUniform1i(3, background->screenBase); glUniform1i(4, background->charBase); - glUniform2i(5, background->x, background->y); + glUniform1i(5, background->size); + glUniform2i(6, background->x, yBase - y); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, 1, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glUseProgram(renderer->compositeProgram); From 51a174e4c57ca7a8189ee53b6bc227fe5698442a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 12:17:19 -0700 Subject: [PATCH 191/429] GBA Video: Better batching/depth testing --- src/gba/renderers/gl.c | 49 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ac026dc68..73e7bb78a 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -43,14 +43,14 @@ static const GLchar* const _gl3Header = static const char* const _vertexShader = "attribute vec2 position;\n" - "uniform ivec2 loc;\n" - "const ivec2 maxPos = ivec2(240, 160);\n" + "uniform ivec3 loc;\n" + "const ivec3 maxPos = ivec3(240, 160, 32);\n" "varying vec2 texCoord;\n" "void main() {\n" - " vec2 local = (position + vec2(0, loc.y)) / vec2(1., maxPos.y);\n" - " gl_Position = vec4(local * 2. - 1., 0., 1.);\n" - " texCoord = local * maxPos;\n" + " vec2 local = (position * loc.x + vec2(0, loc.y)) / vec2(1., maxPos.y);\n" + " gl_Position = vec4(local * 2. - 1., loc.z / float(maxPos.z), 1.);\n" + " texCoord = local * maxPos.xy;\n" "}"; static const char* const _renderTile16 = @@ -531,7 +531,12 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glEnable(GL_SCISSOR_TEST); glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_SCISSOR_TEST); + if (y == 0) { + glClearDepthf(1); + glClear(GL_DEPTH_BUFFER_BIT); + } glBindFramebuffer(GL_FRAMEBUFFER, 0); unsigned priority; @@ -687,7 +692,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(0, 0, y); + glUniform3i(0, 1, y, 0); glUniform1i(1, 0); glUniform1i(2, 1); glUniform1i(3, background->screenBase); @@ -698,20 +703,22 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); - glDepthFunc(GL_LESS); - glEnable(GL_DEPTH_TEST); - glUseProgram(renderer->compositeProgram); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, background->tex); - glUniform2i(0, (background->priority << 3) + (background->index << 1) + 1, y); - glUniform1i(1, 0); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisable(GL_DEPTH_TEST); + if ((y & 0x1F) == 0x1F) { + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glScissor(0, y & ~0x1F, GBA_VIDEO_HORIZONTAL_PIXELS, 0x20); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glUseProgram(renderer->compositeProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, background->tex); + glUniform3i(0, 0x20, y & ~0x1F, (background->priority << 3) + (background->index << 1) + 1); + glUniform1i(1, 0); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisable(GL_DEPTH_TEST); + } glBindFramebuffer(GL_FRAMEBUFFER, 0); } \ No newline at end of file From 7edf7cdb159618bfe4c58d1306f004238556b25a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 12:26:39 -0700 Subject: [PATCH 192/429] GBA Video: Pass disabled layers through proxy --- src/gba/extra/proxy.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index ea884db3b..38bfb4514 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -182,6 +182,11 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD } break; case DIRTY_SCANLINE: + proxyRenderer->backend->disableBG[0] = proxyRenderer->d.disableBG[0]; + proxyRenderer->backend->disableBG[1] = proxyRenderer->d.disableBG[1]; + proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; + proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; + proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; if (item->address < GBA_VIDEO_VERTICAL_PIXELS) { proxyRenderer->backend->drawScanline(proxyRenderer->backend, item->address); } From 3e0675f539218973801f40d1abcacc2ffbf89e6c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 14:56:27 -0700 Subject: [PATCH 193/429] GBA Video: Add GL mode 2 --- include/mgba/internal/gba/renderers/gl.h | 2 + src/gba/renderers/gl.c | 161 ++++++++++++++++++----- 2 files changed, 131 insertions(+), 32 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 254ba743d..402b81afe 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -93,6 +93,8 @@ struct GBAVideoGLRenderer { uint16_t bldy; GBAMosaicControl mosaic; + + int scale; }; void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 73e7bb78a..36e2602f8 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -54,8 +54,8 @@ static const char* const _vertexShader = "}"; static const char* const _renderTile16 = - "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord) {\n" - " int address = tileBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" + "vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n" + " int address = charBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" " int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, paletteId), 0);\n" @@ -68,8 +68,8 @@ static const char* const _renderTile16 = "}"; static const char* const _renderTile256 = - "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord) {\n" - " int address = tileBase + tile * 32 + (localCoord.x >> 1) + (localCoord.y << 2);\n" + "vec4 renderTile(int tile, int paletteId, ivec2 localCoord) {\n" + " int address = charBase + tile * 32 + (localCoord.x >> 1) + (localCoord.y << 2);\n" " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" @@ -91,7 +91,7 @@ static const char* const _renderMode0 = "uniform int size;\n" "uniform ivec2 offset;\n" - "vec4 renderTile(int tile, int tileBase, int paletteId, ivec2 localCoord);\n" + "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" "void main() {\n" " ivec2 coord = ivec2(texCoord) + offset;\n" @@ -109,15 +109,70 @@ static const char* const _renderMode0 = " coord.y ^= 7;\n" " }\n" " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (flags & 0x3) * 256;\n" - " gl_FragColor = renderTile(tile, charBase, int(map.r * 15.9), coord & 7);\n" + " gl_FragColor = renderTile(tile, int(map.r * 15.9), coord & 7);\n" + "}"; + +static const char* const _fetchTileOverflow = + "vec4 fetchTile(ivec2 coord) {\n" + " int sizeAdjusted = (0x8000 << size) - 1;\n" + " coord &= sizeAdjusted;\n" + " return renderTile(coord);\n" + "}"; + +static const char* const _fetchTileNoOverflow = + "vec4 fetchTile(ivec2 coord) {\n" + " int sizeAdjusted = (0x8000 << size) - 1;\n" + " ivec2 outerCoord = coord & ~sizeAdjusted;\n" + " if ((outerCoord.x | outerCoord.y) != 0) {\n" + " vec4 color = texelFetch(palette, ivec2(0, 0), 0);\n" + " color.a = 0;\n" + " return color;\n" + " }\n" + " return renderTile(coord);\n" + "}"; + +static const char* const _renderMode2 = + "varying vec2 texCoord;\n" + "uniform sampler2D vram;\n" + "uniform sampler2D palette;\n" + "uniform int screenBase;\n" + "uniform int charBase;\n" + "uniform int size;\n" + "uniform ivec2 offset;\n" + "uniform mat2x2 transform;\n" + + "vec4 fetchTile(ivec2 coord);\n" + + "vec4 renderTile(ivec2 coord) {\n" + " int map = (coord.x >> 11) + (((coord.y >> 7) & 0x7F0) << size);\n" + " int mapAddress = screenBase + (map >> 1);\n" + " vec4 twomaps = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" + " int tile = int(twomaps[3 - 2 * (map & 1)] * 15.9) + int(twomaps[2 - 2 * (map & 1)] * 15.9) * 16;\n" + " int address = charBase + tile * 32 + ((coord.x >> 9) & 3) + ((coord.y >> 6) & 0x1C);\n" + " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" + " int entry = int(halfrow[3 - ((coord.x >> 7) & 2)] * 15.9);\n" + " int pal2 = int(halfrow[2 - ((coord.x >> 7) & 2)] * 15.9);\n" + " vec4 color = texelFetch(palette, ivec2(entry, pal2), 0);\n" + " if (pal2 > 0 || entry > 0) {\n" + " color.a = 1.;\n" + " } else {\n" + " color.a = 0.;\n" + " }\n" + " return color;\n" + "}" + + "void main() {\n" + " ivec2 coord = ivec2(transform[0] * texCoord.x) + ivec2(transform[1] * fract(texCoord.y)) + offset;\n" + " gl_FragColor = fetchTile(coord);\n" "}"; static const char* const _composite = "varying vec2 texCoord;\n" "uniform sampler2D layer;\n" + "uniform int scale;\n" "void main() {\n" - " vec4 color = texelFetch(layer, ivec2(texCoord), 0);\n" + " vec4 color = texelFetch(layer, ivec2(texCoord * scale), 0);\n" " if (color.a == 0) {\n" " discard;\n" " }\n" @@ -149,6 +204,8 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->d.disableBG[2] = false; renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + + renderer->scale = 1; } void _compileBackground(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { @@ -196,7 +253,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[2], 0); glBindTexture(GL_TEXTURE_2D, glRenderer->layers[3]); @@ -204,7 +261,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[3], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -220,7 +277,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->bg[i].tex, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -255,6 +312,14 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _renderTile256; _compileBackground(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); + shaderBuffer[1] = _renderMode2; + + shaderBuffer[2] = _fetchTileOverflow; + _compileBackground(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); + + shaderBuffer[2] = _fetchTileNoOverflow; + _compileBackground(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); + shaderBuffer[1] = _composite; _compileBackground(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); @@ -530,7 +595,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glEnable(GL_SCISSOR_TEST); - glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glScissor(0, y * glRenderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, glRenderer->scale); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); if (y == 0) { @@ -554,7 +619,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { break; case 1: case 2: - //GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); + GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); break; case 3: //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); @@ -573,7 +638,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[3], y); break; case 2: - //GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[3], y); + GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[3], y); break; } } @@ -591,7 +656,7 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { glFinish(); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); - glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); + glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -676,6 +741,27 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + if ((y & 0x1F) != 0x1F) { + return; + } + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glScissor(0, (y * renderer->scale) % (0x20 * renderer->scale), GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); + glDepthFunc(GL_LESS); + glEnable(GL_DEPTH_TEST); + glUseProgram(renderer->compositeProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, background->tex); + glUniform3i(0, 0x20, y & ~0x1F, (background->priority << 3) + (background->index << 1) + 1); + glUniform1i(1, 0); + glUniform1i(2, renderer->scale); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisable(GL_DEPTH_TEST); +} + void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { int inY = y + background->y; int yBase = inY & 0xFF; @@ -685,8 +771,8 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, yBase += (inY & 0x100) << 1; } glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, y, GBA_VIDEO_HORIZONTAL_PIXELS, 1); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); glUseProgram(renderer->bgProgram[background->multipalette ? 1 : 0]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); @@ -703,22 +789,33 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - if ((y & 0x1F) == 0x1F) { - glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, y & ~0x1F, GBA_VIDEO_HORIZONTAL_PIXELS, 0x20); - glDepthFunc(GL_LESS); - glEnable(GL_DEPTH_TEST); - glUseProgram(renderer->compositeProgram); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, background->tex); - glUniform3i(0, 0x20, y & ~0x1F, (background->priority << 3) + (background->index << 1) + 1); - glUniform1i(1, 0); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisable(GL_DEPTH_TEST); - } + _compositeLayer(renderer, background, y); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); + glUseProgram(renderer->bgProgram[background->overflow ? 2 : 3]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->vramTex); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); + glUniform3i(0, 1, y, 0); + glUniform1i(1, 0); + glUniform1i(2, 1); + glUniform1i(3, background->screenBase); + glUniform1i(4, background->charBase); + glUniform1i(5, background->size); + glUniform2i(6, background->sx, background->sy); + glUniformMatrix2fv(7, 1, GL_FALSE, (GLfloat[]) { background->dx, background->dy, background->dmx, background->dmy }); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + _compositeLayer(renderer, background, y); glBindFramebuffer(GL_FRAMEBUFFER, 0); } \ No newline at end of file From 36477ca40d66b72a401ae7d7a6fdcf4dc056d840 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 15:04:14 -0700 Subject: [PATCH 194/429] Core: Begin on video scale hack --- src/gba/core.c | 14 +++++++++++--- src/platform/qt/CoreController.cpp | 2 +- src/platform/qt/DisplayGL.cpp | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 0edd73b85..3feb64176 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -255,12 +255,19 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con mCoreConfigCopyValue(&core->config, config, "threadedVideo"); #endif mCoreConfigCopyValue(&core->config, config, "hwaccelVideo"); + mCoreConfigCopyValue(&core->config, config, "videoScale"); } static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { - UNUSED(core); - *width = GBA_VIDEO_HORIZONTAL_PIXELS; - *height = GBA_VIDEO_VERTICAL_PIXELS; + struct GBACore* gbacore = (struct GBACore*) core; + int fakeBool; + int scale = 1; + if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { + scale = gbacore->glRenderer.scale; + } + + *width = GBA_VIDEO_HORIZONTAL_PIXELS * scale; + *height = GBA_VIDEO_VERTICAL_PIXELS * scale; } static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { @@ -406,6 +413,7 @@ static void _GBACoreReset(struct mCore* core) { #endif if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { renderer = &gbacore->glRenderer.d; + mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); } if (core->videoLogger) { gbacore->proxyRenderer.logger = core->videoLogger; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 5f6f8ba04..37ea45cac 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -40,7 +40,7 @@ CoreController::CoreController(mCore* core, QObject* parent) m_threadContext.core = core; m_threadContext.userData = this; - QSize size(256, 512); + QSize size(1024, 2048); m_buffers[0].resize(size.width() * size.height() * sizeof(color_t)); m_buffers[1].resize(size.width() * size.height() * sizeof(color_t)); m_buffers[0].fill(0xFF); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 722359255..8ff657016 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -251,7 +251,7 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) m_backend->lockAspectRatio = false; for (int i = 0; i < 2; ++i) { - m_free.append(new uint32_t[256 * 256]); + m_free.append(new uint32_t[1024 * 2048]); } } From fab3091ed1eb9c74c51add1a35b4129e3d6587b4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 15:33:54 -0700 Subject: [PATCH 195/429] Core: Some texid plumbing --- include/mgba/core/core.h | 1 + include/mgba/internal/gba/renderers/gl.h | 5 ++--- src/gb/core.c | 6 ++++++ src/gba/core.c | 27 ++++++++++++++++-------- src/gba/renderers/gl.c | 20 +++++++----------- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index fe08ae0cd..124b02411 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -70,6 +70,7 @@ struct mCore { void (*desiredVideoDimensions)(struct mCore*, unsigned* width, unsigned* height); void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride); + void (*setVideoGLTex)(struct mCore*, unsigned texid); void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); void (*putPixels)(struct mCore*, const void* buffer, size_t stride); diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 402b81afe..4467bee9c 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -62,10 +62,9 @@ struct GBAVideoGLRenderer { struct GBAVideoGLBackground bg[4]; GLuint fbo[2]; - GLuint layers[4]; + GLuint layers[3]; - color_t* outputBuffer; - int outputBufferStride; + GLuint outputTex; GLuint paletteTex; bool paletteDirty; diff --git a/src/gb/core.c b/src/gb/core.c index 99f11029d..20e383393 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -233,6 +233,11 @@ static void _GBCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t st gbcore->renderer.outputBufferStride = stride; } +static void _GBCoreSetVideoGLTex(struct mCore* core, unsigned texid) { + UNUSED(core); + UNUSED(texid); +} + static void _GBCoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->renderer.d.getPixels(&gbcore->renderer.d, stride, buffer); @@ -887,6 +892,7 @@ struct mCore* GBCoreCreate(void) { core->loadConfig = _GBCoreLoadConfig; core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions; core->setVideoBuffer = _GBCoreSetVideoBuffer; + core->setVideoGLTex = _GBCoreSetVideoGLTex; core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; core->getAudioChannel = _GBCoreGetAudioChannel; diff --git a/src/gba/core.c b/src/gba/core.c index 3feb64176..2c6207d8b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -168,9 +168,11 @@ static bool _GBACoreInit(struct mCore* core) { gba->rtcSource = &core->rtc.d; GBAVideoSoftwareRendererCreate(&gbacore->renderer); - GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->renderer.outputBuffer = NULL; + GBAVideoGLRendererCreate(&gbacore->glRenderer); + gbacore->glRenderer.outputTex = -1; + #ifndef DISABLE_THREADING mVideoThreadProxyCreate(&gbacore->threadProxy); #endif @@ -274,11 +276,14 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.outputBuffer = buffer; gbacore->renderer.outputBufferStride = stride; - gbacore->glRenderer.outputBuffer = buffer; - gbacore->glRenderer.outputBufferStride = stride; memset(gbacore->renderer.scanlineDirty, 0xFFFFFFFF, sizeof(gbacore->renderer.scanlineDirty)); } +static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { + struct GBACore* gbacore = (struct GBACore*) core; + gbacore->glRenderer.outputTex = texid; +} + static void _GBACoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) { struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.d.getPixels(&gbacore->renderer.d, stride, buffer); @@ -401,9 +406,16 @@ static void _GBACoreChecksum(const struct mCore* core, void* data, enum mCoreChe static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; - if (gbacore->renderer.outputBuffer) { - struct GBAVideoRenderer* renderer = &gbacore->renderer.d; + if (gbacore->renderer.outputBuffer || gbacore->glRenderer.outputTex != (unsigned) -1) { + struct GBAVideoRenderer* renderer; + if (gbacore->renderer.outputBuffer) { + renderer = &gbacore->renderer.d; + } int fakeBool; + if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { + renderer = &gbacore->glRenderer.d; + mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); + } #ifndef DISABLE_THREADING if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { if (!core->videoLogger) { @@ -411,10 +423,6 @@ static void _GBACoreReset(struct mCore* core) { } } #endif - if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { - renderer = &gbacore->glRenderer.d; - mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); - } if (core->videoLogger) { gbacore->proxyRenderer.logger = core->videoLogger; GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); @@ -951,6 +959,7 @@ struct mCore* GBACoreCreate(void) { core->loadConfig = _GBACoreLoadConfig; core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions; core->setVideoBuffer = _GBACoreSetVideoBuffer; + core->setVideoGLTex = _GBACoreSetVideoGLTex; core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; core->getAudioChannel = _GBACoreGetAudioChannel; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 36e2602f8..e662a2779 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -229,7 +229,7 @@ void _compileBackground(struct GBAVideoGLRenderer* glRenderer, GLuint program, c void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(2, glRenderer->fbo); - glGenTextures(4, glRenderer->layers); + glGenTextures(3, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); @@ -248,21 +248,21 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); + glBindTexture(GL_TEXTURE_2D, glRenderer->outputTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[2], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->outputTex, 0); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[3]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[3], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -331,7 +331,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glDeleteFramebuffers(2, glRenderer->fbo); - glDeleteTextures(4, glRenderer->layers); + glDeleteTextures(3, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); glDeleteTextures(1, &glRenderer->oamTex); @@ -652,12 +652,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { - struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glFinish(); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); - glPixelStorei(GL_PACK_ROW_LENGTH, glRenderer->outputBufferStride); - glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, GL_RGBA, GL_UNSIGNED_BYTE, glRenderer->outputBuffer); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + UNUSED(renderer); + glFlush(); } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { From 18e6acaf727d5fd69d2c8866c897121c020c8ccf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 16:16:29 -0700 Subject: [PATCH 196/429] GBA Video: Basic interpolation for GL renderer --- include/mgba/internal/gba/renderers/gl.h | 7 +++++++ src/gba/renderers/gl.c | 25 +++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 4467bee9c..a305bf9c6 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -54,6 +54,13 @@ struct GBAVideoGLBackground { int16_t dmy; int32_t sx; int32_t sy; + + int16_t lastDx; + int16_t lastDmx; + int16_t lastDy; + int16_t lastDmy; + int32_t lastSx; + int32_t lastSy; }; struct GBAVideoGLRenderer { diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index e662a2779..9f7c786f1 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -139,7 +139,9 @@ static const char* const _renderMode2 = "uniform int charBase;\n" "uniform int size;\n" "uniform ivec2 offset;\n" + "uniform ivec2 oldOffset;\n" "uniform mat2x2 transform;\n" + "uniform mat2x2 oldTransform;\n" "vec4 fetchTile(ivec2 coord);\n" @@ -162,8 +164,9 @@ static const char* const _renderMode2 = "}" "void main() {\n" - " ivec2 coord = ivec2(transform[0] * texCoord.x) + ivec2(transform[1] * fract(texCoord.y)) + offset;\n" - " gl_FragColor = fetchTile(coord);\n" + " vec2 newCoord = transform[0] * texCoord.x + offset;\n" + " vec2 oldCoord = oldTransform[0] * texCoord.x + oldOffset;\n" + " gl_FragColor = fetchTile(ivec2(newCoord * fract(texCoord.y) + oldCoord * (1. - fract(texCoord.y))));\n" "}"; static const char* const _composite = @@ -644,8 +647,22 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + glRenderer->bg[2].lastDx = glRenderer->bg[2].dx; + glRenderer->bg[2].lastDy = glRenderer->bg[2].dy; + glRenderer->bg[2].lastDmx = glRenderer->bg[2].dmx; + glRenderer->bg[2].lastDmy = glRenderer->bg[2].dmy; + glRenderer->bg[2].lastSx = glRenderer->bg[2].sx; + glRenderer->bg[2].lastSy = glRenderer->bg[2].sy; + glRenderer->bg[2].lastSx = glRenderer->bg[2].sx; + glRenderer->bg[2].lastSy = glRenderer->bg[2].sy; glRenderer->bg[2].sx += glRenderer->bg[2].dmx; glRenderer->bg[2].sy += glRenderer->bg[2].dmy; + glRenderer->bg[3].lastDx = glRenderer->bg[3].dx; + glRenderer->bg[3].lastDy = glRenderer->bg[3].dy; + glRenderer->bg[3].lastDmx = glRenderer->bg[3].dmx; + glRenderer->bg[3].lastDmy = glRenderer->bg[3].dmy; + glRenderer->bg[3].lastSx = glRenderer->bg[3].sx; + glRenderer->bg[3].lastSy = glRenderer->bg[3].sy; glRenderer->bg[3].sx += glRenderer->bg[3].dmx; glRenderer->bg[3].sy += glRenderer->bg[3].dmy; } @@ -806,7 +823,9 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(4, background->charBase); glUniform1i(5, background->size); glUniform2i(6, background->sx, background->sy); - glUniformMatrix2fv(7, 1, GL_FALSE, (GLfloat[]) { background->dx, background->dy, background->dmx, background->dmy }); + glUniform2i(7, background->lastSx, background->lastSy); + glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { background->dx, background->dy, background->dmx, background->dmy }); + glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->lastDx, background->lastDy, background->lastDmx, background->lastDmy }); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); From 8a6ea929d2b905e51aa21ccf460e9fb2696da0ea Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 10 May 2019 23:44:04 -0700 Subject: [PATCH 197/429] GBA Video: GL cleanup, initial work on blending --- include/mgba/internal/gba/renderers/gl.h | 22 ++-- src/gba/renderers/gl.c | 146 ++++++++++++++--------- 2 files changed, 97 insertions(+), 71 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index a305bf9c6..f6b253891 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -29,6 +29,15 @@ CXX_GUARD_START #include #endif +struct GBAVideoGLAffine { + int16_t dx; + int16_t dmx; + int16_t dy; + int16_t dmy; + int32_t sx; + int32_t sy; +}; + struct GBAVideoGLBackground { GLuint fbo; GLuint tex; @@ -48,19 +57,8 @@ struct GBAVideoGLBackground { uint16_t y; int32_t refx; int32_t refy; - int16_t dx; - int16_t dmx; - int16_t dy; - int16_t dmy; - int32_t sx; - int32_t sy; - int16_t lastDx; - int16_t lastDmx; - int16_t lastDy; - int16_t lastDmy; - int32_t lastSx; - int32_t lastSy; + struct GBAVideoGLAffine affine[2]; }; struct GBAVideoGLRenderer { diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 9f7c786f1..3aec279bc 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -43,13 +43,13 @@ static const GLchar* const _gl3Header = static const char* const _vertexShader = "attribute vec2 position;\n" - "uniform ivec3 loc;\n" - "const ivec3 maxPos = ivec3(240, 160, 32);\n" + "uniform ivec2 loc;\n" + "const ivec2 maxPos = ivec2(240, 160);\n" "varying vec2 texCoord;\n" "void main() {\n" " vec2 local = (position * loc.x + vec2(0, loc.y)) / vec2(1., maxPos.y);\n" - " gl_Position = vec4(local * 2. - 1., loc.z / float(maxPos.z), 1.);\n" + " gl_Position = vec4(local * 2. - 1., 0., 1.);\n" " texCoord = local * maxPos.xy;\n" "}"; @@ -142,6 +142,7 @@ static const char* const _renderMode2 = "uniform ivec2 oldOffset;\n" "uniform mat2x2 transform;\n" "uniform mat2x2 oldTransform;\n" + "uniform int firstD;\n" "vec4 fetchTile(ivec2 coord);\n" @@ -164,22 +165,43 @@ static const char* const _renderMode2 = "}" "void main() {\n" - " vec2 newCoord = transform[0] * texCoord.x + offset;\n" - " vec2 oldCoord = oldTransform[0] * texCoord.x + oldOffset;\n" - " gl_FragColor = fetchTile(ivec2(newCoord * fract(texCoord.y) + oldCoord * (1. - fract(texCoord.y))));\n" + " float y = fract(texCoord.y);\n" + " float lin = y / ceil(y);\n" + " vec2 mixedTransform = mix(oldTransform[0], transform[0], lin);\n" + " vec2 mixedOffset = mix(oldOffset, offset, lin);\n" + " gl_FragColor = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" "}"; static const char* const _composite = "varying vec2 texCoord;\n" - "uniform sampler2D layer;\n" + "uniform ivec3 inflags;\n" "uniform int scale;\n" + "uniform vec3 blend;\n" + "uniform sampler2D layer;\n" + "uniform sampler2D oldLayer;\n" + "uniform sampler2D buffer;\n" + "out vec4 color;\n" + "out vec3 flags;\n" "void main() {\n" - " vec4 color = texelFetch(layer, ivec2(texCoord * scale), 0);\n" - " if (color.a == 0) {\n" + " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" + " if (pix.a == 0) {\n" " discard;\n" " }\n" - " gl_FragColor = color;\n" + " ivec3 oldFlags = ivec3(texelFetch(buffer, ivec2(texCoord * scale), 0).xyz * vec3(32., 4., 1.));\n" + " ivec3 outflags = ivec3(0, 0, 0);\n" + " if (inflags.x < oldFlags.x) {\n" + " outflags = inflags;\n" + " if ((inflags.y & 1) == 1 && (oldFlags.y & 2) == 2) {\n" + " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " pix *= blend.x;\n" + " pix += oldpix * blend.y;\n" + " }\n" + " } else {\n" + " pix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " }\n" + " color = pix;\n" + " flags = outflags / vec3(32., 4., 1.);\n" "}"; static const GLint _vertices[] = { @@ -264,8 +286,8 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, glRenderer->layers[2], 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -325,6 +347,8 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _composite; _compileBackground(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); + glBindFragDataLocation(glRenderer->compositeProgram, 0, "color"); + glBindFragDataLocation(glRenderer->compositeProgram, 1, "flags"); glDeleteShader(vs); @@ -426,16 +450,16 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, glRenderer->bg[3].y = value; break; case REG_BG2PA: - glRenderer->bg[2].dx = value; + glRenderer->bg[2].affine[0].dx = value; break; case REG_BG2PB: - glRenderer->bg[2].dmx = value; + glRenderer->bg[2].affine[0].dmx = value; break; case REG_BG2PC: - glRenderer->bg[2].dy = value; + glRenderer->bg[2].affine[0].dy = value; break; case REG_BG2PD: - glRenderer->bg[2].dmy = value; + glRenderer->bg[2].affine[0].dmy = value; break; case REG_BG2X_LO: GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value); @@ -450,16 +474,16 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value); break; case REG_BG3PA: - glRenderer->bg[3].dx = value; + glRenderer->bg[3].affine[0].dx = value; break; case REG_BG3PB: - glRenderer->bg[3].dmx = value; + glRenderer->bg[3].affine[0].dmx = value; break; case REG_BG3PC: - glRenderer->bg[3].dy = value; + glRenderer->bg[3].affine[0].dy = value; break; case REG_BG3PD: - glRenderer->bg[3].dmy = value; + glRenderer->bg[3].affine[0].dmy = value; break; case REG_BG3X_LO: GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value); @@ -602,13 +626,15 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); if (y == 0) { - glClearDepthf(1); - glClear(GL_DEPTH_BUFFER_BIT); + glDrawBuffer(GL_COLOR_ATTACHMENT1); + glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2)) / 4.f, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_COLOR_ATTACHMENT0); } glBindFramebuffer(GL_FRAMEBUFFER, 0); unsigned priority; - for (priority = 0; priority < 4; ++priority) { + for (priority = 4; priority--;) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[0], y); } @@ -646,25 +672,15 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } } + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { - glRenderer->bg[2].lastDx = glRenderer->bg[2].dx; - glRenderer->bg[2].lastDy = glRenderer->bg[2].dy; - glRenderer->bg[2].lastDmx = glRenderer->bg[2].dmx; - glRenderer->bg[2].lastDmy = glRenderer->bg[2].dmy; - glRenderer->bg[2].lastSx = glRenderer->bg[2].sx; - glRenderer->bg[2].lastSy = glRenderer->bg[2].sy; - glRenderer->bg[2].lastSx = glRenderer->bg[2].sx; - glRenderer->bg[2].lastSy = glRenderer->bg[2].sy; - glRenderer->bg[2].sx += glRenderer->bg[2].dmx; - glRenderer->bg[2].sy += glRenderer->bg[2].dmy; - glRenderer->bg[3].lastDx = glRenderer->bg[3].dx; - glRenderer->bg[3].lastDy = glRenderer->bg[3].dy; - glRenderer->bg[3].lastDmx = glRenderer->bg[3].dmx; - glRenderer->bg[3].lastDmy = glRenderer->bg[3].dmy; - glRenderer->bg[3].lastSx = glRenderer->bg[3].sx; - glRenderer->bg[3].lastSy = glRenderer->bg[3].sy; - glRenderer->bg[3].sx += glRenderer->bg[3].dmx; - glRenderer->bg[3].sy += glRenderer->bg[3].dmy; + memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + + glRenderer->bg[2].affine[0].sx += glRenderer->bg[2].affine[0].dmx; + glRenderer->bg[2].affine[0].sy += glRenderer->bg[2].affine[0].dmy; + glRenderer->bg[3].affine[0].sx += glRenderer->bg[3].affine[0].dmx; + glRenderer->bg[3].affine[0].sy += glRenderer->bg[3].affine[0].dmy; } } @@ -715,26 +731,26 @@ static void GBAVideoGLRendererWriteBGCNT(struct GBAVideoGLBackground* bg, uint16 static void GBAVideoGLRendererWriteBGX_LO(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refx = (bg->refx & 0xFFFF0000) | value; - bg->sx = bg->refx; + bg->affine[0].sx = bg->refx; } static void GBAVideoGLRendererWriteBGX_HI(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refx = (bg->refx & 0x0000FFFF) | (value << 16); bg->refx <<= 4; bg->refx >>= 4; - bg->sx = bg->refx; + bg->affine[0].sx = bg->refx; } static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refy = (bg->refy & 0xFFFF0000) | value; - bg->sy = bg->refy; + bg->affine[0].sy = bg->refy; } static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refy = (bg->refy & 0x0000FFFF) | (value << 16); bg->refy <<= 4; bg->refy >>= 4; - bg->sy = bg->refy; + bg->affine[0].sy = bg->refy; } static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value) { @@ -754,25 +770,32 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y, int flags) { if ((y & 0x1F) != 0x1F) { return; } glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y * renderer->scale) % (0x20 * renderer->scale), GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glDepthFunc(GL_LESS); - glEnable(GL_DEPTH_TEST); glUseProgram(renderer->compositeProgram); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, background->tex); - glUniform3i(0, 0x20, y & ~0x1F, (background->priority << 3) + (background->index << 1) + 1); - glUniform1i(1, 0); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->outputTex); + glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, renderer->layers[2]); + glUniform2i(0, 0x20, y & ~0x1F); + glUniform3i(1, (background->priority << 3) + (background->index << 1) + 1, flags, renderer->blendEffect); glUniform1i(2, renderer->scale); + glUniform3f(3, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); + glUniform1i(4, 0); + glUniform1i(5, 1); + glUniform1i(6, 2); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisable(GL_DEPTH_TEST); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -791,7 +814,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform3i(0, 1, y, 0); + glUniform2i(0, 1, y); glUniform1i(1, 0); glUniform1i(2, 1); glUniform1i(3, background->screenBase); @@ -802,7 +825,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - _compositeLayer(renderer, background, y); + _compositeLayer(renderer, background, y, background->target1 | (background->target2 * 2)); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -816,21 +839,26 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform3i(0, 1, y, 0); + glUniform2i(0, 1, y); glUniform1i(1, 0); glUniform1i(2, 1); glUniform1i(3, background->screenBase); glUniform1i(4, background->charBase); glUniform1i(5, background->size); - glUniform2i(6, background->sx, background->sy); - glUniform2i(7, background->lastSx, background->lastSy); - glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { background->dx, background->dy, background->dmx, background->dmy }); - glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->lastDx, background->lastDy, background->lastDmx, background->lastDmy }); + glUniform2i(6, background->affine[0].sx, background->affine[0].sy); + glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dmx, background->affine[0].dmy }); + if (renderer->scale > 1) { + glUniform2i(7, background->affine[1].sx, background->affine[1].sy); + glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->affine[1].dx, background->affine[1].dy, background->affine[1].dmx, background->affine[1].dmy }); + } else { + glUniform2i(7, background->affine[0].sx, background->affine[0].sy); + glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dmx, background->affine[0].dmy }); + } glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - _compositeLayer(renderer, background, y); + _compositeLayer(renderer, background, y, background->target1 | (background->target2 * 2)); glBindFramebuffer(GL_FRAMEBUFFER, 0); } \ No newline at end of file From 68f0176ee4fccfc8bb5bf0678b4c7122f1eff0f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 11 May 2019 15:50:50 -0700 Subject: [PATCH 198/429] GBA Video: Mode 2 cubic interpolation --- include/mgba/internal/gba/renderers/gl.h | 4 +- src/gba/renderers/gl.c | 86 +++++++++++++++++++----- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index f6b253891..8da5583e1 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -58,7 +58,7 @@ struct GBAVideoGLBackground { int32_t refx; int32_t refy; - struct GBAVideoGLAffine affine[2]; + struct GBAVideoGLAffine affine[4]; }; struct GBAVideoGLRenderer { @@ -98,6 +98,8 @@ struct GBAVideoGLRenderer { GBAMosaicControl mosaic; + int firstAffine; + int scale; }; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 3aec279bc..7e10e9ab6 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -138,11 +138,10 @@ static const char* const _renderMode2 = "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" - "uniform ivec2 offset;\n" - "uniform ivec2 oldOffset;\n" - "uniform mat2x2 transform;\n" - "uniform mat2x2 oldTransform;\n" - "uniform int firstD;\n" + "uniform ivec2[4] offset;\n" + "uniform ivec2[4] transform;\n" + "precision highp float;\n" + "precision highp int;\n" "vec4 fetchTile(ivec2 coord);\n" @@ -162,13 +161,21 @@ static const char* const _renderMode2 = " color.a = 0.;\n" " }\n" " return color;\n" - "}" + "}\n" + + "vec2 interpolate(ivec2 arr[4], float x) {\n" + " float x1m = 1. - x;\n" + " return x1m * x1m * x1m * arr[0] +" + " 3 * x1m * x1m * x * arr[1] +" + " 3 * x1m * x * x * arr[2] +" + " x * x * x * arr[3];\n" + "}\n" "void main() {\n" " float y = fract(texCoord.y);\n" - " float lin = y / ceil(y);\n" - " vec2 mixedTransform = mix(oldTransform[0], transform[0], lin);\n" - " vec2 mixedOffset = mix(oldOffset, offset, lin);\n" + " float lin = 0.5 - y / ceil(y) * 0.25;\n" + " vec2 mixedTransform = interpolate(transform, lin);\n" + " vec2 mixedOffset = interpolate(offset, lin);\n" " gl_FragColor = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" "}"; @@ -192,7 +199,7 @@ static const char* const _composite = " ivec3 outflags = ivec3(0, 0, 0);\n" " if (inflags.x < oldFlags.x) {\n" " outflags = inflags;\n" - " if ((inflags.y & 1) == 1 && (oldFlags.y & 2) == 2) {\n" + " if (inflags.z == 1 && (inflags.y & 1) == 1 && (oldFlags.y & 2) == 2) {\n" " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" " pix *= blend.x;\n" " pix += oldpix * blend.y;\n" @@ -369,6 +376,7 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { glRenderer->paletteDirty = true; glRenderer->vramDirty = 0xFFFFFF; + glRenderer->firstAffine = -1; } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { @@ -633,6 +641,23 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glBindFramebuffer(GL_FRAMEBUFFER, 0); + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + if (glRenderer->firstAffine < 0) { + memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + glRenderer->firstAffine = y; + } else if (y - glRenderer->firstAffine == 1) { + memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + } + } else { + glRenderer->firstAffine = -1; + } + unsigned priority; for (priority = 4; priority--;) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -674,6 +699,10 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[2], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[1], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[1], sizeof(struct GBAVideoGLAffine)); memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); @@ -685,7 +714,12 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { - UNUSED(renderer); + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->firstAffine = -1; + glRenderer->bg[2].affine[0].sx = glRenderer->bg[2].refx; + glRenderer->bg[2].affine[0].sy = glRenderer->bg[2].refy; + glRenderer->bg[3].affine[0].sx = glRenderer->bg[3].refx; + glRenderer->bg[3].affine[0].sy = glRenderer->bg[3].refy; glFlush(); } @@ -845,14 +879,32 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(3, background->screenBase); glUniform1i(4, background->charBase); glUniform1i(5, background->size); - glUniform2i(6, background->affine[0].sx, background->affine[0].sy); - glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dmx, background->affine[0].dmy }); if (renderer->scale > 1) { - glUniform2i(7, background->affine[1].sx, background->affine[1].sy); - glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->affine[1].dx, background->affine[1].dy, background->affine[1].dmx, background->affine[1].dmy }); + glUniform2iv(6, 4, (GLint[]) { + background->affine[0].sx, background->affine[0].sy, + background->affine[1].sx, background->affine[1].sy, + background->affine[2].sx, background->affine[2].sy, + background->affine[3].sx, background->affine[3].sy, + }); + glUniform2iv(10, 4, (GLint[]) { + background->affine[0].dx, background->affine[0].dy, + background->affine[1].dx, background->affine[1].dy, + background->affine[2].dx, background->affine[2].dy, + background->affine[3].dx, background->affine[3].dy, + }); } else { - glUniform2i(7, background->affine[0].sx, background->affine[0].sy); - glUniformMatrix2fv(9, 1, GL_FALSE, (GLfloat[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dmx, background->affine[0].dmy }); + glUniform2iv(6, 4, (GLint[]) { + background->affine[0].sx, background->affine[0].sy, + background->affine[0].sx, background->affine[0].sy, + background->affine[0].sx, background->affine[0].sy, + background->affine[0].sx, background->affine[0].sy, + }); + glUniform2iv(10, 4, (GLint[]) { + background->affine[0].dx, background->affine[0].dy, + background->affine[0].dx, background->affine[0].dy, + background->affine[0].dx, background->affine[0].dy, + background->affine[0].dx, background->affine[0].dy, + }); } glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); From 62f70379f6817cc3c0ae06d49bf2937ddd4a4bd6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2019 20:21:02 -0700 Subject: [PATCH 199/429] GBA Video: GL sprite initial work --- include/mgba/internal/gba/renderers/common.h | 25 ++ include/mgba/internal/gba/renderers/gl.h | 15 +- .../internal/gba/renderers/video-software.h | 9 +- src/gba/core.c | 5 +- src/gba/renderers/common.c | 33 +++ src/gba/renderers/gl.c | 252 +++++++++++++----- src/gba/renderers/video-software.c | 32 +-- 7 files changed, 265 insertions(+), 106 deletions(-) create mode 100644 include/mgba/internal/gba/renderers/common.h create mode 100644 src/gba/renderers/common.c diff --git a/include/mgba/internal/gba/renderers/common.h b/include/mgba/internal/gba/renderers/common.h new file mode 100644 index 000000000..e90b1f350 --- /dev/null +++ b/include/mgba/internal/gba/renderers/common.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2013-2019 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/. */ +#ifndef GBA_RENDERER_COMMON_H +#define GBA_RENDERER_COMMON_H + +#include + +CXX_GUARD_START + +#include + +struct GBAVideoRendererSprite { + struct GBAObj obj; + int16_t y; + int16_t endY; +}; + +int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite* sprites, int offsetY); + +CXX_GUARD_END + +#endif \ No newline at end of file diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 8da5583e1..636f3bf05 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -13,6 +13,7 @@ CXX_GUARD_START #include #include #include +#include #include #ifdef USE_EPOXY @@ -61,11 +62,23 @@ struct GBAVideoGLBackground { struct GBAVideoGLAffine affine[4]; }; +enum { + GBA_GL_FBO_OBJ = 0, + GBA_GL_FBO_COMPOSITE = 1, + + GBA_GL_TEX_OBJ_COLOR = 0, + GBA_GL_TEX_OBJ_FLAGS = 1, + GBA_GL_TEX_COMPOSITE_FLAGS = 2, +}; + struct GBAVideoGLRenderer { struct GBAVideoRenderer d; struct GBAVideoGLBackground bg[4]; + int oamMax; + struct GBAVideoRendererSprite sprites[128]; + GLuint fbo[2]; GLuint layers[3]; @@ -81,7 +94,7 @@ struct GBAVideoGLRenderer { unsigned vramDirty; GLuint bgProgram[6]; - GLuint objProgram; + GLuint objProgram[4]; GLuint compositeProgram; diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 3012cc10f..87e0addba 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -13,14 +13,9 @@ CXX_GUARD_START #include #include #include +#include #include -struct GBAVideoSoftwareSprite { - struct GBAObj obj; - int y; - int endY; -}; - struct GBAVideoSoftwareBackground { unsigned index; int enabled; @@ -140,7 +135,7 @@ struct GBAVideoSoftwareRenderer { int oamDirty; int oamMax; - struct GBAVideoSoftwareSprite sprites[128]; + struct GBAVideoRendererSprite sprites[128]; int16_t objOffsetX; int16_t objOffsetY; diff --git a/src/gba/core.c b/src/gba/core.c index 2c6207d8b..5284a04b9 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -263,10 +263,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { struct GBACore* gbacore = (struct GBACore*) core; int fakeBool; - int scale = 1; - if (mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { - scale = gbacore->glRenderer.scale; - } + int scale = gbacore->glRenderer.scale; *width = GBA_VIDEO_HORIZONTAL_PIXELS * scale; *height = GBA_VIDEO_VERTICAL_PIXELS * scale; diff --git a/src/gba/renderers/common.c b/src/gba/renderers/common.c new file mode 100644 index 000000000..9065a6267 --- /dev/null +++ b/src/gba/renderers/common.c @@ -0,0 +1,33 @@ +/* Copyright (c) 2013-2019 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 + +#include + +int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite* sprites, int offsetY) { + int i; + int oamMax = 0; + for (i = 0; i < 128; ++i) { + struct GBAObj obj; + LOAD_16LE(obj.a, 0, &oam[i].a); + LOAD_16LE(obj.b, 0, &oam[i].b); + LOAD_16LE(obj.c, 0, &oam[i].c); + if (GBAObjAttributesAIsTransformed(obj.a) || !GBAObjAttributesAIsDisable(obj.a)) { + int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][1]; + if (GBAObjAttributesAIsTransformed(obj.a)) { + height <<= GBAObjAttributesAGetDoubleSize(obj.a); + } + if (GBAObjAttributesAGetY(obj.a) < GBA_VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) { + int y = GBAObjAttributesAGetY(obj.a) + offsetY; + sprites[oamMax].y = y; + sprites[oamMax].endY = y + height; + sprites[oamMax].obj = obj; + ++oamMax; + } + } + } + return oamMax; +} \ No newline at end of file diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 7e10e9ab6..597248310 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -30,12 +30,15 @@ static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint1 static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value); static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value); +static void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GBAObj* sprite, int y, int spriteY); static void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, int y, int priority, int flags); + #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority static const GLchar* const _gl3Header = @@ -44,13 +47,13 @@ static const GLchar* const _gl3Header = static const char* const _vertexShader = "attribute vec2 position;\n" "uniform ivec2 loc;\n" - "const ivec2 maxPos = ivec2(240, 160);\n" + "uniform ivec2 maxPos;\n" "varying vec2 texCoord;\n" "void main() {\n" - " vec2 local = (position * loc.x + vec2(0, loc.y)) / vec2(1., maxPos.y);\n" - " gl_Position = vec4(local * 2. - 1., 0., 1.);\n" - " texCoord = local * maxPos.xy;\n" + " vec2 local = vec2(position.x, float(position.y * loc.x + loc.y) / abs(maxPos.y));\n" + " gl_Position = vec4((local * 2. - 1.) * sign(maxPos), 0., 1.);\n" + " texCoord = local * abs(maxPos);\n" "}"; static const char* const _renderTile16 = @@ -60,10 +63,9 @@ static const char* const _renderTile16 = " int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, paletteId), 0);\n" " if (entry == 0) {\n" - " color.a = 0;\n" - " } else {\n" - " color.a = 1;\n" + " discard;\n" " }\n" + " color.a = 1;\n" " return color;\n" "}"; @@ -74,11 +76,10 @@ static const char* const _renderTile256 = " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, pal2 + (paletteId & 16)), 0);\n" - " if (pal2 > 0 || entry > 0) {\n" - " color.a = 1.;\n" - " } else {\n" - " color.a = 0.;\n" + " if (pal2 + entry == 0) {\n" + " discard;\n" " }\n" + " color.a = 1.;\n" " return color;\n" "}"; @@ -179,6 +180,26 @@ static const char* const _renderMode2 = " gl_FragColor = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" "}"; +static const char* const _renderObjNoTransform = + "varying vec2 texCoord;\n" + "uniform sampler2D vram;\n" + "uniform sampler2D palette;\n" + "uniform int charBase;\n" + "uniform int stride;\n" + "uniform int localPalette;\n" + "uniform ivec3 inflags;\n" + "out vec4 color;\n" + "out vec3 flags;\n" + "const vec3 flagCoeff = vec3(32., 8., 4.);\n" + + "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" + + "void main() {\n" + " ivec2 coord = ivec2(texCoord);\n" + " color = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" + " flags = inflags / flagCoeff;\n" + "}"; + static const char* const _composite = "varying vec2 texCoord;\n" "uniform ivec3 inflags;\n" @@ -186,20 +207,21 @@ static const char* const _composite = "uniform vec3 blend;\n" "uniform sampler2D layer;\n" "uniform sampler2D oldLayer;\n" - "uniform sampler2D buffer;\n" + "uniform sampler2D oldFlags;\n" "out vec4 color;\n" "out vec3 flags;\n" + "const vec3 flagCoeff = vec3(32., 8., 4.);\n" "void main() {\n" " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" " if (pix.a == 0) {\n" " discard;\n" " }\n" - " ivec3 oldFlags = ivec3(texelFetch(buffer, ivec2(texCoord * scale), 0).xyz * vec3(32., 4., 1.));\n" + " ivec3 oflags = ivec3(texelFetch(oldFlags, ivec2(texCoord * scale), 0).xyz * flagCoeff);\n" " ivec3 outflags = ivec3(0, 0, 0);\n" - " if (inflags.x < oldFlags.x) {\n" + " if (inflags.x < oflags.x) {\n" " outflags = inflags;\n" - " if (inflags.z == 1 && (inflags.y & 1) == 1 && (oldFlags.y & 2) == 2) {\n" + " if (inflags.z == 1 && (inflags.y & 1) == 1 && (oflags.y & 2) == 2) {\n" " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" " pix *= blend.x;\n" " pix += oldpix * blend.y;\n" @@ -208,7 +230,7 @@ static const char* const _composite = " pix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" " }\n" " color = pix;\n" - " flags = outflags / vec3(32., 4., 1.);\n" + " flags = outflags / flagCoeff;\n" "}"; static const GLint _vertices[] = { @@ -240,7 +262,7 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->scale = 1; } -void _compileBackground(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { +void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(program, vs); glAttachShader(program, fs); @@ -279,7 +301,24 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], 0); + + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); glBindTexture(GL_TEXTURE_2D, glRenderer->outputTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -288,13 +327,13 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->outputTex, 0); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[2]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[2], 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS], 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -315,7 +354,10 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { } glRenderer->compositeProgram = glCreateProgram(); - glRenderer->objProgram = glCreateProgram(); + glRenderer->objProgram[0] = glCreateProgram(); + glRenderer->objProgram[1] = glCreateProgram(); + glRenderer->objProgram[2] = glCreateProgram(); + glRenderer->objProgram[3] = glCreateProgram(); glRenderer->bgProgram[0] = glCreateProgram(); glRenderer->bgProgram[1] = glCreateProgram(); glRenderer->bgProgram[2] = glCreateProgram(); @@ -339,21 +381,26 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _renderMode0; shaderBuffer[2] = _renderTile16; - _compileBackground(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); + _compileShader(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); shaderBuffer[2] = _renderTile256; - _compileBackground(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); + _compileShader(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); shaderBuffer[1] = _renderMode2; shaderBuffer[2] = _fetchTileOverflow; - _compileBackground(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); + _compileShader(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); shaderBuffer[2] = _fetchTileNoOverflow; - _compileBackground(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); + _compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); + + shaderBuffer[1] = _renderObjNoTransform; + + shaderBuffer[2] = _renderTile16; + _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); shaderBuffer[1] = _composite; - _compileBackground(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); + _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); glBindFragDataLocation(glRenderer->compositeProgram, 0, "color"); glBindFragDataLocation(glRenderer->compositeProgram, 1, "flags"); @@ -369,6 +416,19 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); glDeleteTextures(1, &glRenderer->oamTex); + + glDeleteProgram(glRenderer->bgProgram[0]); + glDeleteProgram(glRenderer->bgProgram[1]); + glDeleteProgram(glRenderer->bgProgram[2]); + glDeleteProgram(glRenderer->bgProgram[3]); + glDeleteProgram(glRenderer->bgProgram[4]); + glDeleteProgram(glRenderer->bgProgram[5]); + glDeleteProgram(glRenderer->bgProgram[6]); + glDeleteProgram(glRenderer->objProgram[0]); + glDeleteProgram(glRenderer->objProgram[1]); + glDeleteProgram(glRenderer->objProgram[2]); + glDeleteProgram(glRenderer->objProgram[3]); + glDeleteProgram(glRenderer->compositeProgram); } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { @@ -610,11 +670,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); glRenderer->paletteDirty = false; } - if (glRenderer->oamDirty) { - glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 4, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, glRenderer->d.oam); - glRenderer->oamDirty = false; - } int i; for (i = 0; i < 24; ++i) { if (!(glRenderer->vramDirty & (1 << i))) { @@ -628,16 +683,25 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { uint32_t backdrop = M_RGB5_TO_RGB8(renderer->palette[0]); glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[1]); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); glEnable(GL_SCISSOR_TEST); glScissor(0, y * glRenderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, glRenderer->scale); glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); if (y == 0) { glDrawBuffer(GL_COLOR_ATTACHMENT1); - glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2)) / 4.f, 0, 1); + glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2)) / 8.f, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glDrawBuffer(GL_COLOR_ATTACHMENT0); + + glClearColor(0, 0, 0, 0); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); + glClear(GL_COLOR_BUFFER_BIT); + + for (i = 0; i < 4; ++i) { + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); + glClear(GL_COLOR_BUFFER_BIT); + } } glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -658,6 +722,27 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstAffine = -1; } + glEnable(GL_SCISSOR_TEST); + int spriteLayers = 0; + if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { + if (glRenderer->oamDirty) { + glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 4, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, glRenderer->d.oam); + glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); + glRenderer->oamDirty = false; + } + int i; + for (i = glRenderer->oamMax; i--;) { + struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i]; + if ((y < sprite->y && (sprite->endY - 256 < 0 || y >= sprite->endY - 256)) || y >= sprite->endY) { + continue; + } + + GBAVideoGLRendererDrawSprite(glRenderer, &sprite->obj, y, sprite->y); + spriteLayers |= 1 << GBAObjAttributesCGetPriority(sprite->obj.c); + } + } + unsigned priority; for (priority = 4; priority--;) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -697,6 +782,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } } + _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], y, 0, 0); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); @@ -804,34 +890,72 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y, int flags) { +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, int y, int priority, int flags) { if ((y & 0x1F) != 0x1F) { return; } - glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[1]); + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_COMPOSITE]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glScissor(0, (y * renderer->scale) % (0x20 * renderer->scale), GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); + glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); glUseProgram(renderer->compositeProgram); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, background->tex); + glBindTexture(GL_TEXTURE_2D, tex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->outputTex); glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->layers[2]); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); glUniform2i(0, 0x20, y & ~0x1F); - glUniform3i(1, (background->priority << 3) + (background->index << 1) + 1, flags, renderer->blendEffect); - glUniform1i(2, renderer->scale); - glUniform3f(3, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); - glUniform1i(4, 0); - glUniform1i(5, 1); - glUniform1i(6, 2); + glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform3i(2, priority, flags, renderer->blendEffect); + glUniform1i(3, renderer->scale); + glUniform3f(4, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); + glUniform1i(5, 0); + glUniform1i(6, 1); + glUniform1i(7, 2); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GBAObj* sprite, int y, int spriteY) { + int width = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][0]; + int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1]; + int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23; + x >>= 23; + + int align = GBAObjAttributesAIs256Color(sprite->a) && !GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt); + unsigned charBase = (BASE_TILE >> 1) + (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x10; + int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x10 >> !GBAObjAttributesAIs256Color(sprite->a)); + + if (spriteY + height >= 256) { + spriteY -= 256; + } + + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); + glViewport(x * renderer->scale, spriteY * renderer->scale, width * renderer->scale, height * renderer->scale); + glScissor(x * renderer->scale, y * renderer->scale, width * renderer->scale, renderer->scale); + glUseProgram(renderer->objProgram[0]); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->vramTex); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); + glUniform2i(0, 1, y - spriteY); + glUniform2i(1, GBAObjAttributesBIsHFlip(sprite->b) ? -width : width, height); + glUniform1i(2, 0); + glUniform1i(3, 1); + glUniform1i(4, charBase); + glUniform1i(5, stride); + glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); + glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, 0, 0); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 });} + void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { int inY = y + background->y; int yBase = inY & 0xFF; @@ -849,19 +973,18 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(0, 1, y); - glUniform1i(1, 0); - glUniform1i(2, 1); - glUniform1i(3, background->screenBase); - glUniform1i(4, background->charBase); - glUniform1i(5, background->size); - glUniform2i(6, background->x, yBase - y); + glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(2, 0); + glUniform1i(3, 1); + glUniform1i(4, background->screenBase); + glUniform1i(5, background->charBase); + glUniform1i(6, background->size); + glUniform2i(7, background->x, yBase - y); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - _compositeLayer(renderer, background, y, background->target1 | (background->target2 * 2)); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); + _compositeLayer(renderer, background->tex, y, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2)); } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -874,32 +997,33 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(0, 1, y); - glUniform1i(1, 0); - glUniform1i(2, 1); - glUniform1i(3, background->screenBase); - glUniform1i(4, background->charBase); - glUniform1i(5, background->size); + glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(2, 0); + glUniform1i(3, 1); + glUniform1i(4, background->screenBase); + glUniform1i(5, background->charBase); + glUniform1i(6, background->size); if (renderer->scale > 1) { - glUniform2iv(6, 4, (GLint[]) { + glUniform2iv(7, 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[1].sx, background->affine[1].sy, background->affine[2].sx, background->affine[2].sy, background->affine[3].sx, background->affine[3].sy, }); - glUniform2iv(10, 4, (GLint[]) { + glUniform2iv(11, 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[1].dx, background->affine[1].dy, background->affine[2].dx, background->affine[2].dy, background->affine[3].dx, background->affine[3].dy, }); } else { - glUniform2iv(6, 4, (GLint[]) { + glUniform2iv(7, 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, }); - glUniform2iv(10, 4, (GLint[]) { + glUniform2iv(11, 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, @@ -910,7 +1034,5 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - _compositeLayer(renderer, background, y, background->target1 | (background->target2 * 2)); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); + _compositeLayer(renderer, background->tex, y, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2)); } \ No newline at end of file diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 46f6cb958..0e5d7dd5f 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -36,7 +36,6 @@ static void GBAVideoSoftwareRendererWriteBGY_LO(struct GBAVideoSoftwareBackgroun static void GBAVideoSoftwareRendererWriteBGY_HI(struct GBAVideoSoftwareBackground* bg, uint16_t value); static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* renderer, uint16_t value); -static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer); static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y); static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer); @@ -498,32 +497,6 @@ static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, #endif } -static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) { - int i; - int oamMax = 0; - for (i = 0; i < 128; ++i) { - struct GBAObj obj; - LOAD_16(obj.a, 0, &renderer->d.oam->obj[i].a); - LOAD_16(obj.b, 0, &renderer->d.oam->obj[i].b); - LOAD_16(obj.c, 0, &renderer->d.oam->obj[i].c); - if (GBAObjAttributesAIsTransformed(obj.a) || !GBAObjAttributesAIsDisable(obj.a)) { - int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(obj.a) * 4 + GBAObjAttributesBGetSize(obj.b)][1]; - if (GBAObjAttributesAIsTransformed(obj.a)) { - height <<= GBAObjAttributesAGetDoubleSize(obj.a); - } - if (GBAObjAttributesAGetY(obj.a) < GBA_VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) { - int y = GBAObjAttributesAGetY(obj.a) + renderer->objOffsetY; - renderer->sprites[oamMax].y = y; - renderer->sprites[oamMax].endY = y + height; - renderer->sprites[oamMax].obj = obj; - ++oamMax; - } - } - } - renderer->oamMax = oamMax; - renderer->oamDirty = 0; -} - static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; @@ -821,14 +794,15 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { int spriteLayers = 0; if (GBARegisterDISPCNTIsObjEnable(renderer->dispcnt) && !renderer->d.disableOBJ) { if (renderer->oamDirty) { - _cleanOAM(renderer); + renderer->oamMax = GBAVideoRendererCleanOAM(renderer->d.oam->obj, renderer->sprites, renderer->objOffsetY); + renderer->oamDirty = false; } renderer->spriteCyclesRemaining = GBARegisterDISPCNTIsHblankIntervalFree(renderer->dispcnt) ? OBJ_HBLANK_FREE_LENGTH : OBJ_LENGTH; int mosaicV = GBAMosaicControlGetObjV(renderer->mosaic) + 1; int mosaicY = y - (y % mosaicV); int i; for (i = 0; i < renderer->oamMax; ++i) { - struct GBAVideoSoftwareSprite* sprite = &renderer->sprites[i]; + struct GBAVideoRendererSprite* sprite = &renderer->sprites[i]; int localY = y; renderer->end = 0; if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { From bd69c9fb26365f8876a20b385e9b9de94ed80feb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2019 22:24:21 -0700 Subject: [PATCH 200/429] GBA Video: Add per-pixel flags in GL --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 127 +++++++++++++++-------- 2 files changed, 86 insertions(+), 42 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 636f3bf05..df6c8c6e7 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -42,6 +42,7 @@ struct GBAVideoGLAffine { struct GBAVideoGLBackground { GLuint fbo; GLuint tex; + GLuint flags; unsigned index; int enabled; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 597248310..2a0e6067a 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -37,7 +37,7 @@ static void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, int y, int priority, int flags); +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int y); #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority @@ -76,7 +76,7 @@ static const char* const _renderTile256 = " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, pal2 + (paletteId & 16)), 0);\n" - " if (pal2 + entry == 0) {\n" + " if ((pal2 | entry) == 0) {\n" " discard;\n" " }\n" " color.a = 1.;\n" @@ -91,6 +91,10 @@ static const char* const _renderMode0 = "uniform int charBase;\n" "uniform int size;\n" "uniform ivec2 offset;\n" + "uniform ivec3 inflags;\n" + "out vec4 color;\n" + "out vec3 flags;\n" + "const vec3 flagCoeff = vec3(32., 8., 4.);\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -102,15 +106,16 @@ static const char* const _renderMode0 = " coord.x &= 255;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" - " int flags = int(map.g * 15.9);\n" - " if ((flags & 4) == 4) {\n" + " int tileFlags = int(map.g * 15.9);\n" + " if ((tileFlags & 4) == 4) {\n" " coord.x ^= 7;\n" " }\n" - " if ((flags & 8) == 8) {\n" + " if ((tileFlags & 8) == 8) {\n" " coord.y ^= 7;\n" " }\n" - " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (flags & 0x3) * 256;\n" - " gl_FragColor = renderTile(tile, int(map.r * 15.9), coord & 7);\n" + " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (tileFlags & 0x3) * 256;\n" + " color = renderTile(tile, int(map.r * 15.9), coord & 7);\n" + " flags = inflags / flagCoeff;\n" "}"; static const char* const _fetchTileOverflow = @@ -125,9 +130,7 @@ static const char* const _fetchTileNoOverflow = " int sizeAdjusted = (0x8000 << size) - 1;\n" " ivec2 outerCoord = coord & ~sizeAdjusted;\n" " if ((outerCoord.x | outerCoord.y) != 0) {\n" - " vec4 color = texelFetch(palette, ivec2(0, 0), 0);\n" - " color.a = 0;\n" - " return color;\n" + " discard;\n" " }\n" " return renderTile(coord);\n" "}"; @@ -139,8 +142,12 @@ static const char* const _renderMode2 = "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" + "uniform ivec3 inflags;\n" "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" + "out vec4 color;\n" + "out vec3 flags;\n" + "const vec3 flagCoeff = vec3(32., 8., 4.);\n" "precision highp float;\n" "precision highp int;\n" @@ -156,11 +163,10 @@ static const char* const _renderMode2 = " int entry = int(halfrow[3 - ((coord.x >> 7) & 2)] * 15.9);\n" " int pal2 = int(halfrow[2 - ((coord.x >> 7) & 2)] * 15.9);\n" " vec4 color = texelFetch(palette, ivec2(entry, pal2), 0);\n" - " if (pal2 > 0 || entry > 0) {\n" - " color.a = 1.;\n" - " } else {\n" - " color.a = 0.;\n" + " if ((pal2 | entry) == 0) {\n" + " discard;\n" " }\n" + " color.a = 1.;\n" " return color;\n" "}\n" @@ -177,7 +183,8 @@ static const char* const _renderMode2 = " float lin = 0.5 - y / ceil(y) * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " gl_FragColor = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" + " color = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" + " flags = inflags / flagCoeff;\n" "}"; static const char* const _renderObjNoTransform = @@ -202,10 +209,10 @@ static const char* const _renderObjNoTransform = static const char* const _composite = "varying vec2 texCoord;\n" - "uniform ivec3 inflags;\n" "uniform int scale;\n" "uniform vec3 blend;\n" "uniform sampler2D layer;\n" + "uniform sampler2D layerFlags;\n" "uniform sampler2D oldLayer;\n" "uniform sampler2D oldFlags;\n" "out vec4 color;\n" @@ -217,6 +224,7 @@ static const char* const _composite = " if (pix.a == 0) {\n" " discard;\n" " }\n" + " ivec3 inflags = ivec3(texelFetch(layerFlags, ivec2(texCoord * scale), 0).xyz * flagCoeff);\n" " ivec3 oflags = ivec3(texelFetch(oldFlags, ivec2(texCoord * scale), 0).xyz * flagCoeff);\n" " ivec3 outflags = ivec3(0, 0, 0);\n" " if (inflags.x < oflags.x) {\n" @@ -228,6 +236,7 @@ static const char* const _composite = " }\n" " } else {\n" " pix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " outflags = oflags;\n" " }\n" " color = pix;\n" " flags = outflags / flagCoeff;\n" @@ -278,6 +287,8 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); } glDeleteShader(fs); + glBindFragDataLocation(program, 0, "color"); + glBindFragDataLocation(program, 1, "flags"); } void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { @@ -342,7 +353,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glRenderer->bg[i].index = i; glGenFramebuffers(1, &glRenderer->bg[i].fbo); glGenTextures(1, &glRenderer->bg[i].tex); + glGenTextures(1, &glRenderer->bg[i].flags); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); + glBindTexture(GL_TEXTURE_2D, glRenderer->bg[i].tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -350,6 +363,15 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->bg[i].tex, 0); + + glBindTexture(GL_TEXTURE_2D, glRenderer->bg[i].flags); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->bg[i].flags, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -399,10 +421,11 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); + shaderBuffer[2] = _renderTile256; + _compileShader(glRenderer, glRenderer->objProgram[2], shaderBuffer, 3, vs, log); + shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); - glBindFragDataLocation(glRenderer->compositeProgram, 0, "color"); - glBindFragDataLocation(glRenderer->compositeProgram, 1, "flags"); glDeleteShader(vs); @@ -686,22 +709,30 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); glEnable(GL_SCISSOR_TEST); glScissor(0, y * glRenderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, glRenderer->scale); + glDrawBuffer(GL_COLOR_ATTACHMENT0); glClear(GL_COLOR_BUFFER_BIT); - glDisable(GL_SCISSOR_TEST); if (y == 0) { + glDisable(GL_SCISSOR_TEST); glDrawBuffer(GL_COLOR_ATTACHMENT1); glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2)) / 8.f, 0, 1); glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - + glClearColor(0, 0, 0, 0); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_COLOR_ATTACHMENT1); glClear(GL_COLOR_BUFFER_BIT); for (i = 0; i < 4; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); - glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffer(GL_COLOR_ATTACHMENT1); + glClear(GL_COLOR_BUFFER_BIT); } + glDrawBuffer(GL_COLOR_ATTACHMENT0); + glEnable(GL_SCISSOR_TEST); } glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -722,7 +753,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstAffine = -1; } - glEnable(GL_SCISSOR_TEST); int spriteLayers = 0; if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { if (glRenderer->oamDirty) { @@ -743,6 +773,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } + _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], y); unsigned priority; for (priority = 4; priority--;) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -782,7 +813,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } } - _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], y, 0, 0); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); @@ -890,7 +920,7 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, int y, int priority, int flags) { +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int y) { if ((y & 0x1F) != 0x1F) { return; } @@ -901,17 +931,19 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, int glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->outputTex); + glBindTexture(GL_TEXTURE_2D, flags); glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, renderer->outputTex); + glActiveTexture(GL_TEXTURE0 + 3); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); glUniform2i(0, 0x20, y & ~0x1F); glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform3i(2, priority, flags, renderer->blendEffect); - glUniform1i(3, renderer->scale); - glUniform3f(4, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); - glUniform1i(5, 0); - glUniform1i(6, 1); - glUniform1i(7, 2); + glUniform1i(2, renderer->scale); + glUniform3f(3, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); + glUniform1i(4, 0); + glUniform1i(5, 1); + glUniform1i(6, 2); + glUniform1i(7, 3); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); @@ -928,16 +960,20 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB int align = GBAObjAttributesAIs256Color(sprite->a) && !GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt); unsigned charBase = (BASE_TILE >> 1) + (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x10; - int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x10 >> !GBAObjAttributesAIs256Color(sprite->a)); + int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x40 >> !GBAObjAttributesAIs256Color(sprite->a)); if (spriteY + height >= 256) { spriteY -= 256; } + if (GBAObjAttributesBIsVFlip(sprite->b)) { + spriteY = (y - height) + (y - spriteY) + 1; + } + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, width * renderer->scale, height * renderer->scale); glScissor(x * renderer->scale, y * renderer->scale, width * renderer->scale, renderer->scale); - glUseProgram(renderer->objProgram[0]); + glUseProgram(renderer->objProgram[GBAObjAttributesAIs256Color(sprite->a) ? 2 : 0]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -949,12 +985,13 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(4, charBase); glUniform1i(5, stride); glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); - glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, 0, 0); + glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj | (renderer->target2Obj * 2)) / 8.f, 0); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 });} + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); +} void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { int inY = y + background->y; @@ -980,11 +1017,14 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform1i(5, background->charBase); glUniform1i(6, background->size); glUniform2i(7, background->x, yBase - y); + glUniform3i(8, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2), renderer->blendEffect); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - _compositeLayer(renderer, background->tex, y, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2)); + _compositeLayer(renderer, background->tex, background->flags, y); } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -1003,27 +1043,28 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(4, background->screenBase); glUniform1i(5, background->charBase); glUniform1i(6, background->size); + glUniform3i(7, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2), renderer->blendEffect); if (renderer->scale > 1) { - glUniform2iv(7, 4, (GLint[]) { + glUniform2iv(8, 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[1].sx, background->affine[1].sy, background->affine[2].sx, background->affine[2].sy, background->affine[3].sx, background->affine[3].sy, }); - glUniform2iv(11, 4, (GLint[]) { + glUniform2iv(12, 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[1].dx, background->affine[1].dy, background->affine[2].dx, background->affine[2].dy, background->affine[3].dx, background->affine[3].dy, }); } else { - glUniform2iv(7, 4, (GLint[]) { + glUniform2iv(8, 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, }); - glUniform2iv(11, 4, (GLint[]) { + glUniform2iv(12, 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, @@ -1032,7 +1073,9 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, } glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - _compositeLayer(renderer, background->tex, y, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2)); + _compositeLayer(renderer, background->tex, background->flags, y); } \ No newline at end of file From c15dedf3f44f76abe87a40fe02db6f9a26f80123 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 00:55:26 -0700 Subject: [PATCH 201/429] GBA Video: Add transformed objects to GL --- include/mgba/internal/gba/renderers/gl.h | 2 +- src/gba/renderers/gl.c | 48 +++++++++++++++++------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index df6c8c6e7..5af071000 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -95,7 +95,7 @@ struct GBAVideoGLRenderer { unsigned vramDirty; GLuint bgProgram[6]; - GLuint objProgram[4]; + GLuint objProgram[2]; GLuint compositeProgram; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 2a0e6067a..58a650bd0 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -187,7 +187,7 @@ static const char* const _renderMode2 = " flags = inflags / flagCoeff;\n" "}"; -static const char* const _renderObjNoTransform = +static const char* const _renderObj = "varying vec2 texCoord;\n" "uniform sampler2D vram;\n" "uniform sampler2D palette;\n" @@ -195,6 +195,8 @@ static const char* const _renderObjNoTransform = "uniform int stride;\n" "uniform int localPalette;\n" "uniform ivec3 inflags;\n" + "uniform mat2x2 transform;\n" + "uniform ivec4 dims;\n" "out vec4 color;\n" "out vec3 flags;\n" "const vec3 flagCoeff = vec3(32., 8., 4.);\n" @@ -202,7 +204,10 @@ static const char* const _renderObjNoTransform = "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " ivec2 coord = ivec2(texCoord);\n" + " ivec2 coord = ivec2(transform * (texCoord - dims.zw / 2) + dims.xy / 2);\n" + " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" + " discard;\n" + " }\n" " color = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" " flags = inflags / flagCoeff;\n" "}"; @@ -378,8 +383,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glRenderer->compositeProgram = glCreateProgram(); glRenderer->objProgram[0] = glCreateProgram(); glRenderer->objProgram[1] = glCreateProgram(); - glRenderer->objProgram[2] = glCreateProgram(); - glRenderer->objProgram[3] = glCreateProgram(); glRenderer->bgProgram[0] = glCreateProgram(); glRenderer->bgProgram[1] = glCreateProgram(); glRenderer->bgProgram[2] = glCreateProgram(); @@ -416,13 +419,13 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _fetchTileNoOverflow; _compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); - shaderBuffer[1] = _renderObjNoTransform; + shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, glRenderer->objProgram[2], shaderBuffer, 3, vs, log); + _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); @@ -449,8 +452,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteProgram(glRenderer->bgProgram[6]); glDeleteProgram(glRenderer->objProgram[0]); glDeleteProgram(glRenderer->objProgram[1]); - glDeleteProgram(glRenderer->objProgram[2]); - glDeleteProgram(glRenderer->objProgram[3]); glDeleteProgram(glRenderer->compositeProgram); } @@ -966,26 +967,45 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB spriteY -= 256; } - if (GBAObjAttributesBIsVFlip(sprite->b)) { + if (!GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesBIsVFlip(sprite->b)) { spriteY = (y - height) + (y - spriteY) + 1; } + int totalWidth = width; + int totalHeight = height; + if (GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesAIsDoubleSize(sprite->a)) { + totalWidth <<= 1; + totalHeight <<= 1; + } + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); - glViewport(x * renderer->scale, spriteY * renderer->scale, width * renderer->scale, height * renderer->scale); - glScissor(x * renderer->scale, y * renderer->scale, width * renderer->scale, renderer->scale); - glUseProgram(renderer->objProgram[GBAObjAttributesAIs256Color(sprite->a) ? 2 : 0]); + glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); + glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); + glUseProgram(renderer->objProgram[GBAObjAttributesAGet256Color(sprite->a)]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(0, 1, y - spriteY); - glUniform2i(1, GBAObjAttributesBIsHFlip(sprite->b) ? -width : width, height); + glUniform2i(1, (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight); glUniform1i(2, 0); glUniform1i(3, 1); glUniform1i(4, charBase); glUniform1i(5, stride); glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); - glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj | (renderer->target2Obj * 2)) / 8.f, 0); + glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, renderer->target1Obj | (renderer->target2Obj * 2), 0); + if (GBAObjAttributesAIsTransformed(sprite->a)) { + struct GBAOAMMatrix mat; + LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); + LOAD_16(mat.b, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].b); + LOAD_16(mat.c, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].c); + LOAD_16(mat.d, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].d); + + glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { mat.a / 256.f, mat.c / 256.f, mat.b / 256.f, mat.d / 256.f }); + } else { + glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); + } + glUniform4i(9, width, height, totalWidth, totalHeight); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); From 509c80abad8221564a0bfade571d868e9e8247af Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 01:16:35 -0700 Subject: [PATCH 202/429] GBA Video: GL semitransparent OBJs --- src/gba/renderers/gl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 58a650bd0..82d2b9c6a 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -240,8 +240,14 @@ static const char* const _composite = " pix += oldpix * blend.y;\n" " }\n" " } else {\n" - " pix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" " outflags = oflags;\n" + " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " if (oflags.z == 1 && (oflags.y & 1) == 1 && (inflags.y & 2) == 2) {\n" + " pix *= blend.y;\n" + " pix += oldpix * blend.x;\n" + " } else {\n" + " pix = oldpix;\n" + " }\n" " }\n" " color = pix;\n" " flags = outflags / flagCoeff;\n" @@ -993,7 +999,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(4, charBase); glUniform1i(5, stride); glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); - glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, renderer->target1Obj | (renderer->target2Obj * 2), 0); + glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2), GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect); if (GBAObjAttributesAIsTransformed(sprite->a)) { struct GBAOAMMatrix mat; LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); From b865d8e479ec16288fa51a40ebf20a91c74dd57d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 02:18:46 -0700 Subject: [PATCH 203/429] SDL: Fix initialization ordering issues --- src/platform/sdl/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 450e1868a..21e4459b7 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -90,6 +90,12 @@ int main(int argc, char** argv) { freeArguments(&args); return 1; } + + if (!renderer.core->init(renderer.core)) { + freeArguments(&args); + return 1; + } + renderer.core->desiredVideoDimensions(renderer.core, &renderer.width, &renderer.height); #ifdef BUILD_GL mSDLGLCreate(&renderer); @@ -106,11 +112,6 @@ int main(int argc, char** argv) { opts.width = renderer.width * renderer.ratio; opts.height = renderer.height * renderer.ratio; - if (!renderer.core->init(renderer.core)) { - freeArguments(&args); - return 1; - } - struct mCheatDevice* device = NULL; if (args.cheatsFile && (device = renderer.core->cheatDevice(renderer.core))) { struct VFile* vf = VFileOpen(args.cheatsFile, O_RDONLY); From 424fbddfea8cdbb424838db3289bea835f2786b5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 13:46:25 -0700 Subject: [PATCH 204/429] GBA Video: GL better blending and finalization --- include/mgba/internal/gba/renderers/gl.h | 15 +- src/gba/renderers/gl.c | 246 +++++++++++++---------- 2 files changed, 152 insertions(+), 109 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 5af071000..b5917f0e1 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -66,10 +66,14 @@ struct GBAVideoGLBackground { enum { GBA_GL_FBO_OBJ = 0, GBA_GL_FBO_COMPOSITE = 1, + GBA_GL_FBO_OUTPUT = 2, GBA_GL_TEX_OBJ_COLOR = 0, GBA_GL_TEX_OBJ_FLAGS = 1, - GBA_GL_TEX_COMPOSITE_FLAGS = 2, + GBA_GL_TEX_COMPOSITE_COLOR = 2, + GBA_GL_TEX_COMPOSITE_FLAGS = 3, + GBA_GL_TEX_COMPOSITE_OLD_COLOR = 4, + GBA_GL_TEX_COMPOSITE_OLD_FLAGS = 5, }; struct GBAVideoGLRenderer { @@ -78,19 +82,17 @@ struct GBAVideoGLRenderer { struct GBAVideoGLBackground bg[4]; int oamMax; + bool oamDirty; struct GBAVideoRendererSprite sprites[128]; - GLuint fbo[2]; - GLuint layers[3]; + GLuint fbo[3]; + GLuint layers[6]; GLuint outputTex; GLuint paletteTex; bool paletteDirty; - GLuint oamTex; - bool oamDirty; - GLuint vramTex; unsigned vramDirty; @@ -98,6 +100,7 @@ struct GBAVideoGLRenderer { GLuint objProgram[2]; GLuint compositeProgram; + GLuint finalizeProgram; GBARegisterDISPCNT dispcnt; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 82d2b9c6a..4c51b27cc 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -38,6 +38,7 @@ static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int y); +static void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y); #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority @@ -91,10 +92,10 @@ static const char* const _renderMode0 = "uniform int charBase;\n" "uniform int size;\n" "uniform ivec2 offset;\n" - "uniform ivec3 inflags;\n" + "uniform ivec4 inflags;\n" "out vec4 color;\n" - "out vec3 flags;\n" - "const vec3 flagCoeff = vec3(32., 8., 4.);\n" + "out vec4 flags;\n" + "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -142,12 +143,12 @@ static const char* const _renderMode2 = "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" - "uniform ivec3 inflags;\n" + "uniform ivec4 inflags;\n" "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" "out vec4 color;\n" - "out vec3 flags;\n" - "const vec3 flagCoeff = vec3(32., 8., 4.);\n" + "out vec4 flags;\n" + "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "precision highp float;\n" "precision highp int;\n" @@ -194,12 +195,12 @@ static const char* const _renderObj = "uniform int charBase;\n" "uniform int stride;\n" "uniform int localPalette;\n" - "uniform ivec3 inflags;\n" + "uniform ivec4 inflags;\n" "uniform mat2x2 transform;\n" "uniform ivec4 dims;\n" "out vec4 color;\n" - "out vec3 flags;\n" - "const vec3 flagCoeff = vec3(32., 8., 4.);\n" + "out vec4 flags;\n" + "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -215,42 +216,66 @@ static const char* const _renderObj = static const char* const _composite = "varying vec2 texCoord;\n" "uniform int scale;\n" - "uniform vec3 blend;\n" "uniform sampler2D layer;\n" "uniform sampler2D layerFlags;\n" "uniform sampler2D oldLayer;\n" - "uniform sampler2D oldFlags;\n" + "uniform sampler2D oldLayerFlags;\n" + "uniform sampler2D oldOldFlags;\n" "out vec4 color;\n" - "out vec3 flags;\n" - "const vec3 flagCoeff = vec3(32., 8., 4.);\n" + "out vec4 flags;\n" + "out vec4 oldColor;\n" + "out vec4 oldFlags;\n" + "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "void main() {\n" " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" " if (pix.a == 0) {\n" " discard;\n" " }\n" - " ivec3 inflags = ivec3(texelFetch(layerFlags, ivec2(texCoord * scale), 0).xyz * flagCoeff);\n" - " ivec3 oflags = ivec3(texelFetch(oldFlags, ivec2(texCoord * scale), 0).xyz * flagCoeff);\n" - " ivec3 outflags = ivec3(0, 0, 0);\n" - " if (inflags.x < oflags.x) {\n" - " outflags = inflags;\n" - " if (inflags.z == 1 && (inflags.y & 1) == 1 && (oflags.y & 2) == 2) {\n" - " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" - " pix *= blend.x;\n" - " pix += oldpix * blend.y;\n" + " ivec4 inflags = ivec4(texelFetch(layerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " ivec4 oflags = ivec4(texelFetch(oldLayerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " if (inflags.x >= oflags.x) {\n" + " ivec4 ooflags = ivec4(texelFetch(oldOldFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " if (inflags.x >= ooflags.x) {\n" + " discard;\n" " }\n" + " oldFlags = inflags / flagCoeff;\n" + " flags = oflags / flagCoeff;\n" + " oldColor = pix;\n" + " color = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" " } else {\n" - " outflags = oflags;\n" - " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" - " if (oflags.z == 1 && (oflags.y & 1) == 1 && (inflags.y & 2) == 2) {\n" - " pix *= blend.y;\n" - " pix += oldpix * blend.x;\n" - " } else {\n" - " pix = oldpix;\n" - " }\n" + " color = pix;\n" + " oldColor = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " flags = inflags / flagCoeff;\n" + " oldFlags = oflags / flagCoeff;\n" " }\n" - " color = pix;\n" - " flags = outflags / flagCoeff;\n" + "}"; + +static const char* const _finalize = + "varying vec2 texCoord;\n" + "uniform int scale;\n" + "uniform sampler2D layer;\n" + "uniform sampler2D layerFlags;\n" + "uniform sampler2D oldLayer;\n" + "uniform sampler2D oldFlags;\n" + "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + + "void main() {\n" + " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(layerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " if ((inflags.y & 13) == 5) {\n" + " ivec4 oflags = ivec4(texelFetch(oldFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " if ((oflags.y & 2) == 2) {\n" + " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" + " pix *= inflags.z / 16.;\n" + " pix += oldpix * oflags.w / 16.;\n" + " }\n" + " } else if ((inflags.y & 13) == 9) {\n" + " pix += (1. - pix) * inflags.z / 16.;\n" + " } else if ((inflags.y & 13) == 13) {\n" + " pix -= pix * inflags.z / 16.;\n" + " }\n" + " gl_FragColor = pix;\n" "}"; static const GLint _vertices[] = { @@ -302,10 +327,20 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const glBindFragDataLocation(program, 1, "flags"); } +static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { + glBindTexture(GL_TEXTURE_2D, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, format, GBA_VIDEO_HORIZONTAL_PIXELS * scale, GBA_VIDEO_VERTICAL_PIXELS * scale, 0, format, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); +} + void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glGenFramebuffers(2, glRenderer->fbo); - glGenTextures(3, glRenderer->layers); + glGenFramebuffers(3, glRenderer->fbo); + glGenTextures(6, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); @@ -318,44 +353,18 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); - glGenTextures(1, &glRenderer->oamTex); - glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], 0); - - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], 0); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); - glBindTexture(GL_TEXTURE_2D, glRenderer->outputTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->outputTex, 0); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT3, glRenderer->scale); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS], 0); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); + _initFramebufferTexture(glRenderer->outputTex, GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -366,27 +375,13 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glGenTextures(1, &glRenderer->bg[i].tex); glGenTextures(1, &glRenderer->bg[i].flags); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); - - glBindTexture(GL_TEXTURE_2D, glRenderer->bg[i].tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glRenderer->bg[i].tex, 0); - - glBindTexture(GL_TEXTURE_2D, glRenderer->bg[i].flags); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, glRenderer->bg[i].flags, 0); - + _initFramebufferTexture(glRenderer->bg[i].tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTexture(glRenderer->bg[i].flags, GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, 0); } glRenderer->compositeProgram = glCreateProgram(); + glRenderer->finalizeProgram = glCreateProgram(); glRenderer->objProgram[0] = glCreateProgram(); glRenderer->objProgram[1] = glCreateProgram(); glRenderer->bgProgram[0] = glCreateProgram(); @@ -435,6 +430,11 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); + glBindFragDataLocation(glRenderer->compositeProgram, 2, "oldColor"); + glBindFragDataLocation(glRenderer->compositeProgram, 3, "oldFlags"); + + shaderBuffer[1] = _finalize; + _compileShader(glRenderer, glRenderer->finalizeProgram, shaderBuffer, 2, vs, log); glDeleteShader(vs); @@ -444,10 +444,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glDeleteFramebuffers(2, glRenderer->fbo); - glDeleteTextures(3, glRenderer->layers); + glDeleteTextures(6, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); - glDeleteTextures(1, &glRenderer->oamTex); glDeleteProgram(glRenderer->bgProgram[0]); glDeleteProgram(glRenderer->bgProgram[1]); @@ -615,9 +614,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, if (value > 0x10) { value = 0x10; } - if (glRenderer->bldy != value) { - glRenderer->bldy = value; - } + glRenderer->bldy = value; break; case REG_WIN0H: /*glRenderer->winN[0].h.end = value; @@ -721,10 +718,14 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { if (y == 0) { glDisable(GL_SCISSOR_TEST); glDrawBuffer(GL_COLOR_ATTACHMENT1); - glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2)) / 8.f, 0, 1); + glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, + (glRenderer->blendEffect == BLEND_ALPHA ? glRenderer->blda : glRenderer->bldy) / 16.f, glRenderer->bldb / 16.f); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0, 0, 0, 0); + glDrawBuffer(GL_COLOR_ATTACHMENT3); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); glDrawBuffer(GL_COLOR_ATTACHMENT0); glClear(GL_COLOR_BUFFER_BIT); @@ -763,8 +764,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { int spriteLayers = 0; if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { if (glRenderer->oamDirty) { - glBindTexture(GL_TEXTURE_2D, glRenderer->oamTex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, 4, 128, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, glRenderer->d.oam); glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); glRenderer->oamDirty = false; } @@ -820,6 +819,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } } + _finalizeLayers(glRenderer, y); + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); @@ -940,25 +941,56 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, flags); glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->outputTex); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); glActiveTexture(GL_TEXTURE0 + 3); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); + glActiveTexture(GL_TEXTURE0 + 4); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); glUniform2i(0, 0x20, y & ~0x1F); glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(2, renderer->scale); - glUniform3f(3, renderer->blda / 16.f, renderer->bldb / 16.f, renderer->bldy / 16.f); - glUniform1i(4, 0); - glUniform1i(5, 1); - glUniform1i(6, 2); - glUniform1i(7, 3); + glUniform1i(3, 0); + glUniform1i(4, 1); + glUniform1i(5, 2); + glUniform1i(6, 3); + glUniform1i(7, 4); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); - glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glBindFramebuffer(GL_FRAMEBUFFER, 0); } +void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { + if ((y & 0x1F) != 0x1F) { + return; + } + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); + glUseProgram(renderer->finalizeProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); + glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR]); + glActiveTexture(GL_TEXTURE0 + 3); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); + glUniform2i(0, 0x20, y & ~0x1F); + glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(2, renderer->scale); + glUniform1i(3, 0); + glUniform1i(4, 1); + glUniform1i(5, 2); + glUniform1i(6, 3); + glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GBAObj* sprite, int y, int spriteY) { int width = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][0]; int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1]; @@ -984,6 +1016,8 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB totalHeight <<= 1; } + enum GBAVideoBlendEffect blendEffect = GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect; + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); @@ -999,7 +1033,9 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(4, charBase); glUniform1i(5, stride); glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); - glUniform3i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2), GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect); + glUniform4i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, + (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), + blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); if (GBAObjAttributesAIsTransformed(sprite->a)) { struct GBAOAMMatrix mat; LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); @@ -1043,7 +1079,9 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform1i(5, background->charBase); glUniform1i(6, background->size); glUniform2i(7, background->x, yBase - y); - glUniform3i(8, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2), renderer->blendEffect); + glUniform4i(8, (background->priority << 3) + (background->index << 1) + 1, + background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), + renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); @@ -1069,7 +1107,9 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(4, background->screenBase); glUniform1i(5, background->charBase); glUniform1i(6, background->size); - glUniform3i(7, (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2), renderer->blendEffect); + glUniform4i(7, (background->priority << 3) + (background->index << 1) + 1, + background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), + renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); if (renderer->scale > 1) { glUniform2iv(8, 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, From a50ea97bce0445171fddd7ecedd11adb321c1780 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 16:15:54 -0700 Subject: [PATCH 205/429] GBA Video: Initialize GL backgrounds better --- src/gba/renderers/gl.c | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 4c51b27cc..ef50347be 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -370,13 +370,34 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { int i; for (i = 0; i < 4; ++i) { - glRenderer->bg[i].index = i; - glGenFramebuffers(1, &glRenderer->bg[i].fbo); - glGenTextures(1, &glRenderer->bg[i].tex); - glGenTextures(1, &glRenderer->bg[i].flags); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); - _initFramebufferTexture(glRenderer->bg[i].tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); - _initFramebufferTexture(glRenderer->bg[i].flags, GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); + struct GBAVideoGLBackground* bg = &glRenderer->bg[i]; + bg->index = i; + bg->enabled = 0; + bg->priority = 0; + bg->charBase = 0; + bg->mosaic = 0; + bg->multipalette = 0; + bg->screenBase = 0; + bg->overflow = 0; + bg->size = 0; + bg->target1 = 0; + bg->target2 = 0; + bg->x = 0; + bg->y = 0; + bg->refx = 0; + bg->refy = 0; + bg->affine[0].dx = 256; + bg->affine[0].dmx = 0; + bg->affine[0].dy = 0; + bg->affine[0].dmy = 256; + bg->affine[0].sx = 0; + bg->affine[0].sy = 0; + glGenFramebuffers(1, &bg->fbo); + glGenTextures(1, &bg->tex); + glGenTextures(1, &bg->flags); + glBindFramebuffer(GL_FRAMEBUFFER, bg->fbo); + _initFramebufferTexture(bg->tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTexture(bg->flags, GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, 0); } From 3e8bb42e9f745f69f2137f071cfdc8fda0f3d435 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 18:07:03 -0700 Subject: [PATCH 206/429] GBA Video: Windows in GL --- include/mgba/internal/gba/renderers/gl.h | 21 +++- .../internal/gba/renderers/video-software.h | 9 +- include/mgba/internal/gba/video.h | 5 + src/gba/renderers/gl.c | 101 ++++++++++++------ 4 files changed, 94 insertions(+), 42 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index b5917f0e1..c8a0391f9 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -66,14 +66,20 @@ struct GBAVideoGLBackground { enum { GBA_GL_FBO_OBJ = 0, GBA_GL_FBO_COMPOSITE = 1, - GBA_GL_FBO_OUTPUT = 2, + GBA_GL_FBO_WINDOW = 2, + GBA_GL_FBO_OUTPUT = 3, + GBA_GL_FBO_MAX +}; +enum { GBA_GL_TEX_OBJ_COLOR = 0, GBA_GL_TEX_OBJ_FLAGS = 1, GBA_GL_TEX_COMPOSITE_COLOR = 2, GBA_GL_TEX_COMPOSITE_FLAGS = 3, GBA_GL_TEX_COMPOSITE_OLD_COLOR = 4, GBA_GL_TEX_COMPOSITE_OLD_FLAGS = 5, + GBA_GL_TEX_WINDOW = 6, + GBA_GL_TEX_MAX }; struct GBAVideoGLRenderer { @@ -85,8 +91,8 @@ struct GBAVideoGLRenderer { bool oamDirty; struct GBAVideoRendererSprite sprites[128]; - GLuint fbo[3]; - GLuint layers[6]; + GLuint fbo[GBA_GL_FBO_MAX]; + GLuint layers[GBA_GL_TEX_MAX]; GLuint outputTex; @@ -115,6 +121,15 @@ struct GBAVideoGLRenderer { GBAMosaicControl mosaic; + struct GBAVideoGLWindowN { + struct GBAVideoWindowRegion h; + struct GBAVideoWindowRegion v; + GBAWindowControl control; + } winN[2]; + + GBAWindowControl winout; + GBAWindowControl objwin; + int firstAffine; int scale; diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 87e0addba..47b8ddfb6 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -70,11 +70,6 @@ enum { #define IS_WRITABLE(PIXEL) ((PIXEL) & 0xFE000000) -struct WindowRegion { - uint8_t end; - uint8_t start; -}; - struct WindowControl { GBAWindowControl packed; int8_t priority; @@ -118,8 +113,8 @@ struct GBAVideoSoftwareRenderer { GBAMosaicControl mosaic; struct WindowN { - struct WindowRegion h; - struct WindowRegion v; + struct GBAVideoWindowRegion h; + struct GBAVideoWindowRegion v; struct WindowControl control; } winN[2]; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 699d2f238..ba8048ffd 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -97,6 +97,11 @@ union GBAOAM { uint16_t raw[512]; }; +struct GBAVideoWindowRegion { + uint8_t end; + uint8_t start; +}; + #define GBA_TEXT_MAP_TILE(MAP) ((MAP) & 0x03FF) #define GBA_TEXT_MAP_HFLIP(MAP) ((MAP) & 0x0400) #define GBA_TEXT_MAP_VFLIP(MAP) ((MAP) & 0x0800) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ef50347be..80450afcd 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -36,8 +36,9 @@ static void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); +static void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y); -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int y); +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int id, int y); static void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y); #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority @@ -216,11 +217,13 @@ static const char* const _renderObj = static const char* const _composite = "varying vec2 texCoord;\n" "uniform int scale;\n" + "uniform int layerId\n;" "uniform sampler2D layer;\n" "uniform sampler2D layerFlags;\n" "uniform sampler2D oldLayer;\n" "uniform sampler2D oldLayerFlags;\n" "uniform sampler2D oldOldFlags;\n" + "uniform sampler2D window;\n" "out vec4 color;\n" "out vec4 flags;\n" "out vec4 oldColor;\n" @@ -232,8 +235,15 @@ static const char* const _composite = " if (pix.a == 0) {\n" " discard;\n" " }\n" + " ivec2 windowFlags = ivec2(texelFetch(window, ivec2(texCoord * scale), 0).xy * 32.);\n" + " if (((windowFlags.x | (windowFlags.y << 4)) & layerId) != 0) {\n" + " discard;\n" + " }\n" " ivec4 inflags = ivec4(texelFetch(layerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" " ivec4 oflags = ivec4(texelFetch(oldLayerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" + " if ((windowFlags.y & 2) != 0) {\n" + " inflags.y = 0;\n" + " }\n" " if (inflags.x >= oflags.x) {\n" " ivec4 ooflags = ivec4(texelFetch(oldOldFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" " if (inflags.x >= ooflags.x) {\n" @@ -339,8 +349,8 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glGenFramebuffers(3, glRenderer->fbo); - glGenTextures(6, glRenderer->layers); + glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); + glGenTextures(GBA_GL_TEX_MAX, glRenderer->layers); glGenTextures(1, &glRenderer->paletteTex); glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); @@ -363,6 +373,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT3, glRenderer->scale); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RG, GL_COLOR_ATTACHMENT0, glRenderer->scale); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); _initFramebufferTexture(glRenderer->outputTex, GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -464,8 +477,8 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - glDeleteFramebuffers(2, glRenderer->fbo); - glDeleteTextures(6, glRenderer->layers); + glDeleteFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); + glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); @@ -638,7 +651,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, glRenderer->bldy = value; break; case REG_WIN0H: - /*glRenderer->winN[0].h.end = value; + glRenderer->winN[0].h.end = value; glRenderer->winN[0].h.start = value >> 8; if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h.start > glRenderer->winN[0].h.end) { glRenderer->winN[0].h.start = 0; @@ -648,10 +661,10 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { glRenderer->winN[0].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; } - }*/ + } break; case REG_WIN1H: - /*glRenderer->winN[1].h.end = value; + glRenderer->winN[1].h.end = value; glRenderer->winN[1].h.start = value >> 8; if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h.start > glRenderer->winN[1].h.end) { glRenderer->winN[1].h.start = 0; @@ -661,10 +674,10 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { glRenderer->winN[1].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; } - }*/ + } break; case REG_WIN0V: - /*glRenderer->winN[0].v.end = value; + glRenderer->winN[0].v.end = value; glRenderer->winN[0].v.start = value >> 8; if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[0].v.start > glRenderer->winN[0].v.end) { glRenderer->winN[0].v.start = 0; @@ -674,10 +687,10 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { glRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; } - }*/ + } break; case REG_WIN1V: - /*glRenderer->winN[1].v.end = value; + glRenderer->winN[1].v.end = value; glRenderer->winN[1].v.start = value >> 8; if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[1].v.start > glRenderer->winN[1].v.end) { glRenderer->winN[1].v.start = 0; @@ -687,26 +700,23 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { glRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; } - }*/ + } break; case REG_WININ: value &= 0x3F3F; - //glRenderer->winN[0].control.packed = value; - //glRenderer->winN[1].control.packed = value >> 8; + glRenderer->winN[0].control = value; + glRenderer->winN[1].control = value >> 8; break; case REG_WINOUT: value &= 0x3F3F; - //glRenderer->winout.packed = value; - //glRenderer->objwin.packed = value >> 8; + glRenderer->winout = value; + glRenderer->objwin = value >> 8; break; case REG_MOSAIC: glRenderer->mosaic = value; break; - case REG_GREENSWP: - mLOG(GBA_VIDEO, STUB, "Stub video register write: 0x%03X", address); - break; default: - mLOG(GBA_VIDEO, GAME_ERROR, "Invalid video register: 0x%03X", address); + break; } return value; } @@ -800,7 +810,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } - _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], y); + GBAVideoGLRendererDrawWindow(glRenderer, y); + _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], 4, y); unsigned priority; for (priority = 4; priority--;) { if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -842,7 +853,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } _finalizeLayers(glRenderer, y); - if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[2], sizeof(struct GBAVideoGLAffine)); @@ -949,7 +959,7 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int y) { +static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int id, int y) { if ((y & 0x1F) != 0x1F) { return; } @@ -967,14 +977,18 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); glActiveTexture(GL_TEXTURE0 + 4); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); + glActiveTexture(GL_TEXTURE0 + 5); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); glUniform2i(0, 0x20, y & ~0x1F); glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(2, renderer->scale); - glUniform1i(3, 0); - glUniform1i(4, 1); - glUniform1i(5, 2); - glUniform1i(6, 3); - glUniform1i(7, 4); + glUniform1i(3, 1 << id); + glUniform1i(4, 0); + glUniform1i(5, 1); + glUniform1i(6, 2); + glUniform1i(7, 3); + glUniform1i(8, 4); + glUniform1i(9, 5); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); @@ -1109,7 +1123,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - _compositeLayer(renderer, background->tex, background->flags, y); + _compositeLayer(renderer, background->tex, background->flags, background->index, y); } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -1164,5 +1178,28 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - _compositeLayer(renderer, background->tex, background->flags, y); -} \ No newline at end of file + _compositeLayer(renderer, background->tex, background->flags, background->index, y); +} + +static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale) { + glScissor(start, y, end - start, scale); + window = ~window & 0xFF; + glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); +} + +void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { + glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); + if (!(renderer->dispcnt & 0xE000)) { + _clearWindow(0xFF, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + } else { + _clearWindow(renderer->winout, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { + _clearWindow(renderer->winN[1].control, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale); + } + if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { + _clearWindow(renderer->winN[0].control, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale); + } + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} From 4e4e46117586ce99ea6536ed325aaa9ee8afcc5c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 13 May 2019 21:32:34 -0700 Subject: [PATCH 207/429] GBA Video: Clean up GL uniforms --- include/mgba/internal/gba/renderers/gl.h | 44 ++++++ src/gba/renderers/gl.c | 193 +++++++++++++++++------ 2 files changed, 186 insertions(+), 51 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index c8a0391f9..c5a09f24a 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -82,6 +82,46 @@ enum { GBA_GL_TEX_MAX }; +enum { + GBA_GL_VS_LOC = 0, + GBA_GL_VS_MAXPOS, + + GBA_GL_BG_VRAM = 2, + GBA_GL_BG_PALETTE, + GBA_GL_BG_SCREENBASE, + GBA_GL_BG_CHARBASE, + GBA_GL_BG_SIZE, + GBA_GL_BG_OFFSET, + GBA_GL_BG_INFLAGS, + GBA_GL_BG_TRANSFORM, + + GBA_GL_OBJ_VRAM = 2, + GBA_GL_OBJ_PALETTE, + GBA_GL_OBJ_CHARBASE, + GBA_GL_OBJ_STRIDE, + GBA_GL_OBJ_LOCALPALETTE, + GBA_GL_OBJ_INFLAGS, + GBA_GL_OBJ_TRANSFORM, + GBA_GL_OBJ_DIMS, + + GBA_GL_COMPOSITE_SCALE = 2, + GBA_GL_COMPOSITE_LAYERID, + GBA_GL_COMPOSITE_LAYER, + GBA_GL_COMPOSITE_LAYERFLAGS, + GBA_GL_COMPOSITE_OLDLAYER, + GBA_GL_COMPOSITE_OLDLAYERFLAGS, + GBA_GL_COMPOSITE_OLDOLDFLAGS, + GBA_GL_COMPOSITE_WINDOW, + + GBA_GL_FINALIZE_SCALE = 2, + GBA_GL_FINALIZE_LAYER, + GBA_GL_FINALIZE_LAYERFLAGS, + GBA_GL_FINALIZE_OLDLAYER, + GBA_GL_FINALIZE_OLDFLAGS, + + GBA_GL_UNIFORM_MAX = 12 +}; + struct GBAVideoGLRenderer { struct GBAVideoRenderer d; @@ -103,10 +143,14 @@ struct GBAVideoGLRenderer { unsigned vramDirty; GLuint bgProgram[6]; + GLuint bgUniforms[6][GBA_GL_UNIFORM_MAX]; GLuint objProgram[2]; + GLuint objUniforms[2][GBA_GL_UNIFORM_MAX]; GLuint compositeProgram; + GLuint compositeUniforms[GBA_GL_UNIFORM_MAX]; GLuint finalizeProgram; + GLuint finalizeUniforms[GBA_GL_UNIFORM_MAX]; GBARegisterDISPCNT dispcnt; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 80450afcd..33a523b20 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -43,6 +43,11 @@ static void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y); #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority +struct GBAVideoGLUniform { + const char* name; + int type; +}; + static const GLchar* const _gl3Header = "#version 130\n"; @@ -85,6 +90,19 @@ static const char* const _renderTile256 = " return color;\n" "}"; +const static struct GBAVideoGLUniform _uniformsMode0[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "vram", GBA_GL_BG_VRAM, }, + { "palette", GBA_GL_BG_PALETTE, }, + { "screenBase", GBA_GL_BG_SCREENBASE, }, + { "charBase", GBA_GL_BG_CHARBASE, }, + { "size", GBA_GL_BG_SIZE, }, + { "offset", GBA_GL_BG_OFFSET, }, + { "inflags", GBA_GL_BG_INFLAGS, }, + { 0 } +}; + static const char* const _renderMode0 = "varying vec2 texCoord;\n" "uniform sampler2D vram;\n" @@ -137,6 +155,20 @@ static const char* const _fetchTileNoOverflow = " return renderTile(coord);\n" "}"; +const static struct GBAVideoGLUniform _uniformsMode2[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "vram", GBA_GL_BG_VRAM, }, + { "palette", GBA_GL_BG_PALETTE, }, + { "screenBase", GBA_GL_BG_SCREENBASE, }, + { "charBase", GBA_GL_BG_CHARBASE, }, + { "size", GBA_GL_BG_SIZE, }, + { "inflags", GBA_GL_BG_INFLAGS, }, + { "offset", GBA_GL_BG_OFFSET, }, + { "transform", GBA_GL_BG_TRANSFORM, }, + { 0 } +}; + static const char* const _renderMode2 = "varying vec2 texCoord;\n" "uniform sampler2D vram;\n" @@ -189,6 +221,20 @@ static const char* const _renderMode2 = " flags = inflags / flagCoeff;\n" "}"; +const static struct GBAVideoGLUniform _uniformsObj[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "vram", GBA_GL_OBJ_VRAM, }, + { "palette", GBA_GL_OBJ_PALETTE, }, + { "charBase", GBA_GL_OBJ_CHARBASE, }, + { "stride", GBA_GL_OBJ_STRIDE, }, + { "localPalette", GBA_GL_OBJ_LOCALPALETTE, }, + { "inflags", GBA_GL_OBJ_INFLAGS, }, + { "transform", GBA_GL_OBJ_TRANSFORM, }, + { "dims", GBA_GL_OBJ_DIMS, }, + { 0 } +}; + static const char* const _renderObj = "varying vec2 texCoord;\n" "uniform sampler2D vram;\n" @@ -214,6 +260,20 @@ static const char* const _renderObj = " flags = inflags / flagCoeff;\n" "}"; +const static struct GBAVideoGLUniform _uniformsComposite[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "scale", GBA_GL_COMPOSITE_SCALE, }, + { "layerId", GBA_GL_COMPOSITE_LAYERID, }, + { "layer", GBA_GL_COMPOSITE_LAYER, }, + { "layerFlags", GBA_GL_COMPOSITE_LAYERFLAGS, }, + { "oldLayer", GBA_GL_COMPOSITE_OLDLAYER, }, + { "oldLayerFlags", GBA_GL_COMPOSITE_OLDLAYERFLAGS, }, + { "oldOldFlags", GBA_GL_COMPOSITE_OLDOLDFLAGS, }, + { "window", GBA_GL_COMPOSITE_WINDOW, }, + { 0 } +}; + static const char* const _composite = "varying vec2 texCoord;\n" "uniform int scale;\n" @@ -261,6 +321,17 @@ static const char* const _composite = " }\n" "}"; +const static struct GBAVideoGLUniform _uniformsFinalize[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "scale", GBA_GL_FINALIZE_SCALE, }, + { "layer", GBA_GL_FINALIZE_LAYER, }, + { "layerFlags", GBA_GL_FINALIZE_LAYERFLAGS, }, + { "oldLayer", GBA_GL_FINALIZE_OLDLAYER, }, + { "oldFlags", GBA_GL_FINALIZE_OLDFLAGS, }, + { 0 } +}; + static const char* const _finalize = "varying vec2 texCoord;\n" "uniform int scale;\n" @@ -347,6 +418,13 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } +static void _lookupUniforms(GLuint program, GLuint* out, const struct GBAVideoGLUniform* uniforms) { + size_t i; + for (i = 0; uniforms[i].name; ++i) { + out[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); + } +} + void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); @@ -442,33 +520,41 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->bgProgram[0], glRenderer->bgUniforms[0], _uniformsMode0); shaderBuffer[2] = _renderTile256; _compileShader(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->bgProgram[1], glRenderer->bgUniforms[1], _uniformsMode0); shaderBuffer[1] = _renderMode2; shaderBuffer[2] = _fetchTileOverflow; _compileShader(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->bgProgram[2], glRenderer->bgUniforms[2], _uniformsMode2); shaderBuffer[2] = _fetchTileNoOverflow; _compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->bgProgram[3], glRenderer->bgUniforms[3], _uniformsMode2); shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->objProgram[0], glRenderer->objUniforms[0], _uniformsObj); shaderBuffer[2] = _renderTile256; _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); + _lookupUniforms(glRenderer->objProgram[1], glRenderer->objUniforms[1], _uniformsObj); shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); + _lookupUniforms(glRenderer->compositeProgram, glRenderer->compositeUniforms, _uniformsComposite); glBindFragDataLocation(glRenderer->compositeProgram, 2, "oldColor"); glBindFragDataLocation(glRenderer->compositeProgram, 3, "oldFlags"); shaderBuffer[1] = _finalize; _compileShader(glRenderer, glRenderer->finalizeProgram, shaderBuffer, 2, vs, log); + _lookupUniforms(glRenderer->finalizeProgram, glRenderer->finalizeUniforms, _uniformsFinalize); glDeleteShader(vs); @@ -963,6 +1049,7 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu if ((y & 0x1F) != 0x1F) { return; } + const GLuint* uniforms = renderer->compositeUniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_COMPOSITE]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); @@ -979,16 +1066,16 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); glActiveTexture(GL_TEXTURE0 + 5); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); - glUniform2i(0, 0x20, y & ~0x1F); - glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(2, renderer->scale); - glUniform1i(3, 1 << id); - glUniform1i(4, 0); - glUniform1i(5, 1); - glUniform1i(6, 2); - glUniform1i(7, 3); - glUniform1i(8, 4); - glUniform1i(9, 5); + glUniform2i(uniforms[GBA_GL_VS_LOC], 0x20, y & ~0x1F); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_COMPOSITE_SCALE], renderer->scale); + glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYERID], 1 << id); + glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYER], 0); + glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYERFLAGS], 1); + glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYER], 2); + glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYERFLAGS], 3); + glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDOLDFLAGS], 4); + glUniform1i(uniforms[GBA_GL_COMPOSITE_WINDOW], 5); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); @@ -1001,6 +1088,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { if ((y & 0x1F) != 0x1F) { return; } + const GLuint* uniforms = renderer->finalizeUniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); @@ -1013,13 +1101,13 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR]); glActiveTexture(GL_TEXTURE0 + 3); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); - glUniform2i(0, 0x20, y & ~0x1F); - glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(2, renderer->scale); - glUniform1i(3, 0); - glUniform1i(4, 1); - glUniform1i(5, 2); - glUniform1i(6, 3); + glUniform2i(uniforms[GBA_GL_VS_LOC], 0x20, y & ~0x1F); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); + glUniform1i(uniforms[GBA_GL_FINALIZE_LAYER], 0); + glUniform1i(uniforms[GBA_GL_FINALIZE_LAYERFLAGS], 1); + glUniform1i(uniforms[GBA_GL_FINALIZE_OLDLAYER], 2); + glUniform1i(uniforms[GBA_GL_FINALIZE_OLDFLAGS], 3); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1053,6 +1141,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB enum GBAVideoBlendEffect blendEffect = GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect; + const GLuint* uniforms = renderer->objUniforms[GBAObjAttributesAGet256Color(sprite->a)]; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); @@ -1061,14 +1150,14 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(0, 1, y - spriteY); - glUniform2i(1, (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight); - glUniform1i(2, 0); - glUniform1i(3, 1); - glUniform1i(4, charBase); - glUniform1i(5, stride); - glUniform1i(6, GBAObjAttributesCGetPalette(sprite->c)); - glUniform4i(7, GBAObjAttributesCGetPriority(sprite->c) << 3, + glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y - spriteY); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight); + glUniform1i(uniforms[GBA_GL_OBJ_VRAM], 0); + glUniform1i(uniforms[GBA_GL_OBJ_PALETTE], 1); + glUniform1i(uniforms[GBA_GL_OBJ_CHARBASE], charBase); + glUniform1i(uniforms[GBA_GL_OBJ_STRIDE], stride); + glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); + glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); if (GBAObjAttributesAIsTransformed(sprite->a)) { @@ -1078,11 +1167,11 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB LOAD_16(mat.c, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].c); LOAD_16(mat.d, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].d); - glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { mat.a / 256.f, mat.c / 256.f, mat.b / 256.f, mat.d / 256.f }); + glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { mat.a / 256.f, mat.c / 256.f, mat.b / 256.f, mat.d / 256.f }); } else { - glUniformMatrix2fv(8, 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); + glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); } - glUniform4i(9, width, height, totalWidth, totalHeight); + glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); @@ -1098,6 +1187,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } else if (background->size == 3) { yBase += (inY & 0x100) << 1; } + const GLuint* uniforms = renderer->bgUniforms[background->multipalette ? 1 : 0]; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); @@ -1106,17 +1196,17 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(0, 1, y); - glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(2, 0); - glUniform1i(3, 1); - glUniform1i(4, background->screenBase); - glUniform1i(5, background->charBase); - glUniform1i(6, background->size); - glUniform2i(7, background->x, yBase - y); - glUniform4i(8, (background->priority << 3) + (background->index << 1) + 1, - background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); + glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); + glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); + glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); + glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); + glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); + glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, + background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), + renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); @@ -1127,6 +1217,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + const GLuint* uniforms = renderer->bgUniforms[background->overflow ? 2 : 3]; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); @@ -1135,37 +1226,37 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(0, 1, y); - glUniform2i(1, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(2, 0); - glUniform1i(3, 1); - glUniform1i(4, background->screenBase); - glUniform1i(5, background->charBase); - glUniform1i(6, background->size); - glUniform4i(7, (background->priority << 3) + (background->index << 1) + 1, + glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); + glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); + glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); + glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); + glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); if (renderer->scale > 1) { - glUniform2iv(8, 4, (GLint[]) { + glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[1].sx, background->affine[1].sy, background->affine[2].sx, background->affine[2].sy, background->affine[3].sx, background->affine[3].sy, }); - glUniform2iv(12, 4, (GLint[]) { + glUniform2iv(uniforms[GBA_GL_BG_TRANSFORM], 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[1].dx, background->affine[1].dy, background->affine[2].dx, background->affine[2].dy, background->affine[3].dx, background->affine[3].dy, }); } else { - glUniform2iv(8, 4, (GLint[]) { + glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, background->affine[0].sx, background->affine[0].sy, }); - glUniform2iv(12, 4, (GLint[]) { + glUniform2iv(uniforms[GBA_GL_BG_TRANSFORM], 4, (GLint[]) { background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, background->affine[0].dx, background->affine[0].dy, From 2752c98b17a2d0e4fdb6a1b2a456bf5bb2968aa5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 09:54:54 -0700 Subject: [PATCH 208/429] GBA Video: GL compatibility fixes --- src/gba/renderers/gl.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 33a523b20..d266417ab 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -52,10 +52,10 @@ static const GLchar* const _gl3Header = "#version 130\n"; static const char* const _vertexShader = - "attribute vec2 position;\n" + "in vec2 position;\n" "uniform ivec2 loc;\n" "uniform ivec2 maxPos;\n" - "varying vec2 texCoord;\n" + "out vec2 texCoord;\n" "void main() {\n" " vec2 local = vec2(position.x, float(position.y * loc.x + loc.y) / abs(maxPos.y));\n" @@ -104,7 +104,7 @@ const static struct GBAVideoGLUniform _uniformsMode0[] = { }; static const char* const _renderMode0 = - "varying vec2 texCoord;\n" + "in vec2 texCoord;\n" "uniform sampler2D vram;\n" "uniform sampler2D palette;\n" "uniform int screenBase;\n" @@ -170,7 +170,7 @@ const static struct GBAVideoGLUniform _uniformsMode2[] = { }; static const char* const _renderMode2 = - "varying vec2 texCoord;\n" + "in vec2 texCoord;\n" "uniform sampler2D vram;\n" "uniform sampler2D palette;\n" "uniform int screenBase;\n" @@ -236,7 +236,7 @@ const static struct GBAVideoGLUniform _uniformsObj[] = { }; static const char* const _renderObj = - "varying vec2 texCoord;\n" + "in vec2 texCoord;\n" "uniform sampler2D vram;\n" "uniform sampler2D palette;\n" "uniform int charBase;\n" @@ -275,7 +275,7 @@ const static struct GBAVideoGLUniform _uniformsComposite[] = { }; static const char* const _composite = - "varying vec2 texCoord;\n" + "in vec2 texCoord;\n" "uniform int scale;\n" "uniform int layerId\n;" "uniform sampler2D layer;\n" @@ -333,13 +333,14 @@ const static struct GBAVideoGLUniform _uniformsFinalize[] = { }; static const char* const _finalize = - "varying vec2 texCoord;\n" + "in vec2 texCoord;\n" "uniform int scale;\n" "uniform sampler2D layer;\n" "uniform sampler2D layerFlags;\n" "uniform sampler2D oldLayer;\n" "uniform sampler2D oldFlags;\n" "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + "out vec4 color;\n" "void main() {\n" " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" @@ -356,7 +357,7 @@ static const char* const _finalize = " } else if ((inflags.y & 13) == 13) {\n" " pix -= pix * inflags.z / 16.;\n" " }\n" - " gl_FragColor = pix;\n" + " color = pix;\n" "}"; static const GLint _vertices[] = { From 49a9da3e5ca5e414d58a2f15920d1349c01124c4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 10:23:09 -0700 Subject: [PATCH 209/429] GBA Video: GL OBJWIN --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index c5a09f24a..435c13c71 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -103,6 +103,7 @@ enum { GBA_GL_OBJ_INFLAGS, GBA_GL_OBJ_TRANSFORM, GBA_GL_OBJ_DIMS, + GBA_GL_OBJ_OBJWIN, GBA_GL_COMPOSITE_SCALE = 2, GBA_GL_COMPOSITE_LAYERID, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index d266417ab..ca133d81b 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -232,6 +232,7 @@ const static struct GBAVideoGLUniform _uniformsObj[] = { { "inflags", GBA_GL_OBJ_INFLAGS, }, { "transform", GBA_GL_OBJ_TRANSFORM, }, { "dims", GBA_GL_OBJ_DIMS, }, + { "objwin", GBA_GL_OBJ_OBJWIN, }, { 0 } }; @@ -245,8 +246,10 @@ static const char* const _renderObj = "uniform ivec4 inflags;\n" "uniform mat2x2 transform;\n" "uniform ivec4 dims;\n" + "uniform vec3 objwin;\n" "out vec4 color;\n" "out vec4 flags;\n" + "out vec2 window;\n" "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -256,8 +259,13 @@ static const char* const _renderObj = " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" " discard;\n" " }\n" - " color = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" + " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" + " if (objwin.x > 0) {\n" + " pix.a = 0;\n" + " }\n" + " color = pix;\n" " flags = inflags / flagCoeff;\n" + " window = objwin.yz;\n" "}"; const static struct GBAVideoGLUniform _uniformsComposite[] = { @@ -542,10 +550,12 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); _lookupUniforms(glRenderer->objProgram[0], glRenderer->objUniforms[0], _uniformsObj); + glBindFragDataLocation(glRenderer->objProgram[0], 2, "window"); shaderBuffer[2] = _renderTile256; _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); _lookupUniforms(glRenderer->objProgram[1], glRenderer->objUniforms[1], _uniformsObj); + glBindFragDataLocation(glRenderer->objProgram[1], 2, "window"); shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); @@ -879,7 +889,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstAffine = -1; } - int spriteLayers = 0; if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { if (glRenderer->oamDirty) { glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); @@ -893,7 +902,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } GBAVideoGLRendererDrawSprite(glRenderer, &sprite->obj, y, sprite->y); - spriteLayers |= 1 << GBAObjAttributesCGetPriority(sprite->obj.c); } } @@ -1175,7 +1183,14 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); glEnableVertexAttribArray(0); - glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { + int window = ~renderer->objwin & 0xFF; + glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f); + glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); + } else { + glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } From 8450417086c5b70904f93f2db720456d54c9cfeb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 13:02:36 -0700 Subject: [PATCH 210/429] Core: Improve OpenGL integration, update Qt to use improvements --- CMakeLists.txt | 22 +++++++-- include/mgba/core/core.h | 1 + include/mgba/core/interface.h | 4 ++ include/mgba/internal/gba/renderers/gl.h | 9 +++- src/gb/core.c | 9 ++++ src/gba/core.c | 39 ++++++++++++++- src/gba/renderers/gl.c | 49 +++++++++++++------ src/platform/qt/CMakeLists.txt | 15 +----- src/platform/qt/CoreController.cpp | 60 +++++++++++++++-------- src/platform/qt/CoreController.h | 9 ++++ src/platform/qt/Display.h | 1 + src/platform/qt/DisplayGL.cpp | 61 +++++++++++++++++------- src/platform/qt/DisplayGL.h | 3 ++ src/platform/qt/Window.cpp | 15 +++++- src/platform/sdl/CMakeLists.txt | 5 +- src/platform/sdl/gles2-sdl.c | 4 +- tools/sanitize-deb.sh | 2 + 17 files changed, 228 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63171dfd4..7b497822d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,7 @@ if(NOT LIBMGBA_ONLY) set(BUILD_SHARED ON CACHE BOOL "Build a shared library") set(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro or OpenEmu cores)") set(BUILD_GL ON CACHE BOOL "Build with OpenGL") - set(BUILD_GLES2 OFF CACHE BOOL "Build with OpenGL|ES 2") + set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2") set(BUILD_GLES3 OFF CACHE BOOL "Build with OpenGL|ES 3") set(USE_EPOXY ON CACHE STRING "Build with libepoxy") set(DISABLE_DEPS OFF CACHE BOOL "Build without dependencies") @@ -447,7 +447,7 @@ set(FEATURE_DEFINES) set(FEATURE_FLAGS) set(FEATURES) set(ENABLES) -if(CMAKE_SYSTEM_NAME MATCHES .*BSD) +if(CMAKE_SYSTEM_NAME MATCHES ".*BSD|DragonFly") set(LIBEDIT_LIBRARIES -ledit) if (CMAKE_SYSTEM_NAME STREQUAL OpenBSD) list(APPEND LIBEDIT_LIBRARIES -ltermcap) @@ -462,9 +462,9 @@ if(BUILD_GL) endif() endif() if(NOT BUILD_GL) - set(OPENGLE_LIBRARY "" CACHE PATH "" FORCE) + set(OPENGL_LIBRARY "" CACHE PATH "" FORCE) endif() -if(BUILD_GLES2 AND NOT BUILD_RASPI) +if(BUILD_GLES2 AND NOT BUILD_RASPI AND NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|Darwin|Linux|.*BSD|DragonFly|Haiku)$") find_path(OPENGLES2_INCLUDE_DIR NAMES GLES2/gl2.h) find_library(OPENGLES2_LIBRARY NAMES GLESv2 GLESv2_CM) if(NOT OPENGLES2_INCLUDE_DIR OR NOT OPENGLES2_LIBRARY) @@ -474,6 +474,16 @@ endif() 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 OS_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 OS_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) @@ -733,6 +743,10 @@ if(USE_EPOXY) link_directories(${EPOXY_LIBRARY_DIRS}) set(OPENGLES2_LIBRARY ${EPOXY_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libepoxy0") +elseif(BUILD_GL) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgl1|libgles2") +elseif(BUILD_GLES2) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgles2") endif() if(USE_SQLITE3) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 124b02411..9cad7a3e8 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -64,6 +64,7 @@ struct mCore { void (*deinit)(struct mCore*); enum mPlatform (*platform)(const struct mCore*); + bool (*supportsFeature)(const struct mCore*, enum mCoreFeature); void (*setSync)(struct mCore*, struct mCoreSync*); void (*loadConfig)(struct mCore*, const struct mCoreConfig*); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 2e9ff63a7..51ba6447f 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -80,6 +80,10 @@ enum mColorFormat { mCOLOR_ANY = -1 }; +enum mCoreFeature { + mCORE_FEATURE_OPENGL = 1, +}; + struct mCoreCallbacks { void* context; void (*videoFrameStarted)(void* context); diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 435c13c71..6ac96a50e 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -16,6 +16,8 @@ CXX_GUARD_START #include #include +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) + #ifdef USE_EPOXY #include #elif defined(BUILD_GL) @@ -27,7 +29,7 @@ CXX_GUARD_START #include #endif #else -#include +#include #endif struct GBAVideoGLAffine { @@ -137,6 +139,9 @@ struct GBAVideoGLRenderer { GLuint outputTex; +#ifdef BUILD_GLES3 + uint16_t shadowPalette[512]; +#endif GLuint paletteTex; bool paletteDirty; @@ -182,6 +187,8 @@ struct GBAVideoGLRenderer { void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer); +#endif + CXX_GUARD_END #endif \ No newline at end of file diff --git a/src/gb/core.c b/src/gb/core.c index 20e383393..264f29bf1 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -138,6 +138,14 @@ static enum mPlatform _GBCorePlatform(const struct mCore* core) { return PLATFORM_GB; } +static bool _GBCoreSupportsFeature(const struct mCore* core, enum mCoreFeature feature) { + UNUSED(core); + switch (feature) { + default: + return false; + } +} + static void _GBCoreSetSync(struct mCore* core, struct mCoreSync* sync) { struct GB* gb = core->board; gb->sync = sync; @@ -888,6 +896,7 @@ struct mCore* GBCoreCreate(void) { core->init = _GBCoreInit; core->deinit = _GBCoreDeinit; core->platform = _GBCorePlatform; + core->supportsFeature = _GBCoreSupportsFeature; core->setSync = _GBCoreSetSync; core->loadConfig = _GBCoreLoadConfig; core->desiredVideoDimensions = _GBCoreDesiredVideoDimensions; diff --git a/src/gba/core.c b/src/gba/core.c index 5284a04b9..839404d03 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -17,7 +17,9 @@ #ifndef DISABLE_THREADING #include #endif +#ifdef BUILD_GLES2 #include +#endif #include #include #include @@ -124,7 +126,9 @@ struct mVideoLogContext; struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; +#ifdef BUILD_GLES2 struct GBAVideoGLRenderer glRenderer; +#endif struct GBAVideoProxyRenderer proxyRenderer; struct mVideoLogContext* logContext; struct mCoreCallbacks logCallbacks; @@ -170,8 +174,10 @@ static bool _GBACoreInit(struct mCore* core) { GBAVideoSoftwareRendererCreate(&gbacore->renderer); gbacore->renderer.outputBuffer = NULL; +#ifdef BUILD_GLES2 GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->glRenderer.outputTex = -1; +#endif #ifndef DISABLE_THREADING mVideoThreadProxyCreate(&gbacore->threadProxy); @@ -212,6 +218,20 @@ static enum mPlatform _GBACorePlatform(const struct mCore* core) { return PLATFORM_GBA; } +static bool _GBACoreSupportsFeature(const struct mCore* core, enum mCoreFeature feature) { + UNUSED(core); + switch (feature) { + case mCORE_FEATURE_OPENGL: +#ifdef BUILD_GLES2 + return true; +#else + return false; +#endif + default: + return false; + } +} + static void _GBACoreSetSync(struct mCore* core, struct mCoreSync* sync) { struct GBA* gba = core->board; gba->sync = sync; @@ -261,9 +281,12 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con } static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { +#ifdef BUILD_GLES2 struct GBACore* gbacore = (struct GBACore*) core; - int fakeBool; int scale = gbacore->glRenderer.scale; +#else + int scale = 1; +#endif *width = GBA_VIDEO_HORIZONTAL_PIXELS * scale; *height = GBA_VIDEO_VERTICAL_PIXELS * scale; @@ -277,8 +300,13 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s } static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { +#ifdef BUILD_GLES2 struct GBACore* gbacore = (struct GBACore*) core; gbacore->glRenderer.outputTex = texid; +#else + UNUSED(core); + UNUSED(texid); +#endif } static void _GBACoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) { @@ -403,16 +431,22 @@ static void _GBACoreChecksum(const struct mCore* core, void* data, enum mCoreChe static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; - if (gbacore->renderer.outputBuffer || gbacore->glRenderer.outputTex != (unsigned) -1) { + if (gbacore->renderer.outputBuffer +#ifdef BUILD_GLES2 + || gbacore->glRenderer.outputTex != (unsigned) -1 +#endif + ) { struct GBAVideoRenderer* renderer; if (gbacore->renderer.outputBuffer) { renderer = &gbacore->renderer.d; } int fakeBool; +#ifdef BUILD_GLES2 if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { renderer = &gbacore->glRenderer.d; mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); } +#endif #ifndef DISABLE_THREADING if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { if (!core->videoLogger) { @@ -952,6 +986,7 @@ struct mCore* GBACoreCreate(void) { core->init = _GBACoreInit; core->deinit = _GBACoreDeinit; core->platform = _GBACorePlatform; + core->supportsFeature = _GBACoreSupportsFeature; core->setSync = _GBACoreSetSync; core->loadConfig = _GBACoreLoadConfig; core->desiredVideoDimensions = _GBACoreDesiredVideoDimensions; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ca133d81b..bdd065cb8 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) + #include #include #include @@ -90,7 +92,7 @@ static const char* const _renderTile256 = " return color;\n" "}"; -const static struct GBAVideoGLUniform _uniformsMode0[] = { +static const struct GBAVideoGLUniform _uniformsMode0[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "vram", GBA_GL_BG_VRAM, }, @@ -155,7 +157,7 @@ static const char* const _fetchTileNoOverflow = " return renderTile(coord);\n" "}"; -const static struct GBAVideoGLUniform _uniformsMode2[] = { +static const struct GBAVideoGLUniform _uniformsMode2[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "vram", GBA_GL_BG_VRAM, }, @@ -221,7 +223,7 @@ static const char* const _renderMode2 = " flags = inflags / flagCoeff;\n" "}"; -const static struct GBAVideoGLUniform _uniformsObj[] = { +static const struct GBAVideoGLUniform _uniformsObj[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "vram", GBA_GL_OBJ_VRAM, }, @@ -268,7 +270,7 @@ static const char* const _renderObj = " window = objwin.yz;\n" "}"; -const static struct GBAVideoGLUniform _uniformsComposite[] = { +static const struct GBAVideoGLUniform _uniformsComposite[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "scale", GBA_GL_COMPOSITE_SCALE, }, @@ -329,7 +331,7 @@ static const char* const _composite = " }\n" "}"; -const static struct GBAVideoGLUniform _uniformsFinalize[] = { +static const struct GBAVideoGLUniform _uniformsFinalize[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "scale", GBA_GL_FINALIZE_SCALE, }, @@ -413,8 +415,10 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); } glDeleteShader(fs); +#ifndef BUILD_GLES3 glBindFragDataLocation(program, 0, "color"); glBindFragDataLocation(program, 1, "flags"); +#endif } static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { @@ -550,18 +554,24 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _renderTile16; _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); _lookupUniforms(glRenderer->objProgram[0], glRenderer->objUniforms[0], _uniformsObj); +#ifndef BUILD_GLES3 glBindFragDataLocation(glRenderer->objProgram[0], 2, "window"); +#endif shaderBuffer[2] = _renderTile256; _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); _lookupUniforms(glRenderer->objProgram[1], glRenderer->objUniforms[1], _uniformsObj); +#ifndef BUILD_GLES3 glBindFragDataLocation(glRenderer->objProgram[1], 2, "window"); +#endif shaderBuffer[1] = _composite; _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); _lookupUniforms(glRenderer->compositeProgram, glRenderer->compositeUniforms, _uniformsComposite); +#ifndef BUILD_GLES3 glBindFragDataLocation(glRenderer->compositeProgram, 2, "oldColor"); glBindFragDataLocation(glRenderer->compositeProgram, 3, "oldFlags"); +#endif shaderBuffer[1] = _finalize; _compileShader(glRenderer, glRenderer->finalizeProgram, shaderBuffer, 2, vs, log); @@ -585,7 +595,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteProgram(glRenderer->bgProgram[3]); glDeleteProgram(glRenderer->bgProgram[4]); glDeleteProgram(glRenderer->bgProgram[5]); - glDeleteProgram(glRenderer->bgProgram[6]); glDeleteProgram(glRenderer->objProgram[0]); glDeleteProgram(glRenderer->objProgram[1]); glDeleteProgram(glRenderer->compositeProgram); @@ -611,9 +620,13 @@ void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) } void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; +#ifdef BUILD_GLES3 + glRenderer->shadowPalette[address >> 1] = (value & 0x3F) | ((value & 0x7FE0) << 1); +#else UNUSED(address); UNUSED(value); - struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; +#endif glRenderer->paletteDirty = true; } @@ -822,7 +835,11 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; if (glRenderer->paletteDirty) { glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); +#ifdef BUILD_GLES3 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_6_5, glRenderer->shadowPalette); +#else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); +#endif glRenderer->paletteDirty = false; } int i; @@ -841,33 +858,33 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); glEnable(GL_SCISSOR_TEST); glScissor(0, y * glRenderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, glRenderer->scale); - glDrawBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glClear(GL_COLOR_BUFFER_BIT); if (y == 0) { glDisable(GL_SCISSOR_TEST); - glDrawBuffer(GL_COLOR_ATTACHMENT1); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, (glRenderer->blendEffect == BLEND_ALPHA ? glRenderer->blda : glRenderer->bldy) / 16.f, glRenderer->bldb / 16.f); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0, 0, 0, 0); - glDrawBuffer(GL_COLOR_ATTACHMENT3); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT3 }); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); - glDrawBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffer(GL_COLOR_ATTACHMENT1); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); for (i = 0; i < 4; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); - glDrawBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffer(GL_COLOR_ATTACHMENT1); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); } - glDrawBuffer(GL_COLOR_ATTACHMENT0); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glEnable(GL_SCISSOR_TEST); } glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1310,3 +1327,5 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { } glBindFramebuffer(GL_FRAMEBUFFER, 0); } + +#endif diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 9b3eb63f0..98a0a9e5a 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -47,17 +47,6 @@ if(APPLE) endif() endif() -if(BUILD_GL) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c) - if(NOT WIN32 OR USE_EPOXY) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c) - endif() -endif() - -if(BUILD_GLES2) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c) -endif() - get_target_property(QT_TYPE Qt5::Core TYPE) if(QT_TYPE STREQUAL STATIC_LIBRARY) set(QT_STATIC ON) @@ -245,7 +234,7 @@ if(NOT DEFINED DATADIR) set(DATADIR ${CMAKE_INSTALL_DATADIR}/${BINARY_NAME}) endif() endif() -if(BUILD_GL OR BUILD_GLES2) +if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) install(DIRECTORY ${CMAKE_SOURCE_DIR}/res/shaders DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) endif() install(FILES ${CMAKE_SOURCE_DIR}/res/nointro.dat DESTINATION ${DATADIR} COMPONENT ${BINARY_NAME}-qt) @@ -291,7 +280,7 @@ add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/res/info.plist.in COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES};${OS_DEFINES};${QT_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") list(APPEND QT_LIBRARIES Qt5::Widgets) -if(BUILD_GL OR BUILD_GLES2) +if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) list(APPEND QT_LIBRARIES Qt5::OpenGL ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY}) endif() if(QT_STATIC) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 37ea45cac..2c6ec39f7 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -40,16 +40,6 @@ CoreController::CoreController(mCore* core, QObject* parent) m_threadContext.core = core; m_threadContext.userData = this; - QSize size(1024, 2048); - m_buffers[0].resize(size.width() * size.height() * sizeof(color_t)); - m_buffers[1].resize(size.width() * size.height() * sizeof(color_t)); - m_buffers[0].fill(0xFF); - m_buffers[1].fill(0xFF); - m_activeBuffer = &m_buffers[0]; - m_completeBuffer = m_buffers[0]; - - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), size.width()); - m_resetActions.append([this]() { if (m_autoload) { mCoreLoadState(m_threadContext.core, 0, m_loadStateFlags); @@ -91,8 +81,10 @@ CoreController::CoreController(mCore* core, QObject* parent) controller->m_resetActions.clear(); - controller->m_activeBuffer = &controller->m_buffers[0]; - context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer->data()), controller->screenDimensions().width()); + if (!controller->m_hwaccel) { + controller->m_activeBuffer = &controller->m_buffers[0]; + context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer->data()), controller->screenDimensions().width()); + } controller->finishFrame(); }; @@ -211,6 +203,9 @@ CoreController::~CoreController() { const color_t* CoreController::drawContext() { QMutexLocker locker(&m_mutex); + if (m_hwaccel) { + return nullptr; + } return reinterpret_cast(m_completeBuffer.constData()); } @@ -340,6 +335,18 @@ void CoreController::setLogger(LogController* logger) { } void CoreController::start() { + if (!m_hwaccel) { + QSize size(1024, 2048); + m_buffers[0].resize(size.width() * size.height() * sizeof(color_t)); + m_buffers[1].resize(size.width() * size.height() * sizeof(color_t)); + m_buffers[0].fill(0xFF); + m_buffers[1].fill(0xFF); + m_activeBuffer = &m_buffers[0]; + m_completeBuffer = m_buffers[0]; + + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), size.width()); + } + if (!m_patched) { mCoreAutoloadPatch(m_threadContext.core); } @@ -800,6 +807,16 @@ void CoreController::endVideoLog() { m_vl = nullptr; } +void CoreController::setFramebufferHandle(int fb) { + Interrupter interrupter(this); + if (fb < 0) { + m_hwaccel = false; + } else { + m_threadContext.core->setVideoGLTex(m_threadContext.core, fb); + m_hwaccel = true; + } +} + void CoreController::updateKeys() { int activeKeys = m_activeKeys | updateAutofire() | m_inputController->pollEvents(); m_threadContext.core->setKeys(m_threadContext.core, activeKeys); @@ -823,17 +840,18 @@ int CoreController::updateAutofire() { void CoreController::finishFrame() { QMutexLocker locker(&m_mutex); - memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); + if (!m_hwaccel) { + memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); - // TODO: Generalize this to triple buffering? - m_activeBuffer = &m_buffers[0]; - if (m_activeBuffer == m_completeBuffer) { - m_activeBuffer = &m_buffers[1]; + // TODO: Generalize this to triple buffering? + m_activeBuffer = &m_buffers[0]; + if (m_activeBuffer == m_completeBuffer) { + m_activeBuffer = &m_buffers[1]; + } + // Copy contents to avoid issues when doing frameskip + memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), screenDimensions().width()); } - // Copy contents to avoid issues when doing frameskip - memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), screenDimensions().width()); - for (auto& action : m_frameActions) { action(); } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index dbcec9cf3..e31602117 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -46,6 +46,10 @@ public: static const bool VIDEO_SYNC = false; static const bool AUDIO_SYNC = true; + enum class Feature { + OPENGL = mCORE_FEATURE_OPENGL, + }; + class Interrupter { public: Interrupter(CoreController*, bool fromThread = false); @@ -69,6 +73,8 @@ public: mPlatform platform() const; QSize screenDimensions() const; + bool supportsFeature(Feature feature) const { return m_threadContext.core->supportsFeature(m_threadContext.core, static_cast(feature)); } + bool hardwareAccelerated() const { return m_hwaccel; } void loadConfig(ConfigController*); @@ -154,6 +160,8 @@ public slots: void startVideoLog(const QString& path); void endVideoLog(); + void setFramebufferHandle(int fb); + signals: void started(); void paused(); @@ -188,6 +196,7 @@ private: QByteArray m_buffers[2]; QByteArray* m_activeBuffer; QByteArray m_completeBuffer; + bool m_hwaccel = false; std::unique_ptr m_cacheSet; std::unique_ptr m_override; diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index de8c03648..f00bdb2b1 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -49,6 +49,7 @@ public: virtual bool supportsShaders() const = 0; virtual VideoShader* shaders() = 0; virtual VideoProxy* videoProxy() { return nullptr; } + virtual int framebufferHandle() { return -1; } signals: void showCursor(); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 8ff657016..6a3afecd6 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -18,7 +18,7 @@ #ifdef BUILD_GL #include "platform/opengl/gl.h" #endif -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 #include "platform/opengl/gles2.h" #ifdef _WIN32 #include @@ -195,6 +195,10 @@ VideoProxy* DisplayGL::videoProxy() { return nullptr; } +int DisplayGL::framebufferHandle() { + return m_painter->glTex(); +} + PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) : m_gl(parent) , m_videoProxy(proxy) @@ -202,7 +206,7 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) #ifdef BUILD_GL mGLContext* glBackend; #endif -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 mGLES2Context* gl2Backend; #endif @@ -213,7 +217,7 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 if (extensions.contains("GL_ARB_framebuffer_object") && majorVersion >= 2) { gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); @@ -239,7 +243,7 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) }; m_backend->init(m_backend, reinterpret_cast(m_gl->winId())); -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 if (m_supportsShaders) { m_shader.preprocessShader = static_cast(&reinterpret_cast(m_backend)->initialShader); } @@ -266,7 +270,7 @@ PainterGL::~PainterGL() { #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 if (m_shader.passes) { mGLES2ShaderFree(&m_shader); } @@ -339,7 +343,7 @@ void PainterGL::start() { epoxy_handle_external_wglMakeCurrent(); #endif -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 if (m_supportsShaders && m_shader.passes) { mGLES2ShaderAttach(reinterpret_cast(m_backend), static_cast(m_shader.passes), m_shader.nPasses); } @@ -422,14 +426,16 @@ void PainterGL::performDraw() { void PainterGL::enqueue(const uint32_t* backing) { m_mutex.lock(); - uint32_t* buffer; - if (m_free.isEmpty()) { - buffer = m_queue.dequeue(); - } else { - buffer = m_free.takeLast(); + uint32_t* buffer = nullptr; + if (backing) { + if (m_free.isEmpty()) { + buffer = m_queue.dequeue(); + } else { + buffer = m_free.takeLast(); + } + QSize size = m_context->screenDimensions(); + memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); } - QSize size = m_context->screenDimensions(); - memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); m_queue.enqueue(buffer); m_mutex.unlock(); } @@ -441,8 +447,10 @@ void PainterGL::dequeue() { return; } uint32_t* buffer = m_queue.dequeue(); - m_backend->postFrame(m_backend, buffer); - m_free.append(buffer); + if (buffer) { + m_backend->postFrame(m_backend, buffer); + m_free.append(buffer); + } m_mutex.unlock(); } @@ -451,7 +459,9 @@ void PainterGL::dequeueAll() { m_mutex.lock(); while (!m_queue.isEmpty()) { buffer = m_queue.dequeue(); - m_free.append(buffer); + if (buffer) { + m_free.append(buffer); + } } if (buffer) { m_backend->postFrame(m_backend, buffer); @@ -464,7 +474,7 @@ void PainterGL::setShaders(struct VDir* dir) { return; } if (!m_active) { -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 m_gl->makeCurrent(); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); @@ -489,7 +499,7 @@ void PainterGL::clearShaders() { return; } if (!m_active) { -#if !defined(_WIN32) || defined(USE_EPOXY) +#ifdef BUILD_GLES2 m_gl->makeCurrent(); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); @@ -509,4 +519,19 @@ VideoShader* PainterGL::shaders() { return &m_shader; } +int PainterGL::glTex() { +#ifdef BUILD_GLES2 + if (supportsShaders()) { + mGLES2Context* gl2Backend = reinterpret_cast(m_backend); + return gl2Backend->tex; + } +#endif +#ifdef BUILD_GL + mGLContext* glBackend = reinterpret_cast(m_backend); + return glBackend->tex; +#else + return -1; +#endif +} + #endif diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 8ef6f9e1c..990269fd0 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -52,6 +52,7 @@ public: bool supportsShaders() const override; VideoShader* shaders() override; VideoProxy* videoProxy() override; + int framebufferHandle() override; public slots: void stopDrawing() override; @@ -111,6 +112,8 @@ public slots: void clearShaders(); VideoShader* shaders(); + int glTex(); + private: void performDraw(); void dequeue(); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 379f5cecb..b0971ddc3 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -851,6 +851,10 @@ void Window::unimplementedBiosCall(int call) { void Window::reloadDisplayDriver() { if (m_controller) { + if (m_controller->hardwareAccelerated()) { + mustRestart(); + return; + } m_display->stopDrawing(); detachWidget(m_display.get()); } @@ -1715,8 +1719,15 @@ void Window::setController(CoreController* controller, const QString& fname) { reloadDisplayDriver(); } - if (m_display->videoProxy()) { - m_display->videoProxy()->attach(controller); + if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && controller->supportsFeature(CoreController::Feature::OPENGL)) { + if (m_display->videoProxy()) { + m_display->videoProxy()->attach(controller); + } + + int fb = m_display->framebufferHandle(); + if (fb >= 0) { + controller->setFramebufferHandle(fb); + } } m_controller = std::shared_ptr(controller); diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index aa4c6cca5..36e73b686 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -77,12 +77,11 @@ if(BUILD_PANDORA) else() if(BUILD_GL) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) - include_directories(${OPENGL_INCLUDE_DIR}) + list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) endif() if(BUILD_GLES2) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gles2-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) + list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() if(NOT BUILD_GL AND NOT BUILD_GLES2) diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 6cc046769..675a1139c 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -35,7 +35,9 @@ bool mSDLGLES2Init(struct mSDLRenderer* renderer) { #endif size_t size = renderer->width * renderer->height * BYTES_PER_PIXEL; -#ifndef __APPLE__ +#ifdef _WIN32 + renderer->outputBuffer = _aligned_malloc(size, 16); +#elif !defined(__APPLE__) renderer->outputBuffer = memalign(16, size); #else posix_memalign((void**) &renderer->outputBuffer, 16, size); diff --git a/tools/sanitize-deb.sh b/tools/sanitize-deb.sh index d400f0489..df00f11dd 100755 --- a/tools/sanitize-deb.sh +++ b/tools/sanitize-deb.sh @@ -31,6 +31,7 @@ while [ $# -gt 0 ]; do rmdep libav rmdep libedit rmdep libelf + rmdep libgl rmdep libpng rmdep libzip rmdep libmagickwand @@ -45,6 +46,7 @@ while [ $# -gt 0 ]; do rmdep libav rmdep libedit rmdep libelf + rmdep libgl rmdep libpng rmdep qt rmdep libzip From bdc4e2837d7f82189e2342851ef3c67340df0741 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 13:56:01 -0700 Subject: [PATCH 211/429] Qt: Add settings for enhancements --- src/platform/qt/SettingsView.cpp | 17 +++++++ src/platform/qt/SettingsView.h | 1 + src/platform/qt/SettingsView.ui | 83 +++++++++++++++++++++++++++++--- src/platform/qt/Window.cpp | 1 + 4 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index c892efc63..3157ec6d3 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -401,6 +401,7 @@ void SettingsView::updateConfig() { saveSetting("logToStdout", m_ui.logToStdout); saveSetting("logFile", m_ui.logFile); saveSetting("useDiscordPresence", m_ui.useDiscordPresence); + saveSetting("audioHle", m_ui.audioHle); if (m_ui.fastForwardUnbounded->isChecked()) { saveSetting("fastForwardRatio", "-1"); @@ -465,6 +466,14 @@ void SettingsView::updateConfig() { emit languageChanged(); } + int videoScale = m_controller->getOption("videoScale").toInt(); + int hwaccelVideo = m_controller->getOption("hwaccelVideo").toInt(); + if (videoScale != m_ui.videoScale->value() || hwaccelVideo != m_ui.hwaccelVideo->currentIndex()) { + emit videoRendererChanged(); + } + saveSetting("videoScale", m_ui.videoScale); + saveSetting("hwaccelVideo", m_ui.hwaccelVideo->currentIndex()); + m_logModel.save(m_controller); m_logModel.logger()->setLogFile(m_ui.logFile->text()); m_logModel.logger()->logToFile(m_ui.logToFile->isChecked()); @@ -541,6 +550,8 @@ void SettingsView::reloadConfig() { loadSetting("logToStdout", m_ui.logToStdout); loadSetting("logFile", m_ui.logFile); loadSetting("useDiscordPresence", m_ui.useDiscordPresence); + loadSetting("audioHle", m_ui.audioHle); + loadSetting("videoScale", m_ui.videoScale); m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt()); @@ -604,6 +615,12 @@ void SettingsView::reloadConfig() { m_ui.cgbModel->setCurrentIndex(index >= 0 ? index : 0); } #endif + + int hwaccelVideo = m_controller->getOption("hwaccelVideo", 1).toInt(); + if (hwaccelVideo < 1) { + hwaccelVideo = 1; + } + m_ui.hwaccelVideo->setCurrentIndex(hwaccelVideo); } void SettingsView::saveSetting(const char* key, const QAbstractButton* field) { diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index b04d21805..0ea562807 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -40,6 +40,7 @@ signals: void displayDriverChanged(); void cameraDriverChanged(); void cameraChanged(const QByteArray&); + void videoRendererChanged(); void pathsChanged(); void languageChanged(); void libraryCleared(); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index ea9cab924..15d7893f9 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -6,8 +6,8 @@ 0 0 - 588 - 488 + 790 + 686 @@ -33,14 +33,14 @@ - + 0 0 - 140 + 200 16777215 @@ -62,6 +62,11 @@ Emulation + + + Enhancements + + BIOS @@ -844,6 +849,70 @@ + + + + + + Video renderer: + + + + + + + + Software + + + + + OpenGL + + + + + + + + OpenGL enhancements + + + + + + High-resolution scale: + + + + + + + × + + + 1 + + + 13 + + + + + + + + + + false + + + XQ GBA audio (experimental) + + + + + @@ -1221,12 +1290,12 @@ - - 77 - 0 + + 77 + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index b0971ddc3..15a13d3b9 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -460,6 +460,7 @@ void Window::openSettingsWindow() { connect(settingsWindow, &SettingsView::audioDriverChanged, this, &Window::reloadAudioDriver); connect(settingsWindow, &SettingsView::cameraDriverChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::cameraChanged, &m_inputController, &InputController::setCamera); + connect(settingsWindow, &SettingsView::videoRendererChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig); #ifdef USE_SQLITE3 From 945bc8fffe99d2cca5bfc646cffcb8c19fef52bb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 16:56:36 -0700 Subject: [PATCH 212/429] CMake: Fix Windows build issues --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b497822d..d25191081 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -476,12 +476,12 @@ if(NOT BUILD_GLES2) endif() if(BUILD_GL) list(APPEND OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/opengl/gl.c) - list(APPEND OS_LIB ${OPENGL_LIBRARY}) + 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 OS_LIB ${OPENGLES2_LIBRARY}) + list(APPEND DEPENDENCY_LIB ${OPENGLES2_LIBRARY}) include_directories(${OPENGLES2_INCLUDE_DIR}) endif() if(BUILD_GLES3) @@ -737,11 +737,13 @@ 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) add_definitions(-DBUILD_GL -DBUILD_GLES2) list(APPEND FEATURES EPOXY) include_directories(AFTER ${EPOXY_INCLUDE_DIRS}) link_directories(${EPOXY_LIBRARY_DIRS}) set(OPENGLES2_LIBRARY ${EPOXY_LIBRARIES}) + list(APPEND DEPENDENCY_LIB ${EPOXY_LIBRARIES}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libepoxy0") elseif(BUILD_GL) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgl1|libgles2") From 24929909f28df24461e62f36e80f0a60675facd3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 17:30:32 -0700 Subject: [PATCH 213/429] Qt: Reload GL context on main thread after shutting down painter --- src/platform/qt/DisplayGL.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 6a3afecd6..a5f4129e9 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -99,6 +99,11 @@ void DisplayGL::stopDrawing() { QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection); m_drawThread->exit(); m_drawThread = nullptr; + + m_gl->context()->makeCurrent(); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif } m_context.reset(); } From 1baa9287f34855f9eaceab89eb7703cb928f5599 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 18:04:51 -0700 Subject: [PATCH 214/429] Qt: Reduce flickering by resizing less often --- src/platform/qt/DisplayGL.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index a5f4129e9..2960e005f 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -316,6 +316,12 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) { void PainterGL::resize(const QSize& size) { m_size = size; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + float r = m_gl->devicePixelRatioF(); +#else + float r = m_gl->devicePixelRatio(); +#endif + m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); if (m_started && !m_active) { forceDraw(); } @@ -323,16 +329,12 @@ void PainterGL::resize(const QSize& size) { void PainterGL::lockAspectRatio(bool lock) { m_backend->lockAspectRatio = lock; - if (m_started && !m_active) { - forceDraw(); - } + resize(m_size); } void PainterGL::lockIntegerScaling(bool lock) { m_backend->lockIntegerScaling = lock; - if (m_started && !m_active) { - forceDraw(); - } + resize(m_size); } void PainterGL::filter(bool filter) { @@ -416,12 +418,6 @@ void PainterGL::unpause() { void PainterGL::performDraw() { m_painter.beginNativePainting(); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - float r = m_gl->devicePixelRatioF(); -#else - float r = m_gl->devicePixelRatio(); -#endif - m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); m_backend->drawFrame(m_backend); m_painter.endNativePainting(); if (m_messagePainter) { From 4bd788f7153ced2403def6478af29da7d0e3cbd5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 20:25:27 -0700 Subject: [PATCH 215/429] Qt: Port to QOpenGLWidget --- src/platform/qt/Display.cpp | 4 ++- src/platform/qt/DisplayGL.cpp | 63 ++++++++++++++++++----------------- src/platform/qt/DisplayGL.h | 23 +++++-------- src/platform/qt/main.cpp | 10 ++++++ 4 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index fd91993bd..ee754c4f0 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -18,13 +18,15 @@ Display::Driver Display::s_driver = Display::Driver::QT; Display* Display::create(QWidget* parent) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY) - QGLFormat format(QGLFormat(QGL::Rgba | QGL::DoubleBuffer)); + QSurfaceFormat format; format.setSwapInterval(1); + format.setSwapBehavior(QSurfaceFormat::TripleBuffer); #endif switch (s_driver) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY) case Driver::OPENGL: + format.setVersion(3, 0); return new DisplayGL(format, parent); #endif #ifdef BUILD_GL diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 2960e005f..81d01f960 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -10,8 +10,11 @@ #include "CoreController.h" #include +#include +#include #include #include +#include #include #include @@ -27,16 +30,17 @@ using namespace QGBA; -DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) +DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) : Display(parent) , m_gl(nullptr) { // This can spontaneously re-enter into this->resizeEvent before creation is done, so we // need to make sure it's initialized to nullptr before we assign the new object to it - m_gl = new EmptyGLWidget(format, this); - m_painter = new PainterGL(format.majorVersion() < 2 ? 1 : m_gl->format().majorVersion(), &m_videoProxy, m_gl); - m_gl->setMouseTracking(true); - m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work? + m_gl = new QOpenGLContext; + m_gl->setFormat(format); + m_gl->create(); + setAttribute(Qt::WA_NativeWindow); + m_painter = new PainterGL(&m_videoProxy, windowHandle(), m_gl); setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions connect(&m_videoProxy, &VideoProxy::dataAvailable, &m_videoProxy, &VideoProxy::processData); @@ -46,6 +50,7 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) DisplayGL::~DisplayGL() { stopDrawing(); delete m_painter; + delete m_gl; } bool DisplayGL::supportsShaders() const { @@ -71,11 +76,10 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { m_painter->setMessagePainter(messagePainter()); m_context = controller; m_painter->resize(size()); - m_gl->move(0, 0); m_drawThread = new QThread(this); m_drawThread->setObjectName("Painter Thread"); - m_gl->context()->doneCurrent(); - m_gl->context()->moveToThread(m_drawThread); + m_gl->doneCurrent(); + m_gl->moveToThread(m_drawThread); m_painter->moveToThread(m_drawThread); m_videoProxy.moveToThread(m_drawThread); connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start); @@ -100,7 +104,7 @@ void DisplayGL::stopDrawing() { m_drawThread->exit(); m_drawThread = nullptr; - m_gl->context()->makeCurrent(); + m_gl->makeCurrent(windowHandle()); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif @@ -185,9 +189,6 @@ void DisplayGL::resizeEvent(QResizeEvent* event) { } void DisplayGL::resizePainter() { - if (m_gl) { - m_gl->resize(size()); - } if (m_drawThread) { QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, size())); } @@ -204,8 +205,9 @@ int DisplayGL::framebufferHandle() { return m_painter->glTex(); } -PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) +PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent) : m_gl(parent) + , m_surface(surface) , m_videoProxy(proxy) { #ifdef BUILD_GL @@ -215,10 +217,12 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) mGLES2Context* gl2Backend; #endif - m_gl->makeCurrent(); + m_gl->makeCurrent(m_surface); + m_window = new QOpenGLPaintDevice; #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif + int majorVersion = m_gl->format().majorVersion(); QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); @@ -241,13 +245,13 @@ PainterGL::PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent) #endif m_backend->swap = [](VideoBackend* v) { PainterGL* painter = static_cast(v->user); - if (!painter->m_gl->isVisible()) { + if (!painter->m_gl->isValid()) { return; } - painter->m_gl->swapBuffers(); + painter->m_gl->swapBuffers(painter->m_gl->surface()); }; - m_backend->init(m_backend, reinterpret_cast(m_gl->winId())); + m_backend->init(m_backend, 0); #ifdef BUILD_GLES2 if (m_supportsShaders) { m_shader.preprocessShader = static_cast(&reinterpret_cast(m_backend)->initialShader); @@ -271,7 +275,7 @@ PainterGL::~PainterGL() { for (auto item : m_free) { delete[] item; } - m_gl->makeCurrent(); + m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif @@ -284,6 +288,7 @@ PainterGL::~PainterGL() { m_gl->doneCurrent(); free(m_backend); m_backend = nullptr; + delete m_window; } void PainterGL::setContext(std::shared_ptr context) { @@ -297,7 +302,7 @@ void PainterGL::resizeContext() { } if (!m_active) { - m_gl->makeCurrent(); + m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif @@ -316,11 +321,7 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) { void PainterGL::resize(const QSize& size) { m_size = size; -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - float r = m_gl->devicePixelRatioF(); -#else - float r = m_gl->devicePixelRatio(); -#endif + float r = m_surface->devicePixelRatio(); m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); if (m_started && !m_active) { forceDraw(); @@ -345,7 +346,7 @@ void PainterGL::filter(bool filter) { } void PainterGL::start() { - m_gl->makeCurrent(); + m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif @@ -368,7 +369,7 @@ void PainterGL::draw() { if (mCoreSyncWaitFrameStart(&m_context->thread()->impl->sync) || !m_queue.isEmpty()) { dequeue(); mCoreSyncWaitFrameEnd(&m_context->thread()->impl->sync); - m_painter.begin(m_gl->context()->device()); + m_painter.begin(m_window); performDraw(); m_painter.end(); m_backend->swap(m_backend); @@ -389,7 +390,7 @@ void PainterGL::draw() { } void PainterGL::forceDraw() { - m_painter.begin(m_gl->context()->device()); + m_painter.begin(m_window); performDraw(); m_painter.end(); m_backend->swap(m_backend); @@ -402,7 +403,7 @@ void PainterGL::stop() { m_backend->clear(m_backend); m_backend->swap(m_backend); m_gl->doneCurrent(); - m_gl->context()->moveToThread(m_gl->thread()); + m_gl->moveToThread(m_surface->thread()); m_context.reset(); moveToThread(m_gl->thread()); m_videoProxy->moveToThread(m_gl->thread()); @@ -474,9 +475,9 @@ void PainterGL::setShaders(struct VDir* dir) { if (!supportsShaders()) { return; } - if (!m_active) { #ifdef BUILD_GLES2 - m_gl->makeCurrent(); + if (!m_active) { + m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif @@ -501,7 +502,7 @@ void PainterGL::clearShaders() { } if (!m_active) { #ifdef BUILD_GLES2 - m_gl->makeCurrent(); + m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 990269fd0..2dbd1f2f0 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -17,9 +17,10 @@ #endif #include -#include +#include #include #include +#include #include #include @@ -29,22 +30,12 @@ namespace QGBA { -class EmptyGLWidget : public QGLWidget { -public: - EmptyGLWidget(const QGLFormat& format, QWidget* parent) : QGLWidget(format, parent) { setAutoBufferSwap(false); } - -protected: - void paintEvent(QPaintEvent* event) override { event->ignore(); } - void resizeEvent(QResizeEvent*) override {} - void mouseMoveEvent(QMouseEvent* event) override { event->ignore(); } -}; - class PainterGL; class DisplayGL : public Display { Q_OBJECT public: - DisplayGL(const QGLFormat& format, QWidget* parent = nullptr); + DisplayGL(const QSurfaceFormat& format, QWidget* parent = nullptr); ~DisplayGL(); void startDrawing(std::shared_ptr) override; @@ -75,7 +66,7 @@ private: void resizePainter(); bool m_isDrawing = false; - QGLWidget* m_gl; + QOpenGLContext* m_gl; PainterGL* m_painter; QThread* m_drawThread = nullptr; std::shared_ptr m_context; @@ -86,7 +77,7 @@ class PainterGL : public QObject { Q_OBJECT public: - PainterGL(int majorVersion, VideoProxy* proxy, QGLWidget* parent); + PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent); ~PainterGL(); void setContext(std::shared_ptr); @@ -123,7 +114,9 @@ private: QQueue m_queue; QPainter m_painter; QMutex m_mutex; - QGLWidget* m_gl; + QWindow* m_surface; + QPaintDevice* m_window; + QOpenGLContext* m_gl; bool m_active = false; bool m_started = false; std::shared_ptr m_context = nullptr; diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 9c3fa5072..e2659eae3 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -17,6 +17,10 @@ #include #include +#ifdef BUILD_GLES2 +#include +#endif + #ifdef QT_STATIC #include #ifdef Q_OS_WIN @@ -65,6 +69,12 @@ int main(int argc, char* argv[]) { QApplication::setApplicationName(projectName); QApplication::setApplicationVersion(projectVersion); +#ifdef BUILD_GLES2 + QSurfaceFormat format; + format.setVersion(3, 0); + QSurfaceFormat::setDefaultFormat(format); +#endif + GBAApp application(argc, argv, &configController); #ifndef Q_OS_MAC From ee6cd3640222dbd95f9f245a51ba1fa34aced9bd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 22:23:18 -0700 Subject: [PATCH 216/429] OpenGL: Use VAOs --- README.md | 2 +- include/mgba/internal/gba/renderers/gl.h | 20 ++-- src/gba/renderers/gl.c | 122 ++++++++++------------- src/platform/opengl/gles2.c | 20 +++- src/platform/opengl/gles2.h | 4 +- src/platform/qt/DisplayGL.cpp | 4 +- 6 files changed, 86 insertions(+), 86 deletions(-) diff --git a/README.md b/README.md index f07dc310d..b3350460a 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Other Unix-like platforms, such as OpenBSD, are known to work as well, but are u ### System requirements -Requirements are minimal. Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required. +Requirements are minimal. Any computer that can run Windows Vista or newer should be able to handle emulation. Support for OpenGL 1.1 or newer is also required, with OpenGL 3.0 or newer for shaders and advanced features. Downloads --------- diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 6ac96a50e..a59569b80 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -125,6 +125,12 @@ enum { GBA_GL_UNIFORM_MAX = 12 }; +struct GBAVideoGLShader { + GLuint program; + GLuint vao; + GLuint uniforms[GBA_GL_UNIFORM_MAX]; +}; + struct GBAVideoGLRenderer { struct GBAVideoRenderer d; @@ -136,6 +142,7 @@ struct GBAVideoGLRenderer { GLuint fbo[GBA_GL_FBO_MAX]; GLuint layers[GBA_GL_TEX_MAX]; + GLuint vbo; GLuint outputTex; @@ -148,15 +155,10 @@ struct GBAVideoGLRenderer { GLuint vramTex; unsigned vramDirty; - GLuint bgProgram[6]; - GLuint bgUniforms[6][GBA_GL_UNIFORM_MAX]; - GLuint objProgram[2]; - GLuint objUniforms[2][GBA_GL_UNIFORM_MAX]; - - GLuint compositeProgram; - GLuint compositeUniforms[GBA_GL_UNIFORM_MAX]; - GLuint finalizeProgram; - GLuint finalizeUniforms[GBA_GL_UNIFORM_MAX]; + struct GBAVideoGLShader bgShader[6]; + struct GBAVideoGLShader objShader[2]; + struct GBAVideoGLShader compositeShader; + struct GBAVideoGLShader finalizeShader; GBARegisterDISPCNT dispcnt; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index bdd065cb8..1bfc1683e 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -399,7 +399,10 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->scale = 1; } -void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const char** shaderBuffer, int shaderBufferLines, GLuint vs, char* log) { +void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, char* log) { + GLuint program = glCreateProgram(); + shader->program = program; + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glAttachShader(program, vs); glAttachShader(program, fs); @@ -419,6 +422,18 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, GLuint program, const glBindFragDataLocation(program, 0, "color"); glBindFragDataLocation(program, 1, "flags"); #endif + + glGenVertexArrays(1, &shader->vao); + glBindVertexArray(shader->vao); + glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); + GLuint positionLocation = glGetAttribLocation(program, "position"); + glVertexAttribPointer(positionLocation, 2, GL_INT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(positionLocation); + + size_t i; + for (i = 0; uniforms[i].name; ++i) { + shader->uniforms[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); + } } static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { @@ -431,13 +446,6 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } -static void _lookupUniforms(GLuint program, GLuint* out, const struct GBAVideoGLUniform* uniforms) { - size_t i; - for (i = 0; uniforms[i].name; ++i) { - out[uniforms[i].type] = glGetUniformLocation(program, uniforms[i].name); - } -} - void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); @@ -472,6 +480,10 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); + glGenBuffers(1, &glRenderer->vbo); + glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW); + int i; for (i = 0; i < 4; ++i) { struct GBAVideoGLBackground* bg = &glRenderer->bg[i]; @@ -505,17 +517,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); } - glRenderer->compositeProgram = glCreateProgram(); - glRenderer->finalizeProgram = glCreateProgram(); - glRenderer->objProgram[0] = glCreateProgram(); - glRenderer->objProgram[1] = glCreateProgram(); - glRenderer->bgProgram[0] = glCreateProgram(); - glRenderer->bgProgram[1] = glCreateProgram(); - glRenderer->bgProgram[2] = glCreateProgram(); - glRenderer->bgProgram[3] = glCreateProgram(); - glRenderer->bgProgram[4] = glCreateProgram(); - glRenderer->bgProgram[5] = glCreateProgram(); - char log[1024]; const GLchar* shaderBuffer[8]; shaderBuffer[0] = _gl3Header; @@ -532,51 +533,44 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _renderMode0; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, glRenderer->bgProgram[0], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[0], glRenderer->bgUniforms[0], _uniformsMode0); + _compileShader(glRenderer, &glRenderer->bgShader[0], shaderBuffer, 3, vs, _uniformsMode0, log); shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, glRenderer->bgProgram[1], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[1], glRenderer->bgUniforms[1], _uniformsMode0); + _compileShader(glRenderer, &glRenderer->bgShader[1], shaderBuffer, 3, vs, _uniformsMode0, log); shaderBuffer[1] = _renderMode2; shaderBuffer[2] = _fetchTileOverflow; - _compileShader(glRenderer, glRenderer->bgProgram[2], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[2], glRenderer->bgUniforms[2], _uniformsMode2); + _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 3, vs, _uniformsMode2, log); shaderBuffer[2] = _fetchTileNoOverflow; - _compileShader(glRenderer, glRenderer->bgProgram[3], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->bgProgram[3], glRenderer->bgUniforms[3], _uniformsMode2); + _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 3, vs, _uniformsMode2, log); shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; - _compileShader(glRenderer, glRenderer->objProgram[0], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->objProgram[0], glRenderer->objUniforms[0], _uniformsObj); + _compileShader(glRenderer, &glRenderer->objShader[0], shaderBuffer, 3, vs, _uniformsObj, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objProgram[0], 2, "window"); + glBindFragDataLocation(glRenderer->objShader[0].program, 2, "window"); #endif shaderBuffer[2] = _renderTile256; - _compileShader(glRenderer, glRenderer->objProgram[1], shaderBuffer, 3, vs, log); - _lookupUniforms(glRenderer->objProgram[1], glRenderer->objUniforms[1], _uniformsObj); + _compileShader(glRenderer, &glRenderer->objShader[1], shaderBuffer, 3, vs, _uniformsObj, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->objProgram[1], 2, "window"); + glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); #endif shaderBuffer[1] = _composite; - _compileShader(glRenderer, glRenderer->compositeProgram, shaderBuffer, 2, vs, log); - _lookupUniforms(glRenderer->compositeProgram, glRenderer->compositeUniforms, _uniformsComposite); + _compileShader(glRenderer, &glRenderer->compositeShader, shaderBuffer, 2, vs, _uniformsComposite, log); #ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->compositeProgram, 2, "oldColor"); - glBindFragDataLocation(glRenderer->compositeProgram, 3, "oldFlags"); + glBindFragDataLocation(glRenderer->compositeShader.program, 2, "oldColor"); + glBindFragDataLocation(glRenderer->compositeShader.program, 3, "oldFlags"); #endif shaderBuffer[1] = _finalize; - _compileShader(glRenderer, glRenderer->finalizeProgram, shaderBuffer, 2, vs, log); - _lookupUniforms(glRenderer->finalizeProgram, glRenderer->finalizeUniforms, _uniformsFinalize); + _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, log); + glBindVertexArray(0); glDeleteShader(vs); GBAVideoGLRendererReset(renderer); @@ -588,16 +582,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); - - glDeleteProgram(glRenderer->bgProgram[0]); - glDeleteProgram(glRenderer->bgProgram[1]); - glDeleteProgram(glRenderer->bgProgram[2]); - glDeleteProgram(glRenderer->bgProgram[3]); - glDeleteProgram(glRenderer->bgProgram[4]); - glDeleteProgram(glRenderer->bgProgram[5]); - glDeleteProgram(glRenderer->objProgram[0]); - glDeleteProgram(glRenderer->objProgram[1]); - glDeleteProgram(glRenderer->compositeProgram); } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { @@ -1075,11 +1059,12 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu if ((y & 0x1F) != 0x1F) { return; } - const GLuint* uniforms = renderer->compositeUniforms; + const GLuint* uniforms = renderer->compositeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_COMPOSITE]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glUseProgram(renderer->compositeProgram); + glUseProgram(renderer->compositeShader.program); + glBindVertexArray(renderer->compositeShader.vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1102,23 +1087,21 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYERFLAGS], 3); glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDOLDFLAGS], 4); glUniform1i(uniforms[GBA_GL_COMPOSITE_WINDOW], 5); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glBindFramebuffer(GL_FRAMEBUFFER, 0); } void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { if ((y & 0x1F) != 0x1F) { return; } - const GLuint* uniforms = renderer->finalizeUniforms; + const GLuint* uniforms = renderer->finalizeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glUseProgram(renderer->finalizeProgram); + glUseProgram(renderer->finalizeShader.program); + glBindVertexArray(renderer->finalizeShader.vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); glActiveTexture(GL_TEXTURE0 + 1); @@ -1134,8 +1117,6 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { glUniform1i(uniforms[GBA_GL_FINALIZE_LAYERFLAGS], 1); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDLAYER], 2); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDFLAGS], 3); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1167,11 +1148,13 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB enum GBAVideoBlendEffect blendEffect = GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect; - const GLuint* uniforms = renderer->objUniforms[GBAObjAttributesAGet256Color(sprite->a)]; + const struct GBAVideoGLShader* shader = &renderer->objShader[GBAObjAttributesAGet256Color(sprite->a)]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); - glUseProgram(renderer->objProgram[GBAObjAttributesAGet256Color(sprite->a)]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1198,8 +1181,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { int window = ~renderer->objwin & 0xFF; glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f); @@ -1220,11 +1201,14 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } else if (background->size == 3) { yBase += (inY & 0x100) << 1; } - const GLuint* uniforms = renderer->bgUniforms[background->multipalette ? 1 : 0]; + + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->multipalette ? 1 : 0]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); - glUseProgram(renderer->bgProgram[background->multipalette ? 1 : 0]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1240,8 +1224,6 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); @@ -1250,11 +1232,13 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { - const GLuint* uniforms = renderer->bgUniforms[background->overflow ? 2 : 3]; + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); - glUseProgram(renderer->bgProgram[background->overflow ? 2 : 3]); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); @@ -1296,8 +1280,6 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, background->affine[0].dx, background->affine[0].dy, }); } - glVertexAttribPointer(0, 2, GL_INT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 94d0856ca..da09ecd60 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -84,6 +84,10 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glGenBuffers(1, &context->vbo); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW); + glClearColor(0.f, 0.f, 0.f, 1.f); struct mGLES2Uniform* uniforms = malloc(sizeof(struct mGLES2Uniform) * 4); @@ -159,6 +163,7 @@ static void mGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, u static void mGLES2ContextDeinit(struct VideoBackend* v) { struct mGLES2Context* context = (struct mGLES2Context*) v; glDeleteTextures(1, &context->tex); + glDeleteBuffers(1, &context->vbo); mGLES2ShaderDeinit(&context->initialShader); mGLES2ShaderDeinit(&context->finalShader); free(context->initialShader.uniforms); @@ -239,8 +244,7 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { glUseProgram(shader->program); glUniform1i(shader->texLocation, 0); glUniform2f(shader->texSizeLocation, context->d.width - padW, context->d.height - padH); - glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices); - glEnableVertexAttribArray(shader->positionLocation); + glBindVertexArray(shader->vao); size_t u; for (u = 0; u < shader->nUniforms; ++u) { struct mGLES2Uniform* uniform = &shader->uniforms[u]; @@ -420,6 +424,13 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f for (i = 0; i < shader->nUniforms; ++i) { shader->uniforms[i].location = glGetUniformLocation(shader->program, shader->uniforms[i].name); } + + glGenVertexArrays(1, &shader->vao); + glBindVertexArray(shader->vao); + glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(shader->positionLocation); + glBindVertexArray(0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -428,6 +439,7 @@ void mGLES2ShaderDeinit(struct mGLES2Shader* shader) { glDeleteShader(shader->fragmentShader); glDeleteProgram(shader->program); glDeleteFramebuffers(1, &shader->fbo); + glDeleteVertexArrays(1, &shader->vao); } void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shaders, size_t nShaders) { @@ -443,7 +455,11 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad for (i = 0; i < nShaders; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, context->shaders[i].fbo); glClear(GL_COLOR_BUFFER_BIT); + + glBindVertexArray(context->shaders[i].vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); } + glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/platform/opengl/gles2.h b/src/platform/opengl/gles2.h index f6d050bc9..59f3b7996 100644 --- a/src/platform/opengl/gles2.h +++ b/src/platform/opengl/gles2.h @@ -62,6 +62,7 @@ struct mGLES2Shader { bool blend; GLuint tex; GLuint fbo; + GLuint vao; GLuint fragmentShader; GLuint vertexShader; GLuint program; @@ -77,8 +78,7 @@ struct mGLES2Context { struct VideoBackend d; GLuint tex; - GLuint texLocation; - GLuint positionLocation; + GLuint vbo; struct mGLES2Shader initialShader; struct mGLES2Shader finalShader; diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 81d01f960..2405cbe07 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -227,7 +227,7 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); #ifdef BUILD_GLES2 - if (extensions.contains("GL_ARB_framebuffer_object") && majorVersion >= 2) { + if ((majorVersion == 2 && extensions.contains("GL_ARB_framebuffer_object")) || majorVersion > 2) { gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); m_backend = &gl2Backend->d; @@ -500,8 +500,8 @@ void PainterGL::clearShaders() { if (!supportsShaders()) { return; } - if (!m_active) { #ifdef BUILD_GLES2 + if (!m_active) { m_gl->makeCurrent(m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); From 3797e1e5f6b001fa1cb2855304c752d81ef25ff6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 22:44:00 -0700 Subject: [PATCH 217/429] GBA Video: Minor GL cleanup --- src/gba/renderers/gl.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 1bfc1683e..d28510014 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -856,16 +856,12 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); for (i = 0; i < 4; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); } glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); @@ -890,6 +886,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstAffine = -1; } + GBAVideoGLRendererDrawWindow(glRenderer, y); if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { if (glRenderer->oamDirty) { glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); @@ -906,7 +903,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } - GBAVideoGLRendererDrawWindow(glRenderer, y); _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], 4, y); unsigned priority; for (priority = 4; priority--;) { From 06cc738b008cb0017965b14013c3039bdd430df8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 14 May 2019 23:33:54 -0700 Subject: [PATCH 218/429] GBA Video: Fix VAOs on Nvidia --- src/gba/renderers/gl.c | 6 +++++- src/platform/opengl/gles2.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index d28510014..5a8521d81 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -428,7 +428,6 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShad glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); GLuint positionLocation = glGetAttribLocation(program, "position"); glVertexAttribPointer(positionLocation, 2, GL_INT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(positionLocation); size_t i; for (i = 0; uniforms[i].name; ++i) { @@ -1084,6 +1083,7 @@ static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLu glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDOLDFLAGS], 4); glUniform1i(uniforms[GBA_GL_COMPOSITE_WINDOW], 5); glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); + glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1113,6 +1113,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { glUniform1i(uniforms[GBA_GL_FINALIZE_LAYERFLAGS], 1); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDLAYER], 2); glUniform1i(uniforms[GBA_GL_FINALIZE_OLDFLAGS], 3); + glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1185,6 +1186,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } + glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1221,6 +1223,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); @@ -1277,6 +1280,7 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, }); } glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index da09ecd60..d51dd568f 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -135,6 +135,15 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { uniforms[3].max.fvec3[2] = 1.0f; mGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, false, uniforms, 4); mGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, false, 0, 0); + + glBindVertexArray(context->initialShader.vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(context->finalShader.vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(0); + glDeleteFramebuffers(1, &context->finalShader.fbo); glDeleteTextures(1, &context->finalShader.tex); context->finalShader.fbo = 0; @@ -296,6 +305,7 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { break; } } + glEnableVertexAttribArray(shader->positionLocation); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindTexture(GL_TEXTURE_2D, shader->tex); } @@ -426,10 +436,6 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f } glGenVertexArrays(1, &shader->vao); - glBindVertexArray(shader->vao); - glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glEnableVertexAttribArray(shader->positionLocation); - glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -458,6 +464,8 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad glBindVertexArray(context->shaders[i].vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(context->shaders[i].positionLocation); } glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); From 99d07c98c5d03510899c50a67573498900cddfef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 15 May 2019 10:16:06 -0700 Subject: [PATCH 219/429] OpenGL: Fix frame sizing regression --- src/platform/opengl/gles2.c | 5 ++--- src/platform/qt/DisplayGL.cpp | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index d51dd568f..465820528 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -192,14 +192,13 @@ static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) drawW -= drawW % v->width; drawH -= drawH % v->height; } - glViewport(0, 0, w, h); - glClearColor(0.f, 0.f, 0.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH); } static void mGLES2ContextClear(struct VideoBackend* v) { UNUSED(v); + glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 2405cbe07..0df112e06 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -321,8 +321,6 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) { void PainterGL::resize(const QSize& size) { m_size = size; - float r = m_surface->devicePixelRatio(); - m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); if (m_started && !m_active) { forceDraw(); } @@ -419,6 +417,8 @@ void PainterGL::unpause() { void PainterGL::performDraw() { m_painter.beginNativePainting(); + float r = m_surface->devicePixelRatio(); + m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r); m_backend->drawFrame(m_backend); m_painter.endNativePainting(); if (m_messagePainter) { From cecf6adb2c5e60a847a75050917a0d47ec889466 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 15 May 2019 10:42:21 -0700 Subject: [PATCH 220/429] GBA Video: Fix 256-color sprites in GL renderer --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 5a8521d81..7dfb40287 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1126,7 +1126,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB int align = GBAObjAttributesAIs256Color(sprite->a) && !GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt); unsigned charBase = (BASE_TILE >> 1) + (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x10; - int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x40 >> !GBAObjAttributesAIs256Color(sprite->a)); + int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x20 >> GBAObjAttributesAGet256Color(sprite->a)); if (spriteY + height >= 256) { spriteY -= 256; From 505d63fab55ff83c7487a4162e7f932fae0e4df1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 15 May 2019 10:42:39 -0700 Subject: [PATCH 221/429] Qt: Fix hwaccel settings --- src/platform/qt/SettingsView.cpp | 13 +++++-------- src/platform/qt/SettingsView.h | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 3157ec6d3..95943c671 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -466,7 +466,7 @@ void SettingsView::updateConfig() { emit languageChanged(); } - int videoScale = m_controller->getOption("videoScale").toInt(); + int videoScale = m_controller->getOption("videoScale", 1).toInt(); int hwaccelVideo = m_controller->getOption("hwaccelVideo").toInt(); if (videoScale != m_ui.videoScale->value() || hwaccelVideo != m_ui.hwaccelVideo->currentIndex()) { emit videoRendererChanged(); @@ -551,7 +551,7 @@ void SettingsView::reloadConfig() { loadSetting("logFile", m_ui.logFile); loadSetting("useDiscordPresence", m_ui.useDiscordPresence); loadSetting("audioHle", m_ui.audioHle); - loadSetting("videoScale", m_ui.videoScale); + loadSetting("videoScale", m_ui.videoScale, 1); m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt()); @@ -616,10 +616,7 @@ void SettingsView::reloadConfig() { } #endif - int hwaccelVideo = m_controller->getOption("hwaccelVideo", 1).toInt(); - if (hwaccelVideo < 1) { - hwaccelVideo = 1; - } + int hwaccelVideo = m_controller->getOption("hwaccelVideo", 0).toInt(); m_ui.hwaccelVideo->setCurrentIndex(hwaccelVideo); } @@ -677,9 +674,9 @@ void SettingsView::loadSetting(const char* key, QSlider* field, int defaultVal) field->setValue(option.isNull() ? defaultVal : option.toInt()); } -void SettingsView::loadSetting(const char* key, QSpinBox* field) { +void SettingsView::loadSetting(const char* key, QSpinBox* field, int defaultVal) { QString option = loadSetting(key); - field->setValue(option.toInt()); + field->setValue(option.isNull() ? defaultVal : option.toInt()); } QString SettingsView::loadSetting(const char* key) { diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 0ea562807..23a8c18ff 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -77,7 +77,7 @@ private: void loadSetting(const char* key, QDoubleSpinBox*); void loadSetting(const char* key, QLineEdit*); void loadSetting(const char* key, QSlider*, int defaultVal = 0); - void loadSetting(const char* key, QSpinBox*); + void loadSetting(const char* key, QSpinBox*, int defaultVal = 0); QString loadSetting(const char* key); }; From 25f0bc7f2be32fdff2190b563d3bf996279a64fb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 15 May 2019 23:43:01 -0700 Subject: [PATCH 222/429] GBA Video: Massively simplify compositing --- include/mgba/internal/gba/renderers/gl.h | 28 +- src/gba/renderers/gl.c | 350 +++++++++-------------- 2 files changed, 148 insertions(+), 230 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index a59569b80..4b1c4a07f 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -67,19 +67,14 @@ struct GBAVideoGLBackground { enum { GBA_GL_FBO_OBJ = 0, - GBA_GL_FBO_COMPOSITE = 1, - GBA_GL_FBO_WINDOW = 2, - GBA_GL_FBO_OUTPUT = 3, + GBA_GL_FBO_WINDOW = 1, + GBA_GL_FBO_OUTPUT = 2, GBA_GL_FBO_MAX }; enum { GBA_GL_TEX_OBJ_COLOR = 0, GBA_GL_TEX_OBJ_FLAGS = 1, - GBA_GL_TEX_COMPOSITE_COLOR = 2, - GBA_GL_TEX_COMPOSITE_FLAGS = 3, - GBA_GL_TEX_COMPOSITE_OLD_COLOR = 4, - GBA_GL_TEX_COMPOSITE_OLD_FLAGS = 5, GBA_GL_TEX_WINDOW = 6, GBA_GL_TEX_MAX }; @@ -107,20 +102,12 @@ enum { GBA_GL_OBJ_DIMS, GBA_GL_OBJ_OBJWIN, - GBA_GL_COMPOSITE_SCALE = 2, - GBA_GL_COMPOSITE_LAYERID, - GBA_GL_COMPOSITE_LAYER, - GBA_GL_COMPOSITE_LAYERFLAGS, - GBA_GL_COMPOSITE_OLDLAYER, - GBA_GL_COMPOSITE_OLDLAYERFLAGS, - GBA_GL_COMPOSITE_OLDOLDFLAGS, - GBA_GL_COMPOSITE_WINDOW, - GBA_GL_FINALIZE_SCALE = 2, - GBA_GL_FINALIZE_LAYER, - GBA_GL_FINALIZE_LAYERFLAGS, - GBA_GL_FINALIZE_OLDLAYER, - GBA_GL_FINALIZE_OLDFLAGS, + GBA_GL_FINALIZE_LAYERS, + GBA_GL_FINALIZE_FLAGS, + GBA_GL_FINALIZE_WINDOW, + GBA_GL_FINALIZE_BACKDROP, + GBA_GL_FINALIZE_BACKDROPFLAGS, GBA_GL_UNIFORM_MAX = 12 }; @@ -157,7 +144,6 @@ struct GBAVideoGLRenderer { struct GBAVideoGLShader bgShader[6]; struct GBAVideoGLShader objShader[2]; - struct GBAVideoGLShader compositeShader; struct GBAVideoGLShader finalizeShader; GBARegisterDISPCNT dispcnt; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 7dfb40287..1aa811485 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -40,10 +40,9 @@ static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y); -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int id, int y); static void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y); -#define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 && glRenderer->bg[X].priority == priority +#define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 struct GBAVideoGLUniform { const char* name; @@ -270,104 +269,93 @@ static const char* const _renderObj = " window = objwin.yz;\n" "}"; -static const struct GBAVideoGLUniform _uniformsComposite[] = { - { "loc", GBA_GL_VS_LOC, }, - { "maxPos", GBA_GL_VS_MAXPOS, }, - { "scale", GBA_GL_COMPOSITE_SCALE, }, - { "layerId", GBA_GL_COMPOSITE_LAYERID, }, - { "layer", GBA_GL_COMPOSITE_LAYER, }, - { "layerFlags", GBA_GL_COMPOSITE_LAYERFLAGS, }, - { "oldLayer", GBA_GL_COMPOSITE_OLDLAYER, }, - { "oldLayerFlags", GBA_GL_COMPOSITE_OLDLAYERFLAGS, }, - { "oldOldFlags", GBA_GL_COMPOSITE_OLDOLDFLAGS, }, - { "window", GBA_GL_COMPOSITE_WINDOW, }, - { 0 } -}; - -static const char* const _composite = - "in vec2 texCoord;\n" - "uniform int scale;\n" - "uniform int layerId\n;" - "uniform sampler2D layer;\n" - "uniform sampler2D layerFlags;\n" - "uniform sampler2D oldLayer;\n" - "uniform sampler2D oldLayerFlags;\n" - "uniform sampler2D oldOldFlags;\n" - "uniform sampler2D window;\n" - "out vec4 color;\n" - "out vec4 flags;\n" - "out vec4 oldColor;\n" - "out vec4 oldFlags;\n" - "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" - - "void main() {\n" - " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" - " if (pix.a == 0) {\n" - " discard;\n" - " }\n" - " ivec2 windowFlags = ivec2(texelFetch(window, ivec2(texCoord * scale), 0).xy * 32.);\n" - " if (((windowFlags.x | (windowFlags.y << 4)) & layerId) != 0) {\n" - " discard;\n" - " }\n" - " ivec4 inflags = ivec4(texelFetch(layerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" - " ivec4 oflags = ivec4(texelFetch(oldLayerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" - " if ((windowFlags.y & 2) != 0) {\n" - " inflags.y = 0;\n" - " }\n" - " if (inflags.x >= oflags.x) {\n" - " ivec4 ooflags = ivec4(texelFetch(oldOldFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" - " if (inflags.x >= ooflags.x) {\n" - " discard;\n" - " }\n" - " oldFlags = inflags / flagCoeff;\n" - " flags = oflags / flagCoeff;\n" - " oldColor = pix;\n" - " color = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" - " } else {\n" - " color = pix;\n" - " oldColor = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" - " flags = inflags / flagCoeff;\n" - " oldFlags = oflags / flagCoeff;\n" - " }\n" - "}"; - static const struct GBAVideoGLUniform _uniformsFinalize[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, { "scale", GBA_GL_FINALIZE_SCALE, }, - { "layer", GBA_GL_FINALIZE_LAYER, }, - { "layerFlags", GBA_GL_FINALIZE_LAYERFLAGS, }, - { "oldLayer", GBA_GL_FINALIZE_OLDLAYER, }, - { "oldFlags", GBA_GL_FINALIZE_OLDFLAGS, }, + { "layers", GBA_GL_FINALIZE_LAYERS, }, + { "flags", GBA_GL_FINALIZE_FLAGS, }, + { "window", GBA_GL_FINALIZE_WINDOW, }, + { "backdrop", GBA_GL_FINALIZE_BACKDROP, }, + { "backdropFlags", GBA_GL_FINALIZE_BACKDROPFLAGS, }, { 0 } }; static const char* const _finalize = "in vec2 texCoord;\n" "uniform int scale;\n" - "uniform sampler2D layer;\n" - "uniform sampler2D layerFlags;\n" - "uniform sampler2D oldLayer;\n" - "uniform sampler2D oldFlags;\n" + "uniform sampler2D layers[5];\n" + "uniform sampler2D flags[5];\n" + "uniform sampler2D window;\n" + "uniform vec4 backdrop;\n" + "uniform vec4 backdropFlags;\n" "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "out vec4 color;\n" - "void main() {\n" - " vec4 pix = texelFetch(layer, ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(layerFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" - " if ((inflags.y & 13) == 5) {\n" - " ivec4 oflags = ivec4(texelFetch(oldFlags, ivec2(texCoord * scale), 0) * flagCoeff);\n" - " if ((oflags.y & 2) == 2) {\n" - " vec4 oldpix = texelFetch(oldLayer, ivec2(texCoord * scale), 0);\n" - " pix *= inflags.z / 16.;\n" - " pix += oldpix * oflags.w / 16.;\n" - " }\n" - " } else if ((inflags.y & 13) == 9) {\n" - " pix += (1. - pix) * inflags.z / 16.;\n" - " } else if ((inflags.y & 13) == 13) {\n" - " pix -= pix * inflags.z / 16.;\n" + "void composite(vec4 pixel, ivec4 flags, inout vec4 topPixel, inout ivec4 topFlags, inout vec4 bottomPixel, inout ivec4 bottomFlags) {\n" + " if (pixel.a == 0) {\n" + " return;\n" " }\n" - " color = pix;\n" + " if (flags.x >= topFlags.x) {\n" + " if (flags.x >= bottomFlags.x) {\n" + " return;\n" + " }\n" + " bottomFlags = flags;\n" + " bottomPixel = pixel;\n" + " } else {\n" + " bottomFlags = topFlags;\n" + " topFlags = flags;\n" + " bottomPixel = topPixel;\n" + " topPixel = pixel;\n" + " }\n" + "}\n" + + "void main() {\n" + " ivec2 windowFlags = ivec2(texelFetch(window, ivec2(texCoord * scale), 0).xy * 32);\n" + " int layerWindow = windowFlags.x | (windowFlags.y << 4);\n" + " vec4 topPixel = backdrop;\n" + " vec4 bottomPixel = backdrop;\n" + " ivec4 topFlags = ivec4(backdropFlags * flagCoeff);\n" + " ivec4 bottomFlags = ivec4(backdropFlags * flagCoeff);\n" + " if ((layerWindow & 16) == 0) {\n" + " vec4 pix = texelFetch(layers[4], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" + " if ((layerWindow & 1) == 0) {\n" + " vec4 pix = texelFetch(layers[0], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" + " if ((layerWindow & 2) == 0) {\n" + " vec4 pix = texelFetch(layers[1], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" + " if ((layerWindow & 4) == 0) {\n" + " vec4 pix = texelFetch(layers[2], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" + " if ((layerWindow & 8) == 0) {\n" + " vec4 pix = texelFetch(layers[3], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" + " if ((layerWindow & 32) != 0) {\n" + " topFlags.y = 0;\n" + " }\n" + " if ((topFlags.y & 13) == 5) {\n" + " if ((bottomFlags.y & 2) == 2) {\n" + " topPixel *= topFlags.z / 16.;\n" + " topPixel += bottomPixel * bottomFlags.w / 16.;\n" + " }\n" + " } else if ((topFlags.y & 13) == 9) {\n" + " topPixel += (1. - topPixel) * topFlags.z / 16.;\n" + " } else if ((topFlags.y & 13) == 13) {\n" + " topPixel -= topPixel * topFlags.z / 16.;\n" + " }\n" + " color = topPixel;\n" "}"; static const GLint _vertices[] = { @@ -465,12 +453,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT3, glRenderer->scale); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RG, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -559,13 +541,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); #endif - shaderBuffer[1] = _composite; - _compileShader(glRenderer, &glRenderer->compositeShader, shaderBuffer, 2, vs, _uniformsComposite, log); -#ifndef BUILD_GLES3 - glBindFragDataLocation(glRenderer->compositeShader.program, 2, "oldColor"); - glBindFragDataLocation(glRenderer->compositeShader.program, 3, "oldFlags"); -#endif - shaderBuffer[1] = _finalize; _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, log); @@ -836,20 +811,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->vramDirty = 0; - uint32_t backdrop = M_RGB5_TO_RGB8(renderer->palette[0]); - glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_COMPOSITE]); - glEnable(GL_SCISSOR_TEST); - glScissor(0, y * glRenderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, glRenderer->scale); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glClear(GL_COLOR_BUFFER_BIT); if (y == 0) { - glDisable(GL_SCISSOR_TEST); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); - glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, - (glRenderer->blendEffect == BLEND_ALPHA ? glRenderer->blda : glRenderer->bldy) / 16.f, glRenderer->bldb / 16.f); - glClear(GL_COLOR_BUFFER_BIT); - + glDisable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT3 }); glClear(GL_COLOR_BUFFER_BIT); @@ -902,44 +865,40 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } } - _compositeLayer(glRenderer, glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], 4, y); - unsigned priority; - for (priority = 4; priority--;) { - if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { - GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[0], y); + if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[0], y); + } + if (TEST_LAYER_ENABLED(1) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[1], y); + } + if (TEST_LAYER_ENABLED(2)) { + switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { + case 0: + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[2], y); + break; + case 1: + case 2: + GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); + break; + case 3: + //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); + break; + case 4: + //GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); + break; + case 5: + //GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); + break; } - if (TEST_LAYER_ENABLED(1) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { - GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[1], y); - } - if (TEST_LAYER_ENABLED(2)) { - switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { - case 0: - GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[2], y); - break; - case 1: - case 2: - GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); - break; - case 3: - //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); - break; - case 4: - //GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); - break; - case 5: - //GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); - break; - } - } - if (TEST_LAYER_ENABLED(3)) { - switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { - case 0: - GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[3], y); - break; - case 2: - GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[3], y); - break; - } + } + if (TEST_LAYER_ENABLED(3)) { + switch (GBARegisterDISPCNTGetMode(glRenderer->dispcnt)) { + case 0: + GBAVideoGLRendererDrawBackgroundMode0(glRenderer, &glRenderer->bg[3], y); + break; + case 2: + GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[3], y); + break; } } _finalizeLayers(glRenderer, y); @@ -1050,69 +1009,46 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -static void _compositeLayer(struct GBAVideoGLRenderer* renderer, GLuint tex, GLuint flags, int id, int y) { - if ((y & 0x1F) != 0x1F) { - return; - } - const GLuint* uniforms = renderer->compositeShader.uniforms; - glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_COMPOSITE]); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); - glUseProgram(renderer->compositeShader.program); - glBindVertexArray(renderer->compositeShader.vao); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, flags); - glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); - glActiveTexture(GL_TEXTURE0 + 3); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); - glActiveTexture(GL_TEXTURE0 + 4); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); - glActiveTexture(GL_TEXTURE0 + 5); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); - glUniform2i(uniforms[GBA_GL_VS_LOC], 0x20, y & ~0x1F); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(uniforms[GBA_GL_COMPOSITE_SCALE], renderer->scale); - glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYERID], 1 << id); - glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYER], 0); - glUniform1i(uniforms[GBA_GL_COMPOSITE_LAYERFLAGS], 1); - glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYER], 2); - glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDLAYERFLAGS], 3); - glUniform1i(uniforms[GBA_GL_COMPOSITE_OLDOLDFLAGS], 4); - glUniform1i(uniforms[GBA_GL_COMPOSITE_WINDOW], 5); - glDrawBuffers(4, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }); - glEnableVertexAttribArray(0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); -} - void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { - if ((y & 0x1F) != 0x1F) { - return; - } const GLuint* uniforms = renderer->finalizeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glScissor(0, (y & ~0x1F) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, 0x20 * renderer->scale); + glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); glUseProgram(renderer->finalizeShader.program); glBindVertexArray(renderer->finalizeShader.vao); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_COLOR]); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_FLAGS]); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_COLOR]); glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_COLOR]); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_FLAGS]); glActiveTexture(GL_TEXTURE0 + 3); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_COMPOSITE_OLD_FLAGS]); - glUniform2i(uniforms[GBA_GL_VS_LOC], 0x20, y & ~0x1F); + glBindTexture(GL_TEXTURE_2D, renderer->bg[0].tex); + glActiveTexture(GL_TEXTURE0 + 4); + glBindTexture(GL_TEXTURE_2D, renderer->bg[0].flags); + glActiveTexture(GL_TEXTURE0 + 5); + glBindTexture(GL_TEXTURE_2D, renderer->bg[1].tex); + glActiveTexture(GL_TEXTURE0 + 6); + glBindTexture(GL_TEXTURE_2D, renderer->bg[1].flags); + glActiveTexture(GL_TEXTURE0 + 7); + glBindTexture(GL_TEXTURE_2D, renderer->bg[2].tex); + glActiveTexture(GL_TEXTURE0 + 8); + glBindTexture(GL_TEXTURE_2D, renderer->bg[2].flags); + glActiveTexture(GL_TEXTURE0 + 9); + glBindTexture(GL_TEXTURE_2D, renderer->bg[3].tex); + glActiveTexture(GL_TEXTURE0 + 10); + glBindTexture(GL_TEXTURE_2D, renderer->bg[3].flags); + + uint32_t backdrop = M_RGB5_TO_RGB8(renderer->d.palette[0]); + glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); - glUniform1i(uniforms[GBA_GL_FINALIZE_LAYER], 0); - glUniform1i(uniforms[GBA_GL_FINALIZE_LAYERFLAGS], 1); - glUniform1i(uniforms[GBA_GL_FINALIZE_OLDLAYER], 2); - glUniform1i(uniforms[GBA_GL_FINALIZE_OLDFLAGS], 3); + glUniform1iv(uniforms[GBA_GL_FINALIZE_LAYERS], 5, (GLint[]) { 3, 5, 7, 9, 1 }); + glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); + glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, + (renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy) / 16.f, renderer->bldb / 16.f); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1226,8 +1162,6 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - - _compositeLayer(renderer, background->tex, background->flags, background->index, y); } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -1283,8 +1217,6 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - - _compositeLayer(renderer, background->tex, background->flags, background->index, y); } static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale) { @@ -1296,18 +1228,18 @@ static void _clearWindow(GBAWindowControl window, int start, int end, int y, int void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); + int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(0xFF, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); } else { - _clearWindow(renderer->winout, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale); } } - glBindFramebuffer(GL_FRAMEBUFFER, 0); } #endif From b92a08e6f1fddee946c93030fceab0af83aea7a0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 15 May 2019 23:43:20 -0700 Subject: [PATCH 223/429] OpenGL: Reset clear color as needed --- src/platform/opengl/gles2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 465820528..35e7ac9e0 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -88,8 +88,6 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { glBindBuffer(GL_ARRAY_BUFFER, context->vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW); - glClearColor(0.f, 0.f, 0.f, 1.f); - struct mGLES2Uniform* uniforms = malloc(sizeof(struct mGLES2Uniform) * 4); uniforms[0].name = "gamma"; uniforms[0].readableName = "Gamma"; @@ -236,6 +234,7 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); + glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); } @@ -459,6 +458,7 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad size_t i; for (i = 0; i < nShaders; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, context->shaders[i].fbo); + glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(context->shaders[i].vao); From ac7ae74822d2740f82b62a644e88fbed789ad2be Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 May 2019 09:59:49 -0700 Subject: [PATCH 224/429] GBA Video: Fix GL sprite window blending --- src/gba/renderers/gl.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 1aa811485..9527ef2a9 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -317,11 +317,6 @@ static const char* const _finalize = " vec4 bottomPixel = backdrop;\n" " ivec4 topFlags = ivec4(backdropFlags * flagCoeff);\n" " ivec4 bottomFlags = ivec4(backdropFlags * flagCoeff);\n" - " if ((layerWindow & 16) == 0) {\n" - " vec4 pix = texelFetch(layers[4], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * scale), 0) * flagCoeff);\n" - " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" - " }\n" " if ((layerWindow & 1) == 0) {\n" " vec4 pix = texelFetch(layers[0], ivec2(texCoord * scale), 0);\n" " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0) * flagCoeff);\n" @@ -343,7 +338,12 @@ static const char* const _finalize = " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 32) != 0) {\n" - " topFlags.y = 0;\n" + " topFlags.y &= ~1;\n" + " }\n" + " if ((layerWindow & 16) == 0) {\n" + " vec4 pix = texelFetch(layers[4], ivec2(texCoord * scale), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((topFlags.y & 13) == 5) {\n" " if ((bottomFlags.y & 2) == 2) {\n" @@ -827,9 +827,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClear(GL_COLOR_BUFFER_BIT); } glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glEnable(GL_SCISSOR_TEST); } - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glEnable(GL_SCISSOR_TEST); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { if (glRenderer->firstAffine < 0) { From 8a26a7977c0dea8315ea9b1a6df9df7da27b1fe5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 16 May 2019 17:09:50 -0700 Subject: [PATCH 225/429] GBA Video: GL screenshots --- include/mgba/feature/video-logger.h | 4 ++++ include/mgba/internal/gba/renderers/gl.h | 2 ++ src/gb/extra/proxy.c | 10 ++++++---- src/gba/core.c | 8 ++++---- src/gba/extra/proxy.c | 12 +++++++++--- src/gba/renderers/gl.c | 17 ++++++++++++++++- 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index bae94157a..d33e83155 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -32,6 +32,7 @@ enum mVideoLoggerEvent { LOGGER_EVENT_INIT, LOGGER_EVENT_DEINIT, LOGGER_EVENT_RESET, + LOGGER_EVENT_GET_PIXELS, }; struct mVideoLoggerDirtyInfo { @@ -73,6 +74,9 @@ struct mVideoLogger { uint16_t* vram; uint16_t* oam; uint16_t* palette; + + const void* pixelBuffer; + size_t pixelStride; }; void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly); diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 4b1c4a07f..209607f1c 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -121,6 +121,8 @@ struct GBAVideoGLShader { struct GBAVideoGLRenderer { struct GBAVideoRenderer d; + uint32_t* temporaryBuffer; + struct GBAVideoGLBackground bg[4]; int oamMax; diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index c5230c88c..d8538124d 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -283,11 +283,13 @@ static void GBVideoProxyRendererGetPixels(struct GBVideoRenderer* renderer, size proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); - } - proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_GET_PIXELS); + mVideoLoggerRendererFlush(proxyRenderer->logger); proxyRenderer->logger->unlock(proxyRenderer->logger); + *pixels = proxyRenderer->logger->pixelBuffer; + *stride = proxyRenderer->logger->pixelStride; + } else { + proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); } } diff --git a/src/gba/core.c b/src/gba/core.c index 839404d03..0fc449972 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -310,13 +310,13 @@ static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { } static void _GBACoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) { - struct GBACore* gbacore = (struct GBACore*) core; - gbacore->renderer.d.getPixels(&gbacore->renderer.d, stride, buffer); + struct GBA* gba = core->board; + gba->video.renderer->getPixels(gba->video.renderer, stride, buffer); } static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t stride) { - struct GBACore* gbacore = (struct GBACore*) core; - gbacore->renderer.d.putPixels(&gbacore->renderer.d, stride, buffer); + struct GBA* gba = core->board; + gba->video.renderer->putPixels(gba->video.renderer, stride, buffer); } static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) { diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 38bfb4514..bd90f1271 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -152,6 +152,9 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve case LOGGER_EVENT_RESET: proxyRenderer->backend->reset(proxyRenderer->backend); break; + case LOGGER_EVENT_GET_PIXELS: + proxyRenderer->backend->getPixels(proxyRenderer->backend, &logger->pixelStride, &logger->pixelBuffer); + break; } } @@ -305,10 +308,13 @@ static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, si proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - } - proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_GET_PIXELS); + mVideoLoggerRendererFlush(proxyRenderer->logger); proxyRenderer->logger->unlock(proxyRenderer->logger); + *pixels = proxyRenderer->logger->pixelBuffer; + *stride = proxyRenderer->logger->pixelStride; + } else { + proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); } } diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 9527ef2a9..c5a069738 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -11,6 +11,7 @@ #include #include #include +#include static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); @@ -435,6 +436,8 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + glRenderer->temporaryBuffer = NULL; + glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); glGenTextures(GBA_GL_TEX_MAX, glRenderer->layers); @@ -552,6 +555,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + if (glRenderer->temporaryBuffer) { + mappedMemoryFree(glRenderer->temporaryBuffer, GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale * glRenderer->scale); + } glDeleteFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); @@ -928,7 +934,16 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { - + struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + *stride = GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale; + if (!glRenderer->temporaryBuffer) { + glRenderer->temporaryBuffer = anonymousMemoryMap(GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale * glRenderer->scale * BYTES_PER_PIXEL); + } + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); + glPixelStorei(GL_PACK_ROW_LENGTH, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale, GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale, GL_RGBA, GL_UNSIGNED_BYTE, (void*) glRenderer->temporaryBuffer); + *pixels = glRenderer->temporaryBuffer; } void GBAVideoGLRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) { From c40217fc8e6a98885a7a272566e892ff1462bdba Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 14:40:16 -0700 Subject: [PATCH 226/429] GBA: Fix hi-res videos --- src/gba/core.c | 4 +++- src/gba/renderers/gl.c | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 0fc449972..44d125f73 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -355,7 +355,9 @@ static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) { struct GBA* gba = core->board; gba->stream = stream; if (stream && stream->videoDimensionsChanged) { - stream->videoDimensionsChanged(stream, GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + unsigned width, height; + core->desiredVideoDimensions(core, &width, &height); + stream->videoDimensionsChanged(stream, width, height); } } diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c5a069738..81fc5cdb8 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -820,9 +820,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { if (y == 0) { glDisable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT3 }); - glClear(GL_COLOR_BUFFER_BIT); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); @@ -939,6 +936,7 @@ void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stri if (!glRenderer->temporaryBuffer) { glRenderer->temporaryBuffer = anonymousMemoryMap(GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * glRenderer->scale * glRenderer->scale * BYTES_PER_PIXEL); } + glFinish(); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); glPixelStorei(GL_PACK_ROW_LENGTH, GBA_VIDEO_HORIZONTAL_PIXELS * glRenderer->scale); glPixelStorei(GL_PACK_ALIGNMENT, 1); From 7a5840fb5a5a01ad94e886663d82079e42e1b001 Mon Sep 17 00:00:00 2001 From: lehoangquyen Date: Mon, 17 Dec 2018 14:14:21 +0800 Subject: [PATCH 227/429] Use atomic functions in more places --- include/mgba-util/common.h | 2 ++ src/gb/sio/lockstep.c | 2 ++ src/gba/sio/lockstep.c | 39 ++++++++++++++++++++++++++++---------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index c3ce5be12..d8ef11029 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -81,6 +81,7 @@ typedef intptr_t ssize_t; #define ATOMIC_STORE(DST, SRC) __atomic_store_n(&DST, SRC, __ATOMIC_RELEASE) #define ATOMIC_LOAD(DST, SRC) DST = __atomic_load_n(&SRC, __ATOMIC_ACQUIRE) #define ATOMIC_ADD(DST, OP) __atomic_add_fetch(&DST, OP, __ATOMIC_RELEASE) +#define ATOMIC_SUB(DST, OP) __atomic_sub_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_OR(DST, OP) __atomic_or_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_AND(DST, OP) __atomic_and_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true,__ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE) @@ -89,6 +90,7 @@ typedef intptr_t ssize_t; #define ATOMIC_STORE(DST, SRC) DST = SRC #define ATOMIC_LOAD(DST, SRC) DST = SRC #define ATOMIC_ADD(DST, OP) DST += OP +#define ATOMIC_SUB(DST, OP) DST -= OP #define ATOMIC_OR(DST, OP) DST |= OP #define ATOMIC_AND(DST, OP) DST &= OP #define ATOMIC_CMPXCHG(DST, EXPECTED, OP) ((DST == EXPECTED) ? ((DST = OP), true) : false) diff --git a/src/gb/sio/lockstep.c b/src/gb/sio/lockstep.c index c60978ffe..2d4ec7546 100644 --- a/src/gb/sio/lockstep.c +++ b/src/gb/sio/lockstep.c @@ -236,6 +236,8 @@ static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t valu mTimingDeschedule(&driver->p->p->timing, &driver->p->event); mTimingDeschedule(&driver->p->p->timing, &node->event); mTimingSchedule(&driver->p->p->timing, &node->event, 0); + } else { + mLOG(GB_SIO, FATAL, "GBSIOLockstepNodeWriteSC() failed to write to masterClaimed\n"); } } return value; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 848dc9b4d..237eff493 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -93,7 +93,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { case SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; node->d.p->rcnt |= 3; - ++node->p->attachedMulti; + ATOMIC_ADD(node->p->attachedMulti, 1); node->d.p->multiplayerControl.ready = node->p->attachedMulti == node->p->d.attached; if (node->id) { node->d.p->rcnt |= 4; @@ -118,7 +118,7 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { node->mode = driver->p->mode; switch (node->mode) { case SIO_MULTI: - --node->p->attachedMulti; + ATOMIC_SUB(node->p->attachedMulti, 1); break; default: break; @@ -132,11 +132,15 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; if (address == REG_SIOCNT) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value); - if (value & 0x0080 && node->p->d.transferActive == TRANSFER_IDLE) { + + enum mLockstepPhase transferActive; + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + + if (value & 0x0080 && transferActive == TRANSFER_IDLE) { if (!node->id && node->d.p->multiplayerControl.ready) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); - node->p->d.transferActive = TRANSFER_STARTING; - node->p->d.transferCycles = GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->d.attached - 1]; + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->d.attached - 1]); mTimingDeschedule(&driver->p->p->timing, &node->event); mTimingSchedule(&driver->p->p->timing, &node->event, 0); } else { @@ -209,11 +213,19 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { bool needsToWait = false; int i; - switch (node->p->d.transferActive) { + + enum mLockstepPhase transferActive; + int attachedMulti, attached; + + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + ATOMIC_LOAD(attachedMulti, node->p->attachedMulti); + ATOMIC_LOAD(attached, node->p->d.attached); + + switch (transferActive) { case TRANSFER_IDLE: // If the master hasn't initiated a transfer, it can keep going. node->nextEvent += LOCKSTEP_INCREMENT; - node->d.p->multiplayerControl.ready = node->p->attachedMulti == node->p->d.attached; + node->d.p->multiplayerControl.ready = attachedMulti == attached; break; case TRANSFER_STARTING: // Start the transfer, but wait for the other GBAs to catch up @@ -276,9 +288,16 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { } static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { - node->d.p->multiplayerControl.ready = node->p->attachedMulti == node->p->d.attached; + enum mLockstepPhase transferActive; + int attachedMulti, attached; + + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + ATOMIC_LOAD(attachedMulti, node->p->attachedMulti); + ATOMIC_LOAD(attached, node->p->d.attached); + + node->d.p->multiplayerControl.ready = attachedMulti == attached; bool signal = false; - switch (node->p->d.transferActive) { + switch (transferActive) { case TRANSFER_IDLE: if (!node->d.p->multiplayerControl.ready) { node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT); @@ -368,7 +387,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive if (value & 0x0080 && !node->id) { // Internal shift clock if (value & 1) { - node->p->d.transferActive = TRANSFER_STARTING; + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); } // Frequency if (value & 2) { From b11de7538e29cc5777097ea8cedeb11db0983cf8 Mon Sep 17 00:00:00 2001 From: Le Hoang Quyen Date: Tue, 18 Dec 2018 02:58:35 +0800 Subject: [PATCH 228/429] Implement atomic macros for win32 --- include/mgba-util/common.h | 14 ++++++++++++++ src/util/ring-fifo.c | 16 ++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index d8ef11029..cb6b35735 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -85,6 +85,18 @@ typedef intptr_t ssize_t; #define ATOMIC_OR(DST, OP) __atomic_or_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_AND(DST, OP) __atomic_and_fetch(&DST, OP, __ATOMIC_RELEASE) #define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true,__ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE) +#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC) +#elif defined _MSC_VER +#define ATOMIC_STORE(DST, SRC) InterlockedExchange(&DST, SRC) +#define ATOMIC_LOAD(DST, SRC) DST = InterlockedOrAcquire(&SRC, 0) +#define ATOMIC_ADD(DST, OP) InterlockedAddRelease(&DST, OP) +#define ATOMIC_SUB(DST, OP) InterlockedAddRelease(&DST, -OP) +#define ATOMIC_OR(DST, OP) InterlockedOrRelease(&DST, OP) +#define ATOMIC_AND(DST, OP) InterlockedAndRelease(&DST, OP) +#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED) +#define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(SRC, 0, 0) #else // TODO #define ATOMIC_STORE(DST, SRC) DST = SRC @@ -94,6 +106,8 @@ typedef intptr_t ssize_t; #define ATOMIC_OR(DST, OP) DST |= OP #define ATOMIC_AND(DST, OP) DST &= OP #define ATOMIC_CMPXCHG(DST, EXPECTED, OP) ((DST == EXPECTED) ? ((DST = OP), true) : false) +#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC) #endif #if defined(_3DS) || defined(GEKKO) || defined(PSP2) diff --git a/src/util/ring-fifo.c b/src/util/ring-fifo.c index bdaac75aa..04d4d1022 100644 --- a/src/util/ring-fifo.c +++ b/src/util/ring-fifo.c @@ -25,8 +25,8 @@ size_t RingFIFOCapacity(const struct RingFIFO* buffer) { size_t RingFIFOSize(const struct RingFIFO* buffer) { const void* read; const void* write; - ATOMIC_LOAD(read, buffer->readPtr); - ATOMIC_LOAD(write, buffer->writePtr); + ATOMIC_LOAD_PTR(read, buffer->readPtr); + ATOMIC_LOAD_PTR(write, buffer->writePtr); if (read <= write) { return (uintptr_t) write - (uintptr_t) read; } else { @@ -35,14 +35,14 @@ size_t RingFIFOSize(const struct RingFIFO* buffer) { } void RingFIFOClear(struct RingFIFO* buffer) { - ATOMIC_STORE(buffer->readPtr, buffer->data); - ATOMIC_STORE(buffer->writePtr, buffer->data); + ATOMIC_STORE_PTR(buffer->readPtr, buffer->data); + ATOMIC_STORE_PTR(buffer->writePtr, buffer->data); } size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length) { void* data = buffer->writePtr; void* end; - ATOMIC_LOAD(end, buffer->readPtr); + ATOMIC_LOAD_PTR(end, buffer->readPtr); // Wrap around if we can't fit enough in here if ((uintptr_t) data - (uintptr_t) buffer->data + length >= buffer->capacity) { @@ -67,14 +67,14 @@ size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length) if (value) { memcpy(data, value, length); } - ATOMIC_STORE(buffer->writePtr, (void*) ((intptr_t) data + length)); + ATOMIC_STORE_PTR(buffer->writePtr, (void*) ((intptr_t) data + length)); return length; } size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length) { void* data = buffer->readPtr; void* end; - ATOMIC_LOAD(end, buffer->writePtr); + ATOMIC_LOAD_PTR(end, buffer->writePtr); // Wrap around if we can't fit enough in here if ((uintptr_t) data - (uintptr_t) buffer->data + length >= buffer->capacity) { @@ -99,6 +99,6 @@ size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length) { if (output) { memcpy(output, data, length); } - ATOMIC_STORE(buffer->readPtr, (void*) ((uintptr_t) data + length)); + ATOMIC_STORE_PTR(buffer->readPtr, (void*) ((uintptr_t) data + length)); return length; } From bb37a60765fafdce9db1aeb0f70f951c29522777 Mon Sep 17 00:00:00 2001 From: Le Hoang Quyen Date: Fri, 17 May 2019 17:07:40 -0700 Subject: [PATCH 229/429] Fixed link cable stability --- include/mgba/core/lockstep.h | 17 +++++ src/core/lockstep.c | 6 ++ src/gb/sio/lockstep.c | 1 - src/gba/sio/lockstep.c | 92 +++++++++++++++++++++-- src/platform/qt/MultiplayerController.cpp | 64 +++++++++------- src/platform/qt/MultiplayerController.h | 16 ++-- 6 files changed, 155 insertions(+), 41 deletions(-) diff --git a/include/mgba/core/lockstep.h b/include/mgba/core/lockstep.h index 06c1bc6b6..ac6cb3f84 100644 --- a/include/mgba/core/lockstep.h +++ b/include/mgba/core/lockstep.h @@ -23,10 +23,14 @@ struct mLockstep { enum mLockstepPhase transferActive; int32_t transferCycles; + void (*lock)(struct mLockstep*); + void (*unlock)(struct mLockstep*); + bool (*signal)(struct mLockstep*, unsigned mask); bool (*wait)(struct mLockstep*, unsigned mask); void (*addCycles)(struct mLockstep*, int id, int32_t cycles); int32_t (*useCycles)(struct mLockstep*, int id, int32_t cycles); + int32_t (*unusedCycles)(struct mLockstep*, int id); void (*unload)(struct mLockstep*, int id); void* context; #ifndef NDEBUG @@ -35,6 +39,19 @@ struct mLockstep { }; void mLockstepInit(struct mLockstep*); +void mLockstepDeinit(struct mLockstep*); + +static inline void mLockstepLock(struct mLockstep* lockstep) { + if (lockstep->lock) { + lockstep->lock(lockstep); + } +} + +static inline void mLockstepUnlock(struct mLockstep* lockstep) { + if (lockstep->unlock) { + lockstep->unlock(lockstep); + } +} CXX_GUARD_END diff --git a/src/core/lockstep.c b/src/core/lockstep.c index 40b1f1e2e..587cff2b5 100644 --- a/src/core/lockstep.c +++ b/src/core/lockstep.c @@ -11,6 +11,12 @@ void mLockstepInit(struct mLockstep* lockstep) { #ifndef NDEBUG lockstep->transferId = 0; #endif + lockstep->lock = NULL; + lockstep->unlock = NULL; +} + +void mLockstepDeinit(struct mLockstep* lockstep) { + UNUSED(lockstep); } // TODO: Migrate nodes diff --git a/src/gb/sio/lockstep.c b/src/gb/sio/lockstep.c index 2d4ec7546..b1d925ebc 100644 --- a/src/gb/sio/lockstep.c +++ b/src/gb/sio/lockstep.c @@ -17,7 +17,6 @@ static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t valu static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); void GBSIOLockstepInit(struct GBSIOLockstep* lockstep) { - mLockstepInit(&lockstep->d); lockstep->players[0] = NULL; lockstep->players[1] = NULL; lockstep->pendingSB[0] = 0xFF; diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 237eff493..356fa130a 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -8,7 +8,8 @@ #include #include -#define LOCKSTEP_INCREMENT 3000 +#define LOCKSTEP_INCREMENT 2000 +#define LOCKSTEP_TRANSFER 512 static bool GBASIOLockstepNodeInit(struct GBASIODriver* driver); static void GBASIOLockstepNodeDeinit(struct GBASIODriver* driver); @@ -17,9 +18,9 @@ static bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver); static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value); static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* driver, uint32_t cyclesLate); +static void _finishTransfer(struct GBASIOLockstepNode* node); void GBASIOLockstepInit(struct GBASIOLockstep* lockstep) { - mLockstepInit(&lockstep->d); lockstep->players[0] = 0; lockstep->players[1] = 0; lockstep->players[2] = 0; @@ -88,7 +89,11 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->nextEvent = 0; node->eventDiff = 0; mTimingSchedule(&driver->p->p->timing, &node->event, 0); + + mLockstepLock(&node->p->d); + node->mode = driver->p->mode; + switch (node->mode) { case SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; @@ -110,11 +115,17 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->phase = node->p->d.transferActive; node->transferId = node->p->d.transferId; #endif + + mLockstepUnlock(&node->p->d); + return true; } bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + + mLockstepLock(&node->p->d); + node->mode = driver->p->mode; switch (node->mode) { case SIO_MULTI: @@ -123,13 +134,43 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { default: break; } + + // Flush ongoing transfer + if (mTimingIsScheduled(&driver->p->p->timing, &node->event)) { + int oldWhen = node->event.when; + + mTimingDeschedule(&driver->p->p->timing, &node->event); + mTimingSchedule(&driver->p->p->timing, &node->event, 0); + node->eventDiff -= oldWhen - node->event.when; + mTimingDeschedule(&driver->p->p->timing, &node->event); + } + node->p->d.unload(&node->p->d, node->id); - mTimingDeschedule(&driver->p->p->timing, &node->event); + + node->p->multiRecv[0] = 0xFFFF; + node->p->multiRecv[1] = 0xFFFF; + node->p->multiRecv[2] = 0xFFFF; + node->p->multiRecv[3] = 0xFFFF; + + _finishTransfer(node); + + if (!node->id) { + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_IDLE); + } + + // Invalidate SIO mode + node->mode = SIO_GPIO; + + mLockstepUnlock(&node->p->d); + return true; } static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + + mLockstepLock(&node->p->d); + if (address == REG_SIOCNT) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value); @@ -141,8 +182,16 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->d.attached - 1]); + + bool scheduled = mTimingIsScheduled(&driver->p->p->timing, &node->event); + int oldWhen = node->event.when; + mTimingDeschedule(&driver->p->p->timing, &node->event); mTimingSchedule(&driver->p->p->timing, &node->event, 0); + + if (scheduled) { + node->eventDiff -= oldWhen - node->event.when; + } } else { value &= ~0x0080; } @@ -152,6 +201,9 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver } else if (address == REG_SIOMLT_SEND) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOMLT_SEND <- %04x", node->id, value); } + + mLockstepUnlock(&node->p->d); + return value; } @@ -159,6 +211,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { if (node->transferFinished) { return; } + struct GBASIO* sio = node->d.p; switch (node->mode) { case SIO_MULTI: @@ -230,18 +283,21 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { case TRANSFER_STARTING: // Start the transfer, but wait for the other GBAs to catch up node->transferFinished = false; - node->p->multiRecv[0] = 0xFFFF; + node->p->multiRecv[0] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1]; + node->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = 0xFFFF; + node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF; + node->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF; + node->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF; node->p->multiRecv[1] = 0xFFFF; node->p->multiRecv[2] = 0xFFFF; node->p->multiRecv[3] = 0xFFFF; needsToWait = true; ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTED); - node->nextEvent += 512; + node->nextEvent += LOCKSTEP_TRANSFER; break; case TRANSFER_STARTED: // All the other GBAs have caught up and are sleeping, we can all continue now - node->p->multiRecv[0] = node->d.p->p->memory.io[REG_SIOMLT_SEND >> 1]; - node->nextEvent += 512; + node->nextEvent += LOCKSTEP_TRANSFER; ATOMIC_STORE(node->p->d.transferActive, TRANSFER_FINISHING); break; case TRANSFER_FINISHING: @@ -281,6 +337,7 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { #ifndef NDEBUG node->phase = node->p->d.transferActive; #endif + if (needsToWait) { return 0; } @@ -307,6 +364,9 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { case TRANSFER_FINISHING: break; case TRANSFER_STARTED: + if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { + break; + } node->transferFinished = false; switch (node->mode) { case SIO_MULTI: @@ -334,6 +394,9 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { signal = true; break; case TRANSFER_FINISHED: + if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { + break; + } _finishTransfer(node); signal = true; break; @@ -344,16 +407,20 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { if (signal) { node->p->d.signal(&node->p->d, 1 << node->id); } + return 0; } static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { struct GBASIOLockstepNode* node = user; + mLockstepLock(&node->p->d); if (node->p->d.attached < 2) { + mLockstepUnlock(&node->p->d); return; } int32_t cycles = 0; node->nextEvent -= cyclesLate; + node->eventDiff += cyclesLate; if (node->nextEvent <= 0) { if (!node->id) { cycles = _masterUpdate(node); @@ -372,12 +439,18 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, mTimingSchedule(timing, &node->event, cycles); } else { node->d.p->p->earlyExit = true; - mTimingSchedule(timing, &node->event, cyclesLate + 1); + node->eventDiff += 1; + mTimingSchedule(timing, &node->event, 1); } + + mLockstepUnlock(&node->p->d); } static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* driver, uint32_t address, uint16_t value) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; + + mLockstepLock(&node->p->d); + if (address == REG_SIOCNT) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value); value &= 0xFF8B; @@ -401,5 +474,8 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive } else if (address == REG_SIODATA32_HI) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04x", node->id, value); } + + mLockstepUnlock(&node->p->d); + return value; } diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index ac68dd4bf..8387d3f03 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -16,26 +16,43 @@ using namespace QGBA; +MultiplayerController::Player::Player(CoreController* coreController, GBSIOLockstepNode* node) + : controller(coreController) + , gbNode(node) +{ +} + +MultiplayerController::Player::Player(CoreController* coreController, GBASIOLockstepNode* node) + : controller(coreController) + , gbaNode(node) +{ +} + MultiplayerController::MultiplayerController() { mLockstepInit(&m_lockstep); m_lockstep.context = this; + m_lockstep.lock = [](mLockstep* lockstep) { + MultiplayerController* controller = static_cast(lockstep->context); + controller->m_lock.lock(); + }; + m_lockstep.unlock = [](mLockstep* lockstep) { + MultiplayerController* controller = static_cast(lockstep->context); + controller->m_lock.unlock(); + }; m_lockstep.signal = [](mLockstep* lockstep, unsigned mask) { MultiplayerController* controller = static_cast(lockstep->context); Player* player = &controller->m_players[0]; bool woke = false; - controller->m_lock.lock(); player->waitMask &= ~mask; if (!player->waitMask && player->awake < 1) { mCoreThreadStopWaiting(player->controller->thread()); player->awake = 1; woke = true; } - controller->m_lock.unlock(); return woke; }; m_lockstep.wait = [](mLockstep* lockstep, unsigned mask) { MultiplayerController* controller = static_cast(lockstep->context); - controller->m_lock.lock(); Player* player = &controller->m_players[0]; bool slept = false; player->waitMask |= mask; @@ -44,7 +61,6 @@ MultiplayerController::MultiplayerController() { player->awake = 0; slept = true; } - controller->m_lock.unlock(); return slept; }; m_lockstep.addCycles = [](mLockstep* lockstep, int id, int32_t cycles) { @@ -52,7 +68,6 @@ MultiplayerController::MultiplayerController() { abort(); } MultiplayerController* controller = static_cast(lockstep->context); - controller->m_lock.lock(); if (!id) { for (int i = 1; i < controller->m_players.count(); ++i) { Player* player = &controller->m_players[i]; @@ -85,11 +100,9 @@ MultiplayerController::MultiplayerController() { controller->m_players[id].controller->setSync(true); controller->m_players[id].cyclesPosted += cycles; } - controller->m_lock.unlock(); }; m_lockstep.useCycles = [](mLockstep* lockstep, int id, int32_t cycles) { MultiplayerController* controller = static_cast(lockstep->context); - controller->m_lock.lock(); Player* player = &controller->m_players[id]; player->cyclesPosted -= cycles; if (player->cyclesPosted <= 0) { @@ -97,15 +110,23 @@ MultiplayerController::MultiplayerController() { player->awake = 0; } cycles = player->cyclesPosted; - controller->m_lock.unlock(); + return cycles; + }; + m_lockstep.unusedCycles= [](mLockstep* lockstep, int id) { + MultiplayerController* controller = static_cast(lockstep->context); + Player* player = &controller->m_players[id]; + auto cycles = player->cyclesPosted; return cycles; }; m_lockstep.unload = [](mLockstep* lockstep, int id) { MultiplayerController* controller = static_cast(lockstep->context); - controller->m_lock.lock(); - Player* player = &controller->m_players[id]; if (id) { + Player* player = &controller->m_players[id]; player->controller->setSync(true); + player->cyclesPosted = 0; + + // release master GBA if it is waiting for this GBA + player = &controller->m_players[0]; player->waitMask &= ~(1 << id); if (!player->waitMask && player->awake < 1) { mCoreThreadStopWaiting(player->controller->thread()); @@ -149,10 +170,13 @@ MultiplayerController::MultiplayerController() { } } } - controller->m_lock.unlock(); }; } +MultiplayerController::~MultiplayerController() { + mLockstepDeinit(&m_lockstep); +} + bool MultiplayerController::attachGame(CoreController* controller) { if (m_lockstep.attached == MAX_GBAS) { return false; @@ -188,14 +212,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBASIOLockstepNode* node = new GBASIOLockstepNode; GBASIOLockstepNodeCreate(node); GBASIOLockstepAttachNode(&m_gbaLockstep, node); - m_players.append({ - controller, - nullptr, - node, - 1, - 0, - 0 - }); + m_players.append({controller, node}); GBASIOSetDriver(&gba->sio, &node->d, SIO_MULTI); @@ -210,14 +227,7 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBSIOLockstepNode* node = new GBSIOLockstepNode; GBSIOLockstepNodeCreate(node); GBSIOLockstepAttachNode(&m_gbLockstep, node); - m_players.append({ - controller, - node, - nullptr, - 1, - 0, - 0 - }); + m_players.append({controller, node}); GBSIOSetDriver(&gb->sio, &node->d); diff --git a/src/platform/qt/MultiplayerController.h b/src/platform/qt/MultiplayerController.h index fefba4cb4..4614c5c6f 100644 --- a/src/platform/qt/MultiplayerController.h +++ b/src/platform/qt/MultiplayerController.h @@ -17,6 +17,8 @@ #include #endif +#include + struct GBSIOLockstepNode; struct GBASIOLockstepNode; @@ -29,6 +31,7 @@ Q_OBJECT public: MultiplayerController(); + ~MultiplayerController(); bool attachGame(CoreController*); void detachGame(CoreController*); @@ -42,12 +45,15 @@ signals: private: struct Player { + Player(CoreController* controller, GBSIOLockstepNode* node); + Player(CoreController* controller, GBASIOLockstepNode* node); + CoreController* controller; - GBSIOLockstepNode* gbNode; - GBASIOLockstepNode* gbaNode; - int awake; - int32_t cyclesPosted; - unsigned waitMask; + GBSIOLockstepNode* gbNode = nullptr; + GBASIOLockstepNode* gbaNode = nullptr; + int awake = 1; + int32_t cyclesPosted = 0; + unsigned waitMask = 0; }; union { mLockstep m_lockstep; From e928c451eb1fd41d772af907430e29e657451a98 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 17:13:03 -0700 Subject: [PATCH 230/429] CHANGES: Update --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 250a7dcd4..a63135d32 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ Features: - Support Discord Rich Presence - Debugger: Add tracing to file - Map viewer supports bitmapped GBA modes + - OpenGL renderer with high-resolution upscaling support Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs @@ -40,6 +41,7 @@ Other fixes: - Wii: Fix aspect ratio (fixes mgba.io/i/500) - Qt: Fix some Qt display driver race conditions - FFmpeg: Fix audio conversion producing gaps + - Core: Improved lockstep driver reliability (Le Hoang Quyen) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash From 768aa0ddc2460bae1238af9db5d62c114fb88527 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 19:25:25 -0700 Subject: [PATCH 231/429] GL: Fix FreeBSD build --- src/platform/sdl/gles2-sdl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 675a1139c..1cedc5ad5 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -13,7 +13,7 @@ #include #include -#ifndef __APPLE__ +#ifdef __linux__ #include #endif @@ -37,7 +37,7 @@ bool mSDLGLES2Init(struct mSDLRenderer* renderer) { size_t size = renderer->width * renderer->height * BYTES_PER_PIXEL; #ifdef _WIN32 renderer->outputBuffer = _aligned_malloc(size, 16); -#elif !defined(__APPLE__) +#elif defined(__linux__) renderer->outputBuffer = memalign(16, size); #else posix_memalign((void**) &renderer->outputBuffer, 16, size); From 320971af93a673400abd7b85427b8ecb763f5dcf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 19:39:20 -0700 Subject: [PATCH 232/429] Qt: Fix Windows build --- src/platform/qt/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 98a0a9e5a..b0b4e5fff 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -288,6 +288,7 @@ if(QT_STATIC) if(WIN32) list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport Qt5WindowsUIAutomationSupport) set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32") + set_target_properties(Qt5::Gui PROPERTIES INTERFACE_LINK_LIBRARIES ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY}) elseif(APPLE) find_package(Cups) find_package(Qt5PrintSupport) From 921f3f864d8e53c9e33dc149985abaf2eb19c8a1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 19:53:46 -0700 Subject: [PATCH 233/429] Qt: Fall back to 1.4 if 2.x context is bad --- src/platform/qt/DisplayGL.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 0df112e06..1d1e79424 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -34,12 +34,29 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) : Display(parent) , m_gl(nullptr) { + setAttribute(Qt::WA_NativeWindow); + // This can spontaneously re-enter into this->resizeEvent before creation is done, so we // need to make sure it's initialized to nullptr before we assign the new object to it m_gl = new QOpenGLContext; m_gl->setFormat(format); m_gl->create(); - setAttribute(Qt::WA_NativeWindow); + + m_gl->makeCurrent(windowHandle()); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif + int majorVersion = m_gl->format().majorVersion(); + QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); + m_gl->doneCurrent(); + + if (majorVersion == 2 && !extensions.contains("GL_ARB_framebuffer_object")) { + QSurfaceFormat newFormat(format); + newFormat.setVersion(1, 4); + m_gl->setFormat(newFormat); + m_gl->create(); + } + m_painter = new PainterGL(&m_videoProxy, windowHandle(), m_gl); setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions From 6890c070e6e0c868312482a442e2b22f757b5edc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 21:14:51 -0700 Subject: [PATCH 234/429] GBA Video: Fix GL mode 2 distortion --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 49 ++++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 209607f1c..b40103ba8 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -91,6 +91,7 @@ enum { GBA_GL_BG_OFFSET, GBA_GL_BG_INFLAGS, GBA_GL_BG_TRANSFORM, + GBA_GL_BG_RANGE, GBA_GL_OBJ_VRAM = 2, GBA_GL_OBJ_PALETTE, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 81fc5cdb8..5b2a41eca 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -41,7 +41,7 @@ static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y); -static void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y); +static void _finalizeLayers(struct GBAVideoGLRenderer* renderer); #define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 @@ -168,6 +168,7 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, { 0 } }; @@ -181,6 +182,7 @@ static const char* const _renderMode2 = "uniform ivec4 inflags;\n" "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" + "uniform vec2 range;\n" "out vec4 color;\n" "out vec4 flags;\n" "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" @@ -215,8 +217,8 @@ static const char* const _renderMode2 = "}\n" "void main() {\n" - " float y = fract(texCoord.y);\n" - " float lin = 0.5 - y / ceil(y) * 0.25;\n" + " float y = texCoord.y - range.x;\n" + " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " color = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" @@ -842,9 +844,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); glRenderer->firstAffine = y; - } else if (y - glRenderer->firstAffine == 1) { - memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); } } else { glRenderer->firstAffine = -1; @@ -903,7 +902,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { break; } } - _finalizeLayers(glRenderer, y); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); @@ -922,6 +920,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + _finalizeLayers(glRenderer); glRenderer->firstAffine = -1; glRenderer->bg[2].affine[0].sx = glRenderer->bg[2].refx; glRenderer->bg[2].affine[0].sy = glRenderer->bg[2].refy; @@ -1021,11 +1020,11 @@ static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, u renderer->target2Bd = GBARegisterBLDCNTGetTarget2Bd(value); } -void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { +void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { const GLuint* uniforms = renderer->finalizeShader.uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); + glScissor(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glUseProgram(renderer->finalizeShader.program); glBindVertexArray(renderer->finalizeShader.vao); glActiveTexture(GL_TEXTURE0); @@ -1052,7 +1051,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer, int y) { glBindTexture(GL_TEXTURE_2D, renderer->bg[3].flags); uint32_t backdrop = M_RGB5_TO_RGB8(renderer->d.palette[0]); - glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); + glUniform2i(uniforms[GBA_GL_VS_LOC], GBA_VIDEO_VERTICAL_PIXELS, 0); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); glUniform1iv(uniforms[GBA_GL_FINALIZE_LAYERS], 5, (GLint[]) { 3, 5, 7, 9, 1 }); @@ -1177,24 +1176,50 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + int reverse; + int forward; + switch (y - renderer->firstAffine) { + case 0: + case 1: + case 2: + case 3: + return; + case 4: + forward = 2; + reverse = 4; + break; + case 5: + forward = 2; + reverse = 3; + break; + case 6: + forward = 2; + reverse = 2; + break; + default: + forward = 1; + reverse = 1; + } + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); + glScissor(0, (y - reverse) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * forward); glUseProgram(shader->program); glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); + glUniform2i(uniforms[GBA_GL_VS_LOC], forward, y - reverse); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); + glUniform2f(uniforms[GBA_GL_BG_RANGE], y, 1); glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); From 876c3051c2d056a6fc1e7fb5b37b9718756feb3a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 21:29:01 -0700 Subject: [PATCH 235/429] GBA Video: Move bldy to WINDOW tex --- src/gba/renderers/gl.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 5b2a41eca..00f8465d3 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -314,8 +314,8 @@ static const char* const _finalize = "}\n" "void main() {\n" - " ivec2 windowFlags = ivec2(texelFetch(window, ivec2(texCoord * scale), 0).xy * 32);\n" - " int layerWindow = windowFlags.x | (windowFlags.y << 4);\n" + " vec4 windowFlags = texelFetch(window, ivec2(texCoord * scale), 0);\n" + " int layerWindow = int(windowFlags.x * 32) | int(windowFlags.y * 512);\n" " vec4 topPixel = backdrop;\n" " vec4 bottomPixel = backdrop;\n" " ivec4 topFlags = ivec4(backdropFlags * flagCoeff);\n" @@ -354,9 +354,9 @@ static const char* const _finalize = " topPixel += bottomPixel * bottomFlags.w / 16.;\n" " }\n" " } else if ((topFlags.y & 13) == 9) {\n" - " topPixel += (1. - topPixel) * topFlags.z / 16.;\n" + " topPixel += (1. - topPixel) * windowFlags.z;\n" " } else if ((topFlags.y & 13) == 13) {\n" - " topPixel -= topPixel * topFlags.z / 16.;\n" + " topPixel -= topPixel * windowFlags.z;\n" " }\n" " color = topPixel;\n" "}"; @@ -459,7 +459,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RG, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); _initFramebufferTexture(glRenderer->outputTex, GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -1058,8 +1058,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, - (renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy) / 16.f, renderer->bldb / 16.f); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, renderer->blda / 16.f, renderer->bldb / 16.f); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1111,8 +1110,8 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(uniforms[GBA_GL_OBJ_STRIDE], stride); glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c) << 3, - (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), - blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); + (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), + renderer->blda, renderer->bldb); if (GBAObjAttributesAIsTransformed(sprite->a)) { struct GBAOAMMatrix mat; LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); @@ -1168,7 +1167,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); + renderer->blda, renderer->bldb); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1221,8 +1220,8 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); glUniform2f(uniforms[GBA_GL_BG_RANGE], y, 1); glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, - background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blendEffect == BLEND_ALPHA ? renderer->blda : renderer->bldy, renderer->bldb); + background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), + renderer->blda, renderer->bldb); if (renderer->scale > 1) { glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, @@ -1256,10 +1255,10 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale) { +static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale, int bldy) { glScissor(start, y, end - start, scale); window = ~window & 0xFF; - glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, 0, 0); + glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, bldy / 16.f, 0); glClear(GL_COLOR_BUFFER_BIT); } @@ -1267,14 +1266,14 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); } else { - _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale); + _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); } } } From ebb6d659455fca127e88d3e3eb0f4b81099a09d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 21:41:35 -0700 Subject: [PATCH 236/429] GBA Video: Fix GL degenerate windows --- src/gba/renderers/gl.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 00f8465d3..f3a76d0af 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1256,7 +1256,12 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, } static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale, int bldy) { - glScissor(start, y, end - start, scale); + if (start > end) { + _clearWindow(window, start, GBA_VIDEO_HORIZONTAL_PIXELS, y, scale, bldy); + _clearWindow(window, 0, end, y, scale, bldy); + return; + } + glScissor(start * scale, y, (end - start) * scale, scale); window = ~window & 0xFF; glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, bldy / 16.f, 0); glClear(GL_COLOR_BUFFER_BIT); @@ -1266,14 +1271,14 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS, y * renderer->scale, renderer->scale, renderer->bldy); } else { - _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS, y * renderer->scale, renderer->scale, renderer->bldy); if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start * renderer->scale, renderer->winN[1].h.end * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start, renderer->winN[1].h.end, y * renderer->scale, renderer->scale, renderer->bldy); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start * renderer->scale, renderer->winN[0].h.end * renderer->scale, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start, renderer->winN[0].h.end, y * renderer->scale, renderer->scale, renderer->bldy); } } } From 43180dca1df957a9e82f08edbf02cd19b00248e8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 00:37:54 -0700 Subject: [PATCH 237/429] GBA Video: Window interpolation --- include/mgba/internal/gba/renderers/gl.h | 2 +- src/gba/renderers/gl.c | 88 +++++++++++++++++------- 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index b40103ba8..479a0b66f 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -163,7 +163,7 @@ struct GBAVideoGLRenderer { GBAMosaicControl mosaic; struct GBAVideoGLWindowN { - struct GBAVideoWindowRegion h; + struct GBAVideoWindowRegion h[2]; struct GBAVideoWindowRegion v; GBAWindowControl control; } winN[2]; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index f3a76d0af..805c3f943 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -727,28 +727,28 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, glRenderer->bldy = value; break; case REG_WIN0H: - glRenderer->winN[0].h.end = value; - glRenderer->winN[0].h.start = value >> 8; - if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h.start > glRenderer->winN[0].h.end) { - glRenderer->winN[0].h.start = 0; + glRenderer->winN[0].h[0].end = value; + glRenderer->winN[0].h[0].start = value >> 8; + if (glRenderer->winN[0].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h[0].start > glRenderer->winN[0].h[0].end) { + glRenderer->winN[0].h[0].start = 0; } - if (glRenderer->winN[0].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[0].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; - if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[0].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[0].h[0].end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h[0].end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[0].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h[0].start = GBA_VIDEO_HORIZONTAL_PIXELS; } } break; case REG_WIN1H: - glRenderer->winN[1].h.end = value; - glRenderer->winN[1].h.start = value >> 8; - if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h.start > glRenderer->winN[1].h.end) { - glRenderer->winN[1].h.start = 0; + glRenderer->winN[1].h[0].end = value; + glRenderer->winN[1].h[0].start = value >> 8; + if (glRenderer->winN[1].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h[0].start > glRenderer->winN[1].h[0].end) { + glRenderer->winN[1].h[0].start = 0; } - if (glRenderer->winN[1].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[1].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; - if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[1].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[1].h[0].end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h[0].end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[1].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h[0].start = GBA_VIDEO_HORIZONTAL_PIXELS; } } break; @@ -820,6 +820,9 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->vramDirty = 0; if (y == 0) { + memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); + memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); + glDisable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); @@ -916,6 +919,8 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->bg[3].affine[0].sx += glRenderer->bg[3].affine[0].dmx; glRenderer->bg[3].affine[0].sy += glRenderer->bg[3].affine[0].dmy; } + memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); + memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { @@ -1255,30 +1260,63 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -static void _clearWindow(GBAWindowControl window, int start, int end, int y, int scale, int bldy) { +static void _scissorWindow(int start, int end, int y, int lines, int scale) { if (start > end) { - _clearWindow(window, start, GBA_VIDEO_HORIZONTAL_PIXELS, y, scale, bldy); - _clearWindow(window, 0, end, y, scale, bldy); + _scissorWindow(start, GBA_VIDEO_HORIZONTAL_PIXELS * scale, y, lines, scale); + _scissorWindow(0, end, y, lines, scale); return; } - glScissor(start * scale, y, (end - start) * scale, scale); + glScissor(start, y, end - start, lines); + glClear(GL_COLOR_BUFFER_BIT); +} + +static void _scissorWindowN(struct GBAVideoWindowRegion* region, int y, int scale) { + int sdelta = region[0].start - region[1].start; + int edelta = region[0].end - region[1].end; + int maxDelta = 0; + if (sdelta > maxDelta) { + maxDelta = sdelta; + } else if (-sdelta > maxDelta) { + maxDelta = -sdelta; + } + if (edelta > maxDelta) { + maxDelta = edelta; + } else if (-edelta > maxDelta) { + maxDelta = -edelta; + } + if (!(sdelta | edelta) || maxDelta >= GBA_VIDEO_VERTICAL_PIXELS / 2) { + _scissorWindow(region[0].start * scale, region[0].end * scale, y, scale, scale); + } else { + int i; + for (i = 0; i < scale; ++i) { + int start = region[1].start * scale + sdelta * i; + int end = region[1].end * scale + edelta * i; + _scissorWindow(start, end, y + i, 1, scale); + } + } +} + +static void _clearWindow(GBAWindowControl window, int bldy) { window = ~window & 0xFF; glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, bldy / 16.f, 0); - glClear(GL_COLOR_BUFFER_BIT); } void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(dispcnt, renderer->bldy); + _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); } else { - _clearWindow(renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winout & dispcnt, renderer->bldy); + _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control & dispcnt, renderer->winN[1].h.start, renderer->winN[1].h.end, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winN[1].control & dispcnt, renderer->bldy); + _scissorWindowN(renderer->winN[1].h, y * renderer->scale, renderer->scale); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control & dispcnt, renderer->winN[0].h.start, renderer->winN[0].h.end, y * renderer->scale, renderer->scale, renderer->bldy); + _clearWindow(renderer->winN[0].control & dispcnt, renderer->bldy); + _scissorWindowN(renderer->winN[0].h, y * renderer->scale, renderer->scale); } } } From 71b6066d4f6aecc85dc1dafc92cecaf6154f8f4a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 01:09:29 -0700 Subject: [PATCH 238/429] GBA Video: Fix some GL handle leaks --- src/gba/renderers/gl.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 805c3f943..96a22501b 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -390,7 +390,7 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->scale = 1; } -void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, char* log) { +static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShader* shader, const char** shaderBuffer, int shaderBufferLines, GLuint vs, const struct GBAVideoGLUniform* uniforms, char* log) { GLuint program = glCreateProgram(); shader->program = program; @@ -426,6 +426,11 @@ void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVideoGLShad } } +static void _deleteShader(struct GBAVideoGLShader* shader) { + glDeleteProgram(shader->program); + glDeleteVertexArrays(1, &shader->vao); +} + static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -564,6 +569,22 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); + + _deleteShader(&glRenderer->bgShader[0]); + _deleteShader(&glRenderer->bgShader[1]); + _deleteShader(&glRenderer->bgShader[2]); + _deleteShader(&glRenderer->bgShader[3]); + _deleteShader(&glRenderer->objShader[0]); + _deleteShader(&glRenderer->objShader[1]); + _deleteShader(&glRenderer->finalizeShader); + + int i; + for (i = 0; i < 4; ++i) { + struct GBAVideoGLBackground* bg = &glRenderer->bg[i]; + glDeleteFramebuffers(1, &bg->fbo); + glDeleteTextures(1, &bg->tex); + glDeleteTextures(1, &bg->flags); + } } void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { From 91cd47ee0e6c710d6f59ac3a7a5639fcd48f23e2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 10:38:23 -0700 Subject: [PATCH 239/429] GBA Video: Fix OBJWIN in GL renderer --- src/gba/renderers/gl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 96a22501b..76365a965 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -250,10 +250,10 @@ static const char* const _renderObj = "uniform ivec4 inflags;\n" "uniform mat2x2 transform;\n" "uniform ivec4 dims;\n" - "uniform vec3 objwin;\n" + "uniform vec4 objwin;\n" "out vec4 color;\n" "out vec4 flags;\n" - "out vec2 window;\n" + "out vec3 window;\n" "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -269,7 +269,7 @@ static const char* const _renderObj = " }\n" " color = pix;\n" " flags = inflags / flagCoeff;\n" - " window = objwin.yz;\n" + " window = objwin.yzw;\n" "}"; static const struct GBAVideoGLUniform _uniformsFinalize[] = { @@ -462,6 +462,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -1152,10 +1153,10 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { int window = ~renderer->objwin & 0xFF; - glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f); + glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f, renderer->bldy / 16.f); glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); } else { - glUniform3f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0); + glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } glEnableVertexAttribArray(0); From 3abee66ae6fd1b572448d2ad241f2f531e1fe4fc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 13:53:13 -0700 Subject: [PATCH 240/429] GBA Video: Mode 2 tweaks --- src/gba/renderers/gl.c | 51 ++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 76365a965..ee0dcff77 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -221,7 +221,7 @@ static const char* const _renderMode2 = " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " color = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" + " color = fetchTile(ivec2(mixedTransform * (texCoord.x - 1) + mixedOffset));\n" " flags = inflags / flagCoeff;\n" "}"; @@ -1202,29 +1202,32 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { - int reverse; - int forward; - switch (y - renderer->firstAffine) { - case 0: - case 1: - case 2: - case 3: - return; - case 4: - forward = 2; - reverse = 4; - break; - case 5: - forward = 2; - reverse = 3; - break; - case 6: - forward = 2; - reverse = 2; - break; - default: - forward = 1; - reverse = 1; + int reverse = 0; + int forward = 1; + if (renderer->scale > 1) { + switch (y - renderer->firstAffine) { + case 0: + case 1: + case 2: + case 3: + return; + case 4: + forward = 2; + reverse = 4; + break; + case 5: + forward = 2; + reverse = 3; + break; + case 6: + forward = 2; + reverse = 2; + break; + case 7: + forward = 2; + reverse = 1; + break; + } } const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; From c5ae273a3a786a00dbe470fac01885819e86e958 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 14:00:34 -0700 Subject: [PATCH 241/429] GBA Video: Move all window bits to x --- src/gba/renderers/gl.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ee0dcff77..24ec58d70 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,6 +13,8 @@ #include #include +#define FLAG_CONST "const vec4 flagCoeff = vec4(64., 32., 16., 16.);\n" + static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer); @@ -116,7 +118,7 @@ static const char* const _renderMode0 = "uniform ivec4 inflags;\n" "out vec4 color;\n" "out vec4 flags;\n" - "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + FLAG_CONST "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -185,7 +187,7 @@ static const char* const _renderMode2 = "uniform vec2 range;\n" "out vec4 color;\n" "out vec4 flags;\n" - "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + FLAG_CONST "precision highp float;\n" "precision highp int;\n" @@ -254,7 +256,7 @@ static const char* const _renderObj = "out vec4 color;\n" "out vec4 flags;\n" "out vec3 window;\n" - "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + FLAG_CONST "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -292,7 +294,7 @@ static const char* const _finalize = "uniform sampler2D window;\n" "uniform vec4 backdrop;\n" "uniform vec4 backdropFlags;\n" - "const vec4 flagCoeff = vec4(32., 32., 16., 16.);\n" + FLAG_CONST "out vec4 color;\n" "void composite(vec4 pixel, ivec4 flags, inout vec4 topPixel, inout ivec4 topFlags, inout vec4 bottomPixel, inout ivec4 bottomFlags) {\n" @@ -315,7 +317,7 @@ static const char* const _finalize = "void main() {\n" " vec4 windowFlags = texelFetch(window, ivec2(texCoord * scale), 0);\n" - " int layerWindow = int(windowFlags.x * 32) | int(windowFlags.y * 512);\n" + " int layerWindow = int(windowFlags.x * 128);\n" " vec4 topPixel = backdrop;\n" " vec4 bottomPixel = backdrop;\n" " ivec4 topFlags = ivec4(backdropFlags * flagCoeff);\n" @@ -1085,7 +1087,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, renderer->blda / 16.f, renderer->bldb / 16.f); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 64.f, renderer->blda / 16.f, renderer->bldb / 16.f); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1152,8 +1154,8 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { - int window = ~renderer->objwin & 0xFF; - glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, (window & 0xF) / 32.f, (window >> 4) / 32.f, renderer->bldy / 16.f); + int window = ~renderer->objwin & 0x3F; + glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, window / 128.f, 0, renderer->bldy / 16.f); glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); } else { glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); @@ -1322,8 +1324,8 @@ static void _scissorWindowN(struct GBAVideoWindowRegion* region, int y, int scal } static void _clearWindow(GBAWindowControl window, int bldy) { - window = ~window & 0xFF; - glClearColor((window & 0xF) / 32.f, (window >> 4) / 32.f, bldy / 16.f, 0); + window = ~window & 0x3F; + glClearColor(window / 128.f, 0, bldy / 16.f, 0); } void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { From 28bd97310da51fc5c1cfe57932140ec465f941a8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 14:20:08 -0700 Subject: [PATCH 242/429] GBA Video: Move bldb to window w --- src/gba/renderers/gl.c | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 24ec58d70..c9a968334 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,7 +13,7 @@ #include #include -#define FLAG_CONST "const vec4 flagCoeff = vec4(64., 32., 16., 16.);\n" +#define FLAG_CONST "const vec4 flagCoeff = vec4(64., 32., 16., 1.);\n" static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); @@ -324,36 +324,36 @@ static const char* const _finalize = " ivec4 bottomFlags = ivec4(backdropFlags * flagCoeff);\n" " if ((layerWindow & 1) == 0) {\n" " vec4 pix = texelFetch(layers[0], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 2) == 0) {\n" " vec4 pix = texelFetch(layers[1], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 4) == 0) {\n" " vec4 pix = texelFetch(layers[2], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 8) == 0) {\n" " vec4 pix = texelFetch(layers[3], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 32) != 0) {\n" - " topFlags.y &= ~1;\n" - " }\n" " if ((layerWindow & 16) == 0) {\n" " vec4 pix = texelFetch(layers[4], ivec2(texCoord * scale), 0);\n" " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * scale), 0) * flagCoeff);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((topFlags.y & 13) == 5) {\n" + " if ((layerWindow & 32) != 0) {\n" + " topFlags.y &= ~1;\n" + " }\n" + " if ((topFlags.y & 13) == 5 || topFlags.w > 0) {\n" " if ((bottomFlags.y & 2) == 2) {\n" " topPixel *= topFlags.z / 16.;\n" - " topPixel += bottomPixel * bottomFlags.w / 16.;\n" + " topPixel += bottomPixel * windowFlags.y;\n" " }\n" " } else if ((topFlags.y & 13) == 9) {\n" " topPixel += (1. - topPixel) * windowFlags.z;\n" @@ -507,7 +507,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glGenTextures(1, &bg->flags); glBindFramebuffer(GL_FRAMEBUFFER, bg->fbo); _initFramebufferTexture(bg->tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); - _initFramebufferTexture(bg->flags, GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); + _initFramebufferTexture(bg->flags, GL_RGB, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1087,7 +1087,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 64.f, renderer->blda / 16.f, renderer->bldb / 16.f); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 64.f, renderer->blda / 16.f, 0); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -1140,7 +1140,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c) << 3, (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), - renderer->blda, renderer->bldb); + renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); if (GBAObjAttributesAIsTransformed(sprite->a)) { struct GBAOAMMatrix mat; LOAD_16(mat.a, 0, &renderer->d.oam->mat[GBAObjAttributesBGetMatIndex(sprite->b)].a); @@ -1155,7 +1155,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { int window = ~renderer->objwin & 0x3F; - glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, window / 128.f, 0, renderer->bldy / 16.f); + glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, window / 128.f, renderer->bldb / 16.f, renderer->bldy / 16.f); glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); } else { glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); @@ -1196,7 +1196,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blda, renderer->bldb); + renderer->blda, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -1253,7 +1253,7 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform2f(uniforms[GBA_GL_BG_RANGE], y, 1); glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blda, renderer->bldb); + renderer->blda, 0); if (renderer->scale > 1) { glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, @@ -1323,26 +1323,26 @@ static void _scissorWindowN(struct GBAVideoWindowRegion* region, int y, int scal } } -static void _clearWindow(GBAWindowControl window, int bldy) { +static void _clearWindow(GBAWindowControl window, int bldb, int bldy) { window = ~window & 0x3F; - glClearColor(window / 128.f, 0, bldy / 16.f, 0); + glClearColor(window / 128.f, bldb / 16.f, bldy / 16.f, 0); } void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(dispcnt, renderer->bldy); + _clearWindow(dispcnt, renderer->bldb, renderer->bldy); _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); } else { - _clearWindow(renderer->winout & dispcnt, renderer->bldy); + _clearWindow(renderer->winout & dispcnt, renderer->bldb, renderer->bldy); _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control & dispcnt, renderer->bldy); + _clearWindow(renderer->winN[1].control & dispcnt, renderer->bldb, renderer->bldy); _scissorWindowN(renderer->winN[1].h, y * renderer->scale, renderer->scale); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control & dispcnt, renderer->bldy); + _clearWindow(renderer->winN[0].control & dispcnt, renderer->bldb, renderer->bldy); _scissorWindowN(renderer->winN[0].h, y * renderer->scale, renderer->scale); } } From 20ea552d17f66519231b4d81c815a522b18c71a3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 15:40:32 -0700 Subject: [PATCH 243/429] GBA Video: GL mode 4, cleanup --- src/gba/renderers/gl.c | 166 +++++++++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 48 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c9a968334..4b9dcd2aa 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -174,6 +174,15 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { { 0 } }; +static const char* const _interpolate = + "vec2 interpolate(ivec2 arr[4], float x) {\n" + " float x1m = 1. - x;\n" + " return x1m * x1m * x1m * arr[0] +" + " 3 * x1m * x1m * x * arr[1] +" + " 3 * x1m * x * x * arr[2] +" + " x * x * x * arr[3];\n" + "}\n"; + static const char* const _renderMode2 = "in vec2 texCoord;\n" "uniform sampler2D vram;\n" @@ -192,6 +201,7 @@ static const char* const _renderMode2 = "precision highp int;\n" "vec4 fetchTile(ivec2 coord);\n" + "vec2 interpolate(ivec2 arr[4], float x);\n" "vec4 renderTile(ivec2 coord) {\n" " int map = (coord.x >> 11) + (((coord.y >> 7) & 0x7F0) << size);\n" @@ -210,20 +220,64 @@ static const char* const _renderMode2 = " return color;\n" "}\n" - "vec2 interpolate(ivec2 arr[4], float x) {\n" - " float x1m = 1. - x;\n" - " return x1m * x1m * x1m * arr[0] +" - " 3 * x1m * x1m * x * arr[1] +" - " 3 * x1m * x * x * arr[2] +" - " x * x * x * arr[3];\n" - "}\n" + "void main() {\n" + " float y = texCoord.y - range.x;\n" + " float lin = 0.5 - y / range.y * 0.25;\n" + " vec2 mixedTransform = interpolate(transform, lin);\n" + " vec2 mixedOffset = interpolate(offset, lin);\n" + " color = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" + " flags = inflags / flagCoeff;\n" + "}"; + +static const struct GBAVideoGLUniform _uniformsMode4[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "vram", GBA_GL_BG_VRAM, }, + { "palette", GBA_GL_BG_PALETTE, }, + { "charBase", GBA_GL_BG_CHARBASE, }, + { "size", GBA_GL_BG_SIZE, }, + { "inflags", GBA_GL_BG_INFLAGS, }, + { "offset", GBA_GL_BG_OFFSET, }, + { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, + { 0 } +}; + +static const char* const _renderMode4 = + "in vec2 texCoord;\n" + "uniform sampler2D vram;\n" + "uniform sampler2D palette;\n" + "uniform int charBase;\n" + "uniform ivec2 size;\n" + "uniform ivec4 inflags;\n" + "uniform ivec2[4] offset;\n" + "uniform ivec2[4] transform;\n" + "uniform vec2 range;\n" + "out vec4 color;\n" + "out vec4 flags;\n" + FLAG_CONST + "precision highp float;\n" + "precision highp int;\n" + + "vec2 interpolate(ivec2 arr[4], float x);\n" "void main() {\n" " float y = texCoord.y - range.x;\n" " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " color = fetchTile(ivec2(mixedTransform * (texCoord.x - 1) + mixedOffset));\n" + " ivec2 coord = ivec2(mixedTransform * texCoord.x + mixedOffset);\n" + " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" + " discard;\n" + " }\n" + " if (coord.y < 0 || coord.y >= (size.y << 8)) {\n" + " discard;\n" + " }\n" + " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" + " vec4 twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0);\n" + " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" + " color = texelFetch(palette, entry, 0);\n" + " color.a = 1;\n" " flags = inflags / flagCoeff;\n" "}"; @@ -533,12 +587,17 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _compileShader(glRenderer, &glRenderer->bgShader[1], shaderBuffer, 3, vs, _uniformsMode0, log); shaderBuffer[1] = _renderMode2; + shaderBuffer[2] = _interpolate; - shaderBuffer[2] = _fetchTileOverflow; - _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 3, vs, _uniformsMode2, log); + shaderBuffer[3] = _fetchTileOverflow; + _compileShader(glRenderer, &glRenderer->bgShader[2], shaderBuffer, 4, vs, _uniformsMode2, log); - shaderBuffer[2] = _fetchTileNoOverflow; - _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 3, vs, _uniformsMode2, log); + shaderBuffer[3] = _fetchTileNoOverflow; + _compileShader(glRenderer, &glRenderer->bgShader[3], shaderBuffer, 4, vs, _uniformsMode2, log); + + shaderBuffer[1] = _renderMode4; + shaderBuffer[2] = _interpolate; + _compileShader(glRenderer, &glRenderer->bgShader[4], shaderBuffer, 3, vs, _uniformsMode4, log); shaderBuffer[1] = _renderObj; @@ -912,7 +971,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); break; case 4: - //GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); + GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); break; case 5: //GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); @@ -1166,6 +1225,22 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } +void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms, int y) { + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->vramTex); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); + glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); + glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, + background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), + renderer->blda, 0); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); +} + void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { int inY = y + background->y; int yBase = inY & 0xFF; @@ -1177,33 +1252,21 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, const struct GBAVideoGLShader* shader = &renderer->bgShader[background->multipalette ? 1 : 0]; const GLuint* uniforms = shader->uniforms; - glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); glUseProgram(shader->program); glBindVertexArray(shader->vao); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, renderer->vramTex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); + _prepareBackground(renderer, background, uniforms, y); glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); - glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); - glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, - background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blda, 0); - glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { +void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms, int y) { int reverse = 0; int forward = 1; if (renderer->scale > 1) { @@ -1232,28 +1295,9 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, } } - const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; - const GLuint* uniforms = shader->uniforms; - glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); - glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, (y - reverse) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * forward); - glUseProgram(shader->program); - glBindVertexArray(shader->vao); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, renderer->vramTex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(uniforms[GBA_GL_VS_LOC], forward, y - reverse); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); - glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); - glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); - glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); - glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); - glUniform2f(uniforms[GBA_GL_BG_RANGE], y, 1); - glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, - background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), - renderer->blda, 0); + glUniform2f(uniforms[GBA_GL_BG_RANGE], y - 1, 1); if (renderer->scale > 1) { glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { background->affine[0].sx, background->affine[0].sy, @@ -1281,7 +1325,33 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, background->affine[0].dx, background->affine[0].dy, }); } - glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + _prepareBackground(renderer, background, uniforms, y); +} + +void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + const struct GBAVideoGLShader* shader = &renderer->bgShader[background->overflow ? 2 : 3]; + const GLuint* uniforms = shader->uniforms; + glUseProgram(shader->program); + glBindVertexArray(shader->vao); + _prepareTransform(renderer, background, uniforms, y); + glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); + glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); +} + +void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + const struct GBAVideoGLShader* shader = &renderer->bgShader[4]; + const GLuint* uniforms = shader->uniforms; + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glUseProgram(shader->program); + _prepareTransform(renderer, background, uniforms, y); + glBindVertexArray(shader->vao); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 0xA000 : 0); + glUniform2i(uniforms[GBA_GL_BG_SIZE], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); From 40d21361154ec96fc4c16637d9dafe78d2726528 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 15:46:25 -0700 Subject: [PATCH 244/429] GBA Video: Fix layering regression --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 4b9dcd2aa..f7dc36ddf 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1146,7 +1146,7 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 64.f, renderer->blda / 16.f, 0); + glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, renderer->blda / 16.f, 0); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); From 3a3d01aedc384e24b2de40c403669cf337587039 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 16:10:12 -0700 Subject: [PATCH 245/429] GBA Video: Fix forced transparency OBJ blending in GL --- src/gba/renderers/gl.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index f7dc36ddf..dc20f3c0f 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -404,11 +404,9 @@ static const char* const _finalize = " if ((layerWindow & 32) != 0) {\n" " topFlags.y &= ~1;\n" " }\n" - " if ((topFlags.y & 13) == 5 || topFlags.w > 0) {\n" - " if ((bottomFlags.y & 2) == 2) {\n" - " topPixel *= topFlags.z / 16.;\n" - " topPixel += bottomPixel * windowFlags.y;\n" - " }\n" + " if (((topFlags.y & 13) == 5 || topFlags.w > 0) && (bottomFlags.y & 2) == 2) {\n" + " topPixel *= topFlags.z / 16.;\n" + " topPixel += bottomPixel * windowFlags.y;\n" " } else if ((topFlags.y & 13) == 9) {\n" " topPixel += (1. - topPixel) * windowFlags.z;\n" " } else if ((topFlags.y & 13) == 13) {\n" @@ -1177,8 +1175,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB totalHeight <<= 1; } - enum GBAVideoBlendEffect blendEffect = GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT ? BLEND_ALPHA : renderer->blendEffect; - const struct GBAVideoGLShader* shader = &renderer->objShader[GBAObjAttributesAGet256Color(sprite->a)]; const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); @@ -1198,7 +1194,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(uniforms[GBA_GL_OBJ_STRIDE], stride); glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c) << 3, - (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (blendEffect * 4), + (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (renderer->blendEffect * 4), renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); if (GBAObjAttributesAIsTransformed(sprite->a)) { struct GBAOAMMatrix mat; From 7cc06ea12db77b7c8c70c6c2a9cc841624e98774 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 16:57:24 -0700 Subject: [PATCH 246/429] Qt: Increase maximum magnifications and scaling --- CHANGES | 1 + src/platform/qt/MapView.ui | 2 +- src/platform/qt/ObjView.ui | 2 +- src/platform/qt/SettingsView.ui | 2 +- src/platform/qt/TileView.ui | 2 +- src/platform/qt/Window.cpp | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index a63135d32..dbf38268f 100644 --- a/CHANGES +++ b/CHANGES @@ -61,6 +61,7 @@ Misc: - Qt: Open a message box for Qt frontend errors - GBA Video: Clean up dead code in sprite rendering loop - FFmpeg: Support audio-only recording + - Qt: Increase maximum magnifications and scaling 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/MapView.ui b/src/platform/qt/MapView.ui index 15a1f5f74..d07a832b5 100644 --- a/src/platform/qt/MapView.ui +++ b/src/platform/qt/MapView.ui @@ -104,7 +104,7 @@ 1 - 4 + 8 diff --git a/src/platform/qt/ObjView.ui b/src/platform/qt/ObjView.ui index 7f33eaeb0..df0a003a9 100644 --- a/src/platform/qt/ObjView.ui +++ b/src/platform/qt/ObjView.ui @@ -59,7 +59,7 @@ 1 - 6 + 8 diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 15d7893f9..23172e691 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -894,7 +894,7 @@ 1 - 13 + 16 diff --git a/src/platform/qt/TileView.ui b/src/platform/qt/TileView.ui index 02c4c533f..4f027a493 100644 --- a/src/platform/qt/TileView.ui +++ b/src/platform/qt/TileView.ui @@ -126,7 +126,7 @@ 1 - 4 + 8 diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 15a13d3b9..d1ec28a99 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1284,7 +1284,7 @@ void Window::setupMenu(QMenuBar* menubar) { m_actions.addMenu(tr("Audio/&Video"), "av"); m_actions.addMenu(tr("Frame size"), "frame", "av"); - for (int i = 1; i <= 6; ++i) { + for (int i = 1; i <= 8; ++i) { Action* setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { Action* setSize = m_frameSizes[i]; showNormal(); From 6cf255daf45ac5f9f778d1c4a56cf07a70f48316 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 17:06:53 -0700 Subject: [PATCH 247/429] Qt: Allow small windows --- src/platform/opengl/gles2.c | 2 +- src/platform/qt/Window.cpp | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 35e7ac9e0..c9994f10a 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -246,7 +246,7 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { glBindTexture(GL_TEXTURE_2D, oldTex); } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST); glUseProgram(shader->program); glUniform1i(shader->texLocation, 0); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d1ec28a99..4498f8c5d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -719,7 +719,6 @@ void Window::gameStarted() { resizeFrame(size * m_savedScale); } attachWidget(m_display.get()); - m_display->setMinimumSize(size); setFocus(); #ifndef Q_OS_MAC @@ -890,7 +889,6 @@ void Window::reloadDisplayDriver() { #endif if (m_controller) { - m_display->setMinimumSize(m_controller->screenDimensions()); connect(m_controller.get(), &CoreController::stopping, m_display.get(), &Display::stopDrawing); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw); @@ -902,13 +900,12 @@ void Window::reloadDisplayDriver() { attachWidget(m_display.get()); m_display->startDrawing(m_controller); - } else { -#ifdef M_CORE_GB - m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); -#elif defined(M_CORE_GBA) - m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); -#endif } +#ifdef M_CORE_GB + m_display->setMinimumSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); +#elif defined(M_CORE_GBA) + m_display->setMinimumSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); +#endif } void Window::reloadAudioDriver() { From 7e476dfb763a832cb5d558602e9f3cbd999cfb3d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 17:26:56 -0700 Subject: [PATCH 248/429] GBA Video: GL modes 3 and 5 --- src/gba/renderers/gl.c | 95 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 6 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index dc20f3c0f..eef9a8fdf 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -229,6 +229,55 @@ static const char* const _renderMode2 = " flags = inflags / flagCoeff;\n" "}"; +static const struct GBAVideoGLUniform _uniformsMode35[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "vram", GBA_GL_BG_VRAM, }, + { "charBase", GBA_GL_BG_CHARBASE, }, + { "size", GBA_GL_BG_SIZE, }, + { "inflags", GBA_GL_BG_INFLAGS, }, + { "offset", GBA_GL_BG_OFFSET, }, + { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, + { 0 } +}; + +static const char* const _renderMode35 = + "in vec2 texCoord;\n" + "uniform sampler2D vram;\n" + "uniform int charBase;\n" + "uniform ivec2 size;\n" + "uniform ivec4 inflags;\n" + "uniform ivec2[4] offset;\n" + "uniform ivec2[4] transform;\n" + "uniform vec2 range;\n" + "out vec4 color;\n" + "out vec4 flags;\n" + FLAG_CONST + "precision highp float;\n" + "precision highp int;\n" + + "vec2 interpolate(ivec2 arr[4], float x);\n" + + "void main() {\n" + " float y = texCoord.y - range.x;\n" + " float lin = 0.5 - y / range.y * 0.25;\n" + " vec2 mixedTransform = interpolate(transform, lin);\n" + " vec2 mixedOffset = interpolate(offset, lin);\n" + " ivec2 coord = ivec2(mixedTransform * texCoord.x + mixedOffset);\n" + " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" + " discard;\n" + " }\n" + " if (coord.y < 0 || coord.y >= (size.y << 8)) {\n" + " discard;\n" + " }\n" + " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" + " ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n" + " int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n" + " color = vec4((sixteen & 0x1F) / 31., ((sixteen >> 5) & 0x1F) / 31., ((sixteen >> 10) & 0x1F) / 31., 1.);\n" + " flags = inflags / flagCoeff;\n" + "}"; + static const struct GBAVideoGLUniform _uniformsMode4[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, @@ -597,6 +646,10 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[2] = _interpolate; _compileShader(glRenderer, &glRenderer->bgShader[4], shaderBuffer, 3, vs, _uniformsMode4, log); + shaderBuffer[1] = _renderMode35; + shaderBuffer[2] = _interpolate; + _compileShader(glRenderer, &glRenderer->bgShader[5], shaderBuffer, 3, vs, _uniformsMode35, log); + shaderBuffer[1] = _renderObj; shaderBuffer[2] = _renderTile16; @@ -966,13 +1019,13 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { GBAVideoGLRendererDrawBackgroundMode2(glRenderer, &glRenderer->bg[2], y); break; case 3: - //GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); + GBAVideoGLRendererDrawBackgroundMode3(glRenderer, &glRenderer->bg[2], y); break; case 4: GBAVideoGLRendererDrawBackgroundMode4(glRenderer, &glRenderer->bg[2], y); break; case 5: - //GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); + GBAVideoGLRendererDrawBackgroundMode5(glRenderer, &glRenderer->bg[2], y); break; } } @@ -1221,7 +1274,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms, int y) { +void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms) { glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glActiveTexture(GL_TEXTURE0); @@ -1251,7 +1304,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); glUseProgram(shader->program); glBindVertexArray(shader->vao); - _prepareBackground(renderer, background, uniforms, y); + _prepareBackground(renderer, background, uniforms); glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); @@ -1321,7 +1374,7 @@ void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBac background->affine[0].dx, background->affine[0].dy, }); } - _prepareBackground(renderer, background, uniforms, y); + _prepareBackground(renderer, background, uniforms); } void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { @@ -1338,14 +1391,29 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } +void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + const struct GBAVideoGLShader* shader = &renderer->bgShader[5]; + const GLuint* uniforms = shader->uniforms; + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); + _prepareTransform(renderer, background, uniforms, y); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], 0); + glUniform2i(uniforms[GBA_GL_BG_SIZE], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); +} + void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { const struct GBAVideoGLShader* shader = &renderer->bgShader[4]; const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glUseProgram(shader->program); - _prepareTransform(renderer, background, uniforms, y); glBindVertexArray(shader->vao); + _prepareTransform(renderer, background, uniforms, y); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 0xA000 : 0); glUniform2i(uniforms[GBA_GL_BG_SIZE], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glEnableVertexAttribArray(0); @@ -1353,6 +1421,21 @@ void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } +void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + const struct GBAVideoGLShader* shader = &renderer->bgShader[5]; + const GLuint* uniforms = shader->uniforms; + glBindFramebuffer(GL_FRAMEBUFFER, background->fbo); + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); + _prepareTransform(renderer, background, uniforms, y); + glUniform1i(uniforms[GBA_GL_BG_CHARBASE], GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 0x5000 : 0); + glUniform2i(uniforms[GBA_GL_BG_SIZE], 160, 128); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); +} + static void _scissorWindow(int start, int end, int y, int lines, int scale) { if (start > end) { _scissorWindow(start, GBA_VIDEO_HORIZONTAL_PIXELS * scale, y, lines, scale); From 4e2052f9341e05a47a20e4060d5dd56d741e0088 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 18:42:45 -0700 Subject: [PATCH 249/429] GBA Audio: Experimental HLE audio --- CMakeLists.txt | 1 + include/mgba/core/cpu.h | 4 + include/mgba/internal/gba/audio.h | 189 +++++++++++ include/mgba/internal/gba/extra/audio-mixer.h | 19 ++ src/gba/audio.c | 50 ++- src/gba/core.c | 18 ++ src/gba/extra/audio-mixer.c | 304 ++++++++++++++++++ src/gba/gba.c | 4 + 8 files changed, 575 insertions(+), 14 deletions(-) create mode 100644 include/mgba/internal/gba/extra/audio-mixer.h create mode 100644 src/gba/extra/audio-mixer.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d25191081..ed522e70b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ file(GLOB GBA_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/test/*.c) file(GLOB GB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/*.c) file(GLOB GB_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/test/*.c) file(GLOB GBA_CHEATS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/cheats/*.c) +file(GLOB GBA_EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/extra/audio-mixer.c) file(GLOB GBA_RR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/rr/*.c) file(GLOB CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.c) file(GLOB CORE_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/test/*.c) diff --git a/include/mgba/core/cpu.h b/include/mgba/core/cpu.h index fe6caedd3..71f3398c2 100644 --- a/include/mgba/core/cpu.h +++ b/include/mgba/core/cpu.h @@ -13,6 +13,10 @@ CXX_GUARD_START enum mCPUComponentType { CPU_COMPONENT_DEBUGGER, CPU_COMPONENT_CHEAT_DEVICE, + CPU_COMPONENT_MISC_1, + CPU_COMPONENT_MISC_2, + CPU_COMPONENT_MISC_3, + CPU_COMPONENT_MISC_4, CPU_COMPONENT_MAX }; diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 10f5a7e65..f08f845b6 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -10,10 +10,14 @@ CXX_GUARD_START +#include #include #include #include +#define MP2K_MAGIC 0x68736D53 +#define MP2K_MAX_SOUND_CHANNELS 12 + mLOG_DECLARE_CATEGORY(GBA_AUDIO); struct GBADMA; @@ -44,6 +48,7 @@ DECL_BITFIELD(GBARegisterSOUNDBIAS, uint16_t); DECL_BITS(GBARegisterSOUNDBIAS, Bias, 0, 10); DECL_BITS(GBARegisterSOUNDBIAS, Resolution, 14, 2); +struct GBAAudioMixer; struct GBAAudio { struct GBA* p; @@ -71,6 +76,8 @@ struct GBAAudio { GBARegisterSOUNDBIAS soundbias; + struct GBAAudioMixer* mixer; + bool externalMixing; int32_t sampleInterval; bool forceDisableChA; @@ -85,6 +92,188 @@ struct GBAStereoSample { int16_t right; }; +struct GBAMP2kADSR { + uint8_t attack; + uint8_t decay; + uint8_t sustain; + uint8_t release; +}; + +struct GBAMP2kSoundChannel { + uint8_t status; + uint8_t type; + uint8_t rightVolume; + uint8_t leftVolume; + struct GBAMP2kADSR adsr; + uint8_t ky; + uint8_t envelopeV; + uint8_t envelopeRight; + uint8_t envelopeLeft; + uint8_t echoVolume; + uint8_t echoLength; + uint8_t d1; + uint8_t d2; + uint8_t gt; + uint8_t midiKey; + uint8_t ve; + uint8_t pr; + uint8_t rp; + uint8_t d3[3]; + uint32_t ct; + uint32_t fw; + uint32_t freq; + uint32_t waveData; + uint32_t cp; + uint32_t track; + uint32_t pp; + uint32_t np; + uint32_t d4; + uint16_t xpi; + uint16_t xpc; +}; + +struct GBAMP2kContext { + uint32_t magic; + uint8_t pcmDmaCounter; + uint8_t reverb; + uint8_t maxChans; + uint8_t masterVolume; + uint8_t freq; + uint8_t mode; + uint8_t c15; + uint8_t pcmDmaPeriod; + uint8_t maxLines; + uint8_t gap[3]; + int32_t pcmSamplesPerVBlank; + int32_t pcmFreq; + int32_t divFreq; + uint32_t cgbChans; + uint32_t func; + uint32_t intp; + uint32_t cgbSound; + uint32_t cgbOscOff; + uint32_t midiKeyToCgbFreq; + uint32_t mPlayJumpTable; + uint32_t plynote; + uint32_t extVolPit; + uint8_t gap2[16]; + struct GBAMP2kSoundChannel chans[MP2K_MAX_SOUND_CHANNELS]; +}; + +struct GBAMP2kMusicPlayerInfo { + uint32_t songHeader; + uint32_t status; + uint8_t trackCount; + uint8_t priority; + uint8_t cmd; + uint8_t unk_B; + uint32_t clock; + uint8_t gap[8]; + uint32_t memAccArea; + uint16_t tempoD; + uint16_t tempoU; + uint16_t tempoI; + uint16_t tempoC; + uint16_t fadeOI; + uint16_t fadeOC; + uint16_t fadeOV; + uint32_t tracks; + uint32_t tone; + uint32_t magic; + uint32_t func; + uint32_t intp; +}; + +struct GBAMP2kInstrument { + uint8_t type; + uint8_t key; + uint8_t length; + union { + uint8_t pan; + uint8_t sweep; + } ps; + union { + uint32_t waveData; + uint32_t subTable; + } data; + union { + struct GBAMP2kADSR adsr; + uint32_t map; + } extInfo; +}; + +struct GBAMP2kMusicPlayerTrack { + uint8_t flags; + uint8_t wait; + uint8_t patternLevel; + uint8_t repN; + uint8_t gateTime; + uint8_t key; + uint8_t velocity; + uint8_t runningStatus; + uint8_t keyM; + uint8_t pitM; + int8_t keyShift; + int8_t keyShiftX; + int8_t tune; + uint8_t pitX; + int8_t bend; + uint8_t bendRange; + uint8_t volMR; + uint8_t volML; + uint8_t vol; + uint8_t volX; + int8_t pan; + int8_t panX; + int8_t modM; + uint8_t mod; + uint8_t modT; + uint8_t lfoSpeed; + uint8_t lfoSpeedC; + uint8_t lfoDelay; + uint8_t lfoDelayC; + uint8_t priority; + uint8_t echoVolume; + uint8_t echoLength; + uint32_t chan; + struct GBAMP2kInstrument instrument; + uint8_t gap[10]; + uint16_t unk_3A; + uint32_t unk_3C; + uint32_t cmdPtr; + uint32_t patternStack[3]; +}; + +struct GBAMP2kTrack { + struct GBAMP2kMusicPlayerTrack track; + struct GBAMP2kSoundChannel* channel; + uint8_t lastCommand; + struct CircleBuffer buffer; + uint32_t samplePlaying; + float currentOffset; + bool waiting; +}; + +struct GBAAudioMixer { + struct mCPUComponent d; + struct GBAAudio* p; + + uint32_t contextAddress; + + bool (*engage)(struct GBAAudioMixer* mixer, uint32_t address); + void (*vblank)(struct GBAAudioMixer* mixer); + void (*step)(struct GBAAudioMixer* mixer); + + struct GBAMP2kContext context; + struct GBAMP2kMusicPlayerInfo player; + struct GBAMP2kTrack activeTracks[MP2K_MAX_SOUND_CHANNELS]; + + double tempo; + double frame; + + struct GBAStereoSample last; +}; + void GBAAudioInit(struct GBAAudio* audio, size_t samples); void GBAAudioReset(struct GBAAudio* audio); void GBAAudioDeinit(struct GBAAudio* audio); diff --git a/include/mgba/internal/gba/extra/audio-mixer.h b/include/mgba/internal/gba/extra/audio-mixer.h new file mode 100644 index 000000000..369a4aaa3 --- /dev/null +++ b/include/mgba/internal/gba/extra/audio-mixer.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2013-2017 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/. */ +#ifndef GBA_AUDIO_MIXER_H +#define GBA_AUDIO_MIXER_H + +#include + +CXX_GUARD_START + +#include + +void GBAAudioMixerCreate(struct GBAAudioMixer* mixer); + +CXX_GUARD_END + +#endif diff --git a/src/gba/audio.c b/src/gba/audio.c index c0ed7cf4c..b337043a3 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -14,6 +14,8 @@ #include #include +#define MP2K_LOCK_MAX 8 + #ifdef _3DS #define blip_add_delta blip_add_delta_fast #endif @@ -24,7 +26,7 @@ const unsigned GBA_AUDIO_SAMPLES = 2048; const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t); const int GBA_AUDIO_VOLUME_MAX = 0x100; -static const int CLOCKS_PER_FRAME = 0x400; +static const int CLOCKS_PER_FRAME = 0x800; static int _applyBias(struct GBAAudio* audio, int sample); static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate); @@ -49,6 +51,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE); CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE); + audio->externalMixing = false; audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; @@ -111,6 +114,20 @@ void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* mLOG(GBA_AUDIO, GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest); return; } + uint32_t source = info->source; + uint32_t magic[2] = { + audio->p->cpu->memory.load32(audio->p->cpu, source - 0x350, NULL), + audio->p->cpu->memory.load32(audio->p->cpu, source - 0x980, NULL) + }; + if (audio->mixer) { + if (magic[0] - MP2K_MAGIC <= MP2K_LOCK_MAX) { + audio->mixer->engage(audio->mixer, source - 0x350); + } else if (magic[1] - MP2K_MAGIC <= MP2K_LOCK_MAX) { + audio->mixer->engage(audio->mixer, source - 0x980); + } else { + audio->externalMixing = false; + } + } info->reg = GBADMARegisterSetDestControl(info->reg, GBA_DMA_FIXED); info->reg = GBADMARegisterSetWidth(info->reg, 1); } @@ -265,23 +282,28 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { sampleLeft >>= psgShift; sampleRight >>= psgShift; - if (!audio->forceDisableChA) { - if (audio->chALeft) { - sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA; - } - - if (audio->chARight) { - sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA; - } + if (audio->mixer) { + audio->mixer->step(audio->mixer); } + if (!audio->externalMixing) { + if (!audio->forceDisableChA) { + if (audio->chALeft) { + sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA; + } - if (!audio->forceDisableChB) { - if (audio->chBLeft) { - sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB; + if (audio->chARight) { + sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA; + } } - if (audio->chBRight) { - sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; + if (!audio->forceDisableChB) { + if (audio->chBLeft) { + sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB; + } + + if (audio->chBRight) { + sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; + } } } diff --git a/src/gba/core.c b/src/gba/core.c index 44d125f73..6b9061f8f 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #ifndef DISABLE_THREADING @@ -123,6 +124,9 @@ static const struct mCoreMemoryBlock _GBAMemoryBlocksEEPROM[] = { }; struct mVideoLogContext; + +#define CPU_COMPONENT_AUDIO_MIXER CPU_COMPONENT_MISC_1 + struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; @@ -140,6 +144,7 @@ struct GBACore { const struct Configuration* overrides; struct mDebuggerPlatform* debuggerPlatform; struct mCheatDevice* cheatDevice; + struct GBAAudioMixer* audioMixer; }; static bool _GBACoreInit(struct mCore* core) { @@ -162,6 +167,7 @@ static bool _GBACoreInit(struct mCore* core) { gbacore->debuggerPlatform = NULL; gbacore->cheatDevice = NULL; gbacore->logContext = NULL; + gbacore->audioMixer = NULL; GBACreate(gba); // TODO: Restore cheats @@ -209,6 +215,7 @@ static void _GBACoreDeinit(struct mCore* core) { mCheatDeviceDestroy(gbacore->cheatDevice); } free(gbacore->cheatDevice); + free(gbacore->audioMixer); mCoreConfigFreeOpts(&core->opts); free(core); } @@ -272,6 +279,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections"); mCoreConfigCopyValue(&core->config, config, "gba.bios"); + mCoreConfigCopyValue(&core->config, config, "gba.audioHle"); #ifndef DISABLE_THREADING mCoreConfigCopyValue(&core->config, config, "threadedVideo"); @@ -464,6 +472,16 @@ static void _GBACoreReset(struct mCore* core) { GBAVideoAssociateRenderer(&gba->video, renderer); } +#ifndef MINIMAL_CORE + int useAudioMixer; + if (!gbacore->audioMixer && mCoreConfigGetIntValue(&core->config, "gba.audioHle", &useAudioMixer) && useAudioMixer) { + gbacore->audioMixer = malloc(sizeof(*gbacore->audioMixer)); + GBAAudioMixerCreate(gbacore->audioMixer); + ((struct ARMCore*) core->cpu)->components[CPU_COMPONENT_AUDIO_MIXER] = &gbacore->audioMixer->d; + ARMHotplugAttach(core->cpu, CPU_COMPONENT_AUDIO_MIXER); + } +#endif + GBAOverrideApplyDefaults(gba, gbacore->overrides); #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c new file mode 100644 index 000000000..b7eb8c315 --- /dev/null +++ b/src/gba/extra/audio-mixer.c @@ -0,0 +1,304 @@ +/* Copyright (c) 2013-2017 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 + +#include +#include +#include + +#define OVERSAMPLE 2 + +static void _mp2kInit(void* cpu, struct mCPUComponent* component); +static void _mp2kDeinit(struct mCPUComponent* component); + +static bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address); +static void _mp2kVblank(struct GBAAudioMixer* mixer); +static void _mp2kStep(struct GBAAudioMixer* mixer); + +void GBAAudioMixerCreate(struct GBAAudioMixer* mixer) { + mixer->d.init = _mp2kInit; + mixer->d.deinit = _mp2kDeinit; + mixer->engage = _mp2kEngage; + mixer->vblank = _mp2kVblank; + mixer->step = _mp2kStep; +} + +void _mp2kInit(void* cpu, struct mCPUComponent* component) { + struct ARMCore* arm = cpu; + struct GBA* gba = (struct GBA*) arm->master; + struct GBAAudioMixer* mixer = (struct GBAAudioMixer*) component; + gba->audio.mixer = mixer; + mixer->p = &gba->audio; + mixer->contextAddress = 0; + mixer->tempo = 120.0 / 75.0; + mixer->frame = 0; + mixer->last.left = 0; + mixer->last.right = 0; + memset(&mixer->context, 0, sizeof(mixer->context)); + memset(&mixer->activeTracks, 0, sizeof(mixer->activeTracks)); + + size_t i; + for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { + mixer->activeTracks[i].channel = &mixer->context.chans[i]; + CircleBufferInit(&mixer->activeTracks[i].buffer, 0x10000); + } +} + +void _mp2kDeinit(struct mCPUComponent* component) { + struct GBAAudioMixer* mixer = (struct GBAAudioMixer*) component; + size_t i; + for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { + CircleBufferDeinit(&mixer->activeTracks[i].buffer); + } +} + +static void _loadInstrument(struct ARMCore* cpu, struct GBAMP2kInstrument* instrument, uint32_t base) { + struct ARMMemory* memory = &cpu->memory; + instrument->type = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, type), 0); + instrument->key = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, key), 0); + instrument->length = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, length), 0); + instrument->ps.pan = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, ps.pan), 0); + if (instrument->type == 0x40 || instrument->type == 0x80) { + instrument->data.subTable = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, data.subTable), 0); + instrument->extInfo.map = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.map), 0); + } else { + instrument->data.waveData = memory->load32(cpu, base + offsetof(struct GBAMP2kInstrument, data.waveData), 0); + instrument->extInfo.adsr.attack = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.attack), 0); + instrument->extInfo.adsr.decay = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.decay), 0); + instrument->extInfo.adsr.sustain = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.sustain), 0); + instrument->extInfo.adsr.release = memory->load8(cpu, base + offsetof(struct GBAMP2kInstrument, extInfo.adsr.release), 0); + } +} + +static void _lookupInstrument(struct ARMCore* cpu, struct GBAMP2kInstrument* instrument, uint8_t key) { + struct ARMMemory* memory = &cpu->memory; + if (instrument->type == 0x40) { + uint32_t subInstrumentBase = instrument->data.subTable; + uint32_t keyTable = instrument->extInfo.map; + uint8_t id = memory->load8(cpu, keyTable + key, 0); + subInstrumentBase += 12 * id; + _loadInstrument(cpu, instrument, subInstrumentBase); + } + if (instrument->type == 0x80) { + uint32_t subInstrumentBase = instrument->data.subTable; + subInstrumentBase += 12 * key; + _loadInstrument(cpu, instrument, subInstrumentBase); + } +} + +static void _stepSample(struct GBAAudioMixer* mixer, struct GBAMP2kTrack* track) { + struct ARMCore* cpu = mixer->p->p->cpu; + struct ARMMemory* memory = &cpu->memory; + uint32_t headerAddress; + struct GBAMP2kInstrument instrument = track->track.instrument; + + uint8_t note = track->track.key; + _lookupInstrument(cpu, &instrument, note); + double freq; + + switch (instrument.type) { + case 0x00: + case 0x08: + case 0x40: + case 0x80: + freq = GBA_ARM7TDMI_FREQUENCY / (double) track->channel->freq; + break; + default: + // We don't care about PSG channels + return; + } + headerAddress = instrument.data.waveData; + if (headerAddress < 0x20) { + mLOG(GBA_AUDIO, ERROR, "Audio track has invalid instrument"); + return; + } + uint32_t loopOffset = memory->load32(cpu, headerAddress + 0x8, 0); + uint32_t endOffset = memory->load32(cpu, headerAddress + 0xC, 0); + uint32_t sampleBase = headerAddress + 0x10; + uint32_t sampleI = track->samplePlaying; + double sampleOffset = track->currentOffset; + double updates = VIDEO_TOTAL_LENGTH / (mixer->tempo * mixer->p->sampleInterval / OVERSAMPLE); + int nSample; + for (nSample = 0; nSample < updates; ++nSample) { + int8_t sample = memory->load8(cpu, sampleBase + sampleI, 0); + + struct GBAStereoSample stereo = { + (sample * track->channel->leftVolume * track->channel->envelopeV) >> 9, + (sample * track->channel->rightVolume * track->channel->envelopeV) >> 9 + }; + + CircleBufferWrite16(&track->buffer, stereo.left); + CircleBufferWrite16(&track->buffer, stereo.right); + + sampleOffset += mixer->p->sampleInterval / OVERSAMPLE; + while (sampleOffset > freq) { + sampleOffset -= freq; + ++sampleI; + if (sampleI >= endOffset) { + sampleI = loopOffset; + } + } + } + + track->samplePlaying = sampleI; + track->currentOffset = sampleOffset; +} + +static void _mp2kReload(struct GBAAudioMixer* mixer) { + struct ARMCore* cpu = mixer->p->p->cpu; + struct ARMMemory* memory = &cpu->memory; + mixer->context.magic = memory->load32(cpu, mixer->contextAddress + offsetof(struct GBAMP2kContext, magic), 0); + int i; + for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { + struct GBAMP2kSoundChannel* ch = &mixer->context.chans[i]; + struct GBAMP2kTrack* track = &mixer->activeTracks[i]; + track->waiting = false; + uint32_t base = mixer->contextAddress + offsetof(struct GBAMP2kContext, chans[i]); + + ch->status = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, status), 0); + ch->type = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, type), 0); + ch->rightVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, rightVolume), 0); + ch->leftVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, leftVolume), 0); + ch->adsr.attack = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.attack), 0); + ch->adsr.decay = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.decay), 0); + ch->adsr.sustain = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.sustain), 0); + ch->adsr.release = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, adsr.release), 0); + ch->ky = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, ky), 0); + ch->envelopeV = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeV), 0); + ch->envelopeRight = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeRight), 0); + ch->envelopeLeft = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, envelopeLeft), 0); + ch->echoVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, echoVolume), 0); + ch->echoLength = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, echoLength), 0); + ch->d1 = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d1), 0); + ch->d2 = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d2), 0); + ch->gt = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, gt), 0); + ch->midiKey = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, midiKey), 0); + ch->ve = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, ve), 0); + ch->pr = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, pr), 0); + ch->rp = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, rp), 0); + ch->d3[0] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[0]), 0); + ch->d3[1] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[1]), 0); + ch->d3[2] = memory->load8(cpu, base + offsetof(struct GBAMP2kSoundChannel, d3[2]), 0); + ch->ct = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, ct), 0); + ch->fw = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, fw), 0); + ch->freq = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, freq), 0); + ch->waveData = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, waveData), 0); + ch->cp = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, cp), 0); + ch->track = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, track), 0); + ch->pp = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, pp), 0); + ch->np = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, np), 0); + ch->d4 = memory->load32(cpu, base + offsetof(struct GBAMP2kSoundChannel, d4), 0); + ch->xpi = memory->load16(cpu, base + offsetof(struct GBAMP2kSoundChannel, xpi), 0); + ch->xpc = memory->load16(cpu, base + offsetof(struct GBAMP2kSoundChannel, xpc), 0); + + base = ch->track; + if (base) { + track->track.flags = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, flags), 0); + track->track.wait = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, wait), 0); + track->track.patternLevel = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternLevel), 0); + track->track.repN = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, repN), 0); + track->track.gateTime = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, gateTime), 0); + track->track.key = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, key), 0); + track->track.velocity = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, velocity), 0); + track->track.runningStatus = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, runningStatus), 0); + track->track.keyM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyM), 0); + track->track.pitM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pitM), 0); + track->track.keyShift = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyShift), 0); + track->track.keyShiftX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, keyShiftX), 0); + track->track.tune = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, tune), 0); + track->track.pitX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pitX), 0); + track->track.bend = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, bend), 0); + track->track.bendRange = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, bendRange), 0); + track->track.volMR = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volMR), 0); + track->track.volML = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volML), 0); + track->track.vol = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, vol), 0); + track->track.volX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, volX), 0); + track->track.pan = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, pan), 0); + track->track.panX = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, panX), 0); + track->track.modM = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, modM), 0); + track->track.mod = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, mod), 0); + track->track.modT = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, modT), 0); + track->track.lfoSpeed = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoSpeed), 0); + track->track.lfoSpeedC = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoSpeedC), 0); + track->track.lfoDelay = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoDelay), 0); + track->track.lfoDelayC = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, lfoDelayC), 0); + track->track.priority = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, priority), 0); + track->track.echoVolume = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, echoVolume), 0); + track->track.echoLength = memory->load8(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, echoLength), 0); + track->track.chan = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, chan), 0); + _loadInstrument(cpu, &track->track.instrument, base + offsetof(struct GBAMP2kMusicPlayerTrack, instrument)); + track->track.cmdPtr = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, cmdPtr), 0); + track->track.patternStack[0] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[0]), 0); + track->track.patternStack[1] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[1]), 0); + track->track.patternStack[2] = memory->load32(cpu, base + offsetof(struct GBAMP2kMusicPlayerTrack, patternStack[2]), 0); + } else { + memset(&track->track, 0, sizeof(track->track)); + } + } +} + +bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address) { + if (address < BASE_WORKING_RAM) { + return false; + } + if (address != mixer->contextAddress) { + mixer->contextAddress = address; + mixer->p->externalMixing = true; + _mp2kReload(mixer); + } + return true; +} + +void _mp2kStep(struct GBAAudioMixer* mixer) { + if (!mixer->p->externalMixing) { + return; + } + mixer->frame += mixer->p->sampleInterval; + + while (mixer->frame >= VIDEO_TOTAL_LENGTH / mixer->tempo) { + int i; + for (i = 0; i < MP2K_MAX_SOUND_CHANNELS; ++i) { + struct GBAMP2kTrack* track = &mixer->activeTracks[i]; + if (track->channel->status > 0) { + _stepSample(mixer, track); + } else { + track->currentOffset = 0; + track->samplePlaying = 0; + CircleBufferClear(&track->buffer); + } + } + mixer->frame -= VIDEO_TOTAL_LENGTH / mixer->tempo; + } + + uint32_t interval = mixer->p->sampleInterval / OVERSAMPLE; + int i; + for (i = 0; i < OVERSAMPLE; ++i) { + struct GBAStereoSample sample = {0}; + size_t track; + for (track = 0; track < MP2K_MAX_SOUND_CHANNELS; ++track) { + if (!mixer->activeTracks[track].channel->status) { + continue; + } + int16_t value; + CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + sample.left += value; + CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + sample.right += value; + } + blip_add_delta(mixer->p->psg.left, mixer->p->clock + i * interval, sample.left - mixer->last.left); + blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.left - mixer->last.left); + mixer->last = sample; + } +} + +void _mp2kVblank(struct GBAAudioMixer* mixer) { + if (!mixer->contextAddress) { + return; + } + mLOG(GBA_AUDIO, DEBUG, "Frame"); + mixer->p->externalMixing = true; + _mp2kReload(mixer); +} diff --git a/src/gba/gba.c b/src/gba/gba.c index 4434fc526..39a3f72c3 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -789,6 +789,10 @@ void GBABreakpoint(struct ARMCore* cpu, int immediate) { void GBAFrameStarted(struct GBA* gba) { GBATestKeypadIRQ(gba); + if (gba->audio.mixer) { + gba->audio.mixer->vblank(gba->audio.mixer); + } + size_t c; for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) { struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c); From 6fd97ce3de40a83a12c51622c58570dd7ecdd2e4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 May 2019 17:16:52 -0700 Subject: [PATCH 250/429] Qt: Enable XQ audio option --- src/platform/qt/SettingsView.cpp | 4 ++-- src/platform/qt/SettingsView.ui | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 95943c671..d5d0a91ac 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -401,7 +401,7 @@ void SettingsView::updateConfig() { saveSetting("logToStdout", m_ui.logToStdout); saveSetting("logFile", m_ui.logFile); saveSetting("useDiscordPresence", m_ui.useDiscordPresence); - saveSetting("audioHle", m_ui.audioHle); + saveSetting("gba.audioHle", m_ui.audioHle); if (m_ui.fastForwardUnbounded->isChecked()) { saveSetting("fastForwardRatio", "-1"); @@ -550,7 +550,7 @@ void SettingsView::reloadConfig() { loadSetting("logToStdout", m_ui.logToStdout); loadSetting("logFile", m_ui.logFile); loadSetting("useDiscordPresence", m_ui.useDiscordPresence); - loadSetting("audioHle", m_ui.audioHle); + loadSetting("gba.audioHle", m_ui.audioHle); loadSetting("videoScale", m_ui.videoScale, 1); m_ui.libraryStyle->setCurrentIndex(loadSetting("libraryStyle").toInt()); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 23172e691..1a7a9e83f 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -40,7 +40,7 @@ - 200 + 180 16777215 @@ -903,9 +903,6 @@ - - false - XQ GBA audio (experimental) From 6364cabce3ff683c7557c8e622152b897ea87928 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 18:38:40 -0700 Subject: [PATCH 251/429] GBA Audio: Default to emulated mixing for XCMD --- src/gba/extra/audio-mixer.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c index b7eb8c315..85941536e 100644 --- a/src/gba/extra/audio-mixer.c +++ b/src/gba/extra/audio-mixer.c @@ -237,6 +237,10 @@ static void _mp2kReload(struct GBAAudioMixer* mixer) { } else { memset(&track->track, 0, sizeof(track->track)); } + if (track->track.runningStatus == 0xCD) { + // XCMD isn't supported + mixer->p->externalMixing = false; + } } } @@ -253,9 +257,6 @@ bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address) { } void _mp2kStep(struct GBAAudioMixer* mixer) { - if (!mixer->p->externalMixing) { - return; - } mixer->frame += mixer->p->sampleInterval; while (mixer->frame >= VIDEO_TOTAL_LENGTH / mixer->tempo) { @@ -288,8 +289,10 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.right += value; } - blip_add_delta(mixer->p->psg.left, mixer->p->clock + i * interval, sample.left - mixer->last.left); - blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.left - mixer->last.left); + if (mixer->p->externalMixing) { + blip_add_delta(mixer->p->psg.left, mixer->p->clock + i * interval, sample.left - mixer->last.left); + blip_add_delta(mixer->p->psg.right, mixer->p->clock + i * interval, sample.left - mixer->last.left); + } mixer->last = sample; } } From 4a3d042089d0ce8c02cf8093105a4933e9770e62 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 18:40:35 -0700 Subject: [PATCH 252/429] CHANGES: Update --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index dbf38268f..a2f445615 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Features: - Debugger: Add tracing to file - Map viewer supports bitmapped GBA modes - OpenGL renderer with high-resolution upscaling support + - Experimental high level "XQ" audio for most GBA games Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs From c18c38b6169f7e7e52a0133a846929ceb3d88b0e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 18 May 2019 19:06:10 -0700 Subject: [PATCH 253/429] GBA: Fix tests --- src/gba/test/cheats.c | 2 ++ src/gba/test/core.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/gba/test/cheats.c b/src/gba/test/cheats.c index 6f4b8cb4c..527c3ccdc 100644 --- a/src/gba/test/cheats.c +++ b/src/gba/test/cheats.c @@ -16,6 +16,7 @@ static int cheatsSetup(void** state) { struct mCore* core = GBACoreCreate(); core->init(core); + mCoreInitConfig(core, NULL); core->cheatDevice(core); *state = core; return 0; @@ -26,6 +27,7 @@ static int cheatsTeardown(void** state) { return 0; } struct mCore* core = *state; + mCoreConfigDeinit(&core->config); core->deinit(core); return 0; } diff --git a/src/gba/test/core.c b/src/gba/test/core.c index acb0165af..9313010b6 100644 --- a/src/gba/test/core.c +++ b/src/gba/test/core.c @@ -27,7 +27,9 @@ M_TEST_DEFINE(reset) { struct mCore* core = GBACoreCreate(); assert_non_null(core); assert_true(core->init(core)); + mCoreInitConfig(core, NULL); core->reset(core); + mCoreConfigDeinit(&core->config); core->deinit(core); } @@ -36,7 +38,9 @@ M_TEST_DEFINE(loadNullROM) { assert_non_null(core); assert_true(core->init(core)); assert_false(core->loadROM(core, NULL)); + mCoreInitConfig(core, NULL); core->reset(core); + mCoreConfigDeinit(&core->config); core->deinit(core); } From 59db2a19460a8a1da529b8995de4adb5da9276fb Mon Sep 17 00:00:00 2001 From: EmpyreusX <36258024+EmpyreusX@users.noreply.github.com> Date: Mon, 20 May 2019 13:45:41 +0800 Subject: [PATCH 254/429] Update mgba-zh_CN.ts --- src/platform/qt/ts/mgba-zh_CN.ts | 298 +++++++++++++++++-------------- 1 file changed, 167 insertions(+), 131 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index b60a570ad..faafd280a 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -4243,21 +4243,26 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 + Enhancements + 增强 + + + BIOS BIOS - + Paths 路径 - + Logging 日志记录 - + Game Boy Game Boy @@ -4272,491 +4277,522 @@ Game Boy Advance 是任天堂有限公司(Nintendo Co., Ltd.)的注册商标 音频缓冲: - - + + 1536 1536 - + 512 512 - + 768 768 - + 1024 1024 - + 2048 2048 - + 3072 3072 - + 4096 4096 - + samples 采样 - + Sample rate: 采样率: - - + + 44100 44100 - + 22050 22050 - + 32000 32000 - + 48000 48000 - + Hz Hz - + Volume: 音量: - - + + Mute 静音 - + Fast forward volume: 快进音量: - + Display driver: 显示驱动: - + Frameskip: 跳帧: - + Skip every 每间隔 - - + + frames - + FPS target: 目标 FPS: - + frames per second 帧每秒 - + Sync: 同步: - + Video 视频 - + Audio 音频 - + Lock aspect ratio 锁定纵横比 - + Force integer scaling 强制整数缩放 - + Bilinear filtering 双线性过滤 - + Language 语言 - + English 英语 - + Library: 库: - + List view 列表查看 - + Tree view 树状查看 - + Show when no game open 未打开游戏时显示 - + Clear cache 清除缓存 - + Allow opposing input directions 允许逆向输入 - + Suspend screensaver 停用屏幕保护程序 - + Pause when inactive 非活动时暂停 - + Show FPS in title bar 在标题栏显示 FPS - + Automatically save cheats 自动保存作弊码 - + Automatically load cheats 自动载入作弊码 - + Automatically save state 自动存档 - + Automatically load state 自动读档 - - + + Enable Discord Rich Presence 启用 Enable Discord Rich Presence - + Fast forward speed: 快进速度: - + + × × - + Unbounded 不限制 - + Autofire interval: 连发间隔: - + Enable rewind 启用回退 - + Rewind history: 回退历史: - + Idle loops: 空循环: - + Run all 运行所有 - + Remove known 移除选定 - + Detect and remove 检测并移除 - + Preload entire ROM into memory 将整个 ROM 预加载到内存中 - + Savestate extra data: 即时存档额外数据: - - + + Screenshot 截图 - - + + Save data 保存数据 - - + + Cheat codes 作弊码 - + Load extra data: - 读档时载入额外数据: + 载入额外数据: - - GB BIOS file: - GB BIOS 文件: + + Video renderer: + 视频渲染器: - - - - - - - - - + + Software + 软件 + + + + OpenGL + OpenGL + + + + OpenGL enhancements + OpenGL 增强 + + + + High-resolution scale: + 高分辨率比例: + + + + XQ GBA audio (experimental) + XQ GBA 音频 (实验) + + + + + + + + + + + Browse 浏览 - + + GB BIOS file: + GB BIOS 文件: + + + Use BIOS file if found 当可用时使用 BIOS 文件 - + Skip BIOS intro 跳过 BIOS 启动画面 - + GBA BIOS file: GBA BIOS 文件: - + GBC BIOS file: GBC BIOS 文件: - + SGB BIOS file: SGB BIOS 文件: - + Save games - 已保存的游戏 + 游戏存档 - - - - - + + + + + Same directory as the ROM 保存在 ROM 所在目录 Save states - 保存即时存档 + 即时存档 - + Screenshots 截图 - + Patches 补丁 - + Cheats 作弊码 - + Log to file 记录日志到文件 - + Log to console 记录日志到控制台 - + Select Log File 选择日志文件 - - Game Boy model - Game Boy 模型 + + Game Boy model: + Game Boy 模型: - - - + + + Autodetect 自动检测 - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Super Game Boy model: Super Game Boy 模型: - + Game Boy Color model: Game Boy Color 模型: - + Default BG colors: 默认背景颜色: - + Super Game Boy borders Super Game Boy 边框 - + Camera driver: 相机驱动: - + Default sprite colors 1: 默认精灵图颜色 1: - + Default sprite colors 2: 默认精灵图颜色 2: - + Use GBC colors in GB games 在 GB 游戏中使用 GBC 颜色 - + Camera: 相机 From 19747ea21d890af09ce96dc45827543f8bdc4de0 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Fri, 26 Jan 2018 22:36:44 +0000 Subject: [PATCH 255/429] CMake: Improved detection of pthreads. --- CMakeLists.txt | 39 +++++++++++++++++--- include/mgba-util/platform/posix/threading.h | 13 ++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed522e70b..8ccebef30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,15 +257,10 @@ if(WIN32) endif() elseif(UNIX) set(USE_PTHREADS ON) - add_definitions(-DUSE_PTHREADS) if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_definitions(-D_GNU_SOURCE) endif() - if(NOT APPLE AND NOT HAIKU) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") - endif() list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/posix/*.c) @@ -351,6 +346,7 @@ if(3DS OR WII) add_definitions(-D_GNU_SOURCE) endif() +include(CheckCCompilerFlag) include(CheckFunctionExists) include(CheckIncludeFiles) check_function_exists(strdup HAVE_STRDUP) @@ -402,6 +398,27 @@ endif() check_function_exists(chmod HAVE_CHMOD) check_function_exists(umask HAVE_UMASK) +if(USE_PTHREADS) + check_include_files("pthread.h" HAVE_PTHREAD_H) + if(HAVE_PTHREAD_H) + check_c_compiler_flag(-pthread HAVE_PTHREAD) + if(HAVE_PTHREAD AND NOT APPLE AND NOT HAIKU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + endif() + + check_function_exists(pthread_create HAVE_PTHREAD_CREATE) + if(HAVE_PTHREAD_CREATE) + add_definitions(-DUSE_PTHREADS) + + check_include_files("pthread_np.h" HAVE_PTHREAD_NP_H) + + check_function_exists(pthread_setname_np HAVE_PTHREAD_SETNAME_NP) + check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP) + endif() + endif() +endif() + set(FUNCTION_DEFINES) if(HAVE_STRDUP) @@ -443,6 +460,18 @@ if(HAVE_UMASK) list(APPEND FUNCTION_DEFINES HAVE_UMASK) endif() +if(HAVE_PTHREAD_NP_H) + list(APPEND FUNCTION_DEFINES HAVE_PTHREAD_NP_H) +endif() + +if(HAVE_PTHREAD_SETNAME_NP) + list(APPEND FUNCTION_DEFINES HAVE_PTHREAD_SETNAME_NP) +endif() + +if(HAVE_PTHREAD_SET_NAME_NP) + list(APPEND FUNCTION_DEFINES HAVE_PTHREAD_SET_NAME_NP) +endif() + # Feature dependencies set(FEATURE_DEFINES) set(FEATURE_FLAGS) diff --git a/include/mgba-util/platform/posix/threading.h b/include/mgba-util/platform/posix/threading.h index 468e1460c..38aac8f62 100644 --- a/include/mgba-util/platform/posix/threading.h +++ b/include/mgba-util/platform/posix/threading.h @@ -12,7 +12,7 @@ CXX_GUARD_START #include #include -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#ifdef HAVE_PTHREAD_NP_H #include #elif defined(__HAIKU__) #include @@ -85,20 +85,15 @@ static inline int ThreadJoin(Thread thread) { } static inline int ThreadSetName(const char* name) { -#ifdef __APPLE__ -#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 +#if defined(__APPLE__) && defined(HAVE_PTHREAD_SETNAME_NP) return pthread_setname_np(name); -#else - UNUSED(name); - return 0; -#endif -#elif defined(__FreeBSD__) || defined(__OpenBSD__) +#elif defined(HAVE_PTHREAD_SET_NAME_NP) pthread_set_name_np(pthread_self(), name); return 0; #elif defined(__HAIKU__) rename_thread(find_thread(NULL), name); return 0; -#elif !defined(BUILD_PANDORA) // Pandora's glibc is too old +#elif defined(HAVE_PTHREAD_SETNAME_NP) return pthread_setname_np(pthread_self(), name); #else UNUSED(name); From 109472f67f5a6019d994272b7cd5db31935294b6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 19 May 2019 15:05:58 -0700 Subject: [PATCH 256/429] GBA: Fix skipping BIOS on irregularly sized ROMs --- CHANGES | 1 + src/gba/core.c | 2 +- src/gba/gba.c | 4 ---- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index a2f445615..733f85d36 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,7 @@ Other fixes: - Qt: Fix some Qt display driver race conditions - FFmpeg: Fix audio conversion producing gaps - Core: Improved lockstep driver reliability (Le Hoang Quyen) + - GBA: Fix skipping BIOS on irregularly sized ROMs Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/core.c b/src/gba/core.c index 6b9061f8f..e753971e6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -528,7 +528,7 @@ static void _GBACoreReset(struct mCore* core) { #endif ARMReset(core->cpu); - if (core->opts.skipBios && gba->isPristine) { + if (core->opts.skipBios && (gba->romVf || gba->memory.rom)) { GBASkipBIOS(core->board); } } diff --git a/src/gba/gba.c b/src/gba/gba.c index 39a3f72c3..42697ffe1 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -241,10 +241,6 @@ void GBAReset(struct ARMCore* cpu) { if (gba->pristineRomSize > SIZE_CART0) { GBAMatrixReset(gba); } - - if (!gba->romVf && gba->memory.rom) { - GBASkipBIOS(gba); - } } void GBASkipBIOS(struct GBA* gba) { From d84793edeef33a3641ae8b6bbb9741e1cd29cd64 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 10:08:56 -0700 Subject: [PATCH 257/429] GBA Video: GL BG mosaic --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 55 +++++++++++++++++++++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 479a0b66f..c4081abbd 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -92,6 +92,7 @@ enum { GBA_GL_BG_INFLAGS, GBA_GL_BG_TRANSFORM, GBA_GL_BG_RANGE, + GBA_GL_BG_MOSAIC, GBA_GL_OBJ_VRAM = 2, GBA_GL_OBJ_PALETTE, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index eef9a8fdf..541cdc528 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -104,6 +104,7 @@ static const struct GBAVideoGLUniform _uniformsMode0[] = { { "size", GBA_GL_BG_SIZE, }, { "offset", GBA_GL_BG_OFFSET, }, { "inflags", GBA_GL_BG_INFLAGS, }, + { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -116,6 +117,7 @@ static const char* const _renderMode0 = "uniform int size;\n" "uniform ivec2 offset;\n" "uniform ivec4 inflags;\n" + "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST @@ -123,7 +125,14 @@ static const char* const _renderMode0 = "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " ivec2 coord = ivec2(texCoord) + offset;\n" + " ivec2 coord = ivec2(texCoord);\n" + " if (mosaic.x > 1) {\n" + " coord.x -= int(mod(coord.x, mosaic.x));\n" + " }\n" + " if (mosaic.y > 1) {\n" + " coord.y -= int(mod(coord.y, mosaic.y));\n" + " }\n" + " coord += offset;\n" " if ((size & 1) == 1) {\n" " coord.y += coord.x & 256;\n" " }\n" @@ -171,6 +180,7 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, { "range", GBA_GL_BG_RANGE, }, + { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -194,6 +204,7 @@ static const char* const _renderMode2 = "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" "uniform vec2 range;\n" + "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST @@ -221,11 +232,18 @@ static const char* const _renderMode2 = "}\n" "void main() {\n" - " float y = texCoord.y - range.x;\n" + " vec2 coord = texCoord;\n" + " if (mosaic.x > 1) {\n" + " coord.x -= mod(coord.x, mosaic.x);\n" + " }\n" + " if (mosaic.y > 1) {\n" + " coord.y -= mod(coord.y, mosaic.y);\n" + " }\n" + " float y = coord.y - range.x;\n" " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " color = fetchTile(ivec2(mixedTransform * texCoord.x + mixedOffset));\n" + " color = fetchTile(ivec2(mixedTransform * coord.x + mixedOffset));\n" " flags = inflags / flagCoeff;\n" "}"; @@ -239,6 +257,7 @@ static const struct GBAVideoGLUniform _uniformsMode35[] = { { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, { "range", GBA_GL_BG_RANGE, }, + { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -251,6 +270,7 @@ static const char* const _renderMode35 = "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" "uniform vec2 range;\n" + "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST @@ -260,11 +280,18 @@ static const char* const _renderMode35 = "vec2 interpolate(ivec2 arr[4], float x);\n" "void main() {\n" - " float y = texCoord.y - range.x;\n" + " vec2 incoord = texCoord;\n" + " if (mosaic.x > 1) {\n" + " incoord.x -= mod(incoord.x, mosaic.x);\n" + " }\n" + " if (mosaic.y > 1) {\n" + " incoord.y -= mod(incoord.y, mosaic.y);\n" + " }\n" + " float y = incoord.y - range.x;\n" " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " ivec2 coord = ivec2(mixedTransform * texCoord.x + mixedOffset);\n" + " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" " discard;\n" " }\n" @@ -289,6 +316,7 @@ static const struct GBAVideoGLUniform _uniformsMode4[] = { { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, { "range", GBA_GL_BG_RANGE, }, + { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -302,6 +330,7 @@ static const char* const _renderMode4 = "uniform ivec2[4] offset;\n" "uniform ivec2[4] transform;\n" "uniform vec2 range;\n" + "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST @@ -311,11 +340,18 @@ static const char* const _renderMode4 = "vec2 interpolate(ivec2 arr[4], float x);\n" "void main() {\n" - " float y = texCoord.y - range.x;\n" + " vec2 incoord = texCoord;\n" + " if (mosaic.x > 1) {\n" + " incoord.x -= mod(incoord.x, mosaic.x);\n" + " }\n" + " if (mosaic.y > 1) {\n" + " incoord.y -= mod(incoord.y, mosaic.y);\n" + " }\n" + " float y = incoord.y - range.x;\n" " float lin = 0.5 - y / range.y * 0.25;\n" " vec2 mixedTransform = interpolate(transform, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " ivec2 coord = ivec2(mixedTransform * texCoord.x + mixedOffset);\n" + " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" " discard;\n" " }\n" @@ -1284,6 +1320,11 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); + if (background->mosaic) { + glUniform2i(uniforms[GBA_GL_BG_MOSAIC], GBAMosaicControlGetBgV(renderer->mosaic), GBAMosaicControlGetBgH(renderer->mosaic)); + } else { + glUniform2i(uniforms[GBA_GL_BG_MOSAIC], 0, 0); + } glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blda, 0); From 6eab8d3418507fb9491f7890357b9d2eaec57383 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 10:26:01 -0700 Subject: [PATCH 258/429] GBA Video: GL OBJ mosaic --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index c4081abbd..7abb46b06 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -103,6 +103,7 @@ enum { GBA_GL_OBJ_TRANSFORM, GBA_GL_OBJ_DIMS, GBA_GL_OBJ_OBJWIN, + GBA_GL_OBJ_MOSAIC, GBA_GL_FINALIZE_SCALE = 2, GBA_GL_FINALIZE_LAYERS, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 541cdc528..fd316fece 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -378,6 +378,7 @@ static const struct GBAVideoGLUniform _uniformsObj[] = { { "transform", GBA_GL_OBJ_TRANSFORM, }, { "dims", GBA_GL_OBJ_DIMS, }, { "objwin", GBA_GL_OBJ_OBJWIN, }, + { "mosaic", GBA_GL_OBJ_MOSAIC, }, { 0 } }; @@ -392,6 +393,7 @@ static const char* const _renderObj = "uniform mat2x2 transform;\n" "uniform ivec4 dims;\n" "uniform vec4 objwin;\n" + "uniform ivec4 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" "out vec3 window;\n" @@ -400,7 +402,14 @@ static const char* const _renderObj = "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" "void main() {\n" - " ivec2 coord = ivec2(transform * (texCoord - dims.zw / 2) + dims.xy / 2);\n" + " vec2 incoord = texCoord;\n" + " if (mosaic.x > 1) {\n" + " incoord.x -= mod(mosaic.z + incoord.x, mosaic.x);\n" + " }\n" + " if (mosaic.y > 1) {\n" + " incoord.y -= mod(mosaic.w + incoord.y, mosaic.y);\n" + " }\n" + " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" " discard;\n" " }\n" @@ -1305,6 +1314,11 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } + if (GBAObjAttributesAIsMosaic(sprite->a)) { + glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], GBAMosaicControlGetObjV(renderer->mosaic), GBAMosaicControlGetObjH(renderer->mosaic), x, spriteY); + } else { + glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0); + } glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); From 29b2262e9a13ccc681e3ef74a18073571810125f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 11:20:00 -0700 Subject: [PATCH 259/429] Qt: Fix bounded fast forward with Qt Multimedia --- CHANGES | 1 + src/platform/qt/CoreController.cpp | 8 ++++++++ src/platform/qt/Window.cpp | 1 + 3 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 733f85d36..d90047be2 100644 --- a/CHANGES +++ b/CHANGES @@ -44,6 +44,7 @@ Other fixes: - FFmpeg: Fix audio conversion producing gaps - Core: Improved lockstep driver reliability (Le Hoang Quyen) - GBA: Fix skipping BIOS on irregularly sized ROMs + - Qt: Fix bounded fast forward with Qt Multimedia Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 2c6ec39f7..804d476d7 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -440,13 +440,21 @@ void CoreController::rewind(int states) { } void CoreController::setFastForward(bool enable) { + if (m_fastForward == enable) { + return; + } m_fastForward = enable; updateFastForward(); + emit fastForwardChanged(enable); } void CoreController::forceFastForward(bool enable) { + if (m_fastForwardForced == enable) { + return; + } m_fastForwardForced = enable; updateFastForward(); + emit fastForwardChanged(enable || m_fastForward); } void CoreController::loadState(int slot) { diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 4498f8c5d..de4660f74 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -924,6 +924,7 @@ void Window::reloadAudioDriver() { m_audioProcessor->requestSampleRate(opts->sampleRate); m_audioProcessor->start(); connect(m_controller.get(), &CoreController::stopping, m_audioProcessor.get(), &AudioProcessor::stop); + connect(m_controller.get(), &CoreController::fastForwardChanged, m_audioProcessor.get(), &AudioProcessor::inputParametersChanged); } void Window::tryMakePortable() { From 326a055b07d4e56d755090a75ad37c7ad9f39f7a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 11:35:34 -0700 Subject: [PATCH 260/429] GBA Video: Initialize and fix mosaic in GL --- src/gba/renderers/gl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index fd316fece..c21116409 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -751,6 +751,8 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { glRenderer->paletteDirty = true; glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; + glRenderer->dispcnt = 0; + glRenderer->mosaic = 0; } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { @@ -1315,7 +1317,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } if (GBAObjAttributesAIsMosaic(sprite->a)) { - glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], GBAMosaicControlGetObjV(renderer->mosaic), GBAMosaicControlGetObjH(renderer->mosaic), x, spriteY); + glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], GBAMosaicControlGetObjV(renderer->mosaic) + 1, GBAMosaicControlGetObjH(renderer->mosaic) + 1, x, spriteY); } else { glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0); } @@ -1335,7 +1337,7 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); if (background->mosaic) { - glUniform2i(uniforms[GBA_GL_BG_MOSAIC], GBAMosaicControlGetBgV(renderer->mosaic), GBAMosaicControlGetBgH(renderer->mosaic)); + glUniform2i(uniforms[GBA_GL_BG_MOSAIC], GBAMosaicControlGetBgV(renderer->mosaic) + 1, GBAMosaicControlGetBgH(renderer->mosaic) + 1); } else { glUniform2i(uniforms[GBA_GL_BG_MOSAIC], 0, 0); } From f781c793f508cb4d84ececcb697f4e2bfe3abc4e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 12:21:10 -0700 Subject: [PATCH 261/429] GBA Video: Use 1d texture for backdrop bits --- include/mgba/internal/gba/renderers/gl.h | 11 ++++--- src/gba/renderers/gl.c | 41 +++++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 7abb46b06..6b10d2777 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -67,15 +67,18 @@ struct GBAVideoGLBackground { enum { GBA_GL_FBO_OBJ = 0, - GBA_GL_FBO_WINDOW = 1, - GBA_GL_FBO_OUTPUT = 2, + GBA_GL_FBO_BACKDROP, + GBA_GL_FBO_WINDOW, + GBA_GL_FBO_OUTPUT, GBA_GL_FBO_MAX }; enum { GBA_GL_TEX_OBJ_COLOR = 0, - GBA_GL_TEX_OBJ_FLAGS = 1, - GBA_GL_TEX_WINDOW = 6, + GBA_GL_TEX_OBJ_FLAGS, + GBA_GL_TEX_BACKDROP_COLOR, + GBA_GL_TEX_BACKDROP_FLAGS, + GBA_GL_TEX_WINDOW, GBA_GL_TEX_MAX }; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c21116409..0822bc64c 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -440,8 +440,8 @@ static const char* const _finalize = "uniform sampler2D layers[5];\n" "uniform sampler2D flags[5];\n" "uniform sampler2D window;\n" - "uniform vec4 backdrop;\n" - "uniform vec4 backdropFlags;\n" + "uniform sampler2D backdrop;\n" + "uniform sampler2D backdropFlags;\n" FLAG_CONST "out vec4 color;\n" @@ -464,12 +464,12 @@ static const char* const _finalize = "}\n" "void main() {\n" + " vec4 topPixel = texelFetch(backdrop, ivec2(0, texCoord.y), 0);\n" + " vec4 bottomPixel = topPixel;\n" + " ivec4 topFlags = ivec4(texelFetch(backdropFlags, ivec2(0, texCoord.y), 0) * flagCoeff);\n" + " ivec4 bottomFlags = topFlags;\n" " vec4 windowFlags = texelFetch(window, ivec2(texCoord * scale), 0);\n" " int layerWindow = int(windowFlags.x * 128);\n" - " vec4 topPixel = backdrop;\n" - " vec4 bottomPixel = backdrop;\n" - " ivec4 topFlags = ivec4(backdropFlags * flagCoeff);\n" - " ivec4 bottomFlags = ivec4(backdropFlags * flagCoeff);\n" " if ((layerWindow & 1) == 0) {\n" " vec4 pix = texelFetch(layers[0], ivec2(texCoord * scale), 0);\n" " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" @@ -585,7 +585,7 @@ static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, format, GBA_VIDEO_HORIZONTAL_PIXELS * scale, GBA_VIDEO_VERTICAL_PIXELS * scale, 0, format, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, format, scale > 0 ? GBA_VIDEO_HORIZONTAL_PIXELS * scale : 1, GBA_VIDEO_VERTICAL_PIXELS * (scale > 0 ? scale : 1), 0, format, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } @@ -612,6 +612,10 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_COLOR], GL_RGB, GL_COLOR_ATTACHMENT0, 0); + _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, 0); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -1015,10 +1019,21 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glClear(GL_COLOR_BUFFER_BIT); } - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } glEnable(GL_SCISSOR_TEST); + uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->d.palette[0]); + glViewport(0, 0, 1, GBA_VIDEO_VERTICAL_PIXELS); + glScissor(0, y, 1, 1); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); + glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); + glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, glRenderer->blda / 16.f, 0); + glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { if (glRenderer->firstAffine < 0) { memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); @@ -1235,16 +1250,20 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glBindTexture(GL_TEXTURE_2D, renderer->bg[3].tex); glActiveTexture(GL_TEXTURE0 + 10); glBindTexture(GL_TEXTURE_2D, renderer->bg[3].flags); + glActiveTexture(GL_TEXTURE0 + 11); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_COLOR]); + glActiveTexture(GL_TEXTURE0 + 12); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_FLAGS]); - uint32_t backdrop = M_RGB5_TO_RGB8(renderer->d.palette[0]); glUniform2i(uniforms[GBA_GL_VS_LOC], GBA_VIDEO_VERTICAL_PIXELS, 0); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); glUniform1iv(uniforms[GBA_GL_FINALIZE_LAYERS], 5, (GLint[]) { 3, 5, 7, 9, 1 }); glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROP], ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glUniform4f(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 1, (renderer->target1Bd | (renderer->target2Bd * 2) | (renderer->blendEffect * 4)) / 32.f, renderer->blda / 16.f, 0); + glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); + glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROP], 11); + glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 12); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); From 53d9e6b43213d9eed2c7bc5b38d16f4fdad37bc3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 13:15:17 -0700 Subject: [PATCH 262/429] GBA Video: Batch VRAM upload --- src/gba/renderers/gl.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 0822bc64c..e7941f161 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -994,13 +994,17 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->paletteDirty = false; } int i; - for (i = 0; i < 24; ++i) { + int first = -1; + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + for (i = 0; i < 25; ++i) { if (!(glRenderer->vramDirty & (1 << i))) { - continue; + if (first >= 0) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * first]); + first = -1; + } + } else if (first < 0) { + first = i; } - // TODO: PBOs - glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * i, 256, 8, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * i]); } glRenderer->vramDirty = 0; From eeee6fe44eb11e77774c7bb3f08c2016682d33cd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 14:42:55 -0700 Subject: [PATCH 263/429] Qt: Fix GL deadlocks --- src/feature/thread-proxy.c | 2 ++ src/gb/extra/proxy.c | 13 ------------- src/gba/extra/proxy.c | 10 ---------- src/gba/video.c | 3 +-- src/platform/qt/CoreController.cpp | 1 - src/platform/qt/DisplayGL.cpp | 6 +++--- src/platform/qt/VideoProxy.cpp | 8 ++++++++ src/platform/qt/VideoProxy.h | 2 +- src/platform/qt/Window.cpp | 2 +- 9 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index 7a67dbedd..6dca713ca 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -153,10 +153,12 @@ static void _wait(struct mVideoLogger* logger) { _proxyThreadRecover(proxyRenderer); return; } + MutexLock(&proxyRenderer->mutex); while (RingFIFOSize(&proxyRenderer->dirtyQueue)) { ConditionWake(&proxyRenderer->toThreadCond); ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); } + MutexUnlock(&proxyRenderer->mutex); } static void _unlock(struct mVideoLogger* logger) { diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index d8538124d..03119226e 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -250,31 +250,21 @@ void GBVideoProxyRendererFinishScanline(struct GBVideoRenderer* renderer, int y) void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->lock(proxyRenderer->logger); - } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend); } mVideoLoggerRendererFinishFrame(proxyRenderer->logger); mVideoLoggerRendererFlush(proxyRenderer->logger); - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->unlock(proxyRenderer->logger); - } } static void GBVideoProxyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->enableSGBBorder(proxyRenderer->backend, enable); - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->unlock(proxyRenderer->logger); - } } static void GBVideoProxyRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels) { @@ -297,9 +287,6 @@ static void GBVideoProxyRendererPutPixels(struct GBVideoRenderer* renderer, size struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - // Insert an extra item into the queue to make sure it gets flushed - mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index bd90f1271..3015b14ce 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -289,28 +289,20 @@ void GBAVideoProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->lock(proxyRenderer->logger); - } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend); } mVideoLoggerRendererFinishFrame(proxyRenderer->logger); mVideoLoggerRendererFlush(proxyRenderer->logger); - if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->unlock(proxyRenderer->logger); - } } static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { - proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_GET_PIXELS); mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->unlock(proxyRenderer->logger); *pixels = proxyRenderer->logger->pixelBuffer; *stride = proxyRenderer->logger->pixelStride; } else { @@ -322,8 +314,6 @@ static void GBAVideoProxyRendererPutPixels(struct GBAVideoRenderer* renderer, si struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - // Insert an extra item into the queue to make sure it gets flushed - mVideoLoggerRendererFlush(proxyRenderer->logger); } proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { diff --git a/src/gba/video.c b/src/gba/video.c index e75d255b1..7660e0b04 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -98,8 +98,7 @@ void GBAVideoReset(struct GBAVideo* video) { memset(video->palette, 0, sizeof(video->palette)); memset(video->oam.raw, 0, sizeof(video->oam.raw)); - video->renderer->deinit(video->renderer); - video->renderer->init(video->renderer); + video->renderer->reset(video->renderer); } void GBAVideoDeinit(struct GBAVideo* video) { diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 804d476d7..10d08bb3c 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -363,7 +363,6 @@ void CoreController::stop() { #endif setPaused(false); mCoreThreadEnd(&m_threadContext); - emit stopping(); } void CoreController::reset() { diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 1d1e79424..dc360cdb0 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -59,9 +59,6 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) m_painter = new PainterGL(&m_videoProxy, windowHandle(), m_gl); setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions - - connect(&m_videoProxy, &VideoProxy::dataAvailable, &m_videoProxy, &VideoProxy::processData); - connect(&m_videoProxy, &VideoProxy::eventPosted, &m_videoProxy, &VideoProxy::handleEvent); } DisplayGL::~DisplayGL() { @@ -417,6 +414,9 @@ void PainterGL::stop() { dequeueAll(); m_backend->clear(m_backend); m_backend->swap(m_backend); + if (m_videoProxy) { + m_videoProxy->reset(); + } m_gl->doneCurrent(); m_gl->moveToThread(m_surface->thread()); m_context.reset(); diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index a6c673207..1eb8fa933 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -24,6 +24,9 @@ VideoProxy::VideoProxy() { m_logger.d.writeData = &callback::func<&VideoProxy::writeData>; m_logger.d.readData = &callback::func<&VideoProxy::readData>; m_logger.d.postEvent = &callback::func<&VideoProxy::postEvent>; + + connect(this, &VideoProxy::dataAvailable, this, &VideoProxy::processData); + connect(this, &VideoProxy::eventPosted, this, &VideoProxy::handleEvent); } void VideoProxy::attach(CoreController* controller) { @@ -41,7 +44,10 @@ void VideoProxy::init() { } void VideoProxy::reset() { + m_mutex.lock(); RingFIFOClear(&m_dirtyQueue); + m_toThreadCond.wakeAll(); + m_mutex.unlock(); } void VideoProxy::deinit() { @@ -92,11 +98,13 @@ void VideoProxy::unlock() { } void VideoProxy::wait() { + m_mutex.lock(); while (RingFIFOSize(&m_dirtyQueue)) { emit dataAvailable(); m_toThreadCond.wakeAll(); m_fromThreadCond.wait(&m_mutex, 1); } + m_mutex.unlock(); } void VideoProxy::wake(int y) { diff --git a/src/platform/qt/VideoProxy.h b/src/platform/qt/VideoProxy.h index 7f778a605..e62facca1 100644 --- a/src/platform/qt/VideoProxy.h +++ b/src/platform/qt/VideoProxy.h @@ -30,11 +30,11 @@ signals: public slots: void processData(); + void reset(); void handleEvent(int); private: void init(); - void reset(); void deinit(); bool writeData(const void* data, size_t length); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index de4660f74..778102edc 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -726,7 +726,6 @@ void Window::gameStarted() { menuBar()->hide(); } #endif - m_display->startDrawing(m_controller); reloadAudioDriver(); multiplayerChanged(); @@ -1733,6 +1732,7 @@ void Window::setController(CoreController* controller, const QString& fname) { m_inputController.recalibrateAxes(); m_controller->setInputController(&m_inputController); m_controller->setLogger(&m_log); + m_display->startDrawing(m_controller); connect(this, &Window::shutdown, [this]() { if (!m_controller) { From bda0f67103dfb316b6da67c4172e52a9e42d9ec1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 15:31:47 -0700 Subject: [PATCH 264/429] Qt: Fix shutdown crashes --- src/gba/extra/proxy.c | 1 + src/platform/qt/CoreController.cpp | 3 --- src/platform/qt/Window.cpp | 18 +++++++++++++----- src/platform/qt/Window.h | 1 + 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 3015b14ce..52a0047b4 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -133,6 +133,7 @@ void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) { proxyRenderer->backend->deinit(proxyRenderer->backend); } else { proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_DEINIT); + mVideoLoggerRendererFlush(proxyRenderer->logger); } mVideoLoggerRendererDeinit(proxyRenderer->logger); diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 10d08bb3c..bd12de40d 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -196,9 +196,6 @@ CoreController::~CoreController() { mCacheSetDeinit(m_cacheSet.get()); m_cacheSet.reset(); } - - mCoreConfigDeinit(&m_threadContext.core->config); - m_threadContext.core->deinit(m_threadContext.core); } const color_t* CoreController::drawContext() { diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 778102edc..335149cf3 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -631,8 +631,10 @@ void Window::closeEvent(QCloseEvent* event) { m_config->setOption("width", GBA_VIDEO_HORIZONTAL_PIXELS * m_savedScale); } saveConfig(); - m_display.reset(); - QMainWindow::closeEvent(event); + if (m_controller) { + event->ignore(); + m_pendingClose = true; + } } void Window::focusInEvent(QFocusEvent*) { @@ -776,6 +778,11 @@ void Window::gameStarted() { void Window::gameStopped() { m_controller.reset(); + m_display->stopDrawing(); + if (m_pendingClose) { + m_display.reset(); + close(); + } #ifdef M_CORE_GBA for (Action* action : m_platformActions) { action->setEnabled(true); @@ -863,7 +870,6 @@ void Window::reloadDisplayDriver() { m_shaderView = std::make_unique(m_display.get(), m_config); #endif - connect(this, &Window::shutdown, m_display.get(), &Display::stopDrawing); connect(m_display.get(), &Display::hideCursor, [this]() { if (static_cast(m_screenWidget->layout())->currentWidget() == m_display.get()) { m_screenWidget->setCursor(Qt::BlankCursor); @@ -888,7 +894,6 @@ void Window::reloadDisplayDriver() { #endif if (m_controller) { - connect(m_controller.get(), &CoreController::stopping, m_display.get(), &Display::stopDrawing); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw); connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw); @@ -1700,6 +1705,9 @@ void Window::setController(CoreController* controller, const QString& fname) { if (!controller) { return; } + if (m_pendingClose) { + return; + } if (m_controller) { m_controller->stop(); @@ -1739,6 +1747,7 @@ void Window::setController(CoreController* controller, const QString& fname) { return; } m_controller->stop(); + disconnect(m_controller.get(), &CoreController::started, this, &Window::gameStarted); }); connect(m_controller.get(), &CoreController::started, this, &Window::gameStarted); @@ -1766,7 +1775,6 @@ void Window::setController(CoreController* controller, const QString& fname) { emit paused(false); }); - connect(m_controller.get(), &CoreController::stopping, m_display.get(), &Display::stopDrawing); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::resizeContext); connect(m_controller.get(), &CoreController::stateLoaded, m_display.get(), &Display::forceDraw); connect(m_controller.get(), &CoreController::rewound, m_display.get(), &Display::forceDraw); diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 01d036d32..526a10496 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -209,6 +209,7 @@ private: QString m_pendingPatch; QString m_pendingState; bool m_pendingPause = false; + bool m_pendingClose = false; bool m_hitUnimplementedBiosCall; From 3056655060b3be0eabd35742ea2b8e1cb18ccb09 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 17:28:08 -0700 Subject: [PATCH 265/429] GBA Video: Fix sprite mosaic clamping (fixes #1008) --- CHANGES | 1 + .../gba/obj/mosaic-height/baseline_0000.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0001.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0002.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0003.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0004.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0005.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0006.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0007.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0008.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0009.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0010.png | Bin 0 -> 1689 bytes .../gba/obj/mosaic-height/baseline_0011.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0012.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0013.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0014.png | Bin 0 -> 1536 bytes .../gba/obj/mosaic-height/baseline_0015.png | Bin 0 -> 1471 bytes .../gba/obj/mosaic-height/baseline_0016.png | Bin 0 -> 1471 bytes cinema/gba/obj/mosaic-height/test.mvl | Bin 0 -> 45041 bytes .../zmc-window-mosaic/baseline_0001.png | Bin 10115 -> 10189 bytes .../zmc-window-mosaic/baseline_0002.png | Bin 10179 -> 10265 bytes .../zmc-window-mosaic/baseline_0003.png | Bin 7843 -> 8022 bytes .../zmc-window-mosaic/baseline_0004.png | Bin 7743 -> 7925 bytes .../zmc-window-mosaic/baseline_0005.png | Bin 6117 -> 6207 bytes .../zmc-window-mosaic/baseline_0006.png | Bin 6073 -> 6158 bytes .../zmc-window-mosaic/baseline_0007.png | Bin 5388 -> 5573 bytes .../zmc-window-mosaic/baseline_0008.png | Bin 5362 -> 5556 bytes .../zmc-window-mosaic/baseline_0009.png | Bin 4811 -> 5032 bytes .../zmc-window-mosaic/baseline_0010.png | Bin 4851 -> 5062 bytes .../zmc-window-mosaic/baseline_0011.png | Bin 4434 -> 4548 bytes .../zmc-window-mosaic/baseline_0012.png | Bin 4409 -> 4518 bytes .../zmc-window-mosaic/baseline_0013.png | Bin 3886 -> 3983 bytes .../zmc-window-mosaic/baseline_0014.png | Bin 3863 -> 3958 bytes .../zmc-window-mosaic/baseline_0015.png | Bin 3858 -> 4054 bytes .../zmc-window-mosaic/baseline_0016.png | Bin 3780 -> 3982 bytes .../zmc-window-mosaic/baseline_0017.png | Bin 3565 -> 3737 bytes .../zmc-window-mosaic/baseline_0018.png | Bin 3447 -> 3618 bytes .../zmc-window-mosaic/baseline_0019.png | Bin 3342 -> 3532 bytes .../zmc-window-mosaic/baseline_0020.png | Bin 3262 -> 3448 bytes .../zmc-window-mosaic/baseline_0021.png | Bin 3147 -> 3284 bytes .../zmc-window-mosaic/baseline_0022.png | Bin 3103 -> 3246 bytes .../zmc-window-mosaic/baseline_0023.png | Bin 2903 -> 3113 bytes .../zmc-window-mosaic/baseline_0024.png | Bin 2826 -> 2999 bytes .../zmc-window-mosaic/baseline_0025.png | Bin 2721 -> 2840 bytes .../zmc-window-mosaic/baseline_0026.png | Bin 2516 -> 2620 bytes .../zmc-window-mosaic/baseline_0027.png | Bin 2301 -> 2361 bytes src/gba/renderers/software-obj.c | 15 ++++----------- src/gba/renderers/video-software.c | 12 +++++++++--- 48 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 cinema/gba/obj/mosaic-height/baseline_0000.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0001.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0002.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0003.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0004.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0005.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0006.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0007.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0008.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0009.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0010.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0011.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0012.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0013.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0014.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0015.png create mode 100644 cinema/gba/obj/mosaic-height/baseline_0016.png create mode 100644 cinema/gba/obj/mosaic-height/test.mvl diff --git a/CHANGES b/CHANGES index d90047be2..fa64821a2 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Emulation fixes: - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) + - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/cinema/gba/obj/mosaic-height/baseline_0000.png b/cinema/gba/obj/mosaic-height/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0001.png b/cinema/gba/obj/mosaic-height/baseline_0001.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0002.png b/cinema/gba/obj/mosaic-height/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0003.png b/cinema/gba/obj/mosaic-height/baseline_0003.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0004.png b/cinema/gba/obj/mosaic-height/baseline_0004.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0005.png b/cinema/gba/obj/mosaic-height/baseline_0005.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0006.png b/cinema/gba/obj/mosaic-height/baseline_0006.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0007.png b/cinema/gba/obj/mosaic-height/baseline_0007.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0008.png b/cinema/gba/obj/mosaic-height/baseline_0008.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0009.png b/cinema/gba/obj/mosaic-height/baseline_0009.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0010.png b/cinema/gba/obj/mosaic-height/baseline_0010.png new file mode 100644 index 0000000000000000000000000000000000000000..448ac5ceec0bfaa3f7912b2fc321cc25506cf34d GIT binary patch literal 1689 zcmaKtdpHwn9LM)`)IuvYQ7&DMvdkqUg zDGr&8Ll0*S4XZ=Vq_Rw!>((l_v*(^o53{5G;;Us zFf%sp&NnhJNk=PkA zn~Xy$AE0U~KkUBGonQvX(x5<>WQ+Lk$q5tLy)eJ2$tn-RxK-_M(LhMLVbj|2y9T;h=P~b4* z8B)KbEL3=g>;L9CRzcPYA@`ly-Q7KYTz67;k4a2)|V0u9d#GOYvP=D|sW zv9lSgyYi)0&W9}Wd@OThFi3|0P8}WmP*Hei0F_O1)}=wk=@mAnt$QJ;Ok02bvu~-{ z{SP4RlOU4PwDGw12CkG*JiccCQI{uVUx1R)`S6JuM1b56Yq* zKT}z=JmPEMmF}$loK~(p<-38X(f7O>Xm85(JGV{}$rJ5`Ekfp;)+qCX z-8Z!Tt1n!5*5XgP>MT@n?l)CNJ_q3!%7F{%qWF7pD|;zyZ{wbAAyQ6Ad|^y$&(tH4 zxL}l7F`>Lm@F=M?;0t+CK>Q^mD$UD(|RX~tP+x9BYJ{> zuPNHHm|T`xKyAWZ&6`Yg$t%pfzbX7wytdWoY8(KVfvp;ER_j{yFp#HrU}* z>ckDXSQ@`6Tm$)h6B-ekABliXL(p+GEm`N#bPhl0Pc)<_k%4jh?R0kSa)b8SBCDdXK^Z979JAtd z6};ZgWl2Ghhh@NJxZ`b~l-ERC3kX(eSFvr#3HDv0d+-KKH1KH_;XdXPS7ZZJjB75V zLQvL6)ajC$J@@rs>EW*|BM6nc@d9w ztsPxySk#S5K9u{~tbIj)2t5AA!3>oK-mp^Jcu}A>_AR|amrT|2{Ff|G9r>37fSo*J J&#=R!{SEFi6E^?= literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0011.png b/cinema/gba/obj/mosaic-height/baseline_0011.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0012.png b/cinema/gba/obj/mosaic-height/baseline_0012.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0013.png b/cinema/gba/obj/mosaic-height/baseline_0013.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0014.png b/cinema/gba/obj/mosaic-height/baseline_0014.png new file mode 100644 index 0000000000000000000000000000000000000000..7f04ae705518fe3936dd81d2d08c954a072d7841 GIT binary patch literal 1536 zcmeAS@N?(olHy`uVBq!ia0vp^AAooP2NRIoyR*!Qfr0h7r;B4q#hkZy6^n02NVF!F zsyifJKhxBtmmR^&yjf>MYvi;|VtP8fJUls(hov%JY?!rn;leXIX@~!^uTNj{b(?La z{I6csn|8`Y&+h$x_36_#saLQ6docQuBIFt62Miwfk~vPdGs)$l@B(gM+^IcM76%kSg+_a<+9`^(S9TYHk% z*<{A?@7q*YyKkZBQC#{`LxO*NaasM{Y_|H0YfBG&x$wPt-ilSLUj4eu>+^fwyq)W~ z{my4bT{XD-t^MG4+qt`zrQ6B8n0Y*AX7A4R`7q0|m@au$#OPgD+FPDwtFL~3pnd(h zN$ur*jhX$m_v+k(-!Xa5JoM$d$+EY}cUY&*Dw}Q_vL)?`Ig)qKO`NkqbI#cnlckgG z<{#dYdHR9&d-E#^va24(Cd6K>a>?5tH_LE;8$S0~CI(knUDhluy1T6XWukqOyYHR& zDeG^`mo>k)&VF(0?V8q?NuJ-IZmmuJruOuFT&$VF-8JSWcSUFXYQq-X5cf@)e@(=U z_pQOssJXB9iHmP}{gUtZo<6QMuNtZ+PvhK{x1;0T>Fw+@?%lt8xn290Tk^M`GMmj` zK31NacyifgZ~R6Jo3+;NZ`Cw!?Frxf)mF4Bdd=@wyADjL-pUm&^X-Q6IsF%#Cx6zS zQMQ|J*`Mf#%JMf2r+$<=bx1dPVQseU@&Nq~tjPrE?o*tzo$R)+f8F-}*vVzQZ;##d z;r6L~9%Po*d$(UzchR01!Nu2nGStuSlKW>Z9~pc?UH{vc-dWQ&ZM@HKfB7PzNb*_n z{^r|)!@fu6#_V65*R%Y1*<+cyV~Vc}pWc6dzT9B%u74Ik_PO7(d-J64OUDkq4Y@Dn zWBx7p-|@fpJ~$ntM?55f7adwwuz6vvUAnQA{)F?Ick(jhFH2oFn#TD~!D`Pwo2GI` z-OJkz=AM6f%68p7?Hf0G58m(iz31p7$z?S{itn>uNuy>K6ifVWh?L3Boqya{akk$| z?ltFDa@!nd%kE#zre4vds267Q=sZO}E^|#-m*rkQ{H5v}=dxP=r_Yxyu79|4asHPr3-k*1FP`=>*H@db))_}Z z0E%JB^?zdpr?|$K+ZNAzd7`%bO0R9qAJ)sOZ|57t{*kyhXDe@PrP0Ev z^>+fq-o)IVRuya~U$}c|G1twMBEDdFGC0Lq{-Hke+79j7pZnz=w|+)*!>3ojW_=Tn zT_0}nblSvlZKHig)^}_D%by0lcye^#@@?;LR8F{Z&i4Iy=N8 M)78&qol`;+0L`!IIsgCw literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0015.png b/cinema/gba/obj/mosaic-height/baseline_0015.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9d0e36129dd108825b93add57273e6c11e1a14 GIT binary patch literal 1471 zcmai!eK6a19LLk9Jx?PoPRzsasJawctj@|2hSAn@P!B~Y7FJIYC6Z=A>^ee2uWYH+ zLpE9}o-#ubNm_~6bRO2BsvZ_{DrkgeNQ347UFz=j{e1rW-skhWdw-~?pewrCCfXnn zNZ0qOcc`jwsUAb~q^b_~;T=Gr)8G4gdtM{dY|dL|%_SQT<1kQ$L$v^fO3+JVFoejS zXU}<6n9ngbF;TiHKX!g<@*19e*0HKu0H3D(B_`u{iPx1YM-Alh(ECUGw|5nl!4ie7 z|E*hS80Yzod#aK-BLtU;!;qbu?&lZ43q|#ZQd5u~m632q4PwUw>;6nA#86-X7`L2w z(lREZ%(8vir^-)CCpx{FuqsEj?YkQ|b}26zwe`$cfz41SUY>NT&=Y1-;aiKr8xiVgm_> zKv;6WAhQh9Qu=16D*}Sujob^ACXl=9F2G1Bl(b}S5}~P{1-@j!mPuf&_sDp0897}+ zN)i{^(HU1px}eQ6qx&zf=fHVQ1d+EZ14Vq)daJ8USoIAcZt7R+A3L4I%ISQDwEIyh=m z3XZx&eS3`Cv>HXkhv-0{88Ov|+vn{(o-K()Ez0Mm0@fDNpu@sxZdB|57zgtuG55>T zd=cZ!P~@wFwd)(4{dO!H`Vrw+5oI;>W$Q9UB02}W!iG8ZXLr?Non03X&j;n@^~!iN z0yGkZ;hMk0A6CcK6%3pO2U-D2K>6Sp1#90l0>NnNBbMXCM|I(ubC-Z-VI{%hfU?@) zw=ujEV5WnOVVT9h5KO**)>)!aO502NfnIAol3%WYca?ul$c5|(iO31L2r9qW5wCz9 zlZhO6C~3q8rl-FrbyF56t7K^eCsqgG1pmov=io?2r|@Y}5n}XH)F! zK8cU8N6-r1_Am(^?m2@%ya3$h@=N`8?dmbR`J&6v&DRV?uI&$L(QCGYukTDJ$v&H1 zyOes7+#AIQH%J$kDcuS;@*$d>M1+l{`(tdz(xrHj>8M!YhTcjjT_zMAg*>e-sYpe# z$H;7~k`7jzgdpHhX%xKiZ{mD^G&Ov63MO;hF6Qz*MN@ueKAb)y7%fF&Ip-6?2QMoe zfT#7P;Y(sM5sA_h6l*pH+5!CtT8k|Z#jF6mSQS};@_JQaNwg`AM%4dbs~F4LbNTyp TWwSzcm_fciLEi0NH;VoP|D&tG literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/baseline_0016.png b/cinema/gba/obj/mosaic-height/baseline_0016.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9d0e36129dd108825b93add57273e6c11e1a14 GIT binary patch literal 1471 zcmai!eK6a19LLk9Jx?PoPRzsasJawctj@|2hSAn@P!B~Y7FJIYC6Z=A>^ee2uWYH+ zLpE9}o-#ubNm_~6bRO2BsvZ_{DrkgeNQ347UFz=j{e1rW-skhWdw-~?pewrCCfXnn zNZ0qOcc`jwsUAb~q^b_~;T=Gr)8G4gdtM{dY|dL|%_SQT<1kQ$L$v^fO3+JVFoejS zXU}<6n9ngbF;TiHKX!g<@*19e*0HKu0H3D(B_`u{iPx1YM-Alh(ECUGw|5nl!4ie7 z|E*hS80Yzod#aK-BLtU;!;qbu?&lZ43q|#ZQd5u~m632q4PwUw>;6nA#86-X7`L2w z(lREZ%(8vir^-)CCpx{FuqsEj?YkQ|b}26zwe`$cfz41SUY>NT&=Y1-;aiKr8xiVgm_> zKv;6WAhQh9Qu=16D*}Sujob^ACXl=9F2G1Bl(b}S5}~P{1-@j!mPuf&_sDp0897}+ zN)i{^(HU1px}eQ6qx&zf=fHVQ1d+EZ14Vq)daJ8USoIAcZt7R+A3L4I%ISQDwEIyh=m z3XZx&eS3`Cv>HXkhv-0{88Ov|+vn{(o-K()Ez0Mm0@fDNpu@sxZdB|57zgtuG55>T zd=cZ!P~@wFwd)(4{dO!H`Vrw+5oI;>W$Q9UB02}W!iG8ZXLr?Non03X&j;n@^~!iN z0yGkZ;hMk0A6CcK6%3pO2U-D2K>6Sp1#90l0>NnNBbMXCM|I(ubC-Z-VI{%hfU?@) zw=ujEV5WnOVVT9h5KO**)>)!aO502NfnIAol3%WYca?ul$c5|(iO31L2r9qW5wCz9 zlZhO6C~3q8rl-FrbyF56t7K^eCsqgG1pmov=io?2r|@Y}5n}XH)F! zK8cU8N6-r1_Am(^?m2@%ya3$h@=N`8?dmbR`J&6v&DRV?uI&$L(QCGYukTDJ$v&H1 zyOes7+#AIQH%J$kDcuS;@*$d>M1+l{`(tdz(xrHj>8M!YhTcjjT_zMAg*>e-sYpe# z$H;7~k`7jzgdpHhX%xKiZ{mD^G&Ov63MO;hF6Qz*MN@ueKAb)y7%fF&Ip-6?2QMoe zfT#7P;Y(sM5sA_h6l*pH+5!CtT8k|Z#jF6mSQS};@_JQaNwg`AM%4dbs~F4LbNTyp TWwSzcm_fciLEi0NH;VoP|D&tG literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/mosaic-height/test.mvl b/cinema/gba/obj/mosaic-height/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..3ab153bb2989077a30ddf3b3993c9af432c8721c GIT binary patch literal 45041 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 Us`!3$IFI0siq=c`3!4xB1MGy1Qvd(} diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0003.png b/cinema/gba/window/zmc-window-mosaic/baseline_0003.png index 05f308fa48ae65851174f043c63cdd78aa789179..c5eb15ff12c3fced862416d8569dd50172fb0888 100644 GIT binary patch literal 8022 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 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0004.png b/cinema/gba/window/zmc-window-mosaic/baseline_0004.png index 6c8b94d45615f0642b8feba0b790c5fe37be5055..2fc7c052fd2cb6e12c406266bac4ec8bb1661f57 100644 GIT binary patch literal 7925 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 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0005.png b/cinema/gba/window/zmc-window-mosaic/baseline_0005.png index 044cf6ebe06e6bde2c0e3650bd8cfe3e1c7b35e9..906f6bfbef2423158ecb7de4900c233b93f23a40 100644 GIT binary patch literal 6207 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 D?*nTo literal 6117 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 literal 6073 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

j+TR$fxpB4a3rB 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 literal 5388 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 ZP|oBKHb$93Fn?nK8Y;TVb9>4{pEQdsw$)YvUUs z0HA2pP*yPX$=u7*0h>)__XYXV%s8-dn_wf?LB_b=i~S=uY+)tjsc*8u*1F=}IKPJSX%Y(BblT31KbS7aC3zoML#8vO*5CrtzD zdd!Aaq@Hh{BzooBTFhYf_LZnlGT(WjlaBY`XW5Hqo{!gly$@b2QFxbmAFfTqC>uW~ zBSD`WkSZt>n!T%k>e?EcaDQ8x+&O%UMg!qxREwWB_Oz$<9_u%BZy1?~Yu&3JHW>yAcUDROQl|b$oDe#U)Iyrc`S6 ze}Tq&w_K%_u(@WDE!TP+@as9?9SJJ*>fh# z&09oh0KVR-8=3m*w`;?~v1te0vTgPeC2zDF)$YJi>X?=Di&-mWI-GA;fVWOjUtdM- zg!s{|zf48XT#pOCwH3?tZQ{)t+@}gqX*JB;F|Si_F*x0FBS;t&5pQg9uk;QS^VTWx zZ$6)u6~AcMKhu%}Aiiv-ZO5WF$)nPmf7GEaaStd-N-Fto^~S(b%ykMZfcx!^JZzqFQVXLknt1uI+nUC|qFTXA7ePuo=x=S<7sn4)wG_=!T~XwKBouFisYc4M}K1%UwWrHluEG+H@mzNKFokxbIUtjw2Ri~PoD3&i{97{JuNzXTo zM?TfKlj7q=``Is#T$Z15e09F8ca|A=^xNhyIUgCz40E?)T0q}(snN~6@VW6y6M+*)+|R)kOxJ%zr-4vfd5KG_Nh{N5=vet)3#SbQQy7L~xKL zAB%&_V!SNZ<3*g7$$gD#EHNF+&`z`dj!}21*D(x>NjgmPfuajt@4lbX~u$TZ<(I#ffSW3(OZ$AGpXyG(pQAqw)F7z+YEkqqR;m=!+f?OY&*Q<{mr-}R;lts4>c-6=O8gt8{6Hx8dANeELAfeEt9Ks=5rLyeoGRVAIh=gg1F zLygljKi7jn-GROwN#~QB(nzI}e2zqtJIu8^*um5O8YQ7(+(TvOn8wwDV{U+VqzU^@ zs@0d+IBh?MB0?#G$1}MLS*8Ko5EQ_iyZdru6=5Fw$YqIzxZ)GyAe{Uaq zB0Rhx;Xd%|7hz%gl(A;g%3)fm=sC^!%qhYTsaxxlB2vl1hn&;e)Qe5tnQKT%Z`48Z za*dj+5@{Fd=U~aRlZOvXd`m)@cczST5&E^a)HZG11#BZ&8KYGztax?`Y^qOJcKn=+_LY{_M`9)Wn9pPtj?+v@IGS2LAFDeIft77O|k zopmAL-L1Gm12;6{KOBmm@X0~; z+)G)9oy9QGe%q6m-p_SXs&dm%mu^J|Ma!K7`Uu@$=AG10Ar(e2y_1zPX{u7Skq~ub>;l<(Z`SL<%F{loh@6`5-ru+-T>2AK=!3>D5b0krH(x{6uSaqI+zh z>YFr{5(vd%2Z{$3DorHmUf6``PQ&GJUEX9WPogva@=c-AHhw&*6)1fA@;+cEls3_? zo^LGL9!-BpaFL@gGEkh9y|>{he87x3M6*pRQd7s%4>w{Mc+@-JoBSpY8Ti zL6|}C$5c|`Q1lnI*rX3=5a;8(-Qv|sCrzV7qcNe~jZVrbBX*j2R<8c2vMwo)&{z<~ zIEJh}l8?>Tz5wE|HkohaTRkizNt?}WWO@FC&%S7~OmioV+i0zKe*IJHQOBK{m^npZ zhE#4NV5y+edV2(=1g_}ouco3BnV>W%hw(VURXu_GnO#y-o6B}kNmDA5t{VM|r5mRpN7AMwn!U){?& z6!*8hC>jVtXZs0A;FO+?=P9~D|LaP@3+^@6HQ-#d2xc}>b>N$XjL+mpNM)@@?%Q}8 z_x&yn+bbemL>?{-u9Zh5P8?F`;yv@Ts7c2kk>W1X4q|4{k?jiCRo~8e&YB}5p-h6& zEc!7Z*=+`I=)Z1|kRRl`1@K}lru>%Ix(~R+(@}#U$w*}a2E^+W>_ypbVPS@8C5eND zKFcIz6u*!a#VE!rLHE%NUYtMcHZQ7%>5Mt<=DCfB#}1R-Uujp=GZwqdZxUnpk5))6 zFjpn++P6&pS@#c9e{V#CiHS{*92g(RZPUzQzFYbXajG6AB~yh}kU8B>`aJeZpY`1nG#f-QjM$Yi!?r&*yCC~Irjfp{q+c;47+MoKtU~%2o z@uzvQH8pdJCj{aZ*tmpE9504L?*4sY^-_80wD7pg$+;55`<+gjihu1t*~U(RK%|1Wj?i6RC2=?!AtJucU&VAFwsGA>{K zuVdH!g4D|@r6)S7(BJ0`;X=T7$oDTkDbunxv~Y{Jl#AtS-FE%tKrmm6)Ipx0P574y z%}B9xA4S|Sv)l6?kd+C$150}sN)<-Yy*KmNV%<{uv4K?2D)|r+cGTP;Hl$ zcMyYBY#6LBIQt#_&UMnGlwl1tBc2`twhVDVG3L#d>=timQBv|lBMLYeRY(S`m3$@T z|;x~9+_koM;Q)8hmBGjYOd5t0r zHAoJ@P4~b8ts%LkoG~&!U-Us%Nk)`!U|*uP-0C8Rz-36AUVe^P?mgZKIne8rkXwEJ zQPV$m)bqgoJtMJ6GB)CP6O7MDqvp}Cg zao$%?u73&cM_5}sUmzhMwcviVdWa8_1hGnES6#ZQX=P^?4;2|ciaUW#{vJC=p7YE+ zD#t7_DYOCcExqAK!G0fU0ttNmby*vGXD$+$inAjfg^>cjGadMsQyLypwWmemD6 zpwUdyoUaLo|MBzxwZoMG8=G;hp8@SDR}N+^SC$O43@f>9(`xU#X6xms5|3X|pjkYz zG>p34xNyV!&AUy{sw^~s)bDs>g8_`oKxRU-<=)RC!Bndb2}Yq^1;VDa*|G2UqHw7Q zIe%-cM)Yy&gK@$jcL1Pxv)$OoDJB$;{I@>kztD%Zowp9*)+q_(0Kr`+?^DyBvBquD z2jL-!Y9g{i>6eBzT77o)n=m9J=(Vj7zv6*ziNn?W2v=Pb9+;3C*q9^DobDdWZ2bw} zd2Mq`@t3}v>PPI0eFCgjXX2@u1)*Y-LxR}%-b&K^dB*mb;FLp5>aV1_UJN8@Fi9;g zF%)T)v9(N92wxeOs<>&!D;B^;*B#cMGRRC>sU<#*wEwKc9?>R_s(9)6nF!SzsVLz& zRB!+(G^+E8Z}+@m3DvaOa^ew07+Mif4^2NrEB#kNsA!S7KABIcnEC|skht)cJ-Aqi zmYmYxzHEuc5G^jZx<}wHcE0UG5o^HPD?_bS8o54C4gITRJ*u1%DD1jUL14PA`^D1X z``X?&jK@lA_PkH#%(>bMC_eA3Ke+q&_H?3jg?qClhtwbE0zCeIxNRaDK%I5`87z{J zsV34RnXlt9Z;2X{LTdOMT^>zKpG-v+CLzs>IL2W+}g4J9V*K`*x1sMQJN$x zzb>AaV(48kEbX7x!6&|Aro1n0${dfs3ldnF;=6NbLKU#ieg?Y^vcy?&x7rCd687v!xG6F1fa@KGr3ZPW8ioy8B=Kq_JCE%O zj%HdJ?4DgE5;*cCY;KT@Q+qW~C_*tBE&J*Wp4YT~#KWPnPx5~Sf$;FarHJeDpN5!1 zJMuhJiw(d3YeD=c-CbT=-5jg5W6A$=fXoVfdgzI&RwJ^FJ0+scQq&M5|F$77N}ee4 zem`(inZ(bLPV%`27K;M>wZFkMY2t(+Kl>m`yY92jL{=MjM#R&W27eS|~F%adR@-J*N}BFc3aY$PFu7`zbb^KvX#UviU6uGRtk(F4_}V z9n8S(%bXXD-f6NNDzjIFz+y1S0e$ODf05x24t{w}XI4hR7QtZ5HLRHnI8`Z^DDv$V zYTn9qR41HoG3!)sPrW&ugtV!?JLpmpIyqZN5X$q}Jh4`tsv5DU4y?%EXV z(Zmch4pIkke&t<^g(~?^XA?4w%V*9-KdE88*^}?<4hN6vh0U?G8YwZZ9HxNPGET$) ziqvqF;bA}dwUr~*cys#lP&}b|y{yw3-5v0(J>=SW?IO^GIa<_SV0)^czq00luR5k1 z*OK8v6O&s>!p`<~eXD6fZ}_e!NoloYe_6*|*G{4&=fxA#g2_xPrW1+ZJbZ(3N!$*v zx`jM$4LK~FhbK)JNEl?3Ykwd&I(5rZa)RjtgEQw)uiQH?_YB@Tl>fNYLtZAoW=gM) zU8_0GDcRsC_#)X&N}?^xWn}9K02vwhzhHY9xj^Yjp>_sdaG}5&^-5uSMmW2WOI2f< zPeTnEMA;AimqWji8sVL*`zCDgU6nRR9ktEhl$l_RbxT<0+|&f;S^P<1>g7~r{1w4! z$kOg(8~X)v@|#PVVT0C42*h8^>3rQ5WYYQT@r{!oUBS&&Xexrkp2OqG2n)53GW-&aVXosH1Nb4!@ z#>3bu`!>4?vs)KQwpN#v@Jn|s+VBDEpPa_HxVI<{Q6n!8XQAf}MUw50Z^caKrXAML zT+McmW#>gVO}jKWogAUp$1dlhP%r%>P4Xc_m(M1Uq1bDDDQ8M_xx6Z;B7ED+1T<8h KDOV`I{O~`TqlISx diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0009.png b/cinema/gba/window/zmc-window-mosaic/baseline_0009.png index 35d54bf965786659ce85d3174abf8ff63d580c75..e2d9b13373a5b6505c3c3b79a6d3541bbb99b1f4 100644 GIT binary patch literal 5032 zcmY*dby!s2+8t0pI;BI9l8%7^i4lixX#_?}7*a~QYeaJBlvJckO1h+F5Ew>4T0(|K z+Tn74_w&2Y{bQf~Jo`NF-tT_TI&1Bh>|sMo zSE$V`lX78IV_mvw2A&DgQ0O4Y99?FXbWGM5+Ek-B@3Iw z|G<;f!{wH20UUyVL@^Gn`m`oR(K{D^wAPS5qcYw4libxBXO+{c%r(fz=Z zSmL&pKtr=j#I@81(aq-fYs3RP668E}a64utGxDGtc&7KkiPg6QUmiqm{7!<+Val3q z(T_TZd>uCKkSn%^xx)~w)h0)xOpw~x%nETI0smRZ8-=5u;T`ncrkgkphI<+mTIMreEwqN@0H|G?fTTX~w zo?^hsb~KuK*ppwTs+yIfzb9z0ej1!-DH5G7hK80S5Yy(RDAxab2Gd9 zyy4N7{FmYIMYJkz_uk%K3XcPm#2@{~T}KZ(JJXR&DZ}v_qE!C3bE}!kWWJ3w_{~de z1~qS=zle`3X1;v3?|cn}GMUNfivu__x>-`%ZwtA& z0Py$n?ca@xfr~6}$()3bw))NSIdqLRk8)GrMm|0%yi@^Oa{t ztTQpfD7HVCy*)=qSI0|~3EJb8zvOBk>-Qjok93Q(I1gx87F$e>Y489=#KhtV2DPKD zmsMxT-OEaY+9*%yOmWxvsC-$qE?@UmiOr2v-@u>agSnmKIf>G?l`+x2eSZuskFuq4nG&e1%~T6 zLHPr)6*B!fe^})kgn_GGAU(J}7f~GNlu(JFUg1 z5xBcVgYFZKE86v6QHJ$-Yw~=$mo52?7c+}vDH8+$09#NARpzW^rVVt{;gT2B7!?Xy zpv{<(yfMRARSg$Vf}cO^Ai3?q%w}=lZ4rxj^%2OnLdq0vkBjs6oO0=u?^CRI9UY23 z{CU$yh}ASpMTg@8RN9UwSM0nv1ZJt{e@`nvd6s&x9_PSQIOX}<(N!KV@=+3}Ohdsf zFN?+&))vW5ngK7kn|$<{aC)8$T1%A(Y~nmfQzw*XkmjMq6Qp_8M6>hJ;J~5UMmD7? z`8fj(8?vENMC#4b&N=;=?erJf$L!xcAy_Dg45+QnPnXo^B7@)ajwqu0 zyM&@4X05V-q2z@zIY&FV4VCCep;HFzhH}qeXxxq#xORp&T7dN{3LApu zcjrCE1z;Zpso_^5($uknHL`DXl%9@%&q+6>e3zRgwLlQ2X^05MJP#NPx6?#k?>rWT z8iDhy6vXo~r4~X!Kx^K%m_8wVLhs);Z*Vn2VS%B0b*t2G*paGlChW0$ zGkkldoKVrnZ-o)c_Zfw*Pm4Lp6%2>%d1Ts6)@08#sB^L3Rc5J}W${B}{0RYztrPV! zZM$&0CM1UJ6d6b1eep~S<=qM6>3VA#e}Y@sx1tJR(~mZ z(M>CWtGf-14o%|={Nm%Eb+3dH#jPsKwY}g#Bt2(n79A3#?6$A%A+0g7VkZ5Yc5MN} zKl>QyP8z)ffX5e)b|&j@QIUTB7O9DdFLztM5VnYaS}02DFBc3hWB%6d$C%8in;Mz> z^UP022mC16f}Zx{)#?7y!#-W2S$y&Y`d3HB3t-@Wm&TT3-lAdgduee@;q4k4wf?=0 zP8(MgftLpDq5KyMmJ0K6Z&H5?nxam7!<$ImA5ArwpuBr*U;(us?Ao;LvvYl6f~Z1D zW`^*^u@EJ@HXu#dF=u6wk@H;k`?%6Wtnf`^DDB1UA?!7U8 z7U2Ib$D|}#RsId*SYXx6&jJ@!@QYSA-V&=?dL_#MkKcjEY3S-_dgaoTZHD8CNDf^LzgXG)mG5 z2Mdq4P61CQQR5b$L$zNzJQ=X$p*dD(sfpcqE%Pc-hhud4yk(Q^#`Kjt+j7INz7H&C zNr*ewt*3Gz!4qnd7My_=#b1ciYX2%guKb(|v&$=vSo`2@z3TN}y%4f5&;EX4JmNW` ztB|Yw(ayVHGKILKdI~99`b|_a&OK@nN{j=Dq*r*!GQrNvF^sU$o5y=itWl)4h3@3P z<@Tf*2V@BBhk%r_Exlic%;`;u62*s-xzrfMaq+-F|K{*Ax>|UX`bE8PsAzbfH<==9 z&kkJ~+?x+mIDsRxjg9yR#U~e*JU{G77R-9djn901#wQw1*Yjk1O4Il(UaaM*EE~5U zzqtpcTl9-eoeF(^XJ6?k*IC;m53_ff;oBkcMbw%>HZ^&&zJZhdfetGA6z~t%kiI_$f2ST9?zb|9~Fs5@wqBXIM+bXb{ zOaNllnd-=z}JwHo;}${`&Bgc1n5gvruCsHb1gQ@XGo>`7BG72J1W7LqR%!F zfqIGKK?uekXij1_lk+luGaL+z^Fk4#n%GWzT;BopgLz&@eNC`XOAt}i38ZNTkIlW9h7}^7@c&Hkml~`e@U0nA>Cw;r^u5B^+xnesan;|gUaO4Q zR^V^Nfrj|3bQ$x7J`?DbNjT;=f61JeS)D~N0Mmp-lI5>bs9Sz&B?MrSJxWgYTJRjx z^@vIUF~}etaNPm41ERH1`%R1SyZyT_9fQ&fO%I7f_9JLitnU5eqU0%V#nv;l+nIY`Y7W*Z#{ z_Nwz{aZ?~=JoD8#-Upc35_V|KkXaumC?R5*cX%Ya6_V&Pn3*|wZrQ^U{>PnkQqZi$6e)_6M?s&WpNjqCp)FQC{iko z@Ge9bNmHEY^quzTfd_k&qK^-ob(8=H0f%SK6jQZj@1k)ecRxOro~3_Yb@2Gj(0tpGIS9YbRH zW1GWt#q8JTHlOX}?dcd^Cv9~m6$lDah-OPnsh4scXDb8utSFf3Xs2ow)5i?eZA&v{ zK(0Bb$4AEPYb0DmlKqZxbq3=RsGmuy+LQxDaMWj4kVJ`|U1scxIV2&yEAyQaErT+1 zu-?#rJsmxL)ry=}Fnc_s1QlCBK(X&`*3}a0r?O5lhN*xEDac%?jk$yY@7A}5i#y{r zL$rs+`;7fcpn6Vu3YLzRp*SUyBjvlDhDYPa5%&qKQ|-J6Gu$5?Bt`s32>(a%{2yVx z)A-g;a}CdQPlV+Qzf53+?@PGJr@PH%*qINlO{%$JO=T-SrTj1w4tA6^V>(|FT6zC8 zvSS)X7;vk||1;CSC7Q&5#9M!0pl(xjg`kGc7+&BR!pKzkhu+e-|A{TF&K$h~ULpUB zyWEH0`My4L01l~BCo4f>R9nJ#W~mam4HMn_ADQKfbSV;bzNa`uNTsRbzfon%sfY3Y zBXGC8K5*Ye--Htn9bt}5b-4342P={FA?#D{rE{X2*qRwP&d7I4vtOqq1iS`D&JSe( zyuU_NHJ4(FBnN;(Kb(wN!&3)kCd#bBMwmc6;Pp0hlpV7mQt&=JgAu~if`-6ct_RH}u@dHd~+(W<~v z=uYeka=;v)I9r+yl0qp>k@S=uaO*Os13Pv3?n6uTR>a|X#yc_QSZkomGbA|ec*ukJ z0G4>cEVVG&iRXJIAjg!r%b5(&Eo(O}u?oszp8hS|>|wuZN|HCcaWN=f8tj7^!ER9@X(TRp#=HZv0EP{_S_b znUQ>{!^y>9?jrWuW-sT-Jpk4~%ylUt>sgrM1BNhy5;`vSH{29rpPFyOPa>}) z?w4KbQyPeZB&-t48eR&sz55)bk}e~%i;Nx}7geTTi22rI&8x|# z%RdTmEBd-YLjJvx!D{m~6~~x#saF*#`}mMA_AEb*Q3@)$*PCxM8XJK9;nMy_DJaT* zX-R9j^)xYL3?a#>s=`6;#b&0~`{(YEKgDpO4J8^=-5x-bF+LKF~Q2F1eE`5ke97=#!TX^h8dHZBwPJpCR2Xc^R*R#G0HI=TyYj9vSN) nHAAc~>GyG$Z!dLtv1~Hz23&A_kml_T96(J;Te147W%$1U?q#Ql literal 4811 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 wwkMg(ud)zHnvTrT7`qm-5T;)h6tJ05=|DY5)KL diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0010.png b/cinema/gba/window/zmc-window-mosaic/baseline_0010.png index 8b555e49e340a6470ac8e70e446456b4a3e70ad7..dd985ca721dc5101dfac8af47fa2e4b56ab7587b 100644 GIT binary patch literal 5062 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 JDivNq{tr7Cbld;{ diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0012.png b/cinema/gba/window/zmc-window-mosaic/baseline_0012.png index 4e4165d5eb95ffb6b03be0cc219e3869ac1d1045..af7e92a27b7243b8bb39db6da488da9fd8f0a54b 100644 GIT binary patch literal 4518 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 V1Xoyna5iWI2D&CXRay_C{{v&!&~pF) literal 3886 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 literal 3863 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 literal 3858 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 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0016.png b/cinema/gba/window/zmc-window-mosaic/baseline_0016.png index d3636525a0bfe1de818d0dee5349fd92870b772f..ea3fa2a169db619a82095f59c75963f0e257b4a6 100644 GIT binary patch literal 3982 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 literal 3780 zcmaJ^XHXML+eH+DO1(5eK#d5z2no#q2~7+gg3_b}Py_^N5_$(g34(AzAoQjJ(jp0= z7wIJ+O_6{YsR2zwm0mvHJMWKszxHEyXJ>Y1ch7Uqp0jax5jt!a1TQc!FtF+A!c9)c zwbNF>!g$)ZH2BLgFtEq#!Ec)d=FoE6-KH%?dLwerSH5Z z`f9_$xC+rv#GN}FVbNT?QNXbvCrA;MbX!+YaZCUwk z6CNbYIXXKBlKZ9sxpHKJxS2cmGi>rZ`NVZMg`W>aI*g4t zp&vzmTP;Wkbe9(OGv2w7mB81mjb z3Z_VYRM1dv_CxK5KgEj_qoB4kWm1%meQFRm*872ndj&@SMs>OCzQ!TnZEF{gtn^-b zvh04LfO|I6agp3w`@zl`1=Q2K{E%scdOTo$YYL@Q@mzXbjtvM5gESYLHXy}{+(8(< z;V0IU?+NmnJ|65GwDu;UA1RO5Khr%uyu5U%AgKimCSHeDyqWRF->0DKB1z$V_RbRv zr>|vH>z*jyi4J0e4A&R`07b||!1gv=6w$Mflj_e{YS{@+4R--brssqNm4_b>dvk;nO6X}8y43Oyb42CC%^58vk4tQ)Ajp=C6JF#)+}QrOWyTI@7`=v8dmE8$v%W-a8qbN|t zN{wAL92Sg5yENUnc-Uzxbe()BUZ^)R7vtSXcE0y~vVwVd?!CSfQ2_?8X>ENt-E2y; zEM9D~@=i(~T9j-`_rSjrE{Scxbt0bnfn&>a|I&Fh#2^t6z%{$Ifl5Z}zZ0_ho%=-G z9xVX4elhH`XO(npoUX6;0zaSJ3dy2Z!DxOV{{$tnGPfmxP1;{wjI7^@atDb!$Xoes z0u1Ck(_PK|D^F=ye6k^)^ok|B)7tWz7tc%L+>_7Z zkJwq*JmW)UG2+1T)<4;%Tew$5PY*k0U4aCZ$h)%-Yv=n_lRhz;Kz&w$3iZ6Wb+d-% zUs7EA7XH895i)uc6T8iD&EJ7VChr$y<>kaU1^Xn@^tXw;KwR;7=0>oVSsHOs{QcYJ z=iO$gCK9m7(GX8o#gW;0t?1e37CE z+O<8mPz>q5Vx}`?XiBZ4A@{5@W+=Yyb-4{McxR-F#(7V!IPU&&OWpkQa-E8A(85fv zrKVOj1Y)u(A(q3d3iD=KWuc7mq^0QEeu0+Y??#q>|As(3Ft@+2Nhv23?Xux7>c!W0 z?$UnVQ{tH_jjpdh@6LJgM{W1Kk78+4`w zS^DeO8_~ylpzBciPV*LZM+#$hQ#+ZMfBD|=+j;I|b_;Pkx`zI@GIJX7vw7X>LAbn$q~DT0@r=YA*^F)`muy_CVO zK0Jb9gH&%=9(*Gl&aaewi~#F(=%%P9k7O_DRIq-zdg_}WIV;?5kBis`CAfw+N8N1j z(pZjMFT!o=x(G{gLS>rERYLh{*e`s$1Bh17j)n?PYAiFbz;%>_SvZ4{t-HVv?{|J| z?P@Gnvy3>O$q{+I8LOFWC!ldLclg+G`-St+x}s!M{+~a^zSbM>Hts&ELyqk!Z08?h zrxgvARHWTJDS#?%4mV_4*t@eTi7G|IB&Qnn@C|vJls0OdsQK4;TzT(SaI}xXbtM|Q2t+9;-?ZvPW(rkL%{{`DUQb`LcFDr$`}=UZ{^ z({$l5a6x?|(8WI3X$~(QXED@k ziqt>6>Z|c_rJq3)(0jh7HSDVIh{i7)rtuX!4t_-b3lR6q`rWh2vv2Lc zuu;;fP&t}r447D-R;|*nMTU%Y%~KQ1Xcn0A;9=~boQ}s8%;>vajX2fztQbeNPIE#+ zViHmJC$%pV5nFlT@~y1M)B)Y`uG#dn|DAe&XQC;tol846`}o(v>PdU+-?0Oh(DM}4$FrL zj<(^UdJ0`)7NUJP@#6_M3b=KtG&A_K;(Z&nA+Zh>lzX@@y;YvQ;X1zS#8y$6AL$i? z4XBWP-mChxZQv{Rq6X(KPu4wwNSmHv)h&T`XPLqug`9r@F{`s28%RC-`sFZ7F3a;j z4$C_kzVSWsn{IcNaaGaP0#M3udNHE!&$YgZUS-}<n4p% z=G$10DZu056lY^m!=FG{pv1ZVPw6~buaUM$Oak>m$b86Ss#UMYHeM7SChZA)m^duz z8)t;@-2-=$GXx{L_NZo>a>YGl-b6VwN2F-}tpQ%(-_-Cw0d*+*;(&o?j*{A?{?Ozg z(T@bwOif`6u;C-*bK}FI6+gflMs*#-+xUf<>;HU<{!NH$+0#`aV{>IipHQ5Rui$T@<;C53(G%VMu!@4i}(Bc#X9@liD7Q%jPLe5_ygUO6UM`E+30J8H`Q~e z&7`{Tgd!xxDVWf`g(q1`6|X?KhQO+dY;VR_E``9}`3|b}$W-c=2gxJuxXAE{>j1>z zZJeho$mCEX_zW2qBu!N*9*uY@9|)7i62L_K`scLXCdR_sG8r#!dqOxq%sg>^G<#U4 z1&4tkcCg?Y@gzS!$s0~^)DKK>nBEzT)kUs2i;*Ef5Iw^+mu5}T6LBrTGI#2QdVo}1X49H z+`Qs*i}h%h6xaZAukw>R=n0U`obtTo<|LU`dJoKLt`!8y zD{-nO()o8repo*xkhCWo%qyMcGrb35+ob_4tlmxT=JD`)e+{#R2;hpP`H4;KQ-fq;usX3+lO&7Ym0jlg}s zWslt0q4UMRU+~9k!MA4`-*!%}cwcF2#MrM?54G?KN&<)ul6t;)ygo-%tY!hv2|&y# Wd4fsX9Dn*dWzf??z^gPLJo_&-!b`{i diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0017.png b/cinema/gba/window/zmc-window-mosaic/baseline_0017.png index 2d6086460d2d57660c138051f29843ecc5c5fdc4..1d58c39787a292df1f457f9e6b01ede86b2b7642 100644 GIT binary patch literal 3737 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 scQc}i3#@*Ze)skJo#Y!<#sE$cP8JpxfT@Y0 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 TBm0Eo9~F}x904oQw0izOh8C+m literal 3262 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 J%J6c`KLBMdLBIe2 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0021.png b/cinema/gba/window/zmc-window-mosaic/baseline_0021.png index 792199be69a35dc73b4c30fefca36331738ff7e0..d47eb372faa1ee2d7b7eda648f99588ca3b2b250 100644 GIT binary patch literal 3284 zcmZ`+c{mhW8@Hq+$r4#6X-X6~OJmH~QVp_z~w=hCN zV`*$twjq;k?8}JE6uzl@zx#am`=0NQbI$WS%kO>9?>*-|&q**hH8{*C$;ZLLaoF%G z%#z)%vCC6lE_U5mAEe5`!JlggyJUSoZyDF(J$Y3u-a%j6zW9t3m10S??Nl&c;+*9I z=r24s+ii_V6m}O-k*kxriL7|<96X8_4P7pDvkjBK%Rg+*DG=4QY9)Y|PrSEHly43_ z?;xIdSqp2Fam(PT1h$tM*a5m1Qb~N=yB&xbDS+_T2byH;MZ{)kgr15+G8WO{JsW5C zCN`sWBRL>aGN4pG-owwhE_0VX=+iy-7o3ED5*bf9G15Yt#cvwt98ZZnZhf3O-tG%| zt|jJP>OxJLQhuTFn#}GfTdrI1=b*Ri&A&7HHf2C;w$qw(XpWmYS6cPb4??LKW4cb72m1z8Kvzt zoQuULKM8<{zibsX2v$0=N0fK){Z@8cC0C(G)H7^_!Tq2QfXY?aF_nY6V`ViP`vwAm z#1jG&WIFJ&_aW+GFR$m3@IUU#3B^XYe4eQ%!$7;Q-e~cYx`X&8Cj4`vMNS(D0~dld znv-y$-cp4UY>kqFW*zH*9-@gyl4kTg{B4_GWGa{yCn0N%kZgmEsm?LdalWXrDrU%= z$t8`;1{Q4sirqk<@lf&UgrYgSjN-*XC`d?%ZJOZ(EDH1X?F)`?J*l}ApuybmsG{G^ z1!jcJd_|q-Ni{$W?dZZRKoZFhC2?%hh9M~?s%owEfciyy5$!}EURCpDfHr)7rN`sd z(z3U;^o)E@ehz78v4ji@SWP4HDhtH7nwGZySP5t_?pM(F@EHXucAqSAtT0UpZ>FcN zJYRAYb`B2CUp$}Z1^W7GJ@@c{$s$O$WvzqLcaG05w*@M!C*tbAY}%lm6;KqD?ye6b z784~y@(o~kN|4F#{WtoFkjqKUhy0*#(=o_L`j?LKEET#y8|@n)RcDGE#VfPWG(?-H zz{3wmI*!O6R2?Xz3kty>_K)M#`GH_zk8=C)3jD%k|Ds=E&U&&M%WK_2E?04v℘F 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 mhvaLQepugp(EkBbs~|`K diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0022.png b/cinema/gba/window/zmc-window-mosaic/baseline_0022.png index 08a6d3dbae13d1b468c57d8edb4537703951d2cc..c9039b6aec542159e77a256ad450a1d8bee0ebec 100644 GIT binary patch delta 3118 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 IM6N<$f*!0KS^xk5 delta 2962 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 IM6N<$f-FM4S^xk5 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0023.png b/cinema/gba/window/zmc-window-mosaic/baseline_0023.png index 57d99fa3c21aa9a9dfa08c756b0efe261dd00320..382444fb8201fbc089060727fb0a1bc507e01d30 100644 GIT binary patch delta 2987 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 literal 2903 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 diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0024.png b/cinema/gba/window/zmc-window-mosaic/baseline_0024.png index a49291156c38d6d78b152c3373bd7c664d4167a6..53d25bf03724cdcca056f974127e42a1bf4bb57e 100644 GIT binary patch delta 2889 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 literal 2721 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 iE4W9p?^~bDe|TU#2H}=H zt4b|lq}EZiwx(!Q5E^Q!tyP+)A+9?!-*@lBJx}N1eCK@UJp89kd0Z(=i*&fi-uC>p zNZNXFcSg0L@|}IGY@lq~9hcet6{e;aXbgnjpr@w9A3B*xSlkbx4vu?*cj3+)8-bg( z1M0;p-r8fMmEU~SZH9N!p6{K4H6G@mU*6vB2~sV2)x$$;ETomOY>z4zK1@I;xm>}} zrKK-jJ70G9c!o3d+DJt@i6g{6d$ih6{bjNvGrRKZyDW4** z`>uRN`mLX<`TjT0iSeC?+!kDONP~_e4(Kae17mXrkt(mmF7A|(loCrqohJetYpQ=3 z7;HG1`r13VcFXK7SwwMK2IsZE1_Putq~^D2tYunr?U#;HTm+#u;NAVU*i%q$?q$Yj zeW(oJ28uf{Ri&WqCeZ$+wB?0;P_K_(D@!J>Lel5;OXF9njZT>DV#{Ik8S&s`;1x5s zm`tJF8@Y;|l~s3=>zgi)EzFfGe#7M~dWZb}#;yHM2*c1#U`n!CW=2?6_gg=gNA!b7 z@4!^zVJV8R5%Y7h-j4)4R zg-Kw&BGo)X&eZ|w{ow3@KrP9@%~+313SSvr+AA}+-&E+JJkSFm`|_od%F>tWSEx-f9Q||5;|D~tS&y%LYb`Jw@rY> zi)kWkNm5c`Fmd3cy6?Q#}n+7ybETMVBHh$yg zB0}hRPa!1Yu@KqG7lo<9G+!_~uzh7!x+L3C#}#oD#>mdh)?yY7VdCd#v8E}@v4E^v zUK>eYKd2Eucm1jope9+282M{}<;PcYx27XRl?uhY(Dl*|NT%uDX^m{&8FZs~^${*v zxoRx;d%zM10S$-h#adAq8nQUxg-&e~?pxy0UMR0?(bjq5#@VLUn7|2lhlYD3TKI_g zF;6nccfHWtZl=p)PUQ8pud6jDE|f_tjrjK9^0SXn?l)8hs_5=%3geiugqWDFxS~dv zS%hUtQu=g|af|2p=qVGuzsq-)95B4uj(FiOeT{k&#g!F9ZTbJV>=3R0!ZpG`?sXuS`Fg8Y)9VO24@qN0P9n)DNAB zyIl4XaxCp39}Vz*vO3jDFZRwuzaO7h-c;JP2=`Wxo@n2Ukzk8Ae3^riZ7B7FAJ_Ug zM;V85`N(!}c`|C<$;dCv-h%Kh%1pViP2+BiB?PGBXwUPGUSDt# zuy1}*x$D5T-yKjn!hbhzf|5+ut-k*kZix3tzdN~cu5Q!*;y=N?G&@zFapnw7JSs!p z(NwgkaZ-AuzX^m0F9gRBhJ4B-e~il5T-K_wn+0c%k{?gnfY@sReT)Kp8ppr>kbwF< zN5x^xj&J+*rw_G@biGDu%a!FIh&#`{Uzo@t+2_1Me)=B_D_kM;2ZW4}RJ_ zZCvABzhNpkA$l>UW8@53v=m&RrM0}2pe_vV+`?JV75;Wx|IB~)j+UDk9GOq||I2i@ zKYrZ%ySo~21)B69@0T-uvqZ)jY%@RKH(>F2$I38Pb2&)wHDjwkM`d{Y#Dq*qV|nkA z5zy}vmh!Z+-qqdN>7U~MtFy5^c}0rm5^lBgJ7=#f!&xiP+lYYq=rXp@rp$=Y-qdz= zT9Lcfdbr$4y)t-Ov(-0=nkfk}u(BvB-PzuS-@<#MQa{fW?h@pX^=p&mQP}3Kc8UH; zeO^|dI)u}m9k7bRbIMDI$loJy z(8!#}zgN->Mqm7fIpf@UG>+|GV;nMHDA*Cxpr~miG+N)($ zjd96nnZq!93Zd9&r6`c7Lo-|8V`0F-AS?UD@{O9Ym)S0(U9=_&PPqg<1YPK zKy;tjpO}Qis1k0VY^RwZ7-!?jK|fP^?jo77hod^D{g=MbY^O1A`uHgiQ1sTIYi?pVhjCN9K2!%-y5Xmm2O} z+dyFQpSGS%#Xq12FO6=Y^tYXz;H9^p6;|tiXhuR2uP!EBjB0HnKB#111r@J;wPj1{Dp diff --git a/cinema/gba/window/zmc-window-mosaic/baseline_0027.png b/cinema/gba/window/zmc-window-mosaic/baseline_0027.png index b9f6dc6f24cd93444ceb121dbba41c9dca4a2ad2..d6fcf669405fe236d93c9e7590725801031a180b 100644 GIT binary patch delta 2182 zcmV;12zmGY5xEkOBU%XnNkl!H%mi3`PAALKf;G|NoU)RLF`DdW!%J6xx`E z8S1%5vtZH`GUbdLjDdd*DQFs1cLgD6hH*P>7@E#!4MO>8sCuh*;9WHg4XPce8bzfX zk$xI~_g-k7iwm9i^K##Hb=#h?T(@ysUF+IuySvMEJr29?`%=rVJ|yrx{M*cMx6YCG z<1c?>IXaCKD=FW2Vr4f%KbZIWA87~Y!Q&M7p4a_04B9PZ2n|3HxN^+--G!(Z5u!$; z_4Yww=RHmH<_FI8U3Y4G=XLFU-xq5Kr=qlfnTVK(nH_Ve6se2du4|{A>%1qTwTsct z678Muh-mHZetWcV?dZ{V@H2?=hlo^8zv}mJda^n4aB;Hp^Y&=%wB7gZsf7x6b==~DTn0s7a2P;GZAqN*dn+3&3t-S=*>Jd5v8fF)m9^`9CP0Iwe`@7&Szp! zXy+UeiHL|4bUFlL=VX~#a*00Gka({v_(JZc@g zIp#P$nX}iK-}|~e^otWEeb=R0!{+ZLI-MxAaQfJUQkL($2V%GAFdyuB@1HjzM3Oi4 zeUr8uj|ivCUA*eMZrep!&oXBhCp}u5k>xl{!7RsOwSnC7ATF8~1Df~hyj}?898sKa z#K{Je_lrWM*MG{}6bHSXLwAXP%`+TyUdTCDRk`Vh)MhWl&dmpe%-m#$Rc9=8%{v=L*)H^^98Q zuO|a!IlwNrVTcoqN7|T(h=j%?!pz$Ylv+;?h|u62%<^0?bRan~QEELefzaR;w_&(f z)uwi;uv%(8Z-LO@4NFWA(K!C7Zrg#^or9SD{>mD zyBMe*ZgLqEe<321PX{A^z^U(3s4^aVI-Gnl(%%F^7bZvLv?sJK3xqC4zRJ(?m zV)I1d`(ph;AoNERwK)Q(KLSDnQ$XnBoDiNP2-3%a(7+TB`XESuv|SVI6<`VoeFTK( z%Yq#POaY;RDIhd31*+{9s0tEFKfnnT07739Rgn_@uM#lj0H)ZD(3_^$Rdu+$@V8LS zB5rxLrtwn~RczGtRYl#BPs^@%GLmoiyRITsg=QBbLIYDk=p*#MJpix=ga)R7&<8<~ zz9tYFm;yo{XBZHFrY{GC2Bv_}AAul!H6Zk-!0Af?p$h<~uLFcG1Dw7H5V{z{&_nBA z2j!!MiB4B7KG@#@pZh5c-BYM;sH(F+?O!Xl`+EKG@U?!1eJ z!5;zLTm8z9GP-t<_*rf z?iGMN>Wow!*rqw*JLteOnUwp_`0mC*Auz=ep)&&$EauSQ=Q(-dD416+-d(smFR zTn)^jfhiy~Fa?ALrug@b_Yb&z-;lu%fs>5}CzEam3lgGM-B9$Vx#%jWZcQ6d5()}{ zlZ^%+f6CBTmvHG4g8&9#=J%b>2Tzg(r*L21Ygtt^@d*$bd_-SWb8N2LmWV`zMBK8Q z58-E=hS1<6>S5@+j)>~EjSCdQYVxsq&T|^PQ_HpO+vCX{_?5V8ZZN5O9zFPw{>kPQ z_Yjzf9TAaux=)c?+rCGwy8Ec|No|TXtGSUBqu_f1rI6XxpE`lw-j?-19r%zVK-t zZ0F)VC36fW@;iyP*fH9f9^q-*pMlVz7*XXpg!&zuZ%s27ex!D4+c)`6p^Ijg7s)ro z+@su@CY}M2q-C%3o|oG8jh>nPOrlJygE#zG!Nv=4PzX%%A4&3_cv!7u)Bpeg07*qo IM6N<$f}cAxy#N3J delta 2099 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 diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index e8a474c0a..a8a471e09 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -17,19 +17,12 @@ #define SPRITE_MOSAIC_LOOP(DEPTH, TYPE) \ SPRITE_YBASE_ ## DEPTH(inY); \ unsigned tileData; \ - if (outX % mosaicH) { \ - if (!inX && xOffset > 0) { \ - inX = mosaicH - (outX % mosaicH); \ - outX += mosaicH - (outX % mosaicH); \ - } else if (inX == width - xOffset) { \ - inX = mosaicH + (outX % mosaicH); \ - outX += mosaicH - (outX % mosaicH); \ - } \ - } \ for (; outX < condition; ++outX, inX += xOffset) { \ int localX = inX - xOffset * (outX % mosaicH); \ - if (localX < 0 || localX > width - 1) { \ - continue; \ + if (localX < 0) { \ + localX = 0; \ + } else if (localX > width - 1) {\ + localX = width - 1; \ } \ SPRITE_XBASE_ ## DEPTH(localX); \ SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(localX); \ diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 0e5d7dd5f..4c83844ad 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -805,11 +805,17 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { struct GBAVideoRendererSprite* sprite = &renderer->sprites[i]; int localY = y; renderer->end = 0; + if ((y < sprite->y && (sprite->endY - 256 < 0 || y >= sprite->endY - 256)) || y >= sprite->endY) { + continue; + } if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { localY = mosaicY; - } - if ((localY < sprite->y && (sprite->endY - 256 < 0 || localY >= sprite->endY - 256)) || localY >= sprite->endY) { - continue; + if (localY < sprite->y) { + localY = sprite->y; + } + if (localY >= sprite->endY) { + localY = sprite->endY - 1; + } } for (w = 0; w < renderer->nWindows; ++w) { if (renderer->spriteCyclesRemaining <= 0) { From 1868ccaadd9e50ad929a72666956f6b01e2e219c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 17:28:34 -0700 Subject: [PATCH 266/429] Qt: Only close GL context on thread when shutting down --- src/platform/qt/DisplayGL.cpp | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index dc360cdb0..3bba105e3 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -315,18 +315,8 @@ void PainterGL::resizeContext() { return; } - if (!m_active) { - m_gl->makeCurrent(m_surface); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif - } - QSize size = m_context->screenDimensions(); m_backend->setDimensions(m_backend, size.width(), size.height()); - if (!m_active) { - m_gl->doneCurrent(); - } } void PainterGL::setMessagePainter(MessagePainter* messagePainter) { @@ -493,12 +483,6 @@ void PainterGL::setShaders(struct VDir* dir) { return; } #ifdef BUILD_GLES2 - if (!m_active) { - m_gl->makeCurrent(m_surface); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif - } if (m_shader.passes) { mGLES2ShaderDetach(reinterpret_cast(m_backend)); mGLES2ShaderFree(&m_shader); @@ -507,9 +491,6 @@ void PainterGL::setShaders(struct VDir* dir) { if (m_started) { mGLES2ShaderAttach(reinterpret_cast(m_backend), static_cast(m_shader.passes), m_shader.nPasses); } - if (!m_active) { - m_gl->doneCurrent(); - } #endif } @@ -518,19 +499,10 @@ void PainterGL::clearShaders() { return; } #ifdef BUILD_GLES2 - if (!m_active) { - m_gl->makeCurrent(m_surface); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif - } if (m_shader.passes) { mGLES2ShaderDetach(reinterpret_cast(m_backend)); mGLES2ShaderFree(&m_shader); } - if (!m_active) { - m_gl->doneCurrent(); - } #endif } From 838d13f2efb8b97aa7e09f93441b5f5090326b8f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 18:19:55 -0700 Subject: [PATCH 267/429] GBA Video: Improve GL sprite mosaic --- src/gba/renderers/gl.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index e7941f161..ff77ed4e7 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -404,10 +404,13 @@ static const char* const _renderObj = "void main() {\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " incoord.x -= mod(mosaic.z + incoord.x, mosaic.x);\n" + " incoord.x = int(clamp(incoord.x - mod(mosaic.z + incoord.x, mosaic.x), 0, dims.z - 1));\n" + " } else if (mosaic.x < -1) {\n" + " incoord.x = dims.z - incoord.x - 1;" + " incoord.x = clamp(dims.z - int(incoord.x - mod(mosaic.z + incoord.x, -mosaic.x)) - 1, 0, dims.z - 1);\n" " }\n" " if (mosaic.y > 1) {\n" - " incoord.y -= mod(mosaic.w + incoord.y, mosaic.y);\n" + " incoord.y = int(clamp(incoord.y - mod(mosaic.w + incoord.y, mosaic.y), 0, dims.w - 1));\n" " }\n" " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" @@ -1340,7 +1343,11 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } if (GBAObjAttributesAIsMosaic(sprite->a)) { - glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], GBAMosaicControlGetObjV(renderer->mosaic) + 1, GBAMosaicControlGetObjH(renderer->mosaic) + 1, x, spriteY); + int mosaicH = GBAMosaicControlGetObjH(renderer->mosaic) + 1; + if (GBAObjAttributesBIsHFlip(sprite->b)) { + mosaicH = -mosaicH; + } + glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], mosaicH, GBAMosaicControlGetObjV(renderer->mosaic) + 1, x, spriteY); } else { glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0); } From bdb584a39849899db5062f0894058c7783860381 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 19:12:45 -0700 Subject: [PATCH 268/429] Qt: Fix GL scaling --- src/platform/qt/CoreController.cpp | 1 + src/platform/qt/CoreController.h | 1 + src/platform/qt/DisplayGL.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index bd12de40d..d073ac654 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -86,6 +86,7 @@ CoreController::CoreController(mCore* core, QObject* parent) context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer->data()), controller->screenDimensions().width()); } + QMetaObject::invokeMethod(controller, "didReset"); controller->finishFrame(); }; diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index e31602117..59fd37ee5 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -170,6 +170,7 @@ signals: void crashed(const QString& errorMessage); void failed(); void frameAvailable(); + void didReset(); void stateLoaded(); void rewound(); diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 3bba105e3..4bbb5a575 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -108,6 +108,7 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatio()); #endif resizePainter(); + connect(m_context.get(), &CoreController::didReset, this, &DisplayGL::resizeContext); } void DisplayGL::stopDrawing() { From fd6948da4d5c066ecbb298081ed5a8cb661c9c86 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 19:16:07 -0700 Subject: [PATCH 269/429] GBA Video: OBJWIN sprites cannot be mosaic --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ff77ed4e7..6d7aafd14 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1342,7 +1342,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } - if (GBAObjAttributesAIsMosaic(sprite->a)) { + if (GBAObjAttributesAIsMosaic(sprite->a) && GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN) { int mosaicH = GBAMosaicControlGetObjH(renderer->mosaic) + 1; if (GBAObjAttributesBIsHFlip(sprite->b)) { mosaicH = -mosaicH; From 35200b6c7ae59841b429dbd196d7a2f9661df88f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 20 May 2019 23:57:48 -0700 Subject: [PATCH 270/429] GB: Fix HALT when IE and IF unused bits are set (fixes #1349) --- CHANGES | 1 + src/gb/gb.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index fa64821a2..60e0bd8b9 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Emulation fixes: - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) + - GB: Fix HALT when IE and IF unused bits are set (fixes mgba.io/i/1349) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gb/gb.c b/src/gb/gb.c index fc3c174b0..5f5178a90 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -723,7 +723,7 @@ static void _enableInterrupts(struct mTiming* timing, void* user, uint32_t cycle void GBHalt(struct LR35902Core* cpu) { struct GB* gb = (struct GB*) cpu->master; - if (!(gb->memory.ie & gb->memory.io[REG_IF])) { + if (!(gb->memory.ie & gb->memory.io[REG_IF] & 0x1F)) { cpu->cycles = cpu->nextEvent; cpu->halted = true; } else if (gb->model < GB_MODEL_CGB) { From e90b8d235467679229ab16032c64bf8508bb5440 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 07:14:03 -0700 Subject: [PATCH 271/429] Qt: Fix crash when GL context is missing --- src/platform/qt/Window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 335149cf3..24a37b0d8 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -634,6 +634,8 @@ void Window::closeEvent(QCloseEvent* event) { if (m_controller) { event->ignore(); m_pendingClose = true; + } else { + m_display.reset(); } } From 18f27d5ee6d4d1d74a9a9826c34aab6cbe8219dc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 07:17:42 -0700 Subject: [PATCH 272/429] Qt: Fix logging trying to open a null file --- src/platform/qt/LogController.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/qt/LogController.cpp b/src/platform/qt/LogController.cpp index e6f80e0b1..dfd472c2f 100644 --- a/src/platform/qt/LogController.cpp +++ b/src/platform/qt/LogController.cpp @@ -127,6 +127,9 @@ void LogController::logToStdout(bool log) { void LogController::setLogFile(const QString& file) { m_logStream.reset(); + if (file.isEmpty()) { + return; + } m_logFile = std::make_unique(file); m_logFile->open(QIODevice::Append | QIODevice::Text); m_logStream = std::make_unique(m_logFile.get()); From 3aae19a8073a60587a908e1029a253cc42b7b9d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 17:17:24 -0700 Subject: [PATCH 273/429] Qt: Windows fixes --- src/platform/qt/DisplayGL.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 4bbb5a575..e0cf146a9 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -35,6 +35,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) , m_gl(nullptr) { setAttribute(Qt::WA_NativeWindow); + windowHandle()->create(); // This can spontaneously re-enter into this->resizeEvent before creation is done, so we // need to make sure it's initialized to nullptr before we assign the new object to it @@ -263,6 +264,10 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent if (!painter->m_gl->isValid()) { return; } + painter->m_gl->makeCurrent(painter->m_surface); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif painter->m_gl->swapBuffers(painter->m_gl->surface()); }; From 84c010783c18fcb53ffddc83ba818055c90da758 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Tue, 21 May 2019 21:24:03 +0100 Subject: [PATCH 274/429] SDL: Simplify setting full screen mode with SDL1 --- src/platform/sdl/gl-common.c | 4 ++-- src/platform/sdl/main.c | 4 ---- src/platform/sdl/main.h | 2 -- src/platform/sdl/sdl-events.h | 2 +- src/platform/sdl/sw-sdl1.c | 4 ++-- 5 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index e4d400b29..d9c62c9a5 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -51,9 +51,9 @@ void mSDLGLCommonInit(struct mSDLRenderer* renderer) { #else SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); #ifdef COLOR_16_BIT - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #else - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL | SDL_RESIZABLE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #endif SDL_WM_SetCaption(projectName, ""); #endif diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 21e4459b7..d82d4fb24 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -131,12 +131,8 @@ int main(int argc, char** argv) { renderer.viewportWidth = renderer.core->opts.width; renderer.viewportHeight = renderer.core->opts.height; -#if SDL_VERSION_ATLEAST(2, 0, 0) renderer.player.fullscreen = renderer.core->opts.fullscreen; renderer.player.windowUpdated = 0; -#else - renderer.fullscreen = renderer.core->opts.fullscreen; -#endif renderer.lockAspectRatio = renderer.core->opts.lockAspectRatio; renderer.lockIntegerScaling = renderer.core->opts.lockIntegerScaling; diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index bd4f2cecc..5f286d5fd 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -54,8 +54,6 @@ struct mSDLRenderer { SDL_Texture* sdlTex; SDL_Renderer* sdlRenderer; SDL_GLContext* glCtx; -#else - bool fullscreen; #endif unsigned width; diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 7df0672c3..8cb1aede2 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -63,10 +63,10 @@ struct mSDLPlayer { size_t playerId; struct mInputMap* bindings; struct SDL_JoystickCombo* joystick; + int fullscreen; int windowUpdated; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Window* window; - int fullscreen; struct mSDLRumble { struct mRumble d; diff --git a/src/platform/sdl/sw-sdl1.c b/src/platform/sdl/sw-sdl1.c index c8002fd24..90a9d2499 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_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #else - SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->fullscreen)); + SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE | (SDL_FULLSCREEN * renderer->player.fullscreen)); #endif SDL_WM_SetCaption(projectName, ""); From 57a7a0a2911aaf28241efce70b12fc9add585dc3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 14:26:30 -0700 Subject: [PATCH 275/429] GBA Video: Fix rounding issues on Nvidia --- src/gba/renderers/gl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 6d7aafd14..ab57298c3 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -404,13 +404,13 @@ static const char* const _renderObj = "void main() {\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " incoord.x = int(clamp(incoord.x - mod(mosaic.z + incoord.x, mosaic.x), 0, dims.z - 1));\n" + " incoord.x = clamp(incoord.x - int(mod(mosaic.z + incoord.x, mosaic.x)), 0, dims.z - 1);\n" " } else if (mosaic.x < -1) {\n" " incoord.x = dims.z - incoord.x - 1;" - " incoord.x = clamp(dims.z - int(incoord.x - mod(mosaic.z + incoord.x, -mosaic.x)) - 1, 0, dims.z - 1);\n" + " incoord.x = clamp(dims.z - incoord.x + int(mod(mosaic.z + incoord.x, -mosaic.x)) - 1, 0, dims.z - 1);\n" " }\n" " if (mosaic.y > 1) {\n" - " incoord.y = int(clamp(incoord.y - mod(mosaic.w + incoord.y, mosaic.y), 0, dims.w - 1));\n" + " incoord.y = clamp(incoord.y - int(mod(mosaic.w + incoord.y, mosaic.y)), 0, dims.w - 1);\n" " }\n" " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" From 6c1bc5548cf61da25f1fc70fe961fbbadff2b714 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 15:17:42 -0700 Subject: [PATCH 276/429] GBA Video: Fix scale/rot sprite mosaic in GL --- src/gba/renderers/gl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ab57298c3..6546dc57d 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -404,13 +404,15 @@ static const char* const _renderObj = "void main() {\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " incoord.x = clamp(incoord.x - int(mod(mosaic.z + incoord.x, mosaic.x)), 0, dims.z - 1);\n" + " int x = int(incoord.x);\n" + " incoord.x = clamp(x - int(mod(mosaic.z + x, mosaic.x)), 0, dims.z - 1);\n" " } else if (mosaic.x < -1) {\n" - " incoord.x = dims.z - incoord.x - 1;" - " incoord.x = clamp(dims.z - incoord.x + int(mod(mosaic.z + incoord.x, -mosaic.x)) - 1, 0, dims.z - 1);\n" + " int x = dims.z - int(incoord.x) - 1;\n" + " incoord.x = clamp(dims.z - x + int(mod(mosaic.z + x, -mosaic.x)) - 1, 0, dims.z - 1);\n" " }\n" " if (mosaic.y > 1) {\n" - " incoord.y = clamp(incoord.y - int(mod(mosaic.w + incoord.y, mosaic.y)), 0, dims.w - 1);\n" + " int y = int(incoord.y);\n" + " incoord.y = clamp(y - int(mod(mosaic.w + y, mosaic.y)), 0, dims.w - 1);\n" " }\n" " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" From 2781a2a9f951b39ff89e47d0d13106918e1316c3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 15:32:20 -0700 Subject: [PATCH 277/429] GBA Video: Implement sprite mosaic on transformed sprites --- CHANGES | 1 + README.md | 1 - README_DE.md | 1 - src/gba/renderers/software-obj.c | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 60e0bd8b9..eff7ec3f7 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Emulation fixes: - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) - GB: Fix HALT when IE and IF unused bits are set (fixes mgba.io/i/1349) + - GBA Video: Implement mosaic on transformed sprites (fixes mgba.io/b/9) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/README.md b/README.md index b3350460a..9042c0ead 100644 --- a/README.md +++ b/README.md @@ -215,7 +215,6 @@ Footnotes [1] Currently missing features are - OBJ window for modes 3, 4 and 5 ([Bug #5](http://mgba.io/b/5)) -- Mosaic for transformed OBJs ([Bug #9](http://mgba.io/b/9)) [2] Flash memory size detection does not work in some cases. These can be configured at runtime, but filing a bug is recommended if such a case is encountered. diff --git a/README_DE.md b/README_DE.md index a41d5fbcd..172b5f826 100644 --- a/README_DE.md +++ b/README_DE.md @@ -215,7 +215,6 @@ Fußnoten [1] Zurzeit fehlende Features sind - OBJ-Fenster für die Modi 3, 4 und 5 ([Bug #5](http://mgba.io/b/5)) -- Mosaik-Effekt für umgewandelte OBJs ([Bug #9](http://mgba.io/b/9)) [2] In manchen Fällen ist es nicht möglich, die Größe des Flash-Speichers automatisch zu ermitteln. Diese kann dann zur Laufzeit konfiguriert werden, es wird jedoch empfohlen, den Fehler zu melden. diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index a8a471e09..de056596d 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -48,6 +48,31 @@ SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(localX); \ } +#define SPRITE_TRANSFORMED_MOSAIC_LOOP(DEPTH, TYPE) \ + unsigned tileData; \ + unsigned widthMask = ~(width - 1); \ + unsigned heightMask = ~(height - 1); \ + int localX = xAccum >> 8; \ + int localY = yAccum >> 8; \ + for (; outX < condition; ++outX, ++inX) { \ + renderer->spriteCyclesRemaining -= 2; \ + xAccum += mat.a; \ + yAccum += mat.c; \ + \ + if (outX % mosaicH == 0) { \ + localX = xAccum >> 8; \ + localY = yAccum >> 8; \ + } \ + \ + if (localX & widthMask || localY & heightMask) { \ + continue; \ + } \ + \ + SPRITE_YBASE_ ## DEPTH(localY); \ + SPRITE_XBASE_ ## DEPTH(localX); \ + SPRITE_DRAW_PIXEL_ ## DEPTH ## _ ## TYPE(localX); \ + } + #define SPRITE_XBASE_16(localX) unsigned xBase = (localX & ~0x7) * 4 + ((localX >> 1) & 2); #define SPRITE_YBASE_16(localY) unsigned yBase = (localY & ~0x7) * stride + (localY & 0x7) * 4; @@ -173,6 +198,13 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re if (end < condition) { condition = end; } + int mosaicH = 1; + if (GBAObjAttributesAIsMosaic(sprite->a)) { + mosaicH = GBAMosaicControlGetObjH(renderer->mosaic) + 1; + if (condition % mosaicH) { + condition += mosaicH - (condition % mosaicH); + } + } int xAccum = mat.a * (inX - 1 - (totalWidth >> 1)) + mat.b * (inY - (totalHeight >> 1)) + (width << 7); int yAccum = mat.c * (inX - 1 - (totalWidth >> 1)) + mat.d * (inY - (totalHeight >> 1)) + (height << 7); @@ -223,6 +255,13 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re palette = &palette[GBAObjAttributesCGetPalette(sprite->c) << 4]; if (flags & FLAG_OBJWIN) { SPRITE_TRANSFORMED_LOOP(16, OBJWIN); + } else if (mosaicH > 1) { + if (objwinSlowPath) { + objwinPalette = &objwinPalette[GBAObjAttributesCGetPalette(sprite->c) << 4]; + SPRITE_TRANSFORMED_MOSAIC_LOOP(16, NORMAL_OBJWIN); + } else { + SPRITE_TRANSFORMED_MOSAIC_LOOP(16, NORMAL); + } } else if (objwinSlowPath) { objwinPalette = &objwinPalette[GBAObjAttributesCGetPalette(sprite->c) << 4]; SPRITE_TRANSFORMED_LOOP(16, NORMAL_OBJWIN); @@ -232,6 +271,12 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re } else { if (flags & FLAG_OBJWIN) { SPRITE_TRANSFORMED_LOOP(256, OBJWIN); + } else if (mosaicH > 1) { + if (objwinSlowPath) { + SPRITE_TRANSFORMED_MOSAIC_LOOP(256, NORMAL_OBJWIN); + } else { + SPRITE_TRANSFORMED_MOSAIC_LOOP(256, NORMAL); + } } else if (objwinSlowPath) { SPRITE_TRANSFORMED_LOOP(256, NORMAL_OBJWIN); } else { From 787c99b949b93e7263c53f483ff556dbd9684869 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2019 22:32:24 -0700 Subject: [PATCH 278/429] Qt: Improve GL syncing --- src/platform/qt/CoreController.h | 3 +++ src/platform/qt/Display.cpp | 2 +- src/platform/qt/DisplayGL.cpp | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 59fd37ee5..978421249 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -98,6 +98,9 @@ public: void setInputController(InputController*); void setLogger(LogController*); + bool audioSync() const { return m_audioSync; } + bool videoSync() const { return m_videoSync; } + public slots: void start(); void stop(); diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index ee754c4f0..ed7c1fd38 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -20,7 +20,7 @@ Display* Display::create(QWidget* parent) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY) QSurfaceFormat format; format.setSwapInterval(1); - format.setSwapBehavior(QSurfaceFormat::TripleBuffer); + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); #endif switch (s_driver) { diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index e0cf146a9..77439874a 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -264,11 +264,12 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent if (!painter->m_gl->isValid()) { return; } + painter->m_gl->doneCurrent(); + painter->m_gl->swapBuffers(painter->m_surface); painter->m_gl->makeCurrent(painter->m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif - painter->m_gl->swapBuffers(painter->m_gl->surface()); }; m_backend->init(m_backend, 0); @@ -383,7 +384,7 @@ void PainterGL::draw() { m_backend->swap(m_backend); if (!m_delayTimer.isValid()) { m_delayTimer.start(); - } else if (m_gl->format().swapInterval()) { + } else if (m_gl->format().swapInterval() && m_context->videoSync()) { while (m_delayTimer.elapsed() < 15) { QThread::usleep(100); } From 52ac4d6868f4f61bf62f3d279197a83786fb4ff9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 11:01:16 -0700 Subject: [PATCH 279/429] GBA Audio: Ensure mixer is initialized --- src/gba/audio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gba/audio.c b/src/gba/audio.c index b337043a3..d2650d6e8 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -55,6 +55,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; + audio->mixer = NULL; } void GBAAudioReset(struct GBAAudio* audio) { From a4ceefa3218e7dda4aea2c33f72e257598b7bb4d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 11:10:55 -0700 Subject: [PATCH 280/429] Qt: Fix exclusive options unchecking --- src/platform/qt/Action.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/Action.cpp b/src/platform/qt/Action.cpp index 0fe4be787..e5d6600d4 100644 --- a/src/platform/qt/Action.cpp +++ b/src/platform/qt/Action.cpp @@ -67,6 +67,10 @@ void Action::trigger(bool active) { return; } + if (m_exclusive && !m_booleanFunction) { + active = true; + } + if (m_function && active) { m_function(); } From 7f86ebc4e6f8f1d24f2a6276a65b0f2635aad81c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 11:15:21 -0700 Subject: [PATCH 281/429] Qt: Preserve native FPS target when saving settings --- src/platform/qt/SettingsView.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index d5d0a91ac..9acf56a99 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -370,7 +370,6 @@ void SettingsView::updateConfig() { saveSetting("videoSync", m_ui.videoSync); saveSetting("audioSync", m_ui.audioSync); saveSetting("frameskip", m_ui.frameskip); - saveSetting("fpsTarget", m_ui.fpsTarget); saveSetting("autofireThreshold", m_ui.autofireThreshold); saveSetting("lockAspectRatio", m_ui.lockAspectRatio); saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling); @@ -409,6 +408,13 @@ void SettingsView::updateConfig() { saveSetting("fastForwardRatio", m_ui.fastForwardRatio); } + double nativeFps = double(GBA_ARM7TDMI_FREQUENCY) / double(VIDEO_TOTAL_LENGTH); + if (nativeFps - m_ui.fpsTarget->value() < 0.0001) { + m_controller->setOption("fpsTarget", QVariant(nativeFps)); + } else { + saveSetting("fpsTarget", m_ui.fpsTarget); + } + switch (m_ui.idleOptimization->currentIndex() + IDLE_LOOP_IGNORE) { case IDLE_LOOP_IGNORE: saveSetting("idleOptimization", "ignore"); From 1084246e8ff7fa66c540c273e40b9cb857fd79e7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 11:18:22 -0700 Subject: [PATCH 282/429] CHANGES: Update --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index eff7ec3f7..2d1a66b0e 100644 --- a/CHANGES +++ b/CHANGES @@ -48,6 +48,7 @@ Other fixes: - Core: Improved lockstep driver reliability (Le Hoang Quyen) - GBA: Fix skipping BIOS on irregularly sized ROMs - Qt: Fix bounded fast forward with Qt Multimedia + - Qt: Fix saving settings with native FPS target Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash From eb5a7951010f00548007b549f08d72d2bc3d4940 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 11:29:24 -0700 Subject: [PATCH 283/429] Qt: Add native FPS button to settings view --- CHANGES | 1 + src/platform/qt/SettingsView.cpp | 4 ++++ src/platform/qt/SettingsView.ui | 23 +++++++++++++++-------- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 2d1a66b0e..f5c0f18e2 100644 --- a/CHANGES +++ b/CHANGES @@ -69,6 +69,7 @@ Misc: - GBA Video: Clean up dead code in sprite rendering loop - FFmpeg: Support audio-only recording - Qt: Increase maximum magnifications and scaling + - Qt: Add native FPS button to settings view 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 9acf56a99..d8bb7e3e7 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -57,6 +57,10 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC } }); + connect(m_ui.nativeGB, &QAbstractButton::pressed, [this]() { + m_ui.fpsTarget->setValue(double(GBA_ARM7TDMI_FREQUENCY) / double(VIDEO_TOTAL_LENGTH)); + }); + if (m_ui.savegamePath->text().isEmpty()) { m_ui.savegameSameDir->setChecked(true); } diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 1a7a9e83f..1f51e5abf 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -6,8 +6,8 @@ 0 0 - 790 - 686 + 849 + 753 @@ -399,21 +399,21 @@ - + Qt::Horizontal - + Sync: - + @@ -431,27 +431,34 @@ - + Lock aspect ratio - + Force integer scaling - + Bilinear filtering + + + + Native (59.7275) + + + From a0af0ce1419eca9cc03f4b7a66638603898f66c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 12:21:53 -0700 Subject: [PATCH 284/429] GL: Fix VAO semantics --- src/gba/renderers/gl.c | 10 ++-------- src/platform/opengl/gles2.c | 6 ++++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 6546dc57d..456fbd31e 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -571,6 +571,7 @@ static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVide glBindVertexArray(shader->vao); glBindBuffer(GL_ARRAY_BUFFER, glRenderer->vbo); GLuint positionLocation = glGetAttribLocation(program, "position"); + glEnableVertexAttribArray(positionLocation); glVertexAttribPointer(positionLocation, 2, GL_INT, GL_FALSE, 0, NULL); size_t i; @@ -1131,12 +1132,12 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; _finalizeLayers(glRenderer); + glBindVertexArray(0); glRenderer->firstAffine = -1; glRenderer->bg[2].affine[0].sx = glRenderer->bg[2].refx; glRenderer->bg[2].affine[0].sy = glRenderer->bg[2].refy; glRenderer->bg[3].affine[0].sx = glRenderer->bg[3].refx; glRenderer->bg[3].affine[0].sy = glRenderer->bg[3].refy; - glFlush(); } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { @@ -1273,7 +1274,6 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROP], 11); glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 12); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1353,7 +1353,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } else { glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0); } - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1399,7 +1398,6 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1475,7 +1473,6 @@ void GBAVideoGLRendererDrawBackgroundMode2(struct GBAVideoGLRenderer* renderer, glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1490,7 +1487,6 @@ void GBAVideoGLRendererDrawBackgroundMode3(struct GBAVideoGLRenderer* renderer, _prepareTransform(renderer, background, uniforms, y); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], 0); glUniform2i(uniforms[GBA_GL_BG_SIZE], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1505,7 +1501,6 @@ void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* renderer, _prepareTransform(renderer, background, uniforms, y); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 0xA000 : 0); glUniform2i(uniforms[GBA_GL_BG_SIZE], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1520,7 +1515,6 @@ void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, _prepareTransform(renderer, background, uniforms, y); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 0x5000 : 0); glUniform2i(uniforms[GBA_GL_BG_SIZE], 160, 128); - glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index c9994f10a..168858241 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -136,9 +136,11 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { glBindVertexArray(context->initialShader.vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(context->initialShader.positionLocation); glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glBindVertexArray(context->finalShader.vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(context->finalShader.positionLocation); glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glBindVertexArray(0); @@ -303,7 +305,6 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { break; } } - glEnableVertexAttribArray(shader->positionLocation); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindTexture(GL_TEXTURE_2D, shader->tex); } @@ -327,6 +328,7 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) { _drawShader(context, &context->finalShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(0); + glBindVertexArray(0); } void mGLES2ContextPostFrame(struct VideoBackend* v, const void* frame) { @@ -463,8 +465,8 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad glBindVertexArray(context->shaders[i].vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(context->shaders[i].positionLocation); + glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); } glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); From 572f4df7e7ed5c5bd82c791bce0c5cfd1050d516 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 13:51:42 -0700 Subject: [PATCH 285/429] GBA Video: Begin work on batching GL draw calls --- include/mgba/internal/gba/renderers/gl.h | 4 + src/gba/renderers/gl.c | 245 +++++++++++++++-------- 2 files changed, 171 insertions(+), 78 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 6b10d2777..e6f8db74c 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -150,6 +150,9 @@ struct GBAVideoGLRenderer { GLuint vramTex; unsigned vramDirty; + uint16_t shadowRegs[0x30]; + uint64_t regsDirty; + struct GBAVideoGLShader bgShader[6]; struct GBAVideoGLShader objShader[2]; struct GBAVideoGLShader finalizeShader; @@ -177,6 +180,7 @@ struct GBAVideoGLRenderer { GBAWindowControl objwin; int firstAffine; + int firstY; int scale; }; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 456fbd31e..ed4b5a28d 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -43,9 +43,11 @@ static void GBAVideoGLRendererDrawBackgroundMode4(struct GBAVideoGLRenderer* ren static void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y); static void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y); +static void _cleanRegister(struct GBAVideoGLRenderer* renderer, int address, uint16_t value); +static void _drawScanlines(struct GBAVideoGLRenderer* renderer, int lastY); static void _finalizeLayers(struct GBAVideoGLRenderer* renderer); -#define TEST_LAYER_ENABLED(X) !renderer->disableBG[X] && glRenderer->bg[X].enabled == 4 +#define TEST_LAYER_ENABLED(X) !glRenderer->d.disableBG[X] && glRenderer->bg[X].enabled == 4 struct GBAVideoGLUniform { const char* name; @@ -761,6 +763,7 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { glRenderer->paletteDirty = true; glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; + glRenderer->firstY = -1; glRenderer->dispcnt = 0; glRenderer->mosaic = 0; } @@ -793,58 +796,87 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, GBAVideoCacheWriteVideoRegister(renderer->cache, address, value); } + glRenderer->regsDirty |= 1ULL << (address >> 1); switch (address) { case REG_DISPCNT: value &= 0xFFF7; + break; + case REG_BG0CNT: + case REG_BG1CNT: + value &= 0xDFFF; + break; + case REG_BG0HOFS: + case REG_BG0VOFS: + case REG_BG1HOFS: + case REG_BG1VOFS: + case REG_BG2HOFS: + case REG_BG2VOFS: + case REG_BG3HOFS: + case REG_BG3VOFS: + value &= 0x01FF; + break; + case REG_BLDALPHA: + value &= 0x1F1F; + break; + case REG_BLDY: + value &= 0x1F; + if (value > 0x10) { + value = 0x10; + } + break; + case REG_WININ: + value &= 0x3F3F; + break; + case REG_WINOUT: + value &= 0x3F3F; + break; + default: + break; + } + glRenderer->shadowRegs[address >> 1] = value; + return value; +} + +void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t value) { + switch (address) { + case REG_DISPCNT: glRenderer->dispcnt = value; GBAVideoGLRendererUpdateDISPCNT(glRenderer); break; case REG_BG0CNT: - value &= 0xDFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[0], value); break; case REG_BG1CNT: - value &= 0xDFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[1], value); break; case REG_BG2CNT: - value &= 0xFFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[2], value); break; case REG_BG3CNT: - value &= 0xFFFF; GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[3], value); break; case REG_BG0HOFS: - value &= 0x01FF; glRenderer->bg[0].x = value; break; case REG_BG0VOFS: - value &= 0x01FF; glRenderer->bg[0].y = value; break; case REG_BG1HOFS: - value &= 0x01FF; glRenderer->bg[1].x = value; break; case REG_BG1VOFS: - value &= 0x01FF; glRenderer->bg[1].y = value; break; case REG_BG2HOFS: - value &= 0x01FF; glRenderer->bg[2].x = value; break; case REG_BG2VOFS: - value &= 0x01FF; glRenderer->bg[2].y = value; break; case REG_BG3HOFS: - value &= 0x01FF; glRenderer->bg[3].x = value; break; case REG_BG3VOFS: - value &= 0x01FF; glRenderer->bg[3].y = value; break; case REG_BG2PA: @@ -911,10 +943,6 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, value &= 0x1F1F; break; case REG_BLDY: - value &= 0x1F; - if (value > 0x10) { - value = 0x10; - } glRenderer->bldy = value; break; case REG_WIN0H: @@ -970,12 +998,10 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, } break; case REG_WININ: - value &= 0x3F3F; glRenderer->winN[0].control = value; glRenderer->winN[1].control = value >> 8; break; case REG_WINOUT: - value &= 0x3F3F; glRenderer->winout = value; glRenderer->objwin = value >> 8; break; @@ -985,11 +1011,43 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, default: break; } - return value; } void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + if (glRenderer->firstAffine < 0) { + memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + glRenderer->firstAffine = y; + } + } else { + glRenderer->firstAffine = -1; + } + + if (glRenderer->paletteDirty || glRenderer->vramDirty || glRenderer->oamDirty || glRenderer->regsDirty) { + if (glRenderer->firstY >= 0) { + _drawScanlines(glRenderer, y - 1); + } + } + if (glRenderer->firstY < 0) { + glRenderer->firstY = y; + } + + int i; + for (i = 0; i < 0x30; ++i) { + if (!(glRenderer->regsDirty & (1ULL << i))) { + continue; + } + _cleanRegister(glRenderer, i << 1, glRenderer->shadowRegs[i]); + } + glRenderer->regsDirty = 0; + if (glRenderer->paletteDirty) { glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); #ifdef BUILD_GLES3 @@ -999,7 +1057,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { #endif glRenderer->paletteDirty = false; } - int i; + int first = -1; glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); for (i = 0; i < 25; ++i) { @@ -1014,6 +1072,11 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->vramDirty = 0; + if (glRenderer->oamDirty) { + glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); + glRenderer->oamDirty = false; + } + if (y == 0) { memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); @@ -1030,11 +1093,32 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClear(GL_COLOR_BUFFER_BIT); } } + + if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { + memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[2], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[1], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[1], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); + + glRenderer->bg[2].affine[0].sx += glRenderer->bg[2].affine[0].dmx; + glRenderer->bg[2].affine[0].sy += glRenderer->bg[2].affine[0].dmy; + glRenderer->bg[3].affine[0].sx += glRenderer->bg[3].affine[0].dmx; + glRenderer->bg[3].affine[0].sy += glRenderer->bg[3].affine[0].dmy; + glRenderer->regsDirty |= 1ULL << 0x30; + } + + memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); + memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); +} + +void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { glEnable(GL_SCISSOR_TEST); uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->d.palette[0]); glViewport(0, 0, 1, GBA_VIDEO_VERTICAL_PIXELS); - glScissor(0, y, 1, 1); + glScissor(0, glRenderer->firstY, 1, y - glRenderer->firstY + 1); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); @@ -1044,30 +1128,12 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glClear(GL_COLOR_BUFFER_BIT); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { - if (glRenderer->firstAffine < 0) { - memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - glRenderer->firstAffine = y; - } - } else { - glRenderer->firstAffine = -1; - } - GBAVideoGLRendererDrawWindow(glRenderer, y); if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { - if (glRenderer->oamDirty) { - glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); - glRenderer->oamDirty = false; - } int i; for (i = glRenderer->oamMax; i--;) { struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i]; - if ((y < sprite->y && (sprite->endY - 256 < 0 || y >= sprite->endY - 256)) || y >= sprite->endY) { + if ((y < sprite->y && (sprite->endY - 256 < 0 || glRenderer->firstY >= sprite->endY - 256)) || glRenderer->firstY >= sprite->endY) { continue; } @@ -1111,29 +1177,16 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { break; } } - - if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { - memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[2], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[1], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[1], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - - glRenderer->bg[2].affine[0].sx += glRenderer->bg[2].affine[0].dmx; - glRenderer->bg[2].affine[0].sy += glRenderer->bg[2].affine[0].dmy; - glRenderer->bg[3].affine[0].sx += glRenderer->bg[3].affine[0].dmx; - glRenderer->bg[3].affine[0].sy += glRenderer->bg[3].affine[0].dmy; - } - memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); - memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); + glRenderer->firstY = -1; } void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + _drawScanlines(glRenderer, GBA_VIDEO_VERTICAL_PIXELS - 1); _finalizeLayers(glRenderer); glBindVertexArray(0); glRenderer->firstAffine = -1; + glRenderer->firstY = -1; glRenderer->bg[2].affine[0].sx = glRenderer->bg[2].refx; glRenderer->bg[2].affine[0].sy = glRenderer->bg[2].refy; glRenderer->bg[3].affine[0].sx = glRenderer->bg[3].refx; @@ -1293,7 +1346,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } if (!GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesBIsVFlip(sprite->b)) { - spriteY = (y - height) + (y - spriteY) + 1; + spriteY = (renderer->firstY - height) + (renderer->firstY - spriteY) + 1; } int totalWidth = width; @@ -1307,14 +1360,14 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]); glViewport(x * renderer->scale, spriteY * renderer->scale, totalWidth * renderer->scale, totalHeight * renderer->scale); - glScissor(x * renderer->scale, y * renderer->scale, totalWidth * renderer->scale, renderer->scale); + glScissor(x * renderer->scale, renderer->firstY * renderer->scale, totalWidth * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); glUseProgram(shader->program); glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); - glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y - spriteY); + glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight); glUniform1i(uniforms[GBA_GL_OBJ_VRAM], 0); glUniform1i(uniforms[GBA_GL_OBJ_PALETTE], 1); @@ -1379,26 +1432,50 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa } void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { - int inY = y + background->y; - int yBase = inY & 0xFF; + int inY0 = renderer->firstY + background->y; + int yDiv = (((y + background->y) & ~0xFF) - background->y) & 0xFF; + int inY1 = yDiv + background->y; + int yBase0 = inY0 & 0xFF; + int yBase1 = inY1 & 0xFF; if (background->size == 2) { - yBase += inY & 0x100; + yBase0 += inY0 & 0x100; + yBase1 += inY1 & 0x100; } else if (background->size == 3) { - yBase += (inY & 0x100) << 1; + yBase0 += (inY0 & 0x100) << 1; + yBase1 += (inY1 & 0x100) << 1; } const struct GBAVideoGLShader* shader = &renderer->bgShader[background->multipalette ? 1 : 0]; const GLuint* uniforms = shader->uniforms; - glScissor(0, y * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale); glUseProgram(shader->program); glBindVertexArray(shader->vao); _prepareBackground(renderer, background, uniforms); - glUniform2i(uniforms[GBA_GL_VS_LOC], 1, y); glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); - glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase - y); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + if (yDiv > renderer->firstY) { + int end = yDiv - 1; + if (end > y) { + end = y; + } + glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, (end - renderer->firstY + 1) * renderer->scale); + glUniform2i(uniforms[GBA_GL_VS_LOC], end - renderer->firstY + 1, renderer->firstY); + glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase0 - renderer->firstY); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + if (y >= yDiv) { + int start = yDiv; + if (yDiv < renderer->firstY) { + start = renderer->firstY; + } + glScissor(0, start * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, (y - start + 1) * renderer->scale); + glUniform2i(uniforms[GBA_GL_VS_LOC], y - start + 1, start); + glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase1 - yDiv); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1529,7 +1606,7 @@ static void _scissorWindow(int start, int end, int y, int lines, int scale) { glClear(GL_COLOR_BUFFER_BIT); } -static void _scissorWindowN(struct GBAVideoWindowRegion* region, int y, int scale) { +static void _scissorWindowN(const struct GBAVideoWindowRegion* region, const struct GBAVideoWindowRegion* v, const struct GBAVideoWindowRegion* y, int scale) { int sdelta = region[0].start - region[1].start; int edelta = region[0].end - region[1].end; int maxDelta = 0; @@ -1543,14 +1620,22 @@ static void _scissorWindowN(struct GBAVideoWindowRegion* region, int y, int scal } else if (-edelta > maxDelta) { maxDelta = -edelta; } + int startY = y->start; + int endY = y->end; + if (startY < v->start) { + startY = v->start; + } + if (endY >= v->end) { + endY = v->end - 1; + } if (!(sdelta | edelta) || maxDelta >= GBA_VIDEO_VERTICAL_PIXELS / 2) { - _scissorWindow(region[0].start * scale, region[0].end * scale, y, scale, scale); + _scissorWindow(region[0].start * scale, region[0].end * scale, startY * scale, (endY - startY + 1) * scale, scale); } else { int i; - for (i = 0; i < scale; ++i) { + for (i = 0; i < scale * (endY - startY + 1); ++i) { int start = region[1].start * scale + sdelta * i; int end = region[1].end * scale + edelta * i; - _scissorWindow(start, end, y + i, 1, scale); + _scissorWindow(start, end, startY * scale + i, 1, scale); } } } @@ -1565,17 +1650,21 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { _clearWindow(dispcnt, renderer->bldb, renderer->bldy); - _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); + _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale, renderer->scale); } else { _clearWindow(renderer->winout & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y * renderer->scale, renderer->scale, renderer->scale); - if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && y < renderer->winN[1].v.end) { + _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale, renderer->scale); + struct GBAVideoWindowRegion yRegion = { + y, + renderer->firstY + }; + if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && renderer->firstY < renderer->winN[1].v.end) { _clearWindow(renderer->winN[1].control & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindowN(renderer->winN[1].h, y * renderer->scale, renderer->scale); + _scissorWindowN(renderer->winN[1].h, &renderer->winN[1].v, &yRegion, renderer->scale); } - if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && y < renderer->winN[0].v.end) { + if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && renderer->firstY < renderer->winN[0].v.end) { _clearWindow(renderer->winN[0].control & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindowN(renderer->winN[0].h, y * renderer->scale, renderer->scale); + _scissorWindowN(renderer->winN[0].h, &renderer->winN[0].v, &yRegion, renderer->scale); } } } From 5cc4c752e59bdedb40feb64b9818d3d5baac6cd8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 20:37:04 -0700 Subject: [PATCH 286/429] GBA Video: Batch affine modifications --- include/mgba/internal/gba/renderers/gl.h | 6 +- src/gba/renderers/gl.c | 326 +++++++++++------------ 2 files changed, 167 insertions(+), 165 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index e6f8db74c..264c506b4 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -62,7 +62,7 @@ struct GBAVideoGLBackground { int32_t refx; int32_t refy; - struct GBAVideoGLAffine affine[4]; + struct GBAVideoGLAffine affine; }; enum { @@ -79,6 +79,8 @@ enum { GBA_GL_TEX_BACKDROP_COLOR, GBA_GL_TEX_BACKDROP_FLAGS, GBA_GL_TEX_WINDOW, + GBA_GL_TEX_AFFINE_2, + GBA_GL_TEX_AFFINE_3, GBA_GL_TEX_MAX }; @@ -94,7 +96,6 @@ enum { GBA_GL_BG_OFFSET, GBA_GL_BG_INFLAGS, GBA_GL_BG_TRANSFORM, - GBA_GL_BG_RANGE, GBA_GL_BG_MOSAIC, GBA_GL_OBJ_VRAM = 2, @@ -130,6 +131,7 @@ struct GBAVideoGLRenderer { uint32_t* temporaryBuffer; struct GBAVideoGLBackground bg[4]; + struct GBAVideoGLAffine affine[2][GBA_VIDEO_VERTICAL_PIXELS]; int oamMax; bool oamDirty; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index ed4b5a28d..c710c2111 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -181,7 +181,6 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, - { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -193,6 +192,25 @@ static const char* const _interpolate = " 3 * x1m * x1m * x * arr[1] +" " 3 * x1m * x * x * arr[2] +" " x * x * x * arr[3];\n" + "}\n" + + "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]) {\n" + " mat[2] = texelFetch(transform, ivec2(0, y), 0).xz;\n" + " ivec4 splitOffset[4];\n" + " splitOffset[2] = texelFetch(transform, ivec2(1, y), 0);\n" + + " mat[0] = texelFetch(transform, ivec2(0, y - 2), 0).xz;\n" + " mat[1] = texelFetch(transform, ivec2(0, y - 1), 0).xz;\n" + " mat[3] = texelFetch(transform, ivec2(0, y + 1), 0).xz;\n" + + " splitOffset[0] = texelFetch(transform, ivec2(1, y - 2), 0);\n" + " splitOffset[1] = texelFetch(transform, ivec2(1, y - 1), 0);\n" + " splitOffset[3] = texelFetch(transform, ivec2(1, y + 1), 0);\n" + + " aff[0] = (splitOffset[0].xz & 0xFFFF) + (splitOffset[0].yw << 16);\n" + " aff[1] = (splitOffset[1].xz & 0xFFFF) + (splitOffset[1].yw << 16);\n" + " aff[2] = (splitOffset[2].xz & 0xFFFF) + (splitOffset[2].yw << 16);\n" + " aff[3] = (splitOffset[3].xz & 0xFFFF) + (splitOffset[3].yw << 16);\n" "}\n"; static const char* const _renderMode2 = @@ -203,9 +221,7 @@ static const char* const _renderMode2 = "uniform int charBase;\n" "uniform int size;\n" "uniform ivec4 inflags;\n" - "uniform ivec2[4] offset;\n" - "uniform ivec2[4] transform;\n" - "uniform vec2 range;\n" + "uniform isampler2D transform;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -215,6 +231,7 @@ static const char* const _renderMode2 = "vec4 fetchTile(ivec2 coord);\n" "vec2 interpolate(ivec2 arr[4], float x);\n" + "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" "vec4 renderTile(ivec2 coord) {\n" " int map = (coord.x >> 11) + (((coord.y >> 7) & 0x7F0) << size);\n" @@ -234,6 +251,9 @@ static const char* const _renderMode2 = "}\n" "void main() {\n" + " ivec2 mat[4];\n" + " ivec2 offset[4];\n" + " loadAffine(int(texCoord.y), mat, offset);\n" " vec2 coord = texCoord;\n" " if (mosaic.x > 1) {\n" " coord.x -= mod(coord.x, mosaic.x);\n" @@ -241,9 +261,9 @@ static const char* const _renderMode2 = " if (mosaic.y > 1) {\n" " coord.y -= mod(coord.y, mosaic.y);\n" " }\n" - " float y = coord.y - range.x;\n" - " float lin = 0.5 - y / range.y * 0.25;\n" - " vec2 mixedTransform = interpolate(transform, lin);\n" + " float y = fract(coord.y);\n" + " float lin = 0.5 + y * 0.25;\n" + " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " color = fetchTile(ivec2(mixedTransform * coord.x + mixedOffset));\n" " flags = inflags / flagCoeff;\n" @@ -258,7 +278,6 @@ static const struct GBAVideoGLUniform _uniformsMode35[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, - { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -269,9 +288,7 @@ static const char* const _renderMode35 = "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" - "uniform ivec2[4] offset;\n" - "uniform ivec2[4] transform;\n" - "uniform vec2 range;\n" + "uniform isampler2D transform;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -280,8 +297,12 @@ static const char* const _renderMode35 = "precision highp int;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" + "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" "void main() {\n" + " ivec2 mat[4];\n" + " ivec2 offset[4];\n" + " loadAffine(int(texCoord.y), mat, offset);\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" " incoord.x -= mod(incoord.x, mosaic.x);\n" @@ -289,9 +310,9 @@ static const char* const _renderMode35 = " if (mosaic.y > 1) {\n" " incoord.y -= mod(incoord.y, mosaic.y);\n" " }\n" - " float y = incoord.y - range.x;\n" - " float lin = 0.5 - y / range.y * 0.25;\n" - " vec2 mixedTransform = interpolate(transform, lin);\n" + " float y = fract(incoord.y);\n" + " float lin = 0.5 + y * 0.25;\n" + " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" @@ -317,7 +338,6 @@ static const struct GBAVideoGLUniform _uniformsMode4[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, - { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -329,9 +349,7 @@ static const char* const _renderMode4 = "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" - "uniform ivec2[4] offset;\n" - "uniform ivec2[4] transform;\n" - "uniform vec2 range;\n" + "uniform isampler2D transform;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -340,8 +358,12 @@ static const char* const _renderMode4 = "precision highp int;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" + "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" "void main() {\n" + " ivec2 mat[4];\n" + " ivec2 offset[4];\n" + " loadAffine(int(texCoord.y), mat, offset);\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" " incoord.x -= mod(incoord.x, mosaic.x);\n" @@ -349,9 +371,9 @@ static const char* const _renderMode4 = " if (mosaic.y > 1) {\n" " incoord.y -= mod(incoord.y, mosaic.y);\n" " }\n" - " float y = incoord.y - range.x;\n" - " float lin = 0.5 - y / range.y * 0.25;\n" - " vec2 mixedTransform = interpolate(transform, lin);\n" + " float y = fract(incoord.y);\n" + " float lin = 0.5 + y * 0.25;\n" + " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" " if (coord.x < 0 || coord.x >= (size.x << 8)) {\n" @@ -615,6 +637,19 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_2]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, NULL); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, NULL); + glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); @@ -654,12 +689,12 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { bg->y = 0; bg->refx = 0; bg->refy = 0; - bg->affine[0].dx = 256; - bg->affine[0].dmx = 0; - bg->affine[0].dy = 0; - bg->affine[0].dmy = 256; - bg->affine[0].sx = 0; - bg->affine[0].sy = 0; + bg->affine.dx = 256; + bg->affine.dmx = 0; + bg->affine.dy = 0; + bg->affine.dmy = 256; + bg->affine.sx = 0; + bg->affine.sy = 0; glGenFramebuffers(1, &bg->fbo); glGenTextures(1, &bg->tex); glGenTextures(1, &bg->flags); @@ -796,7 +831,7 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, GBAVideoCacheWriteVideoRegister(renderer->cache, address, value); } - glRenderer->regsDirty |= 1ULL << (address >> 1); + bool dirty = true; switch (address) { case REG_DISPCNT: value &= 0xFFF7; @@ -815,6 +850,70 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, case REG_BG3VOFS: value &= 0x01FF; break; + case REG_BG2PA: + glRenderer->bg[2].affine.dx = value; + dirty = false; + break; + case REG_BG2PB: + glRenderer->bg[2].affine.dmx = value; + dirty = false; + break; + case REG_BG2PC: + glRenderer->bg[2].affine.dy = value; + dirty = false; + break; + case REG_BG2PD: + glRenderer->bg[2].affine.dmy = value; + dirty = false; + break; + case REG_BG2X_LO: + GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value); + dirty = false; + break; + case REG_BG2X_HI: + GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[2], value); + dirty = false; + break; + case REG_BG2Y_LO: + GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[2], value); + dirty = false; + break; + case REG_BG2Y_HI: + GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value); + dirty = false; + break; + case REG_BG3PA: + glRenderer->bg[3].affine.dx = value; + dirty = false; + break; + case REG_BG3PB: + glRenderer->bg[3].affine.dmx = value; + dirty = false; + break; + case REG_BG3PC: + glRenderer->bg[3].affine.dy = value; + dirty = false; + break; + case REG_BG3PD: + glRenderer->bg[3].affine.dmy = value; + dirty = false; + break; + case REG_BG3X_LO: + GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value); + dirty = false; + break; + case REG_BG3X_HI: + GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[3], value); + dirty = false; + break; + case REG_BG3Y_LO: + GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[3], value); + dirty = false; + break; + case REG_BG3Y_HI: + GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[3], value); + dirty = false; + break; case REG_BLDALPHA: value &= 0x1F1F; break; @@ -833,7 +932,14 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, default: break; } - glRenderer->shadowRegs[address >> 1] = value; + if (glRenderer->shadowRegs[address >> 1] == value) { + dirty = false; + } else { + glRenderer->shadowRegs[address >> 1] = value; + } + if (dirty) { + glRenderer->regsDirty |= 1ULL << (address >> 1); + } return value; } @@ -879,54 +985,6 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t case REG_BG3VOFS: glRenderer->bg[3].y = value; break; - case REG_BG2PA: - glRenderer->bg[2].affine[0].dx = value; - break; - case REG_BG2PB: - glRenderer->bg[2].affine[0].dmx = value; - break; - case REG_BG2PC: - glRenderer->bg[2].affine[0].dy = value; - break; - case REG_BG2PD: - glRenderer->bg[2].affine[0].dmy = value; - break; - case REG_BG2X_LO: - GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value); - break; - case REG_BG2X_HI: - GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[2], value); - break; - case REG_BG2Y_LO: - GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[2], value); - break; - case REG_BG2Y_HI: - GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value); - break; - case REG_BG3PA: - glRenderer->bg[3].affine[0].dx = value; - break; - case REG_BG3PB: - glRenderer->bg[3].affine[0].dmx = value; - break; - case REG_BG3PC: - glRenderer->bg[3].affine[0].dy = value; - break; - case REG_BG3PD: - glRenderer->bg[3].affine[0].dmy = value; - break; - case REG_BG3X_LO: - GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value); - break; - case REG_BG3X_HI: - GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[3], value); - break; - case REG_BG3Y_LO: - GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[3], value); - break; - case REG_BG3Y_HI: - GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[3], value); - break; case REG_BLDCNT: GBAVideoGLRendererWriteBLDCNT(glRenderer, value); value &= 0x3FFF; @@ -1016,14 +1074,10 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; + memcpy(&glRenderer->affine[0][y], &glRenderer->bg[2].affine, sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->affine[1][y], &glRenderer->bg[3].affine, sizeof(struct GBAVideoGLAffine)); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { if (glRenderer->firstAffine < 0) { - memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); glRenderer->firstAffine = y; } } else { @@ -1039,6 +1093,9 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstY = y; } + memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); + memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); + int i; for (i = 0; i < 0x30; ++i) { if (!(glRenderer->regsDirty & (1ULL << i))) { @@ -1095,25 +1152,20 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { - memcpy(&glRenderer->bg[2].affine[3], &glRenderer->bg[2].affine[2], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[3], &glRenderer->bg[3].affine[2], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[2], &glRenderer->bg[2].affine[1], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[2], &glRenderer->bg[3].affine[1], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[2].affine[1], &glRenderer->bg[2].affine[0], sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->bg[3].affine[1], &glRenderer->bg[3].affine[0], sizeof(struct GBAVideoGLAffine)); - - glRenderer->bg[2].affine[0].sx += glRenderer->bg[2].affine[0].dmx; - glRenderer->bg[2].affine[0].sy += glRenderer->bg[2].affine[0].dmy; - glRenderer->bg[3].affine[0].sx += glRenderer->bg[3].affine[0].dmx; - glRenderer->bg[3].affine[0].sy += glRenderer->bg[3].affine[0].dmy; - glRenderer->regsDirty |= 1ULL << 0x30; + glRenderer->bg[2].affine.sx += glRenderer->bg[2].affine.dmx; + glRenderer->bg[2].affine.sy += glRenderer->bg[2].affine.dmy; + glRenderer->bg[3].affine.sx += glRenderer->bg[3].affine.dmx; + glRenderer->bg[3].affine.sy += glRenderer->bg[3].affine.dmy; } - - memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); - memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); } void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { + if (glRenderer->firstAffine >= 0) { + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, glRenderer->affine[0]); + glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_3]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, glRenderer->affine[1]); + } glEnable(GL_SCISSOR_TEST); uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->d.palette[0]); @@ -1187,10 +1239,10 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { glBindVertexArray(0); glRenderer->firstAffine = -1; glRenderer->firstY = -1; - glRenderer->bg[2].affine[0].sx = glRenderer->bg[2].refx; - glRenderer->bg[2].affine[0].sy = glRenderer->bg[2].refy; - glRenderer->bg[3].affine[0].sx = glRenderer->bg[3].refx; - glRenderer->bg[3].affine[0].sy = glRenderer->bg[3].refy; + glRenderer->bg[2].affine.sx = glRenderer->bg[2].refx; + glRenderer->bg[2].affine.sy = glRenderer->bg[2].refy; + glRenderer->bg[3].affine.sx = glRenderer->bg[3].refx; + glRenderer->bg[3].affine.sy = glRenderer->bg[3].refy; } void GBAVideoGLRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { @@ -1245,26 +1297,26 @@ static void GBAVideoGLRendererWriteBGCNT(struct GBAVideoGLBackground* bg, uint16 static void GBAVideoGLRendererWriteBGX_LO(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refx = (bg->refx & 0xFFFF0000) | value; - bg->affine[0].sx = bg->refx; + bg->affine.sx = bg->refx; } static void GBAVideoGLRendererWriteBGX_HI(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refx = (bg->refx & 0x0000FFFF) | (value << 16); bg->refx <<= 4; bg->refx >>= 4; - bg->affine[0].sx = bg->refx; + bg->affine.sx = bg->refx; } static void GBAVideoGLRendererWriteBGY_LO(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refy = (bg->refy & 0xFFFF0000) | value; - bg->affine[0].sy = bg->refy; + bg->affine.sy = bg->refy; } static void GBAVideoGLRendererWriteBGY_HI(struct GBAVideoGLBackground* bg, uint16_t value) { bg->refy = (bg->refy & 0x0000FFFF) | (value << 16); bg->refy <<= 4; bg->refy >>= 4; - bg->affine[0].sy = bg->refy; + bg->affine.sy = bg->refy; } static void GBAVideoGLRendererWriteBLDCNT(struct GBAVideoGLRenderer* renderer, uint16_t value) { @@ -1480,64 +1532,12 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, } void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms, int y) { - int reverse = 0; - int forward = 1; - if (renderer->scale > 1) { - switch (y - renderer->firstAffine) { - case 0: - case 1: - case 2: - case 3: - return; - case 4: - forward = 2; - reverse = 4; - break; - case 5: - forward = 2; - reverse = 3; - break; - case 6: - forward = 2; - reverse = 2; - break; - case 7: - forward = 2; - reverse = 1; - break; - } - } + glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * (y - renderer->firstY + 1)); + glUniform2i(uniforms[GBA_GL_VS_LOC], y - renderer->firstY + 1, renderer->firstY); - glScissor(0, (y - reverse) * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * forward); - glUniform2i(uniforms[GBA_GL_VS_LOC], forward, y - reverse); - glUniform2f(uniforms[GBA_GL_BG_RANGE], y - 1, 1); - if (renderer->scale > 1) { - glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { - background->affine[0].sx, background->affine[0].sy, - background->affine[1].sx, background->affine[1].sy, - background->affine[2].sx, background->affine[2].sy, - background->affine[3].sx, background->affine[3].sy, - }); - glUniform2iv(uniforms[GBA_GL_BG_TRANSFORM], 4, (GLint[]) { - background->affine[0].dx, background->affine[0].dy, - background->affine[1].dx, background->affine[1].dy, - background->affine[2].dx, background->affine[2].dy, - background->affine[3].dx, background->affine[3].dy, - }); - } else { - glUniform2iv(uniforms[GBA_GL_BG_OFFSET], 4, (GLint[]) { - background->affine[0].sx, background->affine[0].sy, - background->affine[0].sx, background->affine[0].sy, - background->affine[0].sx, background->affine[0].sy, - background->affine[0].sx, background->affine[0].sy, - }); - glUniform2iv(uniforms[GBA_GL_BG_TRANSFORM], 4, (GLint[]) { - background->affine[0].dx, background->affine[0].dy, - background->affine[0].dx, background->affine[0].dy, - background->affine[0].dx, background->affine[0].dy, - background->affine[0].dx, background->affine[0].dy, - }); - } + glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_AFFINE_2 + background->index - 2]); + glUniform1i(uniforms[GBA_GL_BG_TRANSFORM], 2); _prepareBackground(renderer, background, uniforms); } From d4c6472101237c51dbc547b6843a5c589f294ed4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 20:38:01 -0700 Subject: [PATCH 287/429] Qt: Fix doneCurrent location --- src/platform/qt/DisplayGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 77439874a..54b6bc59c 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -264,8 +264,8 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent if (!painter->m_gl->isValid()) { return; } - painter->m_gl->doneCurrent(); painter->m_gl->swapBuffers(painter->m_surface); + painter->m_gl->doneCurrent(); painter->m_gl->makeCurrent(painter->m_surface); #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); From 75c212b23cf6a15a0cf4da5aa3ea4e186fabcb95 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 22 May 2019 21:15:23 -0700 Subject: [PATCH 288/429] GBA Video: Extrapolate edges in affine --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 69 ++++++++++++++++++++---- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 264c506b4..cf53c6566 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -96,6 +96,7 @@ enum { GBA_GL_BG_OFFSET, GBA_GL_BG_INFLAGS, GBA_GL_BG_TRANSFORM, + GBA_GL_BG_RANGE, GBA_GL_BG_MOSAIC, GBA_GL_OBJ_VRAM = 2, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c710c2111..4fb3740a9 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -181,6 +181,7 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -195,22 +196,62 @@ static const char* const _interpolate = "}\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]) {\n" - " mat[2] = texelFetch(transform, ivec2(0, y), 0).xz;\n" + " int start = max(range.x, y - 3);\n" " ivec4 splitOffset[4];\n" - " splitOffset[2] = texelFetch(transform, ivec2(1, y), 0);\n" - " mat[0] = texelFetch(transform, ivec2(0, y - 2), 0).xz;\n" - " mat[1] = texelFetch(transform, ivec2(0, y - 1), 0).xz;\n" - " mat[3] = texelFetch(transform, ivec2(0, y + 1), 0).xz;\n" + " mat[0] = texelFetch(transform, ivec2(0, start), 0).xz;\n" + " mat[1] = texelFetch(transform, ivec2(0, start + 1), 0).xz;\n" + " mat[2] = texelFetch(transform, ivec2(0, start + 2), 0).xz;\n" + " mat[3] = texelFetch(transform, ivec2(0, start + 3), 0).xz;\n" - " splitOffset[0] = texelFetch(transform, ivec2(1, y - 2), 0);\n" - " splitOffset[1] = texelFetch(transform, ivec2(1, y - 1), 0);\n" - " splitOffset[3] = texelFetch(transform, ivec2(1, y + 1), 0);\n" + " splitOffset[0] = texelFetch(transform, ivec2(1, start + 0), 0);\n" + " splitOffset[1] = texelFetch(transform, ivec2(1, start + 1), 0);\n" + " splitOffset[2] = texelFetch(transform, ivec2(1, start + 2), 0);\n" + " splitOffset[3] = texelFetch(transform, ivec2(1, start + 3), 0);\n" " aff[0] = (splitOffset[0].xz & 0xFFFF) + (splitOffset[0].yw << 16);\n" " aff[1] = (splitOffset[1].xz & 0xFFFF) + (splitOffset[1].yw << 16);\n" " aff[2] = (splitOffset[2].xz & 0xFFFF) + (splitOffset[2].yw << 16);\n" " aff[3] = (splitOffset[3].xz & 0xFFFF) + (splitOffset[3].yw << 16);\n" + + " if (y - 3 < range.x) {\n" + " ivec2 tempMat[3];\n" + " ivec2 tempAff[3];\n" + " tempMat[0] = ivec2(interpolate(mat, -0.75));\n" + " tempMat[1] = ivec2(interpolate(mat, -0.5));\n" + " tempMat[2] = ivec2(interpolate(mat, -0.25));\n" + " tempAff[0] = ivec2(interpolate(aff, -0.75));\n" + " tempAff[1] = ivec2(interpolate(aff, -0.5));\n" + " tempAff[2] = ivec2(interpolate(aff, -0.25));\n" + " if (range.x == y) {\n" + " mat[3] = mat[0];\n" + " mat[2] = tempMat[2];\n" + " mat[1] = tempMat[1];\n" + " mat[0] = tempMat[0];\n" + " aff[3] = aff[0];\n" + " aff[2] = tempAff[2];\n" + " aff[1] = tempAff[1];\n" + " aff[0] = tempAff[0];\n" + " } else if (range.x == y - 1) {\n" + " mat[3] = mat[1];\n" + " mat[2] = mat[0];\n" + " mat[1] = tempMat[2];\n" + " mat[0] = tempMat[1];\n" + " aff[3] = aff[1];\n" + " aff[2] = aff[0];\n" + " aff[1] = tempAff[2];\n" + " aff[0] = tempAff[1];\n" + " } else if (range.x == y - 2) {\n" + " mat[3] = mat[2];\n" + " mat[2] = mat[1];\n" + " mat[1] = mat[0];\n" + " mat[0] = tempMat[0];\n" + " aff[3] = aff[2];\n" + " aff[2] = aff[1];\n" + " aff[1] = aff[0];\n" + " aff[0] = tempAff[0];\n" + " }\n" + " }\n" "}\n"; static const char* const _renderMode2 = @@ -222,6 +263,7 @@ static const char* const _renderMode2 = "uniform int size;\n" "uniform ivec4 inflags;\n" "uniform isampler2D transform;\n" + "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -262,7 +304,7 @@ static const char* const _renderMode2 = " coord.y -= mod(coord.y, mosaic.y);\n" " }\n" " float y = fract(coord.y);\n" - " float lin = 0.5 + y * 0.25;\n" + " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " color = fetchTile(ivec2(mixedTransform * coord.x + mixedOffset));\n" @@ -278,6 +320,7 @@ static const struct GBAVideoGLUniform _uniformsMode35[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -289,6 +332,7 @@ static const char* const _renderMode35 = "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" "uniform isampler2D transform;\n" + "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -311,7 +355,7 @@ static const char* const _renderMode35 = " incoord.y -= mod(incoord.y, mosaic.y);\n" " }\n" " float y = fract(incoord.y);\n" - " float lin = 0.5 + y * 0.25;\n" + " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" @@ -338,6 +382,7 @@ static const struct GBAVideoGLUniform _uniformsMode4[] = { { "inflags", GBA_GL_BG_INFLAGS, }, { "offset", GBA_GL_BG_OFFSET, }, { "transform", GBA_GL_BG_TRANSFORM, }, + { "range", GBA_GL_BG_RANGE, }, { "mosaic", GBA_GL_BG_MOSAIC, }, { 0 } }; @@ -350,6 +395,7 @@ static const char* const _renderMode4 = "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" "uniform isampler2D transform;\n" + "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "out vec4 color;\n" "out vec4 flags;\n" @@ -372,7 +418,7 @@ static const char* const _renderMode4 = " incoord.y -= mod(incoord.y, mosaic.y);\n" " }\n" " float y = fract(incoord.y);\n" - " float lin = 0.5 + y * 0.25;\n" + " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" @@ -1534,6 +1580,7 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, const GLuint* uniforms, int y) { glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * (y - renderer->firstY + 1)); glUniform2i(uniforms[GBA_GL_VS_LOC], y - renderer->firstY + 1, renderer->firstY); + glUniform2i(uniforms[GBA_GL_BG_RANGE], renderer->firstAffine, y); glActiveTexture(GL_TEXTURE0 + 2); glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_AFFINE_2 + background->index - 2]); From 5b040e236db0dd39e2e29ad7724b9712ac84c57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20Doncam=20Demian=20L=C3=B3pez=20Brante?= Date: Wed, 22 May 2019 21:18:22 -0400 Subject: [PATCH 289/429] Qt: Updated Spanish translation --- src/platform/qt/ts/mgba-es.ts | 1111 +++++++++++++++++++++------------ 1 file changed, 712 insertions(+), 399 deletions(-) diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es.ts index cae9fd4f7..2e950a8df 100644 --- a/src/platform/qt/ts/mgba-es.ts +++ b/src/platform/qt/ts/mgba-es.ts @@ -30,9 +30,15 @@ + © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + © 2013 – 2019 Jeffrey Pfau, licenciado bajo la Mozilla Public License, versión 2.0 +Game Boy Advance es una marca registrada de Nintendo Co., Ltd. + + © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. - © 2013 – 2018 Jeffrey Pfau, licenciado bajo la Mozilla Public License, versión 2.0 + © 2013 – 2018 Jeffrey Pfau, licenciado bajo la Mozilla Public License, versión 2.0 Game Boy Advance es una marca registrada de Nintendo Co., Ltd. @@ -125,6 +131,84 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. 0x00 (00) + + BattleChipView + + + BattleChip Gate + BattleChip Gate + + + + Chip name + Nombre del chip + + + + Insert + Insertar + + + + Save + Guardar + + + + Load + Cargar + + + + Add + Agregar + + + + Remove + Quitar + + + + Gate type + Tipo de Gate + + + + Ba&ttleChip Gate + Ba&ttleChip Gate + + + + Progress &Gate + Progress &Gate + + + + Beast &Link Gate + Beast &Link Gate + + + + Inserted + Insertado + + + + Chip ID + ID de chip + + + + Update Chip data + Actualizar datos del chip + + + + Show advanced + Mostrar ajustes avanzados + + CheatsView @@ -201,12 +285,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Frameskip - Salto de cuadros + Salto Frame delay (ms) - Retraso entre cuadros (ms) + Retraso (ms) @@ -219,7 +303,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. I/O Viewer - Visor de I/O + Visor de E/S @@ -417,7 +501,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Debug - Depuración (Debug) + Debug @@ -427,12 +511,12 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Info - Información (Info) + Info Warning - Advertencia (Warning) + Warning @@ -457,7 +541,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Max Lines - Máximo de líneas + Líneas max. @@ -631,57 +715,69 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Alinear a: - 1 Byte - 1 byte + 1 byte + + + 2 Bytes + 2 bytes + + + 4 Bytes + 4 bytes + + + + &1 Byte + - 2 Bytes - 2 bytes + &2 Bytes + - 4 Bytes - 4 bytes + &4 Bytes + - + Unsigned Integer: Entero sin signo: - + Signed Integer: Entero con signo: - + String: - Cadena: + Cadena de texto: - + Load TBL Cargar TBL - + Copy Selection Copiar selección - + Paste Pegar - + Save Selection Guardar selección - + Load Cargar @@ -717,7 +813,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Transform - Transformación + Transform @@ -936,7 +1032,7 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Super Game Boy (SGB) - + Super Game Boy (SGB) @@ -1203,6 +1299,35 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. No se puede iniciar un procesador de audio sin entrada + + QGBA::BattleChipView + + + BattleChip data missing + Datos del BattleChip no encontrados + + + + BattleChip data is missing. BattleChip Gates will still work, but some graphics will be missing. Would you like to download the data now? + Faltan los datos de BattleChip. Las BattleChip Gates seguirán funcionando, pero faltarán algunos gráficos. ¿Quieres descargar los datos ahora? + + + + + Select deck file + Elegir archivo de baraja + + + + Incompatible deck + Baraja incompatible + + + + The selected deck is not compatible with this Chip Gate + La baraja seleccionada no es compatible con esta Chip Gate + + QGBA::CheatsModel @@ -1249,22 +1374,22 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Error al abrir el archivo de guardado: %1 - + Failed to open game file: %1 Error al abrir el archivo del juego: %1 - + Failed to open snapshot file for reading: %1 Error al leer del archivo de captura: %1 - + Failed to open snapshot file for writing: %1 Error al escribir al archivo de captura: %1 @@ -1277,12 +1402,20 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Error al abrir el archivo del juego: %1 + + QGBA::GBAApp + + + Enable Discord Rich Presence + Habilitar Rich Presence en Discord + + QGBA::GBAKeyEditor Clear Button - Limpiar botón + Limpiar botones @@ -2789,40 +2922,94 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Espacio %1 + + QGBA::LogConfigModel + + + + Default + Por defecto + + + + Fatal + Fatal + + + + Error + Error + + + + Warning + Advertencia (Warning) + + + + Info + Información (Info) + + + + Debug + Depuración (Debug) + + + + Stub + Stub + + + + Game Error + Error de juego + + QGBA::LogController - + + [%1] %2: %3 + [%1] %2: %3 + + + + An error occurred + Ocurrió un error + + + DEBUG DEPURACIÓN - + STUB STUB - + INFO INFORMACIÓN - + WARN ADVERTENCIA - + ERROR ERROR - + FATAL FATAL - + GAME ERROR ERROR DE JUEGO @@ -2830,47 +3017,47 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::MapView - + Map Addr. Dir de mapa - + Mirror Espejar - + None Ninguno - + Both Ambos - + Horizontal Horizontal - + Vertical Vertical - + Export map Exportar mapa - + Portable Network Graphics (*.png) Gráficos de red portátiles (*.png) - + Failed to open output PNG file: %1 Error al abrir el archivo PNG de salida: %1 @@ -2976,54 +3163,54 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 0x%0 - + Off No - + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Inválido - - + + N/A n/d - + Export sprite Exportar sprite - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 Error al abrir el archivo PNG de salida: %1 @@ -3107,59 +3294,59 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (forzar versión 1.x) - + None (Still Image) Nada (imagen estática) - + Keyboard Teclado - + Controllers Controladores - + Shortcuts Atajos de teclado - - + + Shaders Shaders - + Select BIOS Seleccionar BIOS @@ -3200,17 +3387,32 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::ShortcutController - + Action + Acción + + + Keyboard + Teclado + + + Gamepad + Mando + + + + QGBA::ShortcutModel + + Action Acción - + Keyboard Teclado - + Gamepad Mando @@ -3236,108 +3438,108 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) ROMs de Game Boy Advance (%1) - + Game Boy ROMs (%1) ROMs de Game Boy (%1) - + All ROMs (%1) Todas las ROMs (%1) - + %1 Video Logs (*.mvl) Video-registros de %1 (*.mvl) - + Archives (%1) Contenedores (%1) - - - + + + Select ROM Seleccionar ROM - + Select folder Seleccionar carpeta - + Game Boy Advance save files (%1) Archivos de guardado de Game Boy Advance (%1) - - - + + + Select save Seleccionar guardado - + mGBA savestate files (%1) Archivos de estado de guardado de mGBA (%1) - - + + Select savestate Elegir estado de guardado - + Select patch Seleccionar parche - + Patches (*.ips *.ups *.bps) Parches (*.ips *.ups *.bps) - + Select image Seleccionar imagen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Archivo de imagen (*.png *.gif *.jpg *.jpeg);;Todos los archivos (*) - - + + GameShark saves (*.sps *.xps) Guardados de GameShark (*.sps *.xps) - + Select video log Seleccionar video-registro - + Video logs (*.mvl) Video-registros (*.mvl) - + Crash Error fatal - + The game has crashed with the following error: %1 @@ -3346,433 +3548,424 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. %1 - + Couldn't Load No se pudo cargar - + Could not load game. Are you sure it's in the correct format? No se pudo cargar el juego. ¿Estás seguro de que está en el formato correcto? - + Unimplemented BIOS call Llamada a BIOS no implementada - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Este juego utiliza una llamada al BIOS que no se ha implementado. Utiliza el BIOS oficial para obtener la mejor experiencia. - + Really make portable? ¿Hacer "portable"? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Esto hará que el emulador cargue su configuración desde el mismo directorio que el ejecutable. ¿Quieres continuar? - + Restart needed Reinicio necesario - + Some changes will not take effect until the emulator is restarted. Algunos cambios no surtirán efecto hasta que se reinicie el emulador. - + - Player %1 of %2 - Jugador %1 de %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 fps) - %4 - + &File &Archivo - + Load &ROM... Cargar &ROM... - + Load ROM in archive... Cargar ROM desde contenedor... - + Add folder to library... Agregar carpeta a la biblioteca... - + Load alternate save... Cargar guardado alternativo... - + Load temporary save... Cargar guardado temporal... - + Load &patch... Cargar &parche... - + Boot BIOS Arrancar BIOS - + Replace ROM... Reemplazar ROM... - + ROM &info... &Información de la ROM... - + Recent Recientes - + Make portable Hacer "portable" - + &Load state Ca&rgar estado - - F10 - F10 + + About... + Acerca de... - + F10 + F10 + + + Load state file... Cargar archivo de estado... - + &Save state Guardar e&stado - Shift+F10 - Shift+F10 + Shift+F10 - + Save state file... Guardar archivo de estado... - + Quick load Cargado rápido - + Quick save Guardado rápido - + Load recent Cargar reciente - + Save recent Guardar reciente - + Undo load state Deshacer cargar estado - F11 - F11 + F11 - + Undo save state Deshacer guardar estado - Shift+F11 - Shift+F11 + Shift+F11 - - + + State &%1 Estado &%1 - F%1 - F%1 + F%1 + + + Shift+F%1 + Shift+F%1 - Shift+F%1 - Shift+F%1 - - - Load camera image... Cargar imagen para la cámara... - + Import GameShark Save Importar guardado de GameShark - + Export GameShark Save Exportar guardado de GameShark - + New multiplayer window Nueva ventana multijugador - About - Acerca de + Acerca de - + E&xit Salir (&X) - + &Emulation &Emulación - + &Reset &Reinicializar - Ctrl+R - Ctrl+R + Ctrl+R - + Sh&utdown Apagar (&U) - + Yank game pak Tirar del cartucho - + &Pause &Pausar - Ctrl+P - Ctrl+P + Ctrl+P - + &Next frame Cuadro siguie&nte - Ctrl+N - Ctrl+N + Ctrl+N - + Fast forward (held) Avance rápido (mantener) - + &Fast forward &Avance rápido - Shift+Tab - Shift+Tab + Shift+Tab - + Fast forward speed Velocidad de avance rápido - + Unbounded Sin límite - + %0x %0x - + Rewind (held) Rebobinar (mantener) - + Re&wind Re&bobinar - ~ - ~ + ~ - + Step backwards Paso hacia atrás - Ctrl+B - Ctrl+B + Ctrl+B - + Sync to &video Sincronizar a &video - + Sync to &audio Sincronizar a au&dio - + Solar sensor Sensor solar - + Increase solar level Subir nivel - + Decrease solar level Bajar nivel - + Brightest solar level Más claro - + Darkest solar level Más oscuro - + Brightness %1 Brillo %1 - + Audio/&Video Audio/&video - + Frame size Tamaño del cuadro - %1x - %1x + %1x - + Toggle fullscreen Pantalla completa - + Lock aspect ratio Bloquear proporción de aspecto - + Force integer scaling Forzar escala a enteros - + Bilinear filtering Filtro bilineal - + Frame&skip &Salto de cuadros - + Mute Silenciar - + FPS target Objetivo de FPS - + Native (59.7275) Nativo (59,7275) @@ -3809,192 +4002,214 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. 240 - + Take &screenshot Tomar pan&tallazo - + F12 F12 - Record output... - Grabar salida... + Grabar salida... - + Record GIF... Grabar GIF... - Record video log... - Grabar video-registro... + Grabar video-registro... - Stop video log - Detener video-registro + Detener video-registro - + Game Boy Printer... Game Boy Printer... - + + BattleChip Gate... + BattleChip Gate... + + + + %1× + %1× + + + + Record A/V... + Grabar A/V... + + + Video layers Capas de video - + Audio channels Canales de audio - + Adjust layer placement... Ajustar ubicación de capas... - + &Tools Herramien&tas - + View &logs... Ver re&gistros... - + Game &overrides... Ajustes específic&os por juego... - + Game &Pak sensors... Sensores del Game &Pak... - + &Cheats... Tru&cos... - + Settings... Ajustes... - + Open debugger console... Abrir consola de depuración... - + Start &GDB server... Iniciar servidor &GDB... - + View &palette... Ver &paleta... - + View &sprites... Ver &sprites... - + View &tiles... Ver &tiles... - + View &map... Ver &mapa... - + View memory... Ver memoria... - + Search memory... Buscar memoria... - + View &I/O registers... Ver registros &I/O... - + + Record debug video log... + Grabar registro de depuración de video... + + + + Stop debug video log + Detener registro de depuración de video + + + Exit fullscreen Salir de pantalla completa - + GameShark Button (held) Botón GameShark (mantener) - + Autofire Disparo automático - + Autofire A Disparo automático A - + Autofire B Disparo automático B - + Autofire L Disparo automático L - + Autofire R Disparo automático R - + Autofire Start Disparo automático Start - + Autofire Select Disparo automático Select - + Autofire Up Disparo automático Arriba - + Autofire Right Disparo automático Derecha - + Autofire Down Disparo automático Abajo - + Autofire Left Disparo automático Izquierda @@ -4158,505 +4373,588 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Ajustes - + Audio/Video Audio/video - + Interface Interfaz - + Emulation Emulación - + + Enhancements + Mejoras + + + BIOS BIOS - + Paths Rutas - + + Logging + Registros + + + Game Boy Game Boy - + Audio driver: Sistema de audio: - + Audio buffer: Búfer de audio: - - + + 1536 1536 - + 512 512 - + 768 768 - + 1024 1024 - + 2048 2048 - + 3072 3072 - + 4096 4096 - + samples muestras - + Sample rate: Tasa de muestreo: - - + + 44100 44100 - + 22050 22050 - + 32000 32000 - + 48000 48000 - + Hz Hz - + Volume: Volumen: - - + + Mute Silenciar - + Fast forward volume: Vol. durante av. rápido: - + Display driver: Sistema de video: - + Frameskip: Salto de cuadros: - + Skip every Saltar cada - - + + frames cuadros - + FPS target: Objetivo de FPS: - + frames per second cuadros por segundo - + Sync: Sincronizar con: - + Video Video - + Audio Audio - + Lock aspect ratio Bloquear proporción de aspecto - + Bilinear filtering Filtro bilineal - - Force integer scaling - Forzar escalado de enteros + + Log to file + Guardar a archivo - + + Log to console + Guardar a consola + + + + Select Log File + Seleccionar + + + + Game Boy model: + Modelo de Game Boy: + + + + Super Game Boy model: + Modelo de Super Game Boy: + + + + Game Boy Color model: + Modelo de Game Boy Color: + + + + Use GBC colors in GB games + Usar colores de GBC en juegos GB + + + + Camera: + Cámara: + + + + Force integer scaling + Forzar escalado a valores enteros + + + Language Idioma - + English English - + Library: Biblioteca: - + List view Lista - + Tree view Árbol - + Show when no game open Mostrar cuando no haya un juego abierto - + Clear cache Limpiar caché - + Allow opposing input directions Permitir direcciones opuestas al mismo tiempo - + Suspend screensaver Suspender protector de pantalla - + Pause when inactive Pausar al no estar activo - + Show FPS in title bar Mostrar FPS en la barra de título - + Automatically save cheats Guardar trucos automáticamente - + Automatically load cheats Cargar trucos automáticamente - + Automatically save state Guardar estado automáticamente - + Automatically load state Cargar estado automáticamente - - Fast forward speed: - Velocidad de avance rápido: + + Enable Discord Rich Presence + Hablitar Rich Presence en Discord - + + Fast forward speed: + Avance rápido: + + + + × × - + Unbounded Sin límite - + Enable rewind Habilitar el rebobinar - + Rewind history: - Historial de rebobinado: + Hist. de rebobinado: - + Idle loops: Bucles inactivos: - + Run all Ejecutarlos todos - + Remove known Eliminar los conocidos - + Detect and remove Detectar y eliminar - + Savestate extra data: - Guardar datos extra con el estado: + Guardar datos extra: - - + + Screenshot Pantallazo - - + + Save data Datos de guardado - - + + Cheat codes Trucos - + Load extra data: - Cargar datos extra con el estado: + Cargar datos extra: Rewind affects save data El rebobinar afecta los datos de guardado - + Preload entire ROM into memory Cargar ROM completa a la memoria - + Autofire interval: - Intervalo de disparo automático: + Intervalo de turbo: - + + Video renderer: + Renderizador de video: + + + + Software + Software + + + + OpenGL + OpenGL + + + + OpenGL enhancements + Mejoras para OpenGL + + + + High-resolution scale: + Escala de alta resolución: + + + + XQ GBA audio (experimental) + Mejorar audio GBA (experimental) + + + GB BIOS file: Archivo BIOS GB: - - - - - - - - - + + + + + + + + + Browse Examinar - + Use BIOS file if found Usar archivo BIOS si fue encontrado - + Skip BIOS intro Saltar animación de entrada del BIOS - + GBA BIOS file: Archivo BIOS GBA: - + GBC BIOS file: Archivo BIOS GBC: - + SGB BIOS file: - SGB BIOS file: + Archivo BIOS SGB: - + Save games Datos de guardado - - - - - + + + + + Same directory as the ROM Al mismo directorio que la ROM - + Save states Estados de guardado - + Screenshots Pantallazos - + Patches Parches - + Cheats Trucos - Game Boy model - Modelo de Game Boy + Modelo de Game Boy - - - + + + Autodetect Detección automática - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - Super Game Boy model - Modelo de Super Game Boy + Modelo de Super Game Boy - Game Boy Color model - Modelo de Game Boy Color + Modelo de Game Boy Color - + Default BG colors: Colores de fondo por defecto: - + Super Game Boy borders Bordes de Super Game Boy - + Camera driver: Controlador de cámara: - + Default sprite colors 1: Colores de sprite 1 por defecto: - + Default sprite colors 2: Colores de sprite 2 por defecto: @@ -4730,20 +5028,30 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. Tiles - + 256 colors 256 colores - + × × - + Magnification Ampliación + + + Tiles per row + Tiles por fila + + + + Fit to window + Ajustar a ventana + VideoView @@ -4882,86 +5190,91 @@ Game Boy Advance es una marca registrada de Nintendo Co., Ltd. + HEVC (NVENC) + HEVC (NVENC) + + + VP8 VP8 - + VP9 VP9 - + FFV1 FFV1 - + FLAC FLAC - + Opus Opus - + Vorbis Vorbis - + MP3 MP3 - + AAC AAC - + Uncompressed Sin comprimir - + Bitrate (kbps) Tasa de bits (kbps) - + VBR VBR - + ABR ABR - + Dimensions Dimensiones - + : : - + × × - + Lock aspect ratio Bloquear proporción de aspecto - + Show advanced Mostrar ajustes avanzados From 13ffd13cdd841571b5c2c0547611b7a3ea4467e8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 00:04:26 -0700 Subject: [PATCH 290/429] Qt: Improve sync code --- CHANGES | 1 + src/platform/qt/Display.cpp | 2 +- src/platform/qt/DisplayGL.cpp | 65 ++++++++++++++++++++++------------- src/platform/qt/DisplayGL.h | 9 +++-- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index f5c0f18e2..c95593224 100644 --- a/CHANGES +++ b/CHANGES @@ -70,6 +70,7 @@ Misc: - FFmpeg: Support audio-only recording - Qt: Increase maximum magnifications and scaling - Qt: Add native FPS button to settings view + - Qt: Improve sync code 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index ed7c1fd38..afc0cc5cf 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -20,7 +20,7 @@ Display* Display::create(QWidget* parent) { #if defined(BUILD_GL) || defined(BUILD_GLES2) || defined(USE_EPOXY) QSurfaceFormat format; format.setSwapInterval(1); - format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); #endif switch (s_driver) { diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 54b6bc59c..71398e6af 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2019 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 @@ -261,15 +261,9 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent #endif m_backend->swap = [](VideoBackend* v) { PainterGL* painter = static_cast(v->user); - if (!painter->m_gl->isValid()) { - return; + if (!painter->m_swapTimer.isActive()) { + QMetaObject::invokeMethod(&painter->m_swapTimer, "start"); } - painter->m_gl->swapBuffers(painter->m_surface); - painter->m_gl->doneCurrent(); - painter->m_gl->makeCurrent(painter->m_surface); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif }; m_backend->init(m_backend, 0); @@ -287,6 +281,10 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent for (int i = 0; i < 2; ++i) { m_free.append(new uint32_t[1024 * 2048]); } + + m_swapTimer.setInterval(16); + m_swapTimer.setSingleShot(true); + connect(&m_swapTimer, &QTimer::timeout, this, &PainterGL::swap); } PainterGL::~PainterGL() { @@ -375,27 +373,22 @@ void PainterGL::draw() { return; } + if (m_needsUnlock) { + QTimer::singleShot(0, this, &PainterGL::draw); + return; + } + if (mCoreSyncWaitFrameStart(&m_context->thread()->impl->sync) || !m_queue.isEmpty()) { dequeue(); - mCoreSyncWaitFrameEnd(&m_context->thread()->impl->sync); - m_painter.begin(m_window); - performDraw(); - m_painter.end(); - m_backend->swap(m_backend); - if (!m_delayTimer.isValid()) { - m_delayTimer.start(); - } else if (m_gl->format().swapInterval() && m_context->videoSync()) { - while (m_delayTimer.elapsed() < 15) { - QThread::usleep(100); - } - m_delayTimer.restart(); + forceDraw(); + if (m_context->thread()->impl->sync.videoFrameWait) { + m_needsUnlock = true; + } else { + mCoreSyncWaitFrameEnd(&m_context->thread()->impl->sync); } } else { mCoreSyncWaitFrameEnd(&m_context->thread()->impl->sync); } - if (!m_queue.isEmpty()) { - QMetaObject::invokeMethod(this, "draw", Qt::QueuedConnection); - } } void PainterGL::forceDraw() { @@ -438,6 +431,30 @@ void PainterGL::performDraw() { if (m_messagePainter) { m_messagePainter->paint(&m_painter); } + m_frameReady = true; +} + +void PainterGL::swap() { + if (!m_gl->isValid()) { + return; + } + if (m_frameReady) { + m_gl->swapBuffers(m_surface); + m_gl->makeCurrent(m_surface); +#if defined(_WIN32) && defined(USE_EPOXY) + epoxy_handle_external_wglMakeCurrent(); +#endif + m_frameReady = false; + } + if (m_needsUnlock) { + mCoreSyncWaitFrameEnd(&m_context->thread()->impl->sync); + m_needsUnlock = false; + } + if (!m_queue.isEmpty()) { + QMetaObject::invokeMethod(this, "draw", Qt::QueuedConnection); + } else { + m_swapTimer.start(); + } } void PainterGL::enqueue(const uint32_t* backing) { diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 2dbd1f2f0..2c54934f4 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -16,13 +16,13 @@ #endif #endif -#include #include #include #include #include #include #include +#include #include "VideoProxy.h" @@ -105,6 +105,9 @@ public slots: int glTex(); +private slots: + void swap(); + private: void performDraw(); void dequeue(); @@ -125,7 +128,9 @@ private: VideoBackend* m_backend = nullptr; QSize m_size; MessagePainter* m_messagePainter = nullptr; - QElapsedTimer m_delayTimer; + QTimer m_swapTimer{this}; + bool m_needsUnlock = false; + bool m_frameReady = false; VideoProxy* m_videoProxy; }; From bbf06b5f1312c7f5d8dcf3a4e6f8c9ddbf76e6d8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 13:09:13 -0700 Subject: [PATCH 291/429] GBA Video: Simplify GL sprite flipping --- src/gba/renderers/gl.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 4fb3740a9..73dbeabec 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1443,10 +1443,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB spriteY -= 256; } - if (!GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesBIsVFlip(sprite->b)) { - spriteY = (renderer->firstY - height) + (renderer->firstY - spriteY) + 1; - } - int totalWidth = width; int totalHeight = height; if (GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesAIsDoubleSize(sprite->a)) { @@ -1466,7 +1462,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glActiveTexture(GL_TEXTURE0 + 1); glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], (GBAObjAttributesBIsHFlip(sprite->b) && !GBAObjAttributesAIsTransformed(sprite->a)) ? -totalWidth : totalWidth, totalHeight); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); glUniform1i(uniforms[GBA_GL_OBJ_VRAM], 0); glUniform1i(uniforms[GBA_GL_OBJ_PALETTE], 1); glUniform1i(uniforms[GBA_GL_OBJ_CHARBASE], charBase); @@ -1484,7 +1480,15 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { mat.a / 256.f, mat.c / 256.f, mat.b / 256.f, mat.d / 256.f }); } else { - glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { 1.f, 0, 0, 1.f }); + int flipX = 1; + int flipY = 1; + if (GBAObjAttributesBIsHFlip(sprite->b)) { + flipX = -1; + } + if (GBAObjAttributesBIsVFlip(sprite->b)) { + flipY = -1; + } + glUniformMatrix2fv(uniforms[GBA_GL_OBJ_TRANSFORM], 1, GL_FALSE, (GLfloat[]) { flipX, 0, 0, flipY }); } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { From 2506fd5330dbe920836ac442e1b0614a3efc8854 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 13:11:53 -0700 Subject: [PATCH 292/429] GBA Video: Detect OpenGL ES --- src/gba/renderers/gl.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 73dbeabec..a9721b30d 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -54,6 +54,9 @@ struct GBAVideoGLUniform { int type; }; +static const GLchar* const _gles3Header = + "#version 300\n"; + static const GLchar* const _gl3Header = "#version 130\n"; @@ -751,8 +754,13 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { } char log[1024]; - const GLchar* shaderBuffer[8]; - shaderBuffer[0] = _gl3Header; + const GLchar* shaderBuffer[4]; + const GLubyte* version = glGetString(GL_VERSION); + if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) { + shaderBuffer[0] = _gl3Header; + } else { + shaderBuffer[0] = _gles3Header; + } GLuint vs = glCreateShader(GL_VERTEX_SHADER); shaderBuffer[1] = _vertexShader; From c9493932434558a4e49e2ab4e4dd643854540b26 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 14:19:15 -0700 Subject: [PATCH 293/429] GBA Video: Start GLES cleanup --- src/gba/renderers/gl.c | 71 ++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index a9721b30d..93f1c3690 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -55,10 +55,13 @@ struct GBAVideoGLUniform { }; static const GLchar* const _gles3Header = - "#version 300\n"; + "#version 300 es\n" + "precision highp float;\n" + "precision highp int;\n"; static const GLchar* const _gl3Header = - "#version 130\n"; + "#version 130\n" + "precision highp float;\n"; static const char* const _vertexShader = "in vec2 position;\n" @@ -67,9 +70,9 @@ static const char* const _vertexShader = "out vec2 texCoord;\n" "void main() {\n" - " vec2 local = vec2(position.x, float(position.y * loc.x + loc.y) / abs(maxPos.y));\n" - " gl_Position = vec4((local * 2. - 1.) * sign(maxPos), 0., 1.);\n" - " texCoord = local * abs(maxPos);\n" + " vec2 local = vec2(position.x, float(position.y * loc.x + loc.y) / float(maxPos.y));\n" + " gl_Position = vec4((local * 2. - 1.) * vec2(sign(maxPos)), 0., 1.);\n" + " texCoord = local * vec2(abs(maxPos));\n" "}"; static const char* const _renderTile16 = @@ -132,10 +135,10 @@ static const char* const _renderMode0 = "void main() {\n" " ivec2 coord = ivec2(texCoord);\n" " if (mosaic.x > 1) {\n" - " coord.x -= int(mod(coord.x, mosaic.x));\n" + " coord.x -= coord.x % mosaic.x;\n" " }\n" " if (mosaic.y > 1) {\n" - " coord.y -= int(mod(coord.y, mosaic.y));\n" + " coord.y -= coord.y % mosaic.y;\n" " }\n" " coord += offset;\n" " if ((size & 1) == 1) {\n" @@ -153,7 +156,7 @@ static const char* const _renderMode0 = " }\n" " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (tileFlags & 0x3) * 256;\n" " color = renderTile(tile, int(map.r * 15.9), coord & 7);\n" - " flags = inflags / flagCoeff;\n" + " flags = vec4(inflags) / flagCoeff;\n" "}"; static const char* const _fetchTileOverflow = @@ -271,8 +274,6 @@ static const char* const _renderMode2 = "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST - "precision highp float;\n" - "precision highp int;\n" "vec4 fetchTile(ivec2 coord);\n" "vec2 interpolate(ivec2 arr[4], float x);\n" @@ -298,20 +299,20 @@ static const char* const _renderMode2 = "void main() {\n" " ivec2 mat[4];\n" " ivec2 offset[4];\n" - " loadAffine(int(texCoord.y), mat, offset);\n" - " vec2 coord = texCoord;\n" + " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " coord.x -= mod(coord.x, mosaic.x);\n" + " incoord.x = float(int(incoord.x) % mosaic.x);\n" " }\n" " if (mosaic.y > 1) {\n" - " coord.y -= mod(coord.y, mosaic.y);\n" + " incoord.y = float(int(incoord.y) % mosaic.y);\n" " }\n" - " float y = fract(coord.y);\n" + " loadAffine(int(incoord.y), mat, offset);\n" + " float y = fract(incoord.y);\n" " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" - " color = fetchTile(ivec2(mixedTransform * coord.x + mixedOffset));\n" - " flags = inflags / flagCoeff;\n" + " color = fetchTile(ivec2(mixedTransform * incoord.x + mixedOffset));\n" + " flags = vec4(inflags) / flagCoeff;\n" "}"; static const struct GBAVideoGLUniform _uniformsMode35[] = { @@ -340,8 +341,6 @@ static const char* const _renderMode35 = "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST - "precision highp float;\n" - "precision highp int;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" @@ -349,14 +348,14 @@ static const char* const _renderMode35 = "void main() {\n" " ivec2 mat[4];\n" " ivec2 offset[4];\n" - " loadAffine(int(texCoord.y), mat, offset);\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " incoord.x -= mod(incoord.x, mosaic.x);\n" + " incoord.x = float(int(incoord.x) % mosaic.x);\n" " }\n" " if (mosaic.y > 1) {\n" - " incoord.y -= mod(incoord.y, mosaic.y);\n" + " incoord.y = float(int(incoord.y) % mosaic.y);\n" " }\n" + " loadAffine(int(incoord.y), mat, offset);\n" " float y = fract(incoord.y);\n" " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" @@ -372,7 +371,7 @@ static const char* const _renderMode35 = " ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n" " int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n" " color = vec4((sixteen & 0x1F) / 31., ((sixteen >> 5) & 0x1F) / 31., ((sixteen >> 10) & 0x1F) / 31., 1.);\n" - " flags = inflags / flagCoeff;\n" + " flags = vec4(inflags) / flagCoeff;\n" "}"; static const struct GBAVideoGLUniform _uniformsMode4[] = { @@ -403,8 +402,6 @@ static const char* const _renderMode4 = "out vec4 color;\n" "out vec4 flags;\n" FLAG_CONST - "precision highp float;\n" - "precision highp int;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" @@ -412,14 +409,14 @@ static const char* const _renderMode4 = "void main() {\n" " ivec2 mat[4];\n" " ivec2 offset[4];\n" - " loadAffine(int(texCoord.y), mat, offset);\n" " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" - " incoord.x -= mod(incoord.x, mosaic.x);\n" + " incoord.x = float(int(incoord.x) % mosaic.x);\n" " }\n" " if (mosaic.y > 1) {\n" - " incoord.y -= mod(incoord.y, mosaic.y);\n" + " incoord.y = float(int(incoord.y) % mosaic.y);\n" " }\n" + " loadAffine(int(incoord.y), mat, offset);\n" " float y = fract(incoord.y);\n" " float lin = 0.75 + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" @@ -436,7 +433,7 @@ static const char* const _renderMode4 = " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" " color = texelFetch(palette, entry, 0);\n" " color.a = 1;\n" - " flags = inflags / flagCoeff;\n" + " flags = vec4(inflags) / flagCoeff;\n" "}"; static const struct GBAVideoGLUniform _uniformsObj[] = { @@ -478,14 +475,14 @@ static const char* const _renderObj = " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" " int x = int(incoord.x);\n" - " incoord.x = clamp(x - int(mod(mosaic.z + x, mosaic.x)), 0, dims.z - 1);\n" + " incoord.x = clamp(x - (mosaic.z + x) % mosaic.x, 0, dims.z - 1);\n" " } else if (mosaic.x < -1) {\n" " int x = dims.z - int(incoord.x) - 1;\n" - " incoord.x = clamp(dims.z - x + int(mod(mosaic.z + x, -mosaic.x)) - 1, 0, dims.z - 1);\n" + " incoord.x = clamp(dims.z - x + (mosaic.z + x) % -mosaic.x - 1, 0, dims.z - 1);\n" " }\n" " if (mosaic.y > 1) {\n" " int y = int(incoord.y);\n" - " incoord.y = clamp(y - int(mod(mosaic.w + y, mosaic.y)), 0, dims.w - 1);\n" + " incoord.y = clamp(y - (mosaic.w + y) % mosaic.y, 0, dims.w - 1);\n" " }\n" " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" @@ -496,7 +493,7 @@ static const char* const _renderObj = " pix.a = 0;\n" " }\n" " color = pix;\n" - " flags = inflags / flagCoeff;\n" + " flags = vec4(inflags) / flagCoeff;\n" " window = objwin.yzw;\n" "}"; @@ -625,12 +622,12 @@ static void _compileShader(struct GBAVideoGLRenderer* glRenderer, struct GBAVide glAttachShader(program, fs); glShaderSource(fs, shaderBufferLines, shaderBuffer, 0); glCompileShader(fs); - glGetShaderInfoLog(fs, 1024, 0, log); + glGetShaderInfoLog(fs, 2048, 0, log); if (log[0]) { mLOG(GBA_VIDEO, ERROR, "Fragment shader compilation failure: %s", log); } glLinkProgram(program); - glGetProgramInfoLog(program, 1024, 0, log); + glGetProgramInfoLog(program, 2048, 0, log); if (log[0]) { mLOG(GBA_VIDEO, ERROR, "Program link failure: %s", log); } @@ -753,7 +750,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, 0); } - char log[1024]; + char log[2048]; const GLchar* shaderBuffer[4]; const GLubyte* version = glGetString(GL_VERSION); if (strncmp((const char*) version, "OpenGL ES ", strlen("OpenGL ES "))) { @@ -766,7 +763,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { shaderBuffer[1] = _vertexShader; glShaderSource(vs, 2, shaderBuffer, 0); glCompileShader(vs); - glGetShaderInfoLog(vs, 1024, 0, log); + glGetShaderInfoLog(vs, 2048, 0, log); if (log[0]) { mLOG(GBA_VIDEO, ERROR, "Vertex shader compilation failure: %s", log); } From 708a6dc505ec217a1ca89621c655aab97b2a3e9a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 16:27:22 -0700 Subject: [PATCH 294/429] Qt: Include Qt5::Network --- src/platform/qt/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index b0b4e5fff..e5ae84e58 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -23,6 +23,7 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt5Multimedia) +find_package(Qt5Network) find_package(Qt5OpenGL) find_package(Qt5Widgets) @@ -279,7 +280,7 @@ qt5_wrap_ui(UI_SRC ${UI_FILES}) add_executable(${BINARY_NAME}-qt WIN32 MACOSX_BUNDLE main.cpp ${CMAKE_SOURCE_DIR}/res/mgba.icns ${SOURCE_FILES} ${PLATFORM_SRC} ${UI_SRC} ${AUDIO_SRC} ${RESOURCES}) set_target_properties(${BINARY_NAME}-qt PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/res/info.plist.in COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES};${OS_DEFINES};${QT_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") -list(APPEND QT_LIBRARIES Qt5::Widgets) +list(APPEND QT_LIBRARIES Qt5::Widgets Qt5::Network) if(BUILD_GL OR BUILD_GLES2 OR BUILD_EPOXY) list(APPEND QT_LIBRARIES Qt5::OpenGL ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY}) endif() From 2b7464d7810c4b5cdf8814945b88953a61671560 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 17:24:43 -0700 Subject: [PATCH 295/429] GBA Video: Fix more GLES compiler errors --- src/gba/renderers/gl.c | 80 ++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 93f1c3690..f4d98f1e9 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -56,11 +56,13 @@ struct GBAVideoGLUniform { static const GLchar* const _gles3Header = "#version 300 es\n" + "#define OUT(n) layout(location = n)\n" "precision highp float;\n" "precision highp int;\n"; static const GLchar* const _gl3Header = "#version 130\n" + "#define OUT(n)\n" "precision highp float;\n"; static const char* const _vertexShader = @@ -70,7 +72,7 @@ static const char* const _vertexShader = "out vec2 texCoord;\n" "void main() {\n" - " vec2 local = vec2(position.x, float(position.y * loc.x + loc.y) / float(maxPos.y));\n" + " vec2 local = vec2(position.x, float(position.y * float(loc.x) + float(loc.y)) / float(maxPos.y));\n" " gl_Position = vec4((local * 2. - 1.) * vec2(sign(maxPos)), 0., 1.);\n" " texCoord = local * vec2(abs(maxPos));\n" "}"; @@ -84,7 +86,7 @@ static const char* const _renderTile16 = " if (entry == 0) {\n" " discard;\n" " }\n" - " color.a = 1;\n" + " color.a = 1.;\n" " return color;\n" "}"; @@ -126,8 +128,8 @@ static const char* const _renderMode0 = "uniform ivec2 offset;\n" "uniform ivec4 inflags;\n" "uniform ivec2 mosaic;\n" - "out vec4 color;\n" - "out vec4 flags;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out vec4 flags;\n" FLAG_CONST "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -195,10 +197,10 @@ static const struct GBAVideoGLUniform _uniformsMode2[] = { static const char* const _interpolate = "vec2 interpolate(ivec2 arr[4], float x) {\n" " float x1m = 1. - x;\n" - " return x1m * x1m * x1m * arr[0] +" - " 3 * x1m * x1m * x * arr[1] +" - " 3 * x1m * x * x * arr[2] +" - " x * x * x * arr[3];\n" + " return x1m * x1m * x1m * vec2(arr[0]) +" + " 3. * x1m * x1m * x * vec2(arr[1]) +" + " 3. * x1m * x * x * vec2(arr[2]) +" + " x * x * x * vec2(arr[3]);\n" "}\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]) {\n" @@ -271,8 +273,8 @@ static const char* const _renderMode2 = "uniform isampler2D transform;\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" - "out vec4 color;\n" - "out vec4 flags;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out vec4 flags;\n" FLAG_CONST "vec4 fetchTile(ivec2 coord);\n" @@ -338,8 +340,8 @@ static const char* const _renderMode35 = "uniform isampler2D transform;\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" - "out vec4 color;\n" - "out vec4 flags;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out vec4 flags;\n" FLAG_CONST "vec2 interpolate(ivec2 arr[4], float x);\n" @@ -370,7 +372,7 @@ static const char* const _renderMode35 = " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" " ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n" " int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n" - " color = vec4((sixteen & 0x1F) / 31., ((sixteen >> 5) & 0x1F) / 31., ((sixteen >> 10) & 0x1F) / 31., 1.);\n" + " color = vec4(float(sixteen & 0x1F) / 31., float((sixteen >> 5) & 0x1F) / 31., float((sixteen >> 10) & 0x1F) / 31., 1.);\n" " flags = vec4(inflags) / flagCoeff;\n" "}"; @@ -399,8 +401,8 @@ static const char* const _renderMode4 = "uniform isampler2D transform;\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" - "out vec4 color;\n" - "out vec4 flags;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out vec4 flags;\n" FLAG_CONST "vec2 interpolate(ivec2 arr[4], float x);\n" @@ -432,7 +434,7 @@ static const char* const _renderMode4 = " vec4 twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0);\n" " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" " color = texelFetch(palette, entry, 0);\n" - " color.a = 1;\n" + " color.a = 1.;\n" " flags = vec4(inflags) / flagCoeff;\n" "}"; @@ -464,9 +466,9 @@ static const char* const _renderObj = "uniform ivec4 dims;\n" "uniform vec4 objwin;\n" "uniform ivec4 mosaic;\n" - "out vec4 color;\n" - "out vec4 flags;\n" - "out vec3 window;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out vec4 flags;\n" + "OUT(2) out vec3 window;\n" FLAG_CONST "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -475,22 +477,22 @@ static const char* const _renderObj = " vec2 incoord = texCoord;\n" " if (mosaic.x > 1) {\n" " int x = int(incoord.x);\n" - " incoord.x = clamp(x - (mosaic.z + x) % mosaic.x, 0, dims.z - 1);\n" + " incoord.x = float(clamp(x - (mosaic.z + x) % mosaic.x, 0, dims.z - 1));\n" " } else if (mosaic.x < -1) {\n" " int x = dims.z - int(incoord.x) - 1;\n" - " incoord.x = clamp(dims.z - x + (mosaic.z + x) % -mosaic.x - 1, 0, dims.z - 1);\n" + " incoord.x = float(clamp(dims.z - x + (mosaic.z + x) % -mosaic.x - 1, 0, dims.z - 1));\n" " }\n" " if (mosaic.y > 1) {\n" " int y = int(incoord.y);\n" - " incoord.y = clamp(y - (mosaic.w + y) % mosaic.y, 0, dims.w - 1);\n" + " incoord.y = float(clamp(y - (mosaic.w + y) % mosaic.y, 0, dims.w - 1));\n" " }\n" - " ivec2 coord = ivec2(transform * (incoord - dims.zw / 2) + dims.xy / 2);\n" + " ivec2 coord = ivec2(transform * (incoord - vec2(dims.zw) / 2.) + vec2(dims.xy) / 2.);\n" " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" " discard;\n" " }\n" " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" - " if (objwin.x > 0) {\n" - " pix.a = 0;\n" + " if (objwin.x > 0.) {\n" + " pix.a = 0.;\n" " }\n" " color = pix;\n" " flags = vec4(inflags) / flagCoeff;\n" @@ -521,7 +523,7 @@ static const char* const _finalize = "out vec4 color;\n" "void composite(vec4 pixel, ivec4 flags, inout vec4 topPixel, inout ivec4 topFlags, inout vec4 bottomPixel, inout ivec4 bottomFlags) {\n" - " if (pixel.a == 0) {\n" + " if (pixel.a == 0.) {\n" " return;\n" " }\n" " if (flags.x >= topFlags.x) {\n" @@ -543,38 +545,38 @@ static const char* const _finalize = " vec4 bottomPixel = topPixel;\n" " ivec4 topFlags = ivec4(texelFetch(backdropFlags, ivec2(0, texCoord.y), 0) * flagCoeff);\n" " ivec4 bottomFlags = topFlags;\n" - " vec4 windowFlags = texelFetch(window, ivec2(texCoord * scale), 0);\n" - " int layerWindow = int(windowFlags.x * 128);\n" + " vec4 windowFlags = texelFetch(window, ivec2(texCoord * float(scale)), 0);\n" + " int layerWindow = int(windowFlags.x * 128.);\n" " if ((layerWindow & 1) == 0) {\n" - " vec4 pix = texelFetch(layers[0], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" + " vec4 pix = texelFetch(layers[0], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 2) == 0) {\n" - " vec4 pix = texelFetch(layers[1], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" + " vec4 pix = texelFetch(layers[1], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 4) == 0) {\n" - " vec4 pix = texelFetch(layers[2], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" + " vec4 pix = texelFetch(layers[2], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 8) == 0) {\n" - " vec4 pix = texelFetch(layers[3], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * scale), 0).xyz * flagCoeff.xyz, 0);\n" + " vec4 pix = texelFetch(layers[3], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 16) == 0) {\n" - " vec4 pix = texelFetch(layers[4], ivec2(texCoord * scale), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * scale), 0) * flagCoeff);\n" + " vec4 pix = texelFetch(layers[4], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * float(scale)), 0) * flagCoeff);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" " if ((layerWindow & 32) != 0) {\n" " topFlags.y &= ~1;\n" " }\n" " if (((topFlags.y & 13) == 5 || topFlags.w > 0) && (bottomFlags.y & 2) == 2) {\n" - " topPixel *= topFlags.z / 16.;\n" + " topPixel *= float(topFlags.z) / 16.;\n" " topPixel += bottomPixel * windowFlags.y;\n" " } else if ((topFlags.y & 13) == 9) {\n" " topPixel += (1. - topPixel) * windowFlags.z;\n" From 70bc5a0bdbbe7a6faab36609210e6e005f0426dc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 17:42:36 -0700 Subject: [PATCH 296/429] GBA Video: Fix palettes in GLES3 --- src/gba/renderers/gl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index f4d98f1e9..0c1a2e186 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -870,7 +870,7 @@ void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; #ifdef BUILD_GLES3 - glRenderer->shadowPalette[address >> 1] = (value & 0x3F) | ((value & 0x7FE0) << 1); + glRenderer->shadowPalette[address >> 1] = ((value & 0x1F) << 11) | ((value & 0x3E0) << 1) | ((value & 0x7C00) >> 10); #else UNUSED(address); UNUSED(value); @@ -1161,7 +1161,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { if (glRenderer->paletteDirty) { glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); #ifdef BUILD_GLES3 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_6_5, glRenderer->shadowPalette); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 16, 32, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, glRenderer->shadowPalette); #else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); #endif From ffe7142d1f847919d3bbd025fb849d1bc674c539 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 23 May 2019 21:53:32 -0700 Subject: [PATCH 297/429] Qt: Fix crash when shutting down display --- src/platform/qt/DisplayGL.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 71398e6af..12da1bdb1 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -404,6 +404,10 @@ void PainterGL::stop() { dequeueAll(); m_backend->clear(m_backend); m_backend->swap(m_backend); + if (m_swapTimer.isActive()) { + swap(); + m_swapTimer.stop(); + } if (m_videoProxy) { m_videoProxy->reset(); } From e4e2c27789f1c04a5b41b1d8eb8318afde2d3a5b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 02:31:23 -0700 Subject: [PATCH 298/429] GBA Video: Fix layers breaking randomly --- src/gba/renderers/gl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 0c1a2e186..a39540eaa 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1140,6 +1140,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { if (glRenderer->paletteDirty || glRenderer->vramDirty || glRenderer->oamDirty || glRenderer->regsDirty) { if (glRenderer->firstY >= 0) { _drawScanlines(glRenderer, y - 1); + glBindVertexArray(0); } } if (glRenderer->firstY < 0) { From f8362fda6815f28ae1495fb9303beaaf4235f086 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 10:34:36 -0700 Subject: [PATCH 299/429] GBA Video: Improve GL reset --- src/gba/renderers/gl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index a39540eaa..f83ab0bee 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -848,12 +848,21 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; +#ifdef BUILD_GLES3 + int i; + for (i = 0; i < 512; ++i) { + renderer->writePalette(renderer, i << 1, renderer->palette[i]); + } +#else glRenderer->paletteDirty = true; +#endif glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; glRenderer->firstY = -1; glRenderer->dispcnt = 0; glRenderer->mosaic = 0; + memset(glRenderer->shadowRegs, 0, sizeof(glRenderer->shadowRegs)); + glRenderer->regsDirty = 0xFFFFFFFFFFFFULL; } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { From 9204c61ba20fa967e3dfcb46cf1e0351bb5237d5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 12:40:40 -0700 Subject: [PATCH 300/429] GBA Video: Improve detection of when VRAM needs to be uploaded --- src/gba/renderers/gl.c | 126 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 11 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index f83ab0bee..0eaa3e733 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1133,6 +1133,108 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t } } +static bool _dirtyMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + UNUSED(y); + if (!background->enabled) { + return false; + } + unsigned screenBase = background->screenBase >> 11; // Lops off one extra bit + unsigned screenMask = (7 << screenBase) & 0xFFFF; // Technically overzealous + if (renderer->vramDirty & screenMask) { + return true; + } + unsigned charBase = background->charBase >> 11; + unsigned charMask = (0xFFFF << charBase) & 0xFFFF; + if (renderer->vramDirty & charMask) { + return true; + } + return false; +} + +static bool _dirtyMode2(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + UNUSED(y); + if (!background->enabled) { + return false; + } + unsigned screenBase = background->screenBase >> 11; // Lops off one extra bit + unsigned screenMask = (0xF << screenBase) & 0xFFFF; + if (renderer->vramDirty & screenMask) { + return true; + } + unsigned charBase = background->charBase >> 11; + unsigned charMask = (0x3FFF << charBase) & 0xFFFF; + if (renderer->vramDirty & charMask) { + return true; + } + return false; +} + +static bool _dirtyMode3(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + UNUSED(y); + if (!background->enabled) { + return false; + } + if (renderer->vramDirty & 0xFFFFF) { + return true; + } + return false; +} + +static bool _dirtyMode45(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { + UNUSED(y); + if (!background->enabled) { + return false; + } + int start = GBARegisterDISPCNTIsFrameSelect(renderer->dispcnt) ? 5 : 0; + int mask = 0x3FF << start; + if (renderer->vramDirty & mask) { + return true; + } + return false; +} + +static bool _needsVramUpload(struct GBAVideoGLRenderer* renderer, int y) { + if (!renderer->vramDirty) { + return false; + } + if (y == 0) { + return true; + } + + if (GBARegisterDISPCNTIsObjEnable(renderer->dispcnt) && renderer->vramDirty & 0xFF0000) { + return true; + } + + bool dirty = false; + switch (GBARegisterDISPCNTGetMode(renderer->dispcnt)) { + case 0: + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[0], y); + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[1], y); + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[2], y); + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[3], y); + break; + case 1: + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[0], y); + dirty = dirty || _dirtyMode0(renderer, &renderer->bg[1], y); + dirty = dirty || _dirtyMode2(renderer, &renderer->bg[2], y); + break; + case 2: + dirty = dirty || _dirtyMode2(renderer, &renderer->bg[2], y); + dirty = dirty || _dirtyMode2(renderer, &renderer->bg[3], y); + break; + case 3: + dirty = _dirtyMode3(renderer, &renderer->bg[2], y); + break; + case 4: + dirty = _dirtyMode45(renderer, &renderer->bg[2], y); + break; + case 5: + dirty = _dirtyMode45(renderer, &renderer->bg[2], y); + break; + } + return dirty; +} + void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; @@ -1146,7 +1248,7 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstAffine = -1; } - if (glRenderer->paletteDirty || glRenderer->vramDirty || glRenderer->oamDirty || glRenderer->regsDirty) { + if (glRenderer->paletteDirty || _needsVramUpload(glRenderer, y) || glRenderer->oamDirty || glRenderer->regsDirty) { if (glRenderer->firstY >= 0) { _drawScanlines(glRenderer, y - 1); glBindVertexArray(0); @@ -1178,19 +1280,21 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->paletteDirty = false; } - int first = -1; - glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); - for (i = 0; i < 25; ++i) { - if (!(glRenderer->vramDirty & (1 << i))) { - if (first >= 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * first]); - first = -1; + if (_needsVramUpload(glRenderer, y)) { + int first = -1; + glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); + for (i = 0; i < 25; ++i) { + if (!(glRenderer->vramDirty & (1 << i))) { + if (first >= 0) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 8 * first, 256, 8 * (i - first), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &glRenderer->d.vram[2048 * first]); + first = -1; + } + } else if (first < 0) { + first = i; } - } else if (first < 0) { - first = i; } + glRenderer->vramDirty = 0; } - glRenderer->vramDirty = 0; if (glRenderer->oamDirty) { glRenderer->oamMax = GBAVideoRendererCleanOAM(glRenderer->d.oam->obj, glRenderer->sprites, 0); From 4225a2b4b08a554a055590765328932078bfff90 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 12:47:17 -0700 Subject: [PATCH 301/429] GBA Video: Implement GL forced blank --- src/gba/renderers/gl.c | 85 ++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 0eaa3e733..603f5985e 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -859,10 +859,10 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; glRenderer->firstY = -1; - glRenderer->dispcnt = 0; + glRenderer->dispcnt = 0x0080; glRenderer->mosaic = 0; memset(glRenderer->shadowRegs, 0, sizeof(glRenderer->shadowRegs)); - glRenderer->regsDirty = 0xFFFFFFFFFFFFULL; + glRenderer->regsDirty = 0xFFFFFFFFFFFEULL; } void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { @@ -1508,45 +1508,50 @@ void _finalizeLayers(struct GBAVideoGLRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OUTPUT]); glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glScissor(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); - glUseProgram(renderer->finalizeShader.program); - glBindVertexArray(renderer->finalizeShader.vao); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_COLOR]); - glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_FLAGS]); - glActiveTexture(GL_TEXTURE0 + 3); - glBindTexture(GL_TEXTURE_2D, renderer->bg[0].tex); - glActiveTexture(GL_TEXTURE0 + 4); - glBindTexture(GL_TEXTURE_2D, renderer->bg[0].flags); - glActiveTexture(GL_TEXTURE0 + 5); - glBindTexture(GL_TEXTURE_2D, renderer->bg[1].tex); - glActiveTexture(GL_TEXTURE0 + 6); - glBindTexture(GL_TEXTURE_2D, renderer->bg[1].flags); - glActiveTexture(GL_TEXTURE0 + 7); - glBindTexture(GL_TEXTURE_2D, renderer->bg[2].tex); - glActiveTexture(GL_TEXTURE0 + 8); - glBindTexture(GL_TEXTURE_2D, renderer->bg[2].flags); - glActiveTexture(GL_TEXTURE0 + 9); - glBindTexture(GL_TEXTURE_2D, renderer->bg[3].tex); - glActiveTexture(GL_TEXTURE0 + 10); - glBindTexture(GL_TEXTURE_2D, renderer->bg[3].flags); - glActiveTexture(GL_TEXTURE0 + 11); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_COLOR]); - glActiveTexture(GL_TEXTURE0 + 12); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_FLAGS]); + if (GBARegisterDISPCNTIsForcedBlank(renderer->dispcnt)) { + glClearColor(1.f, 1.f, 1.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + } else { + glUseProgram(renderer->finalizeShader.program); + glBindVertexArray(renderer->finalizeShader.vao); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_WINDOW]); + glActiveTexture(GL_TEXTURE0 + 1); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_COLOR]); + glActiveTexture(GL_TEXTURE0 + 2); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_OBJ_FLAGS]); + glActiveTexture(GL_TEXTURE0 + 3); + glBindTexture(GL_TEXTURE_2D, renderer->bg[0].tex); + glActiveTexture(GL_TEXTURE0 + 4); + glBindTexture(GL_TEXTURE_2D, renderer->bg[0].flags); + glActiveTexture(GL_TEXTURE0 + 5); + glBindTexture(GL_TEXTURE_2D, renderer->bg[1].tex); + glActiveTexture(GL_TEXTURE0 + 6); + glBindTexture(GL_TEXTURE_2D, renderer->bg[1].flags); + glActiveTexture(GL_TEXTURE0 + 7); + glBindTexture(GL_TEXTURE_2D, renderer->bg[2].tex); + glActiveTexture(GL_TEXTURE0 + 8); + glBindTexture(GL_TEXTURE_2D, renderer->bg[2].flags); + glActiveTexture(GL_TEXTURE0 + 9); + glBindTexture(GL_TEXTURE_2D, renderer->bg[3].tex); + glActiveTexture(GL_TEXTURE0 + 10); + glBindTexture(GL_TEXTURE_2D, renderer->bg[3].flags); + glActiveTexture(GL_TEXTURE0 + 11); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_COLOR]); + glActiveTexture(GL_TEXTURE0 + 12); + glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_BACKDROP_FLAGS]); - glUniform2i(uniforms[GBA_GL_VS_LOC], GBA_VIDEO_VERTICAL_PIXELS, 0); - glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); - glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); - glUniform1iv(uniforms[GBA_GL_FINALIZE_LAYERS], 5, (GLint[]) { 3, 5, 7, 9, 1 }); - glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); - glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); - glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); - glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROP], 11); - glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 12); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glUniform2i(uniforms[GBA_GL_VS_LOC], GBA_VIDEO_VERTICAL_PIXELS, 0); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_FINALIZE_SCALE], renderer->scale); + glUniform1iv(uniforms[GBA_GL_FINALIZE_LAYERS], 5, (GLint[]) { 3, 5, 7, 9, 1 }); + glUniform1iv(uniforms[GBA_GL_FINALIZE_FLAGS], 5, (GLint[]) { 4, 6, 8, 10, 2 }); + glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); + glUniform1i(uniforms[GBA_GL_FINALIZE_WINDOW], 0); + glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROP], 11); + glUniform1i(uniforms[GBA_GL_FINALIZE_BACKDROPFLAGS], 12); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } glBindFramebuffer(GL_FRAMEBUFFER, 0); } From 89983901f8289119e4ed2b03a800f3e665af16a0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 14:17:42 -0700 Subject: [PATCH 302/429] Qt: Better detection of GL versions and extensions --- src/platform/opengl/gles2.c | 57 ++++++++++++++++++++++++----------- src/platform/qt/DisplayGL.cpp | 11 +++---- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 168858241..82215cce4 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -134,15 +134,17 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { mGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, false, uniforms, 4); mGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, false, 0, 0); - glBindVertexArray(context->initialShader.vao); - glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glEnableVertexAttribArray(context->initialShader.positionLocation); - glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glBindVertexArray(context->finalShader.vao); - glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glEnableVertexAttribArray(context->finalShader.positionLocation); - glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); - glBindVertexArray(0); + if (context->initialShader.vao != (GLuint) -1) { + glBindVertexArray(context->initialShader.vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(context->initialShader.positionLocation); + glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(context->finalShader.vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(context->finalShader.positionLocation); + glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(0); + } glDeleteFramebuffers(1, &context->finalShader.fbo); glDeleteTextures(1, &context->finalShader.tex); @@ -253,7 +255,13 @@ void _drawShader(struct mGLES2Context* context, struct mGLES2Shader* shader) { glUseProgram(shader->program); glUniform1i(shader->texLocation, 0); glUniform2f(shader->texSizeLocation, context->d.width - padW, context->d.height - padH); - glBindVertexArray(shader->vao); + if (shader->vao != (GLuint) -1) { + glBindVertexArray(shader->vao); + } else { + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(shader->positionLocation); + glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + } size_t u; for (u = 0; u < shader->nUniforms; ++u) { struct mGLES2Uniform* uniform = &shader->uniforms[u]; @@ -328,7 +336,9 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) { _drawShader(context, &context->finalShader); glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(0); - glBindVertexArray(0); + if (context->finalShader.vao != (GLuint) -1) { + glBindVertexArray(0); + } } void mGLES2ContextPostFrame(struct VideoBackend* v, const void* frame) { @@ -435,7 +445,12 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f shader->uniforms[i].location = glGetUniformLocation(shader->program, shader->uniforms[i].name); } - glGenVertexArrays(1, &shader->vao); + const GLubyte* extensions = glGetString(GL_EXTENSIONS); + if (shaderBuffer[0] == _gles2Header || version[0] == '3' || strstr((const char*) extensions, "_vertex_array_object") != NULL) { + glGenVertexArrays(1, &shader->vao); + } else { + shader->vao = -1; + } glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -445,7 +460,9 @@ void mGLES2ShaderDeinit(struct mGLES2Shader* shader) { glDeleteShader(shader->fragmentShader); glDeleteProgram(shader->program); glDeleteFramebuffers(1, &shader->fbo); - glDeleteVertexArrays(1, &shader->vao); + if (shader->vao != (GLuint) -1) { + glDeleteVertexArrays(1, &shader->vao); + } } void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shaders, size_t nShaders) { @@ -463,12 +480,16 @@ void mGLES2ShaderAttach(struct mGLES2Context* context, struct mGLES2Shader* shad glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); - glBindVertexArray(context->shaders[i].vao); - glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glEnableVertexAttribArray(context->shaders[i].positionLocation); - glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + if (context->shaders[i].vao != (GLuint) -1) { + glBindVertexArray(context->shaders[i].vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); + glEnableVertexAttribArray(context->shaders[i].positionLocation); + glVertexAttribPointer(context->shaders[i].positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + } + } + if (context->initialShader.vao != (GLuint) -1) { + glBindVertexArray(0); } - glBindVertexArray(0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 12da1bdb1..135e591f8 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -47,11 +47,11 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif - int majorVersion = m_gl->format().majorVersion(); + auto version = m_gl->format().version(); QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); m_gl->doneCurrent(); - if (majorVersion == 2 && !extensions.contains("GL_ARB_framebuffer_object")) { + if ((version == qMakePair(2, 1) && !extensions.contains("GL_ARB_framebuffer_object")) || version == qMakePair(2, 0)) { QSurfaceFormat newFormat(format); newFormat.setVersion(1, 4); m_gl->setFormat(newFormat); @@ -238,12 +238,11 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent #if defined(_WIN32) && defined(USE_EPOXY) epoxy_handle_external_wglMakeCurrent(); #endif - int majorVersion = m_gl->format().majorVersion(); - - QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); #ifdef BUILD_GLES2 - if ((majorVersion == 2 && extensions.contains("GL_ARB_framebuffer_object")) || majorVersion > 2) { + auto version = m_gl->format().version(); + QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); + if ((version == qMakePair(2, 1) && extensions.contains("GL_ARB_framebuffer_object")) || version.first > 2) { gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); m_backend = &gl2Backend->d; From d1d33393cd5b854f66e2fff3714acdb4a9c737c6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 17:28:11 -0700 Subject: [PATCH 303/429] OpenGL: Fix GL version check --- src/platform/opengl/gles2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 82215cce4..a9034204f 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -446,7 +446,7 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f } const GLubyte* extensions = glGetString(GL_EXTENSIONS); - if (shaderBuffer[0] == _gles2Header || version[0] == '3' || strstr((const char*) extensions, "_vertex_array_object") != NULL) { + if (shaderBuffer[0] == _gles2Header || version[0] >= '3' || (extensions && strstr((const char*) extensions, "_vertex_array_object") != NULL)) { glGenVertexArrays(1, &shader->vao); } else { shader->vao = -1; From a33e9d375ca1f3e2a918ab2c27962b37de530a8d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2019 20:48:36 -0700 Subject: [PATCH 304/429] GBA Video: Fix sprite priority regression (fixes #1419) --- .../gba/obj/fzc-obj-priority/baseline_0000.png | Bin 0 -> 29698 bytes .../gba/obj/fzc-obj-priority/baseline_0001.png | Bin 0 -> 29919 bytes .../gba/obj/fzc-obj-priority/baseline_0002.png | Bin 0 -> 29919 bytes .../gba/obj/fzc-obj-priority/baseline_0003.png | Bin 0 -> 29919 bytes .../gba/obj/fzc-obj-priority/baseline_0004.png | Bin 0 -> 29919 bytes .../gba/obj/fzc-obj-priority/baseline_0005.png | Bin 0 -> 29919 bytes .../gba/obj/fzc-obj-priority/baseline_0006.png | Bin 0 -> 30051 bytes cinema/gba/obj/fzc-obj-priority/test.mvl | Bin 0 -> 32368 bytes src/gba/renderers/software-obj.c | 8 ++++---- 9 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0000.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0001.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0002.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0003.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0004.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0005.png create mode 100644 cinema/gba/obj/fzc-obj-priority/baseline_0006.png create mode 100644 cinema/gba/obj/fzc-obj-priority/test.mvl diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0000.png b/cinema/gba/obj/fzc-obj-priority/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..1542506183adc4dc00eec892ddfd48ae6d7ce66f GIT binary patch literal 29698 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≦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 literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0001.png b/cinema/gba/obj/fzc-obj-priority/baseline_0001.png new file mode 100644 index 0000000000000000000000000000000000000000..e17d09e38d7de200a6da42a4292773ad5f357268 GIT binary patch literal 29919 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 JZIHGI{~zou=jQ+b literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0002.png b/cinema/gba/obj/fzc-obj-priority/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..e17d09e38d7de200a6da42a4292773ad5f357268 GIT binary patch literal 29919 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 JZIHGI{~zou=jQ+b literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0003.png b/cinema/gba/obj/fzc-obj-priority/baseline_0003.png new file mode 100644 index 0000000000000000000000000000000000000000..e17d09e38d7de200a6da42a4292773ad5f357268 GIT binary patch literal 29919 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 JZIHGI{~zou=jQ+b literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0004.png b/cinema/gba/obj/fzc-obj-priority/baseline_0004.png new file mode 100644 index 0000000000000000000000000000000000000000..e17d09e38d7de200a6da42a4292773ad5f357268 GIT binary patch literal 29919 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 JZIHGI{~zou=jQ+b literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0005.png b/cinema/gba/obj/fzc-obj-priority/baseline_0005.png new file mode 100644 index 0000000000000000000000000000000000000000..e17d09e38d7de200a6da42a4292773ad5f357268 GIT binary patch literal 29919 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 JZIHGI{~zou=jQ+b literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0006.png b/cinema/gba/obj/fzc-obj-priority/baseline_0006.png new file mode 100644 index 0000000000000000000000000000000000000000..02d52196d8f016dec17ab5226205c0578c1f1cce GIT binary patch literal 30051 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 VIOR@Tvjc!$QeyI=wZevh{{v*!DyRSe literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/fzc-obj-priority/test.mvl b/cinema/gba/obj/fzc-obj-priority/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..ae2a960bb6bd1ca0ebb5126a6fea35a1e1139b3c GIT binary patch literal 32368 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≈DMJ7e|&M8L8zqQi7|9+kp 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 F_-{C2lQ;kX literal 0 HcmV?d00001 diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index de056596d..8e3e677e1 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -80,7 +80,7 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ renderer->spriteLayer[outX] = palette[tileData] | flags; \ } @@ -88,7 +88,7 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ renderer->spriteLayer[outX] = color | flags; \ } @@ -107,7 +107,7 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ renderer->spriteLayer[outX] = palette[tileData] | flags; \ } @@ -115,7 +115,7 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_UNWRITTEN) == FLAG_UNWRITTEN && tileData) { \ + if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ renderer->spriteLayer[outX] = color | flags; \ } From f455650f0d9fea514379e6afd5fed3779c5633f1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 25 May 2019 16:12:56 -0700 Subject: [PATCH 305/429] Changes: Update for 0.7.2 --- CHANGES | 69 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/CHANGES b/CHANGES index c95593224..4d947d061 100644 --- a/CHANGES +++ b/CHANGES @@ -17,50 +17,18 @@ Emulation fixes: - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - - GBA Video: Fix scanline cache with scale factor change edge cases - - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) - - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) - - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) - - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) - - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 - - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) - - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) - - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) - - GB: Fix HALT when IE and IF unused bits are set (fixes mgba.io/i/1349) - - GBA Video: Implement mosaic on transformed sprites (fixes mgba.io/b/9) Other fixes: - - Qt: More app metadata fixes - - Qt: Fix load recent from archive (fixes mgba.io/i/1325) - - LR35902: Fix disassembly of several CB-prefix instructions - - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) - - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) - - CMake: Fix .deb imagemagick dependencies - - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) - - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) - - GB Core: Fix toggling WIN and OBJ being swapped - - All: Fix several memory leaks - - LR35902: Fix trailing whitespace in disassembly - - Qt: Fix adjusting magnification in tile viewer when not fitting to window - - FFmpeg: Improve initialization reliability and cleanup - - Wii: Fix aspect ratio (fixes mgba.io/i/500) - Qt: Fix some Qt display driver race conditions - - FFmpeg: Fix audio conversion producing gaps - Core: Improved lockstep driver reliability (Le Hoang Quyen) - - GBA: Fix skipping BIOS on irregularly sized ROMs - - Qt: Fix bounded fast forward with Qt Multimedia - - Qt: Fix saving settings with native FPS target Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing - - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) - LR35902: Support PC-relative opcode decoding - - Qt: Improve camera initialization - Qt: Support switching webcams - Core: Add keysRead callback - - Vita: Improved frame drawing speed - Qt: Cap window size on start to monitor size - GBA BIOS: Add timings for HLE BIOS math functions (fixes mgba.io/i/1396) - Debugger: Make tracing compatible with breakpoints/watchpoints @@ -72,6 +40,43 @@ Misc: - Qt: Add native FPS button to settings view - Qt: Improve sync code +0.7.2: (2019-05-25) +Emulation fixes: + - GB: Fix HALT when IE and IF unused bits are set (fixes mgba.io/i/1349) + - GB Timer: Fix timing adjustments when writing to TAC (fixes mgba.io/i/1340) + - GB Video: Fix window y changing mid-window (fixes mgba.io/i/1345) + - GB Video: Fix more window edge cases (fixes mgba.io/i/1346) + - GBA: Fix RTC on non-standard sized ROMs (fixes mgba.io/i/1400) + - GBA DMA: Fix DMA0-2 lengths (fixes mgba.io/i/1344) + - GBA Memory: Fix writing to OBJ memory in modes 3 and 5 + - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) + - GBA Video: Fix scanline cache with scale factor change edge cases + - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) + - GBA Video: Implement mosaic on transformed sprites (fixes mgba.io/b/9) +Other fixes: + - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) + - All: Fix several memory leaks + - GB Core: Fix toggling WIN and OBJ being swapped + - GBA: Fix skipping BIOS on irregularly sized ROMs + - CMake: Fix .deb imagemagick dependencies + - FFmpeg: Improve initialization reliability and cleanup + - FFmpeg: Fix audio conversion producing gaps + - LR35902: Fix disassembly of several CB-prefix instructions + - LR35902: Fix trailing whitespace in disassembly + - Qt: More app metadata fixes + - Qt: Fix load recent from archive (fixes mgba.io/i/1325) + - Qt: Fix overrides getting discarded (fixes mgba.io/i/1354) + - Qt: Fix saved scale not getting set on resize (fixes mgba.io/i/1074) + - Qt: Fix crash in sprite viewer magnification (fixes mgba.io/i/1362) + - Qt: Fix adjusting magnification in tile viewer when not fitting to window + - Qt: Fix bounded fast forward with Qt Multimedia + - Qt: Fix saving settings with native FPS target + - Wii: Fix aspect ratio (fixes mgba.io/i/500) +Misc: + - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) + - Qt: Improve camera initialization + - Vita: Improved frame drawing speed + 0.7.1: (2019-02-24) Bugfixes: - 3DS: Work around menu freezing (fixes mgba.io/i/1294) From f5fb96f256d6d2a1bc2a33228c0a83d43cc31ec6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 25 May 2019 23:22:16 -0700 Subject: [PATCH 306/429] GBA Video: More GL ES fixes --- include/mgba/internal/gba/renderers/gl.h | 1 + src/gba/renderers/gl.c | 37 ++++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index cf53c6566..7194fcfe9 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -76,6 +76,7 @@ enum { enum { GBA_GL_TEX_OBJ_COLOR = 0, GBA_GL_TEX_OBJ_FLAGS, + GBA_GL_TEX_OBJ_DEPTH, GBA_GL_TEX_BACKDROP_COLOR, GBA_GL_TEX_BACKDROP_FLAGS, GBA_GL_TEX_WINDOW, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 603f5985e..178d38ff4 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -58,7 +58,8 @@ static const GLchar* const _gles3Header = "#version 300 es\n" "#define OUT(n) layout(location = n)\n" "precision highp float;\n" - "precision highp int;\n"; + "precision highp int;\n" + "precision highp isampler2D;\n"; static const GLchar* const _gl3Header = "#version 130\n" @@ -496,6 +497,7 @@ static const char* const _renderObj = " }\n" " color = pix;\n" " flags = vec4(inflags) / flagCoeff;\n" + " gl_FragDepth = flags.x;\n" " window = objwin.yzw;\n" "}"; @@ -657,16 +659,20 @@ static void _deleteShader(struct GBAVideoGLShader* shader) { glDeleteVertexArrays(1, &shader->vao); } -static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { +static void _initFramebufferTextureEx(GLuint tex, GLenum internalFormat, GLenum format, GLenum type, GLenum attachment, int scale) { glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, format, scale > 0 ? GBA_VIDEO_HORIZONTAL_PIXELS * scale : 1, GBA_VIDEO_VERTICAL_PIXELS * (scale > 0 ? scale : 1), 0, format, GL_UNSIGNED_BYTE, 0); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, scale > 0 ? GBA_VIDEO_HORIZONTAL_PIXELS * scale : 1, GBA_VIDEO_VERTICAL_PIXELS * (scale > 0 ? scale : 1), 0, format, type, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex, 0); } +static void _initFramebufferTexture(GLuint tex, GLenum format, GLenum attachment, int scale) { + _initFramebufferTextureEx(tex, format, format, GL_UNSIGNED_BYTE, attachment, scale); +} + void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; glRenderer->temporaryBuffer = NULL; @@ -702,6 +708,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_DEPTH], GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_ATTACHMENT, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_COLOR], GL_RGB, GL_COLOR_ATTACHMENT0, 0); @@ -1305,11 +1312,16 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); - glDisable(GL_SCISSOR_TEST); + glDisable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); +#ifdef BUILD_GLES3 + glClearDepthf(1.f); +#else + glClearDepth(1); +#endif glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (i = 0; i < 4; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); @@ -1339,18 +1351,17 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { glViewport(0, 0, 1, GBA_VIDEO_VERTICAL_PIXELS); glScissor(0, glRenderer->firstY, 1, y - glRenderer->firstY + 1); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); - glClearColor(((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f); - glClear(GL_COLOR_BUFFER_BIT); - glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT1 }); - glClearColor(1, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, glRenderer->blda / 16.f, 0); - glClear(GL_COLOR_BUFFER_BIT); + glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); + glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f }); + glClearBufferfv(GL_COLOR, 1, (GLfloat[]) { 1.f, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, glRenderer->blda / 16.f, 0.f }); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); GBAVideoGLRendererDrawWindow(glRenderer, y); if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { int i; - for (i = glRenderer->oamMax; i--;) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + for (i = 0; i < glRenderer->oamMax; ++i) { struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i]; if ((y < sprite->y && (sprite->endY - 256 < 0 || glRenderer->firstY >= sprite->endY - 256)) || glRenderer->firstY >= sprite->endY) { continue; @@ -1358,6 +1369,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { GBAVideoGLRendererDrawSprite(glRenderer, &sprite->obj, y, sprite->y); } + glDisable(GL_DEPTH_TEST); } if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -1403,6 +1415,7 @@ void GBAVideoGLRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; _drawScanlines(glRenderer, GBA_VIDEO_VERTICAL_PIXELS - 1); _finalizeLayers(glRenderer); + glDisable(GL_SCISSOR_TEST); glBindVertexArray(0); glRenderer->firstAffine = -1; glRenderer->firstY = -1; From 130cb63bbc45819d844dd7cf30015a533d4168d8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 09:32:00 -0700 Subject: [PATCH 307/429] Qt: Fix shutdown leaks --- src/platform/qt/CoreController.cpp | 3 +++ src/platform/qt/Window.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index d073ac654..579f75d04 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -197,6 +197,9 @@ CoreController::~CoreController() { mCacheSetDeinit(m_cacheSet.get()); m_cacheSet.reset(); } + + mCoreConfigDeinit(&m_threadContext.core->config); + m_threadContext.core->deinit(m_threadContext.core); } const color_t* CoreController::drawContext() { diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 24a37b0d8..7cdc73a4d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -780,11 +780,6 @@ void Window::gameStarted() { void Window::gameStopped() { m_controller.reset(); - m_display->stopDrawing(); - if (m_pendingClose) { - m_display.reset(); - close(); - } #ifdef M_CORE_GBA for (Action* action : m_platformActions) { action->setEnabled(true); @@ -819,6 +814,11 @@ void Window::gameStopped() { m_audioProcessor->stop(); m_audioProcessor.reset(); } + m_display->stopDrawing(); + if (m_pendingClose) { + m_display.reset(); + close(); + } #ifdef USE_DISCORD_RPC DiscordCoordinator::gameStopped(); From 19c4e565d1c5c12b72984338a05b0be70dc6df26 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 09:38:29 -0700 Subject: [PATCH 308/429] GBA Video: Fix VBO leak --- src/gba/renderers/gl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 178d38ff4..4dafd8d3d 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -834,6 +834,7 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); + glDeleteBuffers(1, &glRenderer->vbo); _deleteShader(&glRenderer->bgShader[0]); _deleteShader(&glRenderer->bgShader[1]); From d839098caef428a564aa83fe8cfbceadd8339da7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 11:30:42 -0700 Subject: [PATCH 309/429] Switch: Update arch flags --- src/platform/switch/CMakeToolchain.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/switch/CMakeToolchain.txt b/src/platform/switch/CMakeToolchain.txt index 38c4ff943..3cdee0ddb 100644 --- a/src/platform/switch/CMakeToolchain.txt +++ b/src/platform/switch/CMakeToolchain.txt @@ -7,7 +7,7 @@ else() endif() set(cross_prefix aarch64-none-elf-) -set(arch_flags "-mtune=cortex-a57 -ffunction-sections -march=armv8-a -mtp=soft -fPIC -ftls-model=local-exec") +set(arch_flags "-mtune=cortex-a57 -ffunction-sections -march=armv8-a+crc+crypto -mtp=soft -fPIE") set(inc_flags "-I${LIBNX}/include ${arch_flags}") set(link_flags "-L${LIBNX}/lib -lnx -specs=${LIBNX}/switch.specs ${arch_flags}") From 1f2bd30b14a9b957951397571ccb237c6df02ed6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 14:26:35 -0700 Subject: [PATCH 310/429] Switch: Fix threading-related crash on second launch --- CHANGES | 1 + include/mgba-util/platform/3ds/threading.h | 4 ++-- include/mgba-util/platform/posix/threading.h | 4 ++-- include/mgba-util/platform/psp2/threading.h | 6 +++--- include/mgba-util/platform/switch/threading.h | 6 +++--- include/mgba-util/platform/windows/threading.h | 4 ++-- include/mgba-util/threading.h | 6 ++++++ src/core/rewind.c | 2 +- src/core/thread.c | 2 +- src/feature/gui/gui-runner.c | 2 +- src/feature/thread-proxy.c | 4 ++-- src/platform/3ds/main.c | 2 +- src/platform/psp2/psp2-context.c | 2 +- 13 files changed, 26 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 4d947d061..965aa411c 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Emulation fixes: Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) + - Switch: Fix threading-related crash on second launch Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/include/mgba-util/platform/3ds/threading.h b/include/mgba-util/platform/3ds/threading.h index 769039615..6ce2432b1 100644 --- a/include/mgba-util/platform/3ds/threading.h +++ b/include/mgba-util/platform/3ds/threading.h @@ -98,8 +98,8 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) return !*thread; } -static inline int ThreadJoin(Thread thread) { - return threadJoin(thread, U64_MAX); +static inline int ThreadJoin(Thread* thread) { + return threadJoin(*thread, U64_MAX); } static inline void ThreadSetName(const char* name) { diff --git a/include/mgba-util/platform/posix/threading.h b/include/mgba-util/platform/posix/threading.h index 38aac8f62..64340c852 100644 --- a/include/mgba-util/platform/posix/threading.h +++ b/include/mgba-util/platform/posix/threading.h @@ -80,8 +80,8 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) return pthread_create(thread, 0, entry, context); } -static inline int ThreadJoin(Thread thread) { - return pthread_join(thread, 0); +static inline int ThreadJoin(Thread* thread) { + return pthread_join(*thread, 0); } static inline int ThreadSetName(const char* name) { diff --git a/include/mgba-util/platform/psp2/threading.h b/include/mgba-util/platform/psp2/threading.h index 07388bed8..36364ac95 100644 --- a/include/mgba-util/platform/psp2/threading.h +++ b/include/mgba-util/platform/psp2/threading.h @@ -131,12 +131,12 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) return 0; } -static inline int ThreadJoin(Thread thread) { - int res = sceKernelWaitThreadEnd(thread, 0, 0); +static inline int ThreadJoin(Thread* thread) { + int res = sceKernelWaitThreadEnd(*thread, 0, 0); if (res < 0) { return res; } - return sceKernelDeleteThread(thread); + return sceKernelDeleteThread(*thread); } static inline int ThreadSetName(const char* name) { diff --git a/include/mgba-util/platform/switch/threading.h b/include/mgba-util/platform/switch/threading.h index 7003317b3..2348b6983 100644 --- a/include/mgba-util/platform/switch/threading.h +++ b/include/mgba-util/platform/switch/threading.h @@ -71,12 +71,12 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) return threadStart(thread); } -static inline int ThreadJoin(Thread thread) { - int res = threadWaitForExit(&thread); +static inline int ThreadJoin(Thread* thread) { + int res = threadWaitForExit(thread); if(R_FAILED(res)) { return res; } - return threadClose(&thread); + return threadClose(thread); } static inline void ThreadSetName(const char* name) { diff --git a/include/mgba-util/platform/windows/threading.h b/include/mgba-util/platform/windows/threading.h index 33af88b58..8ea73d3c1 100644 --- a/include/mgba-util/platform/windows/threading.h +++ b/include/mgba-util/platform/windows/threading.h @@ -75,8 +75,8 @@ static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) return GetLastError(); } -static inline int ThreadJoin(Thread thread) { - DWORD error = WaitForSingleObject(thread, INFINITE); +static inline int ThreadJoin(Thread* thread) { + DWORD error = WaitForSingleObject(*thread, INFINITE); if (error == WAIT_FAILED) { return GetLastError(); } diff --git a/include/mgba-util/threading.h b/include/mgba-util/threading.h index a8b0b2176..3a2a4102f 100644 --- a/include/mgba-util/threading.h +++ b/include/mgba-util/threading.h @@ -29,10 +29,16 @@ CXX_GUARD_START #ifdef _3DS // ctrulib already has a type called Thread #include <3ds/thread.h> +#elif defined(__SWITCH__) +#include #else typedef void* Thread; #endif +#ifdef __SWITCH__ +#include +#else typedef void* Mutex; +#endif typedef void* Condition; static inline int MutexInit(Mutex* mutex) { diff --git a/src/core/rewind.c b/src/core/rewind.c index accb73918..11c39fe2a 100644 --- a/src/core/rewind.c +++ b/src/core/rewind.c @@ -53,7 +53,7 @@ void mCoreRewindContextDeinit(struct mCoreRewindContext* context) { context->onThread = false; MutexUnlock(&context->mutex); ConditionWake(&context->cond); - ThreadJoin(context->thread); + ThreadJoin(&context->thread); MutexDeinit(&context->mutex); ConditionDeinit(&context->cond); } diff --git a/src/core/thread.c b/src/core/thread.c index abd7da973..e9e5cfa7e 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -413,7 +413,7 @@ void mCoreThreadJoin(struct mCoreThread* threadContext) { if (!threadContext->impl) { return; } - ThreadJoin(threadContext->impl->thread); + ThreadJoin(&threadContext->impl->thread); MutexDeinit(&threadContext->impl->stateMutex); ConditionDeinit(&threadContext->impl->stateCond); diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 128160cad..b0b1a4ff0 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -233,7 +233,7 @@ void mGUIDeinit(struct mGUIRunner* runner) { ConditionWake(&runner->autosave.cond); MutexUnlock(&runner->autosave.mutex); - ThreadJoin(runner->autosave.thread); + ThreadJoin(&runner->autosave.thread); ConditionDeinit(&runner->autosave.cond); MutexDeinit(&runner->autosave.mutex); diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index 6dca713ca..29a3161e7 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -78,7 +78,7 @@ void mVideoThreadProxyDeinit(struct mVideoLogger* logger) { } MutexUnlock(&proxyRenderer->mutex); if (waiting) { - ThreadJoin(proxyRenderer->thread); + ThreadJoin(&proxyRenderer->thread); } RingFIFODeinit(&proxyRenderer->dirtyQueue); ConditionDeinit(&proxyRenderer->fromThreadCond); @@ -94,7 +94,7 @@ void _proxyThreadRecover(struct mVideoThreadProxy* proxyRenderer) { } RingFIFOClear(&proxyRenderer->dirtyQueue); MutexUnlock(&proxyRenderer->mutex); - ThreadJoin(proxyRenderer->thread); + ThreadJoin(&proxyRenderer->thread); proxyRenderer->threadState = PROXY_THREAD_IDLE; ThreadCreate(&proxyRenderer->thread, _proxyThread, proxyRenderer); } diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 8167b2b27..ea2bc6d45 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -958,7 +958,7 @@ int main() { Thread thread2; if (ThreadCreate(&thread2, _core2Test, NULL) == 0) { core2 = true; - ThreadJoin(thread2); + ThreadJoin(&thread2); } mGUIInit(&runner, "3ds"); diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index f5d8b1254..6df9181a5 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -420,7 +420,7 @@ void mPSP2UnloadROM(struct mGUIRunner* runner) { break; } audioContext.running = false; - ThreadJoin(audioThread); + ThreadJoin(&audioThread); } void mPSP2Paused(struct mGUIRunner* runner) { From b532a214cdffde7ad45989ac1418bf5b28e2a9aa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 18:44:57 -0700 Subject: [PATCH 311/429] GBA Video: Simplify priority --- src/gba/renderers/gl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 4dafd8d3d..985d23c2a 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,7 +13,7 @@ #include #include -#define FLAG_CONST "const vec4 flagCoeff = vec4(64., 32., 16., 1.);\n" +#define FLAG_CONST "const vec4 flagCoeff = vec4(32., 32., 16., 1.);\n" static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); @@ -549,6 +549,11 @@ static const char* const _finalize = " ivec4 bottomFlags = topFlags;\n" " vec4 windowFlags = texelFetch(window, ivec2(texCoord * float(scale)), 0);\n" " int layerWindow = int(windowFlags.x * 128.);\n" + " if ((layerWindow & 16) == 0) {\n" + " vec4 pix = texelFetch(layers[4], ivec2(texCoord * float(scale)), 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * float(scale)), 0) * flagCoeff);\n" + " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" + " }\n" " if ((layerWindow & 1) == 0) {\n" " vec4 pix = texelFetch(layers[0], ivec2(texCoord * float(scale)), 0);\n" " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" @@ -569,11 +574,6 @@ static const char* const _finalize = " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 16) == 0) {\n" - " vec4 pix = texelFetch(layers[4], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * float(scale)), 0) * flagCoeff);\n" - " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" - " }\n" " if ((layerWindow & 32) != 0) {\n" " topFlags.y &= ~1;\n" " }\n" @@ -1608,7 +1608,7 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glUniform1i(uniforms[GBA_GL_OBJ_CHARBASE], charBase); glUniform1i(uniforms[GBA_GL_OBJ_STRIDE], stride); glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); - glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c) << 3, + glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), (renderer->target1Obj || GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT) | (renderer->target2Obj * 2) | (renderer->blendEffect * 4), renderer->blda, GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_SEMITRANSPARENT); if (GBAObjAttributesAIsTransformed(sprite->a)) { @@ -1667,7 +1667,7 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa } else { glUniform2i(uniforms[GBA_GL_BG_MOSAIC], 0, 0); } - glUniform4i(uniforms[GBA_GL_BG_INFLAGS], (background->priority << 3) + (background->index << 1) + 1, + glUniform4i(uniforms[GBA_GL_BG_INFLAGS], background->priority, background->target1 | (background->target2 * 2) | (renderer->blendEffect * 4), renderer->blda, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); From b2450bac5e881de3ba64cf3c9718793ce6ef9873 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 19:00:48 -0700 Subject: [PATCH 312/429] GBA Video: Switch to using integer textures where applicable --- src/gba/renderers/gl.c | 144 ++++++++++++++++++----------------------- 1 file changed, 64 insertions(+), 80 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 985d23c2a..307b4aa11 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,8 +13,6 @@ #include #include -#define FLAG_CONST "const vec4 flagCoeff = vec4(32., 32., 16., 1.);\n" - static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer); @@ -59,6 +57,7 @@ static const GLchar* const _gles3Header = "#define OUT(n) layout(location = n)\n" "precision highp float;\n" "precision highp int;\n" + "precision highp sampler2D;\n" "precision highp isampler2D;\n"; static const GLchar* const _gl3Header = @@ -130,8 +129,7 @@ static const char* const _renderMode0 = "uniform ivec4 inflags;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" - "OUT(1) out vec4 flags;\n" - FLAG_CONST + "OUT(1) out ivec4 flags;\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -159,7 +157,7 @@ static const char* const _renderMode0 = " }\n" " int tile = int(map.a * 15.9) + int(map.b * 15.9) * 16 + (tileFlags & 0x3) * 256;\n" " color = renderTile(tile, int(map.r * 15.9), coord & 7);\n" - " flags = vec4(inflags) / flagCoeff;\n" + " flags = inflags;\n" "}"; static const char* const _fetchTileOverflow = @@ -275,8 +273,7 @@ static const char* const _renderMode2 = "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" - "OUT(1) out vec4 flags;\n" - FLAG_CONST + "OUT(1) out ivec4 flags;\n" "vec4 fetchTile(ivec2 coord);\n" "vec2 interpolate(ivec2 arr[4], float x);\n" @@ -315,7 +312,7 @@ static const char* const _renderMode2 = " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " color = fetchTile(ivec2(mixedTransform * incoord.x + mixedOffset));\n" - " flags = vec4(inflags) / flagCoeff;\n" + " flags = inflags;\n" "}"; static const struct GBAVideoGLUniform _uniformsMode35[] = { @@ -342,8 +339,7 @@ static const char* const _renderMode35 = "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" - "OUT(1) out vec4 flags;\n" - FLAG_CONST + "OUT(1) out ivec4 flags;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" @@ -374,7 +370,7 @@ static const char* const _renderMode35 = " ivec4 entry = ivec4(texelFetch(vram, ivec2(address & 255, address >> 8), 0) * 15.9);\n" " int sixteen = (entry.x << 12) | (entry.y << 8) | (entry.z << 4) | entry.w;\n" " color = vec4(float(sixteen & 0x1F) / 31., float((sixteen >> 5) & 0x1F) / 31., float((sixteen >> 10) & 0x1F) / 31., 1.);\n" - " flags = vec4(inflags) / flagCoeff;\n" + " flags = inflags;\n" "}"; static const struct GBAVideoGLUniform _uniformsMode4[] = { @@ -403,8 +399,7 @@ static const char* const _renderMode4 = "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" - "OUT(1) out vec4 flags;\n" - FLAG_CONST + "OUT(1) out ivec4 flags;\n" "vec2 interpolate(ivec2 arr[4], float x);\n" "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]);\n" @@ -436,7 +431,7 @@ static const char* const _renderMode4 = " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" " color = texelFetch(palette, entry, 0);\n" " color.a = 1.;\n" - " flags = vec4(inflags) / flagCoeff;\n" + " flags = inflags;\n" "}"; static const struct GBAVideoGLUniform _uniformsObj[] = { @@ -465,12 +460,11 @@ static const char* const _renderObj = "uniform ivec4 inflags;\n" "uniform mat2x2 transform;\n" "uniform ivec4 dims;\n" - "uniform vec4 objwin;\n" + "uniform ivec4 objwin;\n" "uniform ivec4 mosaic;\n" "OUT(0) out vec4 color;\n" - "OUT(1) out vec4 flags;\n" - "OUT(2) out vec3 window;\n" - FLAG_CONST + "OUT(1) out ivec4 flags;\n" + "OUT(2) out ivec3 window;\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -492,12 +486,12 @@ static const char* const _renderObj = " discard;\n" " }\n" " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" - " if (objwin.x > 0.) {\n" + " if (objwin.x > 0) {\n" " pix.a = 0.;\n" " }\n" " color = pix;\n" - " flags = vec4(inflags) / flagCoeff;\n" - " gl_FragDepth = flags.x;\n" + " flags = inflags;\n" + " gl_FragDepth = float(flags.x) / 16.;\n" " window = objwin.yzw;\n" "}"; @@ -517,11 +511,10 @@ static const char* const _finalize = "in vec2 texCoord;\n" "uniform int scale;\n" "uniform sampler2D layers[5];\n" - "uniform sampler2D flags[5];\n" - "uniform sampler2D window;\n" + "uniform isampler2D flags[5];\n" + "uniform isampler2D window;\n" "uniform sampler2D backdrop;\n" - "uniform sampler2D backdropFlags;\n" - FLAG_CONST + "uniform isampler2D backdropFlags;\n" "out vec4 color;\n" "void composite(vec4 pixel, ivec4 flags, inout vec4 topPixel, inout ivec4 topFlags, inout vec4 bottomPixel, inout ivec4 bottomFlags) {\n" @@ -545,45 +538,45 @@ static const char* const _finalize = "void main() {\n" " vec4 topPixel = texelFetch(backdrop, ivec2(0, texCoord.y), 0);\n" " vec4 bottomPixel = topPixel;\n" - " ivec4 topFlags = ivec4(texelFetch(backdropFlags, ivec2(0, texCoord.y), 0) * flagCoeff);\n" + " ivec4 topFlags = ivec4(texelFetch(backdropFlags, ivec2(0, texCoord.y), 0));\n" " ivec4 bottomFlags = topFlags;\n" - " vec4 windowFlags = texelFetch(window, ivec2(texCoord * float(scale)), 0);\n" - " int layerWindow = int(windowFlags.x * 128.);\n" - " if ((layerWindow & 16) == 0) {\n" + " ivec4 windowFlags = texelFetch(window, ivec2(texCoord * float(scale)), 0);\n" + " int layerWindow = windowFlags.x;\n" + " if ((layerWindow & 16) != 0) {\n" " vec4 pix = texelFetch(layers[4], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * float(scale)), 0) * flagCoeff);\n" + " ivec4 inflags = ivec4(texelFetch(flags[4], ivec2(texCoord * float(scale)), 0));\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 1) == 0) {\n" + " if ((layerWindow & 1) != 0) {\n" " vec4 pix = texelFetch(layers[0], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[0], ivec2(texCoord * float(scale)), 0).xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 2) == 0) {\n" + " if ((layerWindow & 2) != 0) {\n" " vec4 pix = texelFetch(layers[1], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[1], ivec2(texCoord * float(scale)), 0).xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 4) == 0) {\n" + " if ((layerWindow & 4) != 0) {\n" " vec4 pix = texelFetch(layers[2], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[2], ivec2(texCoord * float(scale)), 0).xyz.xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 8) == 0) {\n" + " if ((layerWindow & 8) != 0) {\n" " vec4 pix = texelFetch(layers[3], ivec2(texCoord * float(scale)), 0);\n" - " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * float(scale)), 0).xyz * flagCoeff.xyz, 0);\n" + " ivec4 inflags = ivec4(texelFetch(flags[3], ivec2(texCoord * float(scale)), 0).xyz, 0);\n" " composite(pix, inflags, topPixel, topFlags, bottomPixel, bottomFlags);\n" " }\n" - " if ((layerWindow & 32) != 0) {\n" + " if ((layerWindow & 32) == 0) {\n" " topFlags.y &= ~1;\n" " }\n" " if (((topFlags.y & 13) == 5 || topFlags.w > 0) && (bottomFlags.y & 2) == 2) {\n" " topPixel *= float(topFlags.z) / 16.;\n" - " topPixel += bottomPixel * windowFlags.y;\n" + " topPixel += bottomPixel * float(windowFlags.y) / 16.;\n" " } else if ((topFlags.y & 13) == 9) {\n" - " topPixel += (1. - topPixel) * windowFlags.z;\n" + " topPixel += (1. - topPixel) * float(windowFlags.z) / 16.;\n" " } else if ((topFlags.y & 13) == 13) {\n" - " topPixel -= topPixel * windowFlags.z;\n" + " topPixel -= topPixel * float(windowFlags.z) / 16.;\n" " }\n" " color = topPixel;\n" "}"; @@ -706,16 +699,16 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, glRenderer->scale); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA, GL_COLOR_ATTACHMENT2, glRenderer->scale); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT2, glRenderer->scale); _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_DEPTH], GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_ATTACHMENT, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_COLOR], GL_RGB, GL_COLOR_ATTACHMENT0, 0); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_FLAGS], GL_RGBA, GL_COLOR_ATTACHMENT1, 0); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_BACKDROP_FLAGS], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_WINDOW]); - _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT0, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OUTPUT]); _initFramebufferTexture(glRenderer->outputTex, GL_RGB, GL_COLOR_ATTACHMENT0, glRenderer->scale); @@ -755,7 +748,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glGenTextures(1, &bg->flags); glBindFramebuffer(GL_FRAMEBUFFER, bg->fbo); _initFramebufferTexture(bg->tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); - _initFramebufferTexture(bg->flags, GL_RGB, GL_COLOR_ATTACHMENT1, glRenderer->scale); + _initFramebufferTextureEx(bg->flags, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, 0); } @@ -1354,7 +1347,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f }); - glClearBufferfv(GL_COLOR, 1, (GLfloat[]) { 1.f, (glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4)) / 32.f, glRenderer->blda / 16.f, 0.f }); + glClearBufferiv(GL_COLOR, 1, (GLint[]) { 32, glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4), glRenderer->blda, 0 }); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); GBAVideoGLRendererDrawWindow(glRenderer, y); @@ -1632,11 +1625,11 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { - int window = ~renderer->objwin & 0x3F; - glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 1, window / 128.f, renderer->bldb / 16.f, renderer->bldy / 16.f); + int window = renderer->objwin & 0x3F; + glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 1, window, renderer->bldb, renderer->bldy); glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); } else { - glUniform4f(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); + glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } if (GBAObjAttributesAIsMosaic(sprite->a) && GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN) { @@ -1787,19 +1780,19 @@ void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -static void _scissorWindow(int start, int end, int y, int lines, int scale) { +static void _scissorWindow(struct GBAVideoGLRenderer* renderer, int window, int start, int end, int y, int lines) { if (start > end) { - _scissorWindow(start, GBA_VIDEO_HORIZONTAL_PIXELS * scale, y, lines, scale); - _scissorWindow(0, end, y, lines, scale); + _scissorWindow(renderer, window, start, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y, lines); + _scissorWindow(renderer, window, 0, end, y, lines); return; } glScissor(start, y, end - start, lines); - glClear(GL_COLOR_BUFFER_BIT); + glClearBufferiv(GL_COLOR, 0, (GLint[]) { window, renderer->bldb, renderer->bldy, 0 }); } -static void _scissorWindowN(const struct GBAVideoWindowRegion* region, const struct GBAVideoWindowRegion* v, const struct GBAVideoWindowRegion* y, int scale) { - int sdelta = region[0].start - region[1].start; - int edelta = region[0].end - region[1].end; +static void _scissorWindowN(struct GBAVideoGLRenderer* renderer, const struct GBAVideoGLWindowN* window, const struct GBAVideoWindowRegion* y, int dispcnt) { + int sdelta = window->h[0].start - window->h[1].start; + int edelta = window->h[0].end - window->h[1].end; int maxDelta = 0; if (sdelta > maxDelta) { maxDelta = sdelta; @@ -1813,49 +1806,40 @@ static void _scissorWindowN(const struct GBAVideoWindowRegion* region, const str } int startY = y->start; int endY = y->end; - if (startY < v->start) { - startY = v->start; + if (startY < window->v.start) { + startY = window->v.start; } - if (endY >= v->end) { - endY = v->end - 1; + if (endY >= window->v.end) { + endY = window->v.end - 1; } if (!(sdelta | edelta) || maxDelta >= GBA_VIDEO_VERTICAL_PIXELS / 2) { - _scissorWindow(region[0].start * scale, region[0].end * scale, startY * scale, (endY - startY + 1) * scale, scale); + _scissorWindow(renderer, window->control & dispcnt, window->h[0].start * renderer->scale, window->h[0].end * renderer->scale, startY * renderer->scale, (endY - startY + 1) * renderer->scale); } else { int i; - for (i = 0; i < scale * (endY - startY + 1); ++i) { - int start = region[1].start * scale + sdelta * i; - int end = region[1].end * scale + edelta * i; - _scissorWindow(start, end, startY * scale + i, 1, scale); + for (i = 0; i < renderer->scale * (endY - startY + 1); ++i) { + int start = window->h[1].start * renderer->scale + sdelta * i; + int end = window->h[1].end * renderer->scale + edelta * i; + _scissorWindow(renderer, window->control & dispcnt, start, end, startY * renderer->scale + i, 1); } } } -static void _clearWindow(GBAWindowControl window, int bldb, int bldy) { - window = ~window & 0x3F; - glClearColor(window / 128.f, bldb / 16.f, bldy / 16.f, 0); -} - void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; if (!(renderer->dispcnt & 0xE000)) { - _clearWindow(dispcnt, renderer->bldb, renderer->bldy); - _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale, renderer->scale); + _scissorWindow(renderer, dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); } else { - _clearWindow(renderer->winout & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindow(0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale, renderer->scale); + _scissorWindow(renderer, renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); struct GBAVideoWindowRegion yRegion = { y, renderer->firstY }; if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && renderer->firstY < renderer->winN[1].v.end) { - _clearWindow(renderer->winN[1].control & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindowN(renderer->winN[1].h, &renderer->winN[1].v, &yRegion, renderer->scale); + _scissorWindowN(renderer, &renderer->winN[1], &yRegion, dispcnt); } if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && renderer->firstY < renderer->winN[0].v.end) { - _clearWindow(renderer->winN[0].control & dispcnt, renderer->bldb, renderer->bldy); - _scissorWindowN(renderer->winN[0].h, &renderer->winN[0].v, &yRegion, renderer->scale); + _scissorWindowN(renderer, &renderer->winN[0], &yRegion, dispcnt); } } } From a64c38d3140d8a4015650096c0f61b7d4a9ee38f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 19:41:54 -0700 Subject: [PATCH 313/429] GBA Video: Fix GL OBJWIN --- src/gba/renderers/gl.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 307b4aa11..fea3229e8 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -486,9 +486,6 @@ static const char* const _renderObj = " discard;\n" " }\n" " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" - " if (objwin.x > 0) {\n" - " pix.a = 0.;\n" - " }\n" " color = pix;\n" " flags = inflags;\n" " gl_FragDepth = float(flags.x) / 16.;\n" @@ -1353,7 +1350,6 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { GBAVideoGLRendererDrawWindow(glRenderer, y); if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { int i; - glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); for (i = 0; i < glRenderer->oamMax; ++i) { struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i]; @@ -1625,10 +1621,12 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } glUniform4i(uniforms[GBA_GL_OBJ_DIMS], width, height, totalWidth, totalHeight); if (GBAObjAttributesAGetMode(sprite->a) == OBJ_MODE_OBJWIN) { + glDisable(GL_DEPTH_TEST); int window = renderer->objwin & 0x3F; glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 1, window, renderer->bldb, renderer->bldy); - glDrawBuffers(3, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }); + glDrawBuffers(3, (GLenum[]) { GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT2 }); } else { + glEnable(GL_DEPTH_TEST); glUniform4i(uniforms[GBA_GL_OBJ_OBJWIN], 0, 0, 0, 0); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); } From 585563eed76c8930b4d0f71d0ba14a371c84f48c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 19:44:21 -0700 Subject: [PATCH 314/429] Switch: Experimental support for hi-res mode --- src/gba/core.c | 16 +++---- src/platform/switch/main.c | 95 ++++++++++++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 27 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index e753971e6..53925cc52 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -18,7 +18,7 @@ #ifndef DISABLE_THREADING #include #endif -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) #include #endif #include @@ -130,7 +130,7 @@ struct mVideoLogContext; struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBAVideoGLRenderer glRenderer; #endif struct GBAVideoProxyRenderer proxyRenderer; @@ -180,7 +180,7 @@ static bool _GBACoreInit(struct mCore* core) { GBAVideoSoftwareRendererCreate(&gbacore->renderer); gbacore->renderer.outputBuffer = NULL; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) GBAVideoGLRendererCreate(&gbacore->glRenderer); gbacore->glRenderer.outputTex = -1; #endif @@ -229,7 +229,7 @@ static bool _GBACoreSupportsFeature(const struct mCore* core, enum mCoreFeature UNUSED(core); switch (feature) { case mCORE_FEATURE_OPENGL: -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) return true; #else return false; @@ -289,7 +289,7 @@ static void _GBACoreLoadConfig(struct mCore* core, const struct mCoreConfig* con } static void _GBACoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) { -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBACore* gbacore = (struct GBACore*) core; int scale = gbacore->glRenderer.scale; #else @@ -308,7 +308,7 @@ static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t s } static void _GBACoreSetVideoGLTex(struct mCore* core, unsigned texid) { -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBACore* gbacore = (struct GBACore*) core; gbacore->glRenderer.outputTex = texid; #else @@ -442,7 +442,7 @@ static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; if (gbacore->renderer.outputBuffer -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) || gbacore->glRenderer.outputTex != (unsigned) -1 #endif ) { @@ -451,7 +451,7 @@ static void _GBACoreReset(struct mCore* core) { renderer = &gbacore->renderer.d; } int fakeBool; -#ifdef BUILD_GLES2 +#if defined(BUILD_GLES2) || defined(BUILD_GLES3) if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { renderer = &gbacore->glRenderer.d; mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index cde839743..f8b635788 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -46,7 +46,7 @@ static const char* const _vertexShader = "varying vec2 texCoord;\n" "void main() {\n" - " vec2 ratio = insize / 256.0;\n" + " vec2 ratio = insize;\n" " vec2 scaledOffset = offset * dims;\n" " gl_Position = vec4(scaledOffset.x * 2.0 - dims.x, scaledOffset.y * -2.0 + dims.y, 0.0, 1.0);\n" " texCoord = offset * ratio;\n" @@ -91,6 +91,7 @@ static unsigned framecount = 0; static unsigned framecap = 10; static u32 vibrationDeviceHandles[4]; static HidVibrationValue vibrationStop = { .freq_low = 160.f, .freq_high = 320.f }; +static bool usePbo = true; static enum ScreenMode { SM_PA, @@ -110,9 +111,9 @@ static bool initEgl() { EGLConfig config; EGLint numConfigs; static const EGLint attributeList[] = { - EGL_RED_SIZE, 1, - EGL_GREEN_SIZE, 1, - EGL_BLUE_SIZE, 1, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, EGL_NONE }; eglChooseConfig(s_display, attributeList, &config, 1, &numConfigs); @@ -165,6 +166,7 @@ static void _mapKey(struct mInputMap* map, uint32_t binding, int nativeKey, enum } static void _drawStart(void) { + glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); } @@ -242,7 +244,15 @@ static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_L, GBA_KEY_L); _mapKey(&runner->core->inputMap, AUTO_INPUT, KEY_R, GBA_KEY_R); - runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + int fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "hwaccelVideo", &fakeBool) && fakeBool && runner->core->supportsFeature(runner->core, mCORE_FEATURE_OPENGL)) { + runner->core->setVideoGLTex(runner->core, tex); + usePbo = false; + } else { + runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + usePbo = true; + } + runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); @@ -281,6 +291,8 @@ static void _gameUnloaded(struct mGUIRunner* runner) { } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { + glViewport(0, 0, 1280, 720); + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -315,26 +327,33 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glUniform1i(texLocation, 0); glUniform2f(dimsLocation, aspectX, aspectY); - glUniform2f(insizeLocation, width, height); + if (usePbo) { + glUniform2f(insizeLocation, width / 256.f, height / 256.f); + } else { + glUniform2f(insizeLocation, 1, 1); + } if (!faded) { glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, 1.0f); } else { - glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); + glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glBindVertexArray(0); glUseProgram(0); + glDisable(GL_BLEND); } static void _prepareForFrame(struct mGUIRunner* runner) { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); - frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); - if (frameBuffer) { - runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + if (usePbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); + if (frameBuffer) { + runner->core->setVideoBuffer(runner->core, frameBuffer, 256); + } + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } static void _drawFrame(struct mGUIRunner* runner, bool faded) { @@ -346,13 +365,17 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + if (usePbo) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + + glBindTexture(GL_TEXTURE_2D, tex); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } else { + glBindTexture(GL_TEXTURE_2D, tex); + } _drawTex(runner, width, height, faded); @@ -689,8 +712,42 @@ int main(int argc, char* argv[]) { }, .nStates = 16 }, + { + .title = "GPU-accelerated renderer (experimental, requires game reload)", + .data = "hwaccelVideo", + .submenu = 0, + .state = 0, + .validStates = (const char*[]) { + "Off", + "On", + }, + .nStates = 2 + }, + { + .title = "Hi-res scaling (requires GPU rendering)", + .data = "videoScale", + .submenu = 0, + .state = 0, + .validStates = (const char*[]) { + "1x", + "2x", + "3x", + "4x", + "5x", + "6x", + }, + .stateMappings = (const struct GUIVariant[]) { + GUI_V_U(1), + GUI_V_U(2), + GUI_V_U(3), + GUI_V_U(4), + GUI_V_U(5), + GUI_V_U(6), + }, + .nStates = 6 + }, }, - .nConfigExtra = 2, + .nConfigExtra = 4, .setup = _setup, .teardown = NULL, .gameLoaded = _gameLoaded, From 5d05e38d27ccf8ec38865e04d2183735c49f9c9f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 19:44:58 -0700 Subject: [PATCH 315/429] Switch: Minor init/deinit fixes --- src/feature/gui/gui-runner.c | 1 + src/platform/switch/main.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index b0b1a4ff0..60a34d79e 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -219,6 +219,7 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) { #ifndef DISABLE_THREADING if (!runner->autosave.running) { runner->autosave.running = true; + runner->autosave.core = NULL; MutexInit(&runner->autosave.mutex); ConditionInit(&runner->autosave.cond); ThreadCreate(&runner->autosave.thread, mGUIAutosaveThread, &runner->autosave); diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index f8b635788..3afae461d 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -806,6 +806,7 @@ int main(int argc, char* argv[]) { psmExit(); audoutExit(); + romfsExit(); deinitEgl(); socketExit(); return 0; From f33a970304f0fb9e2ee852b3973bf07d8d45f441 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 21:37:18 -0700 Subject: [PATCH 316/429] Qt: Fix FPS target maxing out at 59.727 (fixes #1421) --- CHANGES | 1 + src/platform/qt/SettingsView.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 965aa411c..38fb49076 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) - Switch: Fix threading-related crash on second launch + - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index d8bb7e3e7..2739f589a 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -413,7 +413,7 @@ void SettingsView::updateConfig() { } double nativeFps = double(GBA_ARM7TDMI_FREQUENCY) / double(VIDEO_TOTAL_LENGTH); - if (nativeFps - m_ui.fpsTarget->value() < 0.0001) { + if (fabs(nativeFps - m_ui.fpsTarget->value()) < 0.0001) { m_controller->setOption("fpsTarget", QVariant(nativeFps)); } else { saveSetting("fpsTarget", m_ui.fpsTarget); From d025dd57041479d54dfec5238573a1cda877b866 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 26 May 2019 23:53:13 -0700 Subject: [PATCH 317/429] Switch: Dynamic display resizing --- CHANGES | 1 + src/platform/switch/gui-font.c | 2 +- src/platform/switch/main.c | 48 +++++++++++++++++++++++++++------- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 38fb49076..cf0bd2dbd 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,7 @@ Misc: - Qt: Increase maximum magnifications and scaling - Qt: Add native FPS button to settings view - Qt: Improve sync code + - Switch: Dynamic display resizing 0.7.2: (2019-05-25) Emulation fixes: diff --git a/src/platform/switch/gui-font.c b/src/platform/switch/gui-font.c index af08ece63..24d9f2c71 100644 --- a/src/platform/switch/gui-font.c +++ b/src/platform/switch/gui-font.c @@ -114,7 +114,7 @@ struct GUIFont* GUIFontCreate(void) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (!_loadTexture("romfs:/font-new.png")) { GUIFontDestroy(font); return NULL; diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 3afae461d..58eda8ecc 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -92,6 +92,9 @@ static unsigned framecap = 10; static u32 vibrationDeviceHandles[4]; static HidVibrationValue vibrationStop = { .freq_low = 160.f, .freq_high = 320.f }; static bool usePbo = true; +static u8 vmode; +static u32 vwidth; +static u32 vheight; static enum ScreenMode { SM_PA, @@ -291,15 +294,14 @@ static void _gameUnloaded(struct mGUIRunner* runner) { } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { - glViewport(0, 0, 1280, 720); - + glViewport(0, 1080 - vheight, vwidth, vheight); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUseProgram(program); glBindVertexArray(vao); - float aspectX = width / (float) runner->params.width; - float aspectY = height / (float) runner->params.height; + float aspectX = width / (float) vwidth; + float aspectY = height / (float) vheight; float max = 1.f; switch (screenMode) { case SM_PA: @@ -343,6 +345,7 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glBindVertexArray(0); glUseProgram(0); glDisable(GL_BLEND); + glViewport(0, 1080 - runner->params.height, runner->params.width, runner->params.height); } static void _prepareForFrame(struct mGUIRunner* runner) { @@ -432,6 +435,19 @@ static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { static bool _running(struct mGUIRunner* runner) { UNUSED(runner); + u8 newMode = appletGetOperationMode(); + if (newMode != vmode) { + if (newMode == AppletOperationMode_Docked) { + vwidth = 1920; + vheight = 1080; + } else { + vwidth = 1280; + vheight = 720; + } + nwindowSetCrop(nwindowGetDefault(), 0, 0, vwidth, vheight); + vmode = newMode; + } + return appletMainLoop(); } @@ -504,7 +520,14 @@ static int _batteryState(void) { return state; } +static void _guiPrepare(void) { + glViewport(0, 1080 - vheight, vwidth, vheight); +} + int main(int argc, char* argv[]) { + NWindow* window = nwindowGetDefault(); + nwindowSetDimensions(window, 1920, 1080); + socketInitializeDefault(); nxlinkStdio(); initEgl(); @@ -514,10 +537,17 @@ int main(int argc, char* argv[]) { struct GUIFont* font = GUIFontCreate(); - u32 width = 1280; - u32 height = 720; + vmode = appletGetOperationMode(); + if (vmode == AppletOperationMode_Docked) { + vwidth = 1920; + vheight = 1080; + } else { + vwidth = 1280; + vheight = 720; + } + nwindowSetCrop(window, 0, 0, vwidth, vheight); - glViewport(0, 0, width, height); + glViewport(0, 1080 - vheight, vwidth, vheight); glClearColor(0.f, 0.f, 0.f, 1.f); glGenTextures(1, &tex); @@ -626,12 +656,12 @@ int main(int argc, char* argv[]) { struct mGUIRunner runner = { .params = { - width, height, + 1280, 720, font, "/", _drawStart, _drawEnd, _pollInput, _pollCursor, _batteryState, - NULL, NULL, + _guiPrepare, NULL, }, .keySources = (struct GUIInputKeys[]) { { From 89c37820c6a30ec4a9eb9dd3ade851a712d8a607 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 00:06:10 -0700 Subject: [PATCH 318/429] Switch: Fix switching between PBO and FBO games --- src/platform/switch/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 58eda8ecc..c1e64e002 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -252,6 +252,9 @@ static void _setup(struct mGUIRunner* runner) { runner->core->setVideoGLTex(runner->core, tex); usePbo = false; } else { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); runner->core->setVideoBuffer(runner->core, frameBuffer, 256); usePbo = true; } @@ -557,7 +560,6 @@ int main(int argc, char* argv[]) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); From 67c3f386a4106d5d3017aea882f64dc0ae94a375 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 08:46:26 -0700 Subject: [PATCH 319/429] Switch: Pixel-accurate should default to aspect-full if it exceeds screen dimensions --- src/platform/switch/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index c1e64e002..3c86706ae 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -313,7 +313,10 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, } else { max = floor(1.0 / aspectY); } - break; + if (max >= 1.0) { + break; + } + // Fall through case SM_AF: if (aspectX > aspectY) { max = 1.0 / aspectX; From 47bf26ff73d9bdf8a044773b20fc816f6e823e7e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 11:37:09 -0700 Subject: [PATCH 320/429] OpenGL, Qt: Add interframe blending --- CHANGES | 1 + include/mgba/core/config.h | 1 + src/core/config.c | 3 ++ src/platform/opengl/gl.c | 48 ++++++++++++++++++++++++---- src/platform/opengl/gl.h | 3 +- src/platform/opengl/gles2.c | 36 ++++++++++++++++++--- src/platform/opengl/gles2.h | 1 + src/platform/qt/ConfigController.cpp | 1 + src/platform/qt/Display.cpp | 4 +++ src/platform/qt/Display.h | 3 ++ src/platform/qt/DisplayGL.cpp | 15 ++++++++- src/platform/qt/DisplayGL.h | 2 ++ src/platform/qt/DisplayQt.cpp | 21 +++++++++--- src/platform/qt/DisplayQt.h | 2 ++ src/platform/qt/SettingsView.cpp | 2 ++ src/platform/qt/SettingsView.ui | 11 +++++-- src/platform/qt/Window.cpp | 11 +++++++ src/platform/sdl/gl-sdl.c | 1 + src/platform/sdl/main.c | 1 + src/platform/sdl/main.h | 1 + src/platform/video-backend.h | 1 + 21 files changed, 151 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index cf0bd2dbd..e41f1f538 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ Features: - Map viewer supports bitmapped GBA modes - OpenGL renderer with high-resolution upscaling support - Experimental high level "XQ" audio for most GBA games + - Interframe blending for games that use flicker effects Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index b2439c41e..da664ed47 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -42,6 +42,7 @@ struct mCoreOptions { int height; bool lockAspectRatio; bool lockIntegerScaling; + bool interframeBlending; bool resampleVideo; bool suspendScreensaver; char* shader; diff --git a/src/core/config.c b/src/core/config.c index 932c904c2..cd173dfb3 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -354,6 +354,9 @@ void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts) if (_lookupIntValue(config, "lockIntegerScaling", &fakeBool)) { opts->lockIntegerScaling = fakeBool; } + if (_lookupIntValue(config, "interframeBlending", &fakeBool)) { + opts->interframeBlending = fakeBool; + } if (_lookupIntValue(config, "resampleVideo", &fakeBool)) { opts->resampleVideo = fakeBool; } diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index cfa05bea9..bb7afbc6f 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -24,13 +24,20 @@ static const GLint _glTexCoords[] = { static void mGLContextInit(struct VideoBackend* v, WHandle handle) { UNUSED(handle); struct mGLContext* context = (struct mGLContext*) v; - glGenTextures(1, &context->tex); - glBindTexture(GL_TEXTURE_2D, context->tex); + glGenTextures(2, context->tex); + glBindTexture(GL_TEXTURE_2D, context->tex[0]); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); #ifndef _WIN32 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #endif + glBindTexture(GL_TEXTURE_2D, context->tex[1]); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +#ifndef _WIN32 + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#endif + context->activeTex = 0; } static void mGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsigned height) { @@ -38,7 +45,20 @@ static void mGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsi v->width = width; v->height = height; - glBindTexture(GL_TEXTURE_2D, context->tex); + glBindTexture(GL_TEXTURE_2D, context->tex[0]); +#ifdef COLOR_16_BIT +#ifdef COLOR_5_6_5 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0); +#endif +#elif defined(__BIG_ENDIAN__) + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0); +#else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); +#endif + + glBindTexture(GL_TEXTURE_2D, context->tex[1]); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); @@ -54,7 +74,7 @@ static void mGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsi static void mGLContextDeinit(struct VideoBackend* v) { struct mGLContext* context = (struct mGLContext*) v; - glDeleteTextures(1, &context->tex); + glDeleteTextures(2, context->tex); } static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h) { @@ -96,7 +116,21 @@ void mGLContextDrawFrame(struct VideoBackend* v) { glOrtho(0, v->width, v->height, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glBindTexture(GL_TEXTURE_2D, context->tex); + if (v->interframeBlending) { + glEnable(GL_BLEND); + glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); + glBlendColor(1, 1, 1, 0.5); + glBindTexture(GL_TEXTURE_2D, context->tex[context->activeTex ^ 1]); + if (v->filter) { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + glBindTexture(GL_TEXTURE_2D, context->tex[context->activeTex]); if (v->filter) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -105,11 +139,13 @@ void mGLContextDrawFrame(struct VideoBackend* v) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisable(GL_BLEND); } void mGLContextPostFrame(struct VideoBackend* v, const void* frame) { struct mGLContext* context = (struct mGLContext*) v; - glBindTexture(GL_TEXTURE_2D, context->tex); + context->activeTex ^= 1; + glBindTexture(GL_TEXTURE_2D, context->tex[context->activeTex]); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v->width, v->height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame); diff --git a/src/platform/opengl/gl.h b/src/platform/opengl/gl.h index a6412e919..3ff528864 100644 --- a/src/platform/opengl/gl.h +++ b/src/platform/opengl/gl.h @@ -26,7 +26,8 @@ CXX_GUARD_START struct mGLContext { struct VideoBackend d; - GLuint tex; + GLuint tex[2]; + int activeTex; }; void mGLContextCreate(struct mGLContext*); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index a9034204f..d26bb7a2c 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -69,6 +69,16 @@ static const char* const _nullFragmentShader = " gl_FragColor = color;\n" "}"; +static const char* const _interframeFragmentShader = + "varying vec2 texCoord;\n" + "uniform sampler2D tex;\n" + + "void main() {\n" + " vec4 color = texture2D(tex, texCoord);\n" + " color.a = 0.5;\n" + " gl_FragColor = color;\n" + "}"; + static const GLfloat _vertices[] = { -1.f, -1.f, -1.f, 1.f, @@ -133,16 +143,15 @@ static void mGLES2ContextInit(struct VideoBackend* v, WHandle handle) { uniforms[3].max.fvec3[2] = 1.0f; mGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, false, uniforms, 4); mGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, false, 0, 0); + mGLES2ShaderInit(&context->interframeShader, 0, _interframeFragmentShader, -1, -1, false, 0, 0); if (context->initialShader.vao != (GLuint) -1) { glBindVertexArray(context->initialShader.vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glEnableVertexAttribArray(context->initialShader.positionLocation); - glVertexAttribPointer(context->initialShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); glBindVertexArray(context->finalShader.vao); glBindBuffer(GL_ARRAY_BUFFER, context->vbo); - glEnableVertexAttribArray(context->finalShader.positionLocation); - glVertexAttribPointer(context->finalShader.positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(context->interframeShader.vao); + glBindBuffer(GL_ARRAY_BUFFER, context->vbo); glBindVertexArray(0); } @@ -177,6 +186,7 @@ static void mGLES2ContextDeinit(struct VideoBackend* v) { glDeleteBuffers(1, &context->vbo); mGLES2ShaderDeinit(&context->initialShader); mGLES2ShaderDeinit(&context->finalShader); + mGLES2ShaderDeinit(&context->interframeShader); free(context->initialShader.uniforms); } @@ -327,6 +337,11 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) { context->finalShader.filter = v->filter; _drawShader(context, &context->initialShader); + if (v->interframeBlending) { + context->interframeShader.blend = true; + glViewport(0, 0, viewport[2], viewport[3]); + _drawShader(context, &context->interframeShader); + } size_t n; for (n = 0; n < context->nShaders; ++n) { glViewport(0, 0, viewport[2], viewport[3]); @@ -334,6 +349,13 @@ void mGLES2ContextDrawFrame(struct VideoBackend* v) { } glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); _drawShader(context, &context->finalShader); + if (v->interframeBlending) { + context->interframeShader.blend = false; + glBindTexture(GL_TEXTURE_2D, context->tex); + _drawShader(context, &context->initialShader); + glViewport(0, 0, viewport[2], viewport[3]); + _drawShader(context, &context->interframeShader); + } glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(0); if (context->finalShader.vao != (GLuint) -1) { @@ -391,6 +413,8 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (shader->width > 0 && shader->height > 0) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, shader->width, shader->height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); } glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shader->tex, 0); @@ -448,6 +472,10 @@ void mGLES2ShaderInit(struct mGLES2Shader* shader, const char* vs, const char* f const GLubyte* extensions = glGetString(GL_EXTENSIONS); if (shaderBuffer[0] == _gles2Header || version[0] >= '3' || (extensions && strstr((const char*) extensions, "_vertex_array_object") != NULL)) { glGenVertexArrays(1, &shader->vao); + glBindVertexArray(shader->vao); + glEnableVertexAttribArray(shader->positionLocation); + glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glBindVertexArray(0); } else { shader->vao = -1; } diff --git a/src/platform/opengl/gles2.h b/src/platform/opengl/gles2.h index 59f3b7996..0655151e0 100644 --- a/src/platform/opengl/gles2.h +++ b/src/platform/opengl/gles2.h @@ -82,6 +82,7 @@ struct mGLES2Context { struct mGLES2Shader initialShader; struct mGLES2Shader finalShader; + struct mGLES2Shader interframeShader; struct mGLES2Shader* shaders; size_t nShaders; diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 969f0609f..d0794fa94 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -119,6 +119,7 @@ ConfigController::ConfigController(QObject* parent) m_opts.useBios = true; m_opts.suspendScreensaver = true; m_opts.lockAspectRatio = true; + m_opts.interframeBlending = false; mCoreConfigLoad(&m_config); mCoreConfigLoadDefaults(&m_config, &m_opts); mCoreConfigSetDefaultIntValue(&m_config, "sgb.borders", 1); diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index afc0cc5cf..6a4d2bcb5 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -70,6 +70,10 @@ void Display::lockIntegerScaling(bool lock) { m_lockIntegerScaling = lock; } +void Display::interframeBlending(bool lock) { + m_interframeBlending = lock; +} + void Display::filter(bool filter) { m_filter = filter; } diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index f00bdb2b1..a5c1d227a 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -42,6 +42,7 @@ public: bool isAspectRatioLocked() const { return m_lockAspectRatio; } bool isIntegerScalingLocked() const { return m_lockIntegerScaling; } + bool hasInterframeBlending() const { return m_interframeBlending; } bool isFiltered() const { return m_filter; } virtual void startDrawing(std::shared_ptr) = 0; @@ -62,6 +63,7 @@ public slots: virtual void forceDraw() = 0; virtual void lockAspectRatio(bool lock); virtual void lockIntegerScaling(bool lock); + virtual void interframeBlending(bool enable); virtual void filter(bool filter); virtual void framePosted() = 0; virtual void setShaders(struct VDir*) = 0; @@ -83,6 +85,7 @@ private: MessagePainter m_messagePainter; bool m_lockAspectRatio = false; bool m_lockIntegerScaling = false; + bool m_interframeBlending = false; bool m_filter = false; QTimer m_mouseTimer; }; diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 135e591f8..709abd146 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -102,6 +102,7 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { lockAspectRatio(isAspectRatioLocked()); lockIntegerScaling(isIntegerScalingLocked()); + interframeBlending(hasInterframeBlending()); filter(isFiltered()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatioF()); @@ -164,6 +165,13 @@ void DisplayGL::lockIntegerScaling(bool lock) { } } +void DisplayGL::interframeBlending(bool enable) { + Display::interframeBlending(enable); + if (m_drawThread) { + QMetaObject::invokeMethod(m_painter, "interframeBlending", Q_ARG(bool, enable)); + } +} + void DisplayGL::filter(bool filter) { Display::filter(filter); if (m_drawThread) { @@ -276,6 +284,7 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent m_backend->user = this; m_backend->filter = false; m_backend->lockAspectRatio = false; + m_backend->interframeBlending = false; for (int i = 0; i < 2; ++i) { m_free.append(new uint32_t[1024 * 2048]); @@ -344,6 +353,10 @@ void PainterGL::lockIntegerScaling(bool lock) { resize(m_size); } +void PainterGL::interframeBlending(bool enable) { + m_backend->interframeBlending = enable; +} + void PainterGL::filter(bool filter) { m_backend->filter = filter; if (m_started && !m_active) { @@ -546,7 +559,7 @@ int PainterGL::glTex() { #endif #ifdef BUILD_GL mGLContext* glBackend = reinterpret_cast(m_backend); - return glBackend->tex; + return glBackend->tex[0]; #else return -1; #endif diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 2c54934f4..ff6d647b0 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -52,6 +52,7 @@ public slots: void forceDraw() override; void lockAspectRatio(bool lock) override; void lockIntegerScaling(bool lock) override; + void interframeBlending(bool enable) override; void filter(bool filter) override; void framePosted() override; void setShaders(struct VDir*) override; @@ -96,6 +97,7 @@ public slots: void resize(const QSize& size); void lockAspectRatio(bool lock); void lockIntegerScaling(bool lock); + void interframeBlending(bool enable); void filter(bool filter); void resizeContext(); diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 6043a7399..e3c227c1b 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -25,6 +25,7 @@ void DisplayQt::startDrawing(std::shared_ptr controller) { m_width = size.width(); m_height = size.height(); m_backing = std::move(QImage()); + m_oldBacking = std::move(QImage()); m_isDrawing = true; m_context = controller; } @@ -44,6 +45,11 @@ void DisplayQt::lockIntegerScaling(bool lock) { update(); } +void DisplayQt::interframeBlending(bool lock) { + Display::interframeBlending(lock); + update(); +} + void DisplayQt::filter(bool filter) { Display::filter(filter); update(); @@ -55,6 +61,7 @@ void DisplayQt::framePosted() { if (const_cast(m_backing).bits() == reinterpret_cast(buffer)) { return; } + m_oldBacking = m_backing; #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 m_backing = QImage(reinterpret_cast(buffer), m_width, m_height, QImage::Format_RGB16); @@ -65,6 +72,9 @@ void DisplayQt::framePosted() { m_backing = QImage(reinterpret_cast(buffer), m_width, m_height, QImage::Format_ARGB32); m_backing = m_backing.convertToFormat(QImage::Format_RGB32); #endif +#ifndef COLOR_5_6_5 + m_backing = m_backing.rgbSwapped(); +#endif } void DisplayQt::resizeContext() { @@ -75,6 +85,7 @@ void DisplayQt::resizeContext() { if (m_width != size.width() || m_height != size.height()) { m_width = size.width(); m_height = size.height(); + m_oldBacking = std::move(QImage()); m_backing = std::move(QImage()); } } @@ -98,13 +109,15 @@ void DisplayQt::paintEvent(QPaintEvent*) { ds.setWidth(ds.width() - ds.width() % m_width); ds.setHeight(ds.height() - ds.height() % m_height); } +#warning TODO: Add interframeBlending QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2); QRect full(origin, ds); -#ifdef COLOR_5_6_5 + if (hasInterframeBlending()) { + painter.drawImage(full, m_oldBacking, QRect(0, 0, m_width, m_height)); + painter.setOpacity(0.5); + } painter.drawImage(full, m_backing, QRect(0, 0, m_width, m_height)); -#else - painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, m_width, m_height)); -#endif + painter.setOpacity(1); messagePainter()->paint(&painter); } diff --git a/src/platform/qt/DisplayQt.h b/src/platform/qt/DisplayQt.h index 2d242fbe5..5795ccb45 100644 --- a/src/platform/qt/DisplayQt.h +++ b/src/platform/qt/DisplayQt.h @@ -30,6 +30,7 @@ public slots: void forceDraw() override { update(); } void lockAspectRatio(bool lock) override; void lockIntegerScaling(bool lock) override; + void interframeBlending(bool enable) override; void filter(bool filter) override; void framePosted() override; void setShaders(struct VDir*) override {} @@ -44,6 +45,7 @@ private: unsigned m_width; unsigned m_height; QImage m_backing{nullptr}; + QImage m_oldBacking{nullptr}; std::shared_ptr m_context = nullptr; }; diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 2739f589a..75a639b8a 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -377,6 +377,7 @@ void SettingsView::updateConfig() { saveSetting("autofireThreshold", m_ui.autofireThreshold); saveSetting("lockAspectRatio", m_ui.lockAspectRatio); saveSetting("lockIntegerScaling", m_ui.lockIntegerScaling); + saveSetting("interframeBlending", m_ui.interframeBlending); saveSetting("volume", m_ui.volume); saveSetting("mute", m_ui.mute); saveSetting("fastForwardVolume", m_ui.volumeFf); @@ -534,6 +535,7 @@ void SettingsView::reloadConfig() { loadSetting("autofireThreshold", m_ui.autofireThreshold); loadSetting("lockAspectRatio", m_ui.lockAspectRatio); loadSetting("lockIntegerScaling", m_ui.lockIntegerScaling); + loadSetting("interframeBlending", m_ui.interframeBlending); loadSetting("volume", m_ui.volume, 0x100); loadSetting("mute", m_ui.mute, false); loadSetting("fastForwardVolume", m_ui.volumeFf, m_ui.volume->value()); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 1f51e5abf..d674dd15d 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -7,7 +7,7 @@ 0 0 849 - 753 + 797 @@ -445,7 +445,7 @@ - + Bilinear filtering @@ -459,6 +459,13 @@ + + + + Interframe blending + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 7cdc73a4d..ded67df94 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -719,6 +719,7 @@ void Window::gameStarted() { m_screenWidget->setDimensions(size.width(), size.height()); m_config->updateOption("lockIntegerScaling"); m_config->updateOption("lockAspectRatio"); + m_config->updateOption("interframeBlending"); if (m_savedScale > 0) { resizeFrame(size * m_savedScale); } @@ -883,6 +884,7 @@ void Window::reloadDisplayDriver() { const mCoreOptions* opts = m_config->options(); m_display->lockAspectRatio(opts->lockAspectRatio); + m_display->interframeBlending(opts->interframeBlending); m_display->filter(opts->resampleVideo); #if defined(BUILD_GL) || defined(BUILD_GLES2) if (opts->shader) { @@ -1340,6 +1342,15 @@ void Window::setupMenu(QMenuBar* menubar) { }, this); m_config->updateOption("lockIntegerScaling"); + ConfigOption* interframeBlending = m_config->addOption("interframeBlending"); + interframeBlending->addBoolean(tr("Interframe blending"), &m_actions, "av"); + interframeBlending->connect([this](const QVariant& value) { + if (m_display) { + m_display->interframeBlending(value.toBool()); + } + }, this); + m_config->updateOption("interframeBlending"); + ConfigOption* resampleVideo = m_config->addOption("resampleVideo"); resampleVideo->addBoolean(tr("Bilinear filtering"), &m_actions, "av"); resampleVideo->connect([this](const QVariant& value) { diff --git a/src/platform/sdl/gl-sdl.c b/src/platform/sdl/gl-sdl.c index 38e0a2164..539ef88d0 100644 --- a/src/platform/sdl/gl-sdl.c +++ b/src/platform/sdl/gl-sdl.c @@ -35,6 +35,7 @@ bool mSDLGLInit(struct mSDLRenderer* renderer) { renderer->gl.d.user = renderer; renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio; renderer->gl.d.lockIntegerScaling = renderer->lockIntegerScaling; + renderer->gl.d.interframeBlending = renderer->interframeBlending; renderer->gl.d.filter = renderer->filter; renderer->gl.d.swap = mSDLGLCommonSwap; renderer->gl.d.init(&renderer->gl.d, 0); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index d82d4fb24..0bb340c23 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -136,6 +136,7 @@ int main(int argc, char** argv) { renderer.lockAspectRatio = renderer.core->opts.lockAspectRatio; renderer.lockIntegerScaling = renderer.core->opts.lockIntegerScaling; + renderer.interframeBlending = renderer.core->opts.interframeBlending; renderer.filter = renderer.core->opts.resampleVideo; if (!mSDLInit(&renderer)) { diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 5f286d5fd..d6148babf 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -64,6 +64,7 @@ struct mSDLRenderer { bool lockAspectRatio; bool lockIntegerScaling; + bool interframeBlending; bool filter; #ifdef BUILD_GL diff --git a/src/platform/video-backend.h b/src/platform/video-backend.h index f45a56dc5..6d714629a 100644 --- a/src/platform/video-backend.h +++ b/src/platform/video-backend.h @@ -36,6 +36,7 @@ struct VideoBackend { bool filter; bool lockAspectRatio; bool lockIntegerScaling; + bool interframeBlending; }; struct VideoShader { From 0f99419487ab56de9f004cf57a0f2ef97d7b6c13 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 11:46:13 -0700 Subject: [PATCH 321/429] Qt: Fix loading shaders while game is not running --- include/mgba/internal/gba/renderers/gl.h | 1 + src/platform/qt/DisplayGL.cpp | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 7194fcfe9..1d4627e9a 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -45,6 +45,7 @@ struct GBAVideoGLBackground { GLuint fbo; GLuint tex; GLuint flags; + GLuint scanlineTex; unsigned index; int enabled; diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 709abd146..ddf4c211c 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -49,7 +49,6 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) #endif auto version = m_gl->format().version(); QStringList extensions = QString(reinterpret_cast(glGetString(GL_EXTENSIONS))).split(' '); - m_gl->doneCurrent(); if ((version == qMakePair(2, 1) && !extensions.contains("GL_ARB_framebuffer_object")) || version == qMakePair(2, 0)) { QSurfaceFormat newFormat(format); @@ -279,7 +278,6 @@ PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent m_shader.preprocessShader = static_cast(&reinterpret_cast(m_backend)->initialShader); } #endif - m_gl->doneCurrent(); m_backend->user = this; m_backend->filter = false; From 053b571bbdc3131e96b625ed336e30e8f4193138 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Mon, 27 May 2019 21:45:14 +0200 Subject: [PATCH 322/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 744 +++++++++++++++++----------------- 1 file changed, 365 insertions(+), 379 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index d410f9102..b4a54aa7a 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -1289,22 +1289,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -2861,42 +2861,47 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::LogController - + [%1] %2: %3 [%1] %2: %3 - + + An error occurred + Ein Fehler ist aufgetreten + + + DEBUG DEBUG - + STUB STUB - + INFO INFO - + WARN WARN - + ERROR ERROR - + FATAL FATAL - + GAME ERROR GAME ERROR @@ -2904,47 +2909,47 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::MapView - + Map Addr. Map-Addr. - + Mirror Spiegel - + None Keiner - + Both Beidseitig - + Horizontal Horizontal - + Vertical Vertikal - + Export map Map exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 Fehler beim Öffnen der Ausgabe-PNG-Datei: %1 @@ -3156,59 +3161,59 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::SettingsView - - + + Qt Multimedia Qt Multimedia - + SDL SDL - + Software (Qt) Software (Qt) - + OpenGL OpenGL - + OpenGL (force version 1.x) OpenGL (erzwinge Version 1.x) - + None (Still Image) Keiner (Standbild) - + Keyboard Tastatur - + Controllers Gamepads - + Shortcuts Tastenkürzel - - + + Shaders Shader - + Select BIOS BIOS auswählen @@ -3247,19 +3252,19 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - QGBA::ShortcutController + QGBA::ShortcutModel - + Action Aktion - + Keyboard Tastatur - + Gamepad Gamepad @@ -3285,103 +3290,103 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) - - - + + + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3390,117 +3395,117 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren @@ -3510,513 +3515,453 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Savestate (aktueller Zustand) &laden - - F10 - F10 - - - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - - Shift+F10 - Umschalt+F10 - - - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - - F11 - F11 - - - + Undo save state Speichern des Savestate rückgängig machen - - Shift+F11 - Umschalt+F11 - - - - + + State &%1 Savestate &%1 - - F%1 - F%1 - - - - Shift+F%1 - Umschalt+F%1 - - - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - - Ctrl+R - Strg+R - - - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - - Ctrl+P - Strg+P - - - + &Next frame &Nächstes Bild - - Ctrl+N - Strg+N - - - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - - Shift+Tab - Umschalt+Tab - - - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - - ~ - ~ - - - + Step backwards Schrittweiser Rücklauf - - Ctrl+B - Strg+B - - - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Solar-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - - %1x - %1x - - - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - - Record output... - Ausgabe aufzeichen... - - - + Record GIF... GIF aufzeichen... - - Record video log... - Video-Log aufzeichnen... - - - - Stop video log - Video-Log beenden - - - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + Game &Pak sensors... Game &Pak-Sensoren... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... - + Select folder Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + About... Über... - + + %1× + %1x + + + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + + Record A/V... + Audio/Video aufzeichnen... + + + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + + Record debug video log... + Video-Protokoll aufzeichnen... + + + + Stop debug video log + Aufzeichnen des Video-Protokolls beenden + + + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -4195,524 +4140,565 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Emulation - + + Enhancements + Verbesserungen + + + Paths Verzeichnisse - + Logging Protokoll - + Game Boy Game Boy - + Audio driver: Audio-Treiber: - + Audio buffer: Audio-Puffer: - - + + 1536 1536 - + 512 512 - + 768 768 - + 1024 1024 - + 2048 2048 - + 3072 3072 - + 4096 4096 - + samples Samples - + Sample rate: Abtastrate: - - + + 44100 44100 - + 22050 22050 - + 32000 32000 - + 48000 48000 - + Hz Hz - + Volume: Lautstärke: - - + + Mute Stummschalten - + Fast forward volume: Vorspul-Lautstärke: - + Display driver: Anzeige-Treiber: - + Frameskip: Frameskip: - + Skip every Überspringe - - + + frames Bild(er) - + FPS target: Bildwiederholrate: - + frames per second Bilder pro Sekunde - + Sync: Synchronisierung: - + Video Video - + Audio Audio - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Erzwinge pixelgenaue Skalierung (Integer scaling) - + + Native (59.7275) + Nativ (59.7275) + + + Language Sprache - + English Englisch - + List view Listenansicht - + Tree view Baumansicht - + Show FPS in title bar Bildwiederholrate in der Titelleiste anzeigen - + Automatically save cheats Cheats automatisch speichern - + Automatically load cheats Cheats automatisch laden - + Automatically save state Zustand (Savestate) automatisch speichern - + Automatically load state Zustand (Savestate) automatisch laden - + Enable Discord Rich Presence Discord-Integration aktivieren - + + Video renderer: + Video-Renderer: + + + + Software + Software + + + + OpenGL + OpenGL + + + + OpenGL enhancements + OpenGL-Verbesserungen + + + + High-resolution scale: + Hochauflösende Skalierung: + + + + XQ GBA audio (experimental) + XQ GBA-Audio (experimentell) + + + Cheats Cheats - + Log to file In Datei protokollieren - + Log to console Auf die Konsole protokollieren - + Select Log File Protokoll-Datei auswählen - + Camera: Kamera: - - - + + + Autodetect Automatisch erkennen - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + Use GBC colors in GB games Verwende GBC-Farben in GB-Spielen - + Super Game Boy borders Super Game Boy-Rahmen - + Game Boy model: Game Boy-Modell: - + Super Game Boy model: Super Game Boy-Modell: - + Game Boy Color model: Game Boy Color-Modell: - + Camera driver: Kamera-Treiber: - + Library: Bibliothek: - + Show when no game open Anzeigen, wenn kein Spiel geöffnet ist - + Clear cache Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - + + + + + + + + Browse Durchsuchen - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - + + × × - + Unbounded unbegrenzt - + Suspend screensaver Bildschirmschoner deaktivieren - + BIOS BIOS - + Pause when inactive Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen - + Allow opposing input directions Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren - + Bilinear filtering Bilineare Filterung - + Rewind history: Rücklauf-Verlauf: - + Idle loops: Leerlaufprozesse: - + Savestate extra data: Zusätzliche Savestate-Daten: - + Load extra data: Lade zusätzliche Daten: - + Autofire interval: Autofeuer-Intervall: - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches From 5b66a455b0226aa84fcd953c7ebdb70850971b46 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 14:05:11 -0700 Subject: [PATCH 323/429] Switch: Interframe blending --- src/platform/switch/main.c | 65 +++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 3c86706ae..33e2b9298 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #define AUTO_INPUT 0x4E585031 #define SAMPLES 0x400 @@ -67,11 +68,13 @@ static GLuint program; static GLuint vbo; static GLuint vao; static GLuint pbo; +static GLuint copyFbo; static GLuint texLocation; static GLuint dimsLocation; static GLuint insizeLocation; static GLuint colorLocation; static GLuint tex; +static GLuint oldTex; static color_t* frameBuffer; static struct mAVStream stream; @@ -95,6 +98,7 @@ static bool usePbo = true; static u8 vmode; static u32 vwidth; static u32 vheight; +static bool interframeBlending = false; static enum ScreenMode { SM_PA, @@ -130,7 +134,8 @@ static bool initEgl() { } EGLint contextAttributeList[] = { - EGL_CONTEXT_CLIENT_VERSION, 3, + EGL_CONTEXT_MAJOR_VERSION, 3, + EGL_CONTEXT_MINOR_VERSION, 1, EGL_NONE }; s_context = eglCreateContext(s_display, config, EGL_NO_CONTEXT, contextAttributeList); @@ -283,6 +288,10 @@ static void _gameLoaded(struct mGUIRunner* runner) { screenMode = mode; } + int fakeBool; + mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); + interframeBlending = fakeBool; + rumble.up = 0; rumble.down = 0; } @@ -296,7 +305,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) { hidSendVibrationValues(vibrationDeviceHandles, values, 4); } -static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded) { +static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded, bool blendTop) { glViewport(0, 1080 - vheight, vwidth, vheight); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -341,9 +350,9 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glUniform2f(insizeLocation, 1, 1); } if (!faded) { - glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, blendTop ? 0.5f : 1.0f); } else { - glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, 0.8f); + glUniform4f(colorLocation, 0.8f, 0.8f, 0.8f, blendTop ? 0.4f : 0.8f); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -355,6 +364,20 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, } static void _prepareForFrame(struct mGUIRunner* runner) { + if (interframeBlending) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, copyFbo); + glReadBuffer(GL_COLOR_ATTACHMENT0); + int width, height; + int format; + glBindTexture(GL_TEXTURE_2D, tex); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + glBindTexture(GL_TEXTURE_2D, oldTex); + glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, width, height, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + } + if (usePbo) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); @@ -382,11 +405,19 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { glBindTexture(GL_TEXTURE_2D, tex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } else { + } else if (!interframeBlending) { glBindTexture(GL_TEXTURE_2D, tex); } - _drawTex(runner, width, height, faded); + if (interframeBlending) { + glBindTexture(GL_TEXTURE_2D, oldTex); + _drawTex(runner, width, height, faded, false); + glBindTexture(GL_TEXTURE_2D, tex); + _drawTex(runner, width, height, faded, true); + } else { + _drawTex(runner, width, height, faded, false); + } + HidVibrationValue values[4]; if (rumble.up) { @@ -412,7 +443,7 @@ static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, un glBindTexture(GL_TEXTURE_2D, tex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - _drawTex(runner, width, height, faded); + _drawTex(runner, width, height, faded, false); } static uint16_t _pollGameInput(struct mGUIRunner* runner) { @@ -556,20 +587,36 @@ int main(int argc, char* argv[]) { glViewport(0, 1080 - vheight, vwidth, vheight); glClearColor(0.f, 0.f, 0.f, 1.f); - glGenTextures(1, &tex); glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glGenTextures(1, &oldTex); + glBindTexture(GL_TEXTURE_2D, oldTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 256 * 4, NULL, GL_STREAM_DRAW); frameBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 256 * 4, GL_MAP_WRITE_BIT); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glGenFramebuffers(1, ©Fbo); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, oldTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindFramebuffer(GL_READ_FRAMEBUFFER, copyFbo); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + program = glCreateProgram(); GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); @@ -829,7 +876,9 @@ int main(int argc, char* argv[]) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteBuffers(1, &pbo); + glDeleteFramebuffers(1, ©Fbo); glDeleteTextures(1, &tex); + glDeleteTextures(1, &oldTex); glDeleteBuffers(1, &vbo); glDeleteProgram(program); glDeleteVertexArrays(1, &vao); From ebe765d1cdff19d02a7b59527cb1263cc17ad4e6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 14:22:11 -0700 Subject: [PATCH 324/429] GBA Video: Fix alpha issues on GL output texture --- src/gba/renderers/gl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index fea3229e8..18e056c2f 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -568,12 +568,12 @@ static const char* const _finalize = " topFlags.y &= ~1;\n" " }\n" " if (((topFlags.y & 13) == 5 || topFlags.w > 0) && (bottomFlags.y & 2) == 2) {\n" - " topPixel *= float(topFlags.z) / 16.;\n" - " topPixel += bottomPixel * float(windowFlags.y) / 16.;\n" + " topPixel.rgb *= float(topFlags.z) / 16.;\n" + " topPixel.rgb += bottomPixel.rgb * float(windowFlags.y) / 16.;\n" " } else if ((topFlags.y & 13) == 9) {\n" - " topPixel += (1. - topPixel) * float(windowFlags.z) / 16.;\n" + " topPixel.rgb += (1. - topPixel.rgb) * float(windowFlags.z) / 16.;\n" " } else if ((topFlags.y & 13) == 13) {\n" - " topPixel -= topPixel * float(windowFlags.z) / 16.;\n" + " topPixel.rgb -= topPixel.rgb * float(windowFlags.z) / 16.;\n" " }\n" " color = topPixel;\n" "}"; @@ -1343,7 +1343,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { glScissor(0, glRenderer->firstY, 1, y - glRenderer->firstY + 1); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); - glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 0.f }); + glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 1.f }); glClearBufferiv(GL_COLOR, 1, (GLint[]) { 32, glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4), glRenderer->blda, 0 }); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); From 7349a1dab348698f22306478cbab1f5d629a48bb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 14:45:02 -0700 Subject: [PATCH 325/429] CHANGES: Fix bugzilla link --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index e41f1f538..b4180940d 100644 --- a/CHANGES +++ b/CHANGES @@ -56,7 +56,7 @@ Emulation fixes: - GBA Memory: Prevent writing to mirrored BG VRAM (fixes mgba.io/i/743) - GBA Video: Fix scanline cache with scale factor change edge cases - GBA Video: Fix sprite mosaic clamping (fixes mgba.io/i/1008) - - GBA Video: Implement mosaic on transformed sprites (fixes mgba.io/b/9) + - GBA Video: Implement mosaic on transformed sprites (fixes mgba.io/b/5) Other fixes: - 3DS: Ensure core 2 can be used for threaded renderer (fixes mgba.io/i/1371) - All: Fix several memory leaks From ba2d702fb567134cf5a3b36b9360a57852ad12b7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 16:22:37 -0700 Subject: [PATCH 326/429] GBA Video: Replace palette texture with uniforms --- include/mgba/internal/gba/renderers/gl.h | 5 +- src/gba/renderers/gl.c | 64 ++++++++---------------- 2 files changed, 23 insertions(+), 46 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 1d4627e9a..f597ed83b 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -146,10 +146,7 @@ struct GBAVideoGLRenderer { GLuint outputTex; -#ifdef BUILD_GLES3 - uint16_t shadowPalette[512]; -#endif - GLuint paletteTex; + GLint shadowPalette[512]; bool paletteDirty; GLuint vramTex; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 18e056c2f..09320a9e6 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -52,9 +52,12 @@ struct GBAVideoGLUniform { int type; }; +#define PALETTE_ENTRY "#define PALETTE_ENTRY(x) (vec3((ivec3(0x1F, 0x3E0, 0x7C00) & (x)) >> ivec3(0, 5, 10)) / 31.)\n" + static const GLchar* const _gles3Header = "#version 300 es\n" "#define OUT(n) layout(location = n)\n" + PALETTE_ENTRY "precision highp float;\n" "precision highp int;\n" "precision highp sampler2D;\n" @@ -63,6 +66,7 @@ static const GLchar* const _gles3Header = static const GLchar* const _gl3Header = "#version 130\n" "#define OUT(n)\n" + PALETTE_ENTRY "precision highp float;\n"; static const char* const _vertexShader = @@ -82,11 +86,11 @@ static const char* const _renderTile16 = " int address = charBase + tile * 16 + (localCoord.x >> 2) + (localCoord.y << 1);\n" " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" " int entry = int(halfrow[3 - (localCoord.x & 3)] * 15.9);\n" - " vec4 color = texelFetch(palette, ivec2(entry, paletteId), 0);\n" " if (entry == 0) {\n" " discard;\n" " }\n" - " color.a = 1.;\n" + " int paletteEntry = palette[paletteId * 16 + entry];\n" + " vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " return color;\n" "}"; @@ -96,11 +100,11 @@ static const char* const _renderTile256 = " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" " int entry = int(halfrow[3 - 2 * (localCoord.x & 1)] * 15.9);\n" " int pal2 = int(halfrow[2 - 2 * (localCoord.x & 1)] * 15.9);\n" - " vec4 color = texelFetch(palette, ivec2(entry, pal2 + (paletteId & 16)), 0);\n" " if ((pal2 | entry) == 0) {\n" " discard;\n" " }\n" - " color.a = 1.;\n" + " int paletteEntry = palette[pal2 * 16 + entry];\n" + " vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " return color;\n" "}"; @@ -121,7 +125,7 @@ static const struct GBAVideoGLUniform _uniformsMode0[] = { static const char* const _renderMode0 = "in vec2 texCoord;\n" "uniform sampler2D vram;\n" - "uniform sampler2D palette;\n" + "uniform int palette[256];\n" "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" @@ -264,7 +268,7 @@ static const char* const _interpolate = static const char* const _renderMode2 = "in vec2 texCoord;\n" "uniform sampler2D vram;\n" - "uniform sampler2D palette;\n" + "uniform int palette[256];\n" "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" @@ -288,11 +292,11 @@ static const char* const _renderMode2 = " vec4 halfrow = texelFetch(vram, ivec2(address & 255, address >> 8), 0);\n" " int entry = int(halfrow[3 - ((coord.x >> 7) & 2)] * 15.9);\n" " int pal2 = int(halfrow[2 - ((coord.x >> 7) & 2)] * 15.9);\n" - " vec4 color = texelFetch(palette, ivec2(entry, pal2), 0);\n" " if ((pal2 | entry) == 0) {\n" " discard;\n" " }\n" - " color.a = 1.;\n" + " int paletteEntry = palette[pal2 * 16 + entry];\n" + " vec4 color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " return color;\n" "}\n" @@ -391,7 +395,7 @@ static const struct GBAVideoGLUniform _uniformsMode4[] = { static const char* const _renderMode4 = "in vec2 texCoord;\n" "uniform sampler2D vram;\n" - "uniform sampler2D palette;\n" + "uniform int palette[256];\n" "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" @@ -429,8 +433,8 @@ static const char* const _renderMode4 = " int address = charBase + (coord.x >> 8) + (coord.y >> 8) * size.x;\n" " vec4 twoEntries = texelFetch(vram, ivec2((address >> 1) & 255, address >> 9), 0);\n" " ivec2 entry = ivec2(twoEntries[3 - 2 * (address & 1)] * 15.9, twoEntries[2 - 2 * (address & 1)] * 15.9);\n" - " color = texelFetch(palette, entry, 0);\n" - " color.a = 1.;\n" + " int paletteEntry = palette[entry.y * 16 + entry.x];\n" + " color = vec4(PALETTE_ENTRY(paletteEntry), 1.);\n" " flags = inflags;\n" "}"; @@ -453,7 +457,7 @@ static const struct GBAVideoGLUniform _uniformsObj[] = { static const char* const _renderObj = "in vec2 texCoord;\n" "uniform sampler2D vram;\n" - "uniform sampler2D palette;\n" + "uniform int palette[256];\n" "uniform int charBase;\n" "uniform int stride;\n" "uniform int localPalette;\n" @@ -485,7 +489,7 @@ static const char* const _renderObj = " if ((coord & ~(dims.xy - 1)) != ivec2(0, 0)) {\n" " discard;\n" " }\n" - " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, 16 + localPalette, coord & 7);\n" + " vec4 pix = renderTile((coord.x >> 3) + (coord.y >> 3) * stride, localPalette, coord & 7);\n" " color = pix;\n" " flags = inflags;\n" " gl_FragDepth = float(flags.x) / 16.;\n" @@ -670,11 +674,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glGenFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); glGenTextures(GBA_GL_TEX_MAX, glRenderer->layers); - glGenTextures(1, &glRenderer->paletteTex); - glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glGenTextures(1, &glRenderer->vramTex); glBindTexture(GL_TEXTURE_2D, glRenderer->vramTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -822,7 +821,6 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { } glDeleteFramebuffers(GBA_GL_FBO_MAX, glRenderer->fbo); glDeleteTextures(GBA_GL_TEX_MAX, glRenderer->layers); - glDeleteTextures(1, &glRenderer->paletteTex); glDeleteTextures(1, &glRenderer->vramTex); glDeleteBuffers(1, &glRenderer->vbo); @@ -846,14 +844,7 @@ void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer) { void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; -#ifdef BUILD_GLES3 - int i; - for (i = 0; i < 512; ++i) { - renderer->writePalette(renderer, i << 1, renderer->palette[i]); - } -#else glRenderer->paletteDirty = true; -#endif glRenderer->vramDirty = 0xFFFFFF; glRenderer->firstAffine = -1; glRenderer->firstY = -1; @@ -876,12 +867,8 @@ void GBAVideoGLRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) void GBAVideoGLRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; -#ifdef BUILD_GLES3 - glRenderer->shadowPalette[address >> 1] = ((value & 0x1F) << 11) | ((value & 0x3E0) << 1) | ((value & 0x7C00) >> 10); -#else UNUSED(address); UNUSED(value); -#endif glRenderer->paletteDirty = true; } @@ -1269,12 +1256,9 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->regsDirty = 0; if (glRenderer->paletteDirty) { - glBindTexture(GL_TEXTURE_2D, glRenderer->paletteTex); -#ifdef BUILD_GLES3 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 16, 32, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, glRenderer->shadowPalette); -#else - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 16, 32, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, glRenderer->d.palette); -#endif + for (i = 0; i < 512; ++i) { + glRenderer->shadowPalette[i] = glRenderer->d.palette[i]; + } glRenderer->paletteDirty = false; } @@ -1588,12 +1572,10 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB glBindVertexArray(shader->vao); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); glUniform1i(uniforms[GBA_GL_OBJ_VRAM], 0); - glUniform1i(uniforms[GBA_GL_OBJ_PALETTE], 1); + glUniform1iv(uniforms[GBA_GL_OBJ_PALETTE], 256, &renderer->shadowPalette[256]); glUniform1i(uniforms[GBA_GL_OBJ_CHARBASE], charBase); glUniform1i(uniforms[GBA_GL_OBJ_STRIDE], stride); glUniform1i(uniforms[GBA_GL_OBJ_LOCALPALETTE], GBAObjAttributesCGetPalette(sprite->c)); @@ -1648,11 +1630,9 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, renderer->vramTex); - glActiveTexture(GL_TEXTURE0 + 1); - glBindTexture(GL_TEXTURE_2D, renderer->paletteTex); glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); glUniform1i(uniforms[GBA_GL_BG_VRAM], 0); - glUniform1i(uniforms[GBA_GL_BG_PALETTE], 1); + glUniform1iv(uniforms[GBA_GL_OBJ_PALETTE], 256, renderer->shadowPalette); if (background->mosaic) { glUniform2i(uniforms[GBA_GL_BG_MOSAIC], GBAMosaicControlGetBgV(renderer->mosaic) + 1, GBAMosaicControlGetBgH(renderer->mosaic) + 1); } else { From ef2a2e5002e14598d7f67e8dc47c7ffc20b79242 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 20:48:42 -0700 Subject: [PATCH 327/429] GBA Video: Move window drawing to a shader --- include/mgba/internal/gba/renderers/gl.h | 11 +- src/gba/renderers/gl.c | 300 ++++++++++++----------- 2 files changed, 171 insertions(+), 140 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index f597ed83b..13502686b 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -112,6 +112,12 @@ enum { GBA_GL_OBJ_OBJWIN, GBA_GL_OBJ_MOSAIC, + GBA_GL_WIN_DISPCNT = 2, + GBA_GL_WIN_BLEND, + GBA_GL_WIN_FLAGS, + GBA_GL_WIN_WIN0, + GBA_GL_WIN_WIN1, + GBA_GL_FINALIZE_SCALE = 2, GBA_GL_FINALIZE_LAYERS, GBA_GL_FINALIZE_FLAGS, @@ -157,6 +163,7 @@ struct GBAVideoGLRenderer { struct GBAVideoGLShader bgShader[6]; struct GBAVideoGLShader objShader[2]; + struct GBAVideoGLShader windowShader; struct GBAVideoGLShader finalizeShader; GBARegisterDISPCNT dispcnt; @@ -173,11 +180,13 @@ struct GBAVideoGLRenderer { GBAMosaicControl mosaic; struct GBAVideoGLWindowN { - struct GBAVideoWindowRegion h[2]; + struct GBAVideoWindowRegion h; struct GBAVideoWindowRegion v; GBAWindowControl control; } winN[2]; + GLint winNHistory[2][GBA_VIDEO_VERTICAL_PIXELS * 4]; + GBAWindowControl winout; GBAWindowControl objwin; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 09320a9e6..94e8228f9 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -496,6 +496,75 @@ static const char* const _renderObj = " window = objwin.yzw;\n" "}"; +static const struct GBAVideoGLUniform _uniformsWindow[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "dispcnt", GBA_GL_WIN_DISPCNT, }, + { "blend", GBA_GL_WIN_BLEND, }, + { "flags", GBA_GL_WIN_FLAGS, }, + { "win0", GBA_GL_WIN_WIN0, }, + { "win1", GBA_GL_WIN_WIN1, }, + { 0 } +}; + +static const char* const _renderWindow = + "in vec2 texCoord;\n" + "uniform int dispcnt;\n" + "uniform ivec2 blend;\n" + "uniform ivec3 flags;\n" + "uniform ivec4 win0[160];\n" + "uniform ivec4 win1[160];\n" + "OUT(0) out ivec3 window;\n" + + "void crop(vec4 windowParams, int flags, inout ivec3 windowFlags) {\n" + " bvec4 compare = lessThan(texCoord.xxyy, windowParams);\n" + " compare = equal(compare, bvec4(true, false, true, false));\n" + " if (any(compare)) {\n" + " vec2 h = windowParams.xy;\n" + " vec2 v = windowParams.zw;\n" + " if (v.x > v.y) {\n" + " if (compare.z && compare.w) {\n" + " return;\n" + " }\n" + " } else if (compare.z || compare.w) {\n" + " return;\n" + " }\n" + " if (h.x > h.y) {\n" + " if (compare.x && compare.y) {\n" + " return;\n" + " }\n" + " } else if (compare.x || compare.y) {\n" + " return;\n" + " }\n" + " }\n" + " windowFlags.x = flags;\n" + "}\n" + + "vec4 interpolate(ivec4 win[160]) {\n" + " vec4 bottom = vec4(win[int(texCoord.y) - 1]);\n" + " vec4 top = vec4(win[int(texCoord.y)]);\n" + " if (distance(top, bottom) > 40.) {\n" + " return top;\n" + " }\n" + " return vec4(mix(bottom.xy, top.xy, fract(texCoord.y)), top.zw);\n" + "}\n" + + "void main() {\n" + " int dispflags = (dispcnt & 0x1F) | 0x20;\n" + " if ((dispcnt & 0xE0) == 0) {\n" + " window = ivec3(dispflags, blend);\n" + " } else {\n" + " ivec3 windowFlags = ivec3(flags.z, blend);\n" + " if ((dispcnt & 0x40) != 0) { \n" + " crop(interpolate(win1), flags.y, windowFlags);\n" + " }\n" + " if ((dispcnt & 0x20) != 0) { \n" + " crop(interpolate(win0), flags.x, windowFlags);\n" + " }\n" + " window = windowFlags;\n" + " }\n" + "}\n"; + static const struct GBAVideoGLUniform _uniformsFinalize[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, @@ -805,6 +874,12 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); #endif + shaderBuffer[1] = _renderWindow; + _compileShader(glRenderer, &glRenderer->windowShader, shaderBuffer, 2, vs, _uniformsWindow, log); +#ifndef BUILD_GLES3 + glBindFragDataLocation(glRenderer->windowShader.program, 0, "window"); +#endif + shaderBuffer[1] = _finalize; _compileShader(glRenderer, &glRenderer->finalizeShader, shaderBuffer, 2, vs, _uniformsFinalize, log); @@ -878,14 +953,16 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, GBAVideoCacheWriteVideoRegister(renderer->cache, address, value); } - bool dirty = true; + bool dirty = false; switch (address) { case REG_DISPCNT: value &= 0xFFF7; + dirty = true; break; case REG_BG0CNT: case REG_BG1CNT: value &= 0xDFFF; + dirty = true; break; case REG_BG0HOFS: case REG_BG0VOFS: @@ -896,87 +973,126 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, case REG_BG3HOFS: case REG_BG3VOFS: value &= 0x01FF; + dirty = true; break; case REG_BG2PA: glRenderer->bg[2].affine.dx = value; - dirty = false; break; case REG_BG2PB: glRenderer->bg[2].affine.dmx = value; - dirty = false; break; case REG_BG2PC: glRenderer->bg[2].affine.dy = value; - dirty = false; break; case REG_BG2PD: glRenderer->bg[2].affine.dmy = value; - dirty = false; break; case REG_BG2X_LO: GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[2], value); - dirty = false; break; case REG_BG2X_HI: GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[2], value); - dirty = false; break; case REG_BG2Y_LO: GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[2], value); - dirty = false; break; case REG_BG2Y_HI: GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[2], value); - dirty = false; break; case REG_BG3PA: glRenderer->bg[3].affine.dx = value; - dirty = false; break; case REG_BG3PB: glRenderer->bg[3].affine.dmx = value; - dirty = false; break; case REG_BG3PC: glRenderer->bg[3].affine.dy = value; - dirty = false; break; case REG_BG3PD: glRenderer->bg[3].affine.dmy = value; - dirty = false; break; case REG_BG3X_LO: GBAVideoGLRendererWriteBGX_LO(&glRenderer->bg[3], value); - dirty = false; break; case REG_BG3X_HI: GBAVideoGLRendererWriteBGX_HI(&glRenderer->bg[3], value); - dirty = false; break; case REG_BG3Y_LO: GBAVideoGLRendererWriteBGY_LO(&glRenderer->bg[3], value); - dirty = false; break; case REG_BG3Y_HI: GBAVideoGLRendererWriteBGY_HI(&glRenderer->bg[3], value); - dirty = false; break; case REG_BLDALPHA: value &= 0x1F1F; + dirty = true; break; case REG_BLDY: value &= 0x1F; if (value > 0x10) { value = 0x10; } + dirty = true; + break; + case REG_WIN0H: + glRenderer->winN[0].h.end = value; + glRenderer->winN[0].h.start = value >> 8; + if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h.start > glRenderer->winN[0].h.end) { + glRenderer->winN[0].h.start = 0; + } + if (glRenderer->winN[0].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[0].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[0].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + } + } + break; + case REG_WIN1H: + glRenderer->winN[1].h.end = value; + glRenderer->winN[1].h.start = value >> 8; + if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h.start > glRenderer->winN[1].h.end) { + glRenderer->winN[1].h.start = 0; + } + if (glRenderer->winN[1].h.end > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h.end = GBA_VIDEO_HORIZONTAL_PIXELS; + if (glRenderer->winN[1].h.start > GBA_VIDEO_HORIZONTAL_PIXELS) { + glRenderer->winN[1].h.start = GBA_VIDEO_HORIZONTAL_PIXELS; + } + } + break; + case REG_WIN0V: + glRenderer->winN[0].v.end = value; + glRenderer->winN[0].v.start = value >> 8; + if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[0].v.start > glRenderer->winN[0].v.end) { + glRenderer->winN[0].v.start = 0; + } + if (glRenderer->winN[0].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[0].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; + } + } + break; + case REG_WIN1V: + glRenderer->winN[1].v.end = value; + glRenderer->winN[1].v.start = value >> 8; + if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[1].v.start > glRenderer->winN[1].v.end) { + glRenderer->winN[1].v.start = 0; + } + if (glRenderer->winN[1].v.end > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[1].v.end = GBA_VIDEO_VERTICAL_PIXELS; + if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { + glRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; + } + } break; case REG_WININ: - value &= 0x3F3F; - break; case REG_WINOUT: value &= 0x3F3F; + dirty = true; break; default: + dirty = true; break; } if (glRenderer->shadowRegs[address >> 1] == value) { @@ -1050,58 +1166,6 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t case REG_BLDY: glRenderer->bldy = value; break; - case REG_WIN0H: - glRenderer->winN[0].h[0].end = value; - glRenderer->winN[0].h[0].start = value >> 8; - if (glRenderer->winN[0].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[0].h[0].start > glRenderer->winN[0].h[0].end) { - glRenderer->winN[0].h[0].start = 0; - } - if (glRenderer->winN[0].h[0].end > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[0].h[0].end = GBA_VIDEO_HORIZONTAL_PIXELS; - if (glRenderer->winN[0].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[0].h[0].start = GBA_VIDEO_HORIZONTAL_PIXELS; - } - } - break; - case REG_WIN1H: - glRenderer->winN[1].h[0].end = value; - glRenderer->winN[1].h[0].start = value >> 8; - if (glRenderer->winN[1].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS && glRenderer->winN[1].h[0].start > glRenderer->winN[1].h[0].end) { - glRenderer->winN[1].h[0].start = 0; - } - if (glRenderer->winN[1].h[0].end > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[1].h[0].end = GBA_VIDEO_HORIZONTAL_PIXELS; - if (glRenderer->winN[1].h[0].start > GBA_VIDEO_HORIZONTAL_PIXELS) { - glRenderer->winN[1].h[0].start = GBA_VIDEO_HORIZONTAL_PIXELS; - } - } - break; - case REG_WIN0V: - glRenderer->winN[0].v.end = value; - glRenderer->winN[0].v.start = value >> 8; - if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[0].v.start > glRenderer->winN[0].v.end) { - glRenderer->winN[0].v.start = 0; - } - if (glRenderer->winN[0].v.end > GBA_VIDEO_VERTICAL_PIXELS) { - glRenderer->winN[0].v.end = GBA_VIDEO_VERTICAL_PIXELS; - if (glRenderer->winN[0].v.start > GBA_VIDEO_VERTICAL_PIXELS) { - glRenderer->winN[0].v.start = GBA_VIDEO_VERTICAL_PIXELS; - } - } - break; - case REG_WIN1V: - glRenderer->winN[1].v.end = value; - glRenderer->winN[1].v.start = value >> 8; - if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS && glRenderer->winN[1].v.start > glRenderer->winN[1].v.end) { - glRenderer->winN[1].v.start = 0; - } - if (glRenderer->winN[1].v.end > GBA_VIDEO_VERTICAL_PIXELS) { - glRenderer->winN[1].v.end = GBA_VIDEO_VERTICAL_PIXELS; - if (glRenderer->winN[1].v.start > GBA_VIDEO_VERTICAL_PIXELS) { - glRenderer->winN[1].v.start = GBA_VIDEO_VERTICAL_PIXELS; - } - } - break; case REG_WININ: glRenderer->winN[0].control = value; glRenderer->winN[1].control = value >> 8; @@ -1223,8 +1287,6 @@ static bool _needsVramUpload(struct GBAVideoGLRenderer* renderer, int y) { void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; - memcpy(&glRenderer->affine[0][y], &glRenderer->bg[2].affine, sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->affine[1][y], &glRenderer->bg[3].affine, sizeof(struct GBAVideoGLAffine)); if (GBARegisterDISPCNTGetMode(glRenderer->dispcnt) != 0) { if (glRenderer->firstAffine < 0) { glRenderer->firstAffine = y; @@ -1243,9 +1305,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->firstY = y; } - memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); - memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); - int i; for (i = 0; i < 0x30; ++i) { if (!(glRenderer->regsDirty & (1ULL << i))) { @@ -1255,6 +1314,17 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->regsDirty = 0; + memcpy(&glRenderer->affine[0][y], &glRenderer->bg[2].affine, sizeof(struct GBAVideoGLAffine)); + memcpy(&glRenderer->affine[1][y], &glRenderer->bg[3].affine, sizeof(struct GBAVideoGLAffine)); + glRenderer->winNHistory[0][y * 4 + 0] = glRenderer->winN[0].h.start; + glRenderer->winNHistory[0][y * 4 + 1] = glRenderer->winN[0].h.end; + glRenderer->winNHistory[0][y * 4 + 2] = glRenderer->winN[0].v.start; + glRenderer->winNHistory[0][y * 4 + 3] = glRenderer->winN[0].v.end; + glRenderer->winNHistory[1][y * 4 + 0] = glRenderer->winN[1].h.start; + glRenderer->winNHistory[1][y * 4 + 1] = glRenderer->winN[1].h.end; + glRenderer->winNHistory[1][y * 4 + 2] = glRenderer->winN[1].v.start; + glRenderer->winNHistory[1][y * 4 + 3] = glRenderer->winN[1].v.end; + if (glRenderer->paletteDirty) { for (i = 0; i < 512; ++i) { glRenderer->shadowPalette[i] = glRenderer->d.palette[i]; @@ -1284,9 +1354,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } if (y == 0) { - memcpy(&glRenderer->winN[0].h[1], &glRenderer->winN[0].h[0], sizeof(struct GBAVideoWindowRegion)); - memcpy(&glRenderer->winN[1].h[1], &glRenderer->winN[1].h[0], sizeof(struct GBAVideoWindowRegion)); - glDisable(GL_SCISSOR_TEST); glClearColor(0, 0, 0, 0); #ifdef BUILD_GLES3 @@ -1758,68 +1825,23 @@ void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } -static void _scissorWindow(struct GBAVideoGLRenderer* renderer, int window, int start, int end, int y, int lines) { - if (start > end) { - _scissorWindow(renderer, window, start, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, y, lines); - _scissorWindow(renderer, window, 0, end, y, lines); - return; - } - glScissor(start, y, end - start, lines); - glClearBufferiv(GL_COLOR, 0, (GLint[]) { window, renderer->bldb, renderer->bldy, 0 }); -} - -static void _scissorWindowN(struct GBAVideoGLRenderer* renderer, const struct GBAVideoGLWindowN* window, const struct GBAVideoWindowRegion* y, int dispcnt) { - int sdelta = window->h[0].start - window->h[1].start; - int edelta = window->h[0].end - window->h[1].end; - int maxDelta = 0; - if (sdelta > maxDelta) { - maxDelta = sdelta; - } else if (-sdelta > maxDelta) { - maxDelta = -sdelta; - } - if (edelta > maxDelta) { - maxDelta = edelta; - } else if (-edelta > maxDelta) { - maxDelta = -edelta; - } - int startY = y->start; - int endY = y->end; - if (startY < window->v.start) { - startY = window->v.start; - } - if (endY >= window->v.end) { - endY = window->v.end - 1; - } - if (!(sdelta | edelta) || maxDelta >= GBA_VIDEO_VERTICAL_PIXELS / 2) { - _scissorWindow(renderer, window->control & dispcnt, window->h[0].start * renderer->scale, window->h[0].end * renderer->scale, startY * renderer->scale, (endY - startY + 1) * renderer->scale); - } else { - int i; - for (i = 0; i < renderer->scale * (endY - startY + 1); ++i) { - int start = window->h[1].start * renderer->scale + sdelta * i; - int end = window->h[1].end * renderer->scale + edelta * i; - _scissorWindow(renderer, window->control & dispcnt, start, end, startY * renderer->scale + i, 1); - } - } -} - void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { + const struct GBAVideoGLShader* shader = &renderer->windowShader; + const GLuint* uniforms = shader->uniforms; glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_WINDOW]); - int dispcnt = ((renderer->dispcnt >> 8) & 0x1F) | 0x20; - if (!(renderer->dispcnt & 0xE000)) { - _scissorWindow(renderer, dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); - } else { - _scissorWindow(renderer, renderer->winout & dispcnt, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->firstY * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); - struct GBAVideoWindowRegion yRegion = { - y, - renderer->firstY - }; - if (GBARegisterDISPCNTIsWin1Enable(renderer->dispcnt) && y >= renderer->winN[1].v.start && renderer->firstY < renderer->winN[1].v.end) { - _scissorWindowN(renderer, &renderer->winN[1], &yRegion, dispcnt); - } - if (GBARegisterDISPCNTIsWin0Enable(renderer->dispcnt) && y >= renderer->winN[0].v.start && renderer->firstY < renderer->winN[0].v.end) { - _scissorWindowN(renderer, &renderer->winN[0], &yRegion, dispcnt); - } - } + glViewport(0, 0, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, GBA_VIDEO_VERTICAL_PIXELS * renderer->scale); + glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, renderer->scale * (y - renderer->firstY + 1)); + glUseProgram(shader->program); + glBindVertexArray(shader->vao); + glUniform2i(uniforms[GBA_GL_VS_LOC], y - renderer->firstY + 1, renderer->firstY); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); + glUniform1i(uniforms[GBA_GL_WIN_DISPCNT], renderer->dispcnt >> 8); + glUniform2i(uniforms[GBA_GL_WIN_BLEND], renderer->bldb, renderer->bldy); + glUniform3i(uniforms[GBA_GL_WIN_FLAGS], renderer->winN[0].control, renderer->winN[1].control, renderer->winout); + glUniform4iv(uniforms[GBA_GL_WIN_WIN0], GBA_VIDEO_VERTICAL_PIXELS, renderer->winNHistory[0]); + glUniform4iv(uniforms[GBA_GL_WIN_WIN1], GBA_VIDEO_VERTICAL_PIXELS, renderer->winNHistory[1]); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } #endif From a6c503af69c9e9293492898359d21ad00a164d6f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2019 21:30:12 -0700 Subject: [PATCH 328/429] Res: Update nointro.dat --- res/nointro.dat | 18932 +++++++++++++++++++++++++--------------------- 1 file changed, 10371 insertions(+), 8561 deletions(-) diff --git a/res/nointro.dat b/res/nointro.dat index 00252a22f..0c9a52a11 100644 --- a/res/nointro.dat +++ b/res/nointro.dat @@ -1,35765 +1,37575 @@ clrmamepro ( name "Nintendo - Game Boy Advance" description "Nintendo - Game Boy Advance" - version 20151214-211324 - comment "no-intro | www.no-intro.org" + version 20190519-045003 + author "aci68, Bent, BigFred, C. V. Reynolds, chillerecke, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, Jack, jimmsu, kazumi213, Money_114, omonim2007, Powerpuff, PPLToast, relax, RetroGamer, Rifu, SonGoku, Tauwasser, Vallaine01, xuom2, zg" + homepage No-Intro + url "http://www.no-intro.org" ) game ( name "[BIOS] Game Boy Advance (Japan) (Debug Version)" description "[BIOS] Game Boy Advance (Japan) (Debug Version)" - rom ( name "[BIOS] Game Boy Advance (Japan) (Debug Version).gba" size 16384 crc 15E1F676 md5 E60E599135009129B288988A1CBA91DF sha1 AA98A2AD32B86106340665D1222D7D973A1361C7 ) + rom ( name "[BIOS] Game Boy Advance (Japan) (Debug Version).gba" size 16384 crc 15e1f676 sha1 AA98A2AD32B86106340665D1222D7D973A1361C7 ) ) game ( - name "[BIOS] Game Boy Advance (World) (TS2)" - description "[BIOS] Game Boy Advance (World) (TS2)" - rom ( name "[BIOS] Game Boy Advance (World) (TS2).gba" size 16384 crc 81977335 md5 A860E8C0B6D573D191E4EC7DB1B1E4F6 sha1 300C20DF6731A33952DED8C436F7F186D25D3492 flags verified ) + name "[BIOS] Game Boy Advance (World)" + description "[BIOS] Game Boy Advance (World)" + rom ( name "[BIOS] Game Boy Advance (World).gba" size 16384 crc 81977335 sha1 300C20DF6731A33952DED8C436F7F186D25D3492 flags verified ) ) game ( name "007 - Everything or Nothing (USA, Europe) (En,Fr,De)" description "007 - Everything or Nothing (USA, Europe) (En,Fr,De)" - rom ( name "007 - Everything or Nothing (USA, Europe) (En,Fr,De).gba" size 8388608 crc 9D4F1E18 md5 B63B2244EDC2385AE1EAB9C8EE448C6F sha1 FC6163F99B71B05C10686A0D29010B31274E1DC4 flags verified ) + rom ( name "007 - Everything or Nothing (USA, Europe) (En,Fr,De).gba" size 8388608 crc 9d4f1e18 sha1 FC6163F99B71B05C10686A0D29010B31274E1DC4 flags verified ) ) game ( name "007 - Everything or Nothing (Japan)" description "007 - Everything or Nothing (Japan)" - rom ( name "007 - Everything or Nothing (Japan).gba" size 8388608 crc CAF2E99F md5 55354D9E3BC9C1FA682B5110E5ED1544 sha1 6E4E9BE9A07580EF267BE9C2EA1BD0730B3BE44A ) + rom ( name "007 - Everything or Nothing (Japan).gba" size 8388608 crc caf2e99f sha1 6E4E9BE9A07580EF267BE9C2EA1BD0730B3BE44A ) ) game ( name "007 - NightFire (USA, Europe) (En,Fr,De)" description "007 - NightFire (USA, Europe) (En,Fr,De)" - rom ( name "007 - NightFire (USA, Europe) (En,Fr,De).gba" size 8388608 crc 56C83C16 md5 71259FB2BF7ADEB9B5D8C84619A2531E sha1 F4363923181B71448DDD6E28AC72D30B3ECFC019 flags verified ) + rom ( name "007 - NightFire (USA, Europe) (En,Fr,De).gba" size 8388608 crc 56c83c16 sha1 F4363923181B71448DDD6E28AC72D30B3ECFC019 flags verified ) ) game ( name "2 Disney Games - Disney Sports - Football + Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It)" description "2 Disney Games - Disney Sports - Football + Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Disney Games - Disney Sports - Football + Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc C8CDB4ED md5 65F0E74F89304841252B598A708A65FF sha1 04E81E2488E988810332EB215651EF7E57C95BF3 ) + rom ( name "2 Disney Games - Disney Sports - Football + Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc c8cdb4ed sha1 04E81E2488E988810332EB215651EF7E57C95BF3 ) ) game ( name "2 Disney Games - Lilo & Stitch 2 + Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es+En,Fr,De,Es,It,Nl)" description "2 Disney Games - Lilo & Stitch 2 + Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es+En,Fr,De,Es,It,Nl)" - rom ( name "2 Disney Games - Lilo & Stitch 2 + Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es+En,Fr,De,Es,It,Nl).gba" size 16777216 crc 75703943 md5 596DF9A6F24ED99FE5E064FFD9382726 sha1 4B0455173B592407DB9460B7E38FB209FD549772 ) + rom ( name "2 Disney Games - Lilo & Stitch 2 + Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es+En,Fr,De,Es,It,Nl).gba" size 16777216 crc 75703943 sha1 4B0455173B592407DB9460B7E38FB209FD549772 flags verified ) ) game ( name "2 Game Pack! - Hot Wheels - Stunt Track Challenge + Hot Wheels - World Race (USA, Europe)" description "2 Game Pack! - Hot Wheels - Stunt Track Challenge + Hot Wheels - World Race (USA, Europe)" - rom ( name "2 Game Pack! - Hot Wheels - Stunt Track Challenge + Hot Wheels - World Race (USA, Europe).gba" size 16777216 crc 20929EC1 md5 4DAF3D378D5F91277F43A5555829FDC7 sha1 717B2A739C8932374AB48A9C2BBD76A44B4CF2F3 flags verified ) + rom ( name "2 Game Pack! - Hot Wheels - Stunt Track Challenge + Hot Wheels - World Race (USA, Europe).gba" size 16777216 crc 20929ec1 sha1 717B2A739C8932374AB48A9C2BBD76A44B4CF2F3 flags verified ) ) game ( name "2 Game Pack! - Matchbox Missions - Emergency Response & Air, Land and Sea Rescue (Europe) (En,Fr,De,Es,It)" description "2 Game Pack! - Matchbox Missions - Emergency Response & Air, Land and Sea Rescue (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Game Pack! - Matchbox Missions - Emergency Response & Air, Land and Sea Rescue (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 0A907F58 md5 F008F97617B59E221F8135838F7DDCEE sha1 7F42797DF47182A3E6E7AED89A6FD98577D759E0 ) + rom ( name "2 Game Pack! - Matchbox Missions - Emergency Response & Air, Land and Sea Rescue (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 0a907f58 sha1 7F42797DF47182A3E6E7AED89A6FD98577D759E0 ) ) game ( name "2 Game Pack! - Matchbox Missions - Emergency Response + Air, Land and Sea Rescue (USA)" description "2 Game Pack! - Matchbox Missions - Emergency Response + Air, Land and Sea Rescue (USA)" - rom ( name "2 Game Pack! - Matchbox Missions - Emergency Response + Air, Land and Sea Rescue (USA).gba" size 4194304 crc 4080AAC1 md5 ADF9EFCA75FAD810C13A5FB3326DDDD2 sha1 AC9919F32220E128D3DF9A6201374F16AB15E301 ) + rom ( name "2 Game Pack! - Matchbox Missions - Emergency Response + Air, Land and Sea Rescue (USA).gba" size 4194304 crc 4080aac1 sha1 AC9919F32220E128D3DF9A6201374F16AB15E301 ) ) game ( name "2 Game Pack! - Uno & Skip-Bo (Europe) (En,Fr,De,Es,It)" description "2 Game Pack! - Uno & Skip-Bo (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Game Pack! - Uno & Skip-Bo (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E2018633 md5 CC83423C84419FE4011CAF03E84B2E64 sha1 1CFAC0FF2D526030050F4A6F5157398D58199B3D ) + rom ( name "2 Game Pack! - Uno & Skip-Bo (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e2018633 sha1 1CFAC0FF2D526030050F4A6F5157398D58199B3D ) ) game ( name "2 Game Pack! - Uno + Skip-Bo (USA)" description "2 Game Pack! - Uno + Skip-Bo (USA)" - rom ( name "2 Game Pack! - Uno + Skip-Bo (USA).gba" size 4194304 crc 0E2AF604 md5 CF66C71BCC65C5E0EE20C666DF8D6540 sha1 76F85AC10C7BA7F00503FBA4D41FB709B5B9CD22 ) + rom ( name "2 Game Pack! - Uno + Skip-Bo (USA).gba" size 4194304 crc 0e2af604 sha1 76F85AC10C7BA7F00503FBA4D41FB709B5B9CD22 ) ) game ( name "2 Games in 1 - Alla Ricerca di Nemo + Gli Incredibili - Una 'Normale' Famiglia di Supereroi (Italy) (Es,It+It)" description "2 Games in 1 - Alla Ricerca di Nemo + Gli Incredibili - Una 'Normale' Famiglia di Supereroi (Italy) (Es,It+It)" - rom ( name "2 Games in 1 - Alla Ricerca di Nemo + Gli Incredibili - Una 'Normale' Famiglia di Supereroi (Italy) (Es,It+It).gba" size 16777216 crc 9EA46982 md5 0AE1A89CABA4997B5059EAF8F8763727 sha1 DDEAF412F9F252C1A071955C517D1E36FD39AEB0 ) + rom ( name "2 Games in 1 - Alla Ricerca di Nemo + Gli Incredibili - Una 'Normale' Famiglia di Supereroi (Italy) (Es,It+It).gba" size 16777216 crc 9ea46982 sha1 DDEAF412F9F252C1A071955C517D1E36FD39AEB0 ) ) game ( name "2 Games in 1 - Bionicle + Knights' Kingdom (Europe) (En,Fr,De,Da+En,De)" description "2 Games in 1 - Bionicle + Knights' Kingdom (Europe) (En,Fr,De,Da+En,De)" - rom ( name "2 Games in 1 - Bionicle + Knights' Kingdom (Europe) (En,Fr,De,Da+En,De).gba" size 16777216 crc D720BDCA md5 15DB64521EE01C3F0428FDB9798577C5 sha1 578AC431AE298B14D0B65D80FED09A47311CC597 ) + rom ( name "2 Games in 1 - Bionicle + Knights' Kingdom (Europe) (En,Fr,De,Da+En,De).gba" size 16777216 crc d720bdca sha1 578AC431AE298B14D0B65D80FED09A47311CC597 ) ) game ( name "2 Games in 1 - Brother Bear + The Lion King (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Brother Bear + The Lion King (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Brother Bear + The Lion King (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 9E5F961B md5 630A51526DDB738FDC8392AA1C2E6500 sha1 A4E6B2F004678D387600AC46A2E57FE497DC4F18 ) + rom ( name "2 Games in 1 - Brother Bear + The Lion King (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 9e5f961b sha1 A4E6B2F004678D387600AC46A2E57FE497DC4F18 ) ) game ( name "2 Games in 1 - Buscando a Nemo + Los Increibles (Spain) (Es,It+Es)" description "2 Games in 1 - Buscando a Nemo + Los Increibles (Spain) (Es,It+Es)" - rom ( name "2 Games in 1 - Buscando a Nemo + Los Increibles (Spain) (Es,It+Es).gba" size 16777216 crc D7AC0697 md5 ACEAFFD0C62017A1BB4DF5817B61A0A7 sha1 EB6EED6AC64EC225CD14294C4D2A82BA3D524C24 ) + rom ( name "2 Games in 1 - Buscando a Nemo + Los Increibles (Spain) (Es,It+Es).gba" size 16777216 crc d7ac0697 sha1 EB6EED6AC64EC225CD14294C4D2A82BA3D524C24 ) ) game ( name "2 Games in 1 - Cartoon Network Block Party + Cartoon Network Speedway (USA)" description "2 Games in 1 - Cartoon Network Block Party + Cartoon Network Speedway (USA)" - rom ( name "2 Games in 1 - Cartoon Network Block Party + Cartoon Network Speedway (USA).gba" size 8388608 crc B3D323E4 md5 0D750DEFE01DA931BEB8148A71BE112E sha1 B0D9B18157F7E8EC139F04F9AE9508D00FA39313 ) + rom ( name "2 Games in 1 - Cartoon Network Block Party + Cartoon Network Speedway (USA).gba" size 8388608 crc b3d323e4 sha1 B0D9B18157F7E8EC139F04F9AE9508D00FA39313 ) ) game ( name "2 Games in 1 - Columns Crown + ChuChu Rocket! (Europe) (En+En,Ja,Fr,De,Es)" description "2 Games in 1 - Columns Crown + ChuChu Rocket! (Europe) (En+En,Ja,Fr,De,Es)" - rom ( name "2 Games in 1 - Columns Crown + ChuChu Rocket! (Europe) (En+En,Ja,Fr,De,Es).gba" size 16777216 crc 0BEAA2F4 md5 3D1F1A4DBE50B9EC4C83C323EE7CCA7A sha1 1F2960AA527B332348F8E770EA8E792BC6DA2813 ) + rom ( name "2 Games in 1 - Columns Crown + ChuChu Rocket! (Europe) (En+En,Ja,Fr,De,Es).gba" size 16777216 crc 0beaa2f4 sha1 1F2960AA527B332348F8E770EA8E792BC6DA2813 ) ) game ( name "2 Games in 1 - Die Monster AG + Findet Nemo (Germany)" description "2 Games in 1 - Die Monster AG + Findet Nemo (Germany)" - rom ( name "2 Games in 1 - Die Monster AG + Findet Nemo (Germany).gba" size 16777216 crc 4FD20E32 md5 E715D170842826522A7827A89E61998C sha1 294BFC9810FF83CC0B1FBED152D3E80BA219FB80 flags verified ) + rom ( name "2 Games in 1 - Die Monster AG + Findet Nemo (Germany).gba" size 16777216 crc 4fd20e32 sha1 294BFC9810FF83CC0B1FBED152D3E80BA219FB80 flags verified ) ) game ( name "2 Games in 1 - Disney Princesas + El Rey Leon (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Princesas + El Rey Leon (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Princesas + El Rey Leon (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 6472AC25 md5 2B4D29E64F0AB440877488D91BB67AE9 sha1 DC90C8A0784B4572CB7AD1E882D03B9D382170D8 ) + rom ( name "2 Games in 1 - Disney Princesas + El Rey Leon (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 6472ac25 sha1 DC90C8A0784B4572CB7AD1E882D03B9D382170D8 ) ) game ( name "2 Games in 1 - Disney Princesas + Hermano Oso (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Princesas + Hermano Oso (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Princesas + Hermano Oso (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 01B143A9 md5 279605B6241ECA4461003B439DF9E87F sha1 051085B42548FAEAB8318E15CCA4C71A6F48D4E8 ) + rom ( name "2 Games in 1 - Disney Princesas + Hermano Oso (Spain) (Es+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 01b143a9 sha1 051085B42548FAEAB8318E15CCA4C71A6F48D4E8 ) ) game ( name "2 Games in 1 - Disney Princesas + Lizzie McGuire (Spain)" description "2 Games in 1 - Disney Princesas + Lizzie McGuire (Spain)" - rom ( name "2 Games in 1 - Disney Princesas + Lizzie McGuire (Spain).gba" size 16777216 crc 57F886B0 md5 41CB1BCBD023024670BDADC4AF092261 sha1 0E55F66EFCAD4FE80B75942C1D42A86FB8CBCB74 ) + rom ( name "2 Games in 1 - Disney Princesas + Lizzie McGuire (Spain).gba" size 16777216 crc 57f886b0 sha1 0E55F66EFCAD4FE80B75942C1D42A86FB8CBCB74 ) ) game ( name "2 Games in 1 - Disney Princess + Brother Bear (Europe) (En+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Princess + Brother Bear (Europe) (En+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Princess + Brother Bear (Europe) (En+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 34355326 md5 B48CFDA5BD9B7EFE4F0C23F5E65D2C95 sha1 FE5B91F970ADCC1CCEEA35D38DD174B5B328755D ) + rom ( name "2 Games in 1 - Disney Princess + Brother Bear (Europe) (En+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 34355326 sha1 FE5B91F970ADCC1CCEEA35D38DD174B5B328755D ) ) game ( name "2 Games in 1 - Disney Princess + Lizzie McGuire (Europe)" description "2 Games in 1 - Disney Princess + Lizzie McGuire (Europe)" - rom ( name "2 Games in 1 - Disney Princess + Lizzie McGuire (Europe).gba" size 16777216 crc 99C96067 md5 E21A85388112F840D560C8CF90F61BCC sha1 5A5C56306CFCE32FD04B330666272D2E9C88057F ) + rom ( name "2 Games in 1 - Disney Princess + Lizzie McGuire (Europe).gba" size 16777216 crc 99c96067 sha1 5A5C56306CFCE32FD04B330666272D2E9C88057F flags verified ) ) game ( name "2 Games in 1 - Disney Princesse + Frere des Ours (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Princesse + Frere des Ours (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Princesse + Frere des Ours (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 22C54AE1 md5 CA525800D38AC7F1096D69032C689015 sha1 FF663BD8C6A7AC80B57E4A997F616D28340DF64C ) + rom ( name "2 Games in 1 - Disney Princesse + Frere des Ours (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 22c54ae1 sha1 FF663BD8C6A7AC80B57E4A997F616D28340DF64C ) ) game ( name "2 Games in 1 - Disney Princesse + Le Roi Lion (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Princesse + Le Roi Lion (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Princesse + Le Roi Lion (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc CCE9C2E2 md5 6F95DD3E97E52D41C5BA69ADF8E506AF sha1 D11EB620645FCAC8D18A9E384D0C6CCF134D01C2 ) + rom ( name "2 Games in 1 - Disney Princesse + Le Roi Lion (France) (Fr+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc cce9c2e2 sha1 D11EB620645FCAC8D18A9E384D0C6CCF134D01C2 ) ) game ( name "2 Games in 1 - Disney Principesse + Il Re Leone (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Principesse + Il Re Leone (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Principesse + Il Re Leone (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc A4ACBA4A md5 68999D263ABCF3274B5C7C7F95814B70 sha1 6D7E860A0A5B3DF1E2A68B46CB77E01DBF225A56 ) + rom ( name "2 Games in 1 - Disney Principesse + Il Re Leone (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc a4acba4a sha1 6D7E860A0A5B3DF1E2A68B46CB77E01DBF225A56 ) ) game ( name "2 Games in 1 - Disney Principesse + Koda, Fratello Orso (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disney Principesse + Koda, Fratello Orso (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disney Principesse + Koda, Fratello Orso (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 458DEDB1 md5 11FD08B9D7B232DEEF2519E951C65859 sha1 71A7BE1CE275630D09DA692B4299B4F90F82C0D6 ) + rom ( name "2 Games in 1 - Disney Principesse + Koda, Fratello Orso (Italy) (It+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 458dedb1 sha1 71A7BE1CE275630D09DA692B4299B4F90F82C0D6 ) ) game ( name "2 Games in 1 - Disneys Prinzessinnen + Baerenbrueder (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disneys Prinzessinnen + Baerenbrueder (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disneys Prinzessinnen + Baerenbrueder (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 52C8A11F md5 2FCDF9B4F16219242BF5CDD34336F0E6 sha1 16B3FA898912AB677C664D0EDC96F516D89447E7 ) + rom ( name "2 Games in 1 - Disneys Prinzessinnen + Baerenbrueder (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 52c8a11f sha1 16B3FA898912AB677C664D0EDC96F516D89447E7 ) ) game ( name "2 Games in 1 - Disneys Prinzessinnen + Der Koenig der Loewen (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da)" description "2 Games in 1 - Disneys Prinzessinnen + Der Koenig der Loewen (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "2 Games in 1 - Disneys Prinzessinnen + Der Koenig der Loewen (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc AD82CB84 md5 6C1CD0E60FAEBDA42B2804D749E351E2 sha1 3DA2E3756BC0ADF52C3DFB30AE2C70B53B062D54 ) + rom ( name "2 Games in 1 - Disneys Prinzessinnen + Der Koenig der Loewen (Germany) (De+En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc ad82cb84 sha1 3DA2E3756BC0ADF52C3DFB30AE2C70B53B062D54 ) ) game ( name "2 Games in 1 - Dr. Mario + Puzzle League (Europe) (En,Fr,De,Es,It)" description "2 Games in 1 - Dr. Mario + Puzzle League (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Dr. Mario + Puzzle League (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc FB7A7567 md5 EC06F494BE2A51170D7FD439BEE5A057 sha1 DF2918198EE3A5DD4A36B8CC28269E958DE5E1EE ) + rom ( name "2 Games in 1 - Dr. Mario + Puzzle League (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc fb7a7567 sha1 DF2918198EE3A5DD4A36B8CC28269E958DE5E1EE ) ) game ( name "2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)" description "2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA)" - rom ( name "2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA).gba" size 16777216 crc ACE78C4F md5 BE0EC0DC899635EDD6AD0C74574AA826 sha1 F02D179ACCBEB9B68BCAEF8720EB0AE426DDE6EE ) + rom ( name "2 Games in 1 - Dragon Ball Z - The Legacy of Goku I & II (USA).gba" size 16777216 crc ace78c4f sha1 F02D179ACCBEB9B68BCAEF8720EB0AE426DDE6EE ) ) game ( name "2 Games in 1 - Findet Nemo + Die Unglaublichen (Germany)" description "2 Games in 1 - Findet Nemo + Die Unglaublichen (Germany)" - rom ( name "2 Games in 1 - Findet Nemo + Die Unglaublichen (Germany).gba" size 16777216 crc 5DB86E1C md5 82507FD4F17734AE8F48072CBD5EF4E2 sha1 5048638791D849DE5370AF48088D3B0F497736DA ) + rom ( name "2 Games in 1 - Findet Nemo + Die Unglaublichen (Germany).gba" size 16777216 crc 5db86e1c sha1 5048638791D849DE5370AF48088D3B0F497736DA ) ) game ( name "2 Games in 1 - Findet Nemo + Findet Nemo - Das Abenteuer Geht Weiter (Germany) (De+Fr,De,Nl)" description "2 Games in 1 - Findet Nemo + Findet Nemo - Das Abenteuer Geht Weiter (Germany) (De+Fr,De,Nl)" - rom ( name "2 Games in 1 - Findet Nemo + Findet Nemo - Das Abenteuer Geht Weiter (Germany) (De+Fr,De,Nl).gba" size 16777216 crc 60A35C6E md5 4BA18D1EBADB424B3B944AE75DD322F0 sha1 E6F75D8108C9616A53853595123C787FCC5D83D0 ) + rom ( name "2 Games in 1 - Findet Nemo + Findet Nemo - Das Abenteuer Geht Weiter (Germany) (De+Fr,De,Nl).gba" size 16777216 crc 60a35c6e sha1 E6F75D8108C9616A53853595123C787FCC5D83D0 ) ) game ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (En+En,Es,It,Sv,Da)" description "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (En+En,Es,It,Sv,Da)" - rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (En+En,Es,It,Sv,Da).gba" size 16777216 crc 72D5F428 md5 EE2D0FFD5ED6588537E7590540D5CF21 sha1 5D7D2F148D7A35906E9ECB3408A5658A8C8040E8 ) + rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (En+En,Es,It,Sv,Da).gba" size 16777216 crc 72d5f428 sha1 5D7D2F148D7A35906E9ECB3408A5658A8C8040E8 flags verified ) ) game ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Es,It+En,Es,It,Sv,Da)" description "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Es,It+En,Es,It,Sv,Da)" - rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Es,It+En,Es,It,Sv,Da).gba" size 16777216 crc 73444273 md5 2CEDE728164EA50342D41A554EF36A02 sha1 A7B8AA7F3CD86B664F314650206D9043806E9B22 ) + rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Es,It+En,Es,It,Sv,Da).gba" size 16777216 crc 73444273 sha1 A7B8AA7F3CD86B664F314650206D9043806E9B22 ) ) game ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Fr,Nl+Fr,De,Nl)" description "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Fr,Nl+Fr,De,Nl)" - rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Fr,Nl+Fr,De,Nl).gba" size 16777216 crc 2E5EDA0D md5 A217DDA835C51021E8B2E68B773E1170 sha1 379FBA0051EFDBB6CC24E0DB56096A6EBEBAB795 ) + rom ( name "2 Games in 1 - Finding Nemo + Finding Nemo - The Continuing Adventures (Europe) (Fr,Nl+Fr,De,Nl).gba" size 16777216 crc 2e5eda0d sha1 379FBA0051EFDBB6CC24E0DB56096A6EBEBAB795 ) ) game ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe)" description "2 Games in 1 - Finding Nemo + The Incredibles (Europe)" - rom ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe).gba" size 16777216 crc 9702ABCE md5 E46D84FC7D150D0E9A378B788A6B5C92 sha1 5899447FC865AFB716E189FABC9315489985D010 ) + rom ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe).gba" size 16777216 crc 9702abce sha1 5899447FC865AFB716E189FABC9315489985D010 flags verified ) ) game ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe) (Fr,Nl)" description "2 Games in 1 - Finding Nemo + The Incredibles (Europe) (Fr,Nl)" - rom ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe) (Fr,Nl).gba" size 16777216 crc 2D4D69FA md5 FE2F3E4D3B15C8776C45FD7EF060DF89 sha1 2A02888C0F14FE35881EC175A8BC7220E78F2559 ) + rom ( name "2 Games in 1 - Finding Nemo + The Incredibles (Europe) (Fr,Nl).gba" size 16777216 crc 2d4d69fa sha1 2A02888C0F14FE35881EC175A8BC7220E78F2559 ) ) game ( name "2 Games in 1 - Finding Nemo - The Continuing Adventures + The Incredibles (USA)" description "2 Games in 1 - Finding Nemo - The Continuing Adventures + The Incredibles (USA)" - rom ( name "2 Games in 1 - Finding Nemo - The Continuing Adventures + The Incredibles (USA).gba" size 16777216 crc D5A37AA8 md5 CE7A3A9FB7E863D58BB2C71EA2A7A0D5 sha1 118CD86F64151C67BAF590B1030DA2FC6C6ACE16 ) + rom ( name "2 Games in 1 - Finding Nemo - The Continuing Adventures + The Incredibles (USA).gba" size 16777216 crc d5a37aa8 sha1 118CD86F64151C67BAF590B1030DA2FC6C6ACE16 ) ) game ( name "2 Games in 1 - Golden Nugget Casino + Texas Hold 'em Poker (USA)" description "2 Games in 1 - Golden Nugget Casino + Texas Hold 'em Poker (USA)" - rom ( name "2 Games in 1 - Golden Nugget Casino + Texas Hold 'em Poker (USA).gba" size 8388608 crc 6F88E088 md5 291C1AA5D30AFFEB56ECD802B9E8D012 sha1 E0AAEECBE1D52611CA633A45B19CB4D7B4651B0E ) + rom ( name "2 Games in 1 - Golden Nugget Casino + Texas Hold 'em Poker (USA).gba" size 8388608 crc 6f88e088 sha1 E0AAEECBE1D52611CA633A45B19CB4D7B4651B0E ) ) game ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (Europe)" description "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (Europe)" - rom ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (Europe).gba" size 16777216 crc B3C2CF9F md5 B714F4FA916CA53E24434EB7DBFED73B sha1 04DE405E87304241860C301E6F6BEC791ABB4795 ) + rom ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (Europe).gba" size 16777216 crc b3c2cf9f sha1 04DE405E87304241860C301E6F6BEC791ABB4795 ) ) game ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (USA)" description "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (USA)" - rom ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (USA).gba" size 16777216 crc A440A760 md5 9E95F7804E3B8011B89048F68E541DB8 sha1 80FCCDB4F09640F4EEF3F793A016664CE3C5B9EC ) + rom ( name "2 Games in 1 - Hot Wheels - Velocity X + Hot Wheels - World Race (USA).gba" size 16777216 crc a440a760 sha1 80FCCDB4F09640F4EEF3F793A016664CE3C5B9EC ) ) game ( name "2 Games in 1 - Les Razmoket Rencontrent les Delajungle + SpongeBob SquarePants - SuperSponge (France)" description "2 Games in 1 - Les Razmoket Rencontrent les Delajungle + SpongeBob SquarePants - SuperSponge (France)" - rom ( name "2 Games in 1 - Les Razmoket Rencontrent les Delajungle + SpongeBob SquarePants - SuperSponge (France).gba" size 8388608 crc B3BB9A45 md5 DC8786AA2AA0B73B73CB1AD110CCF2E7 sha1 527A294A70AB8700F856CBF52B31538781F2B647 ) + rom ( name "2 Games in 1 - Les Razmoket Rencontrent les Delajungle + SpongeBob SquarePants - SuperSponge (France).gba" size 8388608 crc b3bb9a45 sha1 527A294A70AB8700F856CBF52B31538781F2B647 ) ) game ( name "2 Games in 1 - Monsters & Co. + Alla Ricerca di Nemo (Italy) (En,Fr,It+Es,It)" description "2 Games in 1 - Monsters & Co. + Alla Ricerca di Nemo (Italy) (En,Fr,It+Es,It)" - rom ( name "2 Games in 1 - Monsters & Co. + Alla Ricerca di Nemo (Italy) (En,Fr,It+Es,It).gba" size 16777216 crc 06715995 md5 59287F4FB8D29BDC306E7F45B362CC4A sha1 88C3F076F5381E87BBE61DD1566B3BBA9B60FB41 ) + rom ( name "2 Games in 1 - Monsters & Co. + Alla Ricerca di Nemo (Italy) (En,Fr,It+Es,It).gba" size 16777216 crc 06715995 sha1 88C3F076F5381E87BBE61DD1566B3BBA9B60FB41 ) ) game ( name "2 Games in 1 - Monsters en Co. + Finding Nemo (Netherlands) (En,Es,Nl+Fr,Nl)" description "2 Games in 1 - Monsters en Co. + Finding Nemo (Netherlands) (En,Es,Nl+Fr,Nl)" - rom ( name "2 Games in 1 - Monsters en Co. + Finding Nemo (Netherlands) (En,Es,Nl+Fr,Nl).gba" size 16777216 crc 8F66CAD4 md5 81CC6D957B21D039716751268F402FA8 sha1 7CCCDD6B3E6E83D1BC481D09D52AFBBFEB30DA95 ) -) - -game ( - name "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA)" - description "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA)" - rom ( name "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA).gba" size 16777216 crc AD1C5818 md5 A1D5334B1B3DD31431EB232716EC8519 sha1 6CBA6375BF0214DC60C03C33F53FAC4C3180A94E ) + rom ( name "2 Games in 1 - Monsters en Co. + Finding Nemo (Netherlands) (En,Es,Nl+Fr,Nl).gba" size 16777216 crc 8f66cad4 sha1 7CCCDD6B3E6E83D1BC481D09D52AFBBFEB30DA95 ) ) game ( name "2 Games in 1 - Monsters, Inc. + Finding Nemo (Europe)" description "2 Games in 1 - Monsters, Inc. + Finding Nemo (Europe)" - rom ( name "2 Games in 1 - Monsters, Inc. + Finding Nemo (Europe).gba" size 16777216 crc 6CB47552 md5 43DCA05B7766662A4FE5A46E81F3592D sha1 FDA47644BA7C7601AA549CB4F2209B4FF687B116 flags verified ) + rom ( name "2 Games in 1 - Monsters, Inc. + Finding Nemo (Europe).gba" size 16777216 crc 6cb47552 sha1 FDA47644BA7C7601AA549CB4F2209B4FF687B116 flags verified ) +) + +game ( + name "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA)" + description "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA)" + rom ( name "2 Games in 1 - Monsters, Inc. + Finding Nemo (USA).gba" size 16777216 crc ad1c5818 sha1 6CBA6375BF0214DC60C03C33F53FAC4C3180A94E ) ) game ( name "2 Games in 1 - Monstres & Cie + Le Monde de Nemo (France) (En,Fr,It+Fr,Nl)" description "2 Games in 1 - Monstres & Cie + Le Monde de Nemo (France) (En,Fr,It+Fr,Nl)" - rom ( name "2 Games in 1 - Monstres & Cie + Le Monde de Nemo (France) (En,Fr,It+Fr,Nl).gba" size 16777216 crc 20298A03 md5 31AAA9B8C76C220356B4BED887C1A318 sha1 5454105434346250936492971E1E1DAE0420DFFE ) + rom ( name "2 Games in 1 - Monstres & Cie + Le Monde de Nemo (France) (En,Fr,It+Fr,Nl).gba" size 16777216 crc 20298a03 sha1 5454105434346250936492971E1E1DAE0420DFFE ) ) game ( name "2 Games in 1 - Monstruos, S.A. + Buscando a Nemo (Spain) (En,Es,Nl+Es,It)" description "2 Games in 1 - Monstruos, S.A. + Buscando a Nemo (Spain) (En,Es,Nl+Es,It)" - rom ( name "2 Games in 1 - Monstruos, S.A. + Buscando a Nemo (Spain) (En,Es,Nl+Es,It).gba" size 16777216 crc 9FF018F9 md5 17FA3B069564DD1DFC01EC579FCCF0AD sha1 77006BD92520439A7616D20AD9D4E2DD0B948B22 ) + rom ( name "2 Games in 1 - Monstruos, S.A. + Buscando a Nemo (Spain) (En,Es,Nl+Es,It).gba" size 16777216 crc 9ff018f9 sha1 77006BD92520439A7616D20AD9D4E2DD0B948B22 ) ) game ( name "2 Games in 1 - Moto GP + GT Advance 3 - Pro Concept Racing (Europe) (En,Fr,De,Es,It+En)" description "2 Games in 1 - Moto GP + GT Advance 3 - Pro Concept Racing (Europe) (En,Fr,De,Es,It+En)" - rom ( name "2 Games in 1 - Moto GP + GT Advance 3 - Pro Concept Racing (Europe) (En,Fr,De,Es,It+En).gba" size 16777216 crc 51D6CEB0 md5 D3B699DF6C6CA9BF3C3ABB120FB3EDD8 sha1 642BD76A9917EC5DA2AEAA6B19D1693AB1032787 ) + rom ( name "2 Games in 1 - Moto GP + GT Advance 3 - Pro Concept Racing (Europe) (En,Fr,De,Es,It+En).gba" size 16777216 crc 51d6ceb0 sha1 642BD76A9917EC5DA2AEAA6B19D1693AB1032787 ) ) game ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - La Force du Temps (France) (En,Fr,De+Fr)" description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - La Force du Temps (France) (En,Fr,De+Fr)" - rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - La Force du Temps (France) (En,Fr,De+Fr).gba" size 16777216 crc 14AA2642 md5 D0AAC762BC42A0133529AB72C8CC125C sha1 3293D56EF14F868BCE4089009014496FEFE359DA ) -) - -game ( - name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En)" - description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En)" - rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En).gba" size 16777216 crc 1B6956D0 md5 903CFC3391A05624C48B8DED7D6B2EFD sha1 19D40824D436E9F275D942A4008AC7124129C78C flags verified ) -) - -game ( - name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En)" - description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En)" - rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En).gba" size 16777216 crc 994E7629 md5 BEAA0DE66F48E52EFCC97B50B7777DEC sha1 E8D8FD1CDB48EC4B0F83C38A95109EF1CCFE715D ) + rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - La Force du Temps (France) (En,Fr,De+Fr).gba" size 16777216 crc 14aa2642 sha1 3293D56EF14F868BCE4089009014496FEFE359DA ) ) game ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Germany) (En,Fr,De+De)" description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Germany) (En,Fr,De+De)" - rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Germany) (En,Fr,De+De).gba" size 16777216 crc A5E872D7 md5 C8B81C5FE67F8235C03E350B8DE53730 sha1 9C5E032616BDA5936B07E3B052946D7C36BFB02A ) + rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Germany) (En,Fr,De+De).gba" size 16777216 crc a5e872d7 sha1 9C5E032616BDA5936B07E3B052946D7C36BFB02A ) +) + +game ( + name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En)" + description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En)" + rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (Europe) (En,Fr,De+En).gba" size 16777216 crc 1b6956d0 sha1 19D40824D436E9F275D942A4008AC7124129C78C flags verified ) +) + +game ( + name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En)" + description "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En)" + rom ( name "2 Games in 1 - Power Rangers - Ninja Storm + Power Rangers - Time Force (USA) (En,Fr,De+En).gba" size 16777216 crc 994e7629 sha1 E8D8FD1CDB48EC4B0F83C38A95109EF1CCFE715D ) ) game ( name "2 Games in 1 - Quad Desert Fury + Monster Trucks (USA)" description "2 Games in 1 - Quad Desert Fury + Monster Trucks (USA)" - rom ( name "2 Games in 1 - Quad Desert Fury + Monster Trucks (USA).gba" size 8388608 crc F9EC06A9 md5 F493E3FE4DBE2B9ECDE12CE9590A10E7 sha1 AC0D3528D5829097C71E819E96440CE125B17470 ) + rom ( name "2 Games in 1 - Quad Desert Fury + Monster Trucks (USA).gba" size 8388608 crc f9ec06a9 sha1 AC0D3528D5829097C71E819E96440CE125B17470 ) ) game ( name "2 Games in 1 - Rugrats - Go Wild + SpongeBob SquarePants - SuperSponge (Europe)" description "2 Games in 1 - Rugrats - Go Wild + SpongeBob SquarePants - SuperSponge (Europe)" - rom ( name "2 Games in 1 - Rugrats - Go Wild + SpongeBob SquarePants - SuperSponge (Europe).gba" size 8388608 crc E5AC73BB md5 9178687E7327CBB77458E1093D95CF1F sha1 C4436FD09DDDC226D9670B2F73121B893D33F418 ) + rom ( name "2 Games in 1 - Rugrats - Go Wild + SpongeBob SquarePants - SuperSponge (Europe).gba" size 8388608 crc e5ac73bb sha1 C4436FD09DDDC226D9670B2F73121B893D33F418 ) ) game ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Desatado (Spain) (Es+En,Fr,De,Es,It)" description "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Desatado (Spain) (Es+En,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Desatado (Spain) (Es+En,Fr,De,Es,It).gba" size 16777216 crc D21582D0 md5 AAF042D4AA5852A653EA4416CC798101 sha1 8E68DD7021C73A3F54F7A47B12027D6364CE3790 ) + rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Desatado (Spain) (Es+En,Fr,De,Es,It).gba" size 16777216 crc d21582d0 sha1 8E68DD7021C73A3F54F7A47B12027D6364CE3790 ) ) game ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Les Monstres Se Dechainent (France) (Fr+En,Fr,De,Es,It)" description "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Les Monstres Se Dechainent (France) (Fr+En,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Les Monstres Se Dechainent (France) (Fr+En,Fr,De,Es,It).gba" size 16777216 crc 802C9234 md5 A46846238A4E41AB301F44A3E34D1779 sha1 503CA1459CF74AB625D4D9464528DA320A4A02D1 ) + rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Les Monstres Se Dechainent (France) (Fr+En,Fr,De,Es,It).gba" size 16777216 crc 802c9234 sha1 503CA1459CF74AB625D4D9464528DA320A4A02D1 ) ) game ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (USA)" description "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (USA)" - rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (USA).gba" size 16777216 crc 1F023DBE md5 6F1EDD8D1A8091636A1685DEF759E602 sha1 2E7EFCEE9228EF3E3E7B1381976A956E64EAF198 ) + rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (USA).gba" size 16777216 crc 1f023dbe sha1 2E7EFCEE9228EF3E3E7B1381976A956E64EAF198 ) ) game ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (Europe)" description "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (Europe)" - rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (Europe).gba" size 16777216 crc BFCD892E md5 1E7EE1CF52D5A507AB4A54EE1EFAD630 sha1 527F2411F2ED9215ED5527E41BCFCEDF2DDA2ADB ) + rom ( name "2 Games in 1 - Scooby-Doo + Scooby-Doo 2 - Monsters Unleashed (Europe).gba" size 16777216 crc bfcd892e sha1 527F2411F2ED9215ED5527E41BCFCEDF2DDA2ADB ) ) game ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (USA) (En,Fr,De+En)" description "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (USA) (En,Fr,De+En)" - rom ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (USA) (En,Fr,De+En).gba" size 8388608 crc 5318DF13 md5 7BD5AE371D67113AD2C01109607B418B sha1 78E1AC7414BE6EBA0C016D191DF34E954A1D3BB6 ) + rom ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (USA) (En,Fr,De+En).gba" size 8388608 crc 5318df13 sha1 78E1AC7414BE6EBA0C016D191DF34E954A1D3BB6 ) ) game ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De+En)" description "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De+En)" - rom ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De+En).gba" size 8388608 crc 99566698 md5 5294D185A38489831F0ACB78ABA1030B sha1 D60E1002BC8D436CEED5FEDAE63525703C00287A ) + rom ( name "2 Games in 1 - Scooby-Doo! - Mystery Mayhem + Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De+En).gba" size 8388608 crc 99566698 sha1 D60E1002BC8D436CEED5FEDAE63525703C00287A flags verified ) ) game ( name "2 Games in 1 - Sonic Advance + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es)" description "2 Games in 1 - Sonic Advance + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es)" - rom ( name "2 Games in 1 - Sonic Advance + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es).gba" size 16777216 crc 22489C7C md5 EFCD9B5848F494AAF49051C5D9E83054 sha1 028210706977BB6376E90FA241F88A6D836B72EC flags verified ) + rom ( name "2 Games in 1 - Sonic Advance + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es).gba" size 16777216 crc 22489c7c sha1 028210706977BB6376E90FA241F88A6D836B72EC flags verified ) ) game ( name "2 Games in 1 - Sonic Advance + Sonic Battle (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" description "2 Games in 1 - Sonic Advance + Sonic Battle (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Sonic Advance + Sonic Battle (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 33554432 crc 94CF5B2B md5 1F068B49FA0FFF9F866ABE2D0A965A89 sha1 2C22DD926F8064000F23C39787EA8579E022FCF8 ) + rom ( name "2 Games in 1 - Sonic Advance + Sonic Battle (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 33554432 crc 94cf5b2b sha1 2C22DD926F8064000F23C39787EA8579E022FCF8 ) ) game ( name "2 Games in 1 - Sonic Advance + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" description "2 Games in 1 - Sonic Advance + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Sonic Advance + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 16777216 crc 1127DC09 md5 9A5EE5BDA6C5D01032CE459A8DBD2B57 sha1 2872DDC6BF2EAD9F08ABEC66836FF8CB5C9B0909 ) + rom ( name "2 Games in 1 - Sonic Advance + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 16777216 crc 1127dc09 sha1 2872DDC6BF2EAD9F08ABEC66836FF8CB5C9B0909 ) ) game ( name "2 Games in 1 - Sonic Battle + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es,It+En,Ja,Fr,De,Es)" description "2 Games in 1 - Sonic Battle + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es,It+En,Ja,Fr,De,Es)" - rom ( name "2 Games in 1 - Sonic Battle + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es,It+En,Ja,Fr,De,Es).gba" size 33554432 crc 2C57E588 md5 B7BD2A56BC92F5E04EA7BCBC2841C57E sha1 2D1ACEEA9E69454CEC89ACDD764887D584C06877 ) + rom ( name "2 Games in 1 - Sonic Battle + ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es,It+En,Ja,Fr,De,Es).gba" size 33554432 crc 2c57e588 sha1 2D1ACEEA9E69454CEC89ACDD764887D584C06877 ) ) game ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" description "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc A50DE233 md5 C8C20827E23977FA69AB7F0ABBC08931 sha1 DF086E816109A18D0F037E8C0AA7A2AE40677C14 ) + rom ( name "2 Games in 1 - Sonic Battle + Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc a50de233 sha1 DF086E816109A18D0F037E8C0AA7A2AE40677C14 flags verified ) ) game ( name "2 Games in 1 - Sonic Pinball Party + Columns Crown (Europe) (En,Ja,Fr,De,Es,It+En)" description "2 Games in 1 - Sonic Pinball Party + Columns Crown (Europe) (En,Ja,Fr,De,Es,It+En)" - rom ( name "2 Games in 1 - Sonic Pinball Party + Columns Crown (Europe) (En,Ja,Fr,De,Es,It+En).gba" size 16777216 crc 8577A000 md5 6CE88B00F7CCF862F6386866DCC91558 sha1 81E94573F0EB2DC5DAE5AB3EAB9E2C30D3197203 ) + rom ( name "2 Games in 1 - Sonic Pinball Party + Columns Crown (Europe) (En,Ja,Fr,De,Es,It+En).gba" size 16777216 crc 8577a000 sha1 81E94573F0EB2DC5DAE5AB3EAB9E2C30D3197203 ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Jimmy Neutron Boy Genius (Europe) (En,Fr,De+En,Fr,De,Es)" description "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Jimmy Neutron Boy Genius (Europe) (En,Fr,De+En,Fr,De,Es)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Jimmy Neutron Boy Genius (Europe) (En,Fr,De+En,Fr,De,Es).gba" size 16777216 crc 4BA7F7CB md5 5C0CC78C521FB9D43A99F76B920980AB sha1 11CAF32F79B1FC0B7CEE039F02793760C56A63BE ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Jimmy Neutron Boy Genius (Europe) (En,Fr,De+En,Fr,De,Es).gba" size 16777216 crc 4ba7f7cb sha1 11CAF32F79B1FC0B7CEE039F02793760C56A63BE ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Nicktoons - Freeze Frame Frenzy (USA)" description "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Nicktoons - Freeze Frame Frenzy (USA)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Nicktoons - Freeze Frame Frenzy (USA).gba" size 16777216 crc 5802CAFD md5 01F08A55412611F51CE89A1B90B3AF11 sha1 56026A6D7290E7C09C9E9AC7083E4505AC9D31E5 ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + Nicktoons - Freeze Frame Frenzy (USA).gba" size 16777216 crc 5802cafd sha1 56026A6D7290E7C09C9E9AC7083E4505AC9D31E5 ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + The Fairly OddParents! - Breakin' da Rules (USA)" description "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + The Fairly OddParents! - Breakin' da Rules (USA)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + The Fairly OddParents! - Breakin' da Rules (USA).gba" size 16777216 crc 82C21322 md5 86AE492F7C964724DE06F7CBEBE6437A sha1 D9BA8B21696B3FE2CE5DC31B7F7A8837F52ACAB0 ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - Battle for Bikini Bottom + The Fairly OddParents! - Breakin' da Rules (USA).gba" size 16777216 crc 82c21322 sha1 D9BA8B21696B3FE2CE5DC31B7F7A8837F52ACAB0 flags verified ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (Europe)" description "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (Europe)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (Europe).gba" size 16777216 crc 111D6997 md5 F27EC053BCCC03C8219A6D04169D402A sha1 4B6ABD4ED09674A1B1DA191A2F2FBFAD352DA740 flags verified ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (Europe).gba" size 16777216 crc 111d6997 sha1 4B6ABD4ED09674A1B1DA191A2F2FBFAD352DA740 flags verified ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (USA)" description "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (USA)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (USA).gba" size 16777216 crc D515C0E4 md5 FA11BE8D9B3E6A4851D8F4538922082A sha1 C7610E41FC97358F4FE156BFC0EF3A33E87C8A73 ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - Revenge of the Flying Dutchman + SpongeBob SquarePants - SuperSponge (USA).gba" size 16777216 crc d515c0e4 sha1 C7610E41FC97358F4FE156BFC0EF3A33E87C8A73 ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En+En,Fr,De)" description "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En+En,Fr,De)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En+En,Fr,De).gba" size 16777216 crc 71D52C61 md5 6F77E7BFA48F13113ED42AAAFC791368 sha1 025DC7CF356A812E468B9FA66B6535448D0186FF ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En+En,Fr,De).gba" size 16777216 crc 71d52c61 sha1 025DC7CF356A812E468B9FA66B6535448D0186FF flags verified ) ) game ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe)" description "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe)" - rom ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe).gba" size 16777216 crc 06F0F43C md5 D1D4DF6CF579A743171F39F06FB884FB sha1 C9871F358482D4D463ECFC1914959B05119DEB0E ) + rom ( name "2 Games in 1 - SpongeBob SquarePants - SuperSponge + SpongeBob SquarePants - Battle for Bikini Bottom (Europe).gba" size 16777216 crc 06f0f43c sha1 C9871F358482D4D463ECFC1914959B05119DEB0E ) ) game ( name "2 Games in 1 - The Lion King + Disney Princess (Europe) (En,Fr,De,Es,It,Nl,Sv,Da+En)" description "2 Games in 1 - The Lion King + Disney Princess (Europe) (En,Fr,De,Es,It,Nl,Sv,Da+En)" - rom ( name "2 Games in 1 - The Lion King + Disney Princess (Europe) (En,Fr,De,Es,It,Nl,Sv,Da+En).gba" size 16777216 crc 3B1CF966 md5 65110A08BA48AFA16C8693E88D62C10B sha1 C10F28E821F6820C1D8FE34798172C0131180004 ) + rom ( name "2 Games in 1 - The Lion King + Disney Princess (Europe) (En,Fr,De,Es,It,Nl,Sv,Da+En).gba" size 16777216 crc 3b1cf966 sha1 C10F28E821F6820C1D8FE34798172C0131180004 ) ) game ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl)" description "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl)" - rom ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl).gba" size 16777216 crc A04CEBFE md5 61C2B1E42C45705BC19CB905AE25BD2D sha1 0286E31772601F7C7420722E8FBF8A210D562A06 ) + rom ( name "2 Games in 1 - The SpongeBob SquarePants Movie + SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,Nl).gba" size 16777216 crc a04cebfe sha1 0286E31772601F7C7420722E8FBF8A210D562A06 ) ) game ( name "2 Games in 1! - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)" description "2 Games in 1! - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA)" - rom ( name "2 Games in 1! - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA).gba" size 16777216 crc 280587F2 md5 89BBC0E48966FECA4F22E2B31CAAD638 sha1 3733ADAFF49866A8FE01E23526F4F52CA39CBF58 ) + rom ( name "2 Games in 1! - Dragon Ball Z - Buu's Fury + Dragon Ball GT - Transformation (USA).gba" size 16777216 crc 280587f2 sha1 3733ADAFF49866A8FE01E23526F4F52CA39CBF58 ) ) game ( - name "2 Games in One! - Dr. Mario + Puzzle League (USA, Australia)" - description "2 Games in One! - Dr. Mario + Puzzle League (USA, Australia)" - rom ( name "2 Games in One! - Dr. Mario + Puzzle League (USA, Australia).gba" size 8388608 crc 4C2B7349 md5 279297081BAB92BDC469F3B9127AB4FC sha1 AF6FDAD72D3F4777338B77971F488C0F75B080C1 ) + name "2 Games in One! - Dr. Mario + Puzzle League (USA)" + description "2 Games in One! - Dr. Mario + Puzzle League (USA)" + rom ( name "2 Games in One! - Dr. Mario + Puzzle League (USA).gba" size 8388608 crc 4c2b7349 sha1 AF6FDAD72D3F4777338B77971F488C0F75B080C1 ) ) game ( name "2 Games in One! - Gauntlet + Rampart (USA)" description "2 Games in One! - Gauntlet + Rampart (USA)" - rom ( name "2 Games in One! - Gauntlet + Rampart (USA).gba" size 4194304 crc 5F255362 md5 75FCA6EECCF730D5B9883FA333F6B268 sha1 1BE59C6919A849749D7251D352BF5F1840E4E683 ) + rom ( name "2 Games in One! - Gauntlet + Rampart (USA).gba" size 4194304 crc 5f255362 sha1 1BE59C6919A849749D7251D352BF5F1840E4E683 ) ) game ( name "2 Games in One! - Gauntlet + Rampart (Europe) (En,Fr,De,Es,It)" description "2 Games in One! - Gauntlet + Rampart (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Games in One! - Gauntlet + Rampart (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 36717B52 md5 56915D1408E0CF7842D6C65B1735B90B sha1 AE327BEBC9841C990B3F1D6F8F9F95003D8BF16E ) + rom ( name "2 Games in One! - Gauntlet + Rampart (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 36717b52 sha1 AE327BEBC9841C990B3F1D6F8F9F95003D8BF16E ) ) game ( name "2 Games in One! - Marble Madness + Klax (USA)" description "2 Games in One! - Marble Madness + Klax (USA)" - rom ( name "2 Games in One! - Marble Madness + Klax (USA).gba" size 4194304 crc 5DA05880 md5 A2F94DED0E81AF7CDB36E675E09A60EC sha1 C01AE66E778A89515B408C6162EC0FD63F1BDE1E ) + rom ( name "2 Games in One! - Marble Madness + Klax (USA).gba" size 4194304 crc 5da05880 sha1 C01AE66E778A89515B408C6162EC0FD63F1BDE1E ) ) game ( name "2 Games in One! - Marble Madness + Klax (Europe) (En,Fr,De,Es,It)" description "2 Games in One! - Marble Madness + Klax (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Games in One! - Marble Madness + Klax (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 40DA6C26 md5 3C4895800D08531F190AABA0F92C6FCA sha1 4579C288827DF5F4BCA8CBEF37BE21AEF42A04CE ) + rom ( name "2 Games in One! - Marble Madness + Klax (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 40da6c26 sha1 4579C288827DF5F4BCA8CBEF37BE21AEF42A04CE ) ) game ( name "2 Games in One! - Paperboy + Rampage (USA)" description "2 Games in One! - Paperboy + Rampage (USA)" - rom ( name "2 Games in One! - Paperboy + Rampage (USA).gba" size 4194304 crc 79FE9284 md5 122EC4309CB7AA7A13F880DE1EC3E703 sha1 6A18CC723A2CA74DD5974BF46192F0369F7E33E5 ) + rom ( name "2 Games in One! - Paperboy + Rampage (USA).gba" size 4194304 crc 79fe9284 sha1 6A18CC723A2CA74DD5974BF46192F0369F7E33E5 ) ) game ( name "2 Games in One! - Paperboy + Rampage (Europe) (En,Fr,De,Es,It)" description "2 Games in One! - Paperboy + Rampage (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Games in One! - Paperboy + Rampage (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 44E1761A md5 27138132D4C085BBBC442618579558BC sha1 79CA9D12045F40D2B31015F5DDBC3FB43A34D2E6 ) + rom ( name "2 Games in One! - Paperboy + Rampage (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 44e1761a sha1 79CA9D12045F40D2B31015F5DDBC3FB43A34D2E6 ) ) game ( name "2 Games in One! - Spy Hunter + Super Sprint (USA)" description "2 Games in One! - Spy Hunter + Super Sprint (USA)" - rom ( name "2 Games in One! - Spy Hunter + Super Sprint (USA).gba" size 4194304 crc AD2F5353 md5 2B58AB05006A99C7B075A72141C39346 sha1 B0B7C1BC5BC222EEE353FC7889E591D87D33F0A2 ) + rom ( name "2 Games in One! - Spy Hunter + Super Sprint (USA).gba" size 4194304 crc ad2f5353 sha1 B0B7C1BC5BC222EEE353FC7889E591D87D33F0A2 ) ) game ( name "2 Games in One! - Spy Hunter + Super Sprint (Europe) (En,Fr,De,Es,It)" description "2 Games in One! - Spy Hunter + Super Sprint (Europe) (En,Fr,De,Es,It)" - rom ( name "2 Games in One! - Spy Hunter + Super Sprint (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc BBF32EE3 md5 2644A4B5ADB2BFE2CA1263B9DB9649FC sha1 E280870419C5C462E3A3A90C59CF42307098E75A ) + rom ( name "2 Games in One! - Spy Hunter + Super Sprint (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc bbf32ee3 sha1 E280870419C5C462E3A3A90C59CF42307098E75A ) ) game ( name "2 Great Games! - Pac-Man World + Ms. Pac-Man - Maze Madness (USA)" description "2 Great Games! - Pac-Man World + Ms. Pac-Man - Maze Madness (USA)" - rom ( name "2 Great Games! - Pac-Man World + Ms. Pac-Man - Maze Madness (USA).gba" size 8388608 crc 851127D4 md5 E42D386BA4691E3608D45FB6DC47996E sha1 F945B8F6A9900241E86D84431F683DB37671A8AE ) + rom ( name "2 Great Games! - Pac-Man World + Ms. Pac-Man - Maze Madness (USA).gba" size 8388608 crc 851127d4 sha1 F945B8F6A9900241E86D84431F683DB37671A8AE ) ) game ( name "2 in 1 - Asterix & Obelix - Bash Them All! + Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl)" description "2 in 1 - Asterix & Obelix - Bash Them All! + Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "2 in 1 - Asterix & Obelix - Bash Them All! + Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 183A2207 md5 EAB287293BF4B62301119CFC3A9A9CCC sha1 03B76E408E368BE7A3EF041A22923A4D2754AF6A ) + rom ( name "2 in 1 - Asterix & Obelix - Bash Them All! + Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 183a2207 sha1 03B76E408E368BE7A3EF041A22923A4D2754AF6A ) ) game ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It)" description "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It)" - rom ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5813810F md5 64EE9A205B96F5B2945E1594E8B6DEFD sha1 F116CC8E6A7F6DBA49564031A2AC63D837D4F11B ) + rom ( name "2 in 1 - V-Rally 3 + Stuntman (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5813810f sha1 F116CC8E6A7F6DBA49564031A2AC63D837D4F11B ) ) game ( name "2 in 1 Game Pack - Shrek 2 & Shark Tale (Europe) (En,Fr,De,Es,It,Sv+En,Fr,De,Es,It)" description "2 in 1 Game Pack - Shrek 2 & Shark Tale (Europe) (En,Fr,De,Es,It,Sv+En,Fr,De,Es,It)" - rom ( name "2 in 1 Game Pack - Shrek 2 & Shark Tale (Europe) (En,Fr,De,Es,It,Sv+En,Fr,De,Es,It).gba" size 16777216 crc 1802C624 md5 60C622E488935541EE0D7295BDE1FF85 sha1 A9375826C46CDD1F78AECF8274DB30110CD3D6D3 ) + rom ( name "2 in 1 Game Pack - Shrek 2 & Shark Tale (Europe) (En,Fr,De,Es,It,Sv+En,Fr,De,Es,It).gba" size 16777216 crc 1802c624 sha1 A9375826C46CDD1F78AECF8274DB30110CD3D6D3 ) ) game ( name "2 in 1 Game Pack - Shrek 2 + Shark Tale (USA)" description "2 in 1 Game Pack - Shrek 2 + Shark Tale (USA)" - rom ( name "2 in 1 Game Pack - Shrek 2 + Shark Tale (USA).gba" size 16777216 crc 5CB036C7 md5 48D89FE21745E62460D22354111EA6E0 sha1 226A4C2BBE400D00AFD2FA1D02285FBD4EA5015C ) + rom ( name "2 in 1 Game Pack - Shrek 2 + Shark Tale (USA).gba" size 16777216 crc 5cb036c7 sha1 226A4C2BBE400D00AFD2FA1D02285FBD4EA5015C ) ) game ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It)" description "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It)" - rom ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It).gba" size 33554432 crc D732E52D md5 9E19A3FA1D458C3E8BE8BD6103937473 sha1 5BF33C1F0FD50F268ED5941D3246CFAD1893EF89 ) + rom ( name "2 in 1 Game Pack - Spider-Man & Spider-Man 2 (Europe) (En,Fr,De+En,Fr,De,Es,It).gba" size 33554432 crc d732e52d sha1 5BF33C1F0FD50F268ED5941D3246CFAD1893EF89 ) ) game ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es)" description "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es)" - rom ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es).gba" size 33554432 crc 0AE3637F md5 8C91AF1E9F60E7577219176F18CEFB76 sha1 8BC2B600A043B776BC61FE8C0F4007B4360545F9 ) + rom ( name "2 in 1 Game Pack - Spider-Man + Spider-Man 2 (USA) (En,Fr,De+En,Fr,De,Es).gba" size 33554432 crc 0ae3637f sha1 8BC2B600A043B776BC61FE8C0F4007B4360545F9 ) ) game ( name "2 in 1 Game Pack - Spider-Man - Mysterio's Menace + X2 - Wolverine's Revenge (USA, Europe)" description "2 in 1 Game Pack - Spider-Man - Mysterio's Menace + X2 - Wolverine's Revenge (USA, Europe)" - rom ( name "2 in 1 Game Pack - Spider-Man - Mysterio's Menace + X2 - Wolverine's Revenge (USA, Europe).gba" size 16777216 crc E7BAA5B9 md5 2B5E0FFA2EB716E2600282842C915FC0 sha1 50C0F0531C0EEF9109FBD8424B1067534582316A ) + rom ( name "2 in 1 Game Pack - Spider-Man - Mysterio's Menace + X2 - Wolverine's Revenge (USA, Europe).gba" size 16777216 crc e7baa5b9 sha1 50C0F0531C0EEF9109FBD8424B1067534582316A flags verified ) ) game ( name "2 in 1 Game Pack - Tony Hawk's Underground + Kelly Slater's Pro Surfer (USA, Europe)" description "2 in 1 Game Pack - Tony Hawk's Underground + Kelly Slater's Pro Surfer (USA, Europe)" - rom ( name "2 in 1 Game Pack - Tony Hawk's Underground + Kelly Slater's Pro Surfer (USA, Europe).gba" size 16777216 crc 6D8EF48A md5 7CBFEDC28A27FE3AEE703B2444946946 sha1 EC1BB449B3D52B421E0AC3DFE3FDBCE22822251A flags verified ) + rom ( name "2 in 1 Game Pack - Tony Hawk's Underground + Kelly Slater's Pro Surfer (USA, Europe).gba" size 16777216 crc 6d8ef48a sha1 EC1BB449B3D52B421E0AC3DFE3FDBCE22822251A flags verified ) ) game ( - name "2 Jeux en 1 - Titeuf - Ze Gagmachine + Titeuf - Mega Compet (France)" - description "2 Jeux en 1 - Titeuf - Ze Gagmachine + Titeuf - Mega Compet (France)" - rom ( name "2 Jeux en 1 - Titeuf - Ze Gagmachine + Titeuf - Mega Compet (France).gba" size 8388608 crc 0A5965F4 md5 762E95819D0EA7039DF160AE6E8C5635 sha1 FED9A0252BC840589944FEF23909995065FBE9C5 ) + name "2 Jeux en 1 - Titeuf - Ze Gag Machine + Titeuf - Mega Compet (France)" + description "2 Jeux en 1 - Titeuf - Ze Gag Machine + Titeuf - Mega Compet (France)" + rom ( name "2 Jeux en 1 - Titeuf - Ze Gag Machine + Titeuf - Mega Compet (France).gba" size 8388608 crc 0a5965f4 sha1 FED9A0252BC840589944FEF23909995065FBE9C5 ) ) game ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (USA)" description "2-in-1 Fun Pack - Shrek 2 + Madagascar (USA)" - rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (USA).gba" size 16777216 crc 39D68733 md5 A160E317DCBD117035214CB47F35C466 sha1 A072DE6B8AF91239EA8348E9C6951F9F51AC0388 ) + rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (USA).gba" size 16777216 crc 39d68733 sha1 A072DE6B8AF91239EA8348E9C6951F9F51AC0388 ) ) game ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (Europe)" description "2-in-1 Fun Pack - Shrek 2 + Madagascar (Europe)" - rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (Europe).gba" size 16777216 crc 63BB643F md5 0AF8FB79E9986400FD05DACF0A4373E8 sha1 EFA765B63BC0203C0635D71C7CABCFB7A67FB3C7 ) + rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar (Europe).gba" size 16777216 crc 63bb643f sha1 EFA765B63BC0203C0635D71C7CABCFB7A67FB3C7 ) ) game ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (USA)" description "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (USA)" - rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (USA).gba" size 16777216 crc 18670538 md5 00866E17CE947975D30EFE48AD99628B sha1 0A1F19DA35AB5CB1B61797794876B0526059A844 ) + rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (USA).gba" size 16777216 crc 18670538 sha1 0A1F19DA35AB5CB1B61797794876B0526059A844 ) ) game ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (Europe)" description "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (Europe)" - rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (Europe).gba" size 16777216 crc 3535B2BF md5 665CD847EFECF2A893EE74A9C42C26EB sha1 BE51CFA607D461EFD1DAB640A5B4F5B037C060DF ) + rom ( name "2-in-1 Fun Pack - Shrek 2 + Madagascar - Operation Penguin (Europe).gba" size 16777216 crc 3535b2bf sha1 BE51CFA607D461EFD1DAB640A5B4F5B037C060DF ) ) game ( name "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It)" description "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 50AB4544 md5 BB87013EC30BEBF3DD7CB07AB6786262 sha1 295580745787BA9593799213564484AAAA7FD463 flags verified ) + rom ( name "2006 FIFA World Cup - Germany 2006 (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 50ab4544 sha1 295580745787BA9593799213564484AAAA7FD463 flags verified ) ) game ( name "2K Sports - Major League Baseball 2K7 (USA)" description "2K Sports - Major League Baseball 2K7 (USA)" - rom ( name "2K Sports - Major League Baseball 2K7 (USA).gba" size 8388608 crc 8F3FF0E4 md5 873B5E4111C0CBBC5224B590E845BA21 sha1 07390BC2BD53CD9EE5C6D2805AD374C59C195D9F ) + rom ( name "2K Sports - Major League Baseball 2K7 (USA).gba" size 8388608 crc 8f3ff0e4 sha1 07390BC2BD53CD9EE5C6D2805AD374C59C195D9F ) ) game ( name "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA)" description "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA)" - rom ( name "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA).gba" size 4194304 crc 628A8E32 md5 12D9FCAE83C5295AAC6DA015B75A24D6 sha1 946CCBF8D21ADC7A5587EF85A9759A2DED23875D ) + rom ( name "3 Game Pack! - Candy Land + Chutes and Ladders + Original Memory Game (USA).gba" size 4194304 crc 628a8e32 sha1 946CCBF8D21ADC7A5587EF85A9759A2DED23875D ) ) game ( name "3 Game Pack! - Ker Plunk! + Toss Across + Tip It (USA)" description "3 Game Pack! - Ker Plunk! + Toss Across + Tip It (USA)" - rom ( name "3 Game Pack! - Ker Plunk! + Toss Across + Tip It (USA).gba" size 4194304 crc 8B523FF7 md5 49309E80A5ACF7A4D452F6AD88238581 sha1 56032BA5E0ED90AEF6B9D64D06B573D1D97DD6B9 ) + rom ( name "3 Game Pack! - Ker Plunk! + Toss Across + Tip It (USA).gba" size 4194304 crc 8b523ff7 sha1 56032BA5E0ED90AEF6B9D64D06B573D1D97DD6B9 ) ) game ( name "3 Game Pack! - Mouse Trap + Simon + Operation (USA)" description "3 Game Pack! - Mouse Trap + Simon + Operation (USA)" - rom ( name "3 Game Pack! - Mouse Trap + Simon + Operation (USA).gba" size 4194304 crc 20287753 md5 BD846A0248E2F18BF7521FD2F5479881 sha1 10BED6B69F8984AF49299885FDA0575FCE442A9C ) + rom ( name "3 Game Pack! - Mouse Trap + Simon + Operation (USA).gba" size 4194304 crc 20287753 sha1 10BED6B69F8984AF49299885FDA0575FCE442A9C ) ) game ( name "3 Game Pack! - The Game of Life + Payday + Yahtzee (USA)" description "3 Game Pack! - The Game of Life + Payday + Yahtzee (USA)" - rom ( name "3 Game Pack! - The Game of Life + Payday + Yahtzee (USA).gba" size 4194304 crc E6DC35A9 md5 A40E7BBD268202DA470950335A6793F5 sha1 167A454E4660629ED99B014C77BD3E4AE9EEF294 ) + rom ( name "3 Game Pack! - The Game of Life + Payday + Yahtzee (USA).gba" size 4194304 crc e6dc35a9 sha1 167A454E4660629ED99B014C77BD3E4AE9EEF294 ) ) game ( name "3 Games in 1 - Rugrats - I Gotta Go Party + SpongeBob SquarePants - SuperSponge + Tak and the Power of Juju (Europe) (En+En+En,Fr,De)" description "3 Games in 1 - Rugrats - I Gotta Go Party + SpongeBob SquarePants - SuperSponge + Tak and the Power of Juju (Europe) (En+En+En,Fr,De)" - rom ( name "3 Games in 1 - Rugrats - I Gotta Go Party + SpongeBob SquarePants - SuperSponge + Tak and the Power of Juju (Europe) (En+En+En,Fr,De).gba" size 16777216 crc 6721794B md5 0EB8E248DAC5B8F9730D818617ED54F4 sha1 7E93942ED7264C46B7767B4ED2BAA8BFC1ADD8F2 ) + rom ( name "3 Games in 1 - Rugrats - I Gotta Go Party + SpongeBob SquarePants - SuperSponge + Tak and the Power of Juju (Europe) (En+En+En,Fr,De).gba" size 16777216 crc 6721794b sha1 7E93942ED7264C46B7767B4ED2BAA8BFC1ADD8F2 ) +) + +game ( + name "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (Europe)" + description "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (Europe)" + rom ( name "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (Europe).gba" size 4194304 crc 4fbc3f62 sha1 034F886B18821A00CE7F98FDD91C1C164800BDEF ) +) + +game ( + name "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (USA)" + description "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (USA)" + rom ( name "3 Games in One - Darts + Roll-a-Ball + Shuffle Bowl (USA).gba" size 4194304 crc aafc9afa sha1 A085803150CC3685B946F4C617D1D833E602A47B ) ) game ( name "3 Games in One! - Breakout + Centipede + Warlords (USA)" description "3 Games in One! - Breakout + Centipede + Warlords (USA)" - rom ( name "3 Games in One! - Breakout + Centipede + Warlords (USA).gba" size 4194304 crc 02E0CCA4 md5 CAB2A6BB0D3C754CCF75AC3B3DC94CB0 sha1 E91E58C62363FB10DD4FFCAEB09C98CA6B9B5A77 ) + rom ( name "3 Games in One! - Breakout + Centipede + Warlords (USA).gba" size 4194304 crc 02e0cca4 sha1 E91E58C62363FB10DD4FFCAEB09C98CA6B9B5A77 ) ) game ( name "3 Games in One! - Breakout + Centipede + Warlords (Europe) (En,Fr,De,Es,It)" description "3 Games in One! - Breakout + Centipede + Warlords (Europe) (En,Fr,De,Es,It)" - rom ( name "3 Games in One! - Breakout + Centipede + Warlords (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2AF65E94 md5 B6D0BDFB98D0AB084087E7284CB53BB6 sha1 F898DF0332CC62371F35CC1C7C2B9D5C9E95C403 flags verified ) + rom ( name "3 Games in One! - Breakout + Centipede + Warlords (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2af65e94 sha1 F898DF0332CC62371F35CC1C7C2B9D5C9E95C403 flags verified ) ) game ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (USA)" description "3 Games in One! - Super Breakout + Millipede + Lunar Lander (USA)" - rom ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (USA).gba" size 4194304 crc D191B56F md5 1739DDAFB47C12DA4709E9529C103D68 sha1 A520E5FC2FE3605C58EF4844F7FCCFE7F8DDF5D1 ) + rom ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (USA).gba" size 4194304 crc d191b56f sha1 A520E5FC2FE3605C58EF4844F7FCCFE7F8DDF5D1 ) ) game ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (Europe) (En,Fr,De,Es,It)" description "3 Games in One! - Super Breakout + Millipede + Lunar Lander (Europe) (En,Fr,De,Es,It)" - rom ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B6EF1ED0 md5 426846F424D7463A86F637FDB1765080 sha1 D3D6EC5C0817A0375C81167C70D92350996A21DF ) + rom ( name "3 Games in One! - Super Breakout + Millipede + Lunar Lander (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b6ef1ed0 sha1 D3D6EC5C0817A0375C81167C70D92350996A21DF flags verified ) ) game ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (USA)" description "3 Games in One! - Yars' Revenge + Asteroids + Pong (USA)" - rom ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (USA).gba" size 4194304 crc DBD04637 md5 E0D9909F402DAC923114675CE44D6B48 sha1 B437E06D271115DF5897EE68CAF826BCE87D3C2A ) + rom ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (USA).gba" size 4194304 crc dbd04637 sha1 B437E06D271115DF5897EE68CAF826BCE87D3C2A ) ) game ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (Europe) (En,Fr,De,Es,It)" description "3 Games in One! - Yars' Revenge + Asteroids + Pong (Europe) (En,Fr,De,Es,It)" - rom ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc F42B4E70 md5 0AB0992240121F5E8F9A5D75AAB79A15 sha1 5BC5699E3B877FDA022A3A798B46F515FF4F32E6 flags verified ) + rom ( name "3 Games in One! - Yars' Revenge + Asteroids + Pong (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc f42b4e70 sha1 5BC5699E3B877FDA022A3A798B46F515FF4F32E6 flags verified ) ) game ( name "4 Games on One Game Pak (Nicktoons) (USA)" description "4 Games on One Game Pak (Nicktoons) (USA)" - rom ( name "4 Games on One Game Pak (Nicktoons) (USA).gba" size 33554432 crc CAC0C0D8 md5 E3BBD6705ED20F911A03A2DD184139F5 sha1 C906145594DE76A1D03578FB03635DE62CCE44BA ) + rom ( name "4 Games on One Game Pak (Nicktoons) (USA).gba" size 33554432 crc cac0c0d8 sha1 C906145594DE76A1D03578FB03635DE62CCE44BA flags verified ) ) game ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It)" description "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It)" - rom ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It).gba" size 33554432 crc 04A40017 md5 D366D5B909B3AFBDD3BA87C6D2B2F1F9 sha1 A99BBC7EC018AF85260669917939004BAABF4AC1 ) + rom ( name "4 Games on One Game Pak (Racing) (USA) (En,Fr,De,Es,It).gba" size 33554432 crc 04a40017 sha1 A99BBC7EC018AF85260669917939004BAABF4AC1 ) ) game ( name "Ab durch die Hecke (Germany)" description "Ab durch die Hecke (Germany)" - rom ( name "Ab durch die Hecke (Germany).gba" size 8388608 crc 31E57A19 md5 7A69B9897A61950F9ACAB26329A788E6 sha1 05FC0931ECBDFAED18FFD59DF86FA36A7ED6DA9D ) + rom ( name "Ab durch die Hecke (Germany).gba" size 8388608 crc 31e57a19 sha1 05FC0931ECBDFAED18FFD59DF86FA36A7ED6DA9D ) ) game ( name "Ace Combat Advance (USA, Europe)" description "Ace Combat Advance (USA, Europe)" - rom ( name "Ace Combat Advance (USA, Europe).gba" size 4194304 crc 43F5E157 md5 4E46DD3AE5C9C70C49587D093517049A sha1 856A08E8F60F817B96ADD5BF2F6DB186BEA832EF flags verified ) + rom ( name "Ace Combat Advance (USA, Europe).gba" size 4194304 crc 43f5e157 sha1 856A08E8F60F817B96ADD5BF2F6DB186BEA832EF flags verified ) ) game ( name "Ace Lightning (Europe)" description "Ace Lightning (Europe)" - rom ( name "Ace Lightning (Europe).gba" size 4194304 crc E94AAFC9 md5 21F4383D59BB113B4495BE56E30C0C53 sha1 51D36AA7C16CDF8BCA93E40F6C680F54ED3519F2 flags verified ) + rom ( name "Ace Lightning (Europe).gba" size 4194304 crc e94aafc9 sha1 51D36AA7C16CDF8BCA93E40F6C680F54ED3519F2 flags verified ) ) game ( name "Acrobat Kid (Japan)" description "Acrobat Kid (Japan)" - rom ( name "Acrobat Kid (Japan).gba" size 4194304 crc 71720E98 md5 B14872072D464BE5DF4F1A1D09C158F6 sha1 63BDFE94F51B1E6138EE25FE01549487667ECEA1 ) + rom ( name "Acrobat Kid (Japan).gba" size 4194304 crc 71720e98 sha1 63BDFE94F51B1E6138EE25FE01549487667ECEA1 ) ) game ( name "Action Man - Robot Atak (Europe) (En,Fr,De,Es,It)" description "Action Man - Robot Atak (Europe) (En,Fr,De,Es,It)" - rom ( name "Action Man - Robot Atak (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc D07214A2 md5 D4FECD09B810DBA8A76C5766E713E49F sha1 D74A7495013CD7DB207B4B3825F70B2D213FC658 flags verified ) + rom ( name "Action Man - Robot Atak (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc d07214a2 sha1 D74A7495013CD7DB207B4B3825F70B2D213FC658 flags verified ) ) game ( name "Action Replay (Europe) (En,Fr,De,It) (v3.3) (Unl)" description "Action Replay (Europe) (En,Fr,De,It) (v3.3) (Unl)" - rom ( name "Action Replay (Europe) (En,Fr,De,It) (v3.3) (Unl).gba" size 262144 crc 4304BD2D md5 A4837934FFE072AA692D7BDB1100E34D sha1 ABED6DE60CB45CAEC8297060895BE3E720C4FB6D ) + rom ( name "Action Replay (Europe) (En,Fr,De,It) (v3.3) (Unl).gba" size 262144 crc 4304bd2d sha1 ABED6DE60CB45CAEC8297060895BE3E720C4FB6D ) ) game ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Alt 1) (Unl)" description "Action Replay GBX (Europe) (En,Fr,De,It) (Alt 1) (Unl)" - rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Alt 1) (Unl).gba" size 262144 crc 45BB6F4E md5 1EFA00A76962E01D5A0AEBEB7B0EF8CB sha1 6F1F797C4F2C7751BE8783ADB159A27849C2E2B7 ) + rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Alt 1) (Unl).gba" size 262144 crc 45bb6f4e sha1 6F1F797C4F2C7751BE8783ADB159A27849C2E2B7 ) ) game ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Unl)" description "Action Replay GBX (Europe) (En,Fr,De,It) (Unl)" - rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Unl).gba" size 262144 crc 18CE5322 md5 6667961AEAA0EA3E8211AA83CD1BCD11 sha1 3FC60FA1B564AFCC6F70E3B8A106158E03BBB463 ) + rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (Unl).gba" size 262144 crc 18ce5322 sha1 3FC60FA1B564AFCC6F70E3B8A106158E03BBB463 ) ) game ( name "Action Replay GBX (Europe) (En,Fr,De,It) (v3.1) (Unl)" description "Action Replay GBX (Europe) (En,Fr,De,It) (v3.1) (Unl)" - rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (v3.1) (Unl).gba" size 262144 crc 3DB7A213 md5 55440B63727CA5D2BA26E5FE240D97AD sha1 AA94001DA07E9B9B737CCD980DC0E68C3DC1CDF3 ) + rom ( name "Action Replay GBX (Europe) (En,Fr,De,It) (v3.1) (Unl).gba" size 262144 crc 3db7a213 sha1 AA94001DA07E9B9B737CCD980DC0E68C3DC1CDF3 ) ) game ( name "Action Replay GBX (Europe) (Unl)" description "Action Replay GBX (Europe) (Unl)" - rom ( name "Action Replay GBX (Europe) (Unl).gba" size 262144 crc 5AD72359 md5 136D8CE4DB69B232133585F3BAC449BE sha1 EE4815180741C99BA75DE06A95AA7536D6264152 ) + rom ( name "Action Replay GBX (Europe) (Unl).gba" size 262144 crc 5ad72359 sha1 EE4815180741C99BA75DE06A95AA7536D6264152 ) ) game ( name "Action Replay MAX (Europe) (Unl)" description "Action Replay MAX (Europe) (Unl)" - rom ( name "Action Replay MAX (Europe) (Unl).gba" size 1048576 crc 3FC75439 md5 59F5CB9F76BBED3AFCFA391943C17633 sha1 D91EAE25091FC38382F751C922383CF0D756127B ) + rom ( name "Action Replay MAX (Europe) (Unl).gba" size 1048576 crc 3fc75439 sha1 D91EAE25091FC38382F751C922383CF0D756127B ) ) game ( name "Activision Anthology (USA)" description "Activision Anthology (USA)" - rom ( name "Activision Anthology (USA).gba" size 8388608 crc 14A28D68 md5 5F3567DD3487F600DD2962C2FE73844F sha1 5125BBBBF1DF7782590D99273735826636A2F9BA flags verified ) + rom ( name "Activision Anthology (USA).gba" size 8388608 crc 14a28d68 sha1 5125BBBBF1DF7782590D99273735826636A2F9BA flags verified ) ) game ( name "Advance GT2 (Japan) (En)" description "Advance GT2 (Japan) (En)" - rom ( name "Advance GT2 (Japan) (En).gba" size 8388608 crc EDCB7D46 md5 B1CA40E6E5815DA256890ECAAB1B5D73 sha1 C3988CDA910F181AD989D3E157F4EBDC405ECDA3 ) + rom ( name "Advance GT2 (Japan) (En).gba" size 8388608 crc edcb7d46 sha1 C3988CDA910F181AD989D3E157F4EBDC405ECDA3 ) ) game ( name "Advance GTA (Japan) (En)" description "Advance GTA (Japan) (En)" - rom ( name "Advance GTA (Japan) (En).gba" size 8388608 crc FDC82E98 md5 65FB37341BB23E897DEAA49E17EE3BC0 sha1 9D8C6C6242F4C61886AAFCAAB602CE80DFF3A226 ) + rom ( name "Advance GTA (Japan) (En).gba" size 8388608 crc fdc82e98 sha1 9D8C6C6242F4C61886AAFCAAB602CE80DFF3A226 ) +) + +game ( + name "Advance GTA (Japan) (En) (Rev 1)" + description "Advance GTA (Japan) (En) (Rev 1)" + rom ( name "Advance GTA (Japan) (En) (Rev 1).gba" size 8388608 crc fca59484 sha1 D93ABA5E7F1195F357578106940E2BD916DCF02D flags verified ) ) game ( name "Advance Guardian Heroes (USA)" description "Advance Guardian Heroes (USA)" - rom ( name "Advance Guardian Heroes (USA).gba" size 8388608 crc C501917F md5 A26C440065D89F56275644FFA34140EF sha1 D518D0A4818CC356ED79B29BC3C0E2264C0C2D07 flags verified ) + rom ( name "Advance Guardian Heroes (USA).gba" size 8388608 crc c501917f sha1 D518D0A4818CC356ED79B29BC3C0E2264C0C2D07 flags verified ) ) game ( name "Advance Guardian Heroes (Japan)" description "Advance Guardian Heroes (Japan)" - rom ( name "Advance Guardian Heroes (Japan).gba" size 8388608 crc 1527CA8C md5 53CF5670A528EF46D6D240E6C6C0C9E2 sha1 8899DEC74351FDF5E4A7D9EBA4265BFB6CDA0895 ) + rom ( name "Advance Guardian Heroes (Japan).gba" size 8388608 crc 1527ca8c sha1 8899DEC74351FDF5E4A7D9EBA4265BFB6CDA0895 ) ) game ( name "Advance Guardian Heroes (Europe) (En,Fr)" description "Advance Guardian Heroes (Europe) (En,Fr)" - rom ( name "Advance Guardian Heroes (Europe) (En,Fr).gba" size 8388608 crc 2487B85B md5 411574E9119177482DC07449962A904A sha1 4AB416AB90CDC6BAD186C421D55C06603F2ADAAF flags verified ) + rom ( name "Advance Guardian Heroes (Europe) (En,Fr).gba" size 8388608 crc 2487b85b sha1 4AB416AB90CDC6BAD186C421D55C06603F2ADAAF flags verified ) ) game ( name "Advance Rally (Japan) (En)" description "Advance Rally (Japan) (En)" - rom ( name "Advance Rally (Japan) (En).gba" size 8388608 crc 86ED2599 md5 A822DD94AD89EA5FE660A2564D6558A5 sha1 020FB5BD11D39AEE583FB0E2FEA848ED2BBE0BF2 ) + rom ( name "Advance Rally (Japan) (En).gba" size 8388608 crc 86ed2599 sha1 020FB5BD11D39AEE583FB0E2FEA848ED2BBE0BF2 ) ) game ( name "Advance Wars (USA)" description "Advance Wars (USA)" - rom ( name "Advance Wars (USA).gba" size 4194304 crc DBEF116C md5 27F322F5CD535297AB21BC4A41CBFC12 sha1 D0A0A4CFE9B95AC7118F7EF476F014CA0242EB65 flags verified ) + rom ( name "Advance Wars (USA).gba" size 4194304 crc dbef116c sha1 D0A0A4CFE9B95AC7118F7EF476F014CA0242EB65 flags verified ) ) game ( name "Advance Wars (Europe) (En,Fr,De,Es)" description "Advance Wars (Europe) (En,Fr,De,Es)" - rom ( name "Advance Wars (Europe) (En,Fr,De,Es).gba" size 8388608 crc 66FB29E9 md5 F4C2B2FDA444DCEC1274844B9A764D64 sha1 D5F06A82C3E5F963EF169763EDC2D691FED8124E flags verified ) + rom ( name "Advance Wars (Europe) (En,Fr,De,Es).gba" size 8388608 crc 66fb29e9 sha1 D5F06A82C3E5F963EF169763EDC2D691FED8124E flags verified ) ) game ( name "Advance Wars (USA) (Rev 1)" description "Advance Wars (USA) (Rev 1)" - rom ( name "Advance Wars (USA) (Rev 1).gba" size 4194304 crc 26FD0FC9 md5 04775A93461D24CF1A7E3346D244E516 sha1 15053499D5B3F49128A941D7F2D84876F5424D0C ) + rom ( name "Advance Wars (USA) (Rev 1).gba" size 4194304 crc 26fd0fc9 sha1 15053499D5B3F49128A941D7F2D84876F5424D0C flags verified ) ) game ( - name "Advance Wars 2 - Black Hole Rising (USA, Australia)" - description "Advance Wars 2 - Black Hole Rising (USA, Australia)" - rom ( name "Advance Wars 2 - Black Hole Rising (USA, Australia).gba" size 8388608 crc 5AD0E571 md5 46599031EF71117C587BD3666C326C07 sha1 14DD0B22C894865867AFF89E8116B2DFFAE25605 flags verified ) + name "Advance Wars (USA) (Wii U Virtual Console)" + description "Advance Wars (USA) (Wii U Virtual Console)" + rom ( name "Advance Wars (USA) (Wii U Virtual Console).gba" size 4194304 crc bde36f98 sha1 44551654068EAC31E29DE2F8D78059A1B1F14347 flags verified ) +) + +game ( + name "Advance Wars (Europe) (En,Fr,De,Es) (Wii U Virtual Console)" + description "Advance Wars (Europe) (En,Fr,De,Es) (Wii U Virtual Console)" + rom ( name "Advance Wars (Europe) (En,Fr,De,Es) (Wii U Virtual Console).gba" size 8388608 crc 8400759c sha1 5AB62A81E34C5786E879446BD4DEA5CA071EB94B flags verified ) +) + +game ( + name "Advance Wars 2 - Black Hole Rising (USA)" + description "Advance Wars 2 - Black Hole Rising (USA)" + rom ( name "Advance Wars 2 - Black Hole Rising (USA).gba" size 8388608 crc 5ad0e571 sha1 14DD0B22C894865867AFF89E8116B2DFFAE25605 flags verified ) ) game ( name "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It)" description "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It)" - rom ( name "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5A09AAE6 md5 AD4CF738F97416827BAF17D6C43576D7 sha1 8F78398A33254FF2BA935B5BCCFDCCCCE661684F flags verified ) + rom ( name "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5a09aae6 sha1 8F78398A33254FF2BA935B5BCCFDCCCCE661684F flags verified ) +) + +game ( + name "Advance Wars 2 - Black Hole Rising (USA) (Wii U Virtual Console)" + description "Advance Wars 2 - Black Hole Rising (USA) (Wii U Virtual Console)" + rom ( name "Advance Wars 2 - Black Hole Rising (USA) (Wii U Virtual Console).gba" size 8388608 crc b6ffdde0 sha1 F6DF48F6D7A36965F795023C039FB05985418132 flags verified ) +) + +game ( + name "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Advance Wars 2 - Black Hole Rising (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 8388608 crc bf33782f sha1 C0D436830EBA89D8F2F609C1E2E6BCD276822677 flags verified ) ) game ( name "Adventure of Tokyo Disney Sea (Japan)" description "Adventure of Tokyo Disney Sea (Japan)" - rom ( name "Adventure of Tokyo Disney Sea (Japan).gba" size 4194304 crc 5781ACAF md5 84E3389B9A4A120959B37C15B5BCC460 sha1 FB9ADB7E1F4A5F3B6002FF7E62DCD68A69E9BE25 ) + rom ( name "Adventure of Tokyo Disney Sea (Japan).gba" size 4194304 crc 5781acaf sha1 FB9ADB7E1F4A5F3B6002FF7E62DCD68A69E9BE25 ) ) game ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (USA, Europe)" description "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (USA, Europe)" - rom ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (USA, Europe).gba" size 4194304 crc D2CED674 md5 FCE7ADB1C33F9A75A03E1C425CB9930D sha1 5A4B0F5782E42F04040A4B0FC0073E726E725681 flags verified ) + rom ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (USA, Europe).gba" size 4194304 crc d2ced674 sha1 5A4B0F5782E42F04040A4B0FC0073E726E725681 flags verified ) ) game ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (Germany)" description "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (Germany)" - rom ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (Germany).gba" size 4194304 crc 3690C0FD md5 FCBA36D00EB7347A5836F1CFB8B31CC1 sha1 290F38966500A19E8151773E20335CB2BDF0B8C3 ) + rom ( name "Adventures of Jimmy Neutron Boy Genius vs. Jimmy Negatron, The (Germany).gba" size 4194304 crc 3690c0fd sha1 290F38966500A19E8151773E20335CB2BDF0B8C3 ) ) game ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe)" description "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe)" - rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe).gba" size 4194304 crc D59D753B md5 2C2E9B38C21FD511B4F1871B12183416 sha1 16BA112F07D02484FEBD554F902BB18776144186 flags verified ) + rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Attack of the Twonkies (USA, Europe).gba" size 4194304 crc d59d753b sha1 16BA112F07D02484FEBD554F902BB18776144186 flags verified ) ) game ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe)" description "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe)" - rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe).gba" size 4194304 crc 67756000 md5 BE7B93FDECA8E23CAF4B59B4490999CA sha1 68778C93FC16D06B97462174D91035CB0D0D8BD5 flags verified ) -) - -game ( - name "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" - description "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" - rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (Europe).gba" size 4194304 crc A7E98EBE md5 2548856ED56765E0F8267175BC1AC171 sha1 11050975C211550A8BEA751212CEB8856DAEA759 ) -) - -game ( - name "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta)" - description "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta)" - rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta).gba" size 4194304 crc 6F3EA564 md5 A7763D58C7FD18307CEFD9BCB6391D89 sha1 3F88084C501FB15820F6AD9A9C87AC21AF3B59EB ) + rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe).gba" size 4194304 crc 67756000 sha1 68778C93FC16D06B97462174D91035CB0D0D8BD5 flags verified ) ) game ( name "Aero the Acro-Bat - Rascal Rival Revenge (USA)" description "Aero the Acro-Bat - Rascal Rival Revenge (USA)" - rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (USA).gba" size 4194304 crc B47AC020 md5 266E48E50827E202A9E74255BF29A554 sha1 CDBC609DF128127D05C435F59B781958C0E751FD ) + rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (USA).gba" size 4194304 crc b47ac020 sha1 CDBC609DF128127D05C435F59B781958C0E751FD ) +) + +game ( + name "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" + description "Aero the Acro-Bat - Rascal Rival Revenge (Europe)" + rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (Europe).gba" size 4194304 crc a7e98ebe sha1 11050975C211550A8BEA751212CEB8856DAEA759 flags verified ) +) + +game ( + name "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta)" + description "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta)" + rom ( name "Aero the Acro-Bat - Rascal Rival Revenge (Europe) (Beta).gba" size 4194304 crc 6f3ea564 sha1 3F88084C501FB15820F6AD9A9C87AC21AF3B59EB ) ) game ( name "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It)" description "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It)" - rom ( name "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 90D759E2 md5 D9EA8C0A5CB934DDC7801389FABA43E2 sha1 43261F3D13CFD75034D0836F91F64AE800273C06 flags verified ) + rom ( name "Agassi Tennis Generation (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 90d759e2 sha1 43261F3D13CFD75034D0836F91F64AE800273C06 flags verified ) ) game ( name "Agassi Tennis Generation (USA)" description "Agassi Tennis Generation (USA)" - rom ( name "Agassi Tennis Generation (USA).gba" size 4194304 crc 8BA179B8 md5 4411D6AC05F6E818A16409894D1EC943 sha1 1797251886D165E136CE6BA564AD8C8EC865D829 ) + rom ( name "Agassi Tennis Generation (USA).gba" size 4194304 crc 8ba179b8 sha1 1797251886D165E136CE6BA564AD8C8EC865D829 ) ) game ( name "Agent Hugo - Roborumble (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" description "Agent Hugo - Roborumble (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" - rom ( name "Agent Hugo - Roborumble (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gba" size 4194304 crc 83BC2D2C md5 02FE9812BC5022835D55CE2DDFEE95D7 sha1 AB2C6FAEF04BA4D69EAE936E0DBAA9E776D12EDF flags verified ) + rom ( name "Agent Hugo - Roborumble (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gba" size 4194304 crc 83bc2d2c sha1 AB2C6FAEF04BA4D69EAE936E0DBAA9E776D12EDF flags verified ) ) game ( name "Aggressive Inline (USA)" description "Aggressive Inline (USA)" - rom ( name "Aggressive Inline (USA).gba" size 8388608 crc 3A44FCD5 md5 4E8B17BB4B77CD5568B678596C55A8BB sha1 DF41EF94380E074257424F4725738F2ED7AE68B6 ) + rom ( name "Aggressive Inline (USA).gba" size 8388608 crc 3a44fcd5 sha1 DF41EF94380E074257424F4725738F2ED7AE68B6 ) ) game ( name "Aggressive Inline (Europe) (En,Fr,De)" description "Aggressive Inline (Europe) (En,Fr,De)" - rom ( name "Aggressive Inline (Europe) (En,Fr,De).gba" size 8388608 crc A2F6BCDE md5 0C3521DC74150B501ABA964D4C2A0FC3 sha1 05AB06B8988D0BB6F037B121F73BC40644AFF4E8 flags verified ) + rom ( name "Aggressive Inline (Europe) (En,Fr,De).gba" size 8388608 crc a2f6bcde sha1 05AB06B8988D0BB6F037B121F73BC40644AFF4E8 flags verified ) +) + +game ( + name "Aging Cartridge (World)" + description "Aging Cartridge (World)" + rom ( name "Aging Cartridge (World).gba" size 2097152 crc bbb6a960 sha1 C67E0A5E26EA5EBA2BC11C99D003027A96E44060 flags verified ) ) game ( name "Aigle de Guerre, L' (France)" description "Aigle de Guerre, L' (France)" - rom ( name "Aigle de Guerre, L' (France).gba" size 8388608 crc 36A0E152 md5 DEC3B16B1A70BCA1B467654C01B486D3 sha1 567809BF35D62418A69E469D0CFA9993A889C030 ) + rom ( name "Aigle de Guerre, L' (France).gba" size 8388608 crc 36a0e152 sha1 567809BF35D62418A69E469D0CFA9993A889C030 ) ) game ( name "AirForce Delta II (Japan) (En,Ja,Fr,De)" description "AirForce Delta II (Japan) (En,Ja,Fr,De)" - rom ( name "AirForce Delta II (Japan) (En,Ja,Fr,De).gba" size 4194304 crc 58A972DF md5 7109869B364D162A673B25B5604EBB57 sha1 34AC6B1AF9AB1E016DB11F5AD28042757A68D1F4 ) + rom ( name "AirForce Delta II (Japan) (En,Ja,Fr,De).gba" size 4194304 crc 58a972df sha1 34AC6B1AF9AB1E016DB11F5AD28042757A68D1F4 ) ) game ( name "AirForce Delta Storm (USA) (En,Ja,Fr,De)" description "AirForce Delta Storm (USA) (En,Ja,Fr,De)" - rom ( name "AirForce Delta Storm (USA) (En,Ja,Fr,De).gba" size 4194304 crc EBF757B8 md5 3F729EBA45634801650D0CA02E2AD0BF sha1 7BC53480A43ADA2AAD32D798AB00B6E761726728 flags verified ) + rom ( name "AirForce Delta Storm (USA) (En,Ja,Fr,De).gba" size 4194304 crc ebf757b8 sha1 7BC53480A43ADA2AAD32D798AB00B6E761726728 flags verified ) ) game ( name "Aka-chan Doubutsuen (Japan)" description "Aka-chan Doubutsuen (Japan)" - rom ( name "Aka-chan Doubutsuen (Japan).gba" size 4194304 crc B50CD166 md5 A5C6B967E5D7C35D2ABA50BBF4C5657C sha1 9A0623A8680C4CF9B745F940B99DA0A192764828 ) + rom ( name "Aka-chan Doubutsuen (Japan).gba" size 4194304 crc b50cd166 sha1 9A0623A8680C4CF9B745F940B99DA0A192764828 ) +) + +game ( + name "Aka-chan Doubutsuen (Japan) (Rev 1)" + description "Aka-chan Doubutsuen (Japan) (Rev 1)" + rom ( name "Aka-chan Doubutsuen (Japan) (Rev 1).gba" size 4194304 crc c1072e26 sha1 634624C77C90A8FF40BEC9046133C50041EFC49B flags verified ) ) game ( name "Akumajou Dracula - Circle of the Moon (Japan)" description "Akumajou Dracula - Circle of the Moon (Japan)" - rom ( name "Akumajou Dracula - Circle of the Moon (Japan).gba" size 8388608 crc F3E41D73 md5 8DDB166CF79606F116F6BDF3E4BDBBE2 sha1 45070D7237F6C71306D83C1E7353F50205D9233E ) + rom ( name "Akumajou Dracula - Circle of the Moon (Japan).gba" size 8388608 crc f3e41d73 sha1 45070D7237F6C71306D83C1E7353F50205D9233E flags verified ) ) game ( name "Aladdin (Japan)" description "Aladdin (Japan)" - rom ( name "Aladdin (Japan).gba" size 4194304 crc 587F1AEF md5 70245E4D52CFB1AF2533FEDC6191DCB5 sha1 B29C55B063F81D829992DA63BD8BD3C25B0C90D7 ) + rom ( name "Aladdin (Japan).gba" size 4194304 crc 587f1aef sha1 B29C55B063F81D829992DA63BD8BD3C25B0C90D7 ) ) game ( name "Aladdin (Europe) (En,Fr,De,Es)" description "Aladdin (Europe) (En,Fr,De,Es)" - rom ( name "Aladdin (Europe) (En,Fr,De,Es).gba" size 4194304 crc 594FBB7C md5 8ED4304E943B553F8FF3ABC1E66EA91E sha1 38C9A3B3DE0679484E025534A2EB6FB1F790A46D flags verified ) + rom ( name "Aladdin (Europe) (En,Fr,De,Es).gba" size 4194304 crc 594fbb7c sha1 38C9A3B3DE0679484E025534A2EB6FB1F790A46D flags verified ) ) game ( name "Aladdin (USA) (En,Fr,De,Es)" description "Aladdin (USA) (En,Fr,De,Es)" - rom ( name "Aladdin (USA) (En,Fr,De,Es).gba" size 4194304 crc 40B383F6 md5 4BDA2A3E0249DFD09330DABC3AA20978 sha1 3CFE653A54F3BC9F3AD20234DE680EBFC4145CF6 ) + rom ( name "Aladdin (USA) (En,Fr,De,Es).gba" size 4194304 crc 40b383f6 sha1 3CFE653A54F3BC9F3AD20234DE680EBFC4145CF6 ) ) game ( name "Aleck Bordon Adventure - Tower & Shaft Advance (Japan)" description "Aleck Bordon Adventure - Tower & Shaft Advance (Japan)" - rom ( name "Aleck Bordon Adventure - Tower & Shaft Advance (Japan).gba" size 4194304 crc E068728F md5 70541C3E9C5D18B151A5D41C79134CC9 sha1 2DEF9D7EA29A0ED5845B354E433E0A55E979F636 ) + rom ( name "Aleck Bordon Adventure - Tower & Shaft Advance (Japan).gba" size 4194304 crc e068728f sha1 2DEF9D7EA29A0ED5845B354E433E0A55E979F636 ) ) game ( - name "Alex Ferguson's Player Manager 2002 (Europe) (En,Fr,De,Es,It,Nl)" - description "Alex Ferguson's Player Manager 2002 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Alex Ferguson's Player Manager 2002 (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 92F99295 md5 E2E9FFE86DA23D3CD278D78689BB1FE6 sha1 A870E1321A8AD3317CD695FCC0C713441C25919F ) + name "Alex Ferguson's Player Manager 2002 ~ Total Soccer Manager (Europe) (En,Fr,De,Es,It,Nl)" + description "Alex Ferguson's Player Manager 2002 ~ Total Soccer Manager (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Alex Ferguson's Player Manager 2002 ~ Total Soccer Manager (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 92f99295 sha1 A870E1321A8AD3317CD695FCC0C713441C25919F ) ) game ( name "Alex Rider - Stormbreaker (USA)" description "Alex Rider - Stormbreaker (USA)" - rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc CCA55DFD md5 4B5AEE04F0F61C5EF9343524BD2AC1D4 sha1 E9BA9D340701173CCD3A4D279630E1541ED96A73 ) + rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc cca55dfd sha1 E9BA9D340701173CCD3A4D279630E1541ED96A73 ) ) game ( name "Alex Rider - Stormbreaker (Europe) (En,Fr,De,Es)" description "Alex Rider - Stormbreaker (Europe) (En,Fr,De,Es)" - rom ( name "Alex Rider - Stormbreaker (Europe) (En,Fr,De,Es).gba" size 4194304 crc 25E8E2CD md5 864D9A4E885F1F32A9072A606C739006 sha1 659DBDE917FC74D1CEC3E41D1FB4CDD249AE04A0 flags verified ) + rom ( name "Alex Rider - Stormbreaker (Europe) (En,Fr,De,Es).gba" size 4194304 crc 25e8e2cd sha1 659DBDE917FC74D1CEC3E41D1FB4CDD249AE04A0 flags verified ) ) game ( name "Alien Hominid (Europe) (En,Fr,De,Es,It)" description "Alien Hominid (Europe) (En,Fr,De,Es,It)" - rom ( name "Alien Hominid (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc DFF47236 md5 18EF4EC828A4BF14B6FD241230BB349A sha1 9D0E6BBBE6A364C5C190AA2695F8B58FFCCA8E21 ) + rom ( name "Alien Hominid (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc dff47236 sha1 9D0E6BBBE6A364C5C190AA2695F8B58FFCCA8E21 ) ) game ( name "Alienators - Evolution Continues (USA, Europe)" description "Alienators - Evolution Continues (USA, Europe)" - rom ( name "Alienators - Evolution Continues (USA, Europe).gba" size 4194304 crc 0D694CA4 md5 5EBA0EF1C24F1B003B3063BEB808CE6C sha1 FB691C5E21FA388D75497E9090DB82DEC881E422 ) + rom ( name "Alienators - Evolution Continues (USA, Europe).gba" size 4194304 crc 0d694ca4 sha1 FB691C5E21FA388D75497E9090DB82DEC881E422 ) ) game ( name "All Grown Up! - Express Yourself (USA, Europe)" description "All Grown Up! - Express Yourself (USA, Europe)" - rom ( name "All Grown Up! - Express Yourself (USA, Europe).gba" size 4194304 crc E9C9DD2B md5 D429899CFD9A4858592F34CE9527A159 sha1 C9B6D8D4A6C8998FB7770B13049077F572859427 ) + rom ( name "All Grown Up! - Express Yourself (USA, Europe).gba" size 4194304 crc e9c9dd2b sha1 C9B6D8D4A6C8998FB7770B13049077F572859427 ) ) game ( name "All-Star Baseball 2003 (USA)" description "All-Star Baseball 2003 (USA)" - rom ( name "All-Star Baseball 2003 (USA).gba" size 4194304 crc E30691FE md5 0B2772662E6DF22BD3E5DBB84D9D9E55 sha1 EBCC0100A6D62F1BBE359FE9CC4BAA3C61FB213F ) + rom ( name "All-Star Baseball 2003 (USA).gba" size 4194304 crc e30691fe sha1 EBCC0100A6D62F1BBE359FE9CC4BAA3C61FB213F ) ) game ( - name "All-Star Baseball 2004 (USA)" - description "All-Star Baseball 2004 (USA)" - rom ( name "All-Star Baseball 2004 (USA).gba" size 8388608 crc 60E2DB03 md5 9A7D740691276D4F33CF090BC62BA379 sha1 29E168A84E51C3B765E345BAEE6910433F298993 ) + name "All-Star Baseball 2004 (USA) (Beta 2)" + description "All-Star Baseball 2004 (USA) (Beta 2)" + rom ( name "All-Star Baseball 2004 (USA) (Beta 2).gba" size 8388608 crc 6aa9b41e sha1 E6AD581061116DAA69F12FAC798B4E7E81F6F8B2 ) ) game ( - name "All-Star Baseball 2004 (USA) (Beta)" - description "All-Star Baseball 2004 (USA) (Beta)" - rom ( name "All-Star Baseball 2004 (USA) (Beta).gba" size 8388608 crc 6AA9B41E md5 766F6E0B917707F098FAF6501207A94C sha1 E6AD581061116DAA69F12FAC798B4E7E81F6F8B2 ) + name "All-Star Baseball 2004 (USA) (Beta 1)" + description "All-Star Baseball 2004 (USA) (Beta 1)" + rom ( name "All-Star Baseball 2004 (USA) (Beta 1).gba" size 8388608 crc d6106c26 sha1 F1D17E2083E0AD5B13162B6EFF550A88BB4EF7C8 ) ) game ( - name "All-Star Baseball 2004 (USA) (Beta) (Alt 1)" - description "All-Star Baseball 2004 (USA) (Beta) (Alt 1)" - rom ( name "All-Star Baseball 2004 (USA) (Beta) (Alt 1).gba" size 8388608 crc D6106C26 md5 B5518F9500708791A1FE10DE6B8C3522 sha1 F1D17E2083E0AD5B13162B6EFF550A88BB4EF7C8 ) -) - -game ( - name "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It)" - description "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It)" - rom ( name "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 654F7916 md5 C7C56AAED390488E4112EF64B51BB2AD sha1 4178BC2C89187DCE127AB64DAC2BECF99FED0679 flags verified ) + name "All-Star Baseball 2004 featuring Derek Jeter (USA)" + description "All-Star Baseball 2004 featuring Derek Jeter (USA)" + rom ( name "All-Star Baseball 2004 featuring Derek Jeter (USA).gba" size 8388608 crc 60e2db03 sha1 29E168A84E51C3B765E345BAEE6910433F298993 ) ) game ( name "Altered Beast - Guardian of the Realms (USA)" description "Altered Beast - Guardian of the Realms (USA)" - rom ( name "Altered Beast - Guardian of the Realms (USA).gba" size 8388608 crc C4955F69 md5 DC96748E298935C8E3D49E362CAFA0B8 sha1 194DC1FFF5578DCD8A2A6914647F1B67334F2A8A flags verified ) + rom ( name "Altered Beast - Guardian of the Realms (USA).gba" size 8388608 crc c4955f69 sha1 194DC1FFF5578DCD8A2A6914647F1B67334F2A8A flags verified ) +) + +game ( + name "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It)" + description "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It)" + rom ( name "Altered Beast - Guardian of the Realms (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 654f7916 sha1 4178BC2C89187DCE127AB64DAC2BECF99FED0679 flags verified ) ) game ( name "Amazing Virtual Sea-Monkeys, The (USA)" description "Amazing Virtual Sea-Monkeys, The (USA)" - rom ( name "Amazing Virtual Sea-Monkeys, The (USA).gba" size 4194304 crc 3484F139 md5 8989A8830651CA9705C676676AAF4894 sha1 D596FE5C59B6639FC5E1840BCC90086BCB56F7D0 ) + rom ( name "Amazing Virtual Sea-Monkeys, The (USA).gba" size 4194304 crc 3484f139 sha1 D596FE5C59B6639FC5E1840BCC90086BCB56F7D0 ) ) game ( name "American Bass Challenge (USA)" description "American Bass Challenge (USA)" - rom ( name "American Bass Challenge (USA).gba" size 4194304 crc D76AD62D md5 61D4355A0731C3150C36B5A704173C70 sha1 1FC03CCA393DDBC633D309AAE95B42C89E4D0E96 ) + rom ( name "American Bass Challenge (USA).gba" size 4194304 crc d76ad62d sha1 1FC03CCA393DDBC633D309AAE95B42C89E4D0E96 ) ) game ( name "American Dragon - Jake Long - Rise of the Huntsclan (USA, Europe) (En,Fr,De,Es,It)" description "American Dragon - Jake Long - Rise of the Huntsclan (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "American Dragon - Jake Long - Rise of the Huntsclan (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 698377D2 md5 8A46B929F0DC1522FC0CC378685D8337 sha1 4701C8D26CC608109BC01D0EE189AB1FB646EAD8 flags verified ) + rom ( name "American Dragon - Jake Long - Rise of the Huntsclan (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 698377d2 sha1 4701C8D26CC608109BC01D0EE189AB1FB646EAD8 flags verified ) ) game ( name "American Idol (USA)" description "American Idol (USA)" - rom ( name "American Idol (USA).gba" size 16777216 crc F053FFBF md5 E140B67A8A610BE8DE419E4146940359 sha1 13236689DB1E2236673AE59C2A8FF84340A8A8C2 ) -) - -game ( - name "American Tail, An - Fievel's Gold Rush (USA) (En,Es)" - description "American Tail, An - Fievel's Gold Rush (USA) (En,Es)" - rom ( name "American Tail, An - Fievel's Gold Rush (USA) (En,Es).gba" size 4194304 crc 2A882EA6 md5 0051C7B9D4A3908AFEA19DA18813FCBC sha1 F80528CC2265FEA12E661B1DFF1478BF9BDA1C6C ) + rom ( name "American Idol (USA).gba" size 16777216 crc f053ffbf sha1 13236689DB1E2236673AE59C2A8FF84340A8A8C2 ) ) game ( name "American Tail, An - Fievel's Gold Rush (Europe) (En,Fr,De,Es,It)" description "American Tail, An - Fievel's Gold Rush (Europe) (En,Fr,De,Es,It)" - rom ( name "American Tail, An - Fievel's Gold Rush (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc C8EA6D9E md5 2D434F2B0392F91F7715841A122621C1 sha1 AB6E8646B352E54EAAE2E00101EA7FD378AF0E5E ) + rom ( name "American Tail, An - Fievel's Gold Rush (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc c8ea6d9e sha1 AB6E8646B352E54EAAE2E00101EA7FD378AF0E5E ) +) + +game ( + name "American Tail, An - Fievel's Gold Rush (USA) (En,Es)" + description "American Tail, An - Fievel's Gold Rush (USA) (En,Es)" + rom ( name "American Tail, An - Fievel's Gold Rush (USA) (En,Es).gba" size 4194304 crc 2a882ea6 sha1 F80528CC2265FEA12E661B1DFF1478BF9BDA1C6C ) ) game ( name "Angel Collection - Mezase! Gakuen no Fashion Leader (Japan)" description "Angel Collection - Mezase! Gakuen no Fashion Leader (Japan)" - rom ( name "Angel Collection - Mezase! Gakuen no Fashion Leader (Japan).gba" size 8388608 crc DA6555D8 md5 5054B1D5971B01A35E593048F5C43D49 sha1 1B2708FA0015803DE0299E968A1C9F14D12AD7E8 ) + rom ( name "Angel Collection - Mezase! Gakuen no Fashion Leader (Japan).gba" size 8388608 crc da6555d8 sha1 1B2708FA0015803DE0299E968A1C9F14D12AD7E8 ) ) game ( name "Angel Collection 2 - Pichimo ni Narou (Japan)" description "Angel Collection 2 - Pichimo ni Narou (Japan)" - rom ( name "Angel Collection 2 - Pichimo ni Narou (Japan).gba" size 8388608 crc 7B46D462 md5 436325C0208B757B2EFD50E894D8D1C7 sha1 3619766CEDF93045A9213B0D251A169439990CF1 ) + rom ( name "Angel Collection 2 - Pichimo ni Narou (Japan).gba" size 8388608 crc 7b46d462 sha1 3619766CEDF93045A9213B0D251A169439990CF1 ) ) game ( name "Angelique (Japan)" description "Angelique (Japan)" - rom ( name "Angelique (Japan).gba" size 4194304 crc C9D41F35 md5 978F10569B0A00B023016FB5F287C0B6 sha1 CF01DFC9F25C805B9A72524903F742F11570A8EB ) + rom ( name "Angelique (Japan).gba" size 4194304 crc c9d41f35 sha1 CF01DFC9F25C805B9A72524903F742F11570A8EB ) +) + +game ( + name "Animal Crossing - Balloon Fight (USA, Europe)" + description "Animal Crossing - Balloon Fight (USA, Europe)" + rom ( name "Animal Crossing - Balloon Fight (USA, Europe).gba" size 34764 crc aecd98cd sha1 35A417A1A8443F85013E56B7BFF9DCE30797307A flags verified ) +) + +game ( + name "Animal Crossing - Balloon Fight (Japan) (En)" + description "Animal Crossing - Balloon Fight (Japan) (En)" + rom ( name "Animal Crossing - Balloon Fight (Japan) (En).gba" size 34952 crc 2f5f2cfa sha1 647C9AE66E33AB63BF29B63DA4A4E0E32C65C173 flags verified ) +) + +game ( + name "Animal Crossing - Baseball (USA, Europe)" + description "Animal Crossing - Baseball (USA, Europe)" + rom ( name "Animal Crossing - Baseball (USA, Europe).gba" size 35756 crc b8c154c4 sha1 E5CF0BBAB5CAF0DA47DFAE8F6943C01AC0F7E34E flags verified ) +) + +game ( + name "Animal Crossing - Baseball (Japan) (En)" + description "Animal Crossing - Baseball (Japan) (En)" + rom ( name "Animal Crossing - Baseball (Japan) (En).gba" size 35944 crc beb85708 sha1 A7B4CC200CE02E2A7F54458AE28BFD36FADF01AE flags verified ) +) + +game ( + name "Animal Crossing - Clu Clu Land (USA, Europe)" + description "Animal Crossing - Clu Clu Land (USA, Europe)" + rom ( name "Animal Crossing - Clu Clu Land (USA, Europe).gba" size 34972 crc cb7e10af sha1 36E11BC92FCBF426BF2F0EEF62E884C36AE9D8C8 flags verified ) +) + +game ( + name "Animal Crossing - Clu Clu Land (Japan) (En)" + description "Animal Crossing - Clu Clu Land (Japan) (En)" + rom ( name "Animal Crossing - Clu Clu Land (Japan) (En).gba" size 35160 crc b2cfd55e sha1 C7F54A6ABABCF19A97C48A5F63396C71BB7E0E1A flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong (USA, Europe)" + description "Animal Crossing - Donkey Kong (USA, Europe)" + rom ( name "Animal Crossing - Donkey Kong (USA, Europe).gba" size 34908 crc 4b31dce1 sha1 B6FF00168E929B3F61E95F5464EAD21CF0D985DB flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong (Japan) (En)" + description "Animal Crossing - Donkey Kong (Japan) (En)" + rom ( name "Animal Crossing - Donkey Kong (Japan) (En).gba" size 35096 crc 07eae8cd sha1 488A28E5AE27E348A9177D3E79E0D0F790C09333 flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong 3 (USA, Europe)" + description "Animal Crossing - Donkey Kong 3 (USA, Europe)" + rom ( name "Animal Crossing - Donkey Kong 3 (USA, Europe).gba" size 35452 crc 060ce560 sha1 EB6DD9CE3EA488B8C3ECA602369D4D648D0052D2 flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong 3 (Japan) (En)" + description "Animal Crossing - Donkey Kong 3 (Japan) (En)" + rom ( name "Animal Crossing - Donkey Kong 3 (Japan) (En).gba" size 35640 crc 915d8f9f sha1 1D608F779FA7403C880121245C2A749667DE4D5E flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong Jr. (USA, Europe)" + description "Animal Crossing - Donkey Kong Jr. (USA, Europe)" + rom ( name "Animal Crossing - Donkey Kong Jr. (USA, Europe).gba" size 35644 crc 66035612 sha1 4F24678F518F6A4FE21AB99087B55C941F2412BE flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong Jr. (Japan) (En)" + description "Animal Crossing - Donkey Kong Jr. (Japan) (En)" + rom ( name "Animal Crossing - Donkey Kong Jr. (Japan) (En).gba" size 35832 crc 4074cc86 sha1 E651AA1D48680488CCA00CE3716B5D3AB3FC7DEB flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong Jr. Math (USA, Europe)" + description "Animal Crossing - Donkey Kong Jr. Math (USA, Europe)" + rom ( name "Animal Crossing - Donkey Kong Jr. Math (USA, Europe).gba" size 35740 crc 9b531071 sha1 CE259E96D44DDFB651883A24BEB22809F7438533 flags verified ) +) + +game ( + name "Animal Crossing - Donkey Kong Jr. Math (Japan) (En)" + description "Animal Crossing - Donkey Kong Jr. Math (Japan) (En)" + rom ( name "Animal Crossing - Donkey Kong Jr. Math (Japan) (En).gba" size 35928 crc f75deba3 sha1 C5746316C95D7E6AE9BCC445EA9FC9A21B799DD6 flags verified ) +) + +game ( + name "Animal Crossing - Excitebike (USA, Europe)" + description "Animal Crossing - Excitebike (USA, Europe)" + rom ( name "Animal Crossing - Excitebike (USA, Europe).gba" size 36444 crc a0b3e4de sha1 1E72567AEF01CD4463DEA209D789C349862C8CD5 flags verified ) +) + +game ( + name "Animal Crossing - Excitebike (Japan) (En)" + description "Animal Crossing - Excitebike (Japan) (En)" + rom ( name "Animal Crossing - Excitebike (Japan) (En).gba" size 36632 crc 724a3929 sha1 B2625F02B5951DB918A428076867E36230F7F471 flags verified ) +) + +game ( + name "Animal Crossing - Golf (USA, Europe)" + description "Animal Crossing - Golf (USA, Europe)" + rom ( name "Animal Crossing - Golf (USA, Europe).gba" size 35100 crc c83c01ce sha1 5DF38015CA8F3A6A6E9878E0323A08AB0B12B31B flags verified ) +) + +game ( + name "Animal Crossing - Golf (Japan) (En)" + description "Animal Crossing - Golf (Japan) (En)" + rom ( name "Animal Crossing - Golf (Japan) (En).gba" size 35288 crc ef00f27b sha1 C4D96D8F1D232F4922F1838EA94F88F3FE707363 flags verified ) +) + +game ( + name "Animal Crossing - Ice Climber (USA, Europe)" + description "Animal Crossing - Ice Climber (USA, Europe)" + rom ( name "Animal Crossing - Ice Climber (USA, Europe).gba" size 37036 crc 3bec49df sha1 844845B5E1FF4F5F1390C7AFC781C4BB9B62E699 flags verified ) +) + +game ( + name "Animal Crossing - Ice Climber (Japan) (En)" + description "Animal Crossing - Ice Climber (Japan) (En)" + rom ( name "Animal Crossing - Ice Climber (Japan) (En).gba" size 37224 crc 4f1672e2 sha1 7C5058C8839A5E971C6D71401E0C5A5D229F2820 flags verified ) +) + +game ( + name "Animal Crossing - Mario Bros. (USA, Europe)" + description "Animal Crossing - Mario Bros. (USA, Europe)" + rom ( name "Animal Crossing - Mario Bros. (USA, Europe).gba" size 35420 crc aed34405 sha1 23A8D78B462D4E684763A7DB6547B2D951C56934 flags verified ) +) + +game ( + name "Animal Crossing - Mario Bros. (Japan) (En)" + description "Animal Crossing - Mario Bros. (Japan) (En)" + rom ( name "Animal Crossing - Mario Bros. (Japan) (En).gba" size 35608 crc d9e669b3 sha1 9E485F298DE5171BB6D4A66142B020F6D10054F8 flags verified ) +) + +game ( + name "Animal Crossing - Pinball (USA, Europe)" + description "Animal Crossing - Pinball (USA, Europe)" + rom ( name "Animal Crossing - Pinball (USA, Europe).gba" size 34652 crc ba79f589 sha1 67B78383BF9633F30B2EE99251F9AAC924832C75 flags verified ) +) + +game ( + name "Animal Crossing - Pinball (Japan) (En)" + description "Animal Crossing - Pinball (Japan) (En)" + rom ( name "Animal Crossing - Pinball (Japan) (En).gba" size 34840 crc f676010c sha1 ADF83076BFAB59849B49896487BF296D1C6F125E flags verified ) +) + +game ( + name "Animal Crossing - Soccer (USA, Europe)" + description "Animal Crossing - Soccer (USA, Europe)" + rom ( name "Animal Crossing - Soccer (USA, Europe).gba" size 47708 crc 090f168f sha1 9CB498C0951901FE8523E62A98A530D72A25534E flags verified ) +) + +game ( + name "Animal Crossing - Soccer (Japan) (En)" + description "Animal Crossing - Soccer (Japan) (En)" + rom ( name "Animal Crossing - Soccer (Japan) (En).gba" size 47896 crc e007ffb3 sha1 4535BBF7015235DDADAB00C3F0F5C685493CBBEA flags verified ) +) + +game ( + name "Animal Crossing - Super Mario Bros. (USA, Europe)" + description "Animal Crossing - Super Mario Bros. (USA, Europe)" + rom ( name "Animal Crossing - Super Mario Bros. (USA, Europe).gba" size 52396 crc 34970570 sha1 B9B254174B1A7A7BC01A3B72070F7ECE6F343037 flags verified ) +) + +game ( + name "Animal Crossing - Super Mario Bros. (Japan) (En)" + description "Animal Crossing - Super Mario Bros. (Japan) (En)" + rom ( name "Animal Crossing - Super Mario Bros. (Japan) (En).gba" size 52584 crc eede3f63 sha1 3F7193AC0A2113785953A6798DEAC7F315768AB0 flags verified ) +) + +game ( + name "Animal Crossing - Tennis (USA, Europe)" + description "Animal Crossing - Tennis (USA, Europe)" + rom ( name "Animal Crossing - Tennis (USA, Europe).gba" size 35452 crc 2b2a361d sha1 8DE62672330DB8B8E24C4E8B712D03369A4CB5FC flags verified ) +) + +game ( + name "Animal Crossing - Tennis (Japan) (En)" + description "Animal Crossing - Tennis (Japan) (En)" + rom ( name "Animal Crossing - Tennis (Japan) (En).gba" size 35672 crc 384a5e41 sha1 925A993C41B6D28B6AEC896F387F08B85B352AC6 flags verified ) ) game ( name "Animal Mania - Dokidoki Aishou Check (Japan)" description "Animal Mania - Dokidoki Aishou Check (Japan)" - rom ( name "Animal Mania - Dokidoki Aishou Check (Japan).gba" size 4194304 crc 89E6CD89 md5 91410132C661FCE4074EBA939915D543 sha1 3552B82ABDBE38851C607AC572EFCE24E7783F39 ) + rom ( name "Animal Mania - Dokidoki Aishou Check (Japan).gba" size 4194304 crc 89e6cd89 sha1 3552B82ABDBE38851C607AC572EFCE24E7783F39 ) ) game ( name "Animal Snap - Rescue Them 2 by 2 (Europe)" description "Animal Snap - Rescue Them 2 by 2 (Europe)" - rom ( name "Animal Snap - Rescue Them 2 by 2 (Europe).gba" size 4194304 crc 25015475 md5 59EFE4673056B6385379B83883B30E47 sha1 AD6FEE649C7D17F9348D1D0A555100E6F8F16301 ) + rom ( name "Animal Snap - Rescue Them 2 by 2 (Europe).gba" size 4194304 crc 25015475 sha1 AD6FEE649C7D17F9348D1D0A555100E6F8F16301 ) ) game ( name "Animal Snap - Rescue Them 2 by 2 (USA)" description "Animal Snap - Rescue Them 2 by 2 (USA)" - rom ( name "Animal Snap - Rescue Them 2 by 2 (USA).gba" size 4194304 crc 7304DCA4 md5 8A65CC927274981D1B431BC005FE185D sha1 899B9158F622AB145C6787B2AF65ABDA902E6A95 flags verified ) + rom ( name "Animal Snap - Rescue Them 2 by 2 (USA).gba" size 4194304 crc 7304dca4 sha1 899B9158F622AB145C6787B2AF65ABDA902E6A95 flags verified ) ) game ( name "Animal Yokochou - Doki Doki Kyuushutsu Daisakusen! no Maki (Japan)" description "Animal Yokochou - Doki Doki Kyuushutsu Daisakusen! no Maki (Japan)" - rom ( name "Animal Yokochou - Doki Doki Kyuushutsu Daisakusen! no Maki (Japan).gba" size 16777216 crc D53C9438 md5 7C90CE3EF159FD17FECA4C0F25DE13F2 sha1 EA0BA14FD5088EB519D443A2400A6ECD2B1C9E38 ) + rom ( name "Animal Yokochou - Doki Doki Kyuushutsu Daisakusen! no Maki (Japan).gba" size 16777216 crc d53c9438 sha1 EA0BA14FD5088EB519D443A2400A6ECD2B1C9E38 ) ) game ( name "Animal Yokochou - Doki Doki Shinkyuu Shiken! no Maki (Japan)" description "Animal Yokochou - Doki Doki Shinkyuu Shiken! no Maki (Japan)" - rom ( name "Animal Yokochou - Doki Doki Shinkyuu Shiken! no Maki (Japan).gba" size 16777216 crc 41B39214 md5 5055F42473ED3F2977288181A460B963 sha1 DBD694AD42C8F483D1DDAB2F73CA1515951F5298 flags verified ) + rom ( name "Animal Yokochou - Doki Doki Shinkyuu Shiken! no Maki (Japan).gba" size 16777216 crc 41b39214 sha1 DBD694AD42C8F483D1DDAB2F73CA1515951F5298 flags verified ) ) game ( name "Animaniacs - Lights, Camera, Action! (Europe) (En,Fr,De,Es,It)" description "Animaniacs - Lights, Camera, Action! (Europe) (En,Fr,De,Es,It)" - rom ( name "Animaniacs - Lights, Camera, Action! (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 840D11C1 md5 4075C0553F360E180CF9EFC899B1D8BC sha1 85DD6BD76F285FAC7DDBD729B76FBD5ED83E62CC ) + rom ( name "Animaniacs - Lights, Camera, Action! (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 840d11c1 sha1 85DD6BD76F285FAC7DDBD729B76FBD5ED83E62CC ) ) game ( name "Ant Bully, The (USA) (En,Fr)" description "Ant Bully, The (USA) (En,Fr)" - rom ( name "Ant Bully, The (USA) (En,Fr).gba" size 8388608 crc 8D51A101 md5 3A64D744D25A221E3F10099A5D55F155 sha1 368589E9E80C7A7862002B90ADF23AC69DCB38C5 ) + rom ( name "Ant Bully, The (USA) (En,Fr).gba" size 8388608 crc 8d51a101 sha1 368589E9E80C7A7862002B90ADF23AC69DCB38C5 ) ) game ( name "Ant Bully, The (Europe) (En,Fr,De,Es,It)" description "Ant Bully, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Ant Bully, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 52DC386B md5 B9D1DA4A076AC3FF5F08FC3A2AB76FC9 sha1 A735364887C31A19FA7D250EC830D02220D6A6CD ) + rom ( name "Ant Bully, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 52dc386b sha1 A735364887C31A19FA7D250EC830D02220D6A6CD ) ) game ( name "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 367927ED md5 4F6338B585AF7DD74FE5AAD98E0BA176 sha1 68FCA49CBA74DC108F50EC762AB91B6DFF5A92B8 ) + rom ( name "Antz - Extreme Racing (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 367927ed sha1 68FCA49CBA74DC108F50EC762AB91B6DFF5A92B8 ) ) game ( name "Antz - Extreme Racing (USA)" description "Antz - Extreme Racing (USA)" - rom ( name "Antz - Extreme Racing (USA).gba" size 4194304 crc F4EFC5ED md5 C33CD0B752E2305BECD03604DBD90293 sha1 AD6DED0F643457D652292BB97E30B1AD442E41DA ) + rom ( name "Antz - Extreme Racing (USA).gba" size 4194304 crc f4efc5ed sha1 AD6DED0F643457D652292BB97E30B1AD442E41DA ) ) game ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan)" description "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan)" - rom ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan).gba" size 4194304 crc AD9AF125 md5 E712DC279AA30550031982B9FDC76D87 sha1 0E6C92477793CE495CAA400899EFFB4F87384F3C ) + rom ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan).gba" size 4194304 crc ad9af125 sha1 0E6C92477793CE495CAA400899EFFB4F87384F3C ) ) game ( name "Archer Maclean's 3D Pool (USA)" description "Archer Maclean's 3D Pool (USA)" - rom ( name "Archer Maclean's 3D Pool (USA).gba" size 4194304 crc 4202A9CD md5 78FDA8CE4A49D92F1A7EF3CFD6AE7DFB sha1 5B1DCAB6984D454E3ED3F3FE107F43A645283C0F ) + rom ( name "Archer Maclean's 3D Pool (USA).gba" size 4194304 crc 4202a9cd sha1 5B1DCAB6984D454E3ED3F3FE107F43A645283C0F ) ) game ( name "Arctic Tale (USA)" description "Arctic Tale (USA)" - rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397AC0 md5 BBEAF2FCA8691CF29CAE2E7BCF6FF69F sha1 9654A5C6A40B946C35CC9E09AAE48BDD47EA7692 ) + rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397ac0 sha1 9654A5C6A40B946C35CC9E09AAE48BDD47EA7692 ) ) game ( name "Army Men - Operation Green (USA) (En,Fr,De,Es,It)" description "Army Men - Operation Green (USA) (En,Fr,De,Es,It)" - rom ( name "Army Men - Operation Green (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 6D174E28 md5 60EB386E45D38B41FA10CD2535F681D8 sha1 B0FA4769CDDBC66BC333AD45658524A4AEEEC755 ) + rom ( name "Army Men - Operation Green (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 6d174e28 sha1 B0FA4769CDDBC66BC333AD45658524A4AEEEC755 flags verified ) ) game ( name "Army Men - Turf Wars (USA)" description "Army Men - Turf Wars (USA)" - rom ( name "Army Men - Turf Wars (USA).gba" size 8388608 crc 65AC74CC md5 D3E4164A9C709DBED2BF24E09170FC77 sha1 43BFC86185A06D9D9C27686AD8CB650288B716AE flags verified ) + rom ( name "Army Men - Turf Wars (USA).gba" size 8388608 crc 65ac74cc sha1 43BFC86185A06D9D9C27686AD8CB650288B716AE flags verified ) ) game ( name "Army Men Advance (USA, Europe) (En,Fr,De,Es,It)" description "Army Men Advance (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Army Men Advance (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9A4A509F md5 30FF69A44658FCF2CC381736403E74EF sha1 43CD22C8E5832790B0CDBDCF0E11859021747342 ) + rom ( name "Army Men Advance (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9a4a509f sha1 43CD22C8E5832790B0CDBDCF0E11859021747342 ) ) game ( name "Around the World in 80 Days (USA)" description "Around the World in 80 Days (USA)" - rom ( name "Around the World in 80 Days (USA).gba" size 4194304 crc C2C22AF2 md5 FF81EE924F0B66CA6E1743C056EA0782 sha1 A3649682EF8A2378767154B37CA854D615305646 flags verified ) + rom ( name "Around the World in 80 Days (USA).gba" size 4194304 crc c2c22af2 sha1 A3649682EF8A2378767154B37CA854D615305646 flags verified ) ) game ( name "Around the World in 80 Days (Europe) (En,Fr,De,Es,It,Nl)" description "Around the World in 80 Days (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Around the World in 80 Days (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 2DD8CBD7 md5 34254B26F28EA5CEC1463576FF474FE8 sha1 19C3964FC87F104E12DA591BD91BB182C1092A76 ) + rom ( name "Around the World in 80 Days (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 2dd8cbd7 sha1 19C3964FC87F104E12DA591BD91BB182C1092A76 flags verified ) ) game ( name "Arthur and the Invisibles (USA) (En,Fr,Es)" description "Arthur and the Invisibles (USA) (En,Fr,Es)" - rom ( name "Arthur and the Invisibles (USA) (En,Fr,Es).gba" size 16777216 crc 87C25055 md5 3F78374401030FBBC41FB8B9B6D3A99F sha1 6173EA7E00497E7A908A97E64CB4BC86396E8459 ) + rom ( name "Arthur and the Invisibles (USA) (En,Fr,Es).gba" size 16777216 crc 87c25055 sha1 6173EA7E00497E7A908A97E64CB4BC86396E8459 flags verified ) ) game ( name "Arthur and the Minimoys (Europe) (En,Fr,De,Es,It,Nl)" description "Arthur and the Minimoys (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Arthur and the Minimoys (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc A4DAE90B md5 55E5315F7C8B8DD97482E90E111A1FBA sha1 32E91C705B1244F94361DACD777C8D11D726E068 ) + rom ( name "Arthur and the Minimoys (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc a4dae90b sha1 32E91C705B1244F94361DACD777C8D11D726E068 ) ) game ( name "Ashita no Joe - Makka ni Moeagare! (Japan)" description "Ashita no Joe - Makka ni Moeagare! (Japan)" - rom ( name "Ashita no Joe - Makka ni Moeagare! (Japan).gba" size 16777216 crc 69CDE456 md5 BDC2A5D8D58449CCFD2557443B1CD026 sha1 9BB086529590F2925800C4FA932C8F8403C62967 ) + rom ( name "Ashita no Joe - Makka ni Moeagare! (Japan).gba" size 16777216 crc 69cde456 sha1 9BB086529590F2925800C4FA932C8F8403C62967 ) ) game ( name "Asterix & Obelix - Bash Them All! (Europe) (En,Fr,De,Es,It,Nl)" description "Asterix & Obelix - Bash Them All! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Asterix & Obelix - Bash Them All! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 92360109 md5 27DFC6912ED8BBD27A5B5B32A62A4916 sha1 9C6FC07A77B0CB8A7265147FDB83B0E6D1D629DF flags verified ) + rom ( name "Asterix & Obelix - Bash Them All! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 92360109 sha1 9C6FC07A77B0CB8A7265147FDB83B0E6D1D629DF flags verified ) ) game ( name "Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl)" description "Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc A9B1ECE5 md5 920882439CD994C2F0AB63D32A64EB80 sha1 7145D02143C1A81F6EA72063AC798642B2AAEC3C flags verified ) + rom ( name "Asterix & Obelix XXL (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc a9b1ece5 sha1 7145D02143C1A81F6EA72063AC798642B2AAEC3C flags verified ) ) game ( name "Astro Boy - Omega Factor (USA) (En,Ja,Fr,De,Es,It)" description "Astro Boy - Omega Factor (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Astro Boy - Omega Factor (USA) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc E8619031 md5 C518725055083F6096F3268CF608ACDA sha1 4D652C24979DD7A08EE683B32D1D8986A5511A87 ) + rom ( name "Astro Boy - Omega Factor (USA) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc e8619031 sha1 4D652C24979DD7A08EE683B32D1D8986A5511A87 flags verified ) ) game ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It)" description "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 1E2E8937 md5 8D5B5381539FCAD4DF2BC7902A432DEE sha1 9A4FC3533BBDB28FD5945BD1EE7D84D992EEE12F flags verified ) + rom ( name "Astro Boy - Omega Factor (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 1e2e8937 sha1 9A4FC3533BBDB28FD5945BD1EE7D84D992EEE12F flags verified ) ) game ( name "Astro Boy - Tetsuwan Atom - Atom Heart no Himitsu (Japan)" description "Astro Boy - Tetsuwan Atom - Atom Heart no Himitsu (Japan)" - rom ( name "Astro Boy - Tetsuwan Atom - Atom Heart no Himitsu (Japan).gba" size 8388608 crc E2D94B0D md5 0E24F5E435B0CF651017103DE24F4F92 sha1 CA16DC4044B9AE98A26C826BB3CC19A7E8315315 ) -) - -game ( - name "Atari Anniversary Advance (Europe)" - description "Atari Anniversary Advance (Europe)" - rom ( name "Atari Anniversary Advance (Europe).gba" size 4194304 crc B9B89FDF md5 E91540A58D8C28D15137C7FC6504F78A sha1 57CE9A691989503FF0B94F578664397385A471AF ) + rom ( name "Astro Boy - Tetsuwan Atom - Atom Heart no Himitsu (Japan).gba" size 8388608 crc e2d94b0d sha1 CA16DC4044B9AE98A26C826BB3CC19A7E8315315 flags verified ) ) game ( name "Atari Anniversary Advance (USA)" description "Atari Anniversary Advance (USA)" - rom ( name "Atari Anniversary Advance (USA).gba" size 4194304 crc 4505A638 md5 5557FB798B7E5B05016D8269DDB9E20B sha1 ABA3CAA1F7EF8DF5036ED735916FA04F74F2F29F ) + rom ( name "Atari Anniversary Advance (USA).gba" size 4194304 crc 4505a638 sha1 ABA3CAA1F7EF8DF5036ED735916FA04F74F2F29F ) +) + +game ( + name "Atari Anniversary Advance (Europe)" + description "Atari Anniversary Advance (Europe)" + rom ( name "Atari Anniversary Advance (Europe).gba" size 4194304 crc b9b89fdf sha1 57CE9A691989503FF0B94F578664397385A471AF flags verified ) ) game ( name "Atlantis - The Lost Empire (USA, Europe)" description "Atlantis - The Lost Empire (USA, Europe)" - rom ( name "Atlantis - The Lost Empire (USA, Europe).gba" size 4194304 crc 8BD224C5 md5 B56F85FF2F37C51ACD2E2561ABBCCB64 sha1 10D77CB1F9CB1F6670367DDA9B6A88909E39B322 flags verified ) + rom ( name "Atlantis - The Lost Empire (USA, Europe).gba" size 4194304 crc 8bd224c5 sha1 10D77CB1F9CB1F6670367DDA9B6A88909E39B322 flags verified ) ) game ( name "Atlantis - The Lost Empire (Europe) (En,Fr,De,Es,It,Nl)" description "Atlantis - The Lost Empire (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Atlantis - The Lost Empire (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc B3948DBC md5 45F0B97050A666CE7AB4E3960929F47B sha1 93624EAA9A80CDB791BD14955B55DD7C58C4ABBD ) + rom ( name "Atlantis - The Lost Empire (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc b3948dbc sha1 93624EAA9A80CDB791BD14955B55DD7C58C4ABBD ) ) game ( name "Atomic Betty (USA, Europe)" description "Atomic Betty (USA, Europe)" - rom ( name "Atomic Betty (USA, Europe).gba" size 8388608 crc 8919D82C md5 A3DD3B98AD5049503AF18F80C84731FC sha1 59E7400802AB634065B9674DE3F437DDF8309D6E flags verified ) -) - -game ( - name "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1)" - description "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 4B4E8BC7 md5 06AE9BC5A49C1F5EDAC5F5DBDD30882D sha1 2234F23928C871B00BD48BDCDD5273362D4E0CDC ) + rom ( name "Atomic Betty (USA, Europe).gba" size 8388608 crc 8919d82c sha1 59E7400802AB634065B9674DE3F437DDF8309D6E flags verified ) ) game ( name "ATV - Quad Power Racing (USA, Europe)" description "ATV - Quad Power Racing (USA, Europe)" - rom ( name "ATV - Quad Power Racing (USA, Europe).gba" size 4194304 crc 9C1A7DCB md5 B295F02A07F00F80669352767242268F sha1 43A2C71B1F3B4085ADEE648E5A409BE4517CD7BB flags verified ) + rom ( name "ATV - Quad Power Racing (USA, Europe).gba" size 4194304 crc 9c1a7dcb sha1 43A2C71B1F3B4085ADEE648E5A409BE4517CD7BB flags verified ) +) + +game ( + name "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1)" + description "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1)" + rom ( name "ATV - Quad Power Racing (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 4b4e8bc7 sha1 2234F23928C871B00BD48BDCDD5273362D4E0CDC ) ) game ( name "ATV - Thunder Ridge Riders (USA)" description "ATV - Thunder Ridge Riders (USA)" - rom ( name "ATV - Thunder Ridge Riders (USA).gba" size 4194304 crc 773E73C7 md5 C741F6E950240D0D66AEB60E81FAE12D sha1 40559B783A555F4D59F6380EE69C3DD7DFD35B73 ) + rom ( name "ATV - Thunder Ridge Riders (USA).gba" size 4194304 crc 773e73c7 sha1 40559B783A555F4D59F6380EE69C3DD7DFD35B73 ) ) game ( name "ATV - Thunder Ridge Riders (Europe) (En,Fr,De,Es,It)" description "ATV - Thunder Ridge Riders (Europe) (En,Fr,De,Es,It)" - rom ( name "ATV - Thunder Ridge Riders (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B1D2896F md5 7A0A429DC61A06BBAF62D867910E50CB sha1 6CFD6FAC87B8414913A9D48DFA947DD061CBDAAD ) + rom ( name "ATV - Thunder Ridge Riders (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b1d2896f sha1 6CFD6FAC87B8414913A9D48DFA947DD061CBDAAD ) ) game ( name "Avatar - The Last Airbender (USA)" description "Avatar - The Last Airbender (USA)" - rom ( name "Avatar - The Last Airbender (USA).gba" size 8388608 crc 946787C0 md5 C19779D04914FAE7268BFB8B47B8B048 sha1 9D864E9B3CCCE4E5E1B1C566AFA0D06088E88DFD flags verified ) + rom ( name "Avatar - The Last Airbender (USA).gba" size 8388608 crc 946787c0 sha1 9D864E9B3CCCE4E5E1B1C566AFA0D06088E88DFD flags verified ) ) game ( name "Avatar - The Last Airbender - The Burning Earth (USA)" description "Avatar - The Last Airbender - The Burning Earth (USA)" - rom ( name "Avatar - The Last Airbender - The Burning Earth (USA).gba" size 4194304 crc 52D8D101 md5 068B542444B3AD28E75BE4087A754B58 sha1 788D5E92806017F0F2B1B9E127759515141AEF2A ) + rom ( name "Avatar - The Last Airbender - The Burning Earth (USA).gba" size 4194304 crc 52d8d101 sha1 788D5E92806017F0F2B1B9E127759515141AEF2A ) ) game ( name "Avatar - The Legend of Aang (Europe) (En,Fr,De,Nl)" description "Avatar - The Legend of Aang (Europe) (En,Fr,De,Nl)" - rom ( name "Avatar - The Legend of Aang (Europe) (En,Fr,De,Nl).gba" size 8388608 crc 52FE8A62 md5 EF9198E16C58C4824EFAE668DA1E7040 sha1 4A62DFAAA562B23D4F851D3BB483D0FBF67894AF ) + rom ( name "Avatar - The Legend of Aang (Europe) (En,Fr,De,Nl).gba" size 8388608 crc 52fe8a62 sha1 4A62DFAAA562B23D4F851D3BB483D0FBF67894AF flags verified ) ) game ( name "Avatar - The Legend of Aang - The Burning Earth (Europe) (En,De)" description "Avatar - The Legend of Aang - The Burning Earth (Europe) (En,De)" - rom ( name "Avatar - The Legend of Aang - The Burning Earth (Europe) (En,De).gba" size 4194304 crc EC5D6AFD md5 50DC6C7EA18F906E0F1EDAD4DAD8B442 sha1 F26D1394A6775DB61D84013780A0B97FED6C7F30 ) + rom ( name "Avatar - The Legend of Aang - The Burning Earth (Europe) (En,De).gba" size 4194304 crc ec5d6afd sha1 F26D1394A6775DB61D84013780A0B97FED6C7F30 ) ) game ( name "Aventures de Jackie Chan, Les - La Legende de la Main Noire (France)" description "Aventures de Jackie Chan, Les - La Legende de la Main Noire (France)" - rom ( name "Aventures de Jackie Chan, Les - La Legende de la Main Noire (France).gba" size 4194304 crc D5FB19A0 md5 8D3004602C8C0CBB734C8AA781C425CD sha1 D6DFCD94DBF5763EC1F0DD88388C364098A6CC06 ) + rom ( name "Aventures de Jackie Chan, Les - La Legende de la Main Noire (France).gba" size 4194304 crc d5fb19a0 sha1 D6DFCD94DBF5763EC1F0DD88388C364098A6CC06 ) ) game ( name "Azumanga Daiou Advance (Japan)" description "Azumanga Daiou Advance (Japan)" - rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704F6 md5 34A82A7281E62FDF2051B95DC0DF0488 sha1 95B266E8ECDAE1938CD180F597E5F21CB86D8B96 ) + rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704f6 sha1 95B266E8ECDAE1938CD180F597E5F21CB86D8B96 flags verified ) ) game ( name "B-Densetsu! Battle B-Daman - Fire Spirits! (Japan)" description "B-Densetsu! Battle B-Daman - Fire Spirits! (Japan)" - rom ( name "B-Densetsu! Battle B-Daman - Fire Spirits! (Japan).gba" size 8388608 crc EE41C0EB md5 B97C2E5C0D2668EBB244D6AFA0B1AD95 sha1 8E4FC778307BD70A0179F788EB58C4CC06886139 ) + rom ( name "B-Densetsu! Battle B-Daman - Fire Spirits! (Japan).gba" size 8388608 crc ee41c0eb sha1 8E4FC778307BD70A0179F788EB58C4CC06886139 ) ) game ( name "B-Densetsu! Battle B-Daman - Moero! B-Damashii!! (Japan)" description "B-Densetsu! Battle B-Daman - Moero! B-Damashii!! (Japan)" - rom ( name "B-Densetsu! Battle B-Daman - Moero! B-Damashii!! (Japan).gba" size 8388608 crc D6E4064F md5 A479748CB20E4ED3D72A829DC5A870FD sha1 49BEBA2E36459AF92917ACF911CBF2492F1B07F1 ) + rom ( name "B-Densetsu! Battle B-Daman - Moero! B-Damashii!! (Japan).gba" size 8388608 crc d6e4064f sha1 49BEBA2E36459AF92917ACF911CBF2492F1B07F1 ) ) game ( name "Babar to the Rescue (USA) (En,Fr,Es)" description "Babar to the Rescue (USA) (En,Fr,Es)" - rom ( name "Babar to the Rescue (USA) (En,Fr,Es).gba" size 4194304 crc D4073E33 md5 91BA6A4571E20DD9C7604D685D134607 sha1 80BE43F995DC6E3C1B0003872CE4CB681FE35A4A ) + rom ( name "Babar to the Rescue (USA) (En,Fr,Es).gba" size 4194304 crc d4073e33 sha1 80BE43F995DC6E3C1B0003872CE4CB681FE35A4A ) ) game ( name "Babar to the Rescue (Europe) (En,Fr,De,Da)" description "Babar to the Rescue (Europe) (En,Fr,De,Da)" - rom ( name "Babar to the Rescue (Europe) (En,Fr,De,Da).gba" size 4194304 crc AB7D6C17 md5 7F92CA61A904F2902FA44B622CE2601A sha1 06D6265DF757731B5AD59B8E6E5B9701E703E54B ) + rom ( name "Babar to the Rescue (Europe) (En,Fr,De,Da).gba" size 4194304 crc ab7d6c17 sha1 06D6265DF757731B5AD59B8E6E5B9701E703E54B flags verified ) ) game ( name "Back to Stone (USA) (En,Fr)" description "Back to Stone (USA) (En,Fr)" - rom ( name "Back to Stone (USA) (En,Fr).gba" size 4194304 crc 4C29C9C8 md5 ADC583B26CEF3920FB9FFD152AEB98DD sha1 DB1FE7581858053B58412A97DF262B46838A7BE7 flags verified ) + rom ( name "Back to Stone (USA) (En,Fr).gba" size 4194304 crc 4c29c9c8 sha1 DB1FE7581858053B58412A97DF262B46838A7BE7 flags verified ) ) game ( name "Back to Stone (Europe) (En,Fr)" description "Back to Stone (Europe) (En,Fr)" - rom ( name "Back to Stone (Europe) (En,Fr).gba" size 4194304 crc 5730C85A md5 51617256AC8453F10B9ED40E22A1AAF6 sha1 592081DE986839392C4DB976EB7EBEC68BB51917 ) + rom ( name "Back to Stone (Europe) (En,Fr).gba" size 4194304 crc 5730c85a sha1 592081DE986839392C4DB976EB7EBEC68BB51917 ) ) game ( name "Back Track (USA, Europe)" description "Back Track (USA, Europe)" - rom ( name "Back Track (USA, Europe).gba" size 4194304 crc 48539B4B md5 DE6B60EE6F0DE4F2F7A7FC7C8F4A1D9E sha1 BE97ADE09DF06291E029BEEFFBE0AACF21DB9168 flags verified ) + rom ( name "Back Track (USA, Europe).gba" size 4194304 crc 48539b4b sha1 BE97ADE09DF06291E029BEEFFBE0AACF21DB9168 flags verified ) ) game ( name "Backyard Baseball (USA)" description "Backyard Baseball (USA)" - rom ( name "Backyard Baseball (USA).gba" size 4194304 crc 9F36B4E5 md5 688CAAD7531EC6956AEBBCA88F07E857 sha1 657A639AB3FFBFC85C7A0DA51D640AC2E60EC430 ) + rom ( name "Backyard Baseball (USA).gba" size 4194304 crc 9f36b4e5 sha1 657A639AB3FFBFC85C7A0DA51D640AC2E60EC430 ) ) game ( name "Backyard Baseball 2006 (USA)" description "Backyard Baseball 2006 (USA)" - rom ( name "Backyard Baseball 2006 (USA).gba" size 4194304 crc 92BCD192 md5 4F34EE4D9014CD0B9C6AE52DF1F72AF2 sha1 33223F5B05DDF6EC10A41527BBC3001C6A5414CD ) + rom ( name "Backyard Baseball 2006 (USA).gba" size 4194304 crc 92bcd192 sha1 33223F5B05DDF6EC10A41527BBC3001C6A5414CD ) ) game ( name "Backyard Basketball (USA)" description "Backyard Basketball (USA)" - rom ( name "Backyard Basketball (USA).gba" size 4194304 crc CBDA1D31 md5 8B525F6D0D80A287DF61EC99A97C6C08 sha1 B6B5B490541A3B0C3BD15E598DAFE1D67A022F54 ) + rom ( name "Backyard Basketball (USA).gba" size 4194304 crc cbda1d31 sha1 B6B5B490541A3B0C3BD15E598DAFE1D67A022F54 ) ) game ( name "Backyard Football (USA)" description "Backyard Football (USA)" - rom ( name "Backyard Football (USA).gba" size 4194304 crc 7CCC79B4 md5 9085DD5A5EF4B2820A838C375301FEC2 sha1 D44EF8EB521838FF013904B74D214C17E3E1C801 ) + rom ( name "Backyard Football (USA).gba" size 4194304 crc 7ccc79b4 sha1 D44EF8EB521838FF013904B74D214C17E3E1C801 ) ) game ( name "Backyard Football 2006 (USA)" description "Backyard Football 2006 (USA)" - rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc DB0723E3 md5 EA7D981E25AC274ADAF5ED08F505C60B sha1 53D134268D2FC973388861687E50F77CC4682941 ) + rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc db0723e3 sha1 53D134268D2FC973388861687E50F77CC4682941 ) ) game ( name "Backyard Hockey (USA)" description "Backyard Hockey (USA)" - rom ( name "Backyard Hockey (USA).gba" size 4194304 crc 3A8E31AF md5 CE57EDC0645572AF5244E3E24B586133 sha1 4829AA329E21D9C4822C3DF66426B59A7690BAA4 ) + rom ( name "Backyard Hockey (USA).gba" size 4194304 crc 3a8e31af sha1 4829AA329E21D9C4822C3DF66426B59A7690BAA4 ) ) game ( name "Backyard Skateboarding (USA)" description "Backyard Skateboarding (USA)" - rom ( name "Backyard Skateboarding (USA).gba" size 4194304 crc 4EB19B87 md5 6B618C3FA5F38736632781B0A1ED2D23 sha1 C0E4055ECFB5F40F290044C44DE2E66E2D3DA833 ) + rom ( name "Backyard Skateboarding (USA).gba" size 4194304 crc 4eb19b87 sha1 C0E4055ECFB5F40F290044C44DE2E66E2D3DA833 ) ) game ( name "Backyard Sports - Baseball 2007 (USA)" description "Backyard Sports - Baseball 2007 (USA)" - rom ( name "Backyard Sports - Baseball 2007 (USA).gba" size 4194304 crc 0EE82569 md5 BD5FD53F6315D6668FDBF4E7BF4E81EB sha1 CDE84171B11A767338158C61EE2AD608D4EB8889 ) + rom ( name "Backyard Sports - Baseball 2007 (USA).gba" size 4194304 crc 0ee82569 sha1 CDE84171B11A767338158C61EE2AD608D4EB8889 ) ) game ( name "Backyard Sports - Basketball 2007 (USA)" description "Backyard Sports - Basketball 2007 (USA)" - rom ( name "Backyard Sports - Basketball 2007 (USA).gba" size 4194304 crc 28724CA5 md5 175FFE1EE242CAC0316A9882A240D794 sha1 9852C09A6D31BD39602DD1E92DF7577BEA7AD4A8 ) + rom ( name "Backyard Sports - Basketball 2007 (USA).gba" size 4194304 crc 28724ca5 sha1 9852C09A6D31BD39602DD1E92DF7577BEA7AD4A8 ) ) game ( name "Backyard Sports - Football 2007 (USA)" description "Backyard Sports - Football 2007 (USA)" - rom ( name "Backyard Sports - Football 2007 (USA).gba" size 4194304 crc E9FDC229 md5 68A460A4FACE41897D483D3DE367D809 sha1 1B1504EDD7220E14A694CB2C4B722F29868D8192 ) + rom ( name "Backyard Sports - Football 2007 (USA).gba" size 4194304 crc e9fdc229 sha1 1B1504EDD7220E14A694CB2C4B722F29868D8192 ) ) game ( name "Bakunetsu Dodge Ball Fighters (Japan)" description "Bakunetsu Dodge Ball Fighters (Japan)" - rom ( name "Bakunetsu Dodge Ball Fighters (Japan).gba" size 4194304 crc 9030515D md5 273B9E8C6760BA878E9C6310DB5DCE67 sha1 73A9C1785A2C8B9F833C8842FDF99583C8B1D581 ) + rom ( name "Bakunetsu Dodge Ball Fighters (Japan).gba" size 4194304 crc 9030515d sha1 73A9C1785A2C8B9F833C8842FDF99583C8B1D581 ) ) game ( name "Bakuten Shoot Beyblade - Gekitou! Saikyou Blader (Japan)" description "Bakuten Shoot Beyblade - Gekitou! Saikyou Blader (Japan)" - rom ( name "Bakuten Shoot Beyblade - Gekitou! Saikyou Blader (Japan).gba" size 4194304 crc 7F2E0320 md5 766C7D52CD567BDE521498E0BA5974E8 sha1 A561D50919E3679AD831A2794E6960D84AA36533 ) + rom ( name "Bakuten Shoot Beyblade - Gekitou! Saikyou Blader (Japan).gba" size 4194304 crc 7f2e0320 sha1 A561D50919E3679AD831A2794E6960D84AA36533 ) ) game ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Kouryuu no Shou - Daichi Hen (Japan)" description "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Kouryuu no Shou - Daichi Hen (Japan)" - rom ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Kouryuu no Shou - Daichi Hen (Japan).gba" size 8388608 crc F01EE06C md5 A2D535D55174EC253309D922CA9E594F sha1 08189B5D22520213DE2C579151BE4016929893DE ) + rom ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Kouryuu no Shou - Daichi Hen (Japan).gba" size 8388608 crc f01ee06c sha1 08189B5D22520213DE2C579151BE4016929893DE ) ) game ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Seiryuu no Shou - Takao Hen (Japan)" description "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Seiryuu no Shou - Takao Hen (Japan)" - rom ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Seiryuu no Shou - Takao Hen (Japan).gba" size 8388608 crc 8778B36A md5 A3ADD916E37DC978A45853703D67D48D sha1 30AD2535DB0319AF509812E67467924164AB640F ) + rom ( name "Bakuten Shoot Beyblade 2002 - Gekisen! Team Battle!! Seiryuu no Shou - Takao Hen (Japan).gba" size 8388608 crc 8778b36a sha1 30AD2535DB0319AF509812E67467924164AB640F ) ) game ( name "Bakuten Shoot Beyblade 2002 - Ikuze! Bakutou! Chou Jiryoku Battle!! (Japan)" description "Bakuten Shoot Beyblade 2002 - Ikuze! Bakutou! Chou Jiryoku Battle!! (Japan)" - rom ( name "Bakuten Shoot Beyblade 2002 - Ikuze! Bakutou! Chou Jiryoku Battle!! (Japan).gba" size 8388608 crc 1D1BB02B md5 7EC49EC0FC1B5B53226D36CD9C0A646A sha1 29F319F731256501CC58EDDB4BC28166DBC7F0A8 ) + rom ( name "Bakuten Shoot Beyblade 2002 - Ikuze! Bakutou! Chou Jiryoku Battle!! (Japan).gba" size 8388608 crc 1d1bb02b sha1 29F319F731256501CC58EDDB4BC28166DBC7F0A8 flags verified ) ) game ( name "Baldur's Gate - Dark Alliance (USA)" description "Baldur's Gate - Dark Alliance (USA)" - rom ( name "Baldur's Gate - Dark Alliance (USA).gba" size 8388608 crc DEEDD7D9 md5 13FD90AE7070BA25C2CE4223B8F51A1E sha1 C7C264EC85976F326B34BBD9F5E91DDC6EB29E17 ) + rom ( name "Baldur's Gate - Dark Alliance (USA).gba" size 8388608 crc deedd7d9 sha1 C7C264EC85976F326B34BBD9F5E91DDC6EB29E17 ) ) game ( name "Baldur's Gate - Dark Alliance (Europe) (En,Fr,De,Es,It)" description "Baldur's Gate - Dark Alliance (Europe) (En,Fr,De,Es,It)" - rom ( name "Baldur's Gate - Dark Alliance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 494492DC md5 B8151C67817F126B56ECA07C0B6AEC11 sha1 9D6B740E9224F1636ED6E5BA63C2BB5970B8249F flags verified ) + rom ( name "Baldur's Gate - Dark Alliance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 494492dc sha1 9D6B740E9224F1636ED6E5BA63C2BB5970B8249F flags verified ) ) game ( name "Ballistic - Ecks vs. Sever (USA)" description "Ballistic - Ecks vs. Sever (USA)" - rom ( name "Ballistic - Ecks vs. Sever (USA).gba" size 8388608 crc 0477F153 md5 95ABF2BD63A3758B6D86E278EE1FCA6E sha1 D66A33C71466FFB6558BA6381156D14F73C8C6D8 ) + rom ( name "Ballistic - Ecks vs. Sever (USA).gba" size 8388608 crc 0477f153 sha1 D66A33C71466FFB6558BA6381156D14F73C8C6D8 ) ) game ( name "Banjo-Kazooie - Grunty's Revenge (USA, Europe)" description "Banjo-Kazooie - Grunty's Revenge (USA, Europe)" - rom ( name "Banjo-Kazooie - Grunty's Revenge (USA, Europe).gba" size 8388608 crc DFB5ABA3 md5 4781A8E513DE51AB90292C321AC34374 sha1 8F5B7C20E8BE0F1E7919915B905C2B182A993CEC flags verified ) + rom ( name "Banjo-Kazooie - Grunty's Revenge (USA, Europe).gba" size 8388608 crc dfb5aba3 sha1 8F5B7C20E8BE0F1E7919915B905C2B182A993CEC flags verified ) ) game ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De)" description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De)" - rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De).gba" size 8388608 crc FB4F38E2 md5 1E32D754B8A874D279086F98CF523DFD sha1 F335FEDE72CD0273FCCE925A20CA272EDE08C15B flags verified ) + rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De).gba" size 8388608 crc fb4f38e2 sha1 F335FEDE72CD0273FCCE925A20CA272EDE08C15B flags verified ) ) game ( - name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta)" - description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8337992 crc 106ED779 md5 43CCAB5D3761E9964500A454FDF6776B sha1 F2D3D4F8226C17C5391ABCB2A2CBCE10C59AB4C7 ) + name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 2)" + description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 2)" + rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 2).gba" size 8337992 crc 106ed779 sha1 F2D3D4F8226C17C5391ABCB2A2CBCE10C59AB4C7 flags verified ) ) game ( - name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta) (early)" - description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta) (early)" - rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta) (early).gba" size 8019096 crc 4E0F10FA md5 3B3CDB2583A22769FB80BAE6B334DC81 sha1 5A0B6FE8AC36E05DE9C2E9B31D8B68EF125F4D96 ) + name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 1)" + description "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 1)" + rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De,Es,It) (Beta 1).gba" size 8019096 crc 4e0f10fa sha1 5A0B6FE8AC36E05DE9C2E9B31D8B68EF125F4D96 flags verified ) ) game ( name "Banjo-Kazooie - La Vendetta di Grunty (Italy)" description "Banjo-Kazooie - La Vendetta di Grunty (Italy)" - rom ( name "Banjo-Kazooie - La Vendetta di Grunty (Italy).gba" size 8388608 crc 67AD698F md5 288280C929CDE064B9363A7AD4548A76 sha1 2A38116E3219CD0A9216C9ADF8383BA84489F3B0 ) + rom ( name "Banjo-Kazooie - La Vendetta di Grunty (Italy).gba" size 8388608 crc 67ad698f sha1 2A38116E3219CD0A9216C9ADF8383BA84489F3B0 ) ) game ( name "Banjo-Kazooie - La Venganza de Grunty (Spain)" description "Banjo-Kazooie - La Venganza de Grunty (Spain)" - rom ( name "Banjo-Kazooie - La Venganza de Grunty (Spain).gba" size 8388608 crc 32544634 md5 656B49E4DB1A3AD6475B29C347A4FEFC sha1 3B948A1CB1790C16C7A3FFF9C0CFBF95A973200D ) + rom ( name "Banjo-Kazooie - La Venganza de Grunty (Spain).gba" size 8388608 crc 32544634 sha1 3B948A1CB1790C16C7A3FFF9C0CFBF95A973200D ) ) game ( name "Banjo-Pilot (USA)" description "Banjo-Pilot (USA)" - rom ( name "Banjo-Pilot (USA).gba" size 16777216 crc 6E4030A1 md5 1D55A0E331301A7D36AC326F3D8DC007 sha1 58551D404C46B14CE3611DBFB70848E05BEC2DAC ) + rom ( name "Banjo-Pilot (USA).gba" size 16777216 crc 6e4030a1 sha1 58551D404C46B14CE3611DBFB70848E05BEC2DAC ) ) game ( name "Banjo-Pilot (Europe) (En,Fr,De,Es,It)" description "Banjo-Pilot (Europe) (En,Fr,De,Es,It)" - rom ( name "Banjo-Pilot (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc B98DE3A4 md5 3AC5633408CB7AC50247CDBA396C5536 sha1 5203F49C3B372B49DCB5C23F0DCBBB8432336081 flags verified ) + rom ( name "Banjo-Pilot (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc b98de3a4 sha1 5203F49C3B372B49DCB5C23F0DCBBB8432336081 flags verified ) ) game ( name "Banjo-Pilot (Unknown) (Beta)" description "Banjo-Pilot (Unknown) (Beta)" - rom ( name "Banjo-Pilot (Unknown) (Beta).gba" size 15545696 crc 817FD31D md5 8EC1A2FEE7A9CC9508BF13DC423D424D sha1 51B7FE0AF316F4C25E08B2C8348B579E86697E3F ) + rom ( name "Banjo-Pilot (Unknown) (Beta).gba" size 15545696 crc 817fd31d sha1 51B7FE0AF316F4C25E08B2C8348B579E86697E3F flags verified ) ) game ( name "Barbie - The Princess and the Pauper (USA)" description "Barbie - The Princess and the Pauper (USA)" - rom ( name "Barbie - The Princess and the Pauper (USA).gba" size 4194304 crc F508A7B7 md5 64082D14D8A4ABE32FB8B062D9C0B9ED sha1 432ED848343AD3C66BCB3ACF245CACBB829F5F9C ) + rom ( name "Barbie - The Princess and the Pauper (USA).gba" size 4194304 crc f508a7b7 sha1 432ED848343AD3C66BCB3ACF245CACBB829F5F9C ) ) game ( name "Barbie - The Princess and the Pauper (Europe) (En,Fr,De,Es,It,Nl)" description "Barbie - The Princess and the Pauper (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Barbie - The Princess and the Pauper (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 116194F2 md5 8A12B6C9298E5F9874DF68F62CC23B48 sha1 779F2050EFCD15CAC8B70FEDCE5BD0CCB773F179 ) + rom ( name "Barbie - The Princess and the Pauper (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 116194f2 sha1 779F2050EFCD15CAC8B70FEDCE5BD0CCB773F179 ) ) game ( name "Barbie and the Magic of Pegasus (USA)" description "Barbie and the Magic of Pegasus (USA)" - rom ( name "Barbie and the Magic of Pegasus (USA).gba" size 4194304 crc 29D23835 md5 C0F3E785F1D4A48FCB2B945291A033EF sha1 36E312ABFAF7B9401E9F3D5B796F4AE07A10A09A ) + rom ( name "Barbie and the Magic of Pegasus (USA).gba" size 4194304 crc 29d23835 sha1 36E312ABFAF7B9401E9F3D5B796F4AE07A10A09A ) ) game ( name "Barbie and the Magic of Pegasus (Europe) (En,Fr,De,Es,It,Nl)" description "Barbie and the Magic of Pegasus (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Barbie and the Magic of Pegasus (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 5661E71A md5 31628FE35CFE67066A003F045A32DAAE sha1 26C1D72FBB20FE715CB685CBA071775259BBB236 ) + rom ( name "Barbie and the Magic of Pegasus (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 5661e71a sha1 26C1D72FBB20FE715CB685CBA071775259BBB236 ) ) game ( name "Barbie as the Island Princess (USA)" description "Barbie as the Island Princess (USA)" - rom ( name "Barbie as the Island Princess (USA).gba" size 8388608 crc DB6160EB md5 FCAB58352E45A97A7BECBECC948EA076 sha1 4AC1502B9B292584BEECB8C7BAF1ABBCDB3A2D75 ) + rom ( name "Barbie as the Island Princess (USA).gba" size 8388608 crc db6160eb sha1 4AC1502B9B292584BEECB8C7BAF1ABBCDB3A2D75 ) ) game ( name "Barbie Diaries, The - High School Mystery (USA)" description "Barbie Diaries, The - High School Mystery (USA)" - rom ( name "Barbie Diaries, The - High School Mystery (USA).gba" size 8388608 crc 5C704CBE md5 85BBF8A6F95B9D2D463D0A55F2B69D35 sha1 3E61732FB0D19912B76C16E7FE1407E14BA38447 ) + rom ( name "Barbie Diaries, The - High School Mystery (USA).gba" size 8388608 crc 5c704cbe sha1 3E61732FB0D19912B76C16E7FE1407E14BA38447 ) ) game ( name "Barbie Diaries, The - High School Mystery (Europe)" description "Barbie Diaries, The - High School Mystery (Europe)" - rom ( name "Barbie Diaries, The - High School Mystery (Europe).gba" size 8388608 crc 4E8A650C md5 8E1C2672225640D441932424B5E11243 sha1 1A89DC89D8CFFC119643B99228D4CC567D5421B3 ) + rom ( name "Barbie Diaries, The - High School Mystery (Europe).gba" size 8388608 crc 4e8a650c sha1 1A89DC89D8CFFC119643B99228D4CC567D5421B3 ) ) game ( name "Barbie Groovy Games (USA)" description "Barbie Groovy Games (USA)" - rom ( name "Barbie Groovy Games (USA).gba" size 4194304 crc AA017567 md5 C1B8FBFC0F67A1F8E0C60543167B7DBA sha1 055DB9F8F3BA18358162A1411CF24300A6DE6046 ) + rom ( name "Barbie Groovy Games (USA).gba" size 4194304 crc aa017567 sha1 055DB9F8F3BA18358162A1411CF24300A6DE6046 ) ) game ( name "Barbie Groovy Games (Europe) (En,Fr,De,Es,It)" description "Barbie Groovy Games (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie Groovy Games (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 749339B2 md5 44C77BCF2A866A1A76CF46BD979B64A4 sha1 E41751C52D5CD84B204AC4D73EEFC5B360F56F1D ) + rom ( name "Barbie Groovy Games (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 749339b2 sha1 E41751C52D5CD84B204AC4D73EEFC5B360F56F1D ) ) game ( name "Barbie Horse Adventures (Europe) (En,Fr,De,Es,It,Nl)" description "Barbie Horse Adventures (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Barbie Horse Adventures (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 7C6D9EF3 md5 F7960BB4694205288A59556AB82C34E5 sha1 D3E50B9EAC1E6A695397CF6D81503A9C0C3A40FE ) + rom ( name "Barbie Horse Adventures (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 7c6d9ef3 sha1 D3E50B9EAC1E6A695397CF6D81503A9C0C3A40FE ) ) game ( name "Barbie Horse Adventures - Blue Ribbon Race (USA)" description "Barbie Horse Adventures - Blue Ribbon Race (USA)" - rom ( name "Barbie Horse Adventures - Blue Ribbon Race (USA).gba" size 4194304 crc BA184025 md5 B0C8EDEAE511C647F9617B32DDC37594 sha1 7D8938D54EAFB1558EFCE8BDFBC9DB15AC2072E5 ) + rom ( name "Barbie Horse Adventures - Blue Ribbon Race (USA).gba" size 4194304 crc ba184025 sha1 7D8938D54EAFB1558EFCE8BDFBC9DB15AC2072E5 ) ) game ( name "Barbie in the 12 Dancing Princesses (USA)" description "Barbie in the 12 Dancing Princesses (USA)" - rom ( name "Barbie in the 12 Dancing Princesses (USA).gba" size 4194304 crc 9C0ABDDB md5 6A06B7C152538CE846FBDF523902A000 sha1 FA4E69CEB8D2773BBFC1C225F3604C1F7DF43CDE ) + rom ( name "Barbie in the 12 Dancing Princesses (USA).gba" size 4194304 crc 9c0abddb sha1 FA4E69CEB8D2773BBFC1C225F3604C1F7DF43CDE ) ) game ( name "Barbie in the 12 Dancing Princesses (Europe) (En,Fr,De,Es,It)" description "Barbie in the 12 Dancing Princesses (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie in the 12 Dancing Princesses (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7CA7AA12 md5 11BFEB390128B3FA4AF1E92399A9BD3F sha1 3FEB77F60AD71D4DBB83C7EA0712759E50CCC088 ) + rom ( name "Barbie in the 12 Dancing Princesses (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7ca7aa12 sha1 3FEB77F60AD71D4DBB83C7EA0712759E50CCC088 flags verified ) ) game ( - name "Barbie Superpack (USA)" - description "Barbie Superpack (USA)" - rom ( name "Barbie Superpack (USA).gba" size 8388608 crc C99DB2A1 md5 50552A80C5D80210C941E4AD8230E814 sha1 75392F0CF1C3D79C04C5A0D9503CF979A5DA2E7B ) + name "Barbie Superpack - Secret Agent + Groovy Games (USA)" + description "Barbie Superpack - Secret Agent + Groovy Games (USA)" + rom ( name "Barbie Superpack - Secret Agent + Groovy Games (USA).gba" size 8388608 crc c99db2a1 sha1 75392F0CF1C3D79C04C5A0D9503CF979A5DA2E7B ) ) game ( - name "Barbie Superpack (Europe) (En,Fr,De,Es,It)" - description "Barbie Superpack (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie Superpack (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2C3862C3 md5 F26ABD577F7854C5F967EF5F0D1396AD sha1 314569F6BF47FA3982A49B2F04B6B847CBCA515C ) + name "Barbie Superpack - Secret Agent + Groovy Games (Europe) (En,Fr,De,Es,It)" + description "Barbie Superpack - Secret Agent + Groovy Games (Europe) (En,Fr,De,Es,It)" + rom ( name "Barbie Superpack - Secret Agent + Groovy Games (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2c3862c3 sha1 314569F6BF47FA3982A49B2F04B6B847CBCA515C ) ) game ( name "Barnyard (USA)" description "Barnyard (USA)" - rom ( name "Barnyard (USA).gba" size 8388608 crc FF7987DA md5 56C434600BF895C83A485AB8CBE49500 sha1 7A6E2BF247BA7AC2420A5EEF39B77A5D871785B5 ) + rom ( name "Barnyard (USA).gba" size 8388608 crc ff7987da sha1 7A6E2BF247BA7AC2420A5EEF39B77A5D871785B5 ) ) game ( name "Barnyard (Europe) (En,Fr,De,Es,It,Nl)" description "Barnyard (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Barnyard (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc F2B06467 md5 02CAE6AD10EB30DA0F76CBD8CA994952 sha1 2FE05E2C9DFC02EFE415C735F95FA1D4CD12EEB7 flags verified ) + rom ( name "Barnyard (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc f2b06467 sha1 2FE05E2C9DFC02EFE415C735F95FA1D4CD12EEB7 flags verified ) ) game ( name "Baseball Advance (USA)" description "Baseball Advance (USA)" - rom ( name "Baseball Advance (USA).gba" size 8388608 crc 339F35B8 md5 E345A10A452E8574FA4686539E852F31 sha1 45DEA270943584115517EF2D12E5525932D0F5FA flags verified ) + rom ( name "Baseball Advance (USA).gba" size 8388608 crc 339f35b8 sha1 45DEA270943584115517EF2D12E5525932D0F5FA flags verified ) ) game ( name "Bass Tsuri Shiyouze! - Tournament wa Senryaku da! (Japan)" description "Bass Tsuri Shiyouze! - Tournament wa Senryaku da! (Japan)" - rom ( name "Bass Tsuri Shiyouze! - Tournament wa Senryaku da! (Japan).gba" size 8388608 crc 1326E683 md5 BA5A3B9EB146DBD9D17B1279957DFD5A sha1 4CD862E02892CCC3E2A170EF401BC778C9042A35 ) + rom ( name "Bass Tsuri Shiyouze! - Tournament wa Senryaku da! (Japan).gba" size 8388608 crc 1326e683 sha1 4CD862E02892CCC3E2A170EF401BC778C9042A35 ) ) game ( name "Batman - Rise of Sin Tzu (USA) (En,Fr,Es)" description "Batman - Rise of Sin Tzu (USA) (En,Fr,Es)" - rom ( name "Batman - Rise of Sin Tzu (USA) (En,Fr,Es).gba" size 8388608 crc EF3790D1 md5 294D2E2E0782A347A04EB438185D805F sha1 E4B38B537139DE90659A25C7A51BA44CB7E9111C flags verified ) + rom ( name "Batman - Rise of Sin Tzu (USA) (En,Fr,Es).gba" size 8388608 crc ef3790d1 sha1 E4B38B537139DE90659A25C7A51BA44CB7E9111C flags verified ) ) game ( name "Batman - Vengeance (USA) (En,Fr,Es)" description "Batman - Vengeance (USA) (En,Fr,Es)" - rom ( name "Batman - Vengeance (USA) (En,Fr,Es).gba" size 8388608 crc 9FA17935 md5 06A6D7CD07281747CFE0300700A960FD sha1 CDE073FFBE21DEABDFB8A6D47EB16DB14068F468 ) + rom ( name "Batman - Vengeance (USA) (En,Fr,Es).gba" size 8388608 crc 9fa17935 sha1 CDE073FFBE21DEABDFB8A6D47EB16DB14068F468 ) ) game ( name "Batman - Vengeance (Europe) (En,Fr,De,Es,It,Nl)" description "Batman - Vengeance (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Batman - Vengeance (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 783AC0C7 md5 FFFE680EFF483B4D4366964EB7A150D8 sha1 413D18EE8A41E4B5051EA5BED343EDF8E52EEEE2 ) + rom ( name "Batman - Vengeance (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 783ac0c7 sha1 413D18EE8A41E4B5051EA5BED343EDF8E52EEEE2 flags verified ) ) game ( name "Batman Begins (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Batman Begins (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Batman Begins (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 83C90106 md5 8C48059BF2C40A78B9739EDF5EA411CB sha1 05C7C1BEA2B0CB77976E07C8F2A8B0EF5D1F5685 flags verified ) + rom ( name "Batman Begins (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 83c90106 sha1 05C7C1BEA2B0CB77976E07C8F2A8B0EF5D1F5685 flags verified ) ) game ( name "Battle B-Daman (USA)" description "Battle B-Daman (USA)" - rom ( name "Battle B-Daman (USA).gba" size 8388608 crc 6DCE8A26 md5 2B6B408513302519FD0E3FA72A67444B sha1 7016E0667201C965B6AE78C114B6CC5CB5EC7FF7 ) + rom ( name "Battle B-Daman (USA).gba" size 8388608 crc 6dce8a26 sha1 7016E0667201C965B6AE78C114B6CC5CB5EC7FF7 ) ) game ( name "Battle B-Daman - Fire Spirits! (USA)" description "Battle B-Daman - Fire Spirits! (USA)" - rom ( name "Battle B-Daman - Fire Spirits! (USA).gba" size 8388608 crc 5789F441 md5 E1B689A5776E8E35840E3A676FA11853 sha1 D57084C399BBD4B37D145B712FF6CA22DB9B1C49 ) + rom ( name "Battle B-Daman - Fire Spirits! (USA).gba" size 8388608 crc 5789f441 sha1 D57084C399BBD4B37D145B712FF6CA22DB9B1C49 ) ) game ( name "Battle Network Rockman EXE (Japan)" description "Battle Network Rockman EXE (Japan)" - rom ( name "Battle Network Rockman EXE (Japan).gba" size 8388608 crc D9516E50 md5 1E35207A805AF5BAFDE2361DF6721C60 sha1 6E42DBD5CDEE25851FB55DBA060B28E28E4F4E5F ) + rom ( name "Battle Network Rockman EXE (Japan).gba" size 8388608 crc d9516e50 sha1 6E42DBD5CDEE25851FB55DBA060B28E28E4F4E5F ) ) game ( name "Battle Network Rockman EXE 2 (Japan)" description "Battle Network Rockman EXE 2 (Japan)" - rom ( name "Battle Network Rockman EXE 2 (Japan).gba" size 8388608 crc 98E4F096 md5 5C9A6664DA79A4893895FD0C380FD020 sha1 6ED31EA56328673BA9D87186A7D506C701508E28 ) + rom ( name "Battle Network Rockman EXE 2 (Japan).gba" size 8388608 crc 98e4f096 sha1 6ED31EA56328673BA9D87186A7D506C701508E28 flags verified ) ) game ( name "Battle Network Rockman EXE 2 (Japan) (Rev 1)" description "Battle Network Rockman EXE 2 (Japan) (Rev 1)" - rom ( name "Battle Network Rockman EXE 2 (Japan) (Rev 1).gba" size 8388608 crc 41576087 md5 AE77F77FE5879ABFA3A15D4422DAC2DB sha1 9CB4D57BDEDEE5A760E98A3068C0E39A293B447C ) -) - -game ( - name "Battle Network Rockman EXE 3 (Japan) (Rev 1)" - description "Battle Network Rockman EXE 3 (Japan) (Rev 1)" - rom ( name "Battle Network Rockman EXE 3 (Japan) (Rev 1).gba" size 8388608 crc E48E6BC9 md5 15B8647B2A4E1D62F779703A0A50154A sha1 87E0AB10541EAAA5E9C01F7FAD822A3E1BF52278 ) + rom ( name "Battle Network Rockman EXE 2 (Japan) (Rev 1).gba" size 8388608 crc 41576087 sha1 9CB4D57BDEDEE5A760E98A3068C0E39A293B447C flags verified ) ) game ( name "Battle Network Rockman EXE 3 (Japan)" description "Battle Network Rockman EXE 3 (Japan)" - rom ( name "Battle Network Rockman EXE 3 (Japan).gba" size 8388608 crc 1C57724E md5 EE0B14AAB3CE1039857AD005636E07A4 sha1 2A381543F84DACC0F8310D4516FDE0C33B5FECA0 ) + rom ( name "Battle Network Rockman EXE 3 (Japan).gba" size 8388608 crc 1c57724e sha1 2A381543F84DACC0F8310D4516FDE0C33B5FECA0 ) +) + +game ( + name "Battle Network Rockman EXE 3 (Japan) (Rev 1)" + description "Battle Network Rockman EXE 3 (Japan) (Rev 1)" + rom ( name "Battle Network Rockman EXE 3 (Japan) (Rev 1).gba" size 8388608 crc e48e6bc9 sha1 87E0AB10541EAAA5E9C01F7FAD822A3E1BF52278 flags verified ) ) game ( name "Battle Network Rockman EXE 3 - Black (Japan) (Rev 1)" description "Battle Network Rockman EXE 3 - Black (Japan) (Rev 1)" - rom ( name "Battle Network Rockman EXE 3 - Black (Japan) (Rev 1).gba" size 8388608 crc FD57493B md5 CE9F58D790ACD6260BD45CA4346FAC74 sha1 E089A2254496A4791666C8122585CB785E3012FC ) + rom ( name "Battle Network Rockman EXE 3 - Black (Japan) (Rev 1).gba" size 8388608 crc fd57493b sha1 E089A2254496A4791666C8122585CB785E3012FC ) ) game ( name "Battle Network Rockman EXE 3 - Black (Japan) (Promo)" description "Battle Network Rockman EXE 3 - Black (Japan) (Promo)" - rom ( name "Battle Network Rockman EXE 3 - Black (Japan) (Promo).gba" size 8388608 crc 1F13C41F md5 0B57D3560459BD31C60667AD64843343 sha1 FF65AF8FEA15ECF5A556595EFE414D1211A9AB4E flags verified ) + rom ( name "Battle Network Rockman EXE 3 - Black (Japan) (Promo).gba" size 8388608 crc 1f13c41f sha1 FF65AF8FEA15ECF5A556595EFE414D1211A9AB4E flags verified ) ) game ( name "Battle X Battle - Kyodai Gyo Densetsu (Japan)" description "Battle X Battle - Kyodai Gyo Densetsu (Japan)" - rom ( name "Battle X Battle - Kyodai Gyo Densetsu (Japan).gba" size 4194304 crc 0C01F3B8 md5 8537579863758CEAD65406C13AB40EC0 sha1 6FCFD1823B760A69CE5140AF72C9AFC32E334431 ) -) - -game ( - name "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De)" - description "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De)" - rom ( name "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De).gba" size 8388608 crc 60BFCC8E md5 D7897C2530DEAA9D6ABC224FE9026F50 sha1 B5825F0BCF1E02DC88BE22CE4D889E27F92C01C3 flags verified ) + rom ( name "Battle X Battle - Kyodai Gyo Densetsu (Japan).gba" size 4194304 crc 0c01f3b8 sha1 6FCFD1823B760A69CE5140AF72C9AFC32E334431 ) ) game ( name "BattleBots - Beyond the BattleBox (USA)" description "BattleBots - Beyond the BattleBox (USA)" - rom ( name "BattleBots - Beyond the BattleBox (USA).gba" size 8388608 crc 985B3704 md5 4D5BD1475FB898E5BE99B85AA45F77FA sha1 AA4EE55F8BBB906EDBEC1761ECCC067454A881F8 ) + rom ( name "BattleBots - Beyond the BattleBox (USA).gba" size 8388608 crc 985b3704 sha1 AA4EE55F8BBB906EDBEC1761ECCC067454A881F8 ) +) + +game ( + name "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De)" + description "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De)" + rom ( name "BattleBots - Beyond the BattleBox (Europe) (En,Fr,De).gba" size 8388608 crc 60bfcc8e sha1 B5825F0BCF1E02DC88BE22CE4D889E27F92C01C3 flags verified ) ) game ( name "BattleBots - Design & Destroy (USA)" description "BattleBots - Design & Destroy (USA)" - rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8D5FFBCA md5 C93537014D674BF5843CB1AB5EB942C5 sha1 635986E584EBDC347C77EB45B1370A1206FBD7D7 ) + rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8d5ffbca sha1 635986E584EBDC347C77EB45B1370A1206FBD7D7 ) ) game ( - name "Battletoads (Unknown) (Proto)" - description "Battletoads (Unknown) (Proto)" - rom ( name "Battletoads (Unknown) (Proto).gba" size 2143184 crc 31480D89 md5 7357DACD671DD3AF8BD4A528D0F85493 sha1 4CEEBB84A77E4626C01DDDD2FBC8446344EBF504 ) + name "Battletoads (USA) (Proto)" + description "Battletoads (USA) (Proto)" + rom ( name "Battletoads (USA) (Proto).gba" size 2143184 crc 31480d89 sha1 4CEEBB84A77E4626C01DDDD2FBC8446344EBF504 flags verified ) ) game ( name "BB Ball (Japan)" description "BB Ball (Japan)" - rom ( name "BB Ball (Japan).gba" size 8388608 crc F6989FBF md5 4D01FF5D60CFD19A61FD062EFDBCE0E0 sha1 6F7CF0287646093F0428C060D3447C503D602D1A ) + rom ( name "BB Ball (Japan).gba" size 8388608 crc f6989fbf sha1 6F7CF0287646093F0428C060D3447C503D602D1A ) ) game ( name "Beast Shooter - Mezase Beast King! (Japan)" description "Beast Shooter - Mezase Beast King! (Japan)" - rom ( name "Beast Shooter - Mezase Beast King! (Japan).gba" size 4194304 crc A13760BC md5 CEC078B8F24AE79589E34454784F2386 sha1 1AD488B753498F271CE9C280197FF8E78B1C99BF ) + rom ( name "Beast Shooter - Mezase Beast King! (Japan).gba" size 4194304 crc a13760bc sha1 1AD488B753498F271CE9C280197FF8E78B1C99BF ) ) game ( name "Bee Game, The (USA)" description "Bee Game, The (USA)" - rom ( name "Bee Game, The (USA).gba" size 4194304 crc DA747C99 md5 5183D2AC230C5DBE614D96AB99C53922 sha1 3A073625E7D0F844B940D0D8A71216CDCE335A47 ) + rom ( name "Bee Game, The (USA).gba" size 4194304 crc da747c99 sha1 3A073625E7D0F844B940D0D8A71216CDCE335A47 ) ) game ( name "Berenstain Bears and the Spooky Old Tree, The (USA)" description "Berenstain Bears and the Spooky Old Tree, The (USA)" - rom ( name "Berenstain Bears and the Spooky Old Tree, The (USA).gba" size 4194304 crc F87B787B md5 F5C877C05DB6AC999A86F34A1813FC95 sha1 5E60D9BEC0B5C839802F0B9518CF15A9CC70AAD3 ) + rom ( name "Berenstain Bears and the Spooky Old Tree, The (USA).gba" size 4194304 crc f87b787b sha1 5E60D9BEC0B5C839802F0B9518CF15A9CC70AAD3 ) ) game ( name "Best Friends - Hunde & Katzen (Germany) (En,De)" description "Best Friends - Hunde & Katzen (Germany) (En,De)" - rom ( name "Best Friends - Hunde & Katzen (Germany) (En,De).gba" size 8388608 crc F71761BA md5 458F1B31B305D4DCCDAB13BE203411E0 sha1 5CAFAA89770E4010026AD691E6E33965F27F8852 ) + rom ( name "Best Friends - Hunde & Katzen (Germany) (En,De).gba" size 8388608 crc f71761ba sha1 5CAFAA89770E4010026AD691E6E33965F27F8852 ) ) game ( name "Best Play Pro Yakyuu (Japan)" description "Best Play Pro Yakyuu (Japan)" - rom ( name "Best Play Pro Yakyuu (Japan).gba" size 4194304 crc 61709D3D md5 A1AE1FEAF8199F7C6E2DC368382890BA sha1 BB46A4556AA059F89522251EF0E6C981DFBF5169 ) + rom ( name "Best Play Pro Yakyuu (Japan).gba" size 4194304 crc 61709d3d sha1 BB46A4556AA059F89522251EF0E6C981DFBF5169 ) ) game ( name "Beyblade G-Revolution (USA)" description "Beyblade G-Revolution (USA)" - rom ( name "Beyblade G-Revolution (USA).gba" size 4194304 crc 33AFDBE8 md5 78C34B8026991AB7B0A4990E1AF5D9B5 sha1 A89F7B4EB77DC986022201DB51A676451BA7C5E4 ) + rom ( name "Beyblade G-Revolution (USA).gba" size 4194304 crc 33afdbe8 sha1 A89F7B4EB77DC986022201DB51A676451BA7C5E4 ) ) game ( name "Beyblade G-Revolution (Europe) (En,De,Es,It)" description "Beyblade G-Revolution (Europe) (En,De,Es,It)" - rom ( name "Beyblade G-Revolution (Europe) (En,De,Es,It).gba" size 4194304 crc 5111DF55 md5 2448DBE0DDD454AD9B9217E2F3C64787 sha1 8E6D3AEC2506CCB71E72FEB30C52B22CAB7AB563 flags verified ) + rom ( name "Beyblade G-Revolution (Europe) (En,De,Es,It).gba" size 4194304 crc 5111df55 sha1 8E6D3AEC2506CCB71E72FEB30C52B22CAB7AB563 flags verified ) ) game ( name "Beyblade V-Force - Ultimate Blader Jam (Europe) (En,Fr,De,Es,It)" description "Beyblade V-Force - Ultimate Blader Jam (Europe) (En,Fr,De,Es,It)" - rom ( name "Beyblade V-Force - Ultimate Blader Jam (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 02CF5E5C md5 D3057E966F2383BA5664D4523D8F6DF1 sha1 6D20A586E7BB52B4A9352BBEAEC9D7BE65E93369 flags verified ) + rom ( name "Beyblade V-Force - Ultimate Blader Jam (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 02cf5e5c sha1 6D20A586E7BB52B4A9352BBEAEC9D7BE65E93369 flags verified ) ) game ( name "Beyblade V-Force - Ultimate Blader Jam (USA)" description "Beyblade V-Force - Ultimate Blader Jam (USA)" - rom ( name "Beyblade V-Force - Ultimate Blader Jam (USA).gba" size 8388608 crc 4A49272B md5 DE37C8D6F9B8CD56DFD81CA0F754E54B sha1 CD527C8C24E20E33913FC45199E64B3E6138A6E5 ) + rom ( name "Beyblade V-Force - Ultimate Blader Jam (USA).gba" size 8388608 crc 4a49272b sha1 CD527C8C24E20E33913FC45199E64B3E6138A6E5 ) ) game ( name "Bibi Blocksberg - Der Magische Hexenkreis (Germany)" description "Bibi Blocksberg - Der Magische Hexenkreis (Germany)" - rom ( name "Bibi Blocksberg - Der Magische Hexenkreis (Germany).gba" size 16777216 crc 516CEAC6 md5 C3C8470C8B0E460DEF74307FA985666B sha1 2D16C365C4614D8E2839E352D5A1878BE34CDD9D ) + rom ( name "Bibi Blocksberg - Der Magische Hexenkreis (Germany).gba" size 16777216 crc 516ceac6 sha1 2D16C365C4614D8E2839E352D5A1878BE34CDD9D ) ) game ( name "Bibi und Tina - Ferien auf dem Martinshof (Germany)" description "Bibi und Tina - Ferien auf dem Martinshof (Germany)" - rom ( name "Bibi und Tina - Ferien auf dem Martinshof (Germany).gba" size 16777216 crc 95A19C3C md5 F50A0C3FBF3E206528A3E6F99C80820C sha1 B7361717769FA942E04827DE416B1FC1B5BCFD3E ) + rom ( name "Bibi und Tina - Ferien auf dem Martinshof (Germany).gba" size 16777216 crc 95a19c3c sha1 B7361717769FA942E04827DE416B1FC1B5BCFD3E ) +) + +game ( + name "Bibi und Tina - Ferien auf dem Martinshof (Germany) (Rev 1)" + description "Bibi und Tina - Ferien auf dem Martinshof (Germany) (Rev 1)" + rom ( name "Bibi und Tina - Ferien auf dem Martinshof (Germany) (Rev 1).gba" size 16777216 crc fd8c06ee sha1 29B46F4728D55DB0E0D4092A9BF85F143ADC7E22 flags verified ) ) game ( name "Bible Game, The (USA)" description "Bible Game, The (USA)" - rom ( name "Bible Game, The (USA).gba" size 8388608 crc CEE6904E md5 01D53AE496CA36129F7A62CCF3CEED83 sha1 803CDEC573DAD49F76BD3BC225C485A601528FAC ) + rom ( name "Bible Game, The (USA).gba" size 8388608 crc cee6904e sha1 803CDEC573DAD49F76BD3BC225C485A601528FAC ) ) game ( name "Biene Maja, Die - Klatschmohnwiese in Gefahr (Germany)" description "Biene Maja, Die - Klatschmohnwiese in Gefahr (Germany)" - rom ( name "Biene Maja, Die - Klatschmohnwiese in Gefahr (Germany).gba" size 4194304 crc 0363C23F md5 6E39BAC68382B18DBFE5C7DD548C9A16 sha1 F176DFD53FB108919961B71E25093C6E840D2CE3 ) + rom ( name "Biene Maja, Die - Klatschmohnwiese in Gefahr (Germany).gba" size 4194304 crc 0363c23f sha1 F176DFD53FB108919961B71E25093C6E840D2CE3 ) ) game ( name "Big Mutha Truckers (USA)" description "Big Mutha Truckers (USA)" - rom ( name "Big Mutha Truckers (USA).gba" size 4194304 crc 574907F4 md5 F1BE09AC4B8D6A9E2C955CAB741669EF sha1 6D48801835C211DECD50244E38145823B0C82BE5 ) + rom ( name "Big Mutha Truckers (USA).gba" size 4194304 crc 574907f4 sha1 6D48801835C211DECD50244E38145823B0C82BE5 ) ) game ( name "Big Mutha Truckers (Europe) (En,Fr,De,Es,It)" description "Big Mutha Truckers (Europe) (En,Fr,De,Es,It)" - rom ( name "Big Mutha Truckers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc C54C02D0 md5 34F00ECB5B316478806EECA84CF62E55 sha1 78C81FC4E41C7D846E876411F4759A17495AEC3F ) + rom ( name "Big Mutha Truckers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc c54c02d0 sha1 78C81FC4E41C7D846E876411F4759A17495AEC3F ) ) game ( name "Bionicle (USA)" description "Bionicle (USA)" - rom ( name "Bionicle (USA).gba" size 8388608 crc C38F3530 md5 1934B7380BA91E4966F12C2968451289 sha1 2BBFF2410DCE12B96B98A193A5C5FB07E7B30B8C flags verified ) + rom ( name "Bionicle (USA).gba" size 8388608 crc c38f3530 sha1 2BBFF2410DCE12B96B98A193A5C5FB07E7B30B8C flags verified ) ) game ( name "Bionicle (Europe) (En,Fr,De,Da)" description "Bionicle (Europe) (En,Fr,De,Da)" - rom ( name "Bionicle (Europe) (En,Fr,De,Da).gba" size 8388608 crc 5412A24D md5 2C60AF1C2C17377C27B2D9AAC79F0CEA sha1 C605AB1AA03EBA6BC957929AA5C707A052B06B0D flags verified ) + rom ( name "Bionicle (Europe) (En,Fr,De,Da).gba" size 8388608 crc 5412a24d sha1 C605AB1AA03EBA6BC957929AA5C707A052B06B0D flags verified ) ) game ( name "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc DAEC2264 md5 ED573ADEAB96072232623AA7CFF4F077 sha1 A478F5880C484A70A5FDEFC42F73AAE2EB948168 flags verified ) + rom ( name "Bionicle - Matoran Adventures (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc daec2264 sha1 A478F5880C484A70A5FDEFC42F73AAE2EB948168 flags verified ) ) game ( name "Bionicle - Maze of Shadows (Europe) (En,De)" description "Bionicle - Maze of Shadows (Europe) (En,De)" - rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc BCE2D68E md5 8364F53C818449F93687EC490CD90120 sha1 7FF9811E2BD40B24DA02BE194213D41A0885AA34 ) + rom ( name "Bionicle - Maze of Shadows (Europe) (En,De).gba" size 8388608 crc bce2d68e sha1 7FF9811E2BD40B24DA02BE194213D41A0885AA34 ) ) game ( name "Bionicle - Maze of Shadows (USA)" description "Bionicle - Maze of Shadows (USA)" - rom ( name "Bionicle - Maze of Shadows (USA).gba" size 8388608 crc 3FE09C34 md5 F4F51F42AF0FCF96A1C33705F7F5CE08 sha1 34EDCD0C8E951533D9B4641DFAEFE2C762DED019 ) + rom ( name "Bionicle - Maze of Shadows (USA).gba" size 8388608 crc 3fe09c34 sha1 34EDCD0C8E951533D9B4641DFAEFE2C762DED019 ) ) game ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1)" description "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1)" - rom ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1).gba" size 8388608 crc 9D66EC5E md5 3B4B980B9031056501CFBFB7F8064DF8 sha1 430C7DAC6F7DD989294A8AC1CFDABD9E74B3E682 ) + rom ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1).gba" size 8388608 crc 9d66ec5e sha1 430C7DAC6F7DD989294A8AC1CFDABD9E74B3E682 flags verified ) ) game ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" description "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" - rom ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da).gba" size 16777216 crc F4FAFCCF md5 87D4626C1736B29A0E1F81CB6F3306A6 sha1 0996770EBFBBF2C272542E1AD4FFB0FCAE9C3828 ) + rom ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da).gba" size 16777216 crc f4fafccf sha1 0996770EBFBBF2C272542E1AD4FFB0FCAE9C3828 ) ) game ( name "Bionicle Heroes (Europe) (En,Fr,De,Es,It,Da)" description "Bionicle Heroes (Europe) (En,Fr,De,Es,It,Da)" - rom ( name "Bionicle Heroes (Europe) (En,Fr,De,Es,It,Da).gba" size 16777216 crc B8DC715B md5 729BF3FF498B73F09885BA38735A2858 sha1 102304AAB2816C3483618498CAB65C1626F1CED5 flags verified ) + rom ( name "Bionicle Heroes (Europe) (En,Fr,De,Es,It,Da).gba" size 16777216 crc b8dc715b sha1 102304AAB2816C3483618498CAB65C1626F1CED5 flags verified ) ) game ( name "bit Generations - Boundish (Japan) (En)" description "bit Generations - Boundish (Japan) (En)" - rom ( name "bit Generations - Boundish (Japan) (En).gba" size 4194304 crc 904B55D4 md5 445194AD30C7CF9FC16CE8A7C60419D1 sha1 51C1A436F59F2D480A33836ACF2645CD5442F2A5 flags verified ) + rom ( name "bit Generations - Boundish (Japan) (En).gba" size 4194304 crc 904b55d4 sha1 51C1A436F59F2D480A33836ACF2645CD5442F2A5 flags verified ) ) game ( name "bit Generations - Coloris (Japan) (En)" description "bit Generations - Coloris (Japan) (En)" - rom ( name "bit Generations - Coloris (Japan) (En).gba" size 16777216 crc A04BE1ED md5 FACEA584A4C4465BCB9E028C7B36A481 sha1 91BCE8CFAB330E6645DA105BB145516642C1CA20 ) + rom ( name "bit Generations - Coloris (Japan) (En).gba" size 16777216 crc a04be1ed sha1 91BCE8CFAB330E6645DA105BB145516642C1CA20 ) ) game ( name "bit Generations - Dialhex (Japan) (En)" description "bit Generations - Dialhex (Japan) (En)" - rom ( name "bit Generations - Dialhex (Japan) (En).gba" size 16777216 crc 812EF3A9 md5 A4FE285E6E4C0248D9D2FD9AE22590CD sha1 6C6F74A7012F5BCA0397C34B404A4D9E4B79C933 flags verified ) + rom ( name "bit Generations - Dialhex (Japan) (En).gba" size 16777216 crc 812ef3a9 sha1 6C6F74A7012F5BCA0397C34B404A4D9E4B79C933 flags verified ) ) game ( name "bit Generations - Digidrive (Japan) (En)" description "bit Generations - Digidrive (Japan) (En)" - rom ( name "bit Generations - Digidrive (Japan) (En).gba" size 16777216 crc 0867DC29 md5 0772DFD199BB5039A5D0CC5015D4AF1D sha1 106595ACB960ECBF05DFC1909A0B7E08EE3EF1C6 flags verified ) + rom ( name "bit Generations - Digidrive (Japan) (En).gba" size 16777216 crc 0867dc29 sha1 106595ACB960ECBF05DFC1909A0B7E08EE3EF1C6 flags verified ) ) game ( name "bit Generations - Dotstream (Japan) (En)" description "bit Generations - Dotstream (Japan) (En)" - rom ( name "bit Generations - Dotstream (Japan) (En).gba" size 16777216 crc F0760400 md5 00FC773FFF582DC53604A7229F64E82F sha1 D0883352702F812A03B3C794163AF0FF558BD4C7 ) + rom ( name "bit Generations - Dotstream (Japan) (En).gba" size 16777216 crc f0760400 sha1 D0883352702F812A03B3C794163AF0FF558BD4C7 ) ) game ( name "bit Generations - Orbital (Japan) (En)" description "bit Generations - Orbital (Japan) (En)" - rom ( name "bit Generations - Orbital (Japan) (En).gba" size 16777216 crc D5D43B4B md5 2885A1D384A596A6098855BD155A24A6 sha1 437E3093928CE9B0705476053A059D70F9F84AE3 flags verified ) + rom ( name "bit Generations - Orbital (Japan) (En).gba" size 16777216 crc d5d43b4b sha1 437E3093928CE9B0705476053A059D70F9F84AE3 flags verified ) ) game ( name "bit Generations - Soundvoyager (Japan) (En)" description "bit Generations - Soundvoyager (Japan) (En)" - rom ( name "bit Generations - Soundvoyager (Japan) (En).gba" size 16777216 crc B32E0839 md5 6632F33046615D90A891259D0B2678F9 sha1 B376C61897F810685DBDD55833503A7EA74A235E ) + rom ( name "bit Generations - Soundvoyager (Japan) (En).gba" size 16777216 crc b32e0839 sha1 B376C61897F810685DBDD55833503A7EA74A235E ) ) game ( name "Black Belt Challenge (Europe)" description "Black Belt Challenge (Europe)" - rom ( name "Black Belt Challenge (Europe).gba" size 8388608 crc 72A55741 md5 EDD82D2798C8537CFBF044FD1AFD6A49 sha1 7965812C90267B4C9AA49D303AA651AD406E95A2 flags verified ) + rom ( name "Black Belt Challenge (Europe).gba" size 8388608 crc 72a55741 sha1 7965812C90267B4C9AA49D303AA651AD406E95A2 flags verified ) ) game ( name "Black Black - Bura Bura (Japan)" description "Black Black - Bura Bura (Japan)" - rom ( name "Black Black - Bura Bura (Japan).gba" size 8388608 crc 05A4303E md5 20D7B1BCAF56617DF5718F0052A83011 sha1 80CBB4FBFAF5B0B0F2A01B82C46B672B69EF3FAE ) + rom ( name "Black Black - Bura Bura (Japan).gba" size 8388608 crc 05a4303e sha1 80CBB4FBFAF5B0B0F2A01B82C46B672B69EF3FAE ) ) game ( name "Black Matrix Zero (Japan)" description "Black Matrix Zero (Japan)" - rom ( name "Black Matrix Zero (Japan).gba" size 8388608 crc 2B2AFA2E md5 567C4E75646947464920559892E5747F sha1 697F85513AB5704B8B1D554E087A45BFDB92EC33 ) + rom ( name "Black Matrix Zero (Japan).gba" size 8388608 crc 2b2afa2e sha1 697F85513AB5704B8B1D554E087A45BFDB92EC33 ) ) game ( name "Blackthorne (USA)" description "Blackthorne (USA)" - rom ( name "Blackthorne (USA).gba" size 4194304 crc 8E6DCD53 md5 D0BB79FB5A05702CE8B7D03320FCDF52 sha1 8F7F8C2051130B881E1FC131360CBC4946A63535 flags verified ) + rom ( name "Blackthorne (USA).gba" size 4194304 crc 8e6dcd53 sha1 8F7F8C2051130B881E1FC131360CBC4946A63535 flags verified ) ) game ( name "Blackthorne (Europe)" description "Blackthorne (Europe)" - rom ( name "Blackthorne (Europe).gba" size 4194304 crc E1D36A8C md5 4C84DF7F486BF96316E73CD655C0F46B sha1 4611A129977A4A12186106BBF3A34A51B603D1EA ) + rom ( name "Blackthorne (Europe).gba" size 4194304 crc e1d36a8c sha1 4611A129977A4A12186106BBF3A34A51B603D1EA flags verified ) ) game ( name "Blades of Thunder (USA)" description "Blades of Thunder (USA)" - rom ( name "Blades of Thunder (USA).gba" size 8388608 crc 2CCD4915 md5 2164E4C57A166869961FA1B428FD6DED sha1 CE371C336EDB5E961878223936DE61C40CCB4A97 ) + rom ( name "Blades of Thunder (USA).gba" size 8388608 crc 2ccd4915 sha1 CE371C336EDB5E961878223936DE61C40CCB4A97 ) ) game ( name "Bleach Advance - Kurenai ni Somaru Soul Society (Japan)" description "Bleach Advance - Kurenai ni Somaru Soul Society (Japan)" - rom ( name "Bleach Advance - Kurenai ni Somaru Soul Society (Japan).gba" size 33554432 crc 9DE5CD08 md5 A3827342698BD0FF407E2D805BFC27AD sha1 29D24C38D3EC8BBE9D81DF2F5FF61C4A2DADCEE4 ) + rom ( name "Bleach Advance - Kurenai ni Somaru Soul Society (Japan).gba" size 33554432 crc 9de5cd08 sha1 29D24C38D3EC8BBE9D81DF2F5FF61C4A2DADCEE4 ) ) game ( name "Blender Bros. (USA)" description "Blender Bros. (USA)" - rom ( name "Blender Bros. (USA).gba" size 8388608 crc 9A91D7F1 md5 8AA4F88927F3C5BF1AAED1562742A64D sha1 485B1698B4005BC15A83982B85BAC68BBBAE40EC ) + rom ( name "Blender Bros. (USA).gba" size 8388608 crc 9a91d7f1 sha1 485B1698B4005BC15A83982B85BAC68BBBAE40EC ) +) + +game ( + name "Blue Angelo - Angels from the Shrine (Europe) (Proto 1)" + description "Blue Angelo - Angels from the Shrine (Europe) (Proto 1)" + rom ( name "Blue Angelo - Angels from the Shrine (Europe) (Proto 1).gba" size 8140988 crc 0cec865b sha1 D57B1F717EE65A8E45CF5C2A38A9FC542A1D1D20 flags verified ) +) + +game ( + name "Blue Angelo - Angels from the Shrine (Europe) (Proto 2)" + description "Blue Angelo - Angels from the Shrine (Europe) (Proto 2)" + rom ( name "Blue Angelo - Angels from the Shrine (Europe) (Proto 2).gba" size 19468416 crc f1b924dc sha1 B238ACD325D8A53EAD8E72A95C29922E31D0012E flags verified ) ) game ( name "BMX Trick Racer (USA)" description "BMX Trick Racer (USA)" - rom ( name "BMX Trick Racer (USA).gba" size 16777216 crc B6D79476 md5 2B9A9998D870AFAEC5D7B0F1A2A477F4 sha1 3A42D3331E81E92D49E285B36AE1A6ED5DB6A2EA flags verified ) + rom ( name "BMX Trick Racer (USA).gba" size 16777216 crc b6d79476 sha1 3A42D3331E81E92D49E285B36AE1A6ED5DB6A2EA flags verified ) ) game ( name "Board Game Classics (USA)" description "Board Game Classics (USA)" - rom ( name "Board Game Classics (USA).gba" size 4194304 crc 69D760BB md5 871133B4E4E8B172F7538B0250C9BB45 sha1 83BA1075B9170598FEA26D0F1F9F1ECD3CF0D6D2 ) + rom ( name "Board Game Classics (USA).gba" size 4194304 crc 69d760bb sha1 83BA1075B9170598FEA26D0F1F9F1ECD3CF0D6D2 ) ) game ( - name "Board Game Classics (Europe) (En,Fr,De,Es,It)" - description "Board Game Classics (Europe) (En,Fr,De,Es,It)" - rom ( name "Board Game Classics (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E5C745D8 md5 1DA8C2E3F6594C4287770171D145B7D3 sha1 F9A3058E55D72EFDEBC5E2B4D2B5D6E00E71E5FF flags verified ) + name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It)" + description "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It)" + rom ( name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e5c745d8 sha1 F9A3058E55D72EFDEBC5E2B4D2B5D6E00E71E5FF flags verified ) ) game ( name "Boboboubo Boubobo - 9 Kyoku Senshi Gag Yuugou (Japan)" description "Boboboubo Boubobo - 9 Kyoku Senshi Gag Yuugou (Japan)" - rom ( name "Boboboubo Boubobo - 9 Kyoku Senshi Gag Yuugou (Japan).gba" size 16777216 crc 0BD9700B md5 9EF9715F14AE656BBC4A11F5D2CB7480 sha1 77D8301D8F7E9580E70500597475DF1DF2A0B843 ) + rom ( name "Boboboubo Boubobo - 9 Kyoku Senshi Gag Yuugou (Japan).gba" size 16777216 crc 0bd9700b sha1 77D8301D8F7E9580E70500597475DF1DF2A0B843 ) ) game ( name "Boboboubo Boubobo - Bakutou Hajike Taisen (Japan)" description "Boboboubo Boubobo - Bakutou Hajike Taisen (Japan)" - rom ( name "Boboboubo Boubobo - Bakutou Hajike Taisen (Japan).gba" size 16777216 crc 166FEECB md5 C44FC33A49D116DB3BA5248D877A52F5 sha1 D42817971433E2604A1C57431B0FC6DE52723E6A ) + rom ( name "Boboboubo Boubobo - Bakutou Hajike Taisen (Japan).gba" size 16777216 crc 166feecb sha1 D42817971433E2604A1C57431B0FC6DE52723E6A ) ) game ( name "Boboboubo Boubobo - Maji de!! Shinken Battle (Japan)" description "Boboboubo Boubobo - Maji de!! Shinken Battle (Japan)" - rom ( name "Boboboubo Boubobo - Maji de!! Shinken Battle (Japan).gba" size 8388608 crc 37938CA4 md5 6134D1E8B4794E073413657C98F8C82A sha1 5B5E672031F5148BDD69BC5190FD4CEEF3FFDDC5 ) + rom ( name "Boboboubo Boubobo - Maji de!! Shinken Battle (Japan).gba" size 8388608 crc 37938ca4 sha1 5B5E672031F5148BDD69BC5190FD4CEEF3FFDDC5 ) ) game ( name "Boboboubo Boubobo - Ougi 87.5 Bakuretsu Hanage Shinken (Japan)" description "Boboboubo Boubobo - Ougi 87.5 Bakuretsu Hanage Shinken (Japan)" - rom ( name "Boboboubo Boubobo - Ougi 87.5 Bakuretsu Hanage Shinken (Japan).gba" size 8388608 crc 58105F89 md5 CE085F9EB00A26CF9535172ACC99921C sha1 C93FD22BB10E26CB986161CE1CDC4C2ACB38ADD9 ) + rom ( name "Boboboubo Boubobo - Ougi 87.5 Bakuretsu Hanage Shinken (Japan).gba" size 8388608 crc 58105f89 sha1 C93FD22BB10E26CB986161CE1CDC4C2ACB38ADD9 ) ) game ( name "Boktai - The Sun Is in Your Hand (USA)" description "Boktai - The Sun Is in Your Hand (USA)" - rom ( name "Boktai - The Sun Is in Your Hand (USA).gba" size 16777216 crc E715AC45 md5 FF75C62AB690410CC8FCA24204D783E9 sha1 7164326283DF46A3941EC7B6CECA889CBC40E660 flags verified ) + rom ( name "Boktai - The Sun Is in Your Hand (USA).gba" size 16777216 crc e715ac45 sha1 7164326283DF46A3941EC7B6CECA889CBC40E660 flags verified ) ) game ( name "Boktai - The Sun Is in Your Hand (Europe) (En,Fr,De,Es,It)" description "Boktai - The Sun Is in Your Hand (Europe) (En,Fr,De,Es,It)" - rom ( name "Boktai - The Sun Is in Your Hand (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 9686C36B md5 C8B49C53003B8D9A15D91A5A5D5CC91B sha1 64F7BF0F0560F6E94DA33B549D3206678B29F557 flags verified ) + rom ( name "Boktai - The Sun Is in Your Hand (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 9686c36b sha1 64F7BF0F0560F6E94DA33B549D3206678B29F557 flags verified ) ) game ( - name "Boktai - The Sun Is in Your Hand (USA) (Beta)" - description "Boktai - The Sun Is in Your Hand (USA) (Beta) (probably unfinished US-version still containing J-serial)" - rom ( name "Boktai - The Sun Is in Your Hand (USA) (Beta).gba" size 16777216 crc CF692572 md5 5EED126956C06A047B7098E0FACD7067 sha1 F91126CD3A1BF7BF5F770D3A70229171D0D5A6EE ) + name "Boktai - The Sun Is in Your Hand (USA) (Sample)" + description "Boktai - The Sun Is in Your Hand (USA) (Sample) (Possibly a version given out to press at E3 or an E3 demo)" + rom ( name "Boktai - The Sun Is in Your Hand (USA) (Sample).gba" size 16777216 crc cf692572 sha1 F91126CD3A1BF7BF5F770D3A70229171D0D5A6EE ) ) game ( name "Boktai 2 - Solar Boy Django (USA)" description "Boktai 2 - Solar Boy Django (USA)" - rom ( name "Boktai 2 - Solar Boy Django (USA).gba" size 16777216 crc E1FFB2D1 md5 31231965D6A43D935E3629A67E06E0BB sha1 CD10D8ED82F4DAF4072774F70D015E39A5D32D0B flags verified ) + rom ( name "Boktai 2 - Solar Boy Django (USA).gba" size 16777216 crc e1ffb2d1 sha1 CD10D8ED82F4DAF4072774F70D015E39A5D32D0B flags verified ) ) game ( name "Boktai 2 - Solar Boy Django (Europe) (En,Fr,De,Es,It)" description "Boktai 2 - Solar Boy Django (Europe) (En,Fr,De,Es,It)" - rom ( name "Boktai 2 - Solar Boy Django (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 748189B5 md5 66C0B2E21872F8E9AF56292D881C1516 sha1 EEACDF5A9D3D2173A4A96689B72DC6B7AD92153C flags verified ) + rom ( name "Boktai 2 - Solar Boy Django (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 748189b5 sha1 EEACDF5A9D3D2173A4A96689B72DC6B7AD92153C flags verified ) ) game ( name "Boku wa Koukuu Kanseikan (Japan) (Rev 1)" description "Boku wa Koukuu Kanseikan (Japan) (Rev 1)" - rom ( name "Boku wa Koukuu Kanseikan (Japan) (Rev 1).gba" size 8388608 crc 5E3B163E md5 90F1DFB87A2C47224D43C8F09EDA0841 sha1 54BF631A49C031539D8B3DD5F98B050B0F4A202E ) + rom ( name "Boku wa Koukuu Kanseikan (Japan) (Rev 1).gba" size 8388608 crc 5e3b163e sha1 54BF631A49C031539D8B3DD5F98B050B0F4A202E flags verified ) ) game ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi (Japan)" description "Bokujou Monogatari - Mineral Town no Nakama-tachi (Japan)" - rom ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi (Japan).gba" size 8388608 crc 09185657 md5 D92308BC903F4E92587DF2CEDC89B477 sha1 A655B2789AED14A6AC78C6075FBC533D3062DBE3 ) + rom ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi (Japan).gba" size 8388608 crc 09185657 sha1 A655B2789AED14A6AC78C6075FBC533D3062DBE3 ) ) game ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi for Girl (Japan)" description "Bokujou Monogatari - Mineral Town no Nakama-tachi for Girl (Japan)" - rom ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi for Girl (Japan).gba" size 16777216 crc 7C26672F md5 3A502CDB8F2D8E6E0E3B07685B50FA7E sha1 8B624AEB36A0321C094DC3EE1F64F5573509B212 ) + rom ( name "Bokujou Monogatari - Mineral Town no Nakama-tachi for Girl (Japan).gba" size 16777216 crc 7c26672f sha1 8B624AEB36A0321C094DC3EE1F64F5573509B212 flags verified ) ) game ( name "Bokura no Taiyou - Taiyou Action RPG (Japan)" description "Bokura no Taiyou - Taiyou Action RPG (Japan)" - rom ( name "Bokura no Taiyou - Taiyou Action RPG (Japan).gba" size 16777216 crc A09C0807 md5 9F1C1202ED1D856C5836CEE6818A171E sha1 C51AD84E9403DB94CD18A14AC72F8367B52A0D7F flags verified ) + rom ( name "Bokura no Taiyou - Taiyou Action RPG (Japan).gba" size 16777216 crc a09c0807 sha1 C51AD84E9403DB94CD18A14AC72F8367B52A0D7F flags verified ) ) game ( name "Bomber Man Jetters - Densetsu no Bomber Man (Japan)" description "Bomber Man Jetters - Densetsu no Bomber Man (Japan)" - rom ( name "Bomber Man Jetters - Densetsu no Bomber Man (Japan).gba" size 8388608 crc 70C423B8 md5 C86F84D68F584B666E5490F764FDA27E sha1 7D0FBE2D8ADDBA9D3C49DA7BC0DE792CF10B7268 ) + rom ( name "Bomber Man Jetters - Densetsu no Bomber Man (Japan).gba" size 8388608 crc 70c423b8 sha1 7D0FBE2D8ADDBA9D3C49DA7BC0DE792CF10B7268 flags verified ) ) game ( name "Bomber Man Jetters - Game Collection (Japan)" description "Bomber Man Jetters - Game Collection (Japan)" - rom ( name "Bomber Man Jetters - Game Collection (Japan).gba" size 8388608 crc B9DEA90D md5 4B4D0E642C8B299F3D7D1298ACB0BDDB sha1 55A6EF08C00E5C02B256424495D9F90F6924CB7A ) + rom ( name "Bomber Man Jetters - Game Collection (Japan).gba" size 8388608 crc b9dea90d sha1 55A6EF08C00E5C02B256424495D9F90F6924CB7A ) ) game ( name "Bomber Man Max 2 - Bomber Man Version (Japan)" description "Bomber Man Max 2 - Bomber Man Version (Japan)" - rom ( name "Bomber Man Max 2 - Bomber Man Version (Japan).gba" size 8388608 crc 656CF22E md5 C49C26566F147A3546F7A299D55010BA sha1 625E4C19F045202DE4D95262B5CD30F15C4469FE ) + rom ( name "Bomber Man Max 2 - Bomber Man Version (Japan).gba" size 8388608 crc 656cf22e sha1 625E4C19F045202DE4D95262B5CD30F15C4469FE ) ) game ( name "Bomber Man Max 2 - Max Version (Japan)" description "Bomber Man Max 2 - Max Version (Japan)" - rom ( name "Bomber Man Max 2 - Max Version (Japan).gba" size 8388608 crc 290D8810 md5 EDB9CFE1EFCDD9B8ABCF16DFBD0421B8 sha1 7277EA99C0015DF9AE1A29A9B45909F168624901 ) + rom ( name "Bomber Man Max 2 - Max Version (Japan).gba" size 8388608 crc 290d8810 sha1 7277EA99C0015DF9AE1A29A9B45909F168624901 ) ) game ( name "Bomber Man Story (Japan)" description "Bomber Man Story (Japan)" - rom ( name "Bomber Man Story (Japan).gba" size 4194304 crc 38231BC2 md5 1A806736283FB999F0D1EC35B54CDF88 sha1 1CD1B87DF9CC51CCF024584A4885C6C7A3F42AA0 ) + rom ( name "Bomber Man Story (Japan).gba" size 4194304 crc f7f40189 sha1 BA093C5EF2C2BB57D0F6F6735E82C536C7E9EC45 flags verified ) ) game ( name "Bomberman Max 2 - Blue Advance (USA)" description "Bomberman Max 2 - Blue Advance (USA)" - rom ( name "Bomberman Max 2 - Blue Advance (USA).gba" size 8388608 crc 94C620F3 md5 4EFB16F9D71758336DB0AFEB380859B0 sha1 B2C64452FE8C879C1ABD5CF709E3E26971EEB166 ) + rom ( name "Bomberman Max 2 - Blue Advance (USA).gba" size 8388608 crc 94c620f3 sha1 B2C64452FE8C879C1ABD5CF709E3E26971EEB166 ) ) game ( name "Bomberman Max 2 - Blue Advance (Europe) (En,Fr,De)" description "Bomberman Max 2 - Blue Advance (Europe) (En,Fr,De)" - rom ( name "Bomberman Max 2 - Blue Advance (Europe) (En,Fr,De).gba" size 16777216 crc 09FC4D53 md5 723EE616E311BD9F8584405637D9128C sha1 EB25E28AE1047145FD2CBCC3ECBB63330FBC8FE0 ) + rom ( name "Bomberman Max 2 - Blue Advance (Europe) (En,Fr,De).gba" size 16777216 crc 09fc4d53 sha1 EB25E28AE1047145FD2CBCC3ECBB63330FBC8FE0 flags verified ) ) game ( name "Bomberman Max 2 - Red Advance (USA)" description "Bomberman Max 2 - Red Advance (USA)" - rom ( name "Bomberman Max 2 - Red Advance (USA).gba" size 8388608 crc 4DB517C1 md5 0CC6758258B584E51046B00139C50E60 sha1 1428BB0A78AEBB112A2702ED8561BDFE9BCEDCF1 flags verified ) + rom ( name "Bomberman Max 2 - Red Advance (USA).gba" size 8388608 crc 4db517c1 sha1 1428BB0A78AEBB112A2702ED8561BDFE9BCEDCF1 flags verified ) ) game ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De)" description "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De)" - rom ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De).gba" size 16777216 crc 67D2E5B8 md5 BEE56CA47B1F319E27592BAF2F053EC9 sha1 4D514FE19B59D42BE9A118C99E2008EFEE2AEDCB ) + rom ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De).gba" size 16777216 crc 67d2e5b8 sha1 4D514FE19B59D42BE9A118C99E2008EFEE2AEDCB flags verified ) ) game ( name "Bomberman Tournament (USA, Europe)" description "Bomberman Tournament (USA, Europe)" - rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282E6 md5 79AEF9BBE1378ADFBD688CD66E11A7BE sha1 DA44A5D65F1A00D75A57E5B46E30F9E4E2D18F6C flags verified ) + rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282e6 sha1 DA44A5D65F1A00D75A57E5B46E30F9E4E2D18F6C flags verified ) ) game ( name "Bookworm (USA)" description "Bookworm (USA)" - rom ( name "Bookworm (USA).gba" size 4194304 crc 4D540384 md5 C64B677831500E85222D85C70E2D23B6 sha1 C45D588F8AADE81152AE789D62316DB9138452B8 flags verified ) + rom ( name "Bookworm (USA).gba" size 4194304 crc 4d540384 sha1 C45D588F8AADE81152AE789D62316DB9138452B8 flags verified ) ) game ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate (Japan)" description "Bouken Yuuki Pluster World - Densetsu no Plust Gate (Japan)" - rom ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate (Japan).gba" size 8388608 crc 57438E39 md5 A5F4C03F31988A0BD97569372E1F826D sha1 BB779DE3AA9C08B82FFCB3CB2EB70F151A8A3B13 flags verified ) + rom ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate (Japan).gba" size 8388608 crc 57438e39 sha1 BB779DE3AA9C08B82FFCB3CB2EB70F151A8A3B13 flags verified ) ) game ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate EX (Japan)" description "Bouken Yuuki Pluster World - Densetsu no Plust Gate EX (Japan)" - rom ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate EX (Japan).gba" size 16777216 crc 3F60BF6A md5 D60C5ACE24093283F3DC9C74F3AC2489 sha1 D660E16640897DA847951937F7792724E133A642 ) + rom ( name "Bouken Yuuki Pluster World - Densetsu no Plust Gate EX (Japan).gba" size 16777216 crc 3f60bf6a sha1 D660E16640897DA847951937F7792724E133A642 ) ) game ( name "Bouken Yuuki Pluster World - Pluston GP (Japan)" description "Bouken Yuuki Pluster World - Pluston GP (Japan)" - rom ( name "Bouken Yuuki Pluster World - Pluston GP (Japan).gba" size 8388608 crc CE7A07F0 md5 5D31FFA72FDECF556CDFF2D760274967 sha1 013301F82256EE6F574864455301F0E756974D6E flags verified ) + rom ( name "Bouken Yuuki Pluster World - Pluston GP (Japan).gba" size 8388608 crc ce7a07f0 sha1 013301F82256EE6F574864455301F0E756974D6E flags verified ) ) game ( name "Bouken-ou Beet - Busters Road (Japan)" description "Bouken-ou Beet - Busters Road (Japan)" - rom ( name "Bouken-ou Beet - Busters Road (Japan).gba" size 16777216 crc 1CC42EBC md5 42F9A789CCC93FB5CCFD63F086F5094D sha1 82E8E42FE7B5CEF46079ED18AD38B2F48C26D52D ) + rom ( name "Bouken-ou Beet - Busters Road (Japan).gba" size 16777216 crc 1cc42ebc sha1 82E8E42FE7B5CEF46079ED18AD38B2F48C26D52D ) ) game ( name "Boukyaku no Senritsu (Japan)" description "Boukyaku no Senritsu (Japan)" - rom ( name "Boukyaku no Senritsu (Japan).gba" size 8388608 crc 128EDC4F md5 0C53EF6B66B0F6912A524659C3A068C6 sha1 0DF471F8A7E06FD56ED8FB09D902B65A79520B4D ) -) - -game ( - name "Boulder Dash EX (Europe) (En,Fr,De)" - description "Boulder Dash EX (Europe) (En,Fr,De)" - rom ( name "Boulder Dash EX (Europe) (En,Fr,De).gba" size 4194304 crc D41866A9 md5 70ED2328306FA863BF144B7FDCDBFDFD sha1 DA098CA5D083019AA920FBB648031BACAB549CC4 flags verified ) + rom ( name "Boukyaku no Senritsu (Japan).gba" size 8388608 crc 128edc4f sha1 0DF471F8A7E06FD56ED8FB09D902B65A79520B4D ) ) game ( name "Boulder Dash EX (USA)" description "Boulder Dash EX (USA)" - rom ( name "Boulder Dash EX (USA).gba" size 4194304 crc B355365A md5 8653D5731F4EFFD21E435B9A274023A4 sha1 8BC0DADBD18E3D88645AABA3AA0CED8088201C8F ) + rom ( name "Boulder Dash EX (USA).gba" size 4194304 crc b355365a sha1 8BC0DADBD18E3D88645AABA3AA0CED8088201C8F ) ) game ( name "Boulder Dash EX (Japan)" description "Boulder Dash EX (Japan)" - rom ( name "Boulder Dash EX (Japan).gba" size 4194304 crc E77D5F9B md5 3CC5E954F8ADC6D313C44DA31E3F8A5C sha1 1348BFEAE9C4D82A577EDC76B8FA81F8A8A8C2B2 ) + rom ( name "Boulder Dash EX (Japan).gba" size 4194304 crc e77d5f9b sha1 1348BFEAE9C4D82A577EDC76B8FA81F8A8A8C2B2 ) +) + +game ( + name "Boulder Dash EX (Europe) (En,Fr,De)" + description "Boulder Dash EX (Europe) (En,Fr,De)" + rom ( name "Boulder Dash EX (Europe) (En,Fr,De).gba" size 4194304 crc d41866a9 sha1 DA098CA5D083019AA920FBB648031BACAB549CC4 flags verified ) ) game ( name "Boxing Fever (USA, Europe)" description "Boxing Fever (USA, Europe)" - rom ( name "Boxing Fever (USA, Europe).gba" size 8388608 crc 08A4FDC4 md5 2A43344ED8E9654F0CC95CE788371BA4 sha1 20AD5E7D367BE3E4220B184947585DF7D305B6D3 flags verified ) + rom ( name "Boxing Fever (USA, Europe).gba" size 8388608 crc 08a4fdc4 sha1 20AD5E7D367BE3E4220B184947585DF7D305B6D3 flags verified ) ) game ( name "Bratz (USA) (En,Fr,Es)" description "Bratz (USA) (En,Fr,Es)" - rom ( name "Bratz (USA) (En,Fr,Es).gba" size 4194304 crc 21E5A010 md5 8B809080A689886E7877EC89EB82AE99 sha1 7372324941F48F5D02F667099DE4FAFBC96CFF86 ) + rom ( name "Bratz (USA) (En,Fr,Es).gba" size 4194304 crc 21e5a010 sha1 7372324941F48F5D02F667099DE4FAFBC96CFF86 ) ) game ( name "Bratz (Europe) (En,Fr,De,Es,It)" description "Bratz (Europe) (En,Fr,De,Es,It)" - rom ( name "Bratz (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B30241E2 md5 ACCB22E06C37F68B55D8FA34853F885B sha1 27C83075014FBF4D15A1A91DB5F9C9BABB8E96D3 ) + rom ( name "Bratz (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b30241e2 sha1 27C83075014FBF4D15A1A91DB5F9C9BABB8E96D3 ) ) game ( name "Bratz - Babyz (Europe) (En,Es,It)" description "Bratz - Babyz (Europe) (En,Es,It)" - rom ( name "Bratz - Babyz (Europe) (En,Es,It).gba" size 4194304 crc 08B89540 md5 A7B49DE9AB6230D8077BBEF4D906497B sha1 33B0600B2CC0BFD555BD26BDD73BC9830607A2AC ) + rom ( name "Bratz - Babyz (Europe) (En,Es,It).gba" size 4194304 crc 08b89540 sha1 33B0600B2CC0BFD555BD26BDD73BC9830607A2AC ) ) game ( name "Bratz - Babyz (USA)" description "Bratz - Babyz (USA)" - rom ( name "Bratz - Babyz (USA).gba" size 4194304 crc 23E8A494 md5 33492E64F810FB02F6DFF879B8E0182B sha1 84548F0E15048B024F787CEF41C5258293753C1F ) + rom ( name "Bratz - Babyz (USA).gba" size 4194304 crc 23e8a494 sha1 84548F0E15048B024F787CEF41C5258293753C1F ) ) game ( name "Bratz - Forever Diamondz (USA)" description "Bratz - Forever Diamondz (USA)" - rom ( name "Bratz - Forever Diamondz (USA).gba" size 8388608 crc 9E389908 md5 AFBD8A5D314391D9731692CC1131DC6C sha1 68222B1E029D931C2A9776B7040928A921A9C12B ) + rom ( name "Bratz - Forever Diamondz (USA).gba" size 8388608 crc 9e389908 sha1 68222B1E029D931C2A9776B7040928A921A9C12B ) ) game ( name "Bratz - Forever Diamondz (Germany)" description "Bratz - Forever Diamondz (Germany)" - rom ( name "Bratz - Forever Diamondz (Germany).gba" size 8388608 crc F39CADEB md5 5CD8DF1C60618CE05BB26302DEFB0B7B sha1 FD590CC4C3AD26FF32F80F66890D8CFC968B23FB ) + rom ( name "Bratz - Forever Diamondz (Germany).gba" size 8388608 crc f39cadeb sha1 FD590CC4C3AD26FF32F80F66890D8CFC968B23FB ) ) game ( name "Bratz - Forever Diamondz (Europe) (En,Fr,Es,It)" description "Bratz - Forever Diamondz (Europe) (En,Fr,Es,It)" - rom ( name "Bratz - Forever Diamondz (Europe) (En,Fr,Es,It).gba" size 8388608 crc DB179296 md5 016FE71584C04D4B8725AAFD3CBDAC9C sha1 69B6326D19143F3CA2C2C64AC22A8B73935AF555 flags verified ) + rom ( name "Bratz - Forever Diamondz (Europe) (En,Fr,Es,It).gba" size 8388608 crc db179296 sha1 69B6326D19143F3CA2C2C64AC22A8B73935AF555 flags verified ) ) game ( name "Bratz - Rock Angelz (USA, Europe)" description "Bratz - Rock Angelz (USA, Europe)" - rom ( name "Bratz - Rock Angelz (USA, Europe).gba" size 8388608 crc AA245D0C md5 874AA5C4C6217FEBEC6405A22D7BC9EF sha1 EB2B8DDBB5CA2449F80DDF2C7BEC2BD0B4A75E47 flags verified ) + rom ( name "Bratz - Rock Angelz (USA, Europe).gba" size 8388608 crc aa245d0c sha1 EB2B8DDBB5CA2449F80DDF2C7BEC2BD0B4A75E47 flags verified ) ) game ( name "Bratz - Rock Angelz (Germany)" description "Bratz - Rock Angelz (Germany)" - rom ( name "Bratz - Rock Angelz (Germany).gba" size 8388608 crc 649588CB md5 1176113FE66CF20D5D00DEF9FBDA8C20 sha1 8C217ACB3D7DCDBE677B216A9323BC9E516D65B4 ) + rom ( name "Bratz - Rock Angelz (Germany).gba" size 8388608 crc 649588cb sha1 8C217ACB3D7DCDBE677B216A9323BC9E516D65B4 ) ) game ( name "Bratz - Rock Angelz (France)" description "Bratz - Rock Angelz (France)" - rom ( name "Bratz - Rock Angelz (France).gba" size 8388608 crc 8FC8D6D2 md5 D6482E271791CD7B324C36B55CA3B693 sha1 ABA27782159D9A4D4CBE8D6DE67594134C00BBAA ) + rom ( name "Bratz - Rock Angelz (France).gba" size 8388608 crc 8fc8d6d2 sha1 ABA27782159D9A4D4CBE8D6DE67594134C00BBAA ) ) game ( name "Bratz - Rock Angelz (Spain)" description "Bratz - Rock Angelz (Spain)" - rom ( name "Bratz - Rock Angelz (Spain).gba" size 8388608 crc CFFF9119 md5 6D8F418E5B5EF1929CA9518C34D0BDE6 sha1 D34D8359F9011D55F693E23EFB444A458D8690A2 ) + rom ( name "Bratz - Rock Angelz (Spain).gba" size 8388608 crc cfff9119 sha1 D34D8359F9011D55F693E23EFB444A458D8690A2 ) ) game ( name "Bratz - The Movie (USA)" description "Bratz - The Movie (USA)" - rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2EF801C0 md5 33DE786F427B47750AAED814C761C5B9 sha1 BFAB6A139275B6968531A43AB34D4710E9EFC7EF ) + rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2ef801c0 sha1 BFAB6A139275B6968531A43AB34D4710E9EFC7EF ) ) game ( name "Bratz - The Movie (Germany)" description "Bratz - The Movie (Germany)" - rom ( name "Bratz - The Movie (Germany).gba" size 4194304 crc 04F21321 md5 794C177C712C030BCE32A85DDA73CB36 sha1 8EE0580102162217C95724E9B7209DD85AEC30E4 ) + rom ( name "Bratz - The Movie (Germany).gba" size 4194304 crc 04f21321 sha1 8EE0580102162217C95724E9B7209DD85AEC30E4 ) ) game ( name "Bratz - The Movie (Europe) (Es,It)" description "Bratz - The Movie (Europe) (Es,It)" - rom ( name "Bratz - The Movie (Europe) (Es,It).gba" size 4194304 crc 4386E26C md5 BF585F54686E2B5F55D97D624A8A3E28 sha1 666F09568CBACE84C92EDE16A2B11D1A902C7617 ) + rom ( name "Bratz - The Movie (Europe) (Es,It).gba" size 4194304 crc 4386e26c sha1 666F09568CBACE84C92EDE16A2B11D1A902C7617 ) ) game ( name "Bratz - The Movie (Europe)" description "Bratz - The Movie (Europe)" - rom ( name "Bratz - The Movie (Europe).gba" size 4194304 crc CD485F79 md5 E192F69D5FE9098CC0EE4F85AEEDB4EB sha1 8BB3F1293D1FD60E5050CE522C26F869D76E982D flags verified ) -) - -game ( - name "Breath of Fire (Europe)" - description "Breath of Fire (Europe)" - rom ( name "Breath of Fire (Europe).gba" size 4194304 crc A1C3165D md5 1CB94E81DD0168C33E0EB8B070FDDB6E sha1 F47870D25665588D19B75E90D0BD32A759E64918 flags verified ) + rom ( name "Bratz - The Movie (Europe).gba" size 4194304 crc cd485f79 sha1 8BB3F1293D1FD60E5050CE522C26F869D76E982D flags verified ) ) game ( name "Breath of Fire (USA)" description "Breath of Fire (USA)" - rom ( name "Breath of Fire (USA).gba" size 4194304 crc F06422A8 md5 17A32CFA3D0A5C74F914281EF55C75CD sha1 B30533F68037B47D5439BAB0182169E4A643A38D ) + rom ( name "Breath of Fire (USA).gba" size 4194304 crc f06422a8 sha1 B30533F68037B47D5439BAB0182169E4A643A38D flags verified ) ) game ( name "Breath of Fire (Europe) (En,Fr,De)" description "Breath of Fire (Europe) (En,Fr,De)" - rom ( name "Breath of Fire (Europe) (En,Fr,De).gba" size 4194304 crc D3660549 md5 A413CF9036C03EAC937539A255AC6949 sha1 FDC7E7B6AB680229DCD159EB4DD7D1967B9E88EE flags verified ) + rom ( name "Breath of Fire (Europe) (En,Fr,De).gba" size 4194304 crc d3660549 sha1 FDC7E7B6AB680229DCD159EB4DD7D1967B9E88EE flags verified ) +) + +game ( + name "Breath of Fire (Europe)" + description "Breath of Fire (Europe)" + rom ( name "Breath of Fire (Europe).gba" size 4194304 crc a1c3165d sha1 F47870D25665588D19B75E90D0BD32A759E64918 flags verified ) ) game ( name "Breath of Fire - Ryuu no Senshi (Japan)" description "Breath of Fire - Ryuu no Senshi (Japan)" - rom ( name "Breath of Fire - Ryuu no Senshi (Japan).gba" size 4194304 crc 66E96B35 md5 15DE8E3ED041332E0529C0B884D42D42 sha1 B09DC97AB42F5E32DC6254D09B0B195295B24932 ) + rom ( name "Breath of Fire - Ryuu no Senshi (Japan).gba" size 4194304 crc 66e96b35 sha1 B09DC97AB42F5E32DC6254D09B0B195295B24932 ) ) game ( name "Breath of Fire II (USA)" description "Breath of Fire II (USA)" - rom ( name "Breath of Fire II (USA).gba" size 4194304 crc 6F098DA3 md5 2132B06357239D4E6A0716D963F46597 sha1 D35E452D467093C4A788D290A65ADF05A4270343 flags verified ) + rom ( name "Breath of Fire II (USA).gba" size 4194304 crc 6f098da3 sha1 D35E452D467093C4A788D290A65ADF05A4270343 flags verified ) ) game ( name "Breath of Fire II (Europe)" description "Breath of Fire II (Europe)" - rom ( name "Breath of Fire II (Europe).gba" size 4194304 crc FF5E8E39 md5 433CE4C6D525C74E3E60CDC197F6ABFB sha1 307798CA71BDA7F6B313FF1C18880F22C5A81711 flags verified ) + rom ( name "Breath of Fire II (Europe).gba" size 4194304 crc ff5e8e39 sha1 307798CA71BDA7F6B313FF1C18880F22C5A81711 flags verified ) ) game ( name "Breath of Fire II - Shimei no Ko (Japan)" description "Breath of Fire II - Shimei no Ko (Japan)" - rom ( name "Breath of Fire II - Shimei no Ko (Japan).gba" size 4194304 crc 8A824A70 md5 45FB38AF8D17EDD3BD14171D5FE3AB0E sha1 E862D66DA9286B4C938441BEE2FD1A8E980D694F ) + rom ( name "Breath of Fire II - Shimei no Ko (Japan).gba" size 4194304 crc 8a824a70 sha1 E862D66DA9286B4C938441BEE2FD1A8E980D694F ) ) game ( name "Britney's Dance Beat (USA)" description "Britney's Dance Beat (USA)" - rom ( name "Britney's Dance Beat (USA).gba" size 8388608 crc 443198D8 md5 BB1A8E9129D4D2DCB4BBB3E4879EE97B sha1 8F13503BF068DC13FA60AE8B4F5A83D07FFCA5F4 ) + rom ( name "Britney's Dance Beat (USA).gba" size 8388608 crc 443198d8 sha1 8F13503BF068DC13FA60AE8B4F5A83D07FFCA5F4 ) ) game ( name "Britney's Dance Beat (Europe) (En,Fr)" description "Britney's Dance Beat (Europe) (En,Fr)" - rom ( name "Britney's Dance Beat (Europe) (En,Fr).gba" size 8388608 crc 021CDA8E md5 B9434C3F72E6E0D1B79EB7AB65634840 sha1 3BC3394648DB1CB36CF6FF7E636DD04BBD8F5A43 ) + rom ( name "Britney's Dance Beat (Europe) (En,Fr).gba" size 8388608 crc 021cda8e sha1 3BC3394648DB1CB36CF6FF7E636DD04BBD8F5A43 ) ) game ( name "Britney's Dance Beat (Europe) (En,De)" description "Britney's Dance Beat (Europe) (En,De)" - rom ( name "Britney's Dance Beat (Europe) (En,De).gba" size 8388608 crc CFE69825 md5 9C6A3C4C14FF9D8CA6DF08F3F251C63F sha1 B7D2BBAC630CFD921F65DEA256FCC3DB27B0BF5D ) + rom ( name "Britney's Dance Beat (Europe) (En,De).gba" size 8388608 crc cfe69825 sha1 B7D2BBAC630CFD921F65DEA256FCC3DB27B0BF5D ) ) game ( name "Britney's Dance Beat (Europe)" description "Britney's Dance Beat (Europe)" - rom ( name "Britney's Dance Beat (Europe).gba" size 8388608 crc 886121A8 md5 DCAF52240DF58D7F9D6BE95E918C7BB3 sha1 F8E2185509A81A763F8A052401E64F227EE22627 ) + rom ( name "Britney's Dance Beat (Europe).gba" size 8388608 crc 886121a8 sha1 F8E2185509A81A763F8A052401E64F227EE22627 ) ) game ( name "Broken Circle (Europe) (En,It) (Proto)" description "Broken Circle (Europe) (En,It) (Proto)" - rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8409344 crc E78BC690 md5 420A1CF3E052EC30D3612D7D945C525E sha1 D015A5039FF5D08EEBA3DDB16470EAAB259631D0 ) + rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8388608 crc 1e8f8ae0 sha1 FEC9FDA1C776AC9BB87A609D0BE1EFFE7EA158B6 ) ) game ( name "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It)" description "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It)" - rom ( name "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3A23EFD7 md5 0041789771FAB4154EB638B4BCC68641 sha1 25C6CF94B1B54A1AC5058460FAAD00CF93D272F5 ) + rom ( name "Broken Sword - The Shadow of the Templars (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3a23efd7 sha1 25C6CF94B1B54A1AC5058460FAAD00CF93D272F5 ) ) game ( name "Broken Sword - The Shadow of the Templars (USA) (En,Fr,De,Es,It)" description "Broken Sword - The Shadow of the Templars (USA) (En,Fr,De,Es,It)" - rom ( name "Broken Sword - The Shadow of the Templars (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 3278CE51 md5 5BF98EB8CC6247B4EDF7B9B5B08DBAB9 sha1 314ECED054604866153883EE20E0966E1443E0D9 ) + rom ( name "Broken Sword - The Shadow of the Templars (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 3278ce51 sha1 314ECED054604866153883EE20E0966E1443E0D9 ) ) game ( name "Brother Bear (USA)" description "Brother Bear (USA)" - rom ( name "Brother Bear (USA).gba" size 8388608 crc 342DE1D6 md5 1BDADFFE311EF9FA231C799806AD5CA3 sha1 89E6903500F62E11483402B76C1454AF788646C0 ) + rom ( name "Brother Bear (USA).gba" size 8388608 crc 342de1d6 sha1 89E6903500F62E11483402B76C1454AF788646C0 ) ) game ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da)" description "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc FD814097 md5 B8B752C5659E94C0474FE6050DF498F2 sha1 7E217E5F644B0333C51F3827DF5FD64023AC7C0E ) + rom ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc fd814097 sha1 7E217E5F644B0333C51F3827DF5FD64023AC7C0E ) ) game ( name "Brother Bear (Europe)" description "Brother Bear (Europe)" - rom ( name "Brother Bear (Europe).gba" size 8388608 crc 6220A4B8 md5 80112BA773C8B8072502F46C1781561F sha1 0BD142C546D13C2ADF21A48B48FE09F7633AD6F3 flags verified ) -) - -game ( - name "Bruce Lee - Return of the Legend (USA)" - description "Bruce Lee - Return of the Legend (USA)" - rom ( name "Bruce Lee - Return of the Legend (USA).gba" size 8388608 crc B2A45A4C md5 73D90562373B2B0882354986AABDD61F sha1 EBF28BFBF6932E386C261B28555294F183A08435 ) + rom ( name "Brother Bear (Europe).gba" size 8388608 crc 6220a4b8 sha1 0BD142C546D13C2ADF21A48B48FE09F7633AD6F3 flags verified ) ) game ( name "Bruce Lee - Return of the Legend (Europe) (En,Fr,De,Es,It)" description "Bruce Lee - Return of the Legend (Europe) (En,Fr,De,Es,It)" - rom ( name "Bruce Lee - Return of the Legend (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B5FF39DC md5 BD34635CF119A77C121BBF005B3DDFBE sha1 FC1C50A12B76EFAEAE0BB66C37D0D6CAD4998D3C ) + rom ( name "Bruce Lee - Return of the Legend (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b5ff39dc sha1 FC1C50A12B76EFAEAE0BB66C37D0D6CAD4998D3C ) +) + +game ( + name "Bruce Lee - Return of the Legend (USA)" + description "Bruce Lee - Return of the Legend (USA)" + rom ( name "Bruce Lee - Return of the Legend (USA).gba" size 8388608 crc b2a45a4c sha1 EBF28BFBF6932E386C261B28555294F183A08435 ) ) game ( name "Bubble Bobble - Old & New (Japan)" description "Bubble Bobble - Old & New (Japan)" - rom ( name "Bubble Bobble - Old & New (Japan).gba" size 4194304 crc BE9FD5E7 md5 7AB9B3D99BE1723ECEDDE1ED8D0F359B sha1 973594B533FA97319EA791C09905837B20FD9FCA ) + rom ( name "Bubble Bobble - Old & New (Japan).gba" size 4194304 crc be9fd5e7 sha1 973594B533FA97319EA791C09905837B20FD9FCA ) ) game ( name "Bubble Bobble - Old & New (Europe) (En,Fr,De,Es,It)" description "Bubble Bobble - Old & New (Europe) (En,Fr,De,Es,It)" - rom ( name "Bubble Bobble - Old & New (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc DFA1A201 md5 2D9D80520480DBC4872B774A80F02F07 sha1 179523E4C6DA0DC050626AC69862F2A6E880F70D flags verified ) + rom ( name "Bubble Bobble - Old & New (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc dfa1a201 sha1 179523E4C6DA0DC050626AC69862F2A6E880F70D flags verified ) ) game ( name "Bubble Bobble - Old & New (USA)" description "Bubble Bobble - Old & New (USA)" - rom ( name "Bubble Bobble - Old & New (USA).gba" size 4194304 crc FEEC503C md5 EBE1FC2780D93C4CF42F1FE5815A84BF sha1 EFD718795FD29389942AE93611AC12546A6A3E86 ) + rom ( name "Bubble Bobble - Old & New (USA).gba" size 4194304 crc feec503c sha1 EFD718795FD29389942AE93611AC12546A6A3E86 flags verified ) ) game ( name "Buffy - Im Bann der Daemonen - Koenig Darkhuls Zorn (Germany)" description "Buffy - Im Bann der Daemonen - Koenig Darkhuls Zorn (Germany)" - rom ( name "Buffy - Im Bann der Daemonen - Koenig Darkhuls Zorn (Germany).gba" size 4194304 crc 4D2A1D88 md5 C9091F3E04BB2B0F0989EFB546C3FFC8 sha1 CDFF352154983D0F5CE3C5C58F71B1049234D96D ) + rom ( name "Buffy - Im Bann der Daemonen - Koenig Darkhuls Zorn (Germany).gba" size 4194304 crc 4d2a1d88 sha1 CDFF352154983D0F5CE3C5C58F71B1049234D96D ) ) game ( name "Buffy contre les Vampires - La Colere de Darkhul (France)" description "Buffy contre les Vampires - La Colere de Darkhul (France)" - rom ( name "Buffy contre les Vampires - La Colere de Darkhul (France).gba" size 4194304 crc 339C7586 md5 CA775010545C69BB28EC6635FA48CEFD sha1 832E11838D7D6DA49936A55FCF8686A2ABC0F0E8 ) + rom ( name "Buffy contre les Vampires - La Colere de Darkhul (France).gba" size 4194304 crc 339c7586 sha1 832E11838D7D6DA49936A55FCF8686A2ABC0F0E8 ) ) game ( name "Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe)" description "Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe)" - rom ( name "Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe).gba" size 4194304 crc F5C85BEB md5 E8FE8458EDBF341E9D7EBA0CBEC95D46 sha1 FB52E2D91850FA222187E5CD839BD6405AB90F25 ) + rom ( name "Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe).gba" size 4194304 crc f5c85beb sha1 FB52E2D91850FA222187E5CD839BD6405AB90F25 ) ) game ( name "Bura Bura Donkey (Japan)" description "Bura Bura Donkey (Japan)" - rom ( name "Bura Bura Donkey (Japan).gba" size 8388608 crc 89B09753 md5 CB6451EB458A51AC7D1757D2F419DD3C sha1 EC5671ABBB5DC39531F2E3630FC968EE050E12B2 flags verified ) + rom ( name "Bura Bura Donkey (Japan).gba" size 8388608 crc 89b09753 sha1 EC5671ABBB5DC39531F2E3630FC968EE050E12B2 flags verified ) ) game ( name "Butt-Ugly Martians - B.K.M. Battles (USA)" description "Butt-Ugly Martians - B.K.M. Battles (USA)" - rom ( name "Butt-Ugly Martians - B.K.M. Battles (USA).gba" size 4194304 crc 74BE9148 md5 37B681295390EF9F55EE3222C761C4C3 sha1 24962220F242B49231969F6D313E325148886106 ) + rom ( name "Butt-Ugly Martians - B.K.M. Battles (USA).gba" size 4194304 crc 74be9148 sha1 24962220F242B49231969F6D313E325148886106 ) ) game ( name "Butt-Ugly Martians - B.K.M. Battles (Europe) (En,Fr,De,Es,It)" description "Butt-Ugly Martians - B.K.M. Battles (Europe) (En,Fr,De,Es,It)" - rom ( name "Butt-Ugly Martians - B.K.M. Battles (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7CFF011A md5 6222D8990B98DC3702EA6B1CCAD50183 sha1 6407D8D188552BB539272B0AE4EAAEA0E21AA441 flags verified ) + rom ( name "Butt-Ugly Martians - B.K.M. Battles (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7cff011a sha1 6407D8D188552BB539272B0AE4EAAEA0E21AA441 flags verified ) ) game ( name "Cabbage Patch Kids - The Patch Puppy Rescue (USA)" description "Cabbage Patch Kids - The Patch Puppy Rescue (USA)" - rom ( name "Cabbage Patch Kids - The Patch Puppy Rescue (USA).gba" size 4194304 crc C812A494 md5 F05560AE14F622DE028308B372AB2FE3 sha1 0A18915E4914B48604A0D2E43762C5DD44FCE980 ) + rom ( name "Cabbage Patch Kids - The Patch Puppy Rescue (USA).gba" size 4194304 crc c812a494 sha1 0A18915E4914B48604A0D2E43762C5DD44FCE980 ) ) game ( name "Cabbage Patch Kids - The Patch Puppy Rescue (Europe)" description "Cabbage Patch Kids - The Patch Puppy Rescue (Europe)" - rom ( name "Cabbage Patch Kids - The Patch Puppy Rescue (Europe).gba" size 4194304 crc ED2EB57D md5 25998F81BA65037DCDE78250B7D2C28B sha1 DB05963F51EC781B59FC3C2ACECD4258A8F629A2 ) + rom ( name "Cabbage Patch Kids - The Patch Puppy Rescue (Europe).gba" size 4194304 crc ed2eb57d sha1 DB05963F51EC781B59FC3C2ACECD4258A8F629A2 ) ) game ( name "Cabela's Big Game Hunter (USA)" description "Cabela's Big Game Hunter (USA)" - rom ( name "Cabela's Big Game Hunter (USA).gba" size 8388608 crc 70A8A141 md5 B0A0C0FD729544C7FD786A6A4D4B419F sha1 F6590B9F069856C1A9E43D19B4B05E3175A97E02 ) + rom ( name "Cabela's Big Game Hunter (USA).gba" size 8388608 crc 70a8a141 sha1 F6590B9F069856C1A9E43D19B4B05E3175A97E02 ) ) game ( name "Cabela's Big Game Hunter - 2005 Adventures (USA, Europe)" description "Cabela's Big Game Hunter - 2005 Adventures (USA, Europe)" - rom ( name "Cabela's Big Game Hunter - 2005 Adventures (USA, Europe).gba" size 4194304 crc BD054567 md5 D569EA9204F4683592ED49E47F6F9568 sha1 AFF3C5BC948C2C868BE7DA8A327AEE25BEAA027C flags verified ) + rom ( name "Cabela's Big Game Hunter - 2005 Adventures (USA, Europe).gba" size 4194304 crc bd054567 sha1 AFF3C5BC948C2C868BE7DA8A327AEE25BEAA027C flags verified ) ) game ( name "Caesars Palace Advance - Millennium Gold Edition (USA, Europe)" description "Caesars Palace Advance - Millennium Gold Edition (USA, Europe)" - rom ( name "Caesars Palace Advance - Millennium Gold Edition (USA, Europe).gba" size 8388608 crc 5D54ECE5 md5 CE1B62B6673B0E4338FDA5BCDD1E2366 sha1 CD5DBB8B8361CA5D003EC496A99351020DABC329 ) + rom ( name "Caesars Palace Advance - Millennium Gold Edition (USA, Europe).gba" size 8388608 crc 5d54ece5 sha1 CD5DBB8B8361CA5D003EC496A99351020DABC329 ) ) game ( name "Caesars Palace Advance - Millennium Gold Edition (USA) (Beta)" description "Caesars Palace Advance - Millennium Gold Edition (USA) (Beta)" - rom ( name "Caesars Palace Advance - Millennium Gold Edition (USA) (Beta).gba" size 4194304 crc 13DC0731 md5 FB6512463E361B4A79BB4F62BFCA86FD sha1 1A89CECD9BF89DF42AE4EF35D17D437B17E53C80 ) + rom ( name "Caesars Palace Advance - Millennium Gold Edition (USA) (Beta).gba" size 4194304 crc 13dc0731 sha1 1A89CECD9BF89DF42AE4EF35D17D437B17E53C80 ) ) game ( name "Calciobit (Japan)" description "Calciobit (Japan)" - rom ( name "Calciobit (Japan).gba" size 8388608 crc 498443DA md5 5C1230403A28121A7235D3CDA810E96A sha1 DF835357EE70FC0B6C6EB606D9FF1DCC97EBA9D3 flags verified ) + rom ( name "Calciobit (Japan).gba" size 8388608 crc 498443da sha1 DF835357EE70FC0B6C6EB606D9FF1DCC97EBA9D3 flags verified ) ) game ( name "Camp Lazlo - Leaky Lake Games (USA)" description "Camp Lazlo - Leaky Lake Games (USA)" - rom ( name "Camp Lazlo - Leaky Lake Games (USA).gba" size 4194304 crc 40C2894E md5 6385B15433D8CD369CADEC45E5D5A783 sha1 184FE377D82264C2C3AE426D9E57437EC5F8901E ) + rom ( name "Camp Lazlo - Leaky Lake Games (USA).gba" size 4194304 crc 40c2894e sha1 184FE377D82264C2C3AE426D9E57437EC5F8901E ) ) game ( name "Camp Lazlo - Leaky Lake Games (Europe)" description "Camp Lazlo - Leaky Lake Games (Europe)" - rom ( name "Camp Lazlo - Leaky Lake Games (Europe).gba" size 8388608 crc 37DE9A3D md5 28A966D194D788BF9EF4B5751CEEE872 sha1 138EF77B18B87689D6D6E6E4887874DE3F72E52E ) + rom ( name "Camp Lazlo - Leaky Lake Games (Europe).gba" size 8388608 crc 37de9a3d sha1 138EF77B18B87689D6D6E6E4887874DE3F72E52E ) ) game ( name "Capcom Classics Mini Mix (USA)" description "Capcom Classics Mini Mix (USA)" - rom ( name "Capcom Classics Mini Mix (USA).gba" size 4194304 crc 0BB2D391 md5 05BF1A8337FB6B000DC2B875E1DA07C9 sha1 F5602CB9E8AA13C3631C47FF3213325404940798 flags verified ) + rom ( name "Capcom Classics Mini Mix (USA).gba" size 4194304 crc 0bb2d391 sha1 F5602CB9E8AA13C3631C47FF3213325404940798 flags verified ) ) game ( name "Captain Tsubasa - Eikou no Kiseki (Japan)" description "Captain Tsubasa - Eikou no Kiseki (Japan)" - rom ( name "Captain Tsubasa - Eikou no Kiseki (Japan).gba" size 8388608 crc 5341B274 md5 834C59C74EFDD616CEB429832C06DE31 sha1 58EC6A38285BDC77CE2A322B5F7BE65E1D0895A3 ) + rom ( name "Captain Tsubasa - Eikou no Kiseki (Japan).gba" size 8388608 crc 5341b274 sha1 58EC6A38285BDC77CE2A322B5F7BE65E1D0895A3 ) ) game ( name "Car Battler Joe (USA)" description "Car Battler Joe (USA)" - rom ( name "Car Battler Joe (USA).gba" size 8388608 crc EA0A1B94 md5 37A569F4B2EE0818F89117A5CC958E83 sha1 5C9982A230EBF6C93B1706A242D2149FC052A37C ) + rom ( name "Car Battler Joe (USA).gba" size 8388608 crc ea0a1b94 sha1 5C9982A230EBF6C93B1706A242D2149FC052A37C flags verified ) ) game ( name "Card e-Reader (Japan)" description "Card e-Reader (Japan)" - rom ( name "Card e-Reader (Japan).gba" size 4194304 crc A4EF4E95 md5 B44AACBFE0A64D73B466F8F7BCCA4577 sha1 5CF045A083BF7C86A197A7F19CAF7153F3E227F4 ) + rom ( name "Card e-Reader (Japan).gba" size 4194304 crc a4ef4e95 sha1 5CF045A083BF7C86A197A7F19CAF7153F3E227F4 ) ) game ( name "Card e-Reader+ (Japan)" description "Card e-Reader+ (Japan)" - rom ( name "Card e-Reader+ (Japan).gba" size 8388608 crc 4139E7C3 md5 32CBD7B3468B5F595876161A47F15895 sha1 2AF41785DD72C664E8A1C0F1E1CE0EDCD105DD5E ) + rom ( name "Card e-Reader+ (Japan).gba" size 8388608 crc 4139e7c3 sha1 2AF41785DD72C664E8A1C0F1E1CE0EDCD105DD5E ) ) game ( name "Card Party (Japan)" description "Card Party (Japan)" - rom ( name "Card Party (Japan).gba" size 8388608 crc 3D5A2C07 md5 54024EB18AD484126CE84D30843E0B59 sha1 38D57C56F3FC8D458D3E9B8A6F98174911167DAC ) + rom ( name "Card Party (Japan).gba" size 8388608 crc 3d5a2c07 sha1 38D57C56F3FC8D458D3E9B8A6F98174911167DAC ) ) game ( name "Cardcaptor Sakura - Sakura Card de Mini Game (Japan)" description "Cardcaptor Sakura - Sakura Card de Mini Game (Japan)" - rom ( name "Cardcaptor Sakura - Sakura Card de Mini Game (Japan).gba" size 4194304 crc DBC9CD2E md5 0AB2602D06DA0EE5D87AC319495A78F2 sha1 E91289D5EF58F984F0377D956AAD1D3BF48667BB ) + rom ( name "Cardcaptor Sakura - Sakura Card de Mini Game (Japan).gba" size 4194304 crc dbc9cd2e sha1 E91289D5EF58F984F0377D956AAD1D3BF48667BB ) ) game ( name "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan)" description "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan)" - rom ( name "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan).gba" size 16777216 crc D5BB189C md5 0A05B2762F053783D9E1D20ED10A6B4A sha1 2149B1F92FCD114FA78EE6303181CDC9903AE237 ) + rom ( name "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan).gba" size 16777216 crc d5bb189c sha1 2149B1F92FCD114FA78EE6303181CDC9903AE237 ) +) + +game ( + name "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan) (Rev 1)" + description "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan) (Rev 1)" + rom ( name "Cardcaptor Sakura - Sakura Card Hen - Sakura to Card to Otomodachi (Japan) (Rev 1).gba" size 16777216 crc 2c8488b2 sha1 06F8CEF944241AB73A062972CC7EB4A744DC1B6B flags verified ) ) game ( name "Care Bears - The Care Quests (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Care Bears - The Care Quests (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Care Bears - The Care Quests (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 4194304 crc 6111ED1E md5 ED307F6EA37B57EAE6E7D32B76FDDF7D sha1 606AD547286FDF14CC0FE60E5C34F9DB83A059DC ) + rom ( name "Care Bears - The Care Quests (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 4194304 crc 6111ed1e sha1 606AD547286FDF14CC0FE60E5C34F9DB83A059DC flags verified ) ) game ( name "Care Bears - The Care Quests (USA) (En,Fr,Es)" description "Care Bears - The Care Quests (USA) (En,Fr,Es)" - rom ( name "Care Bears - The Care Quests (USA) (En,Fr,Es).gba" size 4194304 crc F848C327 md5 10D14CBD9D43D2C4D59DA9A7EE64BA95 sha1 750EB05960ACE3BD38C6E362A0F6970AC3371964 ) + rom ( name "Care Bears - The Care Quests (USA) (En,Fr,Es).gba" size 4194304 crc f848c327 sha1 750EB05960ACE3BD38C6E362A0F6970AC3371964 ) ) game ( name "Carrera Power Slide (Europe) (En,Fr,De,Es,It,Nl)" description "Carrera Power Slide (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Carrera Power Slide (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 98D72420 md5 D62D4E34E5DB75A4B44DB96752CC2F69 sha1 965CE9750705FD576CD73EF3450C6537BB6F9C68 flags verified ) + rom ( name "Carrera Power Slide (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 98d72420 sha1 965CE9750705FD576CD73EF3450C6537BB6F9C68 flags verified ) ) game ( name "Cars (USA, Europe)" description "Cars (USA, Europe)" - rom ( name "Cars (USA, Europe).gba" size 8388608 crc 107639A8 md5 214047AC78C08EB59E256F54DF9522F2 sha1 7A3A5236FB3A335FBDC7B3EBB80A42766833D40D flags verified ) + rom ( name "Cars (USA, Europe).gba" size 8388608 crc 107639a8 sha1 7A3A5236FB3A335FBDC7B3EBB80A42766833D40D flags verified ) ) game ( name "Cars (Japan)" description "Cars (Japan)" - rom ( name "Cars (Japan).gba" size 8388608 crc 6D4DE0EE md5 2DD75F1B7E8095AB41918FCCDD64E1AE sha1 5F10460EF1267FFC155475C30F377D37A1EE5E35 ) + rom ( name "Cars (Japan).gba" size 8388608 crc 6d4de0ee sha1 5F10460EF1267FFC155475C30F377D37A1EE5E35 flags verified ) ) game ( name "Cars (Germany)" description "Cars (Germany)" - rom ( name "Cars (Germany).gba" size 8388608 crc EBD92F43 md5 7031E05FEA8257A2658683436B0E3DB1 sha1 8B9800817FAAD9EA6EFDB5ACE585D4D970B19353 ) + rom ( name "Cars (Germany).gba" size 8388608 crc ebd92f43 sha1 8B9800817FAAD9EA6EFDB5ACE585D4D970B19353 ) ) game ( name "Cars (Europe) (Es,Pt)" description "Cars (Europe) (Es,Pt)" - rom ( name "Cars (Europe) (Es,Pt).gba" size 8388608 crc 0B058DB2 md5 0E9DF95D854D56A7BED63B79BAB40BC1 sha1 B7DBDF12678E0F36973CA660178F8978450F4A3E ) + rom ( name "Cars (Europe) (Es,Pt).gba" size 8388608 crc 0b058db2 sha1 B7DBDF12678E0F36973CA660178F8978450F4A3E flags verified ) ) game ( name "Cars (Europe) (Sv,No,Da,Fi)" description "Cars (Europe) (Sv,No,Da,Fi)" - rom ( name "Cars (Europe) (Sv,No,Da,Fi).gba" size 8388608 crc 4F21FD49 md5 99581023CBB348A577D461E328646218 sha1 D0E9061BF7F3C78844915D98C8409D5C09A77EFD ) + rom ( name "Cars (Europe) (Sv,No,Da,Fi).gba" size 8388608 crc 4f21fd49 sha1 D0E9061BF7F3C78844915D98C8409D5C09A77EFD ) ) game ( name "Cars (Europe) (Fr,Nl)" description "Cars (Europe) (Fr,Nl)" - rom ( name "Cars (Europe) (Fr,Nl).gba" size 8388608 crc BD1BFC39 md5 94CDA1AA3381F457186908AC3FE82F24 sha1 63BD4B332D8F5D022901BD0D0F4EBD6A45D928EC ) + rom ( name "Cars (Europe) (Fr,Nl).gba" size 8388608 crc bd1bfc39 sha1 63BD4B332D8F5D022901BD0D0F4EBD6A45D928EC ) ) game ( name "Cars - Mater-National Championship (USA) (En,Fr)" description "Cars - Mater-National Championship (USA) (En,Fr)" - rom ( name "Cars - Mater-National Championship (USA) (En,Fr).gba" size 4194304 crc 189DA289 md5 A9ED5E9CE8B27136133AF666474FD42D sha1 DEDE8D3A8D18CA561325D0CBF22BBF25AD658308 ) + rom ( name "Cars - Mater-National Championship (USA) (En,Fr).gba" size 4194304 crc 189da289 sha1 DEDE8D3A8D18CA561325D0CBF22BBF25AD658308 ) ) game ( name "Cars - Mater-National Championship (Europe) (En,Fr,De,Es,It,Nl)" description "Cars - Mater-National Championship (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Cars - Mater-National Championship (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc D3DB9787 md5 AAA5ACB5B94FCCC8F3DE8FEF3F1A22CB sha1 16C666082DB0E12384D342E5DB4336AC66869D28 ) + rom ( name "Cars - Mater-National Championship (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc d3db9787 sha1 16C666082DB0E12384D342E5DB4336AC66869D28 flags verified ) ) game ( name "Cars - Motori Ruggenti (Italy)" description "Cars - Motori Ruggenti (Italy)" - rom ( name "Cars - Motori Ruggenti (Italy).gba" size 8388608 crc 23CB1A36 md5 7DDE4A9D879BAD9A898A3E32903D406C sha1 98F3733112E85EFF63FCEF6AEFE73D1F19694151 ) + rom ( name "Cars - Motori Ruggenti (Italy).gba" size 8388608 crc 23cb1a36 sha1 98F3733112E85EFF63FCEF6AEFE73D1F19694151 ) ) game ( name "Cartoon Network Block Party (USA)" description "Cartoon Network Block Party (USA)" - rom ( name "Cartoon Network Block Party (USA).gba" size 4194304 crc EDC0CCEE md5 FC244BE5E2A8B811EA2B2E0101D64A6E sha1 5E1AE3428C528755DC9C58E28DF349BF58B17A45 flags verified ) + rom ( name "Cartoon Network Block Party (USA).gba" size 4194304 crc edc0ccee sha1 5E1AE3428C528755DC9C58E28DF349BF58B17A45 flags verified ) ) game ( name "Cartoon Network Speedway (USA)" description "Cartoon Network Speedway (USA)" - rom ( name "Cartoon Network Speedway (USA).gba" size 4194304 crc 066A2705 md5 B3F65540EEA88983C63E454B34D3028E sha1 26AFA157C527DCAA5A4FA0ECCC772426156320D8 ) + rom ( name "Cartoon Network Speedway (USA).gba" size 4194304 crc 066a2705 sha1 26AFA157C527DCAA5A4FA0ECCC772426156320D8 ) ) game ( name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc DDAF8BAC md5 3BC985416F6229EB8C51457C51A64F6D sha1 2321B90C04690E8E4973A4495D25C9197AB5BFCC flags verified ) + rom ( name "Casper (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc ddaf8bac sha1 2321B90C04690E8E4973A4495D25C9197AB5BFCC flags verified ) ) game ( name "Casper (USA) (En,Fr,Es)" description "Casper (USA) (En,Fr,Es)" - rom ( name "Casper (USA) (En,Fr,Es).gba" size 4194304 crc 9F905E60 md5 A6C803E0887F46DB78BDF095628ED7DE sha1 75392D01815D807F8FBD6846469D5D535A6AEEDA ) + rom ( name "Casper (USA) (En,Fr,Es).gba" size 4194304 crc 9f905e60 sha1 75392D01815D807F8FBD6846469D5D535A6AEEDA ) ) game ( name "Castlevania (Europe)" description "Castlevania (Europe)" - rom ( name "Castlevania (Europe).gba" size 8388608 crc 611535DC md5 B7B0E7A5F8E8BD22AC9F5766D1ACEF56 sha1 A127E0C62CE61CD72661A1AF6F0BDA18BCAD26B3 flags verified ) + rom ( name "Castlevania (Europe).gba" size 8388608 crc 611535dc sha1 A127E0C62CE61CD72661A1AF6F0BDA18BCAD26B3 flags verified ) +) + +game ( + name "Castlevania (Europe) (Wii U Virtual Console)" + description "Castlevania (Europe) (Wii U Virtual Console)" + rom ( name "Castlevania (Europe) (Wii U Virtual Console).gba" size 8388608 crc dba05255 sha1 B5FA3402A8FB86786F97D08F88B3CBC790BB5D6E flags verified ) ) game ( name "Castlevania - Akatsuki no Minuet (Japan)" description "Castlevania - Akatsuki no Minuet (Japan)" - rom ( name "Castlevania - Akatsuki no Minuet (Japan).gba" size 8388608 crc 284E3092 md5 146AE198A3D42A66733B9E0EF3EC11EB sha1 0E086345F3BEF45611C252ADF1F4D1FBE642F2C1 flags verified ) + rom ( name "Castlevania - Akatsuki no Minuet (Japan).gba" size 8388608 crc 284e3092 sha1 0E086345F3BEF45611C252ADF1F4D1FBE642F2C1 flags verified ) ) game ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" - rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De).gba" size 8388608 crc D0C91F74 md5 4A5D8E686D55829D54A03FDA8D6887D7 sha1 2E8302C2A5A61614749F609D7EDC8C3E6AF20585 flags verified ) + rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De).gba" size 8388608 crc d0c91f74 sha1 2E8302C2A5A61614749F609D7EDC8C3E6AF20585 flags verified ) ) game ( name "Castlevania - Aria of Sorrow (USA)" description "Castlevania - Aria of Sorrow (USA)" - rom ( name "Castlevania - Aria of Sorrow (USA).gba" size 8388608 crc 35536183 md5 E7470DF4D241F73060D14437011B90CE sha1 ABD71FE01EBB201BCC133074DB1DD8C5253776C7 flags verified ) + rom ( name "Castlevania - Aria of Sorrow (USA).gba" size 8388608 crc 35536183 sha1 ABD71FE01EBB201BCC133074DB1DD8C5253776C7 flags verified ) +) + +game ( + name "Castlevania - Aria of Sorrow (USA) (Wii U Virtual Console)" + description "Castlevania - Aria of Sorrow (USA) (Wii U Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (USA) (Wii U Virtual Console).gba" size 8388608 crc 28baa30e sha1 B69A77970878B453E2B308FE124641F66925AE6A flags verified ) +) + +game ( + name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Wii U Virtual Console)" + description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Wii U Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Wii U Virtual Console).gba" size 8388608 crc d97dbfec sha1 458C42A6B8FD6CF18579B0F7EEF9DCD12B43C12B flags verified ) ) game ( name "Castlevania - Byakuya no Concerto (Japan)" description "Castlevania - Byakuya no Concerto (Japan)" - rom ( name "Castlevania - Byakuya no Concerto (Japan).gba" size 8388608 crc 379B3248 md5 CADE47DEF03AD1CC02A1BD97B5EA4E9F sha1 3AEB81EE60FA3E56A56EE069B0CE0D8BC34D9C4C flags verified ) + rom ( name "Castlevania - Byakuya no Concerto (Japan).gba" size 8388608 crc 379b3248 sha1 3AEB81EE60FA3E56A56EE069B0CE0D8BC34D9C4C flags verified ) ) game ( name "Castlevania - Circle of the Moon (USA)" description "Castlevania - Circle of the Moon (USA)" - rom ( name "Castlevania - Circle of the Moon (USA).gba" size 8388608 crc 1CC059A4 md5 50A1089600603A94E15ECF287F8D5A1F sha1 D661B01EB94186435723AC03344792C11C20C522 flags verified ) + rom ( name "Castlevania - Circle of the Moon (USA).gba" size 8388608 crc 1cc059a4 sha1 D661B01EB94186435723AC03344792C11C20C522 flags verified ) +) + +game ( + name "Castlevania - Circle of the Moon (USA) (Wii U Virtual Console)" + description "Castlevania - Circle of the Moon (USA) (Wii U Virtual Console)" + rom ( name "Castlevania - Circle of the Moon (USA) (Wii U Virtual Console).gba" size 8388608 crc d5412e91 sha1 E055B4AB00E16EC39C9036EF85463C770D809C6C flags verified ) ) game ( name "Castlevania - Harmony of Dissonance (Europe)" description "Castlevania - Harmony of Dissonance (Europe)" - rom ( name "Castlevania - Harmony of Dissonance (Europe).gba" size 8388608 crc 521B3091 md5 E619F9DCD7EF3D4C6851834018B139BD sha1 58034ADF2CF788ED308286090987CA73F807A54F flags verified ) + rom ( name "Castlevania - Harmony of Dissonance (Europe).gba" size 8388608 crc 521b3091 sha1 58034ADF2CF788ED308286090987CA73F807A54F flags verified ) ) game ( name "Castlevania - Harmony of Dissonance (USA)" description "Castlevania - Harmony of Dissonance (USA)" - rom ( name "Castlevania - Harmony of Dissonance (USA).gba" size 8388608 crc 88C1B562 md5 EA589465486D15E91BA94165C8024B55 sha1 B90DA0D9BE0B3A0893CD9E2C399056BCF9579E21 flags verified ) + rom ( name "Castlevania - Harmony of Dissonance (USA).gba" size 8388608 crc 88c1b562 sha1 B90DA0D9BE0B3A0893CD9E2C399056BCF9579E21 flags verified ) ) game ( name "Castlevania Double Pack (USA)" description "Castlevania Double Pack (USA)" - rom ( name "Castlevania Double Pack (USA).gba" size 16777216 crc DBCECC7D md5 90D5887EAEFD16478525478410155DEC sha1 1BA25E80CFBC3D667A0F5D4CBEB295580F586EDB flags verified ) + rom ( name "Castlevania Double Pack (USA).gba" size 16777216 crc dbcecc7d sha1 1BA25E80CFBC3D667A0F5D4CBEB295580F586EDB flags verified ) ) game ( name "Castlevania Double Pack (Europe) (En,Fr,De)" description "Castlevania Double Pack (Europe) (En,Fr,De)" - rom ( name "Castlevania Double Pack (Europe) (En,Fr,De).gba" size 16777216 crc EE495897 md5 C9F99CCDF29FE8F9B5DC52C3A84E95A3 sha1 E7AEA4480F02822904EEF1D7B51C18F169881075 flags verified ) + rom ( name "Castlevania Double Pack (Europe) (En,Fr,De).gba" size 16777216 crc ee495897 sha1 E7AEA4480F02822904EEF1D7B51C18F169881075 flags verified ) ) game ( name "Castleween (Europe) (En,Fr,De,Es,It)" description "Castleween (Europe) (En,Fr,De,Es,It)" - rom ( name "Castleween (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 11A9B76E md5 F146BAF10CF767D2313C4DA94A5845EB sha1 BBDA9C6708D8DD5A7EA6FBF6B7D128287DE2BD82 ) + rom ( name "Castleween (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 11a9b76e sha1 BBDA9C6708D8DD5A7EA6FBF6B7D128287DE2BD82 ) ) game ( - name "Cat in the Hat by Dr. Seuss, The (USA)" - description "Cat in the Hat by Dr. Seuss, The (USA)" - rom ( name "Cat in the Hat by Dr. Seuss, The (USA).gba" size 4194304 crc 13C2249E md5 ADF1AC69CAF510176EE1028ECF6F7ADF sha1 9340482DB02BF5263429A15798D06C509017AA93 ) + name "Cat in the Hat, The (Europe) (En,Fr,De,Es,It)" + description "Cat in the Hat, The (Europe) (En,Fr,De,Es,It)" + rom ( name "Cat in the Hat, The (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a5dbe5ae sha1 A60339E9B4FDBCAC73ED3B677AE17747BDB462AD ) +) + +game ( + name "Cat in the Hat, The (USA)" + description "Cat in the Hat, The (USA)" + rom ( name "Cat in the Hat, The (USA).gba" size 4194304 crc 13c2249e sha1 9340482DB02BF5263429A15798D06C509017AA93 ) ) game ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1ADB373D md5 041CD0228E12F003F9736FDAD77CDBF0 sha1 DC49889CAF678E9DFC2465AB55B7019E2D5D0860 flags verified ) + rom ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1adb373d sha1 DC49889CAF678E9DFC2465AB55B7019E2D5D0860 flags verified ) ) game ( name "Catz (USA, Europe)" description "Catz (USA, Europe)" - rom ( name "Catz (USA, Europe).gba" size 4194304 crc CE418ED1 md5 1851C34D41025D541B6AD76B9146CC6B sha1 8783F76311A8E23173EB4DADABC5176246B1B7B1 flags verified ) + rom ( name "Catz (USA, Europe).gba" size 4194304 crc ce418ed1 sha1 8783F76311A8E23173EB4DADABC5176246B1B7B1 flags verified ) ) game ( name "Catz (Europe) (En,Fr,De,It)" description "Catz (Europe) (En,Fr,De,It)" - rom ( name "Catz (Europe) (En,Fr,De,It).gba" size 8388608 crc C3AA382D md5 BD3938F9273373F99967FF831F9C86D6 sha1 0DAB5140EBC541E03DD00A8CE87CCE4F0326B0E6 ) + rom ( name "Catz (Europe) (En,Fr,De,It).gba" size 8388608 crc c3aa382d sha1 0DAB5140EBC541E03DD00A8CE87CCE4F0326B0E6 ) ) game ( name "Chaoji Maliou 2 (China)" description "Chaoji Maliou 2 (China)" - rom ( name "Chaoji Maliou 2 (China).gba" size 4194304 crc 14A87B75 md5 A2589A40C3F92A539969124CECC9B828 sha1 4FC77A2397086408554C50F9BF06327ABE04066E ) + rom ( name "Chaoji Maliou 2 (China).gba" size 4194304 crc 14a87b75 sha1 4FC77A2397086408554C50F9BF06327ABE04066E ) ) game ( name "Chaoji Maliou Shijie (China)" description "Chaoji Maliou Shijie (China)" - rom ( name "Chaoji Maliou Shijie (China).gba" size 4194304 crc D97D4156 md5 96DBD1BEF3587B60B612F0D30FC94415 sha1 1DA3124A73B2F22ED29F53B057E759191DC1F3F3 ) + rom ( name "Chaoji Maliou Shijie (China).gba" size 4194304 crc d97d4156 sha1 1DA3124A73B2F22ED29F53B057E759191DC1F3F3 ) ) game ( name "Charlie and the Chocolate Factory (USA) (En,Fr,Es,Nl)" description "Charlie and the Chocolate Factory (USA) (En,Fr,Es,Nl)" - rom ( name "Charlie and the Chocolate Factory (USA) (En,Fr,Es,Nl).gba" size 8388608 crc 4E90884D md5 5EA39A20A2AFB038555F013142A2A97A sha1 C85C9015D56530D0FFCEFE6E3A21AA9A011DA8A0 ) + rom ( name "Charlie and the Chocolate Factory (USA) (En,Fr,Es,Nl).gba" size 8388608 crc 4e90884d sha1 C85C9015D56530D0FFCEFE6E3A21AA9A011DA8A0 ) ) game ( name "Charlie and the Chocolate Factory (Europe) (En,Fr,Es,Nl)" description "Charlie and the Chocolate Factory (Europe) (En,Fr,Es,Nl)" - rom ( name "Charlie and the Chocolate Factory (Europe) (En,Fr,Es,Nl).gba" size 8388608 crc 2B3FCC74 md5 1944E6AC9631EEEC604E5FADF749885E sha1 CA0E2A6EE70154F0340FB665C0A50496D774527B ) + rom ( name "Charlie and the Chocolate Factory (Europe) (En,Fr,Es,Nl).gba" size 8388608 crc 2b3fcc74 sha1 CA0E2A6EE70154F0340FB665C0A50496D774527B ) ) game ( name "Charlotte's Web (USA) (En,Fr,De,Es,It)" description "Charlotte's Web (USA) (En,Fr,De,Es,It)" - rom ( name "Charlotte's Web (USA) (En,Fr,De,Es,It).gba" size 16777216 crc BA511FB2 md5 F090251D431126090195E54B6D963E2D sha1 44259E249EB3D8E9AD6FB8F62557F7A2748919E2 flags verified ) + rom ( name "Charlotte's Web (USA) (En,Fr,De,Es,It).gba" size 16777216 crc ba511fb2 sha1 44259E249EB3D8E9AD6FB8F62557F7A2748919E2 flags verified ) ) game ( name "Charlotte's Web (Europe) (En,Fr,De,Es,It)" description "Charlotte's Web (Europe) (En,Fr,De,Es,It)" - rom ( name "Charlotte's Web (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 8658BB4F md5 6DD36759F4B1229D2D66F1C28511417D sha1 FE9E49DB286045EF5462CF400DA26D28C023BF53 ) + rom ( name "Charlotte's Web (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 8658bb4f sha1 FE9E49DB286045EF5462CF400DA26D28C023BF53 ) ) game ( name "Cheetah Girls, The (USA)" description "Cheetah Girls, The (USA)" - rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc E2EFC2AA md5 DEFAB6EC6F979511247AB211D1404BC0 sha1 F46296D4AB97D539DBCFA551E05ED6D58715C5B6 flags verified ) + rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc e2efc2aa sha1 F46296D4AB97D539DBCFA551E05ED6D58715C5B6 flags verified ) ) game ( name "Chessmaster (Europe)" description "Chessmaster (Europe)" - rom ( name "Chessmaster (Europe).gba" size 4194304 crc 27E7FD09 md5 358C87FE02D8CE7207FB101839BBB820 sha1 78F9BD1C4FA2292C9EDDD83A425517F89D4525C2 ) + rom ( name "Chessmaster (Europe).gba" size 4194304 crc 27e7fd09 sha1 78F9BD1C4FA2292C9EDDD83A425517F89D4525C2 ) ) game ( name "Chessmaster (France)" description "Chessmaster (France)" - rom ( name "Chessmaster (France).gba" size 4194304 crc 55EF8392 md5 DB39085A6F31B5F506420A83973AD0FA sha1 EB5630D7B56EBDF4609665D50BF188E3F9EAC668 ) + rom ( name "Chessmaster (France).gba" size 4194304 crc 55ef8392 sha1 EB5630D7B56EBDF4609665D50BF188E3F9EAC668 ) ) game ( name "Chessmaster (USA)" description "Chessmaster (USA)" - rom ( name "Chessmaster (USA).gba" size 4194304 crc 25B0E933 md5 DA7D71352FD92C7E44DE1D7341042F27 sha1 5E3AC500D119A2BBE67D480EDC1C1DD09061E385 ) + rom ( name "Chessmaster (USA).gba" size 4194304 crc 25b0e933 sha1 5E3AC500D119A2BBE67D480EDC1C1DD09061E385 ) ) game ( name "Chessmaster (Germany)" description "Chessmaster (Germany)" - rom ( name "Chessmaster (Germany).gba" size 4194304 crc 06ABACC5 md5 D52806F7BF178947921AA0413F3CC633 sha1 76A69DA6183239F4AB0C45EF43C3EF7E2BD96D03 flags verified ) + rom ( name "Chessmaster (Germany).gba" size 4194304 crc 06abacc5 sha1 76A69DA6183239F4AB0C45EF43C3EF7E2BD96D03 flags verified ) ) game ( name "Chi Vuol Essere Milionario (Italy)" description "Chi Vuol Essere Milionario (Italy)" - rom ( name "Chi Vuol Essere Milionario (Italy).gba" size 4194304 crc B6F8527E md5 AD56E4DF06D70F83548F2EC92DCC15ED sha1 AEC04B9FA3EDFC966889856556C4FD4E5FCF8C51 ) + rom ( name "Chi Vuol Essere Milionario (Italy).gba" size 4194304 crc b6f8527e sha1 AEC04B9FA3EDFC966889856556C4FD4E5FCF8C51 ) ) game ( name "Chicken Little (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Chicken Little (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Chicken Little (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1E86F5B0 md5 A64CD7FA9C84DA61A4A358C321F248DF sha1 619F7D5B1AE9D732AD4186CA3B4DD2D6299022A0 flags verified ) + rom ( name "Chicken Little (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1e86f5b0 sha1 619F7D5B1AE9D732AD4186CA3B4DD2D6299022A0 flags verified ) ) game ( name "Chicken Little (Japan)" description "Chicken Little (Japan)" - rom ( name "Chicken Little (Japan).gba" size 8388608 crc DCBD4991 md5 A06268EE41DFE596990C1916A6EA0ECA sha1 CDA782A307475845952FEF322983F165D0C678A1 ) + rom ( name "Chicken Little (Japan).gba" size 8388608 crc dcbd4991 sha1 CDA782A307475845952FEF322983F165D0C678A1 ) ) game ( name "Chicken Shoot (Europe) (En,Fr,De,Es,It)" description "Chicken Shoot (Europe) (En,Fr,De,Es,It)" - rom ( name "Chicken Shoot (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 5749FDC9 md5 CA8BC391DEF42C66B2E6C7A179B945E9 sha1 D80AB8B60D82812DFBC7D7F1F7CBEB302BC85EC1 ) + rom ( name "Chicken Shoot (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 5749fdc9 sha1 D80AB8B60D82812DFBC7D7F1F7CBEB302BC85EC1 ) ) game ( name "Chicken Shoot (USA)" description "Chicken Shoot (USA)" - rom ( name "Chicken Shoot (USA).gba" size 4194304 crc 4B22E081 md5 36A92215BC1FD68F9DB49C1BE06FE088 sha1 55235F7F2C427E0684E909F3832567F1F576DA02 ) + rom ( name "Chicken Shoot (USA).gba" size 4194304 crc 4b22e081 sha1 55235F7F2C427E0684E909F3832567F1F576DA02 ) ) game ( name "Chicken Shoot 2 (USA)" description "Chicken Shoot 2 (USA)" - rom ( name "Chicken Shoot 2 (USA).gba" size 4194304 crc 1DFE38C2 md5 4ACB75F06293B30690E98740CF3E3F81 sha1 16B793184790411C1461DEC9FAF812BD05B1249C ) + rom ( name "Chicken Shoot 2 (USA).gba" size 4194304 crc 1dfe38c2 sha1 16B793184790411C1461DEC9FAF812BD05B1249C ) ) game ( name "Chicken Shoot 2 (Europe) (En,Fr,De,Es,It)" description "Chicken Shoot 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Chicken Shoot 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 02D12544 md5 21E76AEA003B916A2BEEDDD5B71F8DF5 sha1 226611EED844563FA3816ACC70C3A3FCAAFBFCD8 ) + rom ( name "Chicken Shoot 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 02d12544 sha1 226611EED844563FA3816ACC70C3A3FCAAFBFCD8 ) ) game ( name "Chinmoku no Iseki - Estpolis Gaiden (Japan)" description "Chinmoku no Iseki - Estpolis Gaiden (Japan)" - rom ( name "Chinmoku no Iseki - Estpolis Gaiden (Japan).gba" size 8388608 crc 2C00B4E6 md5 DE794CA5B1D1892FBC8BFAE8C6F2441B sha1 AAF5D856FD85154B62204BEA00677E392BA12396 ) + rom ( name "Chinmoku no Iseki - Estpolis Gaiden (Japan).gba" size 8388608 crc 2c00b4e6 sha1 AAF5D856FD85154B62204BEA00677E392BA12396 ) ) game ( name "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" description "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" - rom ( name "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan).gba" size 8388608 crc DDC4B118 md5 FA6A6FD3E3898A58977F468DB9A1F6F9 sha1 0B32C3ABB700F36864BC468EF6188513B0F4B0A1 ) + rom ( name "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan).gba" size 8388608 crc ddc4b118 sha1 0B32C3ABB700F36864BC468EF6188513B0F4B0A1 ) ) game ( name "Chocobo Land - A Game of Dice (Japan)" description "Chocobo Land - A Game of Dice (Japan)" - rom ( name "Chocobo Land - A Game of Dice (Japan).gba" size 8388608 crc D4F8152E md5 6341167E3C3212C632E7956CF0E69119 sha1 09CB1502E49A022AE4EB37CC9DD278FBE12437F3 ) + rom ( name "Chocobo Land - A Game of Dice (Japan).gba" size 8388608 crc d4f8152e sha1 09CB1502E49A022AE4EB37CC9DD278FBE12437F3 flags verified ) ) game ( name "Choro Q Advance (Japan)" description "Choro Q Advance (Japan)" - rom ( name "Choro Q Advance (Japan).gba" size 4194304 crc 93FE0E34 md5 625B7485CA6EF9D497B8FA392F627CD0 sha1 F7997151C77F5E78C72195A32D96B2354FE5267A ) + rom ( name "Choro Q Advance (Japan).gba" size 4194304 crc 93fe0e34 sha1 F7997151C77F5E78C72195A32D96B2354FE5267A ) ) game ( name "Choro Q Advance 2 (Japan)" description "Choro Q Advance 2 (Japan)" - rom ( name "Choro Q Advance 2 (Japan).gba" size 4194304 crc F5ED5F14 md5 35132FB11EA80DBA872A8EDEB9BA42D6 sha1 CA76D5C2AF1CAF0B2562F922C99A0109586E9227 ) + rom ( name "Choro Q Advance 2 (Japan).gba" size 4194304 crc f5ed5f14 sha1 CA76D5C2AF1CAF0B2562F922C99A0109586E9227 ) ) game ( - name "Chou Makai Mura R (Japan) (En)" - description "Chou Makai Mura R (Japan) (En)" - rom ( name "Chou Makai Mura R (Japan) (En).gba" size 4194304 crc A4F8B4B4 md5 ABF8A36E5CB2EF2C989AC44B5EBE68EA sha1 CCFADCDC39E09F8A0E1D5D9AD35542F498E89D2A ) + name "Chou Makaimura R (Japan)" + description "Chou Makaimura R (Japan)" + rom ( name "Chou Makaimura R (Japan).gba" size 4194304 crc a4f8b4b4 sha1 CCFADCDC39E09F8A0E1D5D9AD35542F498E89D2A ) ) game ( name "Chronicles of Narnia, The - The Lion, the Witch and the Wardrobe (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Chronicles of Narnia, The - The Lion, the Witch and the Wardrobe (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Chronicles of Narnia, The - The Lion, the Witch and the Wardrobe (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 7E198522 md5 291B90DF9403047A5064A1A2E71ED430 sha1 FEA89A96320771BA69354F5452610327AAD49EC0 ) + rom ( name "Chronicles of Narnia, The - The Lion, the Witch and the Wardrobe (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 16777216 crc 7e198522 sha1 FEA89A96320771BA69354F5452610327AAD49EC0 flags verified ) ) game ( name "ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es)" description "ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es)" - rom ( name "ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es).gba" size 4194304 crc 2C8C1B5A md5 2F661853601455283F51E54FB85DEA73 sha1 EA7099F5E4CBEEE929F43DB91B0331855202BB03 ) + rom ( name "ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es).gba" size 4194304 crc 2c8c1b5a sha1 EA7099F5E4CBEEE929F43DB91B0331855202BB03 flags verified ) ) game ( name "ChuChu Rocket! (USA) (En,Ja,Fr,De,Es)" description "ChuChu Rocket! (USA) (En,Ja,Fr,De,Es)" - rom ( name "ChuChu Rocket! (USA) (En,Ja,Fr,De,Es).gba" size 4194304 crc 057FB1B6 md5 76BD3AC13808B1D6ABEA377815B10ADB sha1 F204105308B7758DF84F1A31919204459EA6E54F ) + rom ( name "ChuChu Rocket! (USA) (En,Ja,Fr,De,Es).gba" size 4194304 crc 057fb1b6 sha1 F204105308B7758DF84F1A31919204459EA6E54F ) ) game ( name "ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es)" description "ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es)" - rom ( name "ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es).gba" size 4194304 crc 8AB607C0 md5 6957BAC168FF27F70DF74629751B3F5C sha1 34F3066BC8DBD3F046E43DB01476F87E64DCC38B flags verified ) + rom ( name "ChuChu Rocket! (Europe) (En,Ja,Fr,De,Es).gba" size 4194304 crc 8ab607c0 sha1 34F3066BC8DBD3F046E43DB01476F87E64DCC38B flags verified ) ) game ( name "CIMA - The Enemy (USA)" description "CIMA - The Enemy (USA)" - rom ( name "CIMA - The Enemy (USA).gba" size 8388608 crc EBD928ED md5 A894D51E4C9AE34B398B7DFCDDFFC074 sha1 6F30307DF4603EE54DB4AD50490380FEB93AAA44 ) + rom ( name "CIMA - The Enemy (USA).gba" size 8388608 crc ebd928ed sha1 6F30307DF4603EE54DB4AD50490380FEB93AAA44 flags verified ) ) game ( name "Cinderella - Magical Dreams (USA) (En,Fr,De,Es,It)" description "Cinderella - Magical Dreams (USA) (En,Fr,De,Es,It)" - rom ( name "Cinderella - Magical Dreams (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 22F19169 md5 E0DCEB3EE3BE70E72B425FDF455C7237 sha1 1682D023933BF758C78CE2C18B503EFD4F0803B9 ) + rom ( name "Cinderella - Magical Dreams (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 22f19169 sha1 1682D023933BF758C78CE2C18B503EFD4F0803B9 flags verified ) ) game ( name "Cinderella - Magical Dreams (Europe) (En,Fr,De,Es,It)" description "Cinderella - Magical Dreams (Europe) (En,Fr,De,Es,It)" - rom ( name "Cinderella - Magical Dreams (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc E8BF28E2 md5 C0D02D8DD1F27FB8ECAB1E41ABEC3C97 sha1 5BC03AFF430A2A66403A0D60DA2ACE41837B10A5 ) + rom ( name "Cinderella - Magical Dreams (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc e8bf28e2 sha1 5BC03AFF430A2A66403A0D60DA2ACE41837B10A5 ) ) game ( name "Cinnamon Game Series 2 - Yume no Daibouken (Japan)" description "Cinnamon Game Series 2 - Yume no Daibouken (Japan)" - rom ( name "Cinnamon Game Series 2 - Yume no Daibouken (Japan).gba" size 4194304 crc 5A2CADA1 md5 6C923128BBE3BAF6B242F58B8B1E4154 sha1 FFA0B28B9CF3E3A96713B41ABCA4C076123702EA ) + rom ( name "Cinnamon Game Series 2 - Yume no Daibouken (Japan).gba" size 4194304 crc 5a2cada1 sha1 FFA0B28B9CF3E3A96713B41ABCA4C076123702EA ) ) game ( name "Cinnamon Game Series 3 - Fuwafuwa Daisakusen (Japan)" description "Cinnamon Game Series 3 - Fuwafuwa Daisakusen (Japan)" - rom ( name "Cinnamon Game Series 3 - Fuwafuwa Daisakusen (Japan).gba" size 4194304 crc A1CBA145 md5 634C9F8F862EF0C5D3C7702DB2FB252B sha1 7AE7C0FFC7086B7D7C1170CF52EB63C9F2B5B5E3 ) + rom ( name "Cinnamon Game Series 3 - Fuwafuwa Daisakusen (Japan).gba" size 4194304 crc a1cba145 sha1 7AE7C0FFC7086B7D7C1170CF52EB63C9F2B5B5E3 ) ) game ( name "Cinnamoroll - Koko ni Iru yo (Japan)" description "Cinnamoroll - Koko ni Iru yo (Japan)" - rom ( name "Cinnamoroll - Koko ni Iru yo (Japan).gba" size 4194304 crc 8376D53B md5 978953379422EA0EEF46ED02253FE77A sha1 F13533EB284F7321D8709DF058FF28D61A031802 ) + rom ( name "Cinnamoroll - Koko ni Iru yo (Japan).gba" size 4194304 crc 8376d53b sha1 F13533EB284F7321D8709DF058FF28D61A031802 ) ) game ( name "Classic NES Series - Bomberman (USA, Europe)" description "Classic NES Series - Bomberman (USA, Europe)" - rom ( name "Classic NES Series - Bomberman (USA, Europe).gba" size 4194304 crc CD67F2BA md5 DCF31B1C2C8764ED3E88A6ACDF03CA0A sha1 30E45B70282FCEB9DBF6871CA46A284A26E2C832 flags verified ) + rom ( name "Classic NES Series - Bomberman (USA, Europe).gba" size 4194304 crc cd67f2ba sha1 30E45B70282FCEB9DBF6871CA46A284A26E2C832 flags verified ) ) game ( - name "Classic NES Series - Castlevania (USA, Europe)" - description "Classic NES Series - Castlevania (USA, Europe)" - rom ( name "Classic NES Series - Castlevania (USA, Europe).gba" size 4194304 crc CFC1F558 md5 D6496E67CDBE8A13E509C374014EDE7C sha1 197BA18ACEA5EA1A0859C9BB07AC19B6F8B8A5E1 ) + name "Classic NES Series - Castlevania (USA)" + description "Classic NES Series - Castlevania (USA)" + rom ( name "Classic NES Series - Castlevania (USA).gba" size 4194304 crc cfc1f558 sha1 197BA18ACEA5EA1A0859C9BB07AC19B6F8B8A5E1 ) ) game ( name "Classic NES Series - Donkey Kong (USA, Europe)" description "Classic NES Series - Donkey Kong (USA, Europe)" - rom ( name "Classic NES Series - Donkey Kong (USA, Europe).gba" size 4194304 crc BA82D416 md5 BCC7CC87ECB8BDDBB546B2EFAF0FD6ED sha1 CBAACF6D3929776E8E138644BAB2217BA0F6090A flags verified ) + rom ( name "Classic NES Series - Donkey Kong (USA, Europe).gba" size 4194304 crc ba82d416 sha1 CBAACF6D3929776E8E138644BAB2217BA0F6090A flags verified ) ) game ( name "Classic NES Series - Dr. Mario (USA, Europe)" description "Classic NES Series - Dr. Mario (USA, Europe)" - rom ( name "Classic NES Series - Dr. Mario (USA, Europe).gba" size 4194304 crc CA9F5D2F md5 3FD6101565EBCDF15E0AD7FA04413922 sha1 525CF64D80469A79C5ACD1C1B891A86930B5EE4D ) + rom ( name "Classic NES Series - Dr. Mario (USA, Europe).gba" size 4194304 crc ca9f5d2f sha1 525CF64D80469A79C5ACD1C1B891A86930B5EE4D flags verified ) ) game ( name "Classic NES Series - Excitebike (USA, Europe)" description "Classic NES Series - Excitebike (USA, Europe)" - rom ( name "Classic NES Series - Excitebike (USA, Europe).gba" size 4194304 crc 945C292F md5 F1D7FB5339DEF865B9DF069215E09A6A sha1 5B72DF21B913363B7F98E6942850C1593A3F0A4F ) + rom ( name "Classic NES Series - Excitebike (USA, Europe).gba" size 4194304 crc 945c292f sha1 5B72DF21B913363B7F98E6942850C1593A3F0A4F ) ) game ( name "Classic NES Series - Ice Climber (USA, Europe)" description "Classic NES Series - Ice Climber (USA, Europe)" - rom ( name "Classic NES Series - Ice Climber (USA, Europe).gba" size 4194304 crc 3126D612 md5 217D12D292B630A627C570CA2625E930 sha1 9A524CA65B71DFB3C7BA1282FF18093A1BB08F78 flags verified ) + rom ( name "Classic NES Series - Ice Climber (USA, Europe).gba" size 4194304 crc 3126d612 sha1 9A524CA65B71DFB3C7BA1282FF18093A1BB08F78 flags verified ) ) game ( name "Classic NES Series - Metroid (USA, Europe)" description "Classic NES Series - Metroid (USA, Europe)" - rom ( name "Classic NES Series - Metroid (USA, Europe).gba" size 4194304 crc B2A153C3 md5 5D9DA9584EE479F0F096963BA713710E sha1 0B44ECCD4503BA27A4CDA11D03A11E4B3FD5D6BC flags verified ) + rom ( name "Classic NES Series - Metroid (USA, Europe).gba" size 4194304 crc b2a153c3 sha1 0B44ECCD4503BA27A4CDA11D03A11E4B3FD5D6BC flags verified ) ) game ( name "Classic NES Series - Pac-Man (USA, Europe)" description "Classic NES Series - Pac-Man (USA, Europe)" - rom ( name "Classic NES Series - Pac-Man (USA, Europe).gba" size 4194304 crc 231F80D6 md5 AB5FFA096FF18D465A4CF04C1896A8A6 sha1 DB4EB8666F1649298C53D9773E6EFA00EB555542 flags verified ) + rom ( name "Classic NES Series - Pac-Man (USA, Europe).gba" size 4194304 crc 231f80d6 sha1 DB4EB8666F1649298C53D9773E6EFA00EB555542 flags verified ) ) game ( name "Classic NES Series - Super Mario Bros. (USA, Europe)" description "Classic NES Series - Super Mario Bros. (USA, Europe)" - rom ( name "Classic NES Series - Super Mario Bros. (USA, Europe).gba" size 4194304 crc 7EDDFFAD md5 23B2EFCD1FAB512D615F99A2D1A11D00 sha1 06BDEE2BB21C46BACF8D8CBE4F40DD52DF117195 flags verified ) + rom ( name "Classic NES Series - Super Mario Bros. (USA, Europe).gba" size 4194304 crc 7eddffad sha1 06BDEE2BB21C46BACF8D8CBE4F40DD52DF117195 flags verified ) ) game ( name "Classic NES Series - The Legend of Zelda (USA, Europe)" description "Classic NES Series - The Legend of Zelda (USA, Europe)" - rom ( name "Classic NES Series - The Legend of Zelda (USA, Europe).gba" size 4194304 crc 68B1B7A8 md5 588203BD9DE678A55A9F1707931302F2 sha1 D47BE5A160FC8E7B9F789AD7BA8867EF65B4D448 flags verified ) + rom ( name "Classic NES Series - The Legend of Zelda (USA, Europe).gba" size 4194304 crc 68b1b7a8 sha1 D47BE5A160FC8E7B9F789AD7BA8867EF65B4D448 flags verified ) ) game ( name "Classic NES Series - Xevious (USA, Europe)" description "Classic NES Series - Xevious (USA, Europe)" - rom ( name "Classic NES Series - Xevious (USA, Europe).gba" size 4194304 crc 9E923716 md5 E85CFE28EED4DC739A1851868011BEB6 sha1 BFF779F7E90073ED72363CF3451DAF6AFA6229CA flags verified ) + rom ( name "Classic NES Series - Xevious (USA, Europe).gba" size 4194304 crc 9e923716 sha1 BFF779F7E90073ED72363CF3451DAF6AFA6229CA flags verified ) ) game ( name "Classic NES Series - Zelda II - The Adventure of Link (USA, Europe)" description "Classic NES Series - Zelda II - The Adventure of Link (USA, Europe)" - rom ( name "Classic NES Series - Zelda II - The Adventure of Link (USA, Europe).gba" size 4194304 crc F2DC3B09 md5 9A18BDC223E591DAD8D251E62F755D6E sha1 AB608FC378CD0F8FB905B1B8D5B85400EE00CCFB flags verified ) + rom ( name "Classic NES Series - Zelda II - The Adventure of Link (USA, Europe).gba" size 4194304 crc f2dc3b09 sha1 AB608FC378CD0F8FB905B1B8D5B85400EE00CCFB flags verified ) ) game ( name "Cocoto - Kart Racer (Europe) (En,Fr,De,Es,It)" description "Cocoto - Kart Racer (Europe) (En,Fr,De,Es,It)" - rom ( name "Cocoto - Kart Racer (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc DAB7C402 md5 6F31F72E340681F2BB742097B7C593E8 sha1 BDDD18525F18CE55283F6771D1A99AE574275DC4 ) + rom ( name "Cocoto - Kart Racer (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc dab7c402 sha1 BDDD18525F18CE55283F6771D1A99AE574275DC4 ) ) game ( name "Cocoto - Platform Jumper (Europe) (En,Fr,De,Es,It)" description "Cocoto - Platform Jumper (Europe) (En,Fr,De,Es,It)" - rom ( name "Cocoto - Platform Jumper (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 27411EF5 md5 D94D214F30CFCC4479BA3A41F1ACC7CF sha1 BBAA323EE832CE35F171413034B154C540EAD51D ) + rom ( name "Cocoto - Platform Jumper (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 27411ef5 sha1 BBAA323EE832CE35F171413034B154C540EAD51D ) ) game ( name "CodeBreaker (USA) (Unl)" description "CodeBreaker (USA) (Unl)" - rom ( name "CodeBreaker (USA) (Unl).gba" size 65536 crc F5B2F65E md5 CBB808BCCF5AAB4D46C3C2DA2129429B sha1 1751D631C9955184A2CB55514E94D276C951231B ) + rom ( name "CodeBreaker (USA) (Unl).gba" size 65536 crc f5b2f65e sha1 1751D631C9955184A2CB55514E94D276C951231B ) ) game ( name "Codename - Kids Next Door - Operation S.O.D.A. (USA)" description "Codename - Kids Next Door - Operation S.O.D.A. (USA)" - rom ( name "Codename - Kids Next Door - Operation S.O.D.A. (USA).gba" size 8388608 crc 420A81B7 md5 E26711C4AAE6F6271E73F663B476C66A sha1 BBD176CC9A5331FDFDB332AD037D869610E4B3FB ) + rom ( name "Codename - Kids Next Door - Operation S.O.D.A. (USA).gba" size 8388608 crc 420a81b7 sha1 BBD176CC9A5331FDFDB332AD037D869610E4B3FB ) ) game ( name "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" description "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" - rom ( name "Colin McRae Rally 2.0 (Europe) (En,Fr,De).gba" size 4194304 crc 70520C5C md5 E366059F44F224BF4639A16DC0A9C6C4 sha1 DAAEE12C197655B2A7C3B260AC31A53687A711F6 flags verified ) + rom ( name "Colin McRae Rally 2.0 (Europe) (En,Fr,De).gba" size 4194304 crc 70520c5c sha1 DAAEE12C197655B2A7C3B260AC31A53687A711F6 flags verified ) ) game ( name "Colin McRae Rally 2.0 (USA) (En,Fr,De)" description "Colin McRae Rally 2.0 (USA) (En,Fr,De)" - rom ( name "Colin McRae Rally 2.0 (USA) (En,Fr,De).gba" size 4194304 crc A2E19014 md5 6D0AEF7B4A8AB01DB3C27284DF771A81 sha1 C29CB5E9843816369164A6F60486DC920A86BC6B ) + rom ( name "Colin McRae Rally 2.0 (USA) (En,Fr,De).gba" size 4194304 crc a2e19014 sha1 C29CB5E9843816369164A6F60486DC920A86BC6B ) ) game ( name "Columns Crown (Europe)" description "Columns Crown (Europe)" - rom ( name "Columns Crown (Europe).gba" size 8388608 crc 330A0975 md5 D96E8659DB64595A5EE7234145EBDC66 sha1 9D3982D3E42BF1E2BAE78C2965184629383F7247 flags verified ) + rom ( name "Columns Crown (Europe).gba" size 8388608 crc 330a0975 sha1 9D3982D3E42BF1E2BAE78C2965184629383F7247 flags verified ) ) game ( name "Columns Crown (Japan)" description "Columns Crown (Japan)" - rom ( name "Columns Crown (Japan).gba" size 8388608 crc A592F7DF md5 1F5A23D069BF42A1F3131E8C5A574EFB sha1 70A7229A57F4A296A661136E07E23668011310BF ) + rom ( name "Columns Crown (Japan).gba" size 8388608 crc a592f7df sha1 70A7229A57F4A296A661136E07E23668011310BF flags verified ) ) game ( name "Columns Crown (USA)" description "Columns Crown (USA)" - rom ( name "Columns Crown (USA).gba" size 8388608 crc 6242FFB2 md5 38F369F1CA0872790995943E8CB4A877 sha1 F11C7A225524D418907E42666B33649B585FB6D4 ) + rom ( name "Columns Crown (USA).gba" size 8388608 crc 6242ffb2 sha1 F11C7A225524D418907E42666B33649B585FB6D4 ) ) game ( name "Combat Choro Q - Advance Daisakusen (Japan)" description "Combat Choro Q - Advance Daisakusen (Japan)" - rom ( name "Combat Choro Q - Advance Daisakusen (Japan).gba" size 4194304 crc 4E5BFA90 md5 9FACD164F8558A699B6676868216AF91 sha1 05D33B870E881C3CC2B9B8C5CE403372637B4D00 ) + rom ( name "Combat Choro Q - Advance Daisakusen (Japan).gba" size 4194304 crc 4e5bfa90 sha1 05D33B870E881C3CC2B9B8C5CE403372637B4D00 ) ) game ( name "Combo Pack - Sonic Advance + Sonic Pinball Party (USA) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" description "Combo Pack - Sonic Advance + Sonic Pinball Party (USA) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It)" - rom ( name "Combo Pack - Sonic Advance + Sonic Pinball Party (USA) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 16777216 crc FBAFB638 md5 E0F566030C5AD91A20210476CD521D4E sha1 92F137372EC92E23C8DD190D761461653B80EA41 ) + rom ( name "Combo Pack - Sonic Advance + Sonic Pinball Party (USA) (En,Ja,Fr,De,Es+En,Ja,Fr,De,Es,It).gba" size 16777216 crc fbafb638 sha1 92F137372EC92E23C8DD190D761461653B80EA41 ) ) game ( name "Comix Zone (Europe) (En,Fr,De,Es,It)" description "Comix Zone (Europe) (En,Fr,De,Es,It)" - rom ( name "Comix Zone (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9F30002F md5 F586B690746ADCE9FCAAEF9D3D081117 sha1 7369A1F1A0BF52AAC8CDA97D082095BE08C65E72 ) + rom ( name "Comix Zone (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9f30002f sha1 7369A1F1A0BF52AAC8CDA97D082095BE08C65E72 ) +) + +game ( + name "Contra Advance (USA) (Beta)" + description "Contra Advance (USA) (Beta)" + rom ( name "Contra Advance (USA) (Beta).gba" size 4194304 crc 511d7556 sha1 F04AA9F1DD0FC7B5BCA47AA19BDE8E2A9AC0F35F flags verified ) ) game ( name "Contra Advance - The Alien Wars EX (USA)" description "Contra Advance - The Alien Wars EX (USA)" - rom ( name "Contra Advance - The Alien Wars EX (USA).gba" size 4194304 crc 59781C54 md5 78672EAD9F35F00E467F8C7D308ACDFC sha1 21B593C0FBDEACFBF0F72895FBA2401FD7B60B65 flags verified ) + rom ( name "Contra Advance - The Alien Wars EX (USA).gba" size 4194304 crc 59781c54 sha1 21B593C0FBDEACFBF0F72895FBA2401FD7B60B65 flags verified ) ) game ( name "Contra Advance - The Alien Wars EX (Europe)" description "Contra Advance - The Alien Wars EX (Europe)" - rom ( name "Contra Advance - The Alien Wars EX (Europe).gba" size 4194304 crc 5F443B14 md5 7B279FF2F8F00274542386674384B1FC sha1 4132DFA8D1D858F6B120F28B026FE2BFA1F22EE7 flags verified ) + rom ( name "Contra Advance - The Alien Wars EX (Europe).gba" size 4194304 crc 5f443b14 sha1 4132DFA8D1D858F6B120F28B026FE2BFA1F22EE7 flags verified ) +) + +game ( + name "Contra Advance - The Alien Wars EX (USA) (Wii U Virtual Console)" + description "Contra Advance - The Alien Wars EX (USA) (Wii U Virtual Console)" + rom ( name "Contra Advance - The Alien Wars EX (USA) (Wii U Virtual Console).gba" size 4194304 crc 606bfdd9 sha1 6BFCA66655A58405337DA4F040F758D7312F17EF flags verified ) ) game ( name "Contra Hard Spirits (Japan) (En)" description "Contra Hard Spirits (Japan) (En)" - rom ( name "Contra Hard Spirits (Japan) (En).gba" size 4194304 crc A817AA47 md5 D3F866C892022EC6FA89B4DBDBCB0EFA sha1 CAAF3A350709F13E7E3D26CDC08495A7E6A57B87 ) + rom ( name "Contra Hard Spirits (Japan) (En).gba" size 4194304 crc a817aa47 sha1 CAAF3A350709F13E7E3D26CDC08495A7E6A57B87 ) ) game ( name "Corvette (USA) (En,Fr,De,Es,It)" description "Corvette (USA) (En,Fr,De,Es,It)" - rom ( name "Corvette (USA) (En,Fr,De,Es,It).gba" size 8388608 crc A4C6DB01 md5 5E5295484BB4CFF6C487AE06FA4C4C69 sha1 676145DA9D6824F0BEB7DC4A58062C3BC8AE266A ) + rom ( name "Corvette (USA) (En,Fr,De,Es,It).gba" size 8388608 crc a4c6db01 sha1 676145DA9D6824F0BEB7DC4A58062C3BC8AE266A ) ) game ( name "Cosmo & Wanda - Wenn Elfen Helfen! - Das Schattenduell (Germany)" description "Cosmo & Wanda - Wenn Elfen Helfen! - Das Schattenduell (Germany)" - rom ( name "Cosmo & Wanda - Wenn Elfen Helfen! - Das Schattenduell (Germany).gba" size 4194304 crc 65E88703 md5 B5BE468E85618343BC7AB78588CB5163 sha1 9A6C0834734C25A38149C05C742891F2AD6ECDEA ) + rom ( name "Cosmo & Wanda - Wenn Elfen Helfen! - Das Schattenduell (Germany).gba" size 4194304 crc 65e88703 sha1 9A6C0834734C25A38149C05C742891F2AD6ECDEA ) ) game ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl)" description "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc D8382427 md5 55FEE8B8F0B9185853F02C9E064436A9 sha1 4E184F8F52E5A6B79A272F7674178D3D3CCC3386 flags verified ) + rom ( name "Crash & Spyro Super Pack Volume 1 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc d8382427 sha1 4E184F8F52E5A6B79A272F7674178D3D3CCC3386 flags verified ) ) game ( name "Crash & Spyro Super Pack Volume 2 (Europe) (En,Fr,De,Es,It,Nl)" description "Crash & Spyro Super Pack Volume 2 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash & Spyro Super Pack Volume 2 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 7B3C4F90 md5 AB2A7F46B0C806429CE56FF53DF10620 sha1 53061BF5148C296C12476145CDA0DF88DD7D42AF ) + rom ( name "Crash & Spyro Super Pack Volume 2 (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 7b3c4f90 sha1 53061BF5148C296C12476145CDA0DF88DD7D42AF flags verified ) ) game ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It)" description "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 0510B70F md5 21659BC5B60A7F78318310434C959BC8 sha1 BF33976D1A26E336416E0FD28B2B8DA65450737D ) + rom ( name "Crash & Spyro Super Pack Volume 3 (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 0510b70f sha1 BF33976D1A26E336416E0FD28B2B8DA65450737D ) ) game ( name "Crash & Spyro Superpack - Spyro - Season of Ice + Crash Bandicoot - The Huge Adventure (USA)" description "Crash & Spyro Superpack - Spyro - Season of Ice + Crash Bandicoot - The Huge Adventure (USA)" - rom ( name "Crash & Spyro Superpack - Spyro - Season of Ice + Crash Bandicoot - The Huge Adventure (USA).gba" size 16777216 crc CDBE00E3 md5 394D582B5555937299C6B10AC0ACC717 sha1 CE1B1184685E20A683EC93B79093A1C7C41B818E ) + rom ( name "Crash & Spyro Superpack - Spyro - Season of Ice + Crash Bandicoot - The Huge Adventure (USA).gba" size 16777216 crc cdbe00e3 sha1 CE1B1184685E20A683EC93B79093A1C7C41B818E ) ) game ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA)" description "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA)" - rom ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 33554432 crc 5940906E md5 50126D4115F7EBA81EB206B13B68D726 sha1 95B5A68962CE552A71D8212850E85D90D2844B40 ) + rom ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 33554432 crc 5940906e sha1 95B5A68962CE552A71D8212850E85D90D2844B40 ) ) game ( name "Crash Bandicoot - The Huge Adventure (USA)" description "Crash Bandicoot - The Huge Adventure (USA)" - rom ( name "Crash Bandicoot - The Huge Adventure (USA).gba" size 8388608 crc 034D2D4B md5 32D74527BFE723470C2C5406C325FB59 sha1 5A2651C78BB8A1D707E3C3AF1F46FB64E2104198 ) + rom ( name "Crash Bandicoot - The Huge Adventure (USA).gba" size 8388608 crc 034d2d4b sha1 5A2651C78BB8A1D707E3C3AF1F46FB64E2104198 ) ) game ( name "Crash Bandicoot 2 - N-Tranced (USA)" description "Crash Bandicoot 2 - N-Tranced (USA)" - rom ( name "Crash Bandicoot 2 - N-Tranced (USA).gba" size 8388608 crc 2E16184A md5 617B2B2590E2925228DBDB162B05D6F6 sha1 972158859EA08AA5746AB2E0D4C81AC43728ADFF ) + rom ( name "Crash Bandicoot 2 - N-Tranced (USA).gba" size 8388608 crc 2e16184a sha1 972158859EA08AA5746AB2E0D4C81AC43728ADFF flags verified ) ) game ( name "Crash Bandicoot 2 - N-Tranced (Europe) (En,Fr,De,Es,It,Nl)" description "Crash Bandicoot 2 - N-Tranced (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash Bandicoot 2 - N-Tranced (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 0F1D06A0 md5 03BEECD053B2DDF56341A6A981C561FC sha1 EE9234CA15BA2CAA71FAD7D6AF71E27B2030AE0B ) + rom ( name "Crash Bandicoot 2 - N-Tranced (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 0f1d06a0 sha1 EE9234CA15BA2CAA71FAD7D6AF71E27B2030AE0B flags verified ) ) game ( name "Crash Bandicoot Advance (Japan)" description "Crash Bandicoot Advance (Japan)" - rom ( name "Crash Bandicoot Advance (Japan).gba" size 8388608 crc 64767B34 md5 B7F7CBC994934461DB0A94CB8B752873 sha1 409814B6CCA882F7F1CDBEBBA9503D77B6297EEC ) + rom ( name "Crash Bandicoot Advance (Japan).gba" size 8388608 crc 64767b34 sha1 409814B6CCA882F7F1CDBEBBA9503D77B6297EEC ) ) game ( name "Crash Bandicoot Advance - Wakuwaku Tomodachi Daisakusen! (Japan)" description "Crash Bandicoot Advance - Wakuwaku Tomodachi Daisakusen! (Japan)" - rom ( name "Crash Bandicoot Advance - Wakuwaku Tomodachi Daisakusen! (Japan).gba" size 16777216 crc 0E6A4FEE md5 9CC426F1CCBB18F1E156F6F9EE28D2FC sha1 6BC7E3D8DB8A56447532A6DC8D065CEC243ABCB9 ) + rom ( name "Crash Bandicoot Advance - Wakuwaku Tomodachi Daisakusen! (Japan).gba" size 16777216 crc 0e6a4fee sha1 6BC7E3D8DB8A56447532A6DC8D065CEC243ABCB9 ) ) game ( name "Crash Bandicoot Advance 2 - Guruguru Saimin Dai-panic! (Japan)" description "Crash Bandicoot Advance 2 - Guruguru Saimin Dai-panic! (Japan)" - rom ( name "Crash Bandicoot Advance 2 - Guruguru Saimin Dai-panic! (Japan).gba" size 8388608 crc 04FBA7CF md5 3B11E4CEF56904BBD309690A3CA4F79F sha1 085597AA8E804C33BAC388FBA854F5B2772EC8C8 ) + rom ( name "Crash Bandicoot Advance 2 - Guruguru Saimin Dai-panic! (Japan).gba" size 8388608 crc 04fba7cf sha1 085597AA8E804C33BAC388FBA854F5B2772EC8C8 flags verified ) ) game ( - name "Crash Bandicoot Bakusou Nitro Cart (Japan)" - description "Crash Bandicoot Bakusou Nitro Cart (Japan)" - rom ( name "Crash Bandicoot Bakusou Nitro Cart (Japan).gba" size 8388608 crc 70F8291F md5 10E701D275BB9B34B4C451BF8A611495 sha1 9F80049A5C79894931651F47C634FEE9F8CB62AD ) + name "Crash Bandicoot Bakusou! Nitro Cart (Japan)" + description "Crash Bandicoot Bakusou! Nitro Cart (Japan)" + rom ( name "Crash Bandicoot Bakusou! Nitro Cart (Japan).gba" size 8388608 crc 70f8291f sha1 9F80049A5C79894931651F47C634FEE9F8CB62AD flags verified ) ) game ( name "Crash Bandicoot Fusion (Europe) (En,Fr,De,Es,It)" description "Crash Bandicoot Fusion (Europe) (En,Fr,De,Es,It)" - rom ( name "Crash Bandicoot Fusion (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc F24C8E77 md5 15E37FB594C2DFE85B8B7BA3B7E565BD sha1 E29CB4309D2E94974C34DCEA42C8AB7E90134B55 flags verified ) + rom ( name "Crash Bandicoot Fusion (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc f24c8e77 sha1 E29CB4309D2E94974C34DCEA42C8AB7E90134B55 flags verified ) ) game ( name "Crash Bandicoot Purple - Ripto's Rampage (USA)" description "Crash Bandicoot Purple - Ripto's Rampage (USA)" - rom ( name "Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 16777216 crc FC284E05 md5 A9C93A07964AA816A8E226AE0C735A41 sha1 35D1C8C90890BF7CE66306E6C06A3676A723DCF3 ) + rom ( name "Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 16777216 crc fc284e05 sha1 35D1C8C90890BF7CE66306E6C06A3676A723DCF3 ) ) game ( name "Crash Bandicoot Purple - Ripto's Rampage (USA) (Rev 1)" description "Crash Bandicoot Purple - Ripto's Rampage (USA) (Rev 1)" - rom ( name "Crash Bandicoot Purple - Ripto's Rampage (USA) (Rev 1).gba" size 16777216 crc 3DDF07A1 md5 24EF180602E0658BBE38FABC5D09894C sha1 B14DA39B82D9C69F60DEDA179C073A14D07D5CE7 ) + rom ( name "Crash Bandicoot Purple - Ripto's Rampage (USA) (Rev 1).gba" size 16777216 crc 3ddf07a1 sha1 B14DA39B82D9C69F60DEDA179C073A14D07D5CE7 flags verified ) ) game ( name "Crash Bandicoot XS (Europe) (En,Fr,De,Es,It,Nl)" description "Crash Bandicoot XS (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash Bandicoot XS (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc CCFD654F md5 B282E479E10AEA057E762DE7B9D4CA4B sha1 BDD061E1B5187C0528928EC0DDB6886B1DE16970 flags verified ) + rom ( name "Crash Bandicoot XS (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc ccfd654f sha1 BDD061E1B5187C0528928EC0DDB6886B1DE16970 flags verified ) ) game ( name "Crash Nitro Kart (USA)" description "Crash Nitro Kart (USA)" - rom ( name "Crash Nitro Kart (USA).gba" size 8388608 crc E6D58AA0 md5 9E6FF628DB81CAA74DCA356EAADADAC9 sha1 292001BBD3A99CE503F36DDAB9D092FF07ACA7E7 ) + rom ( name "Crash Nitro Kart (USA).gba" size 8388608 crc e6d58aa0 sha1 292001BBD3A99CE503F36DDAB9D092FF07ACA7E7 ) ) game ( name "Crash Nitro Kart (Europe) (En,Fr,De,Es,It,Nl)" description "Crash Nitro Kart (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash Nitro Kart (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 03925772 md5 41832956AB0723CA79D6883C4492FE84 sha1 91904F5BA5C501B761FC01A48E4EFC41EE5B8E41 ) + rom ( name "Crash Nitro Kart (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 03925772 sha1 91904F5BA5C501B761FC01A48E4EFC41EE5B8E41 flags verified ) ) game ( name "Crash of the Titans (USA) (En,Fr)" description "Crash of the Titans (USA) (En,Fr)" - rom ( name "Crash of the Titans (USA) (En,Fr).gba" size 16777216 crc 6F28B009 md5 FDEF312709444D6D901B8B7C619F5913 sha1 A084E47A029B09A363600E7D20D244EEFFA2D84D ) + rom ( name "Crash of the Titans (USA) (En,Fr).gba" size 16777216 crc 6f28b009 sha1 A084E47A029B09A363600E7D20D244EEFFA2D84D ) ) game ( name "Crash of the Titans (Europe) (En,Fr,De,Es,It,Nl)" description "Crash of the Titans (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Crash of the Titans (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc D1D07FA6 md5 E2403303923BF63CD48C4B32E918B246 sha1 A61671040AE797CDD9023BB965D3DC39C9D8AB75 ) + rom ( name "Crash of the Titans (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc d1d07fa6 sha1 A61671040AE797CDD9023BB965D3DC39C9D8AB75 ) ) game ( - name "Crash Superpack (USA)" - description "Crash Superpack (USA)" - rom ( name "Crash Superpack (USA).gba" size 16777216 crc 2C38BAE2 md5 3638075A07AD63A813DEA97E6AD16D2C sha1 23934042B3F7AC414DEF68246C281E20F735A1D7 ) + name "Crash Superpack - Crash Bandicoot 2 - N-Tranced + Crash Nitro Kart (USA)" + description "Crash Superpack - Crash Bandicoot 2 - N-Tranced + Crash Nitro Kart (USA)" + rom ( name "Crash Superpack - Crash Bandicoot 2 - N-Tranced + Crash Nitro Kart (USA).gba" size 16777216 crc 2c38bae2 sha1 23934042B3F7AC414DEF68246C281E20F735A1D7 flags verified ) ) game ( name "Crayon Shin-chan - Arashi o Yobu Cinemaland no Daibouken! (Japan)" description "Crayon Shin-chan - Arashi o Yobu Cinemaland no Daibouken! (Japan)" - rom ( name "Crayon Shin-chan - Arashi o Yobu Cinemaland no Daibouken! (Japan).gba" size 16777216 crc 6E936A54 md5 E3B402EF6B72847594BCE110FEFA4139 sha1 3C2820877F810D1CB4D56A4881B38A457356BDD1 ) + rom ( name "Crayon Shin-chan - Arashi o Yobu Cinemaland no Daibouken! (Japan).gba" size 16777216 crc 6e936a54 sha1 3C2820877F810D1CB4D56A4881B38A457356BDD1 ) ) game ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan)" description "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan)" - rom ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan).gba" size 33554432 crc 45C84466 md5 7199C3BC2CC2D685AD7ECD9447E6D75F sha1 E17BAA57D339F7D85F562441111696E88088FCDD ) -) - -game ( - name "Crazy Chase (Europe) (Beta)" - description "Crazy Chase (Europe) (Beta)" - rom ( name "Crazy Chase (Europe) (Beta).gba" size 4194304 crc FF7E2E9B md5 7FC96F1C2565F244C7DD561B6CBE43BF sha1 55805EC4D5DFA28D628C2C9E3DF509A8763929EB ) -) - -game ( - name "Crazy Chase (Europe) (En,Fr,De) (Beta)" - description "Crazy Chase (Europe) (En,Fr,De) (Beta)" - rom ( name "Crazy Chase (Europe) (En,Fr,De) (Beta).gba" size 4194304 crc 5F331132 md5 2670653630214CF574B16ED8A7C9EA9E sha1 39530E28DD22A710F2CC414B377C638078AA54B7 ) + rom ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan).gba" size 33554432 crc 45c84466 sha1 E17BAA57D339F7D85F562441111696E88088FCDD ) ) game ( name "Crazy Chase (Europe) (En,Fr,De)" description "Crazy Chase (Europe) (En,Fr,De)" - rom ( name "Crazy Chase (Europe) (En,Fr,De).gba" size 4194304 crc 313F4FFC md5 0A9938A6BB7B657A1FB2588B91900122 sha1 4B711C4514E10F89AAB6EA69CBAFD64AC5E2F52B ) + rom ( name "Crazy Chase (Europe) (En,Fr,De).gba" size 4194304 crc 313f4ffc sha1 4B711C4514E10F89AAB6EA69CBAFD64AC5E2F52B flags verified ) ) game ( name "Crazy Chase (USA)" description "Crazy Chase (USA)" - rom ( name "Crazy Chase (USA).gba" size 4194304 crc CABA1DB9 md5 44A36F758C4328AA0FFC91EC118CF28D sha1 C84759EBA2683A44F49F3CF52AD7C82D6A85CA74 ) + rom ( name "Crazy Chase (USA).gba" size 4194304 crc caba1db9 sha1 C84759EBA2683A44F49F3CF52AD7C82D6A85CA74 ) +) + +game ( + name "Crazy Chase (Europe) (Beta)" + description "Crazy Chase (Europe) (Beta)" + rom ( name "Crazy Chase (Europe) (Beta).gba" size 4194304 crc ff7e2e9b sha1 55805EC4D5DFA28D628C2C9E3DF509A8763929EB ) +) + +game ( + name "Crazy Chase (Europe) (En,Fr,De) (Beta)" + description "Crazy Chase (Europe) (En,Fr,De) (Beta)" + rom ( name "Crazy Chase (Europe) (En,Fr,De) (Beta).gba" size 4194304 crc 5f331132 sha1 39530E28DD22A710F2CC414B377C638078AA54B7 ) ) game ( name "Crazy Frog Racer (Europe) (En,Fr,De,Nl)" description "Crazy Frog Racer (Europe) (En,Fr,De,Nl)" - rom ( name "Crazy Frog Racer (Europe) (En,Fr,De,Nl).gba" size 4194304 crc 2723236B md5 F341BAB11F2BFD79B995554D40A61CBA sha1 9FF4BD804F75BB526849A5DA97E3803F69F31AA1 ) -) - -game ( - name "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It)" - description "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It)" - rom ( name "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4AEBD704 md5 603470CB171BC53491B0A8643F1302EF sha1 6C63AC0E57A0125A73248B75F29C58892D17750E ) + rom ( name "Crazy Frog Racer (Europe) (En,Fr,De,Nl).gba" size 4194304 crc 2723236b sha1 9FF4BD804F75BB526849A5DA97E3803F69F31AA1 ) ) game ( name "Crazy Taxi - Catch a Ride (USA)" description "Crazy Taxi - Catch a Ride (USA)" - rom ( name "Crazy Taxi - Catch a Ride (USA).gba" size 8388608 crc 8EC709D6 md5 8BCF4E0DA6BE539F2099C683FF897B43 sha1 D41F8528E5D010637ECE3A50F22C3C809E49B578 ) + rom ( name "Crazy Taxi - Catch a Ride (USA).gba" size 8388608 crc 8ec709d6 sha1 D41F8528E5D010637ECE3A50F22C3C809E49B578 ) +) + +game ( + name "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It)" + description "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It)" + rom ( name "Crazy Taxi - Catch a Ride (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4aebd704 sha1 6C63AC0E57A0125A73248B75F29C58892D17750E ) ) game ( name "Creatures (Europe) (En,Fr,De)" description "Creatures (Europe) (En,Fr,De)" - rom ( name "Creatures (Europe) (En,Fr,De).gba" size 4194304 crc 68206301 md5 63AFE31B245C10C69E794E2A1D41366B sha1 DA03610FCE2C684C1DD49DACCDA6392B7B86D51E ) + rom ( name "Creatures (Europe) (En,Fr,De).gba" size 4194304 crc 68206301 sha1 DA03610FCE2C684C1DD49DACCDA6392B7B86D51E ) ) game ( name "Creatures (Europe) (En,Es,It)" description "Creatures (Europe) (En,Es,It)" - rom ( name "Creatures (Europe) (En,Es,It).gba" size 4194304 crc 4F18F57E md5 400EAD5C0C15BE96DE3EBACDA5EEDDA7 sha1 2CFE90927401FC2D7F62FCDD2648B2AA0DFA31BF ) + rom ( name "Creatures (Europe) (En,Es,It).gba" size 4194304 crc 4f18f57e sha1 2CFE90927401FC2D7F62FCDD2648B2AA0DFA31BF ) ) game ( name "Croket! - Yume no Banker Survival! (Japan)" description "Croket! - Yume no Banker Survival! (Japan)" - rom ( name "Croket! - Yume no Banker Survival! (Japan).gba" size 8388608 crc A2AAD079 md5 26E70E3BCD7FD311A9BA93F64CBFE30E sha1 F055EEA6A8CF05B6B21555E0F12B44E64E7F058F ) + rom ( name "Croket! - Yume no Banker Survival! (Japan).gba" size 8388608 crc a2aad079 sha1 F055EEA6A8CF05B6B21555E0F12B44E64E7F058F flags verified ) ) game ( name "Croket! 2 - Yami no Bank to Banqueen (Japan)" description "Croket! 2 - Yami no Bank to Banqueen (Japan)" - rom ( name "Croket! 2 - Yami no Bank to Banqueen (Japan).gba" size 16777216 crc 8D5E08D5 md5 A45E4C70FA05008D3E90F2BFC1F6DC93 sha1 C33A0EEAEF33FB8B7C0463D3482B78B147AB304D ) + rom ( name "Croket! 2 - Yami no Bank to Banqueen (Japan).gba" size 16777216 crc 8d5e08d5 sha1 C33A0EEAEF33FB8B7C0463D3482B78B147AB304D ) ) game ( name "Croket! 3 - Granu Oukoku no Nazo (Japan)" description "Croket! 3 - Granu Oukoku no Nazo (Japan)" - rom ( name "Croket! 3 - Granu Oukoku no Nazo (Japan).gba" size 16777216 crc AEC6D07B md5 B33F6D3A7151F15CD10F71A7E2B3DFDD sha1 40944C9E38CECAA18496BDFF6B4C0B34ED58906F flags verified ) + rom ( name "Croket! 3 - Granu Oukoku no Nazo (Japan).gba" size 16777216 crc aec6d07b sha1 40944C9E38CECAA18496BDFF6B4C0B34ED58906F flags verified ) ) game ( name "Croket! 4 - Bank no Mori no Mamorigami (Japan)" description "Croket! 4 - Bank no Mori no Mamorigami (Japan)" - rom ( name "Croket! 4 - Bank no Mori no Mamorigami (Japan).gba" size 16777216 crc C86BF751 md5 87913C168EAE9F2187119BECB03AD598 sha1 BB4CF093A94EE46A2583E13FFE9A028551822448 ) + rom ( name "Croket! 4 - Bank no Mori no Mamorigami (Japan).gba" size 16777216 crc c86bf751 sha1 BB4CF093A94EE46A2583E13FFE9A028551822448 flags verified ) ) game ( name "Croket! Great - Toki no Boukensha (Japan)" description "Croket! Great - Toki no Boukensha (Japan)" - rom ( name "Croket! Great - Toki no Boukensha (Japan).gba" size 16777216 crc F0E81971 md5 E799D636498DEFE6EC44ED038193F366 sha1 410FB8FE2FE07BE146C8454122D874287F92FBAC ) + rom ( name "Croket! Great - Toki no Boukensha (Japan).gba" size 16777216 crc f0e81971 sha1 410FB8FE2FE07BE146C8454122D874287F92FBAC ) ) game ( name "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" description "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" - rom ( name "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es).gba" size 8388608 crc 579BA507 md5 109B5DAB2C9472D26E9B68CABFAC0D4F sha1 7C4FF48FD0B4B055E2353A3A64E5C15F7CE5988B flags verified ) + rom ( name "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es).gba" size 8388608 crc 579ba507 sha1 7C4FF48FD0B4B055E2353A3A64E5C15F7CE5988B flags verified ) ) game ( name "Crouching Tiger, Hidden Dragon (Europe) (En,Fr,De,Es,It)" description "Crouching Tiger, Hidden Dragon (Europe) (En,Fr,De,Es,It)" - rom ( name "Crouching Tiger, Hidden Dragon (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B9A75AC4 md5 7DF46D6DC76D9D84DBED120655D5F69E sha1 A61737A52D2C86422290C6D4BD75950ACD53E775 ) + rom ( name "Crouching Tiger, Hidden Dragon (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b9a75ac4 sha1 A61737A52D2C86422290C6D4BD75950ACD53E775 ) ) game ( name "Crouching Tiger, Hidden Dragon (USA) (Beta)" description "Crouching Tiger, Hidden Dragon (USA) (Beta)" - rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta).gba" size 8388608 crc 204FF8D5 md5 6CB4DC8B610A4238A159A7037185540D sha1 AF24D128B28758A8A1BDA45B5A24A299E1E14B90 ) -) - -game ( - name "Cruis'n Velocity (USA) (Beta)" - description "Cruis'n Velocity (USA) (Beta)" - rom ( name "Cruis'n Velocity (USA) (Beta).gba" size 8388608 crc 5436D5DA md5 6A0D1DD9BC181792F61F7C92262392C4 sha1 D1716D4603DD8DB7AE8715D5142A60230D17E1D2 ) + rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta).gba" size 8388608 crc 204ff8d5 sha1 AF24D128B28758A8A1BDA45B5A24A299E1E14B90 ) ) game ( name "Cruis'n Velocity (USA, Europe)" description "Cruis'n Velocity (USA, Europe)" - rom ( name "Cruis'n Velocity (USA, Europe).gba" size 4194304 crc ADF14DB5 md5 987308F23CEA98609A77629CC1BFB23A sha1 762AABC26501DEE4AA566E8327600433C8EDBF7A flags verified ) + rom ( name "Cruis'n Velocity (USA, Europe).gba" size 4194304 crc adf14db5 sha1 762AABC26501DEE4AA566E8327600433C8EDBF7A flags verified ) +) + +game ( + name "Cruis'n Velocity (USA) (Beta)" + description "Cruis'n Velocity (USA) (Beta)" + rom ( name "Cruis'n Velocity (USA) (Beta).gba" size 8388608 crc 5436d5da sha1 D1716D4603DD8DB7AE8715D5142A60230D17E1D2 ) ) game ( name "Crushed Baseball (USA)" description "Crushed Baseball (USA)" - rom ( name "Crushed Baseball (USA).gba" size 4194304 crc 55FE8579 md5 09DAAE27C8D72F04AC2EA12D8A9CC89D sha1 51C419CD8CD8FD7CA78D0EA74B9B3C3F1E901DF9 ) -) - -game ( - name "CT Special Forces (USA) (En,Fr,De,Es,It,Nl)" - description "CT Special Forces (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc AEA22AE0 md5 BB8477087E3D927AF99CD3263C66F7CF sha1 AB151206C142DBCDB4F2EA9877D6BCD2C89B8B55 ) + rom ( name "Crushed Baseball (USA).gba" size 4194304 crc 55fe8579 sha1 51C419CD8CD8FD7CA78D0EA74B9B3C3F1E901DF9 ) ) game ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" description "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc A20D9ADB md5 81A78EBFF4713C80857482AC6956F52F sha1 E178192BA2C78759245541BD54D96D83A8D5D9C6 ) + rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc a20d9adb sha1 E178192BA2C78759245541BD54D96D83A8D5D9C6 flags verified ) +) + +game ( + name "CT Special Forces (USA) (En,Fr,De,Es,It,Nl)" + description "CT Special Forces (USA) (En,Fr,De,Es,It,Nl)" + rom ( name "CT Special Forces (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc aea22ae0 sha1 AB151206C142DBCDB4F2EA9877D6BCD2C89B8B55 ) ) game ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta)" - rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc 40A0E1C9 md5 6DBD1F78AF20F0034A05C396DB83B86F sha1 FAB8B62A141865F12C69334F4DB14C837D9D94AF ) + rom ( name "CT Special Forces (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc 40a0e1c9 sha1 FAB8B62A141865F12C69334F4DB14C837D9D94AF ) ) game ( name "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl)" description "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 863CBF31 md5 B2E1C0DE1D83068B2DAA90EFC543BD29 sha1 B782DAC774932D93C313B122CA2C7C072CA84840 ) + rom ( name "CT Special Forces - Back to Hell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 863cbf31 sha1 B782DAC774932D93C313B122CA2C7C072CA84840 flags verified ) ) game ( name "CT Special Forces - Bioterror (Europe) (En,Fr,De,Es,It,Nl)" description "CT Special Forces - Bioterror (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces - Bioterror (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7DC40EDA md5 542C75B45890DCA1F893A1F400B9824F sha1 0AC478E4568F5886FCE546B903FD50424A059438 ) + rom ( name "CT Special Forces - Bioterror (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7dc40eda sha1 0AC478E4568F5886FCE546B903FD50424A059438 ) ) game ( name "CT Special Forces 2 - Back in the Trenches (USA) (En,Fr,De,Es,It,Nl)" description "CT Special Forces 2 - Back in the Trenches (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "CT Special Forces 2 - Back in the Trenches (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc D2B58A33 md5 A827B6305C196589C0FA6ED2F9EC0E3B sha1 CEDCA3AAC39309DC122909D11457E306C81E16BE ) + rom ( name "CT Special Forces 2 - Back in the Trenches (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc d2b58a33 sha1 CEDCA3AAC39309DC122909D11457E306C81E16BE ) ) game ( name "Cubix - Robots for Everyone - Clash 'N Bash (USA)" description "Cubix - Robots for Everyone - Clash 'N Bash (USA)" - rom ( name "Cubix - Robots for Everyone - Clash 'N Bash (USA).gba" size 8388608 crc 4171C811 md5 4A5A274A7C2514B21EBB43B2CEADE091 sha1 9E5AED84668E5838CB58A3C33E8D6DB7A85FD536 ) + rom ( name "Cubix - Robots for Everyone - Clash 'N Bash (USA).gba" size 8388608 crc 4171c811 sha1 9E5AED84668E5838CB58A3C33E8D6DB7A85FD536 ) ) game ( name "Curious George (USA)" description "Curious George (USA)" - rom ( name "Curious George (USA).gba" size 4194304 crc F6B549DD md5 B70A1CFD17B2194AD99B2ABF558AADF2 sha1 7153A1E2B246C1997A91257480C67AC8B54FE61B ) + rom ( name "Curious George (USA).gba" size 4194304 crc f6b549dd sha1 7153A1E2B246C1997A91257480C67AC8B54FE61B ) ) game ( name "Curious George (Europe) (En,Fr,De,Es,It,Sv,Da)" description "Curious George (Europe) (En,Fr,De,Es,It,Sv,Da)" - rom ( name "Curious George (Europe) (En,Fr,De,Es,It,Sv,Da).gba" size 4194304 crc EEF104B0 md5 1F49D24AC42D1697A55A45A145B1DD39 sha1 702B89DF39AFAE4D767977AE5B5ED0467E009FFC flags verified ) + rom ( name "Curious George (Europe) (En,Fr,De,Es,It,Sv,Da).gba" size 4194304 crc eef104b0 sha1 702B89DF39AFAE4D767977AE5B5ED0467E009FFC flags verified ) ) game ( name "Custom Robo GX (Japan)" description "Custom Robo GX (Japan)" - rom ( name "Custom Robo GX (Japan).gba" size 8388608 crc F533DC13 md5 AE35FB67A74C92A3F063408FD0BC4A29 sha1 0B5CE051AA1FD83AB0EC79122B07B02BB41096A5 ) + rom ( name "Custom Robo GX (Japan).gba" size 8388608 crc f533dc13 sha1 0B5CE051AA1FD83AB0EC79122B07B02BB41096A5 flags verified ) ) game ( name "Cyberdrive Zoids - Kijuu no Senshi Hyuu (Japan)" description "Cyberdrive Zoids - Kijuu no Senshi Hyuu (Japan)" - rom ( name "Cyberdrive Zoids - Kijuu no Senshi Hyuu (Japan).gba" size 8388608 crc 0020A2ED md5 A267752542EEA07127E53D6179DB760D sha1 3C934188CA5C268DBD0459B0F4C04FFE1C9F3094 ) + rom ( name "Cyberdrive Zoids - Kijuu no Senshi Hyuu (Japan).gba" size 8388608 crc 0020a2ed sha1 3C934188CA5C268DBD0459B0F4C04FFE1C9F3094 ) ) game ( name "Dai-mahjong. (Japan)" description "Dai-mahjong. (Japan)" - rom ( name "Dai-mahjong. (Japan).gba" size 4194304 crc C6CCCA05 md5 30A4CD474AF1B4B156DBEE4CFEB4C0D3 sha1 35E4C69A6A30362D873E3383942F86932A216ECF ) + rom ( name "Dai-mahjong. (Japan).gba" size 4194304 crc c6ccca05 sha1 35E4C69A6A30362D873E3383942F86932A216ECF ) ) game ( name "Daisenryaku for Game Boy Advance (Japan)" description "Daisenryaku for Game Boy Advance (Japan)" - rom ( name "Daisenryaku for Game Boy Advance (Japan).gba" size 8388608 crc 3D644946 md5 47433C75DDD92985B8807002136E8E9D sha1 CC26CE028614A5D47735219050006D1C6C22BCD9 ) + rom ( name "Daisenryaku for Game Boy Advance (Japan).gba" size 8388608 crc 3d644946 sha1 CC26CE028614A5D47735219050006D1C6C22BCD9 ) ) game ( name "Daisuki Teddy (Japan)" description "Daisuki Teddy (Japan)" - rom ( name "Daisuki Teddy (Japan).gba" size 8388608 crc CBB8CDB8 md5 9636918DB9F7489630BB8BFF049F8AE3 sha1 4A8C1674A7BFAF06589CBE94A362F8DEF3351155 flags verified ) + rom ( name "Daisuki Teddy (Japan).gba" size 8388608 crc cbb8cdb8 sha1 4A8C1674A7BFAF06589CBE94A362F8DEF3351155 flags verified ) ) game ( name "Dan Doh!! Tobase Shouri no Smile Shot (Japan)" description "Dan Doh!! Tobase Shouri no Smile Shot (Japan)" - rom ( name "Dan Doh!! Tobase Shouri no Smile Shot (Japan).gba" size 8388608 crc 0F4B50AE md5 5B3DC1A03011107CCECCD102305D9083 sha1 5853A8EC224890F42AD3A998AE62B64BFFAE1F2D ) + rom ( name "Dan Doh!! Tobase Shouri no Smile Shot (Japan).gba" size 8388608 crc 0f4b50ae sha1 5853A8EC224890F42AD3A998AE62B64BFFAE1F2D ) ) game ( name "Dan Doh!! Xi (Japan)" description "Dan Doh!! Xi (Japan)" - rom ( name "Dan Doh!! Xi (Japan).gba" size 8388608 crc E1D5CFF1 md5 D20CF72F03B73D3BE7A3FD89C085F5FE sha1 7D7F17E77F29A54B38246D5B33AEBA6D908377BD flags verified ) + rom ( name "Dan Doh!! Xi (Japan).gba" size 8388608 crc e1d5cff1 sha1 7D7F17E77F29A54B38246D5B33AEBA6D908377BD flags verified ) ) game ( name "Dancing Sword - Senkou (Japan)" description "Dancing Sword - Senkou (Japan)" - rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc E2316D47 md5 293102890D234DB6139F88DA7D785230 sha1 5C5F33E0453CBA1A60039160564DAA53A82DB8AA flags verified ) + rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc e2316d47 sha1 5C5F33E0453CBA1A60039160564DAA53A82DB8AA flags verified ) ) game ( name "Danny Phantom - Dschungelstadt (Germany)" description "Danny Phantom - Dschungelstadt (Germany)" - rom ( name "Danny Phantom - Dschungelstadt (Germany).gba" size 4194304 crc 2D59C1D5 md5 B488ACD6E738BCE4CE01BFB3E41F94E1 sha1 D64F0906FD1C364E93BBA6F28EBA8B3780DF0B8C ) + rom ( name "Danny Phantom - Dschungelstadt (Germany).gba" size 4194304 crc 2d59c1d5 sha1 D64F0906FD1C364E93BBA6F28EBA8B3780DF0B8C ) ) game ( name "Danny Phantom - The Ultimate Enemy (USA)" description "Danny Phantom - The Ultimate Enemy (USA)" - rom ( name "Danny Phantom - The Ultimate Enemy (USA).gba" size 4194304 crc 1384ECEA md5 5964ADD1D23B22F8947FC3372BD18306 sha1 0760350C2D71CD9B7F3CFA9E2E30B682DEFE0901 ) + rom ( name "Danny Phantom - The Ultimate Enemy (USA).gba" size 4194304 crc 1384ecea sha1 0760350C2D71CD9B7F3CFA9E2E30B682DEFE0901 ) ) game ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,De,Es)" description "Danny Phantom - The Ultimate Enemy (Europe) (En,De,Es)" - rom ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,De,Es).gba" size 4194304 crc 506780D1 md5 53E67F535C69E7C95B696ABFE1CE1A2B sha1 B089A9E3690B982FE305CD58CAAD78C662FA93CE ) + rom ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,De,Es).gba" size 4194304 crc 506780d1 sha1 B089A9E3690B982FE305CD58CAAD78C662FA93CE ) ) game ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,Fr,Nl)" description "Danny Phantom - The Ultimate Enemy (Europe) (En,Fr,Nl)" - rom ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,Fr,Nl).gba" size 4194304 crc E1DE905F md5 8FA0CA30575846480A1BBA06DCFD6508 sha1 AE95EDAB3EDA11409B0646E7E03C5166E6E76002 ) + rom ( name "Danny Phantom - The Ultimate Enemy (Europe) (En,Fr,Nl).gba" size 4194304 crc e1de905f sha1 AE95EDAB3EDA11409B0646E7E03C5166E6E76002 ) ) game ( name "Danny Phantom - Urban Jungle (USA)" description "Danny Phantom - Urban Jungle (USA)" - rom ( name "Danny Phantom - Urban Jungle (USA).gba" size 4194304 crc C22E7A2F md5 022CC7CCC60272A2B773071AD448BBA9 sha1 BEFAA0CD61653791BEB9E2D6159AA2A8B0369D60 flags verified ) + rom ( name "Danny Phantom - Urban Jungle (USA).gba" size 4194304 crc c22e7a2f sha1 BEFAA0CD61653791BEB9E2D6159AA2A8B0369D60 flags verified ) ) game ( name "Daredevil (USA, Europe)" description "Daredevil (USA, Europe)" - rom ( name "Daredevil (USA, Europe).gba" size 4194304 crc D438347E md5 AB9F346110D5B97AFA4E3E10347D1000 sha1 DB2BB397B47F1FF247DAD5CFA6E35866B1048A7B flags verified ) + rom ( name "Daredevil (USA, Europe).gba" size 4194304 crc d438347e sha1 DB2BB397B47F1FF247DAD5CFA6E35866B1048A7B flags verified ) ) game ( name "Daredevil (Germany)" description "Daredevil (Germany)" - rom ( name "Daredevil (Germany).gba" size 4194304 crc 4BB9420E md5 407870E802A39EF43D96E1B211BC6936 sha1 2158B70DFDD1D04EE8522E7277DC43C3B2DB56FC ) + rom ( name "Daredevil (Germany).gba" size 4194304 crc 4bb9420e sha1 2158B70DFDD1D04EE8522E7277DC43C3B2DB56FC ) ) game ( name "Daredevil (Europe) (En,Fr,Es,It)" description "Daredevil (Europe) (En,Fr,Es,It)" - rom ( name "Daredevil (Europe) (En,Fr,Es,It).gba" size 4194304 crc 41A9B849 md5 F8D9503C529E3608ED4D91FC7315DEB3 sha1 0445B1D035B287023A94C45D1D77BC091F874ACB ) + rom ( name "Daredevil (Europe) (En,Fr,Es,It).gba" size 4194304 crc 41a9b849 sha1 0445B1D035B287023A94C45D1D77BC091F874ACB ) ) game ( name "Darius R (Japan) (En)" description "Darius R (Japan) (En)" - rom ( name "Darius R (Japan) (En).gba" size 4194304 crc 51BEEED7 md5 10860572E5479BBAA1E790D1FA027207 sha1 EEAF2CB1CBC8E9B447FF37429EF7F08A2D6559F7 flags verified ) + rom ( name "Darius R (Japan) (En).gba" size 4194304 crc 51beeed7 sha1 EEAF2CB1CBC8E9B447FF37429EF7F08A2D6559F7 flags verified ) ) game ( name "Dark Arena (USA, Europe)" description "Dark Arena (USA, Europe)" - rom ( name "Dark Arena (USA, Europe).gba" size 8388608 crc DE5DCDEE md5 E86C23F445B069B1A0BC27DDA5F638B8 sha1 7D7C2F47AFFEF4B69094536497A9A28DB7F347BB flags verified ) + rom ( name "Dark Arena (USA, Europe).gba" size 8388608 crc de5dcdee sha1 7D7C2F47AFFEF4B69094536497A9A28DB7F347BB flags verified ) +) + +game ( + name "Dark Empire (Japan) (Proto)" + description "Dark Empire (Japan) (Proto)" + rom ( name "Dark Empire (Japan) (Proto).gba" size 8388608 crc dd393a80 sha1 CF09AE073EC92C31A7EF5A483E3A3F27105D8A75 flags verified ) ) game ( name "Dave Mirra Freestyle BMX 2 (USA)" description "Dave Mirra Freestyle BMX 2 (USA)" - rom ( name "Dave Mirra Freestyle BMX 2 (USA).gba" size 8388608 crc 64B1E921 md5 87FAEACBFE02C12D1FA89B41EF1D676E sha1 3B86100FCE6FDA95B46C0D9E02D08052E69C2C2C ) + rom ( name "Dave Mirra Freestyle BMX 2 (USA).gba" size 8388608 crc 64b1e921 sha1 3B86100FCE6FDA95B46C0D9E02D08052E69C2C2C ) ) game ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It)" description "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 69E89581 md5 DC5F5D4A85FEE39DC0A6EBD59CD566E7 sha1 5D98B5179F4E9AE7AE72D6A43BED5F046F881A7B flags verified ) + rom ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 69e89581 sha1 5D98B5179F4E9AE7AE72D6A43BED5F046F881A7B flags verified ) ) game ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It) (Rev 1)" description "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 8388608 crc 8E39FEE9 md5 B5AAA0329D150452520AA0DEC5599AAD sha1 4C3A3ECBA81F7A7DF5A05D294BBE796109DD5D4D ) + rom ( name "Dave Mirra Freestyle BMX 2 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 8388608 crc 8e39fee9 sha1 4C3A3ECBA81F7A7DF5A05D294BBE796109DD5D4D flags verified ) ) game ( name "Dave Mirra Freestyle BMX 3 (USA, Europe)" description "Dave Mirra Freestyle BMX 3 (USA, Europe)" - rom ( name "Dave Mirra Freestyle BMX 3 (USA, Europe).gba" size 8388608 crc 8D8F26A5 md5 BCE3926504E6FBC983463AA238EE5FAF sha1 DCCE47B536ACE90A918D94D06698C92538D7E4D1 flags verified ) + rom ( name "Dave Mirra Freestyle BMX 3 (USA, Europe).gba" size 8388608 crc 8d8f26a5 sha1 DCCE47B536ACE90A918D94D06698C92538D7E4D1 flags verified ) ) game ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It)" description "David Beckham Soccer (Europe) (En,Fr,De,Es,It)" - rom ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E9A34F49 md5 121FD8E5E64FF91DB0E14EA991DE4625 sha1 969B0E330ADAF91C37707ED41E4FDB00101D8DBE ) + rom ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e9a34f49 sha1 969B0E330ADAF91C37707ED41E4FDB00101D8DBE flags verified ) ) game ( name "David Beckham Soccer (USA) (En,Es)" description "David Beckham Soccer (USA) (En,Es)" - rom ( name "David Beckham Soccer (USA) (En,Es).gba" size 4194304 crc 7E4DB1CC md5 9AF9F7652DFBD45D06B50A6925EE18F6 sha1 98E58464F852958E0CCAF7250FE8FB8990B84B3C ) + rom ( name "David Beckham Soccer (USA) (En,Es).gba" size 4194304 crc 7e4db1cc sha1 98E58464F852958E0CCAF7250FE8FB8990B84B3C ) ) game ( name "Davis Cup (Europe) (En,Fr,De,Es,It)" description "Davis Cup (Europe) (En,Fr,De,Es,It)" - rom ( name "Davis Cup (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4C7375F4 md5 A7050CB081978C01421677D386933512 sha1 FB8F72D6F6130D54398442A2D1D6B7F1E1829902 flags verified ) + rom ( name "Davis Cup (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4c7375f4 sha1 FB8F72D6F6130D54398442A2D1D6B7F1E1829902 flags verified ) ) game ( name "Davis Cup (USA) (En,Fr,De,Es,It)" description "Davis Cup (USA) (En,Fr,De,Es,It)" - rom ( name "Davis Cup (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 82B4D89C md5 C66C7460875F2D6A42BD441DD8ED1F56 sha1 AA56F0F712D8DE0A2CE32ED22470F7BE1BE19EC9 ) + rom ( name "Davis Cup (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 82b4d89c sha1 AA56F0F712D8DE0A2CE32ED22470F7BE1BE19EC9 ) ) game ( name "Dead to Rights (USA)" description "Dead to Rights (USA)" - rom ( name "Dead to Rights (USA).gba" size 8388608 crc 52C1826C md5 F22CA50C999FDDB4FEEF6BCB32B9D94A sha1 2E6E240BB80597F081550EB5E0478E3443CD685C ) + rom ( name "Dead to Rights (USA).gba" size 8388608 crc 52c1826c sha1 2E6E240BB80597F081550EB5E0478E3443CD685C ) ) game ( name "Dead to Rights (Europe) (En,Fr,De,Es,It)" description "Dead to Rights (Europe) (En,Fr,De,Es,It)" - rom ( name "Dead to Rights (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2994DE1D md5 01356207595154E92EFA8B97B6E48ACD sha1 0291AA7A98DFE24907D763CE860178CF3B9C6EBE ) + rom ( name "Dead to Rights (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2994de1d sha1 0291AA7A98DFE24907D763CE860178CF3B9C6EBE ) ) game ( name "Deadly Skies (Europe) (En,Ja,Fr,De)" description "Deadly Skies (Europe) (En,Ja,Fr,De)" - rom ( name "Deadly Skies (Europe) (En,Ja,Fr,De).gba" size 4194304 crc FE7C8402 md5 3DB6FE46ECC0F553EE9BCF9ED3EADB10 sha1 44CF348A7F6229D0063411F7EFA9411DAC2EB26C ) + rom ( name "Deadly Skies (Europe) (En,Ja,Fr,De).gba" size 4194304 crc fe7c8402 sha1 44CF348A7F6229D0063411F7EFA9411DAC2EB26C ) ) game ( name "Deal or No Deal (USA)" description "Deal or No Deal (USA)" - rom ( name "Deal or No Deal (USA).gba" size 4194304 crc B6C00EDB md5 7618D824C146A521ECAAD69D4B8443EA sha1 3691000350DB3B36311439C5D9C9879EE756FEA6 ) + rom ( name "Deal or No Deal (USA).gba" size 4194304 crc b6c00edb sha1 3691000350DB3B36311439C5D9C9879EE756FEA6 ) ) game ( name "Defender (USA)" description "Defender (USA)" - rom ( name "Defender (USA).gba" size 4194304 crc 2E271C13 md5 3ECB36C34B0A441BAD7A628760575E0C sha1 D9BC7D7A0500C7CF58CE4010071048A6C462B2DE ) + rom ( name "Defender (USA).gba" size 4194304 crc 2e271c13 sha1 D9BC7D7A0500C7CF58CE4010071048A6C462B2DE ) ) game ( name "Defender - For All Mankind (Europe) (En,Fr,De,Es,It)" description "Defender - For All Mankind (Europe) (En,Fr,De,Es,It)" - rom ( name "Defender - For All Mankind (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3B86FDC4 md5 60BEEFDE1C43E81C95CC30C20D1E85C0 sha1 4D45E4109AADE339514FDD3AD826CE8CD4CFB5E7 ) + rom ( name "Defender - For All Mankind (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3b86fdc4 sha1 4D45E4109AADE339514FDD3AD826CE8CD4CFB5E7 flags verified ) ) game ( name "Defender of the Crown (USA)" description "Defender of the Crown (USA)" - rom ( name "Defender of the Crown (USA).gba" size 4194304 crc DE6698FE md5 7BA10BEC1582DC62D0A1AC742AF9AB7B sha1 EFBEA6DFA027A578E4F9878768A82C9BD7F2C31C ) + rom ( name "Defender of the Crown (USA).gba" size 4194304 crc de6698fe sha1 EFBEA6DFA027A578E4F9878768A82C9BD7F2C31C ) ) game ( name "Defender of the Crown (Europe)" description "Defender of the Crown (Europe)" - rom ( name "Defender of the Crown (Europe).gba" size 4194304 crc 6968959A md5 A6FE988A31724789A21BAE6B65CD79B2 sha1 4E37071533E946EFD4166EFC409562CC21AF83D2 ) + rom ( name "Defender of the Crown (Europe).gba" size 4194304 crc 6968959a sha1 4E37071533E946EFD4166EFC409562CC21AF83D2 ) ) game ( name "DemiKids - Dark Version (USA)" description "DemiKids - Dark Version (USA)" - rom ( name "DemiKids - Dark Version (USA).gba" size 8388608 crc 1BAB58BD md5 4A28DAA8F0C619AD90CA97B3B941353D sha1 F3DBC8C6D58C33B88C28306F54FF742DA1C8D6C9 ) + rom ( name "DemiKids - Dark Version (USA).gba" size 8388608 crc 1bab58bd sha1 F3DBC8C6D58C33B88C28306F54FF742DA1C8D6C9 ) ) game ( name "DemiKids - Light Version (USA)" description "DemiKids - Light Version (USA)" - rom ( name "DemiKids - Light Version (USA).gba" size 8388608 crc DC4357C4 md5 F87A7DC67415D1F4C16CC430FCF98D9D sha1 8BC80EB5F08BFA83597483390B18092D9A12700D ) -) - -game ( - name "Demon Driver - Time to Burn Rubber! (USA)" - description "Demon Driver - Time to Burn Rubber! (USA)" - rom ( name "Demon Driver - Time to Burn Rubber! (USA).gba" size 4194304 crc 9374AF5E md5 6129C86F94B5C7ED3C725CF2AF593E56 sha1 9DFE428843A22363AD8CC8EA0F818E439EF62F39 ) + rom ( name "DemiKids - Light Version (USA).gba" size 8388608 crc dc4357c4 sha1 8BC80EB5F08BFA83597483390B18092D9A12700D flags verified ) ) game ( name "Demon Driver - Time to Burn Rubber! (Europe)" description "Demon Driver - Time to Burn Rubber! (Europe)" - rom ( name "Demon Driver - Time to Burn Rubber! (Europe).gba" size 4194304 crc 1CC36766 md5 0DA9790131EB40950B8CEA5E84F38953 sha1 0BC7E430BD87281293D1F4C5919EF77F2DA47EF6 ) + rom ( name "Demon Driver - Time to Burn Rubber! (Europe).gba" size 4194304 crc 1cc36766 sha1 0BC7E430BD87281293D1F4C5919EF77F2DA47EF6 ) +) + +game ( + name "Demon Driver - Time to Burn Rubber! (USA)" + description "Demon Driver - Time to Burn Rubber! (USA)" + rom ( name "Demon Driver - Time to Burn Rubber! (USA).gba" size 4194304 crc 9374af5e sha1 9DFE428843A22363AD8CC8EA0F818E439EF62F39 ) ) game ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It)" description "Denki Blocks! (Europe) (En,Fr,De,Es,It)" - rom ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6144EC15 md5 2AE643E7A49F5044CDC9413D86B8D538 sha1 FE9047DD7940E55A9D667824AEEEB7ABBD025E59 flags verified ) + rom ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6144ec15 sha1 FE9047DD7940E55A9D667824AEEEB7ABBD025E59 flags verified ) ) game ( name "Denki Blocks! (Japan)" description "Denki Blocks! (Japan)" - rom ( name "Denki Blocks! (Japan).gba" size 4194304 crc 0053FD6A md5 B152F47BF277560ECC1054AE8981A775 sha1 F82C881D47EC3FFC98966A2C083A85241A7A3E29 ) + rom ( name "Denki Blocks! (Japan).gba" size 4194304 crc 0053fd6a sha1 F82C881D47EC3FFC98966A2C083A85241A7A3E29 ) ) game ( name "Denki Blocks! (USA) (En,Es)" description "Denki Blocks! (USA) (En,Es)" - rom ( name "Denki Blocks! (USA) (En,Es).gba" size 4194304 crc E064107F md5 8B7A6C21E2619DBFB5064C76D074F582 sha1 4ED60EA5A72E44B0014A4DB1553FD5DAF1F6339D ) + rom ( name "Denki Blocks! (USA) (En,Es).gba" size 4194304 crc e064107f sha1 4ED60EA5A72E44B0014A4DB1553FD5DAF1F6339D ) ) game ( name "Densetsu no Stafy (Japan)" description "Densetsu no Stafy (Japan)" - rom ( name "Densetsu no Stafy (Japan).gba" size 8388608 crc FAE94C8B md5 06ED08799B2F163076FE9FC0CFE65A4C sha1 75F6297F42C41E2A6D108DE9A372308AD2DF6A9C flags verified ) + rom ( name "Densetsu no Stafy (Japan).gba" size 8388608 crc fae94c8b sha1 75F6297F42C41E2A6D108DE9A372308AD2DF6A9C flags verified ) ) game ( name "Densetsu no Stafy 2 (Japan)" description "Densetsu no Stafy 2 (Japan)" - rom ( name "Densetsu no Stafy 2 (Japan).gba" size 16777216 crc EA73EB54 md5 0635251B85657F9C1DE295546DA09AEB sha1 8322867CC4369307048DEB20A8BB16C3DD0910DF flags verified ) + rom ( name "Densetsu no Stafy 2 (Japan).gba" size 16777216 crc ea73eb54 sha1 8322867CC4369307048DEB20A8BB16C3DD0910DF flags verified ) ) game ( name "Densetsu no Stafy 3 (Japan)" description "Densetsu no Stafy 3 (Japan)" - rom ( name "Densetsu no Stafy 3 (Japan).gba" size 16777216 crc FCAF1AA8 md5 A9A2F5D60EA44E08901ABDFE69F2438A sha1 A7A742E779D314F6909F1350DB2DA8A63445C433 flags verified ) + rom ( name "Densetsu no Stafy 3 (Japan).gba" size 16777216 crc fcaf1aa8 sha1 A7A742E779D314F6909F1350DB2DA8A63445C433 flags verified ) ) game ( name "Densetsu no Stafy 3 (Japan) (Rev 1)" description "Densetsu no Stafy 3 (Japan) (Rev 1)" - rom ( name "Densetsu no Stafy 3 (Japan) (Rev 1).gba" size 16777216 crc 2D6E4C3B md5 EE4FBCEC249A68B796BE491F56FFE03D sha1 DAE5354BFE4CCAFC92D22B1389265DBF1F79B636 ) + rom ( name "Densetsu no Stafy 3 (Japan) (Rev 1).gba" size 16777216 crc 2d6e4c3b sha1 DAE5354BFE4CCAFC92D22B1389265DBF1F79B636 flags verified ) ) game ( name "Derby Stallion Advance (Japan)" description "Derby Stallion Advance (Japan)" - rom ( name "Derby Stallion Advance (Japan).gba" size 4194304 crc 9746EF12 md5 88BBE65DA38EDA5082175FA13F092311 sha1 D884A3466A39B2285ED3E494986BD59CA887F9C4 ) + rom ( name "Derby Stallion Advance (Japan).gba" size 4194304 crc 9746ef12 sha1 D884A3466A39B2285ED3E494986BD59CA887F9C4 ) ) game ( name "Desert Strike Advance (USA)" description "Desert Strike Advance (USA)" - rom ( name "Desert Strike Advance (USA).gba" size 4194304 crc CC1C1405 md5 171E7BDF6B194CC9AE301F5424714A1A sha1 9FD7E323CFA2EEBF5B01467DED6C96A0A2219BDF ) + rom ( name "Desert Strike Advance (USA).gba" size 4194304 crc cc1c1405 sha1 9FD7E323CFA2EEBF5B01467DED6C96A0A2219BDF ) ) game ( name "Deutschland Sucht den Superstar (Germany)" description "Deutschland Sucht den Superstar (Germany)" - rom ( name "Deutschland Sucht den Superstar (Germany).gba" size 16777216 crc 51F50F7D md5 1995BFB86365486C6568AAA86B2330C0 sha1 CE5253E82671569500AF3D5DF9D3131916FBE23D flags verified ) + rom ( name "Deutschland Sucht den Superstar (Germany).gba" size 16777216 crc 51f50f7d sha1 CE5253E82671569500AF3D5DF9D3131916FBE23D flags verified ) ) game ( name "Dexter's Laboratory - Chess Challenge (USA)" description "Dexter's Laboratory - Chess Challenge (USA)" - rom ( name "Dexter's Laboratory - Chess Challenge (USA).gba" size 8388608 crc AE61322E md5 DA1471E76473766F201EAD7C9C9E3595 sha1 A6725F72BBC29C270322EAB0D8043F7C16E1C96D ) + rom ( name "Dexter's Laboratory - Chess Challenge (USA).gba" size 8388608 crc ae61322e sha1 A6725F72BBC29C270322EAB0D8043F7C16E1C96D ) ) game ( name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" description "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es)" - rom ( name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es).gba" size 8388608 crc F5436F5D md5 2A0D1BB21640A97228F334853B0289C3 sha1 E04DBB5E0534CF241E8FEE85D17B1CC8A0032F14 ) -) - -game ( - name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" - description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 6BF168E6 md5 C4E93A88CA2A79A051D8A93F2B879A46 sha1 B838B5BB37BFEB3315A68B6D372F29A5DE635444 ) -) - -game ( - name "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It)" - description "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It)" - rom ( name "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3E8012BF md5 5E42D25EE9C5C16A7169F1C5A35B9451 sha1 9C34C6F69AF46FA977654C5A79141B96C9D273F6 flags verified ) + rom ( name "Dexter's Laboratory - Chess Challenge (Europe) (En,Fr,De,Es).gba" size 8388608 crc f5436f5d sha1 E04DBB5E0534CF241E8FEE85D17B1CC8A0032F14 ) ) game ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It)" - rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It).gba" size 4194304 crc E948D412 md5 8AA75EB2E94320C942E8C71CEDCEC97C sha1 F230375BA4B0346D749E50117FE701D8C1CBFFFA flags verified ) + rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e948d412 sha1 F230375BA4B0346D749E50117FE701D8C1CBFFFA flags verified ) +) + +game ( + name "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It)" + description "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It)" + rom ( name "Dexter's Laboratory - Deesaster Strikes! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3e8012bf sha1 9C34C6F69AF46FA977654C5A79141B96C9D273F6 flags verified ) +) + +game ( + name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" + description "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1)" + rom ( name "Dexter's Laboratory - Deesaster Strikes! (USA) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 6bf168e6 sha1 B838B5BB37BFEB3315A68B6D372F29A5DE635444 ) ) game ( name "Di Gi Charat - DigiCommunication (Japan)" description "Di Gi Charat - DigiCommunication (Japan)" - rom ( name "Di Gi Charat - DigiCommunication (Japan).gba" size 8388608 crc A1288427 md5 6427AD3BB3D1617276D2FD0737E2D9E7 sha1 35F9FA0305DE3382AA6FB01F14BAA9419FFA5349 ) + rom ( name "Di Gi Charat - DigiCommunication (Japan).gba" size 8388608 crc a1288427 sha1 35F9FA0305DE3382AA6FB01F14BAA9419FFA5349 flags verified ) ) game ( name "Diadroids World - Evil Teikoku no Yabou (Japan)" description "Diadroids World - Evil Teikoku no Yabou (Japan)" - rom ( name "Diadroids World - Evil Teikoku no Yabou (Japan).gba" size 8388608 crc A2D6CEA6 md5 B2436C0B6E02D17771B48CDCF24BEE66 sha1 4FC0E2240DDD11D4A1F9A80EAFF3B945C8F27C8A ) + rom ( name "Diadroids World - Evil Teikoku no Yabou (Japan).gba" size 8388608 crc a2d6cea6 sha1 4FC0E2240DDD11D4A1F9A80EAFF3B945C8F27C8A ) ) game ( - name "Diddy Kong Pilot (Unknown) (Proto)" - description "Diddy Kong Pilot (Unknown) (Proto)" - rom ( name "Diddy Kong Pilot (Unknown) (Proto).gba" size 12277472 crc 057DC388 md5 E56DA89876F44184900EE955D5864742 sha1 0CB385781742C25BF9D4CBEAE8E83F7750AF48DB ) + name "Diddy Kong Pilot (Unknown) (Proto) (2003)" + description "Diddy Kong Pilot (Unknown) (Proto) (2003)" + rom ( name "Diddy Kong Pilot (Unknown) (Proto) (2003).gba" size 12277472 crc 057dc388 sha1 0CB385781742C25BF9D4CBEAE8E83F7750AF48DB flags verified ) +) + +game ( + name "Diddy Kong Pilot (Unknown) (Proto) (2001)" + description "Diddy Kong Pilot (Unknown) (Proto) (2001)" + rom ( name "Diddy Kong Pilot (Unknown) (Proto) (2001).gba" size 7509167 crc 8903cc5f sha1 E14BFB4D63C6BD35C3A1A4AAD4EB91E94D0402B3 flags verified ) ) game ( name "DigiCommunication Nyo - Datou! Black Gemagema Dan (Japan)" description "DigiCommunication Nyo - Datou! Black Gemagema Dan (Japan)" - rom ( name "DigiCommunication Nyo - Datou! Black Gemagema Dan (Japan).gba" size 16777216 crc 1372E829 md5 C627E05CD3E6613EF772B92CC86ADA1C sha1 177A4D01A88A512CBC8DC5927B55999169359BBC ) -) - -game ( - name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" - description "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" - rom ( name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc EA5FC3DA md5 23A85707E6B7BB14D559F207824B2389 sha1 ECF0E597839905C9F23C6D568C79FC00C2719F49 ) + rom ( name "DigiCommunication Nyo - Datou! Black Gemagema Dan (Japan).gba" size 16777216 crc 1372e829 sha1 177A4D01A88A512CBC8DC5927B55999169359BBC ) ) game ( name "Digimon - Battle Spirit (USA)" description "Digimon - Battle Spirit (USA)" - rom ( name "Digimon - Battle Spirit (USA).gba" size 4194304 crc CEEF2008 md5 A4E3E4754C7BD16E5E2A52EE83AB2BE1 sha1 2BA954A54DD34B2B450D9EF718EB8A0F570B6549 ) + rom ( name "Digimon - Battle Spirit (USA).gba" size 4194304 crc ceef2008 sha1 2BA954A54DD34B2B450D9EF718EB8A0F570B6549 ) +) + +game ( + name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" + description "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It)" + rom ( name "Digimon - Battle Spirit (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ea5fc3da sha1 ECF0E597839905C9F23C6D568C79FC00C2719F49 flags verified ) ) game ( name "Digimon - Battle Spirit 2 (USA) (En,Fr,De,Es,It)" description "Digimon - Battle Spirit 2 (USA) (En,Fr,De,Es,It)" - rom ( name "Digimon - Battle Spirit 2 (USA) (En,Fr,De,Es,It).gba" size 4194304 crc C4C246EF md5 DB4A8ED843DFB471622F37A8EFB35111 sha1 B73352F15D23C09C0280BF1E732FEEBA8F0E6082 ) + rom ( name "Digimon - Battle Spirit 2 (USA) (En,Fr,De,Es,It).gba" size 4194304 crc c4c246ef sha1 B73352F15D23C09C0280BF1E732FEEBA8F0E6082 ) ) game ( name "Digimon - Battle Spirit 2 (Europe) (En,Fr,De,Es,It)" description "Digimon - Battle Spirit 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Digimon - Battle Spirit 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 00C906A3 md5 898914FE623432C8CF062764CAB39B9E sha1 83469A10E8828D9EE55F7F9BB3C970F7E4CEB149 ) + rom ( name "Digimon - Battle Spirit 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 00c906a3 sha1 83469A10E8828D9EE55F7F9BB3C970F7E4CEB149 ) ) game ( name "Digimon Racing (Japan)" description "Digimon Racing (Japan)" - rom ( name "Digimon Racing (Japan).gba" size 8388608 crc C50468A8 md5 BC1769F39636FCA6E05EFDF0B2431B35 sha1 F8C5729A75D1A76919F19AA867B26559650DD109 ) + rom ( name "Digimon Racing (Japan).gba" size 8388608 crc c50468a8 sha1 F8C5729A75D1A76919F19AA867B26559650DD109 ) ) game ( name "Digimon Racing (Europe) (En,Fr,De,Es,It)" description "Digimon Racing (Europe) (En,Fr,De,Es,It)" - rom ( name "Digimon Racing (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4F1B0157 md5 2AF323F1B5A498D3060B5B8FB94410ED sha1 39A54C21E881634C8587496DC36FD5BB871AD4EB ) + rom ( name "Digimon Racing (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4f1b0157 sha1 39A54C21E881634C8587496DC36FD5BB871AD4EB ) ) game ( name "Digimon Racing (USA) (En,Fr,De,Es,It)" description "Digimon Racing (USA) (En,Fr,De,Es,It)" - rom ( name "Digimon Racing (USA) (En,Fr,De,Es,It).gba" size 8388608 crc DADD4C10 md5 0B8E817C956BF56035C3A5C73174F81B sha1 37C0BC3C8FC1B79EFD18121FEC6F2DF97DDB3BDF ) + rom ( name "Digimon Racing (USA) (En,Fr,De,Es,It).gba" size 8388608 crc dadd4c10 sha1 37C0BC3C8FC1B79EFD18121FEC6F2DF97DDB3BDF ) ) game ( name "Dinotopia - The Timestone Pirates (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Dinotopia - The Timestone Pirates (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Dinotopia - The Timestone Pirates (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7BD01B31 md5 BAB43E61606514080129A179E931B2B6 sha1 939F52824D6598DE9C3CA5F1F33787E1EE01D442 ) + rom ( name "Dinotopia - The Timestone Pirates (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7bd01b31 sha1 939F52824D6598DE9C3CA5F1F33787E1EE01D442 ) ) game ( name "Disney Princesas (Spain)" description "Disney Princesas (Spain)" - rom ( name "Disney Princesas (Spain).gba" size 8388608 crc 425785C8 md5 282F4032DAEE65C2CBF421ECE93E4A41 sha1 39915BA54006C1BC47A711067A198A9FBC2AED8E ) + rom ( name "Disney Princesas (Spain).gba" size 8388608 crc 425785c8 sha1 39915BA54006C1BC47A711067A198A9FBC2AED8E ) ) game ( name "Disney Princess (USA, Europe)" description "Disney Princess (USA, Europe)" - rom ( name "Disney Princess (USA, Europe).gba" size 8388608 crc 4A2B9E0B md5 434AF1B315A2A337313AC82C3DE078FF sha1 FBB2D5C6A209074A92459EC4918A5213BFA0197D flags verified ) + rom ( name "Disney Princess (USA, Europe).gba" size 8388608 crc 4a2b9e0b sha1 FBB2D5C6A209074A92459EC4918A5213BFA0197D flags verified ) ) game ( name "Disney Princess - Royal Adventure (USA)" description "Disney Princess - Royal Adventure (USA)" - rom ( name "Disney Princess - Royal Adventure (USA).gba" size 8388608 crc C6AD2251 md5 76CDC3EC8B886F378EBC6DE368399220 sha1 A033A92EAB635C035444B2165FE04631AA3BB118 ) + rom ( name "Disney Princess - Royal Adventure (USA).gba" size 8388608 crc c6ad2251 sha1 A033A92EAB635C035444B2165FE04631AA3BB118 ) ) game ( name "Disney Princess - Royal Adventure (Europe) (En,Fr,De)" description "Disney Princess - Royal Adventure (Europe) (En,Fr,De)" - rom ( name "Disney Princess - Royal Adventure (Europe) (En,Fr,De).gba" size 8388608 crc 92C695CC md5 669FBBD100F67D864A2028BE1217719D sha1 A143CD7260AC39235A4CF223B9F76D9998F8B7C4 ) + rom ( name "Disney Princess - Royal Adventure (Europe) (En,Fr,De).gba" size 8388608 crc 92c695cc sha1 A143CD7260AC39235A4CF223B9F76D9998F8B7C4 flags verified ) ) game ( name "Disney Princesse (France)" description "Disney Princesse (France)" - rom ( name "Disney Princesse (France).gba" size 8388608 crc 3944BD7E md5 BBB91114B96A3B57BF40B15EDFC12187 sha1 B357F21432A55584779E84F200181D655EF3BA10 ) + rom ( name "Disney Princesse (France).gba" size 8388608 crc 3944bd7e sha1 B357F21432A55584779E84F200181D655EF3BA10 ) ) game ( name "Disney Principesse (Italy)" description "Disney Principesse (Italy)" - rom ( name "Disney Principesse (Italy).gba" size 8388608 crc 481E668E md5 1CD1D918E2730AC739BF2BCF14373382 sha1 FD2FFBDA8016543BCD90A231768791A3C3728CF7 ) + rom ( name "Disney Principesse (Italy).gba" size 8388608 crc 481e668e sha1 FD2FFBDA8016543BCD90A231768791A3C3728CF7 ) ) game ( name "Disney Sports - American Football (Japan)" description "Disney Sports - American Football (Japan)" - rom ( name "Disney Sports - American Football (Japan).gba" size 16777216 crc B92E9057 md5 E6985222B701BD435DDB0A30E7FC4FB9 sha1 6FF7ABA52A2728D19059A2B496928649F33BD73B ) + rom ( name "Disney Sports - American Football (Japan).gba" size 16777216 crc b92e9057 sha1 6FF7ABA52A2728D19059A2B496928649F33BD73B flags verified ) ) game ( name "Disney Sports - Basketball (USA)" description "Disney Sports - Basketball (USA)" - rom ( name "Disney Sports - Basketball (USA).gba" size 16777216 crc 80EC6CF0 md5 1C4467EFEB8C13831B8AD08D7E8F4908 sha1 8999364D93339017743AB280D22FDA6C61BE3F42 ) + rom ( name "Disney Sports - Basketball (USA).gba" size 16777216 crc 80ec6cf0 sha1 8999364D93339017743AB280D22FDA6C61BE3F42 ) ) game ( name "Disney Sports - Basketball (Japan)" description "Disney Sports - Basketball (Japan)" - rom ( name "Disney Sports - Basketball (Japan).gba" size 16777216 crc 3911B4B6 md5 1EF40E56D3EAB2501445BA73D26BF827 sha1 EEC333260CF38D0B9288A8F8CAFD6D2DB22C8CA6 ) + rom ( name "Disney Sports - Basketball (Japan).gba" size 16777216 crc 3911b4b6 sha1 EEC333260CF38D0B9288A8F8CAFD6D2DB22C8CA6 ) ) game ( name "Disney Sports - Basketball (Europe) (En,Fr,De,Es,It)" description "Disney Sports - Basketball (Europe) (En,Fr,De,Es,It)" - rom ( name "Disney Sports - Basketball (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc D6D89F81 md5 B52A72E07155057E21E6519472F5A2AA sha1 521411BEFD94287869D5FB58BC970C9ECF04EB21 ) + rom ( name "Disney Sports - Basketball (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc d6d89f81 sha1 521411BEFD94287869D5FB58BC970C9ECF04EB21 ) ) game ( name "Disney Sports - Football (USA)" description "Disney Sports - Football (USA)" - rom ( name "Disney Sports - Football (USA).gba" size 16777216 crc 01413DB1 md5 86F872EAFA573D4535E5F536AB7F5D2B sha1 C806B83F73DEFCE9FCF269B9023FC1CC6DBF356C ) + rom ( name "Disney Sports - Football (USA).gba" size 16777216 crc 01413db1 sha1 C806B83F73DEFCE9FCF269B9023FC1CC6DBF356C ) ) game ( name "Disney Sports - Football (Soccer) (Europe) (En,Fr,De,Es,It)" description "Disney Sports - Football (Soccer) (Europe) (En,Fr,De,Es,It)" - rom ( name "Disney Sports - Football (Soccer) (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 33F73199 md5 190634951B15D743AB39FB56D105C15B sha1 5D0698E4F0735B730EA78975DD5B2049931B622A ) + rom ( name "Disney Sports - Football (Soccer) (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 33f73199 sha1 5D0698E4F0735B730EA78975DD5B2049931B622A ) ) game ( name "Disney Sports - Motocross (USA)" description "Disney Sports - Motocross (USA)" - rom ( name "Disney Sports - Motocross (USA).gba" size 16777216 crc A771AD79 md5 D4C87FFEB5548C6CF7F6B392A24161FC sha1 30B3DA95577C14573C5A99193880E4FB6A4597D9 ) + rom ( name "Disney Sports - Motocross (USA).gba" size 16777216 crc a771ad79 sha1 30B3DA95577C14573C5A99193880E4FB6A4597D9 ) ) game ( name "Disney Sports - Motocross (Japan)" description "Disney Sports - Motocross (Japan)" - rom ( name "Disney Sports - Motocross (Japan).gba" size 16777216 crc 1A62D76F md5 172F722A84BD79496059745E3A148F7D sha1 28E29B10232C7DCACDD34B98B07B7535D93A0B57 ) + rom ( name "Disney Sports - Motocross (Japan).gba" size 16777216 crc 1a62d76f sha1 28E29B10232C7DCACDD34B98B07B7535D93A0B57 ) ) game ( name "Disney Sports - Motocross (Europe) (En,Fr,De,Es,It)" description "Disney Sports - Motocross (Europe) (En,Fr,De,Es,It)" - rom ( name "Disney Sports - Motocross (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 72DCB4F4 md5 5186E20734061DF457A430BBF963E5D9 sha1 93861A20E1E0EE756238DFBDC3E8EE8A633A4E70 ) + rom ( name "Disney Sports - Motocross (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 72dcb4f4 sha1 93861A20E1E0EE756238DFBDC3E8EE8A633A4E70 ) ) game ( name "Disney Sports - Skateboarding (Japan)" description "Disney Sports - Skateboarding (Japan)" - rom ( name "Disney Sports - Skateboarding (Japan).gba" size 16777216 crc 5DF4A476 md5 1739FF2B55B034C58AA1618A2E49D4E8 sha1 3EC93FAF0F1E9B9B848E6C3B2CACA486E0DAFCDF ) + rom ( name "Disney Sports - Skateboarding (Japan).gba" size 16777216 crc 5df4a476 sha1 3EC93FAF0F1E9B9B848E6C3B2CACA486E0DAFCDF ) ) game ( name "Disney Sports - Skateboarding (USA)" description "Disney Sports - Skateboarding (USA)" - rom ( name "Disney Sports - Skateboarding (USA).gba" size 16777216 crc 37FFD837 md5 2694632A5422D0C1553E298458798797 sha1 D8148C320229AFE460AE1277FB99EF6CA9F62EA0 ) + rom ( name "Disney Sports - Skateboarding (USA).gba" size 16777216 crc 37ffd837 sha1 D8148C320229AFE460AE1277FB99EF6CA9F62EA0 ) ) game ( name "Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It)" description "Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It)" - rom ( name "Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 10C05C7B md5 DEE39C7BCC84C236108AD7F36CF6DCC0 sha1 0D3CEB741D658275B775EDF7DB562A9FB5AAE98A ) + rom ( name "Disney Sports - Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 10c05c7b sha1 0D3CEB741D658275B775EDF7DB562A9FB5AAE98A ) ) game ( name "Disney Sports - Snowboarding (Europe) (En,Fr,De,Es,It)" description "Disney Sports - Snowboarding (Europe) (En,Fr,De,Es,It)" - rom ( name "Disney Sports - Snowboarding (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 77B7FCCE md5 5A20E35F872BCD5C4698B1AF8BFF7BD7 sha1 C7171637404A6EE61E77AC02E08AC08D2D443367 ) + rom ( name "Disney Sports - Snowboarding (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 77b7fcce sha1 C7171637404A6EE61E77AC02E08AC08D2D443367 ) ) game ( name "Disney Sports - Snowboarding (Japan)" description "Disney Sports - Snowboarding (Japan)" - rom ( name "Disney Sports - Snowboarding (Japan).gba" size 16777216 crc BDC23A47 md5 E473C37F4E450CEB42CF7D48556B55E7 sha1 3EEE23C92B6B3E5428C450806B54F155AC0B126B ) + rom ( name "Disney Sports - Snowboarding (Japan).gba" size 16777216 crc bdc23a47 sha1 3EEE23C92B6B3E5428C450806B54F155AC0B126B ) ) game ( name "Disney Sports - Snowboarding (USA)" description "Disney Sports - Snowboarding (USA)" - rom ( name "Disney Sports - Snowboarding (USA).gba" size 16777216 crc 4733693C md5 1529F4677CBA3E47F4BE897F02B71044 sha1 7E5CCF21F13E115A811DC19310390A9BEACFF07F ) + rom ( name "Disney Sports - Snowboarding (USA).gba" size 16777216 crc 4733693c sha1 7E5CCF21F13E115A811DC19310390A9BEACFF07F ) ) game ( name "Disney Sports - Soccer (Japan)" description "Disney Sports - Soccer (Japan)" - rom ( name "Disney Sports - Soccer (Japan).gba" size 16777216 crc 680957E7 md5 F71BB7305C4AA4FF83D83D949ADD1126 sha1 C673503B5D0FCCF72BAC845888280D7202D0E84C ) + rom ( name "Disney Sports - Soccer (Japan).gba" size 16777216 crc 680957e7 sha1 C673503B5D0FCCF72BAC845888280D7202D0E84C ) ) game ( name "Disney Sports - Soccer (USA)" description "Disney Sports - Soccer (USA)" - rom ( name "Disney Sports - Soccer (USA).gba" size 16777216 crc 2F1316D2 md5 496E1D4C049692F0ACE43EC3EEFC708E sha1 637E62E9173DAA1E8A022C60A995070079C6FE32 flags verified ) + rom ( name "Disney Sports - Soccer (USA).gba" size 16777216 crc 2f1316d2 sha1 637E62E9173DAA1E8A022C60A995070079C6FE32 flags verified ) ) game ( name "Disney's Game + TV Episode - Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" description "Disney's Game + TV Episode - Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" - rom ( name "Disney's Game + TV Episode - Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 33554432 crc 2706B300 md5 90F6A072681959F117B4901FEB5B2CB7 sha1 14A56541B7A4196600F7392269DB67FC1BEBBAFF ) + rom ( name "Disney's Game + TV Episode - Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 33554432 crc 2706b300 sha1 14A56541B7A4196600F7392269DB67FC1BEBBAFF ) ) game ( name "Disney's Party (USA, Europe) (En,Fr,De,Es,It)" description "Disney's Party (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Disney's Party (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6BB63774 md5 8DBD6BFDFF54F2FC0F1BBDE11706A803 sha1 D4AD55CD32017A853C85F6247935C75F9B8CB7BC ) + rom ( name "Disney's Party (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6bb63774 sha1 D4AD55CD32017A853C85F6247935C75F9B8CB7BC ) ) game ( name "Disneys Prinzessinnen (Germany)" description "Disneys Prinzessinnen (Germany)" - rom ( name "Disneys Prinzessinnen (Germany).gba" size 8388608 crc E21B4285 md5 F575C8C844AE2FFAD9ADC7F91C886D54 sha1 C2305D37F66444D4929CC2B600CEC45A915D32DC ) + rom ( name "Disneys Prinzessinnen (Germany).gba" size 8388608 crc e21b4285 sha1 C2305D37F66444D4929CC2B600CEC45A915D32DC ) ) game ( name "DK - King of Swing (Europe) (En,Fr,De,Es,It)" description "DK - King of Swing (Europe) (En,Fr,De,Es,It)" - rom ( name "DK - King of Swing (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc F93B73D9 md5 1D8B145985BB38F9DE77405C9F1FA60B sha1 80717DCDB1844F826DA116C9278DFD1386C92FC1 flags verified ) + rom ( name "DK - King of Swing (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc f93b73d9 sha1 80717DCDB1844F826DA116C9278DFD1386C92FC1 flags verified ) ) game ( - name "DK - King of Swing (USA, Australia)" - description "DK - King of Swing (USA, Australia)" - rom ( name "DK - King of Swing (USA, Australia).gba" size 8388608 crc D610B239 md5 054223E916F9A4F543812AE795145CB5 sha1 8F8B10B09D5169B097840DF36CCA5C67C216BEDA ) + name "DK - King of Swing (USA)" + description "DK - King of Swing (USA)" + rom ( name "DK - King of Swing (USA).gba" size 8388608 crc d610b239 sha1 8F8B10B09D5169B097840DF36CCA5C67C216BEDA ) ) game ( name "DK - King of Swing (USA) (Demo) (Kiosk)" description "DK - King of Swing (USA) (Demo) (Kiosk)" - rom ( name "DK - King of Swing (USA) (Demo) (Kiosk).gba" size 8388608 crc 049626D1 md5 90D814291CC18D1E9E07378C42D67C2D sha1 D704EA9311C6AC9773BB70181DE86BA0843583FD ) + rom ( name "DK - King of Swing (USA) (Demo) (Kiosk).gba" size 8388608 crc 049626d1 sha1 D704EA9311C6AC9773BB70181DE86BA0843583FD ) ) game ( name "Dogz (USA)" description "Dogz (USA)" - rom ( name "Dogz (USA).gba" size 8388608 crc 124F27C0 md5 3981044EBB25A3DB6B6F5DA9725E4F4E sha1 462F05C18534CB22FFFC65D47351A29F10A3F254 ) + rom ( name "Dogz (USA).gba" size 8388608 crc 124f27c0 sha1 462F05C18534CB22FFFC65D47351A29F10A3F254 ) ) game ( name "Dogz (Europe) (En,Fr,De,It)" description "Dogz (Europe) (En,Fr,De,It)" - rom ( name "Dogz (Europe) (En,Fr,De,It).gba" size 16777216 crc 2216FBD6 md5 D97380D2FC4230738BF6F6080C577B94 sha1 D4A3E4F1D5C29AA2F77A1D32BF70FEBA25FF1832 ) + rom ( name "Dogz (Europe) (En,Fr,De,It).gba" size 16777216 crc 2216fbd6 sha1 D4A3E4F1D5C29AA2F77A1D32BF70FEBA25FF1832 ) ) game ( name "Dogz (Europe)" description "Dogz (Europe)" - rom ( name "Dogz (Europe).gba" size 8388608 crc AA8DEA30 md5 75EC8B0B1BC187F559B3571A0F0DFA4D sha1 C76C28CBD39C31377F41D6FC7297080AD5690D0E ) + rom ( name "Dogz (Europe).gba" size 8388608 crc aa8dea30 sha1 C76C28CBD39C31377F41D6FC7297080AD5690D0E ) ) game ( name "Dogz (France)" description "Dogz (France)" - rom ( name "Dogz (France).gba" size 8388608 crc 10AC14F9 md5 2A04B5EAB350D2863809B3B516210D41 sha1 3959BA1C479C7894556F68DC7AC08541140D37C4 ) + rom ( name "Dogz (France).gba" size 8388608 crc 10ac14f9 sha1 3959BA1C479C7894556F68DC7AC08541140D37C4 ) ) game ( name "Dogz - Fashion (USA)" description "Dogz - Fashion (USA)" - rom ( name "Dogz - Fashion (USA).gba" size 8388608 crc 63BD3463 md5 6C4ADC19A909F934C7C01C4F889A12D9 sha1 2DB620FBC629E957E8B73DD169BF83950814FD51 ) + rom ( name "Dogz - Fashion (USA).gba" size 8388608 crc 63bd3463 sha1 2DB620FBC629E957E8B73DD169BF83950814FD51 ) ) game ( name "Dogz - Fashion (Europe)" description "Dogz - Fashion (Europe)" - rom ( name "Dogz - Fashion (Europe).gba" size 8388608 crc 5236473D md5 C3AD9A91E86B6195451FA0FCF695FB79 sha1 729099DD230581D86BDF86E91359D74B79FE862C flags verified ) + rom ( name "Dogz - Fashion (Europe).gba" size 8388608 crc 5236473d sha1 729099DD230581D86BDF86E91359D74B79FE862C flags verified ) ) game ( name "Dogz 2 (USA)" description "Dogz 2 (USA)" - rom ( name "Dogz 2 (USA).gba" size 16777216 crc 0E2ACA9E md5 60619052B2BFDE557F3B873FE29ECF21 sha1 BD12AAADFAC73E7FDE336C8B25ECE78447CC1D87 ) + rom ( name "Dogz 2 (USA).gba" size 16777216 crc 0e2aca9e sha1 BD12AAADFAC73E7FDE336C8B25ECE78447CC1D87 ) ) game ( name "Dogz 2 (Europe)" description "Dogz 2 (Europe)" - rom ( name "Dogz 2 (Europe).gba" size 16777216 crc 28163523 md5 FA99E7BE703B7F204C33AB8EA7A69E67 sha1 A1897F4719BEA1D3F6B6E68FAE752EED7E3DF021 ) + rom ( name "Dogz 2 (Europe).gba" size 16777216 crc 28163523 sha1 A1897F4719BEA1D3F6B6E68FAE752EED7E3DF021 ) ) game ( name "Dogz 2 (Europe) (En,Fr,De,It)" description "Dogz 2 (Europe) (En,Fr,De,It)" - rom ( name "Dogz 2 (Europe) (En,Fr,De,It).gba" size 16777216 crc 41CE1EED md5 839F44AEC4456B2BE03A1BDEC90AE7F7 sha1 D5A8887C0EA1DB4F447648E4FAECEAF07EC99493 ) + rom ( name "Dogz 2 (Europe) (En,Fr,De,It).gba" size 16777216 crc 41ce1eed sha1 D5A8887C0EA1DB4F447648E4FAECEAF07EC99493 ) ) game ( - name "Dokapon (USA)" - description "Dokapon (USA)" - rom ( name "Dokapon (USA).gba" size 8388608 crc 5617E407 md5 936A8172335FFC3391D182E909942D76 sha1 280F9E01A3CAEE74BC9FDE55E6326005DDBA5196 ) + name "Dogz 2 (USA) (Rev 1)" + description "Dogz 2 (USA) (Rev 1)" + rom ( name "Dogz 2 (USA) (Rev 1).gba" size 16777216 crc a0ebb191 sha1 FF2772E347212264D1A1C4D322A08685ADC1E6A7 flags verified ) ) game ( - name "Dokapon (Europe) (En,Fr,De)" - description "Dokapon (Europe) (En,Fr,De)" - rom ( name "Dokapon (Europe) (En,Fr,De).gba" size 8388608 crc 654DF50E md5 18317FA6E27EA0EA7509F1319BC0865C sha1 7D85EF1F0219CFE9010031FC8240053A0575BEEC flags verified ) + name "Dokapon - Monster Hunter (USA)" + description "Dokapon - Monster Hunter (USA)" + rom ( name "Dokapon - Monster Hunter (USA).gba" size 8388608 crc 5617e407 sha1 280F9E01A3CAEE74BC9FDE55E6326005DDBA5196 ) +) + +game ( + name "Dokapon - Monster Hunter! (Europe) (En,Fr,De)" + description "Dokapon - Monster Hunter! (Europe) (En,Fr,De)" + rom ( name "Dokapon - Monster Hunter! (Europe) (En,Fr,De).gba" size 8388608 crc 654df50e sha1 7D85EF1F0219CFE9010031FC8240053A0575BEEC flags verified ) ) game ( name "Dokapon Q - Monster Hunter! (Japan)" description "Dokapon Q - Monster Hunter! (Japan)" - rom ( name "Dokapon Q - Monster Hunter! (Japan).gba" size 8388608 crc 45B3EDC4 md5 1FA9862E396758EE4EB6923E5CE4F9BC sha1 84099BB38A979B30FE5DD8E663D52CCF6CFB89AA ) + rom ( name "Dokapon Q - Monster Hunter! (Japan).gba" size 8388608 crc 45b3edc4 sha1 84099BB38A979B30FE5DD8E663D52CCF6CFB89AA ) ) game ( name "Dokidoki Cooking Series 1 - Komugi-chan no Happy Cake (Japan)" description "Dokidoki Cooking Series 1 - Komugi-chan no Happy Cake (Japan)" - rom ( name "Dokidoki Cooking Series 1 - Komugi-chan no Happy Cake (Japan).gba" size 8388608 crc FE198026 md5 DB41F49AFFDAC264849A0F4245FE533C sha1 5633769B002ED9AE00B090EED1FF4D2AF80246A0 ) + rom ( name "Dokidoki Cooking Series 1 - Komugi-chan no Happy Cake (Japan).gba" size 8388608 crc fe198026 sha1 5633769B002ED9AE00B090EED1FF4D2AF80246A0 flags verified ) ) game ( name "Dokidoki Cooking Series 2 - Gourmet Kitchen - Suteki na Obentou (Japan)" description "Dokidoki Cooking Series 2 - Gourmet Kitchen - Suteki na Obentou (Japan)" - rom ( name "Dokidoki Cooking Series 2 - Gourmet Kitchen - Suteki na Obentou (Japan).gba" size 8388608 crc 08DFC956 md5 9E86774CC5246458CF3F32D64501F56C sha1 11DA3A8E99457787F1263FF3396CB85B083583F0 ) + rom ( name "Dokidoki Cooking Series 2 - Gourmet Kitchen - Suteki na Obentou (Japan).gba" size 8388608 crc 08dfc956 sha1 11DA3A8E99457787F1263FF3396CB85B083583F0 ) ) game ( name "Dokodemo Taikyoku - Yakuman Advance (Japan)" description "Dokodemo Taikyoku - Yakuman Advance (Japan)" - rom ( name "Dokodemo Taikyoku - Yakuman Advance (Japan).gba" size 8388608 crc C2424EDD md5 76DEAAAFE8CD89891C8FB2D4E1B5DEAF sha1 5C3924D428EE9553A81E88D33BCADAF56A0BB8A6 ) + rom ( name "Dokodemo Taikyoku - Yakuman Advance (Japan).gba" size 8388608 crc c2424edd sha1 5C3924D428EE9553A81E88D33BCADAF56A0BB8A6 ) ) game ( name "Dokodemo Taikyoku - Yakuman Advance (Japan) (Rev 1)" description "Dokodemo Taikyoku - Yakuman Advance (Japan) (Rev 1)" - rom ( name "Dokodemo Taikyoku - Yakuman Advance (Japan) (Rev 1).gba" size 8388608 crc A7279ED5 md5 790E80AB14B2BFBA6E4B18954F5AC5D6 sha1 C02A52DE3714F61913D7444857250101B6F9C329 ) + rom ( name "Dokodemo Taikyoku - Yakuman Advance (Japan) (Rev 1).gba" size 8388608 crc a7279ed5 sha1 C02A52DE3714F61913D7444857250101B6F9C329 flags verified ) ) game ( name "Domo-kun no Fushigi Television (Japan)" description "Domo-kun no Fushigi Television (Japan)" - rom ( name "Domo-kun no Fushigi Television (Japan).gba" size 8388608 crc E743C611 md5 2151C4D48BE4C45F54A2A7365E4293EB sha1 C5C70840C6222C52A2E814D106AB1F2478CD5CAB ) + rom ( name "Domo-kun no Fushigi Television (Japan).gba" size 8388608 crc e743c611 sha1 C5C70840C6222C52A2E814D106AB1F2478CD5CAB ) ) game ( name "Donald Duck Advance (Europe) (En,Fr,De,Es,It)" description "Donald Duck Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Donald Duck Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4C086A5E md5 028807EA1E01C6645D38E228F6915A31 sha1 25D775890227EBC5AB6FD867EE81C02BA716E50E ) + rom ( name "Donald Duck Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4c086a5e sha1 25D775890227EBC5AB6FD867EE81C02BA716E50E flags verified ) ) game ( name "Donald Duck Advance (Japan)" description "Donald Duck Advance (Japan)" - rom ( name "Donald Duck Advance (Japan).gba" size 8388608 crc 0195DE8F md5 6300AC165DCA85A863C5346B8A23EDE1 sha1 40B8F2C6BA5F2F4EC94B0768DC8AA3906569413C ) + rom ( name "Donald Duck Advance (Japan).gba" size 8388608 crc 0195de8f sha1 40B8F2C6BA5F2F4EC94B0768DC8AA3906569413C ) ) game ( name "Donald Duck Advance (USA)" description "Donald Duck Advance (USA)" - rom ( name "Donald Duck Advance (USA).gba" size 8388608 crc 936DAAB2 md5 8384AA8735B5A036FDDDB5DA430CB25B sha1 020081AD9DDA023ADF604B790DDFC95FCF2A7835 ) + rom ( name "Donald Duck Advance (USA).gba" size 8388608 crc 936daab2 sha1 020081AD9DDA023ADF604B790DDFC95FCF2A7835 ) ) game ( - name "Donchan Puzzle Hanabi de Dohn Advance (Japan)" - description "Donchan Puzzle Hanabi de Dohn Advance (Japan)" - rom ( name "Donchan Puzzle Hanabi de Dohn Advance (Japan).gba" size 8388608 crc 500922E8 md5 D00363A1B7CD2A61A11732117DF24166 sha1 5598E6143DD0DAB1793507317624973557F35568 ) -) - -game ( - name "Donkey Kong Country (USA)" - description "Donkey Kong Country (USA)" - rom ( name "Donkey Kong Country (USA).gba" size 8388608 crc 12F7A968 md5 B3806462180CDA73D1F8F48D72236394 sha1 FCC62356A3B7157CA7DDA1398C9BF1AF1DD31265 ) + name "Donchan Puzzle - Hanabi de Dohn! Advance (Japan)" + description "Donchan Puzzle - Hanabi de Dohn! Advance (Japan)" + rom ( name "Donchan Puzzle - Hanabi de Dohn! Advance (Japan).gba" size 8388608 crc 500922e8 sha1 5598E6143DD0DAB1793507317624973557F35568 ) ) game ( name "Donkey Kong Country (Europe) (En,Fr,De,Es,It)" description "Donkey Kong Country (Europe) (En,Fr,De,Es,It)" - rom ( name "Donkey Kong Country (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 41D277FE md5 C1FB9BADF816B6D7836F4990F8119815 sha1 8995F0BE99A9CFF66474A8975B8499BD69FB4C45 flags verified ) + rom ( name "Donkey Kong Country (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 41d277fe sha1 8995F0BE99A9CFF66474A8975B8499BD69FB4C45 flags verified ) +) + +game ( + name "Donkey Kong Country (USA)" + description "Donkey Kong Country (USA)" + rom ( name "Donkey Kong Country (USA).gba" size 8388608 crc 12f7a968 sha1 FCC62356A3B7157CA7DDA1398C9BF1AF1DD31265 flags verified ) ) game ( name "Donkey Kong Country 2 (Europe) (En,Fr,De,Es,It)" description "Donkey Kong Country 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Donkey Kong Country 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc AEF11223 md5 86A1C5AAE8AFE04ACAF1AE475249E9BA sha1 2243E9B8C299744E351BDD9E28BC2212F0840782 flags verified ) + rom ( name "Donkey Kong Country 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc aef11223 sha1 2243E9B8C299744E351BDD9E28BC2212F0840782 flags verified ) ) game ( - name "Donkey Kong Country 2 (USA, Australia)" - description "Donkey Kong Country 2 (USA, Australia)" - rom ( name "Donkey Kong Country 2 (USA, Australia).gba" size 8388608 crc 11417FC1 md5 A1F160EE30ED36EDEA341A6F1C6A4EFC sha1 B0A4D59447C8D7C321BEA4DC7253B0F581129EDE ) + name "Donkey Kong Country 2 (USA)" + description "Donkey Kong Country 2 (USA)" + rom ( name "Donkey Kong Country 2 (USA).gba" size 8388608 crc 11417fc1 sha1 B0A4D59447C8D7C321BEA4DC7253B0F581129EDE flags verified ) ) game ( name "Donkey Kong Country 3 (Europe) (En,Fr,De,Es,It)" description "Donkey Kong Country 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "Donkey Kong Country 3 (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 708A6168 md5 D7F41D490BCB72F0711B070DE85A8C8B sha1 AA4EAF41D1339451AE42EF99D0C931FE624BD6FA flags verified ) + rom ( name "Donkey Kong Country 3 (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 708a6168 sha1 AA4EAF41D1339451AE42EF99D0C931FE624BD6FA flags verified ) ) game ( - name "Donkey Kong Country 3 (USA, Australia)" - description "Donkey Kong Country 3 (USA, Australia)" - rom ( name "Donkey Kong Country 3 (USA, Australia).gba" size 16777216 crc FE03E5AF md5 F577A97D679E669F8063910EB060E864 sha1 C50982B4C26E25BA3538BE97B585D95737D7ADE7 ) + name "Donkey Kong Country 3 (USA)" + description "Donkey Kong Country 3 (USA)" + rom ( name "Donkey Kong Country 3 (USA).gba" size 16777216 crc fe03e5af sha1 C50982B4C26E25BA3538BE97B585D95737D7ADE7 flags verified ) ) game ( name "Doom (USA, Europe)" description "Doom (USA, Europe)" - rom ( name "Doom (USA, Europe).gba" size 8388608 crc 58C641B3 md5 A4078F38DBB47AB22A9C74B725F3E481 sha1 AF2B2206777651C7993C1AE9008D07C31430207E flags verified ) + rom ( name "Doom (USA, Europe).gba" size 8388608 crc 58c641b3 sha1 AF2B2206777651C7993C1AE9008D07C31430207E flags verified ) ) game ( name "Doom II (USA)" description "Doom II (USA)" - rom ( name "Doom II (USA).gba" size 16777216 crc C885D9E9 md5 EFEFEE9082A83FC6E49F87510746EAC0 sha1 2FEEFFC96386CF2CC0B2076928B010F18E9E9748 flags verified ) + rom ( name "Doom II (USA).gba" size 16777216 crc c885d9e9 sha1 2FEEFFC96386CF2CC0B2076928B010F18E9E9748 flags verified ) ) game ( name "Doom II (Europe)" description "Doom II (Europe)" - rom ( name "Doom II (Europe).gba" size 16777216 crc 60CD3207 md5 3DF76EB314F21144D2D68758C11DEA5F sha1 38C7BAFDC2E6D7B9700385C01FBEF6B6888E4A33 ) + rom ( name "Doom II (Europe).gba" size 16777216 crc 60cd3207 sha1 38C7BAFDC2E6D7B9700385C01FBEF6B6888E4A33 flags verified ) ) game ( name "Dora the Explorer - Dora's World Adventure! (USA)" description "Dora the Explorer - Dora's World Adventure! (USA)" - rom ( name "Dora the Explorer - Dora's World Adventure! (USA).gba" size 4194304 crc 7B311C5C md5 81DF4456E398F87E893C522810CC8CDA sha1 BB071A3AAA24FA904EA01DE13931A3E2A0A8B5A5 ) + rom ( name "Dora the Explorer - Dora's World Adventure! (USA).gba" size 4194304 crc 7b311c5c sha1 BB071A3AAA24FA904EA01DE13931A3E2A0A8B5A5 ) ) game ( name "Dora the Explorer - Super Spies (USA)" description "Dora the Explorer - Super Spies (USA)" - rom ( name "Dora the Explorer - Super Spies (USA).gba" size 4194304 crc 650FDFDB md5 1975EDA7D93CDB6D0828533DD34A05A7 sha1 FA51E2102CE0A0E70C5DB2F8776D2237C8D7DB7D ) + rom ( name "Dora the Explorer - Super Spies (USA).gba" size 4194304 crc 650fdfdb sha1 FA51E2102CE0A0E70C5DB2F8776D2237C8D7DB7D ) ) game ( name "Dora the Explorer - Super Star Adventures! (USA)" description "Dora the Explorer - Super Star Adventures! (USA)" - rom ( name "Dora the Explorer - Super Star Adventures! (USA).gba" size 4194304 crc 2CEE050F md5 AEE29C76808D8DEBCFB3B7945270861B sha1 0423A5D577CB0AE2674FF16FC83104E9240AA60E ) + rom ( name "Dora the Explorer - Super Star Adventures! (USA).gba" size 4194304 crc 2cee050f sha1 0423A5D577CB0AE2674FF16FC83104E9240AA60E ) ) game ( name "Dora the Explorer - Super Star Adventures! (Europe) (En,Fr,Nl)" description "Dora the Explorer - Super Star Adventures! (Europe) (En,Fr,Nl)" - rom ( name "Dora the Explorer - Super Star Adventures! (Europe) (En,Fr,Nl).gba" size 4194304 crc 528BCA02 md5 7512E1D5B00D7D5FEB8EC02D2E835ED1 sha1 6F7456848FF0C102BF50569E7F1A8BFEFECD66B2 ) + rom ( name "Dora the Explorer - Super Star Adventures! (Europe) (En,Fr,Nl).gba" size 4194304 crc 528bca02 sha1 6F7456848FF0C102BF50569E7F1A8BFEFECD66B2 ) ) game ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA)" description "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA)" - rom ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA).gba" size 4194304 crc 9439541C md5 E23047FCF278CA962B8E95690490CC1C sha1 10D1DF1CB3FD94A14FFF239083968B5182772A4D flags verified ) + rom ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA).gba" size 4194304 crc 9439541c sha1 10D1DF1CB3FD94A14FFF239083968B5182772A4D flags verified ) ) game ( name "Dora the Explorer Double Pack (USA)" description "Dora the Explorer Double Pack (USA)" - rom ( name "Dora the Explorer Double Pack (USA).gba" size 8388608 crc 1F9D002E md5 3B9F6AEE661C62A576B3D18058EBD813 sha1 BC11D9C123F7390F8B0D691528F2A9A5FCF423AF ) + rom ( name "Dora the Explorer Double Pack (USA).gba" size 8388608 crc 1f9d002e sha1 BC11D9C123F7390F8B0D691528F2A9A5FCF423AF ) ) game ( name "Doraemon - Dokodemo Walker (Japan)" description "Doraemon - Dokodemo Walker (Japan)" - rom ( name "Doraemon - Dokodemo Walker (Japan).gba" size 8388608 crc E28AFEBC md5 4B2678E47717C23CA7D27101662BEAA6 sha1 3E98BD11ABED560B1669185E6FC326303E82CA01 ) + rom ( name "Doraemon - Dokodemo Walker (Japan).gba" size 8388608 crc e28afebc sha1 3E98BD11ABED560B1669185E6FC326303E82CA01 ) ) game ( name "Doraemon - Midori no Wakusei Dokidoki Daikyuushutsu! (Japan)" description "Doraemon - Midori no Wakusei Dokidoki Daikyuushutsu! (Japan)" - rom ( name "Doraemon - Midori no Wakusei Dokidoki Daikyuushutsu! (Japan).gba" size 8388608 crc 95565762 md5 8734C1F1BB86042C40696786825181EB sha1 5A466592DF316A1D37432DEDCF456098D18BCCAA ) + rom ( name "Doraemon - Midori no Wakusei Dokidoki Daikyuushutsu! (Japan).gba" size 8388608 crc 95565762 sha1 5A466592DF316A1D37432DEDCF456098D18BCCAA ) ) game ( name "Double Dragon Advance (USA)" description "Double Dragon Advance (USA)" - rom ( name "Double Dragon Advance (USA).gba" size 4194304 crc 764FAFB5 md5 9F738E440D5A6EBBE5E5DCF8B727BBB3 sha1 A08352C4961537E50071982A912AE15A5519F1BE flags verified ) + rom ( name "Double Dragon Advance (USA).gba" size 4194304 crc 764fafb5 sha1 A08352C4961537E50071982A912AE15A5519F1BE flags verified ) ) game ( name "Double Dragon Advance (Japan)" description "Double Dragon Advance (Japan)" - rom ( name "Double Dragon Advance (Japan).gba" size 4194304 crc A3330E8F md5 98B3619A09EB08C2C6816C6CD2747527 sha1 CB270B06B9161AFE9DB3ABEC32B53BFD2E241864 ) + rom ( name "Double Dragon Advance (Japan).gba" size 4194304 crc a3330e8f sha1 CB270B06B9161AFE9DB3ABEC32B53BFD2E241864 ) ) game ( name "Double Game! - Cartoon Network Block Party & Cartoon Network Speedway (Europe)" description "Double Game! - Cartoon Network Block Party & Cartoon Network Speedway (Europe)" - rom ( name "Double Game! - Cartoon Network Block Party & Cartoon Network Speedway (Europe).gba" size 8388608 crc 3A4F8E4D md5 0A2726E1C0ECB255B88CA3085AFC7891 sha1 4E93B1D6EB04D38D2C638A3A0E03784E3973108D ) + rom ( name "Double Game! - Cartoon Network Block Party & Cartoon Network Speedway (Europe).gba" size 8388608 crc 3a4f8e4d sha1 4E93B1D6EB04D38D2C638A3A0E03784E3973108D ) ) game ( name "Double Game! - Golden Nugget Casino & Texas Hold 'em Poker (Europe)" description "Double Game! - Golden Nugget Casino & Texas Hold 'em Poker (Europe)" - rom ( name "Double Game! - Golden Nugget Casino & Texas Hold 'em Poker (Europe).gba" size 8388608 crc CFF20829 md5 904299E3D5EC737C17EFDAC25126016D sha1 E1C4DD83EDDC542D568B1582F3D1FBA55BFE7385 ) + rom ( name "Double Game! - Golden Nugget Casino & Texas Hold 'em Poker (Europe).gba" size 8388608 crc cff20829 sha1 E1C4DD83EDDC542D568B1582F3D1FBA55BFE7385 ) ) game ( name "Double Game! - Quad Desert Fury & Monster Trucks (Europe)" description "Double Game! - Quad Desert Fury & Monster Trucks (Europe)" - rom ( name "Double Game! - Quad Desert Fury & Monster Trucks (Europe).gba" size 8388608 crc 0DB22E8C md5 A822BDF8301F00B392627F7E3476510C sha1 489524C8A7647931DC0118B8F25FAABBC8BAA02E ) + rom ( name "Double Game! - Quad Desert Fury & Monster Trucks (Europe).gba" size 8388608 crc 0db22e8c sha1 489524C8A7647931DC0118B8F25FAABBC8BAA02E ) ) game ( name "Double Pack - Sonic Advance & ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es)" description "Double Pack - Sonic Advance & ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es)" - rom ( name "Double Pack - Sonic Advance & ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es).gba" size 16777216 crc 21EF5165 md5 A85BA35D880113D4F92163E899948C04 sha1 79831F3124A2781E02B18F343B546D75A73554A7 ) + rom ( name "Double Pack - Sonic Advance & ChuChu Rocket! (Japan) (En,Ja,Fr,De,Es).gba" size 16777216 crc 21ef5165 sha1 79831F3124A2781E02B18F343B546D75A73554A7 ) ) game ( - name "Double Pack - Sonic Advance & Sonic Battle (Japan) (En,Ja,Fr,De,Es+En,Ja)" - description "Double Pack - Sonic Advance & Sonic Battle (Japan) (En,Ja,Fr,De,Es+En,Ja)" - rom ( name "Double Pack - Sonic Advance & Sonic Battle (Japan) (En,Ja,Fr,De,Es+En,Ja).gba" size 33554432 crc 31D712D3 md5 451C80DD3DC1F1455829219E3C550BE0 sha1 30C8DACDE7D657082759DF4F0235BCB3B44AC663 ) + name "Double Pack - Sonic Battle & Sonic Advance (Japan) (En,Ja,Fr,De,Es+En,Ja)" + description "Double Pack - Sonic Battle & Sonic Advance (Japan) (En,Ja,Fr,De,Es+En,Ja)" + rom ( name "Double Pack - Sonic Battle & Sonic Advance (Japan) (En,Ja,Fr,De,Es+En,Ja).gba" size 33554432 crc 31d712d3 sha1 30C8DACDE7D657082759DF4F0235BCB3B44AC663 ) ) game ( - name "Double Pack - Sonic Battle & Sonic Pinball Party (Japan) (En,Ja+En,Ja,Fr,De,Es,It)" - description "Double Pack - Sonic Battle & Sonic Pinball Party (Japan) (En,Ja+En,Ja,Fr,De,Es,It)" - rom ( name "Double Pack - Sonic Battle & Sonic Pinball Party (Japan) (En,Ja+En,Ja,Fr,De,Es,It).gba" size 33554432 crc 0DFAA3F2 md5 6B00A4D7D88BB4B78FC014CC50BCE319 sha1 8B21125B992E25E63343DF76068099FCD108EF12 ) -) - -game ( - name "Doubutsu-jima no Chobigurumi (Japan) (Rev 1)" - description "Doubutsu-jima no Chobigurumi (Japan) (Rev 1)" - rom ( name "Doubutsu-jima no Chobigurumi (Japan) (Rev 1).gba" size 8388608 crc B9C15F87 md5 46ED4E547F7B96A029C345870CE42380 sha1 1273D6199C1A44C77132FC09BC04504BC680FE7D ) + name "Double Pack - Sonic Pinball Party & Sonic Battle (Japan) (En,Ja+En,Ja,Fr,De,Es,It)" + description "Double Pack - Sonic Pinball Party & Sonic Battle (Japan) (En,Ja+En,Ja,Fr,De,Es,It)" + rom ( name "Double Pack - Sonic Pinball Party & Sonic Battle (Japan) (En,Ja+En,Ja,Fr,De,Es,It).gba" size 33554432 crc 0dfaa3f2 sha1 8B21125B992E25E63343DF76068099FCD108EF12 ) ) game ( name "Doubutsu-jima no Chobigurumi (Japan)" description "Doubutsu-jima no Chobigurumi (Japan)" - rom ( name "Doubutsu-jima no Chobigurumi (Japan).gba" size 8388608 crc C764CC7E md5 830D34040BE2289D156228ADDC5972DD sha1 5C77F64471EAC6EF647B203DECDE5FF4F9A69438 ) + rom ( name "Doubutsu-jima no Chobigurumi (Japan).gba" size 8388608 crc c764cc7e sha1 5C77F64471EAC6EF647B203DECDE5FF4F9A69438 ) +) + +game ( + name "Doubutsu-jima no Chobigurumi (Japan) (Rev 1)" + description "Doubutsu-jima no Chobigurumi (Japan) (Rev 1)" + rom ( name "Doubutsu-jima no Chobigurumi (Japan) (Rev 1).gba" size 8388608 crc b9c15f87 sha1 1273D6199C1A44C77132FC09BC04504BC680FE7D flags verified ) ) game ( name "Doubutsu-jima no Chobigurumi 2 - Tama-chan Monogatari (Japan)" description "Doubutsu-jima no Chobigurumi 2 - Tama-chan Monogatari (Japan)" - rom ( name "Doubutsu-jima no Chobigurumi 2 - Tama-chan Monogatari (Japan).gba" size 4194304 crc 16347E33 md5 A0C9F4034BB720AAB33B356B002E8A55 sha1 A9895902AE00DF7BAAF6D5FE94882FC35A6005A9 ) + rom ( name "Doubutsu-jima no Chobigurumi 2 - Tama-chan Monogatari (Japan).gba" size 4194304 crc 16347e33 sha1 A9895902AE00DF7BAAF6D5FE94882FC35A6005A9 ) ) game ( name "Downforce (Europe) (En,Fr,De,Es,It)" description "Downforce (Europe) (En,Fr,De,Es,It)" - rom ( name "Downforce (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc EB326294 md5 2F14E9E9357B04EE867D837A3DD3FCDD sha1 939ED52B73ACFCF4E724D71A62C240B9585F6B41 ) + rom ( name "Downforce (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc eb326294 sha1 939ED52B73ACFCF4E724D71A62C240B9585F6B41 ) ) game ( name "Downtown - Nekketsu Monogatari EX (Japan)" description "Downtown - Nekketsu Monogatari EX (Japan)" - rom ( name "Downtown - Nekketsu Monogatari EX (Japan).gba" size 4194304 crc 32E9A0BD md5 B0CB6DC69206ED9B20496E49AE2840CC sha1 9F5CB4E49F6B724FB5D907D291C5F179FCF1C360 ) + rom ( name "Downtown - Nekketsu Monogatari EX (Japan).gba" size 4194304 crc 32e9a0bd sha1 9F5CB4E49F6B724FB5D907D291C5F179FCF1C360 ) +) + +game ( + name "Dr. Mario (USA) (Kiosk, GameCube)" + description "Dr. Mario (USA) (Kiosk, GameCube)" + rom ( name "Dr. Mario (USA) (Kiosk, GameCube).gba" size 49404 crc 5e81043e sha1 0EB2C5B584D072F7CD1D837CEB2B1222FCEC441B flags verified ) ) game ( name "Dr. Mario & Panel de Pon (Japan)" description "Dr. Mario & Panel de Pon (Japan)" - rom ( name "Dr. Mario & Panel de Pon (Japan).gba" size 8388608 crc 129BF78F md5 2705C33D0C7CF9B0AFF99C1B64D4465D sha1 FC4371A6E16116182C70EEE6E8A1B53DF0FC693C flags verified ) + rom ( name "Dr. Mario & Panel de Pon (Japan).gba" size 8388608 crc 129bf78f sha1 FC4371A6E16116182C70EEE6E8A1B53DF0FC693C flags verified ) ) game ( name "Dr. Muto (Europe) (En,Fr,De,Es,It)" description "Dr. Muto (Europe) (En,Fr,De,Es,It)" - rom ( name "Dr. Muto (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 46736F58 md5 567FEC94E59F8E546FCF5D1BF4576744 sha1 1C37F9B838D00CCF54E152466310EE722886A599 flags verified ) + rom ( name "Dr. Muto (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 46736f58 sha1 1C37F9B838D00CCF54E152466310EE722886A599 flags verified ) ) game ( - name "Dr. Seuss' - The Cat in the Hat (USA)" - description "Dr. Seuss' - The Cat in the Hat (USA)" - rom ( name "Dr. Seuss' - The Cat in the Hat (USA).gba" size 4194304 crc 13ADBF3B md5 22A0E9F0E8C1C51272A2E29EF2DE56E7 sha1 921B768682624ADA6AA1A7F8BFA4DC07366095AF flags verified ) -) - -game ( - name "Dr. Seuss' - The Cat in the Hat (Europe) (En,Fr,De,Es,It)" - description "Dr. Seuss' - The Cat in the Hat (Europe) (En,Fr,De,Es,It)" - rom ( name "Dr. Seuss' - The Cat in the Hat (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A5DBE5AE md5 D5A8437BE47F77EA14409B0B40A026FA sha1 A60339E9B4FDBCAC73ED3B677AE17747BDB462AD ) + name "Dr. Seuss' The Cat in the Hat (USA)" + description "Dr. Seuss' The Cat in the Hat (USA)" + rom ( name "Dr. Seuss' The Cat in the Hat (USA).gba" size 4194304 crc 13adbf3b sha1 921B768682624ADA6AA1A7F8BFA4DC07366095AF flags verified ) ) game ( name "Dr. Sudoku (USA)" description "Dr. Sudoku (USA)" - rom ( name "Dr. Sudoku (USA).gba" size 4194304 crc FC003E2B md5 23564039143B0F8BEB2E9F3CA4AB742E sha1 0DA4E12281A616AE63B95479BADF932DDB30DF5B ) + rom ( name "Dr. Sudoku (USA).gba" size 4194304 crc fc003e2b sha1 0DA4E12281A616AE63B95479BADF932DDB30DF5B ) ) game ( name "Dr. Sudoku (Europe)" description "Dr. Sudoku (Europe)" - rom ( name "Dr. Sudoku (Europe).gba" size 4194304 crc E9848D13 md5 30FF41B3A469BAD7CE39DEB6D50F8154 sha1 D87DB7A5C39A384917B5F8F628F3338F2C5A4DC7 ) + rom ( name "Dr. Sudoku (Europe).gba" size 4194304 crc e9848d13 sha1 D87DB7A5C39A384917B5F8F628F3338F2C5A4DC7 ) ) game ( name "Dragon Ball - Advance Adventure (Japan)" description "Dragon Ball - Advance Adventure (Japan)" - rom ( name "Dragon Ball - Advance Adventure (Japan).gba" size 16777216 crc 8A06337A md5 DDA55EE90530B82555F0F37CBAA90B9F sha1 BBD47A73717729183F4516E7F2F4AFA6756ACE44 ) + rom ( name "Dragon Ball - Advance Adventure (Japan).gba" size 16777216 crc 8a06337a sha1 BBD47A73717729183F4516E7F2F4AFA6756ACE44 ) ) game ( name "Dragon Ball - Advance Adventure (Korea)" description "Dragon Ball - Advance Adventure (Korea)" - rom ( name "Dragon Ball - Advance Adventure (Korea).gba" size 16777216 crc 4E2CC84D md5 6DDC7F2D8949448C198FC1183BCBCB0B sha1 642D6D5ED9D1C9DCACD59B2F11C07CF54B9CD0E7 ) + rom ( name "Dragon Ball - Advance Adventure (Korea).gba" size 16777216 crc 4e2cc84d sha1 642D6D5ED9D1C9DCACD59B2F11C07CF54B9CD0E7 ) ) game ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It)" description "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 6C135820 md5 CB14DF09EA41694532A9327510BB28C1 sha1 E49AE836B14F84DC8CD817BF912FCDCE82D8A587 flags verified ) + rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 6c135820 sha1 E49AE836B14F84DC8CD817BF912FCDCE82D8A587 flags verified ) ) game ( name "Dragon Ball - Advanced Adventure (USA)" description "Dragon Ball - Advanced Adventure (USA)" - rom ( name "Dragon Ball - Advanced Adventure (USA).gba" size 16777216 crc 7D7306DF md5 442BAB94B7B3BA7E4A8799D18DE52731 sha1 1338584D8CFA57402603197E65D2E2FF0184D24F ) + rom ( name "Dragon Ball - Advanced Adventure (USA).gba" size 16777216 crc 7d7306df sha1 1338584D8CFA57402603197E65D2E2FF0184D24F ) ) game ( name "Dragon Ball GT - Transformation (USA)" description "Dragon Ball GT - Transformation (USA)" - rom ( name "Dragon Ball GT - Transformation (USA).gba" size 8388608 crc AD964A91 md5 B60ABAC7FDBF012DE5A3C9403ECE89E8 sha1 8DD4B6E95DCA4554A919BFF55128481A9A95B611 ) + rom ( name "Dragon Ball GT - Transformation (USA).gba" size 8388608 crc ad964a91 sha1 8DD4B6E95DCA4554A919BFF55128481A9A95B611 ) ) game ( name "Dragon Ball Z - Bukuu Tougeki (Japan)" description "Dragon Ball Z - Bukuu Tougeki (Japan)" - rom ( name "Dragon Ball Z - Bukuu Tougeki (Japan).gba" size 16777216 crc 6C0F0B86 md5 5AE021D162364F781F33A96CD9775E4C sha1 9EE0EE17816AB4214D8DFBF7D2FAF9CE08900374 ) + rom ( name "Dragon Ball Z - Bukuu Tougeki (Japan).gba" size 16777216 crc 6c0f0b86 sha1 9EE0EE17816AB4214D8DFBF7D2FAF9CE08900374 ) ) game ( name "Dragon Ball Z - Buu's Fury (USA)" description "Dragon Ball Z - Buu's Fury (USA)" - rom ( name "Dragon Ball Z - Buu's Fury (USA).gba" size 8388608 crc 01C1707F md5 3A74FCE97F1EA2B28C2A50EC3DF0ACEE sha1 F1C4B07554D2A3B1AD2F325307051E775CE68087 flags verified ) + rom ( name "Dragon Ball Z - Buu's Fury (USA).gba" size 8388608 crc 01c1707f sha1 F1C4B07554D2A3B1AD2F325307051E775CE68087 flags verified ) ) game ( name "Dragon Ball Z - Collectible Card Game (USA)" description "Dragon Ball Z - Collectible Card Game (USA)" - rom ( name "Dragon Ball Z - Collectible Card Game (USA).gba" size 8388608 crc F6124D7F md5 8EE261B598C4C1189DFAAA3361697C5F sha1 338E4ED81071FA6C55CA7CA3BBBDF84BC3BA8855 flags verified ) + rom ( name "Dragon Ball Z - Collectible Card Game (USA).gba" size 8388608 crc f6124d7f sha1 338E4ED81071FA6C55CA7CA3BBBDF84BC3BA8855 flags verified ) ) game ( name "Dragon Ball Z - Moogongtoogeuk (Korea)" description "Dragon Ball Z - Moogongtoogeuk (Korea)" - rom ( name "Dragon Ball Z - Moogongtoogeuk (Korea).gba" size 16777216 crc E4893DD7 md5 7AFCF95672D0652C09F77CCC1AFCAF02 sha1 EFE773B4D4B6AD77201EDFA9B09453D4FEFEB8D3 ) + rom ( name "Dragon Ball Z - Moogongtoogeuk (Korea).gba" size 16777216 crc e4893dd7 sha1 EFE773B4D4B6AD77201EDFA9B09453D4FEFEB8D3 ) ) game ( name "Dragon Ball Z - Supersonic Warriors (USA)" description "Dragon Ball Z - Supersonic Warriors (USA)" - rom ( name "Dragon Ball Z - Supersonic Warriors (USA).gba" size 16777216 crc 9A857A70 md5 09F49996195A3FCE6141306F9EEB2944 sha1 F6F956989773E39CFDE407D3763EB7F767EF2033 flags verified ) + rom ( name "Dragon Ball Z - Supersonic Warriors (USA).gba" size 16777216 crc 9a857a70 sha1 F6F956989773E39CFDE407D3763EB7F767EF2033 flags verified ) ) game ( name "Dragon Ball Z - Supersonic Warriors (Europe) (En,Fr,De,Es,It)" description "Dragon Ball Z - Supersonic Warriors (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball Z - Supersonic Warriors (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc B4D9572C md5 571DBFEC3908D625676669ED68A8F530 sha1 7F1072FFAE4B25639D660D0AB67951B955FD8252 flags verified ) + rom ( name "Dragon Ball Z - Supersonic Warriors (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc b4d9572c sha1 7F1072FFAE4B25639D660D0AB67951B955FD8252 flags verified ) ) game ( name "Dragon Ball Z - Taiketsu (USA)" description "Dragon Ball Z - Taiketsu (USA)" - rom ( name "Dragon Ball Z - Taiketsu (USA).gba" size 8388608 crc 64EC07E7 md5 B7B1550606411B985B54F75F0750FEB1 sha1 1FAC4E187B8CF0AEB218CA307F10955F432D258D flags verified ) + rom ( name "Dragon Ball Z - Taiketsu (USA).gba" size 8388608 crc 64ec07e7 sha1 1FAC4E187B8CF0AEB218CA307F10955F432D258D flags verified ) ) game ( name "Dragon Ball Z - Taiketsu (Europe) (En,Fr,De,Es,It)" description "Dragon Ball Z - Taiketsu (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball Z - Taiketsu (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc D0E79665 md5 0FD6897002244985CAB200501E1B48C9 sha1 C6AFECB00A7BBA30C483610E695BE3588ECD2864 flags verified ) + rom ( name "Dragon Ball Z - Taiketsu (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d0e79665 sha1 C6AFECB00A7BBA30C483610E695BE3588ECD2864 flags verified ) ) game ( name "Dragon Ball Z - The Legacy of Goku (USA)" description "Dragon Ball Z - The Legacy of Goku (USA)" - rom ( name "Dragon Ball Z - The Legacy of Goku (USA).gba" size 8388608 crc D47CCFF4 md5 3100FC5A4427A7B0CC20B861134E60F2 sha1 A3C8C76742F11FC6A3F6E3FCCA20992458CAC0B5 flags verified ) + rom ( name "Dragon Ball Z - The Legacy of Goku (USA).gba" size 8388608 crc d47ccff4 sha1 A3C8C76742F11FC6A3F6E3FCCA20992458CAC0B5 flags verified ) ) game ( name "Dragon Ball Z - The Legacy of Goku (Europe) (En,Fr,De,Es,It)" description "Dragon Ball Z - The Legacy of Goku (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball Z - The Legacy of Goku (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc CA6E149C md5 8246B72CB4B6872724836776C123CB55 sha1 C2691355247B03083578071D4D4A017F5599BE20 flags verified ) + rom ( name "Dragon Ball Z - The Legacy of Goku (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ca6e149c sha1 C2691355247B03083578071D4D4A017F5599BE20 flags verified ) ) game ( name "Dragon Ball Z - The Legacy of Goku II (Europe) (En,Fr,De,Es,It)" description "Dragon Ball Z - The Legacy of Goku II (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon Ball Z - The Legacy of Goku II (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 20684433 md5 D6A12374A2414BE686480A4936A2FF48 sha1 DB36FF52FCD63F753F9D66439AA3D2216701C326 flags verified ) + rom ( name "Dragon Ball Z - The Legacy of Goku II (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 20684433 sha1 DB36FF52FCD63F753F9D66439AA3D2216701C326 flags verified ) ) game ( name "Dragon Ball Z - The Legacy of Goku II (USA)" description "Dragon Ball Z - The Legacy of Goku II (USA)" - rom ( name "Dragon Ball Z - The Legacy of Goku II (USA).gba" size 8388608 crc 204142E1 md5 4E1565AA1F0627C2BF5E51019440CB70 sha1 18E0715DEC419F3501C301511530D2EDCD590F8B flags verified ) + rom ( name "Dragon Ball Z - The Legacy of Goku II (USA).gba" size 8388608 crc 204142e1 sha1 18E0715DEC419F3501C301511530D2EDCD590F8B flags verified ) ) game ( name "Dragon Ball Z - The Legacy of Goku II International (Japan)" description "Dragon Ball Z - The Legacy of Goku II International (Japan)" - rom ( name "Dragon Ball Z - The Legacy of Goku II International (Japan).gba" size 8388608 crc B3297D59 md5 EAEC6E4F1192AD24C484B05056E3AA76 sha1 4E18F54B8BACE6ED32B6315B159E903F61D69339 ) + rom ( name "Dragon Ball Z - The Legacy of Goku II International (Japan).gba" size 8388608 crc b3297d59 sha1 4E18F54B8BACE6ED32B6315B159E903F61D69339 flags verified ) ) game ( name "Dragon Drive - World D Break (Japan)" description "Dragon Drive - World D Break (Japan)" - rom ( name "Dragon Drive - World D Break (Japan).gba" size 8388608 crc E5A571AD md5 259CFD0FF14F96159FCF9AA156CEC4DA sha1 26DD31B698CF33D9ADADEBEB6086899C84BF7C6D ) + rom ( name "Dragon Drive - World D Break (Japan).gba" size 8388608 crc e5a571ad sha1 26DD31B698CF33D9ADADEBEB6086899C84BF7C6D ) ) game ( name "Dragon Quest Characters - Torneko no Daibouken 2 Advance - Fushigi no Dungeon (Japan)" description "Dragon Quest Characters - Torneko no Daibouken 2 Advance - Fushigi no Dungeon (Japan)" - rom ( name "Dragon Quest Characters - Torneko no Daibouken 2 Advance - Fushigi no Dungeon (Japan).gba" size 8388608 crc 2B077791 md5 B6F2C552E3282344A81D8DA3CDCB7041 sha1 684E27B2DC02DE5D2855D2DDC7CE262F8732341A ) + rom ( name "Dragon Quest Characters - Torneko no Daibouken 2 Advance - Fushigi no Dungeon (Japan).gba" size 8388608 crc 2b077791 sha1 684E27B2DC02DE5D2855D2DDC7CE262F8732341A flags verified ) ) game ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan)" description "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan)" - rom ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan).gba" size 16777216 crc C891B2A0 md5 EE36C7A4CC06BF050DB0B872BEBB03D9 sha1 F306CE96404CFF93CAEE78C86696A69B431B289A flags verified ) + rom ( name "Dragon Quest Characters - Torneko no Daibouken 3 Advance - Fushigi no Dungeon (Japan).gba" size 16777216 crc c891b2a0 sha1 F306CE96404CFF93CAEE78C86696A69B431B289A flags verified ) ) game ( name "Dragon Quest Monsters - Caravan Heart (Japan)" description "Dragon Quest Monsters - Caravan Heart (Japan)" - rom ( name "Dragon Quest Monsters - Caravan Heart (Japan).gba" size 8388608 crc 3C24ABCC md5 FC6A66C32B91FA0E526AE7782F29E86A sha1 430A7062844888E68BD5587ED53A769BA548ADB3 ) + rom ( name "Dragon Quest Monsters - Caravan Heart (Japan).gba" size 8388608 crc 3c24abcc sha1 430A7062844888E68BD5587ED53A769BA548ADB3 ) ) game ( name "Dragon Tales - Dragon Adventures (USA)" description "Dragon Tales - Dragon Adventures (USA)" - rom ( name "Dragon Tales - Dragon Adventures (USA).gba" size 4194304 crc 8AF23450 md5 EB345977C4B1C846C9DEC4141EC18343 sha1 FFE8B5882778A74D414A21B610D4DC0AFF1126E4 ) + rom ( name "Dragon Tales - Dragon Adventures (USA).gba" size 4194304 crc 8af23450 sha1 FFE8B5882778A74D414A21B610D4DC0AFF1126E4 ) ) game ( name "Dragon's Rock (Europe) (En,Fr,De,Es,It)" description "Dragon's Rock (Europe) (En,Fr,De,Es,It)" - rom ( name "Dragon's Rock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc F0CA6D70 md5 CC979F837ABD1318BFA42B84B075A7BE sha1 AE1EF264F71129CC6AAC6620E6F9768F748E7B47 ) + rom ( name "Dragon's Rock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc f0ca6d70 sha1 AE1EF264F71129CC6AAC6620E6F9768F748E7B47 ) ) game ( name "Drake & Josh (USA) (En,Fr)" description "Drake & Josh (USA) (En,Fr)" - rom ( name "Drake & Josh (USA) (En,Fr).gba" size 4194304 crc 63A4422E md5 CA1E7CA13FC27EC962B8163D8E94DCE0 sha1 07499BF3329BCD38F4DD8BB7E392E44957243534 flags verified ) + rom ( name "Drake & Josh (USA) (En,Fr).gba" size 4194304 crc 63a4422e sha1 07499BF3329BCD38F4DD8BB7E392E44957243534 flags verified ) ) game ( name "Drill Dozer (USA)" description "Drill Dozer (USA)" - rom ( name "Drill Dozer (USA).gba" size 8388608 crc E60EC183 md5 14DAB12E795098988D46B96885170538 sha1 C1058CC2482B91204100CC8515DA99AEB06773F5 flags verified ) + rom ( name "Drill Dozer (USA).gba" size 8388608 crc e60ec183 sha1 C1058CC2482B91204100CC8515DA99AEB06773F5 flags verified ) +) + +game ( + name "Drill Dozer (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Drill Dozer (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Drill Dozer (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 8388608 crc 4c09614e sha1 2246A0F00C3B5F8AE147C764FBC29FCBC097E673 flags verified ) ) game ( name "Driv3r (Europe) (En,Fr,De,Es,It)" description "Driv3r (Europe) (En,Fr,De,Es,It)" - rom ( name "Driv3r (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B617B354 md5 48D7F169A879773BAB490C4C1A9DFD5B sha1 3E4DA1CD2A5915D2218CD59E061BAEB3A08BE1C6 flags verified ) + rom ( name "Driv3r (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b617b354 sha1 3E4DA1CD2A5915D2218CD59E061BAEB3A08BE1C6 flags verified ) ) game ( name "Driv3r (USA)" description "Driv3r (USA)" - rom ( name "Driv3r (USA).gba" size 8388608 crc 6C66CFBE md5 3FBC7FDA7D0BBAA03EC037E710CF1DD8 sha1 DF2238FC239BDD0226A1B39DEEF06FA521EAE48E ) + rom ( name "Driv3r (USA).gba" size 8388608 crc 6c66cfbe sha1 DF2238FC239BDD0226A1B39DEEF06FA521EAE48E ) ) game ( name "Driven (USA) (En,Fr,De,Es,It)" description "Driven (USA) (En,Fr,De,Es,It)" - rom ( name "Driven (USA) (En,Fr,De,Es,It).gba" size 4194304 crc F2068738 md5 5BFCFC20061AB866890EB72CA78AA7A4 sha1 316E19C792BBD2B977A5FDC31FC319ECA33B1C8C ) + rom ( name "Driven (USA) (En,Fr,De,Es,It).gba" size 4194304 crc f2068738 sha1 316E19C792BBD2B977A5FDC31FC319ECA33B1C8C ) ) game ( name "Driven (Europe) (En,Fr,De,Es,It)" description "Driven (Europe) (En,Fr,De,Es,It)" - rom ( name "Driven (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 95F2C572 md5 2D8C8D7F7BB5DCFC9D7B8EB54A9281B3 sha1 F79F8DA5569EC4DF15AB15FA81C38907DD31A6B2 ) + rom ( name "Driven (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 95f2c572 sha1 F79F8DA5569EC4DF15AB15FA81C38907DD31A6B2 ) ) game ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It)" description "Driver 2 Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 69EE551C md5 DC99BCCA77EC59C109576B867AB2B3EA sha1 A3B755E1D5820A2E094A2C0C47BFAF526A8D7E5A flags verified ) + rom ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 69ee551c sha1 A3B755E1D5820A2E094A2C0C47BFAF526A8D7E5A flags verified ) ) game ( name "Driver 2 Advance (USA)" description "Driver 2 Advance (USA)" - rom ( name "Driver 2 Advance (USA).gba" size 8388608 crc BBE2A163 md5 BEAB4156E466E97DC7F0B16948D371B7 sha1 4BF6F5E5D57E05C2FEAAFBBCA1C795A6638011C4 flags verified ) + rom ( name "Driver 2 Advance (USA).gba" size 8388608 crc bbe2a163 sha1 4BF6F5E5D57E05C2FEAAFBBCA1C795A6638011C4 flags verified ) ) game ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It) (Beta)" description "Driver 2 Advance (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc B24FA448 md5 E07AB5A02CD7C2F503CEF587890AFB54 sha1 0135A92F0043DF0D0EBAC7F45C53C44D8B095AE2 ) + rom ( name "Driver 2 Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc b24fa448 sha1 0135A92F0043DF0D0EBAC7F45C53C44D8B095AE2 ) ) game ( name "Drome Racers (Europe) (En,Fr,De,Da)" description "Drome Racers (Europe) (En,Fr,De,Da)" - rom ( name "Drome Racers (Europe) (En,Fr,De,Da).gba" size 8388608 crc D6101BC0 md5 585A0F57C4DB96B18DBF15F9C0C2FA6F sha1 DE8D38AB95AC072A9D96989BA04D895D46B841AE ) + rom ( name "Drome Racers (Europe) (En,Fr,De,Da).gba" size 8388608 crc d6101bc0 sha1 DE8D38AB95AC072A9D96989BA04D895D46B841AE flags verified ) ) game ( name "Drome Racers (USA)" description "Drome Racers (USA)" - rom ( name "Drome Racers (USA).gba" size 8388608 crc AD356FB9 md5 9F39A0635363F9E534A4B48C64D52322 sha1 BF810C4A61B03D3D76063633695E45FDD9F789F7 ) -) - -game ( - name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta) [b]" - description "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta) [b]" - rom ( name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta) [b].gba" size 4194304 crc 484E7D56 md5 D41CFF4CF06A89D9A79DF9E47F192D20 sha1 BF38C881B273FEE0F89C02E431B285593B964932 flags baddump ) + rom ( name "Drome Racers (USA).gba" size 8388608 crc ad356fb9 sha1 BF810C4A61B03D3D76063633695E45FDD9F789F7 ) ) game ( name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl)" description "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc F14B65EF md5 CE3627AFE4EDA2A1C5E4674939E5F041 sha1 DABF722AF4E3D879D421987817E7320C1E02293B flags verified ) + rom ( name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc f14b65ef sha1 DABF722AF4E3D879D421987817E7320C1E02293B flags verified ) +) + +game ( + name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + description "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + rom ( name "Droopy's Tennis Open (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc 484e7d56 sha1 BF38C881B273FEE0F89C02E431B285593B964932 ) ) game ( name "Dual Blades (USA)" description "Dual Blades (USA)" - rom ( name "Dual Blades (USA).gba" size 4194304 crc AFF3A0C6 md5 EFA8473A8125181965F08156C95CC6BB sha1 B37C522B48E80D93231B491B025663F1624E3D75 ) + rom ( name "Dual Blades (USA).gba" size 4194304 crc aff3a0c6 sha1 B37C522B48E80D93231B491B025663F1624E3D75 ) ) game ( name "Dual Blades (Japan)" description "Dual Blades (Japan)" - rom ( name "Dual Blades (Japan).gba" size 4194304 crc 522F1F51 md5 6F152B5EB5292F837B2D75B101EE9D55 sha1 4859A9D5B577D21E1228647E195B217EA193F19C ) + rom ( name "Dual Blades (Japan).gba" size 4194304 crc 522f1f51 sha1 4859A9D5B577D21E1228647E195B217EA193F19C ) ) game ( name "Duel Masters (Japan)" description "Duel Masters (Japan)" - rom ( name "Duel Masters (Japan).gba" size 4194304 crc 0D32851A md5 D0F57426579FA85C81C1A9EC9C549E4C sha1 EB187F4EFEF85C86DAB136F9BFD064022BF26F27 ) + rom ( name "Duel Masters (Japan).gba" size 4194304 crc 0d32851a sha1 EB187F4EFEF85C86DAB136F9BFD064022BF26F27 ) ) game ( name "Duel Masters - Kaijudo Showdown (USA)" description "Duel Masters - Kaijudo Showdown (USA)" - rom ( name "Duel Masters - Kaijudo Showdown (USA).gba" size 8388608 crc 804E5DE2 md5 02F23BF2F90126574BC0DE0752BED485 sha1 4A818E070B9097CCFB0D73B2B13636CA4B774A4F ) + rom ( name "Duel Masters - Kaijudo Showdown (USA).gba" size 8388608 crc 804e5de2 sha1 4A818E070B9097CCFB0D73B2B13636CA4B774A4F ) ) game ( name "Duel Masters - Kaijudo Showdown (Europe) (En,Fr,De,Es,It)" description "Duel Masters - Kaijudo Showdown (Europe) (En,Fr,De,Es,It)" - rom ( name "Duel Masters - Kaijudo Showdown (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 52E0AA95 md5 8D51B71A3AE3D1646C368725ABD0B1ED sha1 254647471ACF5C878FCC8742638E1D955A67BC6F ) + rom ( name "Duel Masters - Kaijudo Showdown (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 52e0aa95 sha1 254647471ACF5C878FCC8742638E1D955A67BC6F flags verified ) ) game ( name "Duel Masters - Sempai Legends (USA)" description "Duel Masters - Sempai Legends (USA)" - rom ( name "Duel Masters - Sempai Legends (USA).gba" size 8388608 crc 1CE344CA md5 2ADEB64FF470FB08A472F3CB6F5D7D44 sha1 524418EEE05520A9A1E6B12918780435698C06E1 ) + rom ( name "Duel Masters - Sempai Legends (USA).gba" size 8388608 crc 1ce344ca sha1 524418EEE05520A9A1E6B12918780435698C06E1 ) ) game ( name "Duel Masters - Sempai Legends (Europe) (En,Fr,De,Es,It)" description "Duel Masters - Sempai Legends (Europe) (En,Fr,De,Es,It)" - rom ( name "Duel Masters - Sempai Legends (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2FFF9BA9 md5 5F412F4E7ED5603152BCED92F5B6884A sha1 9603C135ACAAD05D1AA0FF007A26A41BFBC68B1C flags verified ) + rom ( name "Duel Masters - Sempai Legends (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2fff9ba9 sha1 9603C135ACAAD05D1AA0FF007A26A41BFBC68B1C flags verified ) ) game ( name "Duel Masters - Shadow of the Code (Europe) (En,Fr,De,Es,It)" description "Duel Masters - Shadow of the Code (Europe) (En,Fr,De,Es,It)" - rom ( name "Duel Masters - Shadow of the Code (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 9D429F3E md5 23AAC6D60E04EEF54CEC26066FA2D4C3 sha1 F611FFC79AD099EA53DBBEA98AC179DA81904E6B ) + rom ( name "Duel Masters - Shadow of the Code (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 9d429f3e sha1 F611FFC79AD099EA53DBBEA98AC179DA81904E6B ) ) game ( name "Duel Masters - Shadow of the Code (USA)" description "Duel Masters - Shadow of the Code (USA)" - rom ( name "Duel Masters - Shadow of the Code (USA).gba" size 16777216 crc 94D9053D md5 7E4B22C8A115D33A30A3E130884CDE5D sha1 88B4D57BCFDA1E8E96656395D80C2552CA4066FE ) + rom ( name "Duel Masters - Shadow of the Code (USA).gba" size 16777216 crc 94d9053d sha1 88B4D57BCFDA1E8E96656395D80C2552CA4066FE ) ) game ( name "Duel Masters 2 - Invincible Advance (Japan)" description "Duel Masters 2 - Invincible Advance (Japan)" - rom ( name "Duel Masters 2 - Invincible Advance (Japan).gba" size 8388608 crc 4A7DE98E md5 1F739DF174644981268F67EFBCA5DAB8 sha1 916C978DFF1306E474758BF3CF070EFD617DC825 ) + rom ( name "Duel Masters 2 - Invincible Advance (Japan).gba" size 8388608 crc 4a7de98e sha1 916C978DFF1306E474758BF3CF070EFD617DC825 ) ) game ( name "Duel Masters 2 - Kirifuda Shoubu Ver. (Japan)" description "Duel Masters 2 - Kirifuda Shoubu Ver. (Japan)" - rom ( name "Duel Masters 2 - Kirifuda Shoubu Ver. (Japan).gba" size 8388608 crc 4D6A5E1D md5 40124EA3EFA3DBFFE94BA752121375E1 sha1 49D9B6B15CF019A1EE8417DA6F375E3724CEAEFD ) + rom ( name "Duel Masters 2 - Kirifuda Shoubu Ver. (Japan).gba" size 8388608 crc 4d6a5e1d sha1 49D9B6B15CF019A1EE8417DA6F375E3724CEAEFD ) ) game ( name "Duel Masters 3 (Japan)" description "Duel Masters 3 (Japan)" - rom ( name "Duel Masters 3 (Japan).gba" size 8388608 crc D65E3E03 md5 0635910ECEB7B59722A49C9D7D12BBC2 sha1 07617A0C443010FFF99FDF292E3DD556B2C5D406 ) + rom ( name "Duel Masters 3 (Japan).gba" size 8388608 crc d65e3e03 sha1 07617A0C443010FFF99FDF292E3DD556B2C5D406 ) +) + +game ( + name "Duel Masters 3 (Japan) (Rev 1)" + description "Duel Masters 3 (Japan) (Rev 1)" + rom ( name "Duel Masters 3 (Japan) (Rev 1).gba" size 8388608 crc d2b9cfb6 sha1 05AD843564C663A050E137AE0EC07D09F585C714 flags verified ) ) game ( name "Duke Nukem Advance (USA)" description "Duke Nukem Advance (USA)" - rom ( name "Duke Nukem Advance (USA).gba" size 8388608 crc 06570282 md5 DFCA43FB18B5EE86B3ECAB2631862D6F sha1 EF9D2C9910A95E456447EE7288AE5AA659B33AD2 ) + rom ( name "Duke Nukem Advance (USA).gba" size 8388608 crc 06570282 sha1 EF9D2C9910A95E456447EE7288AE5AA659B33AD2 ) ) game ( name "Duke Nukem Advance (Europe) (En,Fr,De,It)" description "Duke Nukem Advance (Europe) (En,Fr,De,It)" - rom ( name "Duke Nukem Advance (Europe) (En,Fr,De,It).gba" size 8388608 crc DC7DAB56 md5 54BC72AB1F56930DDB05C66F118D7608 sha1 F01522EE46F5AA821ADBBA0A97B1A745FF9059F5 flags verified ) + rom ( name "Duke Nukem Advance (Europe) (En,Fr,De,It).gba" size 8388608 crc dc7dab56 sha1 F01522EE46F5AA821ADBBA0A97B1A745FF9059F5 flags verified ) ) game ( name "Dungeons & Dragons - Eye of the Beholder (USA)" description "Dungeons & Dragons - Eye of the Beholder (USA)" - rom ( name "Dungeons & Dragons - Eye of the Beholder (USA).gba" size 4194304 crc 91B16892 md5 3AA4F5BD135064DEBA3394215D4C560D sha1 6270CCF39DD6968F9F6E7D6516F9EE233AA8CDDB ) + rom ( name "Dungeons & Dragons - Eye of the Beholder (USA).gba" size 4194304 crc 91b16892 sha1 6270CCF39DD6968F9F6E7D6516F9EE233AA8CDDB ) ) game ( name "Dungeons & Dragons - Eye of the Beholder (Europe) (En,Fr,De,Es,It)" description "Dungeons & Dragons - Eye of the Beholder (Europe) (En,Fr,De,Es,It)" - rom ( name "Dungeons & Dragons - Eye of the Beholder (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 26351555 md5 D2F0D0B2CCB4A138636746C46B091CD0 sha1 08F3609B5C3988C4F716991B840439AF5920FE9E flags verified ) + rom ( name "Dungeons & Dragons - Eye of the Beholder (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 26351555 sha1 08F3609B5C3988C4F716991B840439AF5920FE9E flags verified ) ) game ( - name "Dynasty Warriors Advance (USA, Australia)" - description "Dynasty Warriors Advance (USA, Australia)" - rom ( name "Dynasty Warriors Advance (USA, Australia).gba" size 16777216 crc AD5A2A4E md5 2A2661CBC8E3891864FDC1D34F9D1C9B sha1 6839254172E558923CDE6A912A5EE537EEC5FD40 flags verified ) + name "Dynasty Warriors Advance (USA)" + description "Dynasty Warriors Advance (USA)" + rom ( name "Dynasty Warriors Advance (USA).gba" size 16777216 crc ad5a2a4e sha1 6839254172E558923CDE6A912A5EE537EEC5FD40 flags verified ) ) game ( name "Dynasty Warriors Advance (Europe) (En,Fr,De,Es,It)" description "Dynasty Warriors Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Dynasty Warriors Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 74CDB37A md5 E36E394B1D44B3C50CD8630D54DA9E4D sha1 F4E8FB4DBC409C508CE523F45E9F85892BD26A89 flags verified ) + rom ( name "Dynasty Warriors Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 74cdb37a sha1 F4E8FB4DBC409C508CE523F45E9F85892BD26A89 flags verified ) ) game ( name "e-Reader (USA)" description "e-Reader (USA)" - rom ( name "e-Reader (USA).gba" size 8388608 crc 8B27CD67 md5 7B17E51D5A61780F9823203C6254ED8F sha1 4B7005E81EE9FFEE333B3F6095C3611800B56588 ) + rom ( name "e-Reader (USA).gba" size 8388608 crc 8b27cd67 sha1 4B7005E81EE9FFEE333B3F6095C3611800B56588 ) ) game ( name "E.T. - The Extra-Terrestrial (USA)" description "E.T. - The Extra-Terrestrial (USA)" - rom ( name "E.T. - The Extra-Terrestrial (USA).gba" size 4194304 crc 8B082CCE md5 D8B6D1AF6D00558C3BB33D81AD18C483 sha1 CEBA86ED45D46D67F5152921926ADD453E1EAE6E ) + rom ( name "E.T. - The Extra-Terrestrial (USA).gba" size 4194304 crc 8b082cce sha1 CEBA86ED45D46D67F5152921926ADD453E1EAE6E ) ) game ( name "E.T. - The Extra-Terrestrial (Europe) (En,Fr,De,Es,It,Nl)" description "E.T. - The Extra-Terrestrial (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "E.T. - The Extra-Terrestrial (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 10ECE4CB md5 85F8893A2C07EAD2A164F823D665F415 sha1 5ECD014D2544C473B113B2A111740CD9211C2F70 flags verified ) + rom ( name "E.T. - The Extra-Terrestrial (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 10ece4cb sha1 5ECD014D2544C473B113B2A111740CD9211C2F70 flags verified ) ) game ( name "Earthworm Jim (USA, Europe)" description "Earthworm Jim (USA, Europe)" - rom ( name "Earthworm Jim (USA, Europe).gba" size 8388608 crc C4991D13 md5 54A50DBAEA5A9154CC820F3FC13A34BB sha1 8C3148C1C863A1E31B6F4C380C9390DC12FAE9AC flags verified ) + rom ( name "Earthworm Jim (USA, Europe).gba" size 8388608 crc c4991d13 sha1 8C3148C1C863A1E31B6F4C380C9390DC12FAE9AC flags verified ) ) game ( name "Earthworm Jim 2 (USA)" description "Earthworm Jim 2 (USA)" - rom ( name "Earthworm Jim 2 (USA).gba" size 8388608 crc 7496555C md5 41C45028C30A5F0241F5B479A954C745 sha1 E500950377B64ECFF541B92DDE99DF5F717ABD0E ) + rom ( name "Earthworm Jim 2 (USA).gba" size 8388608 crc 7496555c sha1 E500950377B64ECFF541B92DDE99DF5F717ABD0E ) ) game ( name "Earthworm Jim 2 (Europe) (En,Fr,De,Es,It)" description "Earthworm Jim 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Earthworm Jim 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc D211E8DA md5 3414C77D76EB093ABC478F67EF7EC3B9 sha1 231A8C59D10ED12C9EA7A4124942AD3C50F495D7 flags verified ) + rom ( name "Earthworm Jim 2 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d211e8da sha1 231A8C59D10ED12C9EA7A4124942AD3C50F495D7 flags verified ) ) game ( name "Ecks V Sever (Europe) (En,Fr,De,Es,It)" description "Ecks V Sever (Europe) (En,Fr,De,Es,It)" - rom ( name "Ecks V Sever (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc AF726026 md5 A455D815CDB8CBC740961BB72BEC4475 sha1 CA100B4A9B96207912B0E4EDA068452A2D79613E ) + rom ( name "Ecks V Sever (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc af726026 sha1 CA100B4A9B96207912B0E4EDA068452A2D79613E ) ) game ( name "Ecks vs Sever (USA) (En,Fr,De,Es,It)" description "Ecks vs Sever (USA) (En,Fr,De,Es,It)" - rom ( name "Ecks vs Sever (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 86A861F1 md5 6E76914FA33B3436079AC16ECF778D15 sha1 CF1D42089BEC9B6C9DAC7C6DFB7CD28C0CCA2B51 ) + rom ( name "Ecks vs Sever (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 86a861f1 sha1 CF1D42089BEC9B6C9DAC7C6DFB7CD28C0CCA2B51 ) ) game ( name "Ecks vs. Sever II - Ballistic (Europe) (En,Fr,De,Es,It)" description "Ecks vs. Sever II - Ballistic (Europe) (En,Fr,De,Es,It)" - rom ( name "Ecks vs. Sever II - Ballistic (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 83297D13 md5 0687FDAC8B7FBC2D5147EC9F5F4D2525 sha1 F294D72470C4001C6ED66BAEAA8745EDFB011762 ) + rom ( name "Ecks vs. Sever II - Ballistic (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 83297d13 sha1 F294D72470C4001C6ED66BAEAA8745EDFB011762 ) ) game ( name "Ed, Edd n Eddy - Jawbreakers! (USA)" description "Ed, Edd n Eddy - Jawbreakers! (USA)" - rom ( name "Ed, Edd n Eddy - Jawbreakers! (USA).gba" size 4194304 crc 48E5A70E md5 9E3C1AF23EA83CC4852C632525BEA1C5 sha1 893413581BAEF9859E8DD0CC2007655C147C382F flags verified ) + rom ( name "Ed, Edd n Eddy - Jawbreakers! (USA).gba" size 4194304 crc 48e5a70e sha1 893413581BAEF9859E8DD0CC2007655C147C382F flags verified ) ) game ( name "Ed, Edd n Eddy - Jawbreakers! (Europe) (En,Fr,De,Es,It)" description "Ed, Edd n Eddy - Jawbreakers! (Europe) (En,Fr,De,Es,It)" - rom ( name "Ed, Edd n Eddy - Jawbreakers! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E7F6E42F md5 9A819E0CE5E550BFF890F8329B6986DA sha1 7C12385A5933260AAE3B30206A09071F6203D406 flags verified ) + rom ( name "Ed, Edd n Eddy - Jawbreakers! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e7f6e42f sha1 7C12385A5933260AAE3B30206A09071F6203D406 flags verified ) ) game ( name "Ed, Edd n Eddy - Jawbreakers! (USA) (Rev 1)" description "Ed, Edd n Eddy - Jawbreakers! (USA) (Rev 1)" - rom ( name "Ed, Edd n Eddy - Jawbreakers! (USA) (Rev 1).gba" size 4194304 crc 315A9114 md5 E94540FB5D5E27D7A33C50076BD7628A sha1 3559337718FD907560B6BAD384170CC0CB997099 ) + rom ( name "Ed, Edd n Eddy - Jawbreakers! (USA) (Rev 1).gba" size 4194304 crc 315a9114 sha1 3559337718FD907560B6BAD384170CC0CB997099 ) ) game ( name "Ed, Edd n Eddy - The Mis-Edventures (USA) (En,Fr)" description "Ed, Edd n Eddy - The Mis-Edventures (USA) (En,Fr)" - rom ( name "Ed, Edd n Eddy - The Mis-Edventures (USA) (En,Fr).gba" size 8388608 crc 64EDB487 md5 0886EEE57B5F9E97D2981A00134FD641 sha1 2D4AAAD62FAF905E4138015261D59360756E7DEE ) + rom ( name "Ed, Edd n Eddy - The Mis-Edventures (USA) (En,Fr).gba" size 8388608 crc 64edb487 sha1 2D4AAAD62FAF905E4138015261D59360756E7DEE ) ) game ( name "Ed, Edd n Eddy - The Mis-Edventures (Europe) (En,Fr)" description "Ed, Edd n Eddy - The Mis-Edventures (Europe) (En,Fr)" - rom ( name "Ed, Edd n Eddy - The Mis-Edventures (Europe) (En,Fr).gba" size 8388608 crc BAA13BC4 md5 9AC5DDEF9BE27D933D366E224FBA4163 sha1 4423573023841E4977B77BC8ACE1AD7CAC221F92 ) + rom ( name "Ed, Edd n Eddy - The Mis-Edventures (Europe) (En,Fr).gba" size 8388608 crc baa13bc4 sha1 4423573023841E4977B77BC8ACE1AD7CAC221F92 ) ) game ( name "Egg Mania (USA) (En,Fr,Es)" description "Egg Mania (USA) (En,Fr,Es)" - rom ( name "Egg Mania (USA) (En,Fr,Es).gba" size 4194304 crc E8B15678 md5 3B58275A454884B6FA70FA007544C998 sha1 4E35DC68F8F00A01B79B36C7406B95511CFE86EC flags verified ) + rom ( name "Egg Mania (USA) (En,Fr,Es).gba" size 4194304 crc e8b15678 sha1 4E35DC68F8F00A01B79B36C7406B95511CFE86EC flags verified ) ) game ( name "Egg Mania - Tsukande! Mawashite! Dossun Puzzle!! (Japan)" description "Egg Mania - Tsukande! Mawashite! Dossun Puzzle!! (Japan)" - rom ( name "Egg Mania - Tsukande! Mawashite! Dossun Puzzle!! (Japan).gba" size 4194304 crc 4BEAB3AC md5 5B2C0B980E224FEF620F02437F3C9FF0 sha1 D175D957D8BABE6D2F9B2FB785304FD6E89C94CE ) -) - -game ( - name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta)" - description "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta)" - rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc F4C9A628 md5 E8FB25970F5634B9B159EDEF8C719090 sha1 1940CD1E8781C1A238AC7BF79F7B9A36D5E8B1A5 ) + rom ( name "Egg Mania - Tsukande! Mawashite! Dossun Puzzle!! (Japan).gba" size 4194304 crc 4beab3ac sha1 D175D957D8BABE6D2F9B2FB785304FD6E89C94CE ) ) game ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl)" description "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0B2961CE md5 882E200550D6ADDAFDC0F9AA2B03DEB1 sha1 5514D090D08643A07457E4698D848657AE5CD179 ) + rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0b2961ce sha1 5514D090D08643A07457E4698D848657AE5CD179 ) +) + +game ( + name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + description "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc f4c9a628 sha1 1940CD1E8781C1A238AC7BF79F7B9A36D5E8B1A5 ) ) game ( name "Elemix! (Japan)" description "Elemix! (Japan)" - rom ( name "Elemix! (Japan).gba" size 4194304 crc FA28BED8 md5 F65E87D6867D2AE8561FFCD1AB9ED57B sha1 E9E11A2D0A1AB20B103F846B8C123FBA42FD9C23 ) + rom ( name "Elemix! (Japan).gba" size 4194304 crc fa28bed8 sha1 E9E11A2D0A1AB20B103F846B8C123FBA42FD9C23 ) ) game ( name "Elevator Action - Old & New (Japan)" description "Elevator Action - Old & New (Japan)" - rom ( name "Elevator Action - Old & New (Japan).gba" size 8388608 crc 2D88526A md5 7BB739BA35535F79BDB44E7161349EC1 sha1 E4C023B5849556322C48012615AC40CC75CA750E ) + rom ( name "Elevator Action - Old & New (Japan).gba" size 8388608 crc 2d88526a sha1 E4C023B5849556322C48012615AC40CC75CA750E ) ) game ( name "Elf - The Movie (USA) (En,Fr,De,Es,It)" description "Elf - The Movie (USA) (En,Fr,De,Es,It)" - rom ( name "Elf - The Movie (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 9A1F8165 md5 1FE0AA775A55230C0CF8236F4376DBE9 sha1 06B313920E7ADC05A0F4C968D05F9DB70926C0AB ) + rom ( name "Elf - The Movie (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 9a1f8165 sha1 06B313920E7ADC05A0F4C968D05F9DB70926C0AB ) ) game ( name "Elf - The Movie (Europe) (En,Fr,De,Es,It)" description "Elf - The Movie (Europe) (En,Fr,De,Es,It)" - rom ( name "Elf - The Movie (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 1E107999 md5 BEB83CB1E4ECAE51A34EC3E99DA384B4 sha1 CAFD930F39683D92F9240E30F61FCCC5394B530C ) + rom ( name "Elf - The Movie (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 1e107999 sha1 CAFD930F39683D92F9240E30F61FCCC5394B530C ) ) game ( name "Elf Bowling 1 & 2 (USA)" description "Elf Bowling 1 & 2 (USA)" - rom ( name "Elf Bowling 1 & 2 (USA).gba" size 4194304 crc 68FEFF40 md5 25CDCF14F0FCE47D9C6C8155774948FA sha1 013F128C8D67F1165196B4F29297BCD4616C5033 ) + rom ( name "Elf Bowling 1 & 2 (USA).gba" size 4194304 crc 68feff40 sha1 013F128C8D67F1165196B4F29297BCD4616C5033 ) ) game ( name "Enchanted - Once Upon Andalasia (USA) (En,Fr)" description "Enchanted - Once Upon Andalasia (USA) (En,Fr)" - rom ( name "Enchanted - Once Upon Andalasia (USA) (En,Fr).gba" size 8388608 crc AF23FFFF md5 C088FB6231309F2B0BCD70B251052038 sha1 32D13E77A1FDE9D28D95F867EE11B85DF95D833E ) + rom ( name "Enchanted - Once Upon Andalasia (USA) (En,Fr).gba" size 8388608 crc af23ffff sha1 32D13E77A1FDE9D28D95F867EE11B85DF95D833E ) ) game ( name "Eragon (Europe) (En,Fr,De,Es,It)" description "Eragon (Europe) (En,Fr,De,Es,It)" - rom ( name "Eragon (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc BB05A63F md5 D0C000353F6BD4D93A1FBF5BE04B7585 sha1 92BB07AB53B4C704F611934C2B1B97C820B88693 flags verified ) + rom ( name "Eragon (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc bb05a63f sha1 92BB07AB53B4C704F611934C2B1B97C820B88693 flags verified ) ) game ( name "Eragon (USA)" description "Eragon (USA)" - rom ( name "Eragon (USA).gba" size 16777216 crc AF8AF2E8 md5 16E66D48B063671E1D6A3DB5FF0950BC sha1 B48BF75B6F9B2C69BF0B2B9B1920D9DDB69E66AA ) + rom ( name "Eragon (USA).gba" size 16777216 crc af8af2e8 sha1 B48BF75B6F9B2C69BF0B2B9B1920D9DDB69E66AA ) ) game ( name "Erementar Gerad - Tozasareshi Uta (Japan)" description "Erementar Gerad - Tozasareshi Uta (Japan)" - rom ( name "Erementar Gerad - Tozasareshi Uta (Japan).gba" size 8388608 crc 8C1AFCA4 md5 CE4EF88567B8D7AA8A0675A0BAC996B8 sha1 8C005E02B64CCF07DE5905311DB68983B0A3B76D ) + rom ( name "Erementar Gerad - Tozasareshi Uta (Japan).gba" size 8388608 crc 8c1afca4 sha1 8C005E02B64CCF07DE5905311DB68983B0A3B76D ) ) game ( name "ESPN Final Round Golf (Europe)" description "ESPN Final Round Golf (Europe)" - rom ( name "ESPN Final Round Golf (Europe).gba" size 8388608 crc 4878BBEA md5 E3C1E29F3560ED88F4A04E1C6CE87B3E sha1 D6AEAAAE47C8BD4F651F8CE2B97D61286B21E25A ) + rom ( name "ESPN Final Round Golf (Europe).gba" size 8388608 crc 4878bbea sha1 D6AEAAAE47C8BD4F651F8CE2B97D61286B21E25A flags verified ) ) game ( name "ESPN Final Round Golf 2002 (USA)" description "ESPN Final Round Golf 2002 (USA)" - rom ( name "ESPN Final Round Golf 2002 (USA).gba" size 8388608 crc C9BC75A5 md5 553F4CC7EA38A44642874A8501553E26 sha1 ECEE20B629A38BAB7EDBC972C70B2C968F50C23C ) + rom ( name "ESPN Final Round Golf 2002 (USA).gba" size 8388608 crc c9bc75a5 sha1 ECEE20B629A38BAB7EDBC972C70B2C968F50C23C ) ) game ( name "ESPN Great Outdoor Games - Bass 2002 (USA)" description "ESPN Great Outdoor Games - Bass 2002 (USA)" - rom ( name "ESPN Great Outdoor Games - Bass 2002 (USA).gba" size 8388608 crc DA9D815F md5 18F479A8D3E0AC87D5F6495A43F76876 sha1 D0F1E474C3FC4241DC400F0F52E591AC0798C452 ) + rom ( name "ESPN Great Outdoor Games - Bass 2002 (USA).gba" size 8388608 crc da9d815f sha1 D0F1E474C3FC4241DC400F0F52E591AC0798C452 ) ) game ( name "ESPN Great Outdoor Games - Bass Tournament (Europe)" description "ESPN Great Outdoor Games - Bass Tournament (Europe)" - rom ( name "ESPN Great Outdoor Games - Bass Tournament (Europe).gba" size 8388608 crc 28F0A921 md5 84B222956DE83BD53D37D9C3E0EE3AF1 sha1 D9320757C7543476614FC9F91E22FD96A30A32F4 ) + rom ( name "ESPN Great Outdoor Games - Bass Tournament (Europe).gba" size 8388608 crc 28f0a921 sha1 D9320757C7543476614FC9F91E22FD96A30A32F4 ) ) game ( name "ESPN International Winter Sports (Europe)" description "ESPN International Winter Sports (Europe)" - rom ( name "ESPN International Winter Sports (Europe).gba" size 4194304 crc A56AFBB7 md5 D61EFB2839076E80B05E55D5CF7A60E9 sha1 AC9521D3B98D898CC7D579CD0294AECB16DB0C41 flags verified ) + rom ( name "ESPN International Winter Sports (Europe).gba" size 4194304 crc a56afbb7 sha1 AC9521D3B98D898CC7D579CD0294AECB16DB0C41 flags verified ) ) game ( name "ESPN International Winter Sports 2002 (USA)" description "ESPN International Winter Sports 2002 (USA)" - rom ( name "ESPN International Winter Sports 2002 (USA).gba" size 4194304 crc FF51A9A9 md5 AEE485056BB727880AB4F4056B7DA477 sha1 EE674C8A32FC6BF1E7A381721C8F9125328F5EC9 ) + rom ( name "ESPN International Winter Sports 2002 (USA).gba" size 4194304 crc ff51a9a9 sha1 EE674C8A32FC6BF1E7A381721C8F9125328F5EC9 ) ) game ( name "ESPN Winter X-Games Snowboarding 2 (Europe)" description "ESPN Winter X-Games Snowboarding 2 (Europe)" - rom ( name "ESPN Winter X-Games Snowboarding 2 (Europe).gba" size 4194304 crc CE62F1F4 md5 7DDCF8A78366AD89E82FA8AA62B18777 sha1 C8CF4AEC13986AC66DCED918548318E8A551A689 flags verified ) + rom ( name "ESPN Winter X-Games Snowboarding 2 (Europe).gba" size 4194304 crc ce62f1f4 sha1 C8CF4AEC13986AC66DCED918548318E8A551A689 flags verified ) ) game ( name "ESPN Winter X-Games Snowboarding 2002 (Japan) (En)" description "ESPN Winter X-Games Snowboarding 2002 (Japan) (En)" - rom ( name "ESPN Winter X-Games Snowboarding 2002 (Japan) (En).gba" size 4194304 crc 3C5AC0C5 md5 E81A7F17531FEE0906CDCA576EFE41B4 sha1 4227CBC4F8C66D3688C1E13647503FB02CB64327 ) + rom ( name "ESPN Winter X-Games Snowboarding 2002 (Japan) (En).gba" size 4194304 crc 3c5ac0c5 sha1 4227CBC4F8C66D3688C1E13647503FB02CB64327 ) ) game ( name "ESPN Winter X-Games Snowboarding 2002 (USA)" description "ESPN Winter X-Games Snowboarding 2002 (USA)" - rom ( name "ESPN Winter X-Games Snowboarding 2002 (USA).gba" size 4194304 crc DE9E85BF md5 2F78A6EE027003FA5472EB90FC1322A7 sha1 6012907965D45326BEB27A98CADE8EFACEF5E377 ) + rom ( name "ESPN Winter X-Games Snowboarding 2002 (USA).gba" size 4194304 crc de9e85bf sha1 6012907965D45326BEB27A98CADE8EFACEF5E377 ) ) game ( name "ESPN X-Games Skateboarding (USA)" description "ESPN X-Games Skateboarding (USA)" - rom ( name "ESPN X-Games Skateboarding (USA).gba" size 8388608 crc 9766B309 md5 96DD9B5B227A30C25DB3265A2C755D6A sha1 1D3ABC8BED9118B1FC2C53E6C3AA7A10ECE8852D ) + rom ( name "ESPN X-Games Skateboarding (USA).gba" size 8388608 crc 9766b309 sha1 1D3ABC8BED9118B1FC2C53E6C3AA7A10ECE8852D ) ) game ( name "ESPN X-Games Skateboarding (Japan) (En)" description "ESPN X-Games Skateboarding (Japan) (En)" - rom ( name "ESPN X-Games Skateboarding (Japan) (En).gba" size 8388608 crc 7ABD7E9A md5 E53B022AE20ADABC1C5EDBABD3879D17 sha1 125BC2EE9A993ADCE91B37ED52B5200D3B276937 ) + rom ( name "ESPN X-Games Skateboarding (Japan) (En).gba" size 8388608 crc 7abd7e9a sha1 125BC2EE9A993ADCE91B37ED52B5200D3B276937 ) ) game ( name "ESPN X-Games Skateboarding (Europe) (En,Fr,De,Es,It)" description "ESPN X-Games Skateboarding (Europe) (En,Fr,De,Es,It)" - rom ( name "ESPN X-Games Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2C79E3D1 md5 6B9533F53075390CBB31078BA5D13346 sha1 F1FDB6D0689352C888E30A2BA222E9B2F92FDC78 ) + rom ( name "ESPN X-Games Skateboarding (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2c79e3d1 sha1 F1FDB6D0689352C888E30A2BA222E9B2F92FDC78 ) +) + +game ( + name "Essence of War, The - Glory Days (Europe) (En,Fr,De,Es,It)" + description "Essence of War, The - Glory Days (Europe) (En,Fr,De,Es,It)" + rom ( name "Essence of War, The - Glory Days (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 84adb2c3 sha1 D7E72D3EDFAB366962741A8959985439CBB8541B flags verified ) ) game ( name "European Super League (Europe) (En,Fr,De,Es,It)" description "European Super League (Europe) (En,Fr,De,Es,It)" - rom ( name "European Super League (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 748AD738 md5 A0B6C2FD85BA0FCDE92A15DAF7AACEAB sha1 F505D1F50B8C0BA2C571C67702D00AD7CA4ECD3A ) + rom ( name "European Super League (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 748ad738 sha1 F505D1F50B8C0BA2C571C67702D00AD7CA4ECD3A ) ) game ( - name "Ever Girl (USA)" - description "Ever Girl (USA)" - rom ( name "Ever Girl (USA).gba" size 4194304 crc AFBB1D35 md5 3D803864B58E1F842DD7AC944A52367A sha1 D6B58D50634B8541D631CE893222EF5F7BBDAC6A ) + name "everGirl (USA)" + description "everGirl (USA)" + rom ( name "everGirl (USA).gba" size 4194304 crc afbb1d35 sha1 D6B58D50634B8541D631CE893222EF5F7BBDAC6A ) ) game ( name "EX Monopoly (Japan)" description "EX Monopoly (Japan)" - rom ( name "EX Monopoly (Japan).gba" size 4194304 crc 916EFD5B md5 D6C5534615DE1C9478768506F5282FF0 sha1 DCBE4D167ADDA76F7D59BBAA96FEB03852806B97 ) + rom ( name "EX Monopoly (Japan).gba" size 4194304 crc 916efd5b sha1 DCBE4D167ADDA76F7D59BBAA96FEB03852806B97 flags verified ) +) + +game ( + name "EX Monopoly (Japan) (Rev 1)" + description "EX Monopoly (Japan) (Rev 1)" + rom ( name "EX Monopoly (Japan) (Rev 1).gba" size 4194304 crc d45abf21 sha1 29E1E9037ADA40D6A81360794C9AFF13FFAA7135 flags verified ) ) game ( name "Exciting Bass (Japan)" description "Exciting Bass (Japan)" - rom ( name "Exciting Bass (Japan).gba" size 8388608 crc AB27E52A md5 BEF73FC45C449C4940C14767B0926264 sha1 E7216240814E26527CE078BE2C3B835973CD7DCC ) + rom ( name "Exciting Bass (Japan).gba" size 8388608 crc ab27e52a sha1 E7216240814E26527CE078BE2C3B835973CD7DCC ) ) game ( name "Expedition der Stachelbeeren - Zoff im Zoo (Germany)" description "Expedition der Stachelbeeren - Zoff im Zoo (Germany)" - rom ( name "Expedition der Stachelbeeren - Zoff im Zoo (Germany).gba" size 4194304 crc 9D60610D md5 408ABFFA368F995D122792BF1DBBCBC1 sha1 61CA1A20372C25DBFF2A64901FF879336ACCF0BA ) -) - -game ( - name "Extreme Ghostbusters - Code Ecto-1 (USA)" - description "Extreme Ghostbusters - Code Ecto-1 (USA)" - rom ( name "Extreme Ghostbusters - Code Ecto-1 (USA).gba" size 4194304 crc E434FA06 md5 CA03360842A7C269F9A46DE25D5E779F sha1 A77EEFC2D6DD9069E5F53612707D0389F7645E99 ) + rom ( name "Expedition der Stachelbeeren - Zoff im Zoo (Germany).gba" size 4194304 crc 9d60610d sha1 61CA1A20372C25DBFF2A64901FF879336ACCF0BA ) ) game ( name "Extreme Ghostbusters - Code Ecto-1 (Europe) (En,Fr,De,Es,It,Pt)" description "Extreme Ghostbusters - Code Ecto-1 (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Extreme Ghostbusters - Code Ecto-1 (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 88CC876C md5 8CBBFC4BAC6A08F33E91D7CD6408A660 sha1 0B182D21997EC3BF2B27E9BF966A779A22715E7E flags verified ) + rom ( name "Extreme Ghostbusters - Code Ecto-1 (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 88cc876c sha1 0B182D21997EC3BF2B27E9BF966A779A22715E7E flags verified ) +) + +game ( + name "Extreme Ghostbusters - Code Ecto-1 (USA)" + description "Extreme Ghostbusters - Code Ecto-1 (USA)" + rom ( name "Extreme Ghostbusters - Code Ecto-1 (USA).gba" size 4194304 crc e434fa06 sha1 A77EEFC2D6DD9069E5F53612707D0389F7645E99 ) ) game ( name "Extreme Skate Adventure (USA, Europe)" description "Extreme Skate Adventure (USA, Europe)" - rom ( name "Extreme Skate Adventure (USA, Europe).gba" size 8388608 crc AD7BB7C8 md5 08D2FE71572E3537F2E7D7C08DAB5707 sha1 92A587C8775CBED8F402E6E42D9C05EBE547607E flags verified ) + rom ( name "Extreme Skate Adventure (USA, Europe).gba" size 8388608 crc ad7bb7c8 sha1 92A587C8775CBED8F402E6E42D9C05EBE547607E flags verified ) ) game ( name "Extreme Skate Adventure (Europe) (Fr,De)" description "Extreme Skate Adventure (Europe) (Fr,De)" - rom ( name "Extreme Skate Adventure (Europe) (Fr,De).gba" size 8388608 crc 58594AE9 md5 F2B1C6F30BD79859DC75AC2C8ABEE538 sha1 D213A7F6B5268BEA068D7B3EC3436360E77B29AC ) + rom ( name "Extreme Skate Adventure (Europe) (Fr,De).gba" size 8388608 crc 58594ae9 sha1 D213A7F6B5268BEA068D7B3EC3436360E77B29AC ) ) game ( - name "Eyeshield 21 Devilbats Devildays (Japan)" - description "Eyeshield 21 Devilbats Devildays (Japan)" - rom ( name "Eyeshield 21 Devilbats Devildays (Japan).gba" size 16777216 crc 620784AF md5 0260C5C32BEC282426882F5C127ED781 sha1 36D3271C8EA33B9D10A77738F7916B7EFE749BC7 flags verified ) + name "Extreme Skate Adventure (USA) (Rev 1)" + description "Extreme Skate Adventure (USA) (Rev 1)" + rom ( name "Extreme Skate Adventure (USA) (Rev 1).gba" size 8388608 crc 7a3ef446 sha1 AD2A7B48F473778D0006CCCF91C3058AD494BE8F flags verified ) +) + +game ( + name "Eyeshield 21 - DevilBats DevilDays (Japan)" + description "Eyeshield 21 - DevilBats DevilDays (Japan)" + rom ( name "Eyeshield 21 - DevilBats DevilDays (Japan).gba" size 16777216 crc 620784af sha1 36D3271C8EA33B9D10A77738F7916B7EFE749BC7 flags verified ) ) game ( name "EZ-Talk - Shokyuu Hen 1 (Japan)" description "EZ-Talk - Shokyuu Hen 1 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 1 (Japan).gba" size 8388608 crc D256F6F7 md5 6519CD2A2A4A4B35104502C3243279B2 sha1 8F79A8674D20BB50BBAB2DB0220333B3B0E57832 ) + rom ( name "EZ-Talk - Shokyuu Hen 1 (Japan).gba" size 8388608 crc d256f6f7 sha1 8F79A8674D20BB50BBAB2DB0220333B3B0E57832 ) ) game ( name "EZ-Talk - Shokyuu Hen 2 (Japan)" description "EZ-Talk - Shokyuu Hen 2 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 2 (Japan).gba" size 8388608 crc 38D91A54 md5 371E238E0398877BD758CC4CD4499AD0 sha1 931C2C9038988BA5C96CC10024F785ED42A939E1 ) + rom ( name "EZ-Talk - Shokyuu Hen 2 (Japan).gba" size 8388608 crc 38d91a54 sha1 931C2C9038988BA5C96CC10024F785ED42A939E1 ) ) game ( name "EZ-Talk - Shokyuu Hen 3 (Japan)" description "EZ-Talk - Shokyuu Hen 3 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 3 (Japan).gba" size 8388608 crc 5FA07E85 md5 A581264601CBD608BD19922DE4DC871E sha1 0E1CCE9EAFD452A55C232E08A5CA55440A6CCDD8 ) + rom ( name "EZ-Talk - Shokyuu Hen 3 (Japan).gba" size 8388608 crc 5fa07e85 sha1 0E1CCE9EAFD452A55C232E08A5CA55440A6CCDD8 ) ) game ( name "EZ-Talk - Shokyuu Hen 4 (Japan)" description "EZ-Talk - Shokyuu Hen 4 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 4 (Japan).gba" size 8388608 crc 0CA6DCF1 md5 E03754F31D720DAEB5C6968C23647882 sha1 6B60EFF8A05BFC5693B032BF74DB9B0DC1FF9E5B ) + rom ( name "EZ-Talk - Shokyuu Hen 4 (Japan).gba" size 8388608 crc 0ca6dcf1 sha1 6B60EFF8A05BFC5693B032BF74DB9B0DC1FF9E5B ) ) game ( name "EZ-Talk - Shokyuu Hen 5 (Japan)" description "EZ-Talk - Shokyuu Hen 5 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 5 (Japan).gba" size 8388608 crc A0E8EB88 md5 0EC6477593E4C9273B91676E464488F6 sha1 479BE21EC3E2B973D76D6D6B1B5A54EC977EEDD1 ) + rom ( name "EZ-Talk - Shokyuu Hen 5 (Japan).gba" size 8388608 crc a0e8eb88 sha1 479BE21EC3E2B973D76D6D6B1B5A54EC977EEDD1 ) ) game ( name "EZ-Talk - Shokyuu Hen 6 (Japan)" description "EZ-Talk - Shokyuu Hen 6 (Japan)" - rom ( name "EZ-Talk - Shokyuu Hen 6 (Japan).gba" size 8388608 crc A8AB645D md5 B51533D78E10FAA7D17774ADBBB03F44 sha1 4850D23D7C17F951AF7C54251B10E97AC41FD5B6 ) + rom ( name "EZ-Talk - Shokyuu Hen 6 (Japan).gba" size 8388608 crc a8ab645d sha1 4850D23D7C17F951AF7C54251B10E97AC41FD5B6 ) ) game ( name "F-14 Tomcat (USA, Europe)" description "F-14 Tomcat (USA, Europe)" - rom ( name "F-14 Tomcat (USA, Europe).gba" size 4194304 crc 1428FE1C md5 399E38FFBA58FCCF07950791FAE00539 sha1 CB7918076ABE28DDB29C420A3BBBA617915F2DE8 ) + rom ( name "F-14 Tomcat (USA, Europe).gba" size 4194304 crc 1428fe1c sha1 CB7918076ABE28DDB29C420A3BBBA617915F2DE8 ) ) game ( name "F-Zero - Climax (Japan)" description "F-Zero - Climax (Japan)" - rom ( name "F-Zero - Climax (Japan).gba" size 16777216 crc DBDC71E3 md5 8D27B349BCA44D938B67F9A28712F6C9 sha1 6EB9208C493E8BAA43ECC0DACF71A8CB631BE7CA flags verified ) + rom ( name "F-Zero - Climax (Japan).gba" size 16777216 crc dbdc71e3 sha1 6EB9208C493E8BAA43ECC0DACF71A8CB631BE7CA flags verified ) ) game ( name "F-Zero - Falcon Densetsu (Japan)" description "F-Zero - Falcon Densetsu (Japan)" - rom ( name "F-Zero - Falcon Densetsu (Japan).gba" size 16777216 crc 2446B920 md5 9175A1771A550ED2237DE4231AEBC1F1 sha1 35F47A985873B3018D4BE05AB7B539DFE3BFF21A ) + rom ( name "F-Zero - Falcon Densetsu (Japan).gba" size 16777216 crc 2446b920 sha1 35F47A985873B3018D4BE05AB7B539DFE3BFF21A ) ) game ( name "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It)" description "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It)" - rom ( name "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc F1D5601B md5 66900CC9E3051638D89B364150B31ACD sha1 1BFE5E96138CF0ED5D3D33BFEC215B734AD32D3A flags verified ) + rom ( name "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc f1d5601b sha1 1BFE5E96138CF0ED5D3D33BFEC215B734AD32D3A flags verified ) ) game ( name "F-Zero - GP Legend (USA)" description "F-Zero - GP Legend (USA)" - rom ( name "F-Zero - GP Legend (USA).gba" size 16777216 crc 781AAB58 md5 B6984CA369145367AB79EB33F2F3480E sha1 977588D9D27B7115E0BB309FB019AE81B9F413FF ) + rom ( name "F-Zero - GP Legend (USA).gba" size 16777216 crc 781aab58 sha1 977588D9D27B7115E0BB309FB019AE81B9F413FF flags verified ) +) + +game ( + name "F-Zero - GP Legend (USA) (Wii U Virtual Console)" + description "F-Zero - GP Legend (USA) (Wii U Virtual Console)" + rom ( name "F-Zero - GP Legend (USA) (Wii U Virtual Console).gba" size 16777216 crc 9075c6fd sha1 6EF9BD0D816FBE347E72CAB07068C939C9F3D9B6 flags verified ) +) + +game ( + name "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "F-Zero - GP Legend (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 16777216 crc d9b2d53d sha1 82791235ABE3BBD5866E228E12CD9AAAE0F5CDE8 flags verified ) ) game ( name "F-Zero - Maximum Velocity (USA, Europe)" description "F-Zero - Maximum Velocity (USA, Europe)" - rom ( name "F-Zero - Maximum Velocity (USA, Europe).gba" size 4194304 crc BD5E9798 md5 55C14323547AA4F83E5EEDE98D0417F3 sha1 8A08E29EC987F9CBDDE21C34D5F7657AA7BA0BE6 flags verified ) + rom ( name "F-Zero - Maximum Velocity (USA, Europe).gba" size 4194304 crc bd5e9798 sha1 8A08E29EC987F9CBDDE21C34D5F7657AA7BA0BE6 flags verified ) +) + +game ( + name "F-Zero - Maximum Velocity (USA) (Wii U Virtual Console)" + description "F-Zero - Maximum Velocity (USA) (Wii U Virtual Console)" + rom ( name "F-Zero - Maximum Velocity (USA) (Wii U Virtual Console).gba" size 4194304 crc 4b5f1cdd sha1 BD08E426C743C7429EFD576CE0EF00A70CFFD72A flags verified ) ) game ( name "F-Zero for Game Boy Advance (Japan)" description "F-Zero for Game Boy Advance (Japan)" - rom ( name "F-Zero for Game Boy Advance (Japan).gba" size 4194304 crc 25E3FC9A md5 0915AC62D58A160028EB47141657013F sha1 CD8648B7158CF7C979CC05DEA4C1AA927496E8B7 ) + rom ( name "F-Zero for Game Boy Advance (Japan).gba" size 4194304 crc 25e3fc9a sha1 CD8648B7158CF7C979CC05DEA4C1AA927496E8B7 flags verified ) ) game ( name "F1 2002 (USA, Europe)" description "F1 2002 (USA, Europe)" - rom ( name "F1 2002 (USA, Europe).gba" size 4194304 crc 7DD20F33 md5 C5E3A3D61B6C46D78BD66BD842FBA8B8 sha1 C5B3860403425DA6F062DD5B6D433781051E1A85 flags verified ) + rom ( name "F1 2002 (USA, Europe).gba" size 4194304 crc 7dd20f33 sha1 C5B3860403425DA6F062DD5B6D433781051E1A85 flags verified ) ) game ( name "F1 2002 (Europe) (En,Fr,De,Es,It)" description "F1 2002 (Europe) (En,Fr,De,Es,It)" - rom ( name "F1 2002 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc AAC551FD md5 AB1C6C1E37DF4C3DACF88A1ECBE59AFD sha1 AE8C986DE946E7FDE8249E958C6743816FB05784 flags verified ) + rom ( name "F1 2002 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc aac551fd sha1 AE8C986DE946E7FDE8249E958C6743816FB05784 flags verified ) ) game ( name "F24 Stealth Fighter (USA)" description "F24 Stealth Fighter (USA)" - rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387EA7C md5 E6DDD053F1C7C9F3DEC98F3B8F8D46F4 sha1 AC9188C7836DD388B488D02E8774DC61B1D30B4A flags verified ) + rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387ea7c sha1 AC9188C7836DD388B488D02E8774DC61B1D30B4A flags verified ) ) game ( name "Fairly OddParents!, The - Breakin' da Rules (USA)" description "Fairly OddParents!, The - Breakin' da Rules (USA)" - rom ( name "Fairly OddParents!, The - Breakin' da Rules (USA).gba" size 4194304 crc 9BF9CA2F md5 E7AF002A857D9960E3B5CE7A7F524813 sha1 35A84D39BFA1BF2C528D770E9B3D70A69A623973 ) + rom ( name "Fairly OddParents!, The - Breakin' da Rules (USA).gba" size 4194304 crc 9bf9ca2f sha1 35A84D39BFA1BF2C528D770E9B3D70A69A623973 ) ) game ( name "Fairly OddParents!, The - Clash with the Anti-World (USA)" description "Fairly OddParents!, The - Clash with the Anti-World (USA)" - rom ( name "Fairly OddParents!, The - Clash with the Anti-World (USA).gba" size 4194304 crc 6FD773CD md5 778EB070E354CAA92A1BA7E8B5D5DF29 sha1 0A0BABA3F66B7508236AEE7D74F21188E3F6B315 ) + rom ( name "Fairly OddParents!, The - Clash with the Anti-World (USA).gba" size 4194304 crc 6fd773cd sha1 0A0BABA3F66B7508236AEE7D74F21188E3F6B315 ) ) game ( name "Fairly OddParents!, The - Clash with the Anti-World (Europe) (En,De,Es,Nl)" description "Fairly OddParents!, The - Clash with the Anti-World (Europe) (En,De,Es,Nl)" - rom ( name "Fairly OddParents!, The - Clash with the Anti-World (Europe) (En,De,Es,Nl).gba" size 4194304 crc 91E7BA6C md5 6710E9E70FC995F7F7A7B8D66AA1863B sha1 701162F2CD3678AB20E3D1D095604B6A2FC9DBEA flags verified ) + rom ( name "Fairly OddParents!, The - Clash with the Anti-World (Europe) (En,De,Es,Nl).gba" size 4194304 crc 91e7ba6c sha1 701162F2CD3678AB20E3D1D095604B6A2FC9DBEA flags verified ) ) game ( name "Fairly OddParents!, The - Enter the Cleft (USA)" description "Fairly OddParents!, The - Enter the Cleft (USA)" - rom ( name "Fairly OddParents!, The - Enter the Cleft (USA).gba" size 4194304 crc B0533F41 md5 E4AC9D76D7153C94919CE5A73DC984A4 sha1 CD9BD32CBF86D83688FA86AA24604391A779E5AB flags verified ) + rom ( name "Fairly OddParents!, The - Enter the Cleft (USA).gba" size 4194304 crc b0533f41 sha1 CD9BD32CBF86D83688FA86AA24604391A779E5AB flags verified ) ) game ( name "Fairly OddParents!, The - Shadow Showdown (USA)" description "Fairly OddParents!, The - Shadow Showdown (USA)" - rom ( name "Fairly OddParents!, The - Shadow Showdown (USA).gba" size 4194304 crc BA72E185 md5 2D7E907C4E4741F1A2FCF4C4CAAE030E sha1 6DCAB3A6A888CC992E0B9432B828E692424E404B ) + rom ( name "Fairly OddParents!, The - Shadow Showdown (USA).gba" size 4194304 crc ba72e185 sha1 6DCAB3A6A888CC992E0B9432B828E692424E404B ) ) game ( name "Fairly OddParents!, The - Shadow Showdown (Europe)" description "Fairly OddParents!, The - Shadow Showdown (Europe)" - rom ( name "Fairly OddParents!, The - Shadow Showdown (Europe).gba" size 4194304 crc 23188CB3 md5 12B7A60B8FABA2B44B1FDF1396578037 sha1 CB645E6BE17D2F0F5467804B5CDFA12FC312C881 ) + rom ( name "Fairly OddParents!, The - Shadow Showdown (Europe).gba" size 4194304 crc 23188cb3 sha1 CB645E6BE17D2F0F5467804B5CDFA12FC312C881 ) ) game ( name "Famicom Mini - Dai-2-ji Super Robot Taisen (Japan) (Promo)" description "Famicom Mini - Dai-2-ji Super Robot Taisen (Japan) (Promo)" - rom ( name "Famicom Mini - Dai-2-ji Super Robot Taisen (Japan) (Promo).gba" size 4194304 crc 423B8FC5 md5 27EAB36CF2CC7F11C0A194EAD66F2570 sha1 842CAE5E8156F9DA5C7271A265F8DD0C763AEFE3 ) + rom ( name "Famicom Mini - Dai-2-ji Super Robot Taisen (Japan) (Promo).gba" size 4194304 crc 423b8fc5 sha1 842CAE5E8156F9DA5C7271A265F8DD0C763AEFE3 ) ) game ( name "Famicom Mini - Kidou Senshi Z Gundam - Hot Scramble (Japan) (Promo)" description "Famicom Mini - Kidou Senshi Z Gundam - Hot Scramble (Japan) (Promo)" - rom ( name "Famicom Mini - Kidou Senshi Z Gundam - Hot Scramble (Japan) (Promo).gba" size 4194304 crc FAE4FDEC md5 E8198EEE6C26FC9966D78B8BD681D583 sha1 50AC24A3A42D11B96FE62A8F248F0A930A48EB78 ) + rom ( name "Famicom Mini - Kidou Senshi Z Gundam - Hot Scramble (Japan) (Promo).gba" size 4194304 crc fae4fdec sha1 50AC24A3A42D11B96FE62A8F248F0A930A48EB78 ) ) game ( name "Famicom Mini 01 - Super Mario Bros. (Japan) (En) (Rev 1)" description "Famicom Mini 01 - Super Mario Bros. (Japan) (En) (Rev 1)" - rom ( name "Famicom Mini 01 - Super Mario Bros. (Japan) (En) (Rev 1).gba" size 4194304 crc 5848884C md5 0C9ACCC7B0525D01C304B320F31FDD12 sha1 28A4F19E566A5A9AE3470045E99A3F03E786244E flags verified ) + rom ( name "Famicom Mini 01 - Super Mario Bros. (Japan) (En) (Rev 1).gba" size 4194304 crc 5848884c sha1 28A4F19E566A5A9AE3470045E99A3F03E786244E flags verified ) ) game ( name "Famicom Mini 02 - Donkey Kong (Japan) (En)" description "Famicom Mini 02 - Donkey Kong (Japan) (En)" - rom ( name "Famicom Mini 02 - Donkey Kong (Japan) (En).gba" size 4194304 crc 86D346AF md5 38B3CB43042199D7F27C2AE48C814EFD sha1 13D496A5E4E0E3C4C65A99F3DD3BCC4973604CED ) + rom ( name "Famicom Mini 02 - Donkey Kong (Japan) (En).gba" size 4194304 crc 86d346af sha1 13D496A5E4E0E3C4C65A99F3DD3BCC4973604CED ) ) game ( name "Famicom Mini 03 - Ice Climber (Japan) (En)" description "Famicom Mini 03 - Ice Climber (Japan) (En)" - rom ( name "Famicom Mini 03 - Ice Climber (Japan) (En).gba" size 4194304 crc 5646F9D1 md5 0DD74002834F454214E9CCC24E8D0D37 sha1 B82C00D059D9C38C3EA493032FA1D36D5185EF80 ) + rom ( name "Famicom Mini 03 - Ice Climber (Japan) (En).gba" size 4194304 crc 5646f9d1 sha1 B82C00D059D9C38C3EA493032FA1D36D5185EF80 ) ) game ( name "Famicom Mini 04 - Excitebike (Japan) (En)" description "Famicom Mini 04 - Excitebike (Japan) (En)" - rom ( name "Famicom Mini 04 - Excitebike (Japan) (En).gba" size 4194304 crc 319CDF36 md5 1BEDC59516027735021BF3BBEEBB7A7F sha1 D7DE5A18A950C7DBC5174AE0C293FB365F0B98CB ) + rom ( name "Famicom Mini 04 - Excitebike (Japan) (En).gba" size 4194304 crc 319cdf36 sha1 D7DE5A18A950C7DBC5174AE0C293FB365F0B98CB ) ) game ( name "Famicom Mini 05 - Zelda no Densetsu 1 - The Hyrule Fantasy (Japan)" description "Famicom Mini 05 - Zelda no Densetsu 1 - The Hyrule Fantasy (Japan)" - rom ( name "Famicom Mini 05 - Zelda no Densetsu 1 - The Hyrule Fantasy (Japan).gba" size 4194304 crc 114E37A1 md5 7634CCC0B976463E6C2F769120E9EA75 sha1 F7A425F77A26A26B8E3F6ADDE2BB89AE1F63377E ) + rom ( name "Famicom Mini 05 - Zelda no Densetsu 1 - The Hyrule Fantasy (Japan).gba" size 4194304 crc 114e37a1 sha1 F7A425F77A26A26B8E3F6ADDE2BB89AE1F63377E flags verified ) ) game ( name "Famicom Mini 06 - Pac-Man (Japan) (En)" description "Famicom Mini 06 - Pac-Man (Japan) (En)" - rom ( name "Famicom Mini 06 - Pac-Man (Japan) (En).gba" size 4194304 crc 3FEC1606 md5 5AA326B89D7A21BE6B18660D2AF00B73 sha1 91458BC32C78FE412F725C0D3B777DD5AF8AC10B ) + rom ( name "Famicom Mini 06 - Pac-Man (Japan) (En).gba" size 4194304 crc 3fec1606 sha1 91458BC32C78FE412F725C0D3B777DD5AF8AC10B ) ) game ( name "Famicom Mini 07 - Xevious (Japan) (En)" description "Famicom Mini 07 - Xevious (Japan) (En)" - rom ( name "Famicom Mini 07 - Xevious (Japan) (En).gba" size 4194304 crc 1CD1F78C md5 75ABA692225B15A27DE0221C78B1FB2C sha1 5CD976A599BC717136BE6D34D5ED05CACCDAC459 ) + rom ( name "Famicom Mini 07 - Xevious (Japan) (En).gba" size 4194304 crc 1cd1f78c sha1 5CD976A599BC717136BE6D34D5ED05CACCDAC459 ) ) game ( name "Famicom Mini 08 - Mappy (Japan) (En)" description "Famicom Mini 08 - Mappy (Japan) (En)" - rom ( name "Famicom Mini 08 - Mappy (Japan) (En).gba" size 4194304 crc D4B0779A md5 9CF0D63B1D23A5A9D63582D5D732DD81 sha1 504AC987F866E52434633725D2425C12F4829E8B ) + rom ( name "Famicom Mini 08 - Mappy (Japan) (En).gba" size 4194304 crc d4b0779a sha1 504AC987F866E52434633725D2425C12F4829E8B ) ) game ( name "Famicom Mini 09 - Bomber Man (Japan) (En)" description "Famicom Mini 09 - Bomber Man (Japan) (En)" - rom ( name "Famicom Mini 09 - Bomber Man (Japan) (En).gba" size 4194304 crc 3B92EE60 md5 2A8FD829E00A657483862065FA1426BD sha1 55FAF165142357F671DC3CC2841379012A281836 ) + rom ( name "Famicom Mini 09 - Bomber Man (Japan) (En).gba" size 4194304 crc 3b92ee60 sha1 55FAF165142357F671DC3CC2841379012A281836 ) ) game ( name "Famicom Mini 10 - Star Soldier (Japan) (En)" description "Famicom Mini 10 - Star Soldier (Japan) (En)" - rom ( name "Famicom Mini 10 - Star Soldier (Japan) (En).gba" size 4194304 crc 0958EE09 md5 51E7AC9C4B2E17F9417ABAB0E2A4FFCF sha1 072A4AAB0E817CF9F6F7E8E9ECA01CE9129A69F7 ) + rom ( name "Famicom Mini 10 - Star Soldier (Japan) (En).gba" size 4194304 crc 0958ee09 sha1 072A4AAB0E817CF9F6F7E8E9ECA01CE9129A69F7 ) ) game ( name "Famicom Mini 11 - Mario Bros. (Japan)" description "Famicom Mini 11 - Mario Bros. (Japan)" - rom ( name "Famicom Mini 11 - Mario Bros. (Japan).gba" size 4194304 crc 9CD4D6CF md5 D3C35D62376F2C53E5207EF1839E9A01 sha1 E2A48D19AE151C9AF3FA8199D608FB8CFA417031 ) + rom ( name "Famicom Mini 11 - Mario Bros. (Japan).gba" size 4194304 crc 9cd4d6cf sha1 E2A48D19AE151C9AF3FA8199D608FB8CFA417031 ) ) game ( name "Famicom Mini 12 - Clu Clu Land (Japan)" description "Famicom Mini 12 - Clu Clu Land (Japan)" - rom ( name "Famicom Mini 12 - Clu Clu Land (Japan).gba" size 4194304 crc C4C03AA8 md5 0C3E9BE48D9EB03538D15342DF0D5ED2 sha1 132B71A3E51421F1C2DA6C12C72408CA7DB262C2 ) + rom ( name "Famicom Mini 12 - Clu Clu Land (Japan).gba" size 4194304 crc c4c03aa8 sha1 132B71A3E51421F1C2DA6C12C72408CA7DB262C2 ) ) game ( name "Famicom Mini 13 - Balloon Fight (Japan)" description "Famicom Mini 13 - Balloon Fight (Japan)" - rom ( name "Famicom Mini 13 - Balloon Fight (Japan).gba" size 4194304 crc 45D299D7 md5 43CF7F82D9C674A81731A2880E62577C sha1 B3E9710536C5E7CC13FDB2169CA31C5FEDA8AC8B flags verified ) + rom ( name "Famicom Mini 13 - Balloon Fight (Japan).gba" size 4194304 crc 45d299d7 sha1 B3E9710536C5E7CC13FDB2169CA31C5FEDA8AC8B flags verified ) ) game ( name "Famicom Mini 14 - Wrecking Crew (Japan)" description "Famicom Mini 14 - Wrecking Crew (Japan)" - rom ( name "Famicom Mini 14 - Wrecking Crew (Japan).gba" size 4194304 crc 6C0611F0 md5 07E2833F49ABB1B8310887CB2A7F125C sha1 2CF08CA3B76E6D1F5705457C6296826C71A38A34 ) + rom ( name "Famicom Mini 14 - Wrecking Crew (Japan).gba" size 4194304 crc 6c0611f0 sha1 2CF08CA3B76E6D1F5705457C6296826C71A38A34 ) ) game ( name "Famicom Mini 15 - Dr. Mario (Japan)" description "Famicom Mini 15 - Dr. Mario (Japan)" - rom ( name "Famicom Mini 15 - Dr. Mario (Japan).gba" size 4194304 crc E23A7ED0 md5 5052C6228AB288508F19A5A49608CEB1 sha1 35633B66CC920AC45E061CF40EB7761405881CEF ) + rom ( name "Famicom Mini 15 - Dr. Mario (Japan).gba" size 4194304 crc e23a7ed0 sha1 35633B66CC920AC45E061CF40EB7761405881CEF ) ) game ( name "Famicom Mini 16 - Dig Dug (Japan)" description "Famicom Mini 16 - Dig Dug (Japan)" - rom ( name "Famicom Mini 16 - Dig Dug (Japan).gba" size 4194304 crc 57513B63 md5 2A788508404BC0CC9D1AFBA8E4EECBE5 sha1 7D870C79A7576630A16471D91BD23C1681B7DDC3 ) + rom ( name "Famicom Mini 16 - Dig Dug (Japan).gba" size 4194304 crc 57513b63 sha1 7D870C79A7576630A16471D91BD23C1681B7DDC3 ) ) game ( name "Famicom Mini 17 - Takahashi Meijin no Bouken-jima (Japan)" description "Famicom Mini 17 - Takahashi Meijin no Bouken-jima (Japan)" - rom ( name "Famicom Mini 17 - Takahashi Meijin no Bouken-jima (Japan).gba" size 4194304 crc 3BEF3B74 md5 8BC6682A224F5CE290FEE24BDCD9AE54 sha1 DBD9EED25971EF42DCE3852FAA778571C4BB3FAA ) + rom ( name "Famicom Mini 17 - Takahashi Meijin no Bouken-jima (Japan).gba" size 4194304 crc 3bef3b74 sha1 DBD9EED25971EF42DCE3852FAA778571C4BB3FAA ) ) game ( - name "Famicom Mini 18 - Makai Mura (Japan)" - description "Famicom Mini 18 - Makai Mura (Japan)" - rom ( name "Famicom Mini 18 - Makai Mura (Japan).gba" size 4194304 crc 85261EC6 md5 E31BD6871331A0AE82BA418BC254234D sha1 D52329277B87FFBFE87E3E7F5CA8153170FE177E ) + name "Famicom Mini 18 - Makaimura (Japan)" + description "Famicom Mini 18 - Makaimura (Japan)" + rom ( name "Famicom Mini 18 - Makaimura (Japan).gba" size 4194304 crc 85261ec6 sha1 D52329277B87FFBFE87E3E7F5CA8153170FE177E flags verified ) ) game ( name "Famicom Mini 19 - Twin Bee (Japan)" description "Famicom Mini 19 - Twin Bee (Japan)" - rom ( name "Famicom Mini 19 - Twin Bee (Japan).gba" size 4194304 crc 26A17681 md5 5FEB34C125B4D6072BAE444C0DC794EA sha1 B3FA545FFDBCCB612B56C817C64AB16580B1A1AD ) + rom ( name "Famicom Mini 19 - Twin Bee (Japan).gba" size 4194304 crc 26a17681 sha1 B3FA545FFDBCCB612B56C817C64AB16580B1A1AD ) ) game ( name "Famicom Mini 20 - Ganbare Goemon! - Karakuri Douchuu (Japan)" description "Famicom Mini 20 - Ganbare Goemon! - Karakuri Douchuu (Japan)" - rom ( name "Famicom Mini 20 - Ganbare Goemon! - Karakuri Douchuu (Japan).gba" size 4194304 crc 10B48DBA md5 697EDC3418B89D1054B59C33C994C08A sha1 B681C2D7979B008D98EDA75AE12BC071CC21DA6F ) + rom ( name "Famicom Mini 20 - Ganbare Goemon! - Karakuri Douchuu (Japan).gba" size 4194304 crc 10b48dba sha1 B681C2D7979B008D98EDA75AE12BC071CC21DA6F ) ) game ( name "Famicom Mini 21 - Super Mario Bros. 2 (Japan)" description "Famicom Mini 21 - Super Mario Bros. 2 (Japan)" - rom ( name "Famicom Mini 21 - Super Mario Bros. 2 (Japan).gba" size 4194304 crc F55674A3 md5 5C46126C6A429A3704F15139DADB19BE sha1 3455D771F2E974E1AC55543AF741AE7FDED0312A ) + rom ( name "Famicom Mini 21 - Super Mario Bros. 2 (Japan).gba" size 4194304 crc f55674a3 sha1 3455D771F2E974E1AC55543AF741AE7FDED0312A ) ) game ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan)" description "Famicom Mini 22 - Nazo no Murasame Jou (Japan)" - rom ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan).gba" size 4194304 crc 8233349C md5 E559A4743A79FB5374872D758C3C67B2 sha1 0100D4E94C30ADF73CD6082B89911DEDF723ECD5 ) + rom ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan).gba" size 4194304 crc 8233349c sha1 0100D4E94C30ADF73CD6082B89911DEDF723ECD5 flags verified ) ) game ( name "Famicom Mini 23 - Metroid (Japan)" description "Famicom Mini 23 - Metroid (Japan)" - rom ( name "Famicom Mini 23 - Metroid (Japan).gba" size 4194304 crc ABECCDAB md5 F24E3E9760003F0629B31FF96E9427B6 sha1 2E1DF85E7D41198BD56735C5C9746904464D7150 ) + rom ( name "Famicom Mini 23 - Metroid (Japan).gba" size 4194304 crc abeccdab sha1 2E1DF85E7D41198BD56735C5C9746904464D7150 flags verified ) ) game ( name "Famicom Mini 24 - Hikari Shinwa - Palthena no Kagami (Japan)" description "Famicom Mini 24 - Hikari Shinwa - Palthena no Kagami (Japan)" - rom ( name "Famicom Mini 24 - Hikari Shinwa - Palthena no Kagami (Japan).gba" size 4194304 crc F311EDAC md5 76759E14E1A4072397C105419D702735 sha1 CCA6EB41EA8EDC8115994FAD2A0B329AF44BB659 ) + rom ( name "Famicom Mini 24 - Hikari Shinwa - Palthena no Kagami (Japan).gba" size 4194304 crc f311edac sha1 CCA6EB41EA8EDC8115994FAD2A0B329AF44BB659 ) ) game ( name "Famicom Mini 25 - The Legend of Zelda 2 - Link no Bouken (Japan)" description "Famicom Mini 25 - The Legend of Zelda 2 - Link no Bouken (Japan)" - rom ( name "Famicom Mini 25 - The Legend of Zelda 2 - Link no Bouken (Japan).gba" size 4194304 crc 1CBE712A md5 825BDD7778A8740BF04421164E233C39 sha1 203AF9B451880595E8344BB508E839DC65B83930 ) + rom ( name "Famicom Mini 25 - The Legend of Zelda 2 - Link no Bouken (Japan).gba" size 4194304 crc 1cbe712a sha1 203AF9B451880595E8344BB508E839DC65B83930 ) ) game ( name "Famicom Mini 26 - Famicom Mukashibanashi - Shin Onigashima - Zen, Kouhen (Japan)" description "Famicom Mini 26 - Famicom Mukashibanashi - Shin Onigashima - Zen, Kouhen (Japan)" - rom ( name "Famicom Mini 26 - Famicom Mukashibanashi - Shin Onigashima - Zen, Kouhen (Japan).gba" size 4194304 crc 63B51337 md5 4F8F9AB44EF8C3503102C22DFF34AA7A sha1 2F938A543FEB9506C8C41DBC9822B09D60BFBE75 ) + rom ( name "Famicom Mini 26 - Famicom Mukashibanashi - Shin Onigashima - Zen, Kouhen (Japan).gba" size 4194304 crc 63b51337 sha1 2F938A543FEB9506C8C41DBC9822B09D60BFBE75 ) ) game ( name "Famicom Mini 27 - Famicom Tantei Club - Kieta Koukeisha - Zen, Kouhen (Japan)" description "Famicom Mini 27 - Famicom Tantei Club - Kieta Koukeisha - Zen, Kouhen (Japan)" - rom ( name "Famicom Mini 27 - Famicom Tantei Club - Kieta Koukeisha - Zen, Kouhen (Japan).gba" size 4194304 crc 3CF43405 md5 87097E92087EDE6F94CAD64C847542A3 sha1 BC7824CF06073DAD51C1132DE5EF336965D07B46 ) + rom ( name "Famicom Mini 27 - Famicom Tantei Club - Kieta Koukeisha - Zen, Kouhen (Japan).gba" size 4194304 crc 3cf43405 sha1 BC7824CF06073DAD51C1132DE5EF336965D07B46 ) ) game ( name "Famicom Mini 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen, Kouhen (Japan)" description "Famicom Mini 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen, Kouhen (Japan)" - rom ( name "Famicom Mini 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen, Kouhen (Japan).gba" size 4194304 crc 75E1B220 md5 782ECBF2E6B30EA684B34CE3E21310DA sha1 1DB238E8065D4EF17BCFA1E839815348DA4A7353 ) + rom ( name "Famicom Mini 28 - Famicom Tantei Club Part II - Ushiro ni Tatsu Shoujo - Zen, Kouhen (Japan).gba" size 4194304 crc 75e1b220 sha1 1DB238E8065D4EF17BCFA1E839815348DA4A7353 ) ) game ( name "Famicom Mini 29 - Akumajou Dracula (Japan)" description "Famicom Mini 29 - Akumajou Dracula (Japan)" - rom ( name "Famicom Mini 29 - Akumajou Dracula (Japan).gba" size 4194304 crc 012FA057 md5 38716F2C17A53D1FF6FB2231BF9E543A sha1 DCFB0F7CB4EDB67F2D449C43BA33DEF09DB38BF9 ) + rom ( name "Famicom Mini 29 - Akumajou Dracula (Japan).gba" size 4194304 crc 012fa057 sha1 DCFB0F7CB4EDB67F2D449C43BA33DEF09DB38BF9 flags verified ) ) game ( name "Famicom Mini 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)" description "Famicom Mini 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan)" - rom ( name "Famicom Mini 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan).gba" size 4194304 crc 9ED2DAEB md5 DC5AB6E75BD9C0CA3C92CC04EE94A24D sha1 D3E54CFC3E0B08F54BD8B4520E0B661FBF0A75D8 ) + rom ( name "Famicom Mini 30 - SD Gundam World - Gachapon Senshi Scramble Wars (Japan).gba" size 4194304 crc 9ed2daeb sha1 D3E54CFC3E0B08F54BD8B4520E0B661FBF0A75D8 ) +) + +game ( + name "Famicom Mini Collection (China) (Proto)" + description "Famicom Mini Collection (China) (Proto)" + rom ( name "Famicom Mini Collection (China) (Proto).gba" size 4194304 crc b9283b7c sha1 288E48DBD2CB20790E4093B4606B5DAC2C6DAC6C flags verified ) ) game ( name "Famille Delajungle, La - A la Poursuite de Darwin (France)" description "Famille Delajungle, La - A la Poursuite de Darwin (France)" - rom ( name "Famille Delajungle, La - A la Poursuite de Darwin (France).gba" size 4194304 crc F344D661 md5 B618FDD6303B5FA0F38C472E7BA6CC26 sha1 B2EEC085F441EB3B9D29050390E2191860D19439 ) + rom ( name "Famille Delajungle, La - A la Poursuite de Darwin (France).gba" size 4194304 crc f344d661 sha1 B2EEC085F441EB3B9D29050390E2191860D19439 ) ) game ( name "Famille Delajungle, La - Le Film (France)" description "Famille Delajungle, La - Le Film (France)" - rom ( name "Famille Delajungle, La - Le Film (France).gba" size 4194304 crc AFA71C84 md5 FDA461B129B3630E13A9173A4ED5FD88 sha1 C6F2B2F6239ADCEF1AB2C95AD94BB7A01143D0B1 ) + rom ( name "Famille Delajungle, La - Le Film (France).gba" size 4194304 crc afa71c84 sha1 C6F2B2F6239ADCEF1AB2C95AD94BB7A01143D0B1 ) ) game ( name "Family Feud (USA)" description "Family Feud (USA)" - rom ( name "Family Feud (USA).gba" size 4194304 crc EC36A3DF md5 079F35BF49C4C64ACA46AC5B82C358E6 sha1 37262E445C866F67CF0FF77CD64E2CE82454125A ) + rom ( name "Family Feud (USA).gba" size 4194304 crc ec36a3df sha1 37262E445C866F67CF0FF77CD64E2CE82454125A ) ) game ( name "Family Tennis Advance (Japan)" description "Family Tennis Advance (Japan)" - rom ( name "Family Tennis Advance (Japan).gba" size 4194304 crc BB43C681 md5 2E4A8FC4E1724E22A890B7C41C880058 sha1 544219C57CFE312F6BD799CAF53E90B3F63B0142 ) + rom ( name "Family Tennis Advance (Japan).gba" size 4194304 crc bb43c681 sha1 544219C57CFE312F6BD799CAF53E90B3F63B0142 flags verified ) ) game ( name "Famista Advance (Japan)" description "Famista Advance (Japan)" - rom ( name "Famista Advance (Japan).gba" size 4194304 crc F7A58AE8 md5 F5BDBF35D4AD87FAE71EC94BB77C7A49 sha1 6AA75B95B5FF6F0D9E81FA682D668FE0FC0F78DA ) + rom ( name "Famista Advance (Japan).gba" size 4194304 crc f7a58ae8 sha1 6AA75B95B5FF6F0D9E81FA682D668FE0FC0F78DA flags verified ) ) game ( name "Fancy Pocket (Japan)" description "Fancy Pocket (Japan)" - rom ( name "Fancy Pocket (Japan).gba" size 4194304 crc A29A50E7 md5 669C6124171C3DD81B5663FECAE2376C sha1 67F69CA28C8248045D7F6120DBDAB2468C0E1969 ) + rom ( name "Fancy Pocket (Japan).gba" size 4194304 crc a29a50e7 sha1 67F69CA28C8248045D7F6120DBDAB2468C0E1969 ) +) + +game ( + name "Fanqiejiang Wangguo Da Maoxian (China) (Proto)" + description "Fanqiejiang Wangguo Da Maoxian (China) (Proto)" + rom ( name "Fanqiejiang Wangguo Da Maoxian (China) (Proto).gba" size 8388608 crc 5116a665 sha1 51AB57E6B414BAE66F3E3EF4335DC0D68DF2ED5E flags verified ) ) game ( name "Fantastic 4 (USA)" description "Fantastic 4 (USA)" - rom ( name "Fantastic 4 (USA).gba" size 16777216 crc FF2C6EA9 md5 04105C845973DF1D717B2487227F0FB0 sha1 9673C055A04657A620AD1ED2710C3D33FB2A70A4 ) + rom ( name "Fantastic 4 (USA).gba" size 16777216 crc ff2c6ea9 sha1 9673C055A04657A620AD1ED2710C3D33FB2A70A4 ) ) game ( name "Fantastic 4 (Europe) (Fr,De,Es,Nl)" description "Fantastic 4 (Europe) (Fr,De,Es,Nl)" - rom ( name "Fantastic 4 (Europe) (Fr,De,Es,Nl).gba" size 16777216 crc 88643DE0 md5 D5C9B6657E5D9FED85E5D25B79ACB3DE sha1 1E6EF7A4C941EA074ED88010F5CD7BAB7C807D0D ) + rom ( name "Fantastic 4 (Europe) (Fr,De,Es,Nl).gba" size 16777216 crc 88643de0 sha1 1E6EF7A4C941EA074ED88010F5CD7BAB7C807D0D flags verified ) ) game ( name "Fantastic 4 (Europe)" description "Fantastic 4 (Europe)" - rom ( name "Fantastic 4 (Europe).gba" size 16777216 crc B30AE33D md5 9CF2886C15142660DA7F70954B182F1F sha1 758B2AFAF4DCD96BAAB60E04D64EB22718EFCECF ) + rom ( name "Fantastic 4 (Europe).gba" size 16777216 crc b30ae33d sha1 758B2AFAF4DCD96BAAB60E04D64EB22718EFCECF ) ) game ( name "Fantastic 4 - Flame On (USA)" description "Fantastic 4 - Flame On (USA)" - rom ( name "Fantastic 4 - Flame On (USA).gba" size 8388608 crc DDDE4295 md5 098752D6F195AB8C34E0EEBAD3A0A779 sha1 C2F979E257608DC3425E9567A14A8A514443E614 ) + rom ( name "Fantastic 4 - Flame On (USA).gba" size 8388608 crc ddde4295 sha1 C2F979E257608DC3425E9567A14A8A514443E614 ) ) game ( name "Fantastic 4 - Flame On (Europe) (En,Fr,Es,It)" description "Fantastic 4 - Flame On (Europe) (En,Fr,Es,It)" - rom ( name "Fantastic 4 - Flame On (Europe) (En,Fr,Es,It).gba" size 8388608 crc 671957AF md5 2A48CFC3BF07C4F64CD267489D46DCA8 sha1 9BF00167388DB1394510A47E49A59D8793CF1C65 ) + rom ( name "Fantastic 4 - Flame On (Europe) (En,Fr,Es,It).gba" size 8388608 crc 671957af sha1 9BF00167388DB1394510A47E49A59D8793CF1C65 ) ) game ( name "Fantastic Children (Japan)" description "Fantastic Children (Japan)" - rom ( name "Fantastic Children (Japan).gba" size 8388608 crc FEFE25BE md5 43265D5F7709133927133A331B55C61B sha1 8AF0853249F6F4DA90AC1044C387E067EF85972A ) + rom ( name "Fantastic Children (Japan).gba" size 8388608 crc fefe25be sha1 8AF0853249F6F4DA90AC1044C387E067EF85972A ) ) game ( name "Fantastic Maerchen - Cake-ya-san Monogatari (Japan)" description "Fantastic Maerchen - Cake-ya-san Monogatari (Japan)" - rom ( name "Fantastic Maerchen - Cake-ya-san Monogatari (Japan).gba" size 8388608 crc EC60D573 md5 5AC646626D2D311AEB585BF0DFD9FD91 sha1 826C247EF4E5B831AA0D75E97CFDFE06C48AD7AF ) + rom ( name "Fantastic Maerchen - Cake-ya-san Monogatari (Japan).gba" size 8388608 crc ec60d573 sha1 826C247EF4E5B831AA0D75E97CFDFE06C48AD7AF ) ) game ( name "Fantastici 4, I (Italy)" description "Fantastici 4, I (Italy)" - rom ( name "Fantastici 4, I (Italy).gba" size 16777216 crc 5D4645E1 md5 5FCADB94EEB7DD0B0BA775D9CFF2C886 sha1 22868CB063A6F259B3AAB2062403F2F633D7B39F ) + rom ( name "Fantastici 4, I (Italy).gba" size 16777216 crc 5d4645e1 sha1 22868CB063A6F259B3AAB2062403F2F633D7B39F ) +) + +game ( + name "Farbe (Germany) (En)" + description "Farbe (Germany) (En)" + rom ( name "Farbe (Germany) (En).gba" size 8388608 crc 8cc3c550 sha1 B59790B9C4C1B00A2E6CAF40C3ACFDBEA64D3C98 flags verified ) ) game ( name "Fear Factor Unleashed (USA)" description "Fear Factor Unleashed (USA)" - rom ( name "Fear Factor Unleashed (USA).gba" size 8388608 crc BF91C27D md5 8DD342A81937540BB7AEA1521CB11D1C sha1 D6F60F7D1707DCA21C61F50DB2B6324B7D680012 ) + rom ( name "Fear Factor Unleashed (USA).gba" size 8388608 crc 1289639c sha1 BF933C51BDCB52AE54D518E80129C687B751F836 ) ) game ( name "Field of Nine - Digital Edition 2001 (Japan)" description "Field of Nine - Digital Edition 2001 (Japan)" - rom ( name "Field of Nine - Digital Edition 2001 (Japan).gba" size 8388608 crc 4FD9C349 md5 8AABD68732A738C01A07AE606E0EB3B6 sha1 876E474D92E97CC3E56C0D557458D6BB49366E04 ) + rom ( name "Field of Nine - Digital Edition 2001 (Japan).gba" size 8388608 crc 4fd9c349 sha1 876E474D92E97CC3E56C0D557458D6BB49366E04 ) ) game ( name "FIFA Soccer 06 (USA, Europe) (En,Fr,De,Es,It,Nl)" description "FIFA Soccer 06 (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "FIFA Soccer 06 (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc BE4C3CB1 md5 13682A498EFFAEF25AAAAD9AC02CB4C0 sha1 D44618A182D036BE6C744B57C5195593117B4543 flags verified ) + rom ( name "FIFA Soccer 06 (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc be4c3cb1 sha1 D44618A182D036BE6C744B57C5195593117B4543 flags verified ) ) game ( name "FIFA Soccer 07 (USA, Europe) (En,Fr,De,Es)" description "FIFA Soccer 07 (USA, Europe) (En,Fr,De,Es)" - rom ( name "FIFA Soccer 07 (USA, Europe) (En,Fr,De,Es).gba" size 8388608 crc D8C7553B md5 BF4A0F61E2E78A120BA1EDD4CFA6A101 sha1 AD593A9BDBE8B4EE3FD3B8FEA66C06FCB6A66534 flags verified ) + rom ( name "FIFA Soccer 07 (USA, Europe) (En,Fr,De,Es).gba" size 8388608 crc d8c7553b sha1 AD593A9BDBE8B4EE3FD3B8FEA66C06FCB6A66534 flags verified ) ) game ( name "FIFA Soccer 2003 (USA, Europe) (En,Fr,De,Es,It)" description "FIFA Soccer 2003 (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "FIFA Soccer 2003 (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 81F58837 md5 B05E5030DA8F059CE836A594E16309B5 sha1 2D9E6DA415469CA7731E1831039955331D709009 flags verified ) + rom ( name "FIFA Soccer 2003 (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 81f58837 sha1 2D9E6DA415469CA7731E1831039955331D709009 flags verified ) ) game ( name "FIFA Soccer 2004 (USA, Europe) (En,Fr,De,Es,It)" description "FIFA Soccer 2004 (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "FIFA Soccer 2004 (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1ABBC24F md5 F9E6BFC9404BE783B149259FFD9C5DA0 sha1 031204FBBFD00A2ECE04EAE590596CDF676D9537 ) + rom ( name "FIFA Soccer 2004 (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1abbc24f sha1 031204FBBFD00A2ECE04EAE590596CDF676D9537 flags verified ) ) game ( name "FIFA Soccer 2005 (USA, Europe) (En,Fr,De,Es,It,Nl)" description "FIFA Soccer 2005 (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "FIFA Soccer 2005 (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc DA90F396 md5 4C5C302D02ECFCD274DAE63461A1692B sha1 5F1B0AACC5AFAA9DD275B2DF780C8A588719AFA8 flags verified ) + rom ( name "FIFA Soccer 2005 (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc da90f396 sha1 5F1B0AACC5AFAA9DD275B2DF780C8A588719AFA8 flags verified ) ) game ( name "FightBox (Europe)" description "FightBox (Europe)" - rom ( name "FightBox (Europe).gba" size 4194304 crc 928B4E05 md5 8D4B0E1203548601A7C34C20680C0B75 sha1 0E3A4509DF4EF1C2F292B9B450BAE66522DFE8DF flags verified ) -) - -game ( - name "FILA Decathlon (Europe) (Beta)" - description "FILA Decathlon (Europe) (Beta)" - rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434E3A md5 E187189CA821FD17AFD4D9DE7A376F9C sha1 1DC940DDA8DA59ADE503C1E8901A0E44285F4E9B ) + rom ( name "FightBox (Europe).gba" size 4194304 crc 928b4e05 sha1 0E3A4509DF4EF1C2F292B9B450BAE66522DFE8DF flags verified ) ) game ( name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" description "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv)" - rom ( name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv).gba" size 4194304 crc 628355B5 md5 BC2F9688AA915EE1EAA6CD06F8E1BB11 sha1 41EFD4B2FC8BE52A12AADD1E4BF696FCC98230CA ) + rom ( name "FILA Decathlon (Europe) (En,Fr,De,Es,It,Sv).gba" size 4194304 crc 628355b5 sha1 41EFD4B2FC8BE52A12AADD1E4BF696FCC98230CA flags verified ) ) game ( - name "Final Fantasy I & II - Dawn of Souls (USA, Australia)" - description "Final Fantasy I & II - Dawn of Souls (USA, Australia)" - rom ( name "Final Fantasy I & II - Dawn of Souls (USA, Australia).gba" size 16777216 crc 1B39CDAB md5 5D29999685413C4D2BEC10D3160F6EE6 sha1 6472695D69661490F78245E2982E1E676C080BE7 flags verified ) + name "FILA Decathlon (Europe) (Beta)" + description "FILA Decathlon (Europe) (Beta)" + rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434e3a sha1 1DC940DDA8DA59ADE503C1E8901A0E44285F4E9B ) +) + +game ( + name "Final Fantasy I & II - Dawn of Souls (USA)" + description "Final Fantasy I & II - Dawn of Souls (USA)" + rom ( name "Final Fantasy I & II - Dawn of Souls (USA).gba" size 16777216 crc 1b39cdab sha1 6472695D69661490F78245E2982E1E676C080BE7 flags verified ) ) game ( name "Final Fantasy I & II - Dawn of Souls (Europe) (En,Fr,De,Es,It)" description "Final Fantasy I & II - Dawn of Souls (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy I & II - Dawn of Souls (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7C9854C6 md5 12EA1887210DFA6164D7CBEAE7573A48 sha1 200C4AAAE84720F56C8140F7E8D0086292121C4B flags verified ) + rom ( name "Final Fantasy I & II - Dawn of Souls (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7c9854c6 sha1 200C4AAAE84720F56C8140F7E8D0086292121C4B flags verified ) ) game ( name "Final Fantasy I, II Advance (Japan) (Rev 1)" description "Final Fantasy I, II Advance (Japan) (Rev 1)" - rom ( name "Final Fantasy I, II Advance (Japan) (Rev 1).gba" size 16777216 crc 0F3BD723 md5 3B3DB67A969C970421AF875ADACB5EFA sha1 3D1C580B9B3007F6F910D80F4C7421F5D2E19DBE ) + rom ( name "Final Fantasy I, II Advance (Japan) (Rev 1).gba" size 16777216 crc 0f3bd723 sha1 3D1C580B9B3007F6F910D80F4C7421F5D2E19DBE flags verified ) +) + +game ( + name "Final Fantasy I, II Advance (Japan) (Rev 1) (Wii U Virtual Console)" + description "Final Fantasy I, II Advance (Japan) (Rev 1) (Wii U Virtual Console)" + rom ( name "Final Fantasy I, II Advance (Japan) (Rev 1) (Wii U Virtual Console).gba" size 16777216 crc 2c58c9c1 sha1 EE60276F72CE0D1852F741F02BF1F4478B8F2D61 flags verified ) ) game ( name "Final Fantasy IV Advance (Japan)" description "Final Fantasy IV Advance (Japan)" - rom ( name "Final Fantasy IV Advance (Japan).gba" size 8388608 crc 17036E02 md5 971A2979E6E04942E61271DDD563F480 sha1 417C7713F01D8E7A7C1F7BC11DEB2E214D426CD9 flags verified ) + rom ( name "Final Fantasy IV Advance (Japan).gba" size 8388608 crc 17036e02 sha1 417C7713F01D8E7A7C1F7BC11DEB2E214D426CD9 flags verified ) ) game ( - name "Final Fantasy IV Advance (USA, Australia)" - description "Final Fantasy IV Advance (USA, Australia)" - rom ( name "Final Fantasy IV Advance (USA, Australia).gba" size 8388608 crc FEEEBDE4 md5 C74DD5CC3AB6E5D4AC53B1677E1ABD69 sha1 C49BE22EAF999774D5F2983E12ED4AACE2950F36 flags verified ) + name "Final Fantasy IV Advance (USA)" + description "Final Fantasy IV Advance (USA)" + rom ( name "Final Fantasy IV Advance (USA).gba" size 8388608 crc feeebde4 sha1 C49BE22EAF999774D5F2983E12ED4AACE2950F36 flags verified ) ) game ( name "Final Fantasy IV Advance (Europe) (En,Fr,De,Es,It)" description "Final Fantasy IV Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy IV Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 27F2BC67 md5 2FF590AA635590C2F8140C88CBB19025 sha1 B09D50D782B184C8641AEA6DD904AE46C3CC72E6 flags verified ) + rom ( name "Final Fantasy IV Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 27f2bc67 sha1 B09D50D782B184C8641AEA6DD904AE46C3CC72E6 flags verified ) ) game ( name "Final Fantasy IV Advance (Japan) (Rev 1)" description "Final Fantasy IV Advance (Japan) (Rev 1)" - rom ( name "Final Fantasy IV Advance (Japan) (Rev 1).gba" size 8388608 crc 80F1133B md5 002DC5540EC997B98C1E8D29D3ABFE24 sha1 621A2F95B4884CDC3D3F7A97DE9C4E8B4B0C31C0 ) + rom ( name "Final Fantasy IV Advance (Japan) (Rev 1).gba" size 8388608 crc 80f1133b sha1 621A2F95B4884CDC3D3F7A97DE9C4E8B4B0C31C0 ) ) game ( name "Final Fantasy Tactics Advance (Japan)" description "Final Fantasy Tactics Advance (Japan)" - rom ( name "Final Fantasy Tactics Advance (Japan).gba" size 16777216 crc A57B0034 md5 760490D2224D727B149EB47617D02A5E sha1 FA9D23EE88C7FE24374337ACA03EB864B5B991F4 ) + rom ( name "Final Fantasy Tactics Advance (Japan).gba" size 16777216 crc a57b0034 sha1 FA9D23EE88C7FE24374337ACA03EB864B5B991F4 flags verified ) ) game ( - name "Final Fantasy Tactics Advance (USA, Australia)" - description "Final Fantasy Tactics Advance (USA, Australia)" - rom ( name "Final Fantasy Tactics Advance (USA, Australia).gba" size 16777216 crc 5645E56C md5 CD99CDDE3D45554C1B36FBEB8863B7BD sha1 4AC05441F4DE70A4EC3DD932116346C61B8783D9 flags verified ) + name "Final Fantasy Tactics Advance (USA)" + description "Final Fantasy Tactics Advance (USA)" + rom ( name "Final Fantasy Tactics Advance (USA).gba" size 16777216 crc 5645e56c sha1 4AC05441F4DE70A4EC3DD932116346C61B8783D9 flags verified ) ) game ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" description "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc BA5DE047 md5 6EA5FC0E4B56A232AC3CBDAB4B4A6BCD sha1 9EFAF328CBBCBC830BE14940E42E4B92D90DFB58 flags verified ) + rom ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ba5de047 sha1 9EFAF328CBBCBC830BE14940E42E4B92D90DFB58 flags verified ) +) + +game ( + name "Final Fantasy Tactics Advance (USA) (Wii U Virtual Console)" + description "Final Fantasy Tactics Advance (USA) (Wii U Virtual Console)" + rom ( name "Final Fantasy Tactics Advance (USA) (Wii U Virtual Console).gba" size 16777216 crc 5964df89 sha1 3CA7CFFE302E733501A4777A576928EA159B89E4 flags verified ) ) game ( name "Final Fantasy V Advance (Japan)" description "Final Fantasy V Advance (Japan)" - rom ( name "Final Fantasy V Advance (Japan).gba" size 8388608 crc FC7909A7 md5 B8FB00C59242AFC33B1A40D0D2B94EE7 sha1 F4F6806051097C3088A5763D6D7211024FE5CC34 ) + rom ( name "Final Fantasy V Advance (Japan).gba" size 8388608 crc fc7909a7 sha1 F4F6806051097C3088A5763D6D7211024FE5CC34 ) ) game ( name "Final Fantasy V Advance (USA)" description "Final Fantasy V Advance (USA)" - rom ( name "Final Fantasy V Advance (USA).gba" size 8388608 crc 7A24AB0C md5 9ED82843CC54876362BE56FACCB15D75 sha1 492789276EAA3E94152B143AD92F310B8A3D5366 flags verified ) + rom ( name "Final Fantasy V Advance (USA).gba" size 8388608 crc 7a24ab0c sha1 492789276EAA3E94152B143AD92F310B8A3D5366 flags verified ) ) game ( name "Final Fantasy V Advance (Europe) (En,Fr,De,Es,It)" description "Final Fantasy V Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy V Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7197117E md5 EBC874A9FFABAACD7EA1A3E128DD97D3 sha1 4FC4BC7C1C3ABE9D2F9C59A3AE4172B5CB57BD2C ) + rom ( name "Final Fantasy V Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7197117e sha1 4FC4BC7C1C3ABE9D2F9C59A3AE4172B5CB57BD2C ) +) + +game ( + name "Final Fantasy V Advance (Japan) (Wii U Virtual Console)" + description "Final Fantasy V Advance (Japan) (Wii U Virtual Console)" + rom ( name "Final Fantasy V Advance (Japan) (Wii U Virtual Console).gba" size 8388608 crc bb4a2de0 sha1 B9FCF062355A66537AEC0B791400C55EC2436E3C flags verified ) ) game ( name "Final Fantasy VI Advance (Japan)" description "Final Fantasy VI Advance (Japan)" - rom ( name "Final Fantasy VI Advance (Japan).gba" size 8388608 crc D67478FE md5 09DAF6531DED19B7921367084E439B2F sha1 1850FEDDE7305C4BAF42E0594AAABE17C549D7E2 flags verified ) + rom ( name "Final Fantasy VI Advance (Japan).gba" size 8388608 crc d67478fe sha1 1850FEDDE7305C4BAF42E0594AAABE17C549D7E2 flags verified ) ) game ( name "Final Fantasy VI Advance (USA)" description "Final Fantasy VI Advance (USA)" - rom ( name "Final Fantasy VI Advance (USA).gba" size 8388608 crc D708F5AB md5 D1C3D1798A3F347FBAB41F151C99DECE sha1 E9A2A58BC56ACE26CB56D0CF5CDAD1A10AA5DEDF flags verified ) + rom ( name "Final Fantasy VI Advance (USA).gba" size 8388608 crc d708f5ab sha1 E9A2A58BC56ACE26CB56D0CF5CDAD1A10AA5DEDF flags verified ) ) game ( name "Final Fantasy VI Advance (Europe) (En,Fr,De,Es,It)" description "Final Fantasy VI Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Final Fantasy VI Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc D15DEBA5 md5 7F6BF3B4D84F113AA454136E5B53FD77 sha1 C5B27ED0870EA64E6A001C5BC367F76571ACE973 ) + rom ( name "Final Fantasy VI Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc d15deba5 sha1 C5B27ED0870EA64E6A001C5BC367F76571ACE973 ) ) game ( name "Final Fight One (Japan)" description "Final Fight One (Japan)" - rom ( name "Final Fight One (Japan).gba" size 4194304 crc C9E5E223 md5 9A3DB7E1FE781945DF44EB6BE8713567 sha1 3A0FA85187AA7C20842ABEB1A6CBC11B21131B2C ) + rom ( name "Final Fight One (Japan).gba" size 4194304 crc c9e5e223 sha1 3A0FA85187AA7C20842ABEB1A6CBC11B21131B2C ) ) game ( name "Final Fight One (Europe)" description "Final Fight One (Europe)" - rom ( name "Final Fight One (Europe).gba" size 4194304 crc 9DD5E6FA md5 D8453317272826159FEFCF254F25ADA4 sha1 0FF0852B7763149F77544E9A8AEF5F2174178BD1 flags verified ) + rom ( name "Final Fight One (Europe).gba" size 4194304 crc 9dd5e6fa sha1 0FF0852B7763149F77544E9A8AEF5F2174178BD1 flags verified ) ) game ( name "Final Fight One (USA)" description "Final Fight One (USA)" - rom ( name "Final Fight One (USA).gba" size 4194304 crc 052C9997 md5 C6AF74AEEABFD6D7EE2875E355F49AF2 sha1 17918E125BCAFD44FCF3B21813575C2CCB19BD45 ) + rom ( name "Final Fight One (USA).gba" size 4194304 crc 052c9997 sha1 17918E125BCAFD44FCF3B21813575C2CCB19BD45 ) +) + +game ( + name "Final Fight One (USA) (Wii U Virtual Console)" + description "Final Fight One (USA) (Wii U Virtual Console)" + rom ( name "Final Fight One (USA) (Wii U Virtual Console).gba" size 4194304 crc df77dad2 sha1 C1B60A87CCB0AA915696A799765196A0D3A3CE53 flags verified ) ) game ( name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan)" description "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan)" - rom ( name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan).gba" size 16777216 crc A0093822 md5 C4777D142E1A0427FB78B5167497D471 sha1 4894C960C64B4F2D250E054FFD5D6971940C3B17 ) + rom ( name "Final Fire Pro Wrestling - Yume no Dantai Unei! (Japan).gba" size 16777216 crc a0093822 sha1 4894C960C64B4F2D250E054FFD5D6971940C3B17 ) ) game ( name "Findet Nemo (Germany) (Beta)" description "Findet Nemo (Germany) (Beta)" - rom ( name "Findet Nemo (Germany) (Beta).gba" size 8388608 crc 92197FBB md5 03E4DF3B3506EEE9173DFFD6E5DB4FCE sha1 8C9E1517BCF4C7B9C099D4FEF8EF4BDEBA2C7857 ) + rom ( name "Findet Nemo (Germany) (Beta).gba" size 8388608 crc 92197fbb sha1 8C9E1517BCF4C7B9C099D4FEF8EF4BDEBA2C7857 ) ) game ( name "Findet Nemo (Germany)" description "Findet Nemo (Germany)" - serial "AGB-AZID-NOE" - rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6B6B0908 md5 C7262E8C52597D29C8858C1EA1EB0161 sha1 5C5EE51C4BC8196BEA226B3BF4750C8DE1EE7F38 ) -) - -game ( - name "Finding Nemo (Europe) (Fr,Nl)" - description "Finding Nemo (Europe) (Fr,Nl)" - rom ( name "Finding Nemo (Europe) (Fr,Nl).gba" size 8388608 crc 269AF7DD md5 4C863F423CD8052BB3D780DA001745B0 sha1 587F8CC627329EE76A129D7D6E7C56F20F6CD832 ) -) - -game ( - name "Finding Nemo (Japan)" - description "Finding Nemo (Japan)" - rom ( name "Finding Nemo (Japan).gba" size 8388608 crc F895BA2D md5 C5EC72000373809A4D43BFEE2911745F sha1 CAB85C042C168E46EC42547A87AF1B036E45C2A4 ) -) - -game ( - name "Finding Nemo (Europe) (Es,It)" - description "Finding Nemo (Europe) (Es,It)" - rom ( name "Finding Nemo (Europe) (Es,It).gba" size 8388608 crc 3E6F4F03 md5 B7A094F8568555602158DCEE3750179F sha1 64B3D390CA1D2DF4F12B857A64E9C68860C1682E ) + rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6b6b0908 sha1 5C5EE51C4BC8196BEA226B3BF4750C8DE1EE7F38 flags verified ) ) game ( name "Finding Nemo (USA, Europe)" description "Finding Nemo (USA, Europe)" - rom ( name "Finding Nemo (USA, Europe).gba" size 8388608 crc 3B098667 md5 C824E72AA57E94EEA86343E107B0DCA2 sha1 A0C98D05B0854BB724F1EA5DF89F19F77E6BEB79 flags verified ) + rom ( name "Finding Nemo (USA, Europe).gba" size 8388608 crc 3b098667 sha1 A0C98D05B0854BB724F1EA5DF89F19F77E6BEB79 flags verified ) +) + +game ( + name "Finding Nemo (Europe) (Fr,Nl)" + description "Finding Nemo (Europe) (Fr,Nl)" + rom ( name "Finding Nemo (Europe) (Fr,Nl).gba" size 8388608 crc 269af7dd sha1 587F8CC627329EE76A129D7D6E7C56F20F6CD832 ) +) + +game ( + name "Finding Nemo (Japan)" + description "Finding Nemo (Japan)" + rom ( name "Finding Nemo (Japan).gba" size 8388608 crc f895ba2d sha1 CAB85C042C168E46EC42547A87AF1B036E45C2A4 flags verified ) +) + +game ( + name "Finding Nemo (Europe) (Es,It)" + description "Finding Nemo (Europe) (Es,It)" + rom ( name "Finding Nemo (Europe) (Es,It).gba" size 8388608 crc 3e6f4f03 sha1 64B3D390CA1D2DF4F12B857A64E9C68860C1682E ) ) game ( name "Finding Nemo - Aratanaru Bouken (Japan)" description "Finding Nemo - Aratanaru Bouken (Japan)" - rom ( name "Finding Nemo - Aratanaru Bouken (Japan).gba" size 4194304 crc 4C77EDA6 md5 4E17057F495446EA4AE146405A957309 sha1 5F767C59461214E8C16CAF8427E34E462B831747 ) + rom ( name "Finding Nemo - Aratanaru Bouken (Japan).gba" size 4194304 crc 4c77eda6 sha1 5F767C59461214E8C16CAF8427E34E462B831747 flags verified ) ) game ( name "Finding Nemo - The Continuing Adventures (USA, Europe)" description "Finding Nemo - The Continuing Adventures (USA, Europe)" - rom ( name "Finding Nemo - The Continuing Adventures (USA, Europe).gba" size 4194304 crc 4F9ACA4F md5 68500BCBB838A9D361272F34FA20CE1A sha1 66881E8204F770973DCF01B4F9F919FA2F6DB99B flags verified ) + rom ( name "Finding Nemo - The Continuing Adventures (USA, Europe).gba" size 4194304 crc 4f9aca4f sha1 66881E8204F770973DCF01B4F9F919FA2F6DB99B flags verified ) ) game ( name "Finding Nemo - The Continuing Adventures (Europe) (Fr,De,Nl)" description "Finding Nemo - The Continuing Adventures (Europe) (Fr,De,Nl)" - rom ( name "Finding Nemo - The Continuing Adventures (Europe) (Fr,De,Nl).gba" size 4194304 crc 1E8CEFE9 md5 B7685A523A772E659D992E071AA2CD1E sha1 3FDB20833BE10287930621A5CEB941330BF24E27 ) + rom ( name "Finding Nemo - The Continuing Adventures (Europe) (Fr,De,Nl).gba" size 4194304 crc 1e8cefe9 sha1 3FDB20833BE10287930621A5CEB941330BF24E27 ) ) game ( name "Finding Nemo - The Continuing Adventures (Europe) (En,Es,It,Sv,Da)" description "Finding Nemo - The Continuing Adventures (Europe) (En,Es,It,Sv,Da)" - rom ( name "Finding Nemo - The Continuing Adventures (Europe) (En,Es,It,Sv,Da).gba" size 4194304 crc 45BC9C37 md5 89C2AF08FB993266D8CD79AF28AABCE2 sha1 E29BAD428B9AE4E5BDA9C6D6C0FF5CA739B8F78D flags verified ) + rom ( name "Finding Nemo - The Continuing Adventures (Europe) (En,Es,It,Sv,Da).gba" size 4194304 crc 45bc9c37 sha1 E29BAD428B9AE4E5BDA9C6D6C0FF5CA739B8F78D flags verified ) ) game ( name "Fire Eaters - Zero Bandits (Europe) (Demo)" description "Fire Eaters - Zero Bandits (Europe) (Demo)" - rom ( name "Fire Eaters - Zero Bandits (Europe) (Demo).gba" size 8388608 crc 8698F50A md5 8E501D5ABF552C71851B535F451EE663 sha1 2F5AD08E5E87533328DEB688D383313E558A44D6 ) + rom ( name "Fire Eaters - Zero Bandits (Europe) (Demo).gba" size 8388608 crc 8698f50a sha1 2F5AD08E5E87533328DEB688D383313E558A44D6 ) ) game ( name "Fire Emblem (USA, Australia)" description "Fire Emblem (USA, Australia)" - rom ( name "Fire Emblem (USA, Australia).gba" size 16777216 crc 2A524221 md5 F1A1B9742FCD467A531DD4314C4E7D19 sha1 C735FDBB9E8ABE19E0C6A44708DF19ACC962E204 flags verified ) + rom ( name "Fire Emblem (USA, Australia).gba" size 16777216 crc 2a524221 sha1 C735FDBB9E8ABE19E0C6A44708DF19ACC962E204 flags verified ) ) game ( name "Fire Emblem (Europe) (En,Fr,De)" description "Fire Emblem (Europe) (En,Fr,De)" - rom ( name "Fire Emblem (Europe) (En,Fr,De).gba" size 16777216 crc 4A805ED1 md5 7B7A43F3AC4A3FACC65AA6B616C0B887 sha1 C37E3BAE84B53E6972ED7608541A62896FA5D6A3 flags verified ) + rom ( name "Fire Emblem (Europe) (En,Fr,De).gba" size 16777216 crc 4a805ed1 sha1 C37E3BAE84B53E6972ED7608541A62896FA5D6A3 flags verified ) ) game ( name "Fire Emblem (Europe) (En,Es,It)" description "Fire Emblem (Europe) (En,Es,It)" - rom ( name "Fire Emblem (Europe) (En,Es,It).gba" size 16777216 crc 9DECC754 md5 34B91944C89770903B4D04D40E3E8512 sha1 F2EB087E9254FAA7656EC6F1CF81FA701A853124 ) + rom ( name "Fire Emblem (Europe) (En,Es,It).gba" size 16777216 crc 9decc754 sha1 F2EB087E9254FAA7656EC6F1CF81FA701A853124 ) +) + +game ( + name "Fire Emblem (USA) (Wii U Virtual Console)" + description "Fire Emblem (USA) (Wii U Virtual Console)" + rom ( name "Fire Emblem (USA) (Wii U Virtual Console).gba" size 16777216 crc 1b8713c7 sha1 A9DC86554BD10ED842A126EDA8367BE3CE857D77 flags verified ) +) + +game ( + name "Fire Emblem (Europe) (En,Fr,De) (Wii U Virtual Console)" + description "Fire Emblem (Europe) (En,Fr,De) (Wii U Virtual Console)" + rom ( name "Fire Emblem (Europe) (En,Fr,De) (Wii U Virtual Console).gba" size 16777216 crc 335c5855 sha1 BD826084425979B5DF7AE68982EC21D5AB83408E flags verified ) ) game ( name "Fire Emblem - Fuuin no Tsurugi (Japan)" description "Fire Emblem - Fuuin no Tsurugi (Japan)" - rom ( name "Fire Emblem - Fuuin no Tsurugi (Japan).gba" size 8388608 crc D38763E1 md5 8643FE7632D4895DCAACA230475E70FB sha1 A57095DA867DE4D585C33D4394712986245FE6CA ) + rom ( name "Fire Emblem - Fuuin no Tsurugi (Japan).gba" size 8388608 crc d38763e1 sha1 A57095DA867DE4D585C33D4394712986245FE6CA flags verified ) ) game ( name "Fire Emblem - Rekka no Ken (Japan)" description "Fire Emblem - Rekka no Ken (Japan)" - rom ( name "Fire Emblem - Rekka no Ken (Japan).gba" size 16777216 crc F0C10E72 md5 9485F273F4E97E9E8F21966407F2E782 sha1 037702B1FEBD5C9535262165BF030551D153DE81 ) + rom ( name "Fire Emblem - Rekka no Ken (Japan).gba" size 16777216 crc f0c10e72 sha1 037702B1FEBD5C9535262165BF030551D153DE81 flags verified ) +) + +game ( + name "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-06)" + description "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-06)" + rom ( name "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-06).gba" size 16777216 crc b40d6854 sha1 A408D29A9B80829A0864F531E04213F585192CED ) +) + +game ( + name "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-19)" + description "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-19) (Leaked from an Intelligent System's FTP)" + rom ( name "Fire Emblem - Rekka no Ken (Japan) (Beta) (2003-02-19).gba" size 16777216 crc 8146a270 sha1 3B987BD15A3958901F38686C54A6250AB3398703 ) ) game ( name "Fire Emblem - Seima no Kouseki (Japan)" description "Fire Emblem - Seima no Kouseki (Japan)" - rom ( name "Fire Emblem - Seima no Kouseki (Japan).gba" size 16777216 crc 9D76826F md5 607E314DBE861A2DBE444052BA32C4B5 sha1 7DA0456035366AA18414FAA79D8FE7649F03C1ED ) + rom ( name "Fire Emblem - Seima no Kouseki (Japan).gba" size 16777216 crc 9d76826f sha1 7DA0456035366AA18414FAA79D8FE7649F03C1ED ) +) + +game ( + name "Fire Emblem - Seima no Kouseki (Japan) (Beta)" + description "Fire Emblem - Seima no Kouseki (Japan) (Beta)" + rom ( name "Fire Emblem - Seima no Kouseki (Japan) (Beta).gba" size 16777216 crc cd9d8972 sha1 81C48809C9B8C3A099B7F9B1E08AB3DD8ADDE368 ) ) game ( name "Fire Emblem - The Sacred Stones (USA, Australia)" description "Fire Emblem - The Sacred Stones (USA, Australia)" - rom ( name "Fire Emblem - The Sacred Stones (USA, Australia).gba" size 16777216 crc A47246AE md5 005531FEF9EFBB642095FB8F64645236 sha1 C25B145E37456171ADA4B0D440BF88A19F4D509F flags verified ) + rom ( name "Fire Emblem - The Sacred Stones (USA, Australia).gba" size 16777216 crc a47246ae sha1 C25B145E37456171ADA4B0D440BF88A19F4D509F flags verified ) ) game ( name "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It)" description "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It)" - rom ( name "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc B3005195 md5 8F0DAD780F01CE002331693F4733F27E sha1 51B166DCCA231369D7F98000766746DD4B98839C flags verified ) + rom ( name "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc b3005195 sha1 51B166DCCA231369D7F98000766746DD4B98839C flags verified ) +) + +game ( + name "Fire Emblem - The Sacred Stones (USA) (Wii U Virtual Console)" + description "Fire Emblem - The Sacred Stones (USA) (Wii U Virtual Console)" + rom ( name "Fire Emblem - The Sacred Stones (USA) (Wii U Virtual Console).gba" size 16777216 crc dea3b767 sha1 48671A710CAB196CDDDD1560E76EF1EDFB689943 flags verified ) +) + +game ( + name "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Fire Emblem - The Sacred Stones (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 33554432 crc 2653401a sha1 8E12184314E55ED454411194B6EB677BB6A318EF flags verified ) ) game ( name "Fire Pro Wrestling (USA, Europe)" description "Fire Pro Wrestling (USA, Europe)" - rom ( name "Fire Pro Wrestling (USA, Europe).gba" size 8388608 crc 12AA524C md5 AACBDC2916C5941607B0B2D6D68512ED sha1 CC9E51F22A6428AF407D3C26B191AA27C387980F ) + rom ( name "Fire Pro Wrestling (USA, Europe).gba" size 8388608 crc 12aa524c sha1 CC9E51F22A6428AF407D3C26B191AA27C387980F ) ) game ( name "Fire Pro Wrestling 2 (USA)" description "Fire Pro Wrestling 2 (USA)" - rom ( name "Fire Pro Wrestling 2 (USA).gba" size 8388608 crc B9CFC1D3 md5 AE34E324B26F0D693EE73F6A4B8B995E sha1 732E16060F7D824ED6B03F07BFC2BC2F3BE1C79C ) + rom ( name "Fire Pro Wrestling 2 (USA).gba" size 8388608 crc b9cfc1d3 sha1 732E16060F7D824ED6B03F07BFC2BC2F3BE1C79C ) ) game ( name "Fire Pro Wrestling A (Japan)" description "Fire Pro Wrestling A (Japan)" - rom ( name "Fire Pro Wrestling A (Japan).gba" size 8388608 crc 0BB47E83 md5 FEEC220B3324EC3BF48A6902A83B7206 sha1 31BDD1B360646D41FB4D11E5BC1338097A928400 ) + rom ( name "Fire Pro Wrestling A (Japan).gba" size 8388608 crc 0bb47e83 sha1 31BDD1B360646D41FB4D11E5BC1338097A928400 ) ) game ( - name "Flashback Legends (France) (En,Fr) (Proto)" - description "Flashback Legends (France) (En,Fr) (Proto)" - rom ( name "Flashback Legends (France) (En,Fr) (Proto).gba" size 3955244 crc EB33477D md5 04613E49B4E7A8FD022B1FA51E664AE9 sha1 9CD436521E98014977A2DFDDE64E8A531A1DF12A ) + name "Flashback Legends (France) (Proto)" + description "Flashback Legends (France) (Proto)" + rom ( name "Flashback Legends (France) (Proto).gba" size 3955244 crc eb33477d sha1 9CD436521E98014977A2DFDDE64E8A531A1DF12A ) ) game ( name "Flintstones, The - Big Trouble in Bedrock (USA)" description "Flintstones, The - Big Trouble in Bedrock (USA)" - rom ( name "Flintstones, The - Big Trouble in Bedrock (USA).gba" size 4194304 crc 3B09694B md5 A73253D79628D92C2FEE1E9D2BBD6FF5 sha1 7621AE8D6110D8C7D41CDE336D67E0E44CDBF48B ) + rom ( name "Flintstones, The - Big Trouble in Bedrock (USA).gba" size 4194304 crc 3b09694b sha1 7621AE8D6110D8C7D41CDE336D67E0E44CDBF48B ) ) game ( name "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It)" description "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It)" - rom ( name "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 39782C26 md5 2C66F51BD6546FB780D52F981A57106E sha1 3EB5A53A395ACFAAE672D8B8E3C79FC4442A00AB ) + rom ( name "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 39782c26 sha1 3EB5A53A395ACFAAE672D8B8E3C79FC4442A00AB ) ) game ( name "Flushed Away (USA)" description "Flushed Away (USA)" - rom ( name "Flushed Away (USA).gba" size 8388608 crc 0ED5DF4B md5 DB607F2427469E017560FD23FDC7EA70 sha1 47C4852A850C0F094673289377C65BDFB5E8936E ) + rom ( name "Flushed Away (USA).gba" size 8388608 crc 0ed5df4b sha1 47C4852A850C0F094673289377C65BDFB5E8936E ) ) game ( name "Flushed Away (Europe) (En,Fr,De,Es,It)" description "Flushed Away (Europe) (En,Fr,De,Es,It)" - rom ( name "Flushed Away (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 62E435DE md5 47464B466905280CF769A6945BBAC3DA sha1 F80FE42D364F9DA301607CEAB9751C771E068417 ) + rom ( name "Flushed Away (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 62e435de sha1 F80FE42D364F9DA301607CEAB9751C771E068417 flags verified ) ) game ( name "Ford Racing 3 (USA)" description "Ford Racing 3 (USA)" - rom ( name "Ford Racing 3 (USA).gba" size 4194304 crc 56D38756 md5 A3B2DD184E80764A1A3C0D7799089327 sha1 FA323718777C3EC1B323341D35D83859F103450F ) + rom ( name "Ford Racing 3 (USA).gba" size 4194304 crc 56d38756 sha1 FA323718777C3EC1B323341D35D83859F103450F ) ) game ( name "Ford Racing 3 (Europe) (En,Fr,De,Es,It)" description "Ford Racing 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "Ford Racing 3 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 94E3D277 md5 3CECCC2582E3C35C5D729AE508DD465F sha1 0CFB4FB42694B64E5FBCBEED58160D9EBDD461B0 ) + rom ( name "Ford Racing 3 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 94e3d277 sha1 0CFB4FB42694B64E5FBCBEED58160D9EBDD461B0 ) ) game ( name "Formation Soccer 2002 (Japan)" description "Formation Soccer 2002 (Japan)" - rom ( name "Formation Soccer 2002 (Japan).gba" size 4194304 crc 47F663A0 md5 6DB14EC7D0443807ECD615E72E12E0CD sha1 EB1B92B6BA23E8A96DB007DB0EB446B23129F06E ) + rom ( name "Formation Soccer 2002 (Japan).gba" size 4194304 crc 47f663a0 sha1 EB1B92B6BA23E8A96DB007DB0EB446B23129F06E ) ) game ( name "Fortress (USA, Europe)" description "Fortress (USA, Europe)" - rom ( name "Fortress (USA, Europe).gba" size 4194304 crc BEE67855 md5 DB64D910FEEC15DC3F3BC90C151E731B sha1 C3175D11FADD85AC743B837A161AE1BE89429A7A flags verified ) + rom ( name "Fortress (USA, Europe).gba" size 4194304 crc bee67855 sha1 C3175D11FADD85AC743B837A161AE1BE89429A7A flags verified ) ) game ( name "Foster's Home for Imaginary Friends (USA)" description "Foster's Home for Imaginary Friends (USA)" - rom ( name "Foster's Home for Imaginary Friends (USA).gba" size 4194304 crc D7C80592 md5 1207A415C9ACFBD206E5580F34E73BA2 sha1 9DCFDDF55A2A60DB2946E52959D82CB53C63E7DF ) + rom ( name "Foster's Home for Imaginary Friends (USA).gba" size 4194304 crc d7c80592 sha1 9DCFDDF55A2A60DB2946E52959D82CB53C63E7DF ) ) game ( name "Foster's Home for Imaginary Friends (Europe)" description "Foster's Home for Imaginary Friends (Europe)" - rom ( name "Foster's Home for Imaginary Friends (Europe).gba" size 4194304 crc DEE47A85 md5 784E266E768506888DD0F656FD7CF715 sha1 0B60FDBD2991BBC7E7FF1933CC5947BE3E69411D ) + rom ( name "Foster's Home for Imaginary Friends (Europe).gba" size 4194304 crc dee47a85 sha1 0B60FDBD2991BBC7E7FF1933CC5947BE3E69411D ) ) game ( name "Frank Herbert's Dune - Ornithopter Assault (Europe) (En,Fr,De,Es,It) (Proto)" description "Frank Herbert's Dune - Ornithopter Assault (Europe) (En,Fr,De,Es,It) (Proto)" - rom ( name "Frank Herbert's Dune - Ornithopter Assault (Europe) (En,Fr,De,Es,It) (Proto).gba" size 4194304 crc 298D627B md5 4605B16D7D9162A77E26C090AB7A28DA sha1 1D317FB050F6D5B850F4B88B72F3420CB175EDF3 ) -) - -game ( - name "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi)" - description "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi)" - rom ( name "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi).gba" size 4194304 crc 9BB561A8 md5 E582614D06F941FF491543A721A9ACB0 sha1 25F215AF94412D1B5A7026FCEAB1A3B6CD2A9E69 ) -) - -game ( - name "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2)" - description "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2)" - rom ( name "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2).gba" size 4194304 crc A0952CD0 md5 FC13F41345DF4ABA40FFC69402E64704 sha1 CE978DBDA60DDBEE77657A60CF2102722E645DCF ) -) - -game ( - name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1)" - description "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1)" - rom ( name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1).gba" size 4194304 crc 1A2F7EE6 md5 5C76354506A11FE8883783FA3BD07E62 sha1 5211FB864A60461F7AE20C42E2BF60E08A9F96BA ) + rom ( name "Frank Herbert's Dune - Ornithopter Assault (Europe) (En,Fr,De,Es,It) (Proto).gba" size 4194304 crc 298d627b sha1 1D317FB050F6D5B850F4B88B72F3420CB175EDF3 flags verified ) ) game ( name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi)" description "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi)" - rom ( name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi).gba" size 4194304 crc 17C48263 md5 62B84A21CFF0C51DBEEAD301010DC5EF sha1 9114816441BE2173491496C4F2DBBDA9DEF0BF2C ) + rom ( name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi).gba" size 4194304 crc 17c48263 sha1 9114816441BE2173491496C4F2DBBDA9DEF0BF2C ) +) + +game ( + name "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi)" + description "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi)" + rom ( name "Franklin the Turtle (USA) (En,Fr,De,Es,It,Sv,No,Da,Fi).gba" size 4194304 crc 9bb561a8 sha1 25F215AF94412D1B5A7026FCEAB1A3B6CD2A9E69 ) +) + +game ( + name "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2)" + description "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2)" + rom ( name "Franklin the Turtle (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi) (Rev 2).gba" size 4194304 crc a0952cd0 sha1 CE978DBDA60DDBEE77657A60CF2102722E645DCF flags verified ) +) + +game ( + name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1)" + description "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1)" + rom ( name "Franklin the Turtle (Europe) (En,Fr,De,It,Sv,No,Da,Fi) (Rev 1).gba" size 4194304 crc 1a2f7ee6 sha1 5211FB864A60461F7AE20C42E2BF60E08A9F96BA flags verified ) ) game ( name "Franklin's Great Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Franklin's Great Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Franklin's Great Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 4194304 crc 22E65767 md5 F5A10AEAB11D8F77BE5CD4D9BE1C2766 sha1 24F3CAC73F6D21500CC4ACD5238B0176D35DB0D2 ) + rom ( name "Franklin's Great Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 4194304 crc 22e65767 sha1 24F3CAC73F6D21500CC4ACD5238B0176D35DB0D2 flags verified ) ) game ( name "Franklin's Great Adventures (USA) (En,Fr,Es)" description "Franklin's Great Adventures (USA) (En,Fr,Es)" - rom ( name "Franklin's Great Adventures (USA) (En,Fr,Es).gba" size 4194304 crc 7FBF8E98 md5 36EAF4FEC9E81F3EA44869033996CEDD sha1 2DA756BED887DBD33FC0EFDD3DCD01FBB92AE0DC ) + rom ( name "Franklin's Great Adventures (USA) (En,Fr,Es).gba" size 4194304 crc 7fbf8e98 sha1 2DA756BED887DBD33FC0EFDD3DCD01FBB92AE0DC ) ) game ( name "Freekstyle (USA)" description "Freekstyle (USA)" - rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 md5 11289EEB3326A826CDA771CEE60B6B7F sha1 DCECCE5EBC93CFC421094ECB00A50DFE371BAD24 flags verified ) + rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 sha1 DCECCE5EBC93CFC421094ECB00A50DFE371BAD24 flags verified ) ) game ( name "Freekstyle (Europe) (En,Fr,De,Es,It)" description "Freekstyle (Europe) (En,Fr,De,Es,It)" - rom ( name "Freekstyle (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 96871A23 md5 1B1D09FF352571DAC46B1790E000876D sha1 7D775A8815C14B1849D33E580960D1A2B76BB518 ) + rom ( name "Freekstyle (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 96871a23 sha1 7D775A8815C14B1849D33E580960D1A2B76BB518 ) ) game ( name "Freestyle Scooter (Europe)" description "Freestyle Scooter (Europe)" - rom ( name "Freestyle Scooter (Europe).gba" size 4194304 crc 0187988F md5 4CBA219BCCA2320EBF9C33410B6BECDE sha1 43CE66E7C5E7892350AF8E6C905559DE007B9FF9 ) + rom ( name "Freestyle Scooter (Europe).gba" size 4194304 crc 0187988f sha1 43CE66E7C5E7892350AF8E6C905559DE007B9FF9 ) ) game ( name "Frogger - Kodaibunmei no Nazo (Japan)" description "Frogger - Kodaibunmei no Nazo (Japan)" - rom ( name "Frogger - Kodaibunmei no Nazo (Japan).gba" size 8388608 crc 6853109B md5 4564FC48460AF11378AB12D5F181B219 sha1 8C1A3208D6BD34DF966617FCC5F539B14CC5992A ) + rom ( name "Frogger - Kodaibunmei no Nazo (Japan).gba" size 8388608 crc 6853109b sha1 8C1A3208D6BD34DF966617FCC5F539B14CC5992A flags verified ) ) game ( name "Frogger - Mahou no Kuni no Daibouken (Japan)" description "Frogger - Mahou no Kuni no Daibouken (Japan)" - rom ( name "Frogger - Mahou no Kuni no Daibouken (Japan).gba" size 8388608 crc B1EF7532 md5 706163C6ECDD4E595EB49CCE8107D0FC sha1 19DC5A95BDE29CF699629CB8191D168A04339877 ) + rom ( name "Frogger - Mahou no Kuni no Daibouken (Japan).gba" size 8388608 crc b1ef7532 sha1 19DC5A95BDE29CF699629CB8191D168A04339877 flags verified ) ) game ( name "Frogger Advance - The Great Quest (USA)" description "Frogger Advance - The Great Quest (USA)" - rom ( name "Frogger Advance - The Great Quest (USA).gba" size 8388608 crc B75782C9 md5 8451B02AB3FCB7CDA5C2DA3170BB6002 sha1 537AC41923D2E873E388732BADEAD1141C65C1FA flags verified ) + rom ( name "Frogger Advance - The Great Quest (USA).gba" size 8388608 crc b75782c9 sha1 537AC41923D2E873E388732BADEAD1141C65C1FA flags verified ) ) game ( name "Frogger Advance - The Great Quest (Europe) (En,Fr,De,Es,It)" description "Frogger Advance - The Great Quest (Europe) (En,Fr,De,Es,It)" - rom ( name "Frogger Advance - The Great Quest (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8873BD29 md5 D8DE1BC487149BDFD96F03031A8B0EBB sha1 776E2F4306A9561D2130E341764F27F7C16C5637 ) + rom ( name "Frogger Advance - The Great Quest (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8873bd29 sha1 776E2F4306A9561D2130E341764F27F7C16C5637 flags verified ) ) game ( name "Frogger's Adventures - Temple of the Frog (USA) (En,Fr,De,Es,It)" description "Frogger's Adventures - Temple of the Frog (USA) (En,Fr,De,Es,It)" - rom ( name "Frogger's Adventures - Temple of the Frog (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2EB9EEE6 md5 228CBF6936579B32B8CC6D7B092DAD9C sha1 7B4C27009198DF18555E63FB5DCAD223EAF09815 ) + rom ( name "Frogger's Adventures - Temple of the Frog (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2eb9eee6 sha1 7B4C27009198DF18555E63FB5DCAD223EAF09815 ) ) game ( name "Frogger's Adventures - Temple of the Frog (Europe) (En,Fr,De,Es,It)" description "Frogger's Adventures - Temple of the Frog (Europe) (En,Fr,De,Es,It)" - rom ( name "Frogger's Adventures - Temple of the Frog (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9F8D58AA md5 75AF521C08DEA3EED23D31C002A3E47F sha1 775243ABE242CD748BF9A9648481EFE61B93F046 ) -) - -game ( - name "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It)" - description "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It)" - rom ( name "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8ACD3AFC md5 FD3690A50BE799B40F00BC8989229C07 sha1 C23CB8BE7FA9D39D7C3B855B9033A9A115519B2D ) + rom ( name "Frogger's Adventures - Temple of the Frog (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9f8d58aa sha1 775243ABE242CD748BF9A9648481EFE61B93F046 ) ) game ( name "Frogger's Adventures 2 - The Lost Wand (USA) (En,Es)" description "Frogger's Adventures 2 - The Lost Wand (USA) (En,Es)" - rom ( name "Frogger's Adventures 2 - The Lost Wand (USA) (En,Es).gba" size 8388608 crc 27B95C01 md5 0C508E4785E89F25F5A746CBA838ED4B sha1 33101A170460FBB9664B4A1750A620436BE7261D flags verified ) + rom ( name "Frogger's Adventures 2 - The Lost Wand (USA) (En,Es).gba" size 8388608 crc 27b95c01 sha1 33101A170460FBB9664B4A1750A620436BE7261D flags verified ) +) + +game ( + name "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It)" + description "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It)" + rom ( name "Frogger's Adventures 2 - The Lost Wand (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8acd3afc sha1 C23CB8BE7FA9D39D7C3B855B9033A9A115519B2D ) ) game ( name "Frogger's Journey - The Forgotten Relic (USA)" description "Frogger's Journey - The Forgotten Relic (USA)" - rom ( name "Frogger's Journey - The Forgotten Relic (USA).gba" size 8388608 crc 6F8BFDBC md5 16AE239C819D0A772307E3193D593860 sha1 19ED8E33FEE941BAE582ADBC67BF8B6BC53CB069 ) + rom ( name "Frogger's Journey - The Forgotten Relic (USA).gba" size 8388608 crc 6f8bfdbc sha1 19ED8E33FEE941BAE582ADBC67BF8B6BC53CB069 ) ) game ( name "From TV Animation One Piece - Mezase! King of Belly (Japan)" description "From TV Animation One Piece - Mezase! King of Belly (Japan)" - rom ( name "From TV Animation One Piece - Mezase! King of Belly (Japan).gba" size 8388608 crc E6F5BDD5 md5 B4B64FFA04795EF56F3925702A2BE291 sha1 9B4E610A2F342F06DE3704F7F0B35E6E562DA928 ) + rom ( name "From TV Animation One Piece - Mezase! King of Belly (Japan).gba" size 8388608 crc e6f5bdd5 sha1 9B4E610A2F342F06DE3704F7F0B35E6E562DA928 ) ) game ( name "From TV Animation One Piece - Nanatsu-jima no Daihihou (Japan)" description "From TV Animation One Piece - Nanatsu-jima no Daihihou (Japan)" - rom ( name "From TV Animation One Piece - Nanatsu-jima no Daihihou (Japan).gba" size 8388608 crc FD4CE9C8 md5 12E67891BD86B4B417B7462D7EE891EF sha1 7F1448B7F9D71E9701162749766CD3374B2965D8 ) + rom ( name "From TV Animation One Piece - Nanatsu-jima no Daihihou (Japan).gba" size 8388608 crc fd4ce9c8 sha1 7F1448B7F9D71E9701162749766CD3374B2965D8 flags verified ) ) game ( name "Frontier Stories (Japan)" description "Frontier Stories (Japan)" - rom ( name "Frontier Stories (Japan).gba" size 8388608 crc 4D6BF573 md5 8E11C9E996E0FCAE6D95483B4A2ADFDC sha1 542B83AF98FB489E420E6E8547D76351993A56C9 ) -) - -game ( - name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2)" - description "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2)" - rom ( name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2).gba" size 8388608 crc 195D7EA7 md5 A80A447EBDE7C4BAC73CAF9D6910F9EE sha1 21BA1D85C204F58F2867B9FDE8498318C8423BE7 ) + rom ( name "Frontier Stories (Japan).gba" size 8388608 crc 4d6bf573 sha1 542B83AF98FB489E420E6E8547D76351993A56C9 ) ) game ( name "Fruits Mura no Doubutsu-tachi (Japan)" description "Fruits Mura no Doubutsu-tachi (Japan)" - rom ( name "Fruits Mura no Doubutsu-tachi (Japan).gba" size 8388608 crc EBF89B0D md5 69198BA531E06FA1CD9014D6D41AC0D4 sha1 8D582AD27C888E3DBBFFBD421F40B54D15F977EF ) + rom ( name "Fruits Mura no Doubutsu-tachi (Japan).gba" size 8388608 crc ebf89b0d sha1 8D582AD27C888E3DBBFFBD421F40B54D15F977EF ) +) + +game ( + name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2)" + description "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2)" + rom ( name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 2).gba" size 8388608 crc 195d7ea7 sha1 21BA1D85C204F58F2867B9FDE8498318C8423BE7 ) +) + +game ( + name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 1)" + description "Fruits Mura no Doubutsu-tachi (Japan) (Rev 1)" + rom ( name "Fruits Mura no Doubutsu-tachi (Japan) (Rev 1).gba" size 8388608 crc aa14b198 sha1 31ECF4C1539EF7460706B17BB4404D4254C6265A flags verified ) ) game ( name "Fushigi no Kuni no Alice (Japan)" description "Fushigi no Kuni no Alice (Japan)" - rom ( name "Fushigi no Kuni no Alice (Japan).gba" size 4194304 crc 2CDA40E1 md5 20121E429EE5ECE132B9AC3B0F22EFE9 sha1 2B2D625E71C4FFC53CE6FC573672A50E1B788DBC ) + rom ( name "Fushigi no Kuni no Alice (Japan).gba" size 4194304 crc 2cda40e1 sha1 2B2D625E71C4FFC53CE6FC573672A50E1B788DBC ) ) game ( name "Fushigi no Kuni no Angelique (Japan)" description "Fushigi no Kuni no Angelique (Japan)" - rom ( name "Fushigi no Kuni no Angelique (Japan).gba" size 4194304 crc 803FC474 md5 F4DD91F51E8B310542D333EA0D2C9F0C sha1 EA6D9B71023D400141E480119FCE4EAD28DBB845 ) + rom ( name "Fushigi no Kuni no Angelique (Japan).gba" size 4194304 crc 803fc474 sha1 EA6D9B71023D400141E480119FCE4EAD28DBB845 ) ) game ( - name "Futari wa PreCure - Arienaai! Yume no Sono wa Daimeikyuu (Japan)" - description "Futari wa PreCure - Arienaai! Yume no Sono wa Daimeikyuu (Japan)" - rom ( name "Futari wa PreCure - Arienaai! Yume no Sono wa Daimeikyuu (Japan).gba" size 4194304 crc 6026EECD md5 3A79FE76FEFAEE55CD4BEA89940F5B73 sha1 07F15E69CFEAE805DAC20D28380079A48DEB97A8 flags verified ) + name "Futari wa Pretty Cure - Arienaai! Yume no Sono wa Daimeikyuu (Japan)" + description "Futari wa Pretty Cure - Arienaai! Yume no Sono wa Daimeikyuu (Japan)" + rom ( name "Futari wa Pretty Cure - Arienaai! Yume no Sono wa Daimeikyuu (Japan).gba" size 4194304 crc 6026eecd sha1 07F15E69CFEAE805DAC20D28380079A48DEB97A8 flags verified ) ) game ( - name "Futari wa PreCure Max Heart - Maji Maji! Fight de IN Janai (Japan)" - description "Futari wa PreCure Max Heart - Maji Maji! Fight de IN Janai (Japan)" - rom ( name "Futari wa PreCure Max Heart - Maji Maji! Fight de IN Janai (Japan).gba" size 8388608 crc 541C18F9 md5 8174D9620184763725F25E149B228E79 sha1 FB6B864B13F41AF2521C7E9C7BEC0B490962452F ) + name "Futari wa Pretty Cure Max Heart - Maji Maji! Fight de IN Janai (Japan)" + description "Futari wa Pretty Cure Max Heart - Maji Maji! Fight de IN Janai (Japan)" + rom ( name "Futari wa Pretty Cure Max Heart - Maji Maji! Fight de IN Janai (Japan).gba" size 8388608 crc 541c18f9 sha1 FB6B864B13F41AF2521C7E9C7BEC0B490962452F flags verified ) ) game ( name "Gachasute! Dino Device - Blue (Japan)" description "Gachasute! Dino Device - Blue (Japan)" - rom ( name "Gachasute! Dino Device - Blue (Japan).gba" size 8388608 crc EB9F6F11 md5 5CC9B8D313D1EE5EA7C994DC18F85B95 sha1 EAC296B55BEA162DF72E417A501BE70060BD1337 ) + rom ( name "Gachasute! Dino Device - Blue (Japan).gba" size 8388608 crc eb9f6f11 sha1 EAC296B55BEA162DF72E417A501BE70060BD1337 ) ) game ( name "Gachasute! Dino Device - Red (Japan)" description "Gachasute! Dino Device - Red (Japan)" - rom ( name "Gachasute! Dino Device - Red (Japan).gba" size 8388608 crc DDA5EC5E md5 23A1A8685D67405271F297F5A042FA23 sha1 9086AA71D23A753CF0E307A37D56C61C3805ADB6 ) + rom ( name "Gachasute! Dino Device - Red (Japan).gba" size 8388608 crc dda5ec5e sha1 9086AA71D23A753CF0E307A37D56C61C3805ADB6 ) ) game ( name "Gachasute! Dino Device 2 - Dragon (Japan)" description "Gachasute! Dino Device 2 - Dragon (Japan)" - rom ( name "Gachasute! Dino Device 2 - Dragon (Japan).gba" size 4194304 crc A63DFD2C md5 8A6795C788C97627E06A987CF25B4D2B sha1 8BB322121CA889ED8A7B22A907CD835E23FD4449 ) + rom ( name "Gachasute! Dino Device 2 - Dragon (Japan).gba" size 4194304 crc a63dfd2c sha1 8BB322121CA889ED8A7B22A907CD835E23FD4449 ) ) game ( name "Gachasute! Dino Device 2 - Phoenix (Japan)" description "Gachasute! Dino Device 2 - Phoenix (Japan)" - rom ( name "Gachasute! Dino Device 2 - Phoenix (Japan).gba" size 4194304 crc 67E21BFE md5 533268AC99BC27456DDA1FC423C56911 sha1 A209AB6E216A1054961BB25C26AEF79C749E2D67 ) + rom ( name "Gachasute! Dino Device 2 - Phoenix (Japan).gba" size 4194304 crc 67e21bfe sha1 A209AB6E216A1054961BB25C26AEF79C749E2D67 flags verified ) ) game ( name "Gachinko Pro Yakyuu (Japan)" description "Gachinko Pro Yakyuu (Japan)" - rom ( name "Gachinko Pro Yakyuu (Japan).gba" size 8388608 crc 81DE0C16 md5 DE7ACDA94A1F36A2B9218A10ADE91E68 sha1 E3A4E08507B6DADA3DAC464888E8CB97DEC3A33A ) + rom ( name "Gachinko Pro Yakyuu (Japan).gba" size 8388608 crc 81de0c16 sha1 E3A4E08507B6DADA3DAC464888E8CB97DEC3A33A ) ) game ( name "Gadget Racers (USA)" description "Gadget Racers (USA)" - rom ( name "Gadget Racers (USA).gba" size 4194304 crc 95DD156A md5 484128ABB48B33871C909403C90B9B04 sha1 BEF8444D0730B61E55883CC3EDF754F884F7DF61 ) + rom ( name "Gadget Racers (USA).gba" size 4194304 crc 95dd156a sha1 BEF8444D0730B61E55883CC3EDF754F884F7DF61 ) ) game ( name "Gadget Racers (Europe) (En,Fr,De)" description "Gadget Racers (Europe) (En,Fr,De)" - rom ( name "Gadget Racers (Europe) (En,Fr,De).gba" size 8388608 crc D2BC5027 md5 963C095C626A5DAC37251853D406597F sha1 7A7CD2860C677AAF6D45814877727E0077C7707B flags verified ) + rom ( name "Gadget Racers (Europe) (En,Fr,De).gba" size 8388608 crc d2bc5027 sha1 7A7CD2860C677AAF6D45814877727E0077C7707B flags verified ) ) game ( name "Gakkou no Kaidan - Hyakuyoubako no Fuuin (Japan)" description "Gakkou no Kaidan - Hyakuyoubako no Fuuin (Japan)" - rom ( name "Gakkou no Kaidan - Hyakuyoubako no Fuuin (Japan).gba" size 8388608 crc 5847A906 md5 CC47DA225C68373CEA90C2CAA2963A8E sha1 F7E55C8A94EEC49EF9EED39AC076688DE2EE5A42 ) + rom ( name "Gakkou no Kaidan - Hyakuyoubako no Fuuin (Japan).gba" size 8388608 crc 5847a906 sha1 F7E55C8A94EEC49EF9EED39AC076688DE2EE5A42 ) ) game ( name "Gakkou o Tsukurou!! Advance (Japan)" description "Gakkou o Tsukurou!! Advance (Japan)" - rom ( name "Gakkou o Tsukurou!! Advance (Japan).gba" size 8388608 crc 6EB70422 md5 DF83B7498860FBF0678D8FC6A2664E18 sha1 5BD69C56B2B61DB05464BEBC2B579457B986C01B ) + rom ( name "Gakkou o Tsukurou!! Advance (Japan).gba" size 8388608 crc 6eb70422 sha1 5BD69C56B2B61DB05464BEBC2B579457B986C01B ) ) game ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan)" description "Gakuen Alice - Dokidoki Fushigi Taiken (Japan)" - rom ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan).gba" size 8388608 crc AAB51F8C md5 CB9EE964B373D6C44272A292571BF9C1 sha1 2D97FDE943DD575CBF29C420EB6694F411CFD626 ) + rom ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan).gba" size 8388608 crc aab51f8c sha1 2D97FDE943DD575CBF29C420EB6694F411CFD626 ) ) game ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan) (Rev 1)" description "Gakuen Alice - Dokidoki Fushigi Taiken (Japan) (Rev 1)" - rom ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan) (Rev 1).gba" size 8388608 crc 8CB61158 md5 5FCD171900998007031FA54FDAF55268 sha1 3B61A6B5CB8E4451FA296245A6344006E69D5272 ) + rom ( name "Gakuen Alice - Dokidoki Fushigi Taiken (Japan) (Rev 1).gba" size 8388608 crc 8cb61158 sha1 3B61A6B5CB8E4451FA296245A6344006E69D5272 ) ) game ( name "Gakuen Senki Muryou (Japan)" description "Gakuen Senki Muryou (Japan)" - rom ( name "Gakuen Senki Muryou (Japan).gba" size 8388608 crc 82983321 md5 D74A23C7DF011771C5BFA6F36B2DD920 sha1 138659FEB870C798FA7F6553AF0E859B6736D030 ) + rom ( name "Gakuen Senki Muryou (Japan).gba" size 8388608 crc 82983321 sha1 138659FEB870C798FA7F6553AF0E859B6736D030 ) ) game ( name "Galaxy Angel Game Boy Advance - Moridakusan Tenshi no Full-Course - Okawari Jiyuu (Japan)" description "Galaxy Angel Game Boy Advance - Moridakusan Tenshi no Full-Course - Okawari Jiyuu (Japan)" - rom ( name "Galaxy Angel Game Boy Advance - Moridakusan Tenshi no Full-Course - Okawari Jiyuu (Japan).gba" size 16777216 crc B99E2333 md5 91874D50834CC7B752922F917F9CD8F7 sha1 6C7AB1710303F48174646F00FC5C6981D2B4CB31 ) + rom ( name "Galaxy Angel Game Boy Advance - Moridakusan Tenshi no Full-Course - Okawari Jiyuu (Japan).gba" size 16777216 crc b99e2333 sha1 6C7AB1710303F48174646F00FC5C6981D2B4CB31 ) ) game ( name "Galidor - Defenders of the Outer Dimension (USA) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Galidor - Defenders of the Outer Dimension (USA) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Galidor - Defenders of the Outer Dimension (USA) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 4D8F49F9 md5 101C1C8ED0CA51DA145B101C8A42B0EB sha1 86CF0842E9FCBDFE6240BE580E08AE44E0A07A47 ) + rom ( name "Galidor - Defenders of the Outer Dimension (USA) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 4d8f49f9 sha1 86CF0842E9FCBDFE6240BE580E08AE44E0A07A47 ) ) game ( name "Gambler Densetsu Tetsuya - Yomigaeru Densetsu (Japan)" description "Gambler Densetsu Tetsuya - Yomigaeru Densetsu (Japan)" - rom ( name "Gambler Densetsu Tetsuya - Yomigaeru Densetsu (Japan).gba" size 8388608 crc 8A879018 md5 0A0F0C3F73CA585C19F516C7E45FDA74 sha1 BF4664EC225ED66E72E98393B9B6EC10B3CC9B10 ) + rom ( name "Gambler Densetsu Tetsuya - Yomigaeru Densetsu (Japan).gba" size 8388608 crc 8a879018 sha1 BF4664EC225ED66E72E98393B9B6EC10B3CC9B10 ) ) game ( name "Game & Watch Gallery 4 (USA)" description "Game & Watch Gallery 4 (USA)" - rom ( name "Game & Watch Gallery 4 (USA).gba" size 4194304 crc 7E90CEA2 md5 89BD27CD7228736D9C00461ABD20C208 sha1 56BE8E044ABA698F1D573053B5AF8E0C0BFCC060 flags verified ) + rom ( name "Game & Watch Gallery 4 (USA).gba" size 4194304 crc 7e90cea2 sha1 56BE8E044ABA698F1D573053B5AF8E0C0BFCC060 flags verified ) +) + +game ( + name "Game & Watch Gallery 4 (USA) (Wii U Virtual Console)" + description "Game & Watch Gallery 4 (USA) (Wii U Virtual Console)" + rom ( name "Game & Watch Gallery 4 (USA) (Wii U Virtual Console).gba" size 4194304 crc 0a517352 sha1 3FD362B2E05F86F430BB5225CBEB4A8D04EF9D1F flags verified ) ) game ( name "Game & Watch Gallery Advance (Europe)" description "Game & Watch Gallery Advance (Europe)" - rom ( name "Game & Watch Gallery Advance (Europe).gba" size 4194304 crc 85C837AF md5 A08C51144B35F3A09BA1C65B583FEDDD sha1 3D6935D925A375ADD5532B50816C497D3CD67C59 flags verified ) + rom ( name "Game & Watch Gallery Advance (Europe).gba" size 4194304 crc 85c837af sha1 3D6935D925A375ADD5532B50816C497D3CD67C59 flags verified ) ) game ( name "Game Boy Advance Video - All Grown Up! - Volume 1 (USA)" description "Game Boy Advance Video - All Grown Up! - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - All Grown Up! - Volume 1 (USA).gba" size 33554432 crc FFBD4DA9 md5 ECB42C36F389B45E7B93D14673DBE506 sha1 02158627FD5A526F848077440182FA92AD87EA3F ) + rom ( name "Game Boy Advance Video - All Grown Up! - Volume 1 (USA).gba" size 33554432 crc ffbd4da9 sha1 02158627FD5A526F848077440182FA92AD87EA3F ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Platinum (France)" description "Game Boy Advance Video - Cartoon Network Collection - Edition Platinum (France)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Platinum (France).gba" size 33554432 crc FC042F18 md5 1577640560B3CBFF587EE29BA073A2C1 sha1 01564B86644CF43F49320E0C05854896F8C60C2F ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Platinum (France).gba" size 33554432 crc fc042f18 sha1 01564B86644CF43F49320E0C05854896F8C60C2F ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Premium (France)" description "Game Boy Advance Video - Cartoon Network Collection - Edition Premium (France)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Premium (France).gba" size 33554432 crc 58F1CDE8 md5 3FC8B5ADF57D1C1975C132686D398FCF sha1 F63052E2B53C42601F53148BEE69F89D9591FBF9 flags verified ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Premium (France).gba" size 33554432 crc 58f1cde8 sha1 F63052E2B53C42601F53148BEE69F89D9591FBF9 flags verified ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Speciale (France)" description "Game Boy Advance Video - Cartoon Network Collection - Edition Speciale (France)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Speciale (France).gba" size 33554432 crc 71154D42 md5 FC8CB7B530C412E403B4B4EB98751586 sha1 73CBDD82640F166737173B0E8197D771D7906A91 ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Edition Speciale (France).gba" size 33554432 crc 71154d42 sha1 73CBDD82640F166737173B0E8197D771D7906A91 ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Limited Edition (USA)" description "Game Boy Advance Video - Cartoon Network Collection - Limited Edition (USA)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Limited Edition (USA).gba" size 33554432 crc 5D918B2D md5 CFF33AABB6BDAC294C1A250AFE5248B0 sha1 AC63A7691774BDE6EAAD4C2C5C4D305E7CC0535A ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Limited Edition (USA).gba" size 33554432 crc 5d918b2d sha1 AC63A7691774BDE6EAAD4C2C5C4D305E7CC0535A ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Platinum Edition (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Platinum Edition (USA, Europe)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Platinum Edition (USA, Europe).gba" size 33554432 crc 6443554B md5 638D4C91D3119289573E94FC47AA2AB0 sha1 0CF9B536F87CB21F738BD7552E95BD114B0F0B2E ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Platinum Edition (USA, Europe).gba" size 33554432 crc 6443554b sha1 0CF9B536F87CB21F738BD7552E95BD114B0F0B2E ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe).gba" size 33554432 crc F2825729 md5 A1DCDF3F1625FEB7ECD54D747D08FB37 sha1 D0FE380FCDF5B1BB99188ED95C8C3272CBB65CE8 flags verified ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Premium Edition (USA, Europe).gba" size 33554432 crc f2825729 sha1 D0FE380FCDF5B1BB99188ED95C8C3272CBB65CE8 flags verified ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe).gba" size 33554432 crc E9B7B8A4 md5 9E026E4C444DDD4CDCD275F7162835F1 sha1 5F17D2EC1A3BA1D605D486B6F6ABCDE6D82DF767 flags verified ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA, Europe).gba" size 33554432 crc e9b7b8a4 sha1 5F17D2EC1A3BA1D605D486B6F6ABCDE6D82DF767 flags verified ) ) game ( - name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA)" - description "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA).gba" size 33554432 crc 91F39447 md5 9D88169F003267C96A4A42E8F4C377BD sha1 3227D82E64024A5DC0E5B7F3FD768B0FEC19E9B0 flags verified ) + name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" + description "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe).gba" size 33554432 crc 91f39447 sha1 3227D82E64024A5DC0E5B7F3FD768B0FEC19E9B0 flags verified ) ) game ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 2 (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Volume 2 (USA, Europe)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 2 (USA, Europe).gba" size 33554432 crc 4BFAA8DE md5 80236C93C72DC4EE4BD0E3C22FFAC303 sha1 692FFA1856780EDD28B3AA55526AD06EEDDC292E flags verified ) + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 2 (USA, Europe).gba" size 33554432 crc 4bfaa8de sha1 692FFA1856780EDD28B3AA55526AD06EEDDC292E flags verified ) ) game ( name "Game Boy Advance Video - Codename - Kids Next Door - Volume 1 (USA, Europe)" description "Game Boy Advance Video - Codename - Kids Next Door - Volume 1 (USA, Europe)" - rom ( name "Game Boy Advance Video - Codename - Kids Next Door - Volume 1 (USA, Europe).gba" size 33554432 crc 4463F345 md5 09A08B8E39FA938D4DD121642F3A0CB1 sha1 5E78808676213D6E5B55A78560FC47112F3008D4 ) + rom ( name "Game Boy Advance Video - Codename - Kids Next Door - Volume 1 (USA, Europe).gba" size 33554432 crc 4463f345 sha1 5E78808676213D6E5B55A78560FC47112F3008D4 flags verified ) ) game ( name "Game Boy Advance Video - Disney Channel Collection - Volume 1 (USA)" description "Game Boy Advance Video - Disney Channel Collection - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Disney Channel Collection - Volume 1 (USA).gba" size 33554432 crc 7CC985CB md5 340F5CE39C1D2EA31A7B61148B376F70 sha1 53069A5A8B564495AD800F0685B4D1970859B0F8 ) + rom ( name "Game Boy Advance Video - Disney Channel Collection - Volume 1 (USA).gba" size 33554432 crc 7cc985cb sha1 53069A5A8B564495AD800F0685B4D1970859B0F8 ) +) + +game ( + name "Game Boy Advance Video - Disney Channel Collection - Volume 2 (USA) (Rev 5)" + description "Game Boy Advance Video - Disney Channel Collection - Volume 2 (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Disney Channel Collection - Volume 2 (USA) (Rev 5).gba" size 67108864 crc 60dfd79c sha1 864CE0DB324B1252DF923804F8C6E812D5EBCBBA flags verified ) ) game ( name "Game Boy Advance Video - Dora the Explorer - Volume 1 (USA)" description "Game Boy Advance Video - Dora the Explorer - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Dora the Explorer - Volume 1 (USA).gba" size 33554432 crc DD6A7FCC md5 CC49428F911D2A550C192E5829D8C8AE sha1 67FE664BDADC7927BA888014EA923F11E3334B6C ) + rom ( name "Game Boy Advance Video - Dora the Explorer - Volume 1 (USA).gba" size 33554432 crc dd6a7fcc sha1 67FE664BDADC7927BA888014EA923F11E3334B6C ) ) game ( name "Game Boy Advance Video - Dragon Ball GT - Volume 1 (USA)" description "Game Boy Advance Video - Dragon Ball GT - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Dragon Ball GT - Volume 1 (USA).gba" size 33554432 crc DA559199 md5 E6BDA86BEDEC314B4A2096AFDA57367F sha1 DC85CCCC0CEDE3FC11D257995CD7D3CC64CA00E0 ) + rom ( name "Game Boy Advance Video - Dragon Ball GT - Volume 1 (USA).gba" size 33554432 crc da559199 sha1 DC85CCCC0CEDE3FC11D257995CD7D3CC64CA00E0 ) ) game ( name "Game Boy Advance Video - Nicktoons - Volume 3 (USA)" description "Game Boy Advance Video - Nicktoons - Volume 3 (USA)" - rom ( name "Game Boy Advance Video - Nicktoons - Volume 3 (USA).gba" size 33554432 crc 6FBF5CEB md5 E45A12595BFF7E3386C8AC2650972AC2 sha1 2732103FDA15D8FB017F21023D2FDA22AE7A548A ) + rom ( name "Game Boy Advance Video - Nicktoons - Volume 3 (USA).gba" size 33554432 crc 6fbf5ceb sha1 2732103FDA15D8FB017F21023D2FDA22AE7A548A ) ) game ( name "Game Boy Advance Video - Nicktoons Collection - Volume 1 (USA)" description "Game Boy Advance Video - Nicktoons Collection - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 1 (USA).gba" size 33554432 crc 5D47676F md5 F0F7BA8C3766252A6E8D1D4FCF4EB5DD sha1 B3BF6D95B548A82808A109CEFAAF8B0C22CA66F2 ) + rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 1 (USA).gba" size 33554432 crc 5d47676f sha1 B3BF6D95B548A82808A109CEFAAF8B0C22CA66F2 ) ) game ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA)" description "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA)" - rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA).gba" size 33554432 crc 65DEEEB6 md5 10799BA44ADDE27FB8919A61BE5C63F1 sha1 03A767124F034B1EEA51AB84BA6E80EC76F7F50C ) + rom ( name "Game Boy Advance Video - Nicktoons Collection - Volume 2 (USA).gba" size 33554432 crc 65deeeb6 sha1 03A767124F034B1EEA51AB84BA6E80EC76F7F50C ) ) game ( name "Game Boy Advance Video - Pokemon - Volume 1 (USA)" description "Game Boy Advance Video - Pokemon - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Pokemon - Volume 1 (USA).gba" size 33554432 crc A59EF954 md5 E6E925F30CD62E8BC0841935235D7703 sha1 AD0164DF397860B0967590EE46CA1F41D6CECDCD ) + rom ( name "Game Boy Advance Video - Pokemon - Volume 1 (USA).gba" size 33554432 crc a59ef954 sha1 AD0164DF397860B0967590EE46CA1F41D6CECDCD ) ) game ( name "Game Boy Advance Video - Pokemon - Volume 2 (USA)" description "Game Boy Advance Video - Pokemon - Volume 2 (USA)" - rom ( name "Game Boy Advance Video - Pokemon - Volume 2 (USA).gba" size 33554432 crc 0DA1A383 md5 156F42E151118269786D15DB8B71F300 sha1 E7B2E00D6A60E8C149CD07B0EE8D98BF2B4EFD15 ) + rom ( name "Game Boy Advance Video - Pokemon - Volume 2 (USA).gba" size 33554432 crc 0da1a383 sha1 E7B2E00D6A60E8C149CD07B0EE8D98BF2B4EFD15 ) ) game ( name "Game Boy Advance Video - Pokemon - Volume 3 (USA)" description "Game Boy Advance Video - Pokemon - Volume 3 (USA)" - rom ( name "Game Boy Advance Video - Pokemon - Volume 3 (USA).gba" size 33554432 crc A36AA9C5 md5 E3354800674C44704952A33556234B75 sha1 0F0020EF4278E1777BAAF74B6787355A5CB57D50 ) + rom ( name "Game Boy Advance Video - Pokemon - Volume 3 (USA).gba" size 33554432 crc a36aa9c5 sha1 0F0020EF4278E1777BAAF74B6787355A5CB57D50 ) ) game ( name "Game Boy Advance Video - Pokemon - Volume 4 (USA)" description "Game Boy Advance Video - Pokemon - Volume 4 (USA)" - rom ( name "Game Boy Advance Video - Pokemon - Volume 4 (USA).gba" size 33554432 crc BE468496 md5 780DCD0CB1E1913BB68DF762B4A0A873 sha1 FD79B821FF601E0091F19AB9C86B08F1C39EA2F3 ) + rom ( name "Game Boy Advance Video - Pokemon - Volume 4 (USA).gba" size 33554432 crc be468496 sha1 FD79B821FF601E0091F19AB9C86B08F1C39EA2F3 ) +) + +game ( + name "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" + description "Game Boy Advance Video - Shark Tale (USA) (Rev 6)" + rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 6).gba" size 67108864 crc d2cf417a sha1 9BC5B60793B8A6DE3B80EB2C213CD125E1FA468E flags verified ) +) + +game ( + name "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" + description "Game Boy Advance Video - Shark Tale (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shark Tale (USA) (Rev 5).gba" size 67108864 crc 01468820 sha1 6128A476EDB10E6839AC5BD2697E83B9B7A9B234 flags verified ) +) + +game ( + name "Game Boy Advance Video - Shrek (USA) (Rev 5)" + description "Game Boy Advance Video - Shrek (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shrek (USA) (Rev 5).gba" size 67108864 crc 690176e5 sha1 2DEDEA86EC289A0E31089299613D9F74CCA03609 flags verified ) +) + +game ( + name "Game Boy Advance Video - Shrek (USA) (Rev 6)" + description "Game Boy Advance Video - Shrek (USA) (Rev 6)" + rom ( name "Game Boy Advance Video - Shrek (USA) (Rev 6).gba" size 67108864 crc 4010e9fa sha1 95D612057682B7B886441D387B167BA2493E49EF flags verified ) +) + +game ( + name "Game Boy Advance Video - Shrek + Shark Tale (USA) (Rev 5)" + description "Game Boy Advance Video - Shrek + Shark Tale (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shrek + Shark Tale (USA) (Rev 5).gba" size 67108864 crc aadb3e3d sha1 F23390B7A62C605FBCE6730ADDC29D381488E076 flags verified ) +) + +game ( + name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" + description "Game Boy Advance Video - Shrek 2 (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 5).gba" size 67108864 crc 0d353654 sha1 5CD627E205020297B25D707131883BE5850515FE flags verified ) +) + +game ( + name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" + description "Game Boy Advance Video - Shrek 2 (USA) (Rev 6)" + rom ( name "Game Boy Advance Video - Shrek 2 (USA) (Rev 6).gba" size 67108864 crc 925b6c02 sha1 3BCB4ACC5DA539BC1B91C9537BF7FFA081DED1D4 flags verified ) ) game ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA)" description "Game Boy Advance Video - Sonic X - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA).gba" size 33554432 crc 363C3EB8 md5 36DFCAB0D39BAE344F1E9ECDA2A226B7 sha1 DC4C959A7740315D892633869F7FC6382AADBB0E ) + rom ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA).gba" size 33554432 crc 363c3eb8 sha1 DC4C959A7740315D892633869F7FC6382AADBB0E ) ) game ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 1 (USA) (Rev 1)" description "Game Boy Advance Video - SpongeBob SquarePants - Volume 1 (USA) (Rev 1)" - rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 1 (USA) (Rev 1).gba" size 33554432 crc D47BF1D4 md5 5FD40871088818467ED5405AAF9644E1 sha1 65F6B06C5397B9406960050025361550E0FF2E92 flags verified ) + rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 1 (USA) (Rev 1).gba" size 33554432 crc d47bf1d4 sha1 65F6B06C5397B9406960050025361550E0FF2E92 flags verified ) ) game ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 2 (USA) (Rev 1)" description "Game Boy Advance Video - SpongeBob SquarePants - Volume 2 (USA) (Rev 1)" - rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 2 (USA) (Rev 1).gba" size 33554432 crc 7074364A md5 7E3FF9DFB76C4160F3BC70F1727AF203 sha1 C4CAA875F93657626BF73541DDD61EB5C8B4957E ) + rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 2 (USA) (Rev 1).gba" size 33554432 crc 7074364a sha1 C4CAA875F93657626BF73541DDD61EB5C8B4957E ) ) game ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 3 (USA)" description "Game Boy Advance Video - SpongeBob SquarePants - Volume 3 (USA)" - rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 3 (USA).gba" size 33554432 crc 9772CA45 md5 181CA9365D62BF3ACFDBB4C6717D3C12 sha1 FA11AEEF21CDD18FCFEA281990030ACB65C7AA96 ) + rom ( name "Game Boy Advance Video - SpongeBob SquarePants - Volume 3 (USA).gba" size 33554432 crc 9772ca45 sha1 FA11AEEF21CDD18FCFEA281990030ACB65C7AA96 ) ) game ( name "Game Boy Advance Video - Strawberry Shortcake - Volume 1 (USA)" description "Game Boy Advance Video - Strawberry Shortcake - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Strawberry Shortcake - Volume 1 (USA).gba" size 33554432 crc FF7582EF md5 224F20711583402F8575795B3CCEA869 sha1 F84CC8A33E3A75E42F4E8023A5CC851C92EA409A ) + rom ( name "Game Boy Advance Video - Strawberry Shortcake - Volume 1 (USA).gba" size 33554432 crc ff7582ef sha1 F84CC8A33E3A75E42F4E8023A5CC851C92EA409A ) ) game ( name "Game Boy Advance Video - Super Robot Monkey Team - Hyper Force Go! - Volume 1 (USA)" description "Game Boy Advance Video - Super Robot Monkey Team - Hyper Force Go! - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - Super Robot Monkey Team - Hyper Force Go! - Volume 1 (USA).gba" size 33554432 crc D743A070 md5 60FA719B84F02367ADDC3D0DAD085AA8 sha1 E3BCE6DDF9437BDED89FC662E992C1AB0AA1DBBA ) + rom ( name "Game Boy Advance Video - Super Robot Monkey Team - Hyper Force Go! - Volume 1 (USA).gba" size 33554432 crc d743a070 sha1 E3BCE6DDF9437BDED89FC662E992C1AB0AA1DBBA ) ) game ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Le Demenagement (France)" description "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Le Demenagement (France)" - rom ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Le Demenagement (France).gba" size 33554432 crc 1EE78166 md5 41322207C6B54012F094A3410DF58C7A sha1 1C7444A45C9BD15B1643C195832497881955ACEE flags verified ) + rom ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Le Demenagement (France).gba" size 33554432 crc 1ee78166 sha1 1C7444A45C9BD15B1643C195832497881955ACEE flags verified ) ) game ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Things Change (USA, Europe)" description "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Things Change (USA, Europe)" - rom ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Things Change (USA, Europe).gba" size 33554432 crc 046589C8 md5 B38AA51C2C27BF689E3D3DA520D77339 sha1 8B9665CE2CEFD663F7722F38B64F9271F7C00DAA ) + rom ( name "Game Boy Advance Video - Teenage Mutant Ninja Turtles - Things Change (USA, Europe).gba" size 33554432 crc 046589c8 sha1 8B9665CE2CEFD663F7722F38B64F9271F7C00DAA flags verified ) ) game ( name "Game Boy Advance Video - The Adventures of Jimmy Neutron Boy Genius - Volume 1 (USA)" description "Game Boy Advance Video - The Adventures of Jimmy Neutron Boy Genius - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - The Adventures of Jimmy Neutron Boy Genius - Volume 1 (USA).gba" size 33554432 crc 0E556EDF md5 933F0A8D75E55D098B977014C5A51309 sha1 1414C55BD3D252FDC05C0A94085F12DDDF86EA31 ) + rom ( name "Game Boy Advance Video - The Adventures of Jimmy Neutron Boy Genius - Volume 1 (USA).gba" size 33554432 crc 0e556edf sha1 1414C55BD3D252FDC05C0A94085F12DDDF86EA31 ) ) game ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 1 (USA)" description "Game Boy Advance Video - The Fairly OddParents! - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 1 (USA).gba" size 33554432 crc 7958DF20 md5 B78C873CCE43CE5559E71FEA4CEFFB52 sha1 42E343E5048F99F05F7CDE5AAD6BFCC3D2410399 ) + rom ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 1 (USA).gba" size 33554432 crc 7958df20 sha1 42E343E5048F99F05F7CDE5AAD6BFCC3D2410399 ) ) game ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 2 (USA) (Rev 1)" description "Game Boy Advance Video - The Fairly OddParents! - Volume 2 (USA) (Rev 1)" - rom ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 2 (USA) (Rev 1).gba" size 33554432 crc BBCBC6FD md5 98668D516CC0753737118CDCED3CAFD4 sha1 5B8A83410D8F9DE12113E2974D65B5790AAF62FB ) + rom ( name "Game Boy Advance Video - The Fairly OddParents! - Volume 2 (USA) (Rev 1).gba" size 33554432 crc bbcbc6fd sha1 5B8A83410D8F9DE12113E2974D65B5790AAF62FB ) ) game ( name "Game Boy Advance Video - The Proud Family - Volume 1 (USA)" description "Game Boy Advance Video - The Proud Family - Volume 1 (USA)" - rom ( name "Game Boy Advance Video - The Proud Family - Volume 1 (USA).gba" size 33554432 crc C6A91365 md5 4A6CF80D29A6E4AB9B4204E6783657E0 sha1 31A2CBB9B1B5ADF7DE399EECF2A9CEC4F5412767 ) + rom ( name "Game Boy Advance Video - The Proud Family - Volume 1 (USA).gba" size 33554432 crc c6a91365 sha1 31A2CBB9B1B5ADF7DE399EECF2A9CEC4F5412767 ) ) game ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe)" description "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe)" - rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe).gba" size 33554432 crc 8D631F4E md5 E6E630C0E5EFE24D54242B55388FC4B2 sha1 6DAF15BB61A10D1BBF94009886D6A76F9C937F8B ) + rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (USA, Europe).gba" size 33554432 crc 8d631f4e sha1 6DAF15BB61A10D1BBF94009886D6A76F9C937F8B flags verified ) ) game ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" description "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France)" - rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France).gba" size 33554432 crc C9B6CCF1 md5 D7B7AAA61D7DBC76ED84ABE391DEE6DF sha1 8FB43E5018CF2D4B1A2AA2D1693862CE248AB6B0 flags verified ) + rom ( name "Game Boy Advance Video - Yu-Gi-Oh! - Yugi vs. Joey (France).gba" size 33554432 crc c9b6ccf1 sha1 8FB43E5018CF2D4B1A2AA2D1693862CE248AB6B0 flags verified ) +) + +game ( + name "Game Boy Gallery 4 (Japan) (Wii U Virtual Console)" + description "Game Boy Gallery 4 (Japan) (Wii U Virtual Console)" + rom ( name "Game Boy Gallery 4 (Japan) (Wii U Virtual Console).gba" size 4194304 crc 11cfc797 sha1 1C42316F5170DA878C57BE47DF3672285835F963 flags verified ) ) game ( name "Game Boy Wars Advance 1+2 (Japan)" description "Game Boy Wars Advance 1+2 (Japan)" - rom ( name "Game Boy Wars Advance 1+2 (Japan).gba" size 16777216 crc 49EE1FDD md5 08D5C8E67CF1CDBA2E55452C2E2414C1 sha1 0E805762D02DF41A7C1F840569D17EFB2FB92B1C ) + rom ( name "Game Boy Wars Advance 1+2 (Japan).gba" size 16777216 crc 49ee1fdd sha1 0E805762D02DF41A7C1F840569D17EFB2FB92B1C ) ) game ( name "Games Explosion! (USA)" description "Games Explosion! (USA)" - rom ( name "Games Explosion! (USA).gba" size 4194304 crc 68D63D5F md5 05C54425438B4E1FB9944F380DF39B4E sha1 F2D95CABF5CD75EE4EBCDF7B8EF669C6D8EDE989 ) + rom ( name "Games Explosion! (USA).gba" size 4194304 crc 68d63d5f sha1 F2D95CABF5CD75EE4EBCDF7B8EF669C6D8EDE989 ) ) game ( name "GameShark GBA (USA) (Alt 1) (Unl)" description "GameShark GBA (USA) (Alt 1) (Unl)" - rom ( name "GameShark GBA (USA) (Alt 1) (Unl).gba" size 262144 crc 9AD94C62 md5 7FA04C2A15D3561C9D2641AAB6946D6A sha1 9AB35E211AC9CC4AA4CE594C073B44C630E46814 ) + rom ( name "GameShark GBA (USA) (Alt 1) (Unl).gba" size 262144 crc 9ad94c62 sha1 9AB35E211AC9CC4AA4CE594C073B44C630E46814 ) ) game ( name "GameShark GBA (USA) (Unl)" description "GameShark GBA (USA) (Unl)" - rom ( name "GameShark GBA (USA) (Unl).gba" size 262144 crc D71DBCA6 md5 24B6419D695679A176C1D8EF4F21D667 sha1 02DC2E2AB31AD5111F3EFAD391F66945344F33E3 ) + rom ( name "GameShark GBA (USA) (Unl).gba" size 262144 crc d71dbca6 sha1 02DC2E2AB31AD5111F3EFAD391F66945344F33E3 ) ) game ( name "Ganbare! Dodge Fighters (Japan)" description "Ganbare! Dodge Fighters (Japan)" - rom ( name "Ganbare! Dodge Fighters (Japan).gba" size 4194304 crc 276E5814 md5 1FB97AE3ABE61BB55643559084CEB160 sha1 88B7832624BDB1DA62B5E8F2EBCEECC4628C7924 ) + rom ( name "Ganbare! Dodge Fighters (Japan).gba" size 4194304 crc 276e5814 sha1 88B7832624BDB1DA62B5E8F2EBCEECC4628C7924 ) ) game ( name "Gang del Bosco, La (Italy)" description "Gang del Bosco, La (Italy)" - rom ( name "Gang del Bosco, La (Italy).gba" size 8388608 crc 52A5B59D md5 9B71CC4B1E11FE39CED0C3E41061A117 sha1 75E7060B7DCE72D01FBD6A6D1D8E1D752BFC92D0 ) -) - -game ( - name "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" - description "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" - rom ( name "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 76035741 md5 CD27477E70B529B736746185B882100E sha1 7798A726A819E8A7DDCCD834AFD50D811796CFEE ) -) - -game ( - name "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2)" - description "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2)" - serial "AGB-BGOP-EUR" - rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2).gba" size 8388608 crc 0C3AA538 md5 42322E4FFCB66A6ACFE340642BDC8705 sha1 3E38901CECAD2C8AE3E5D91375AF6FA5D7734C19 flags verified ) -) - -game ( - name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1)" - description "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1)" - serial "AGB-BGOP-EUR" - rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1).gba" size 8388608 crc 387EB638 md5 54AECBD6193FA4306C371916F00FF6C6 sha1 5EAD81908F576E37837BAB60D5C580CA684A8FC5 ) + rom ( name "Gang del Bosco, La (Italy).gba" size 8388608 crc 52a5b59d sha1 75E7060B7DCE72D01FBD6A6D1D8E1D752BFC92D0 ) ) game ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It)" description "Garfield - The Search for Pooky (Europe) (En,Fr,De,It)" - rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It).gba" size 16777216 crc CE9291F1 md5 85CC314417D8F96798248507629EAA8B sha1 6A144FFCC55C9CB7C8B3E8A4AB49EFE45DD25C3E ) + rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It).gba" size 16777216 crc ce9291f1 sha1 6A144FFCC55C9CB7C8B3E8A4AB49EFE45DD25C3E flags verified ) +) + +game ( + name "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" + description "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It)" + rom ( name "Garfield - The Search for Pooky (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 76035741 sha1 7798A726A819E8A7DDCCD834AFD50D811796CFEE ) +) + +game ( + name "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2)" + description "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2)" + rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,Es,It) (Rev 2).gba" size 8388608 crc 0c3aa538 sha1 3E38901CECAD2C8AE3E5D91375AF6FA5D7734C19 flags verified ) +) + +game ( + name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1)" + description "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1)" + rom ( name "Garfield - The Search for Pooky (Europe) (En,Fr,De,It) (Rev 1).gba" size 8388608 crc 387eb638 sha1 5EAD81908F576E37837BAB60D5C580CA684A8FC5 flags verified ) ) game ( name "Garfield and His Nine Lives (USA) (En,Fr,Es)" description "Garfield and His Nine Lives (USA) (En,Fr,Es)" - rom ( name "Garfield and His Nine Lives (USA) (En,Fr,Es).gba" size 4194304 crc D442F13D md5 D8D8A330E5471FAEF5B527B18AA24AD2 sha1 6BEFCC1236770EC8ED833D49B5D8DBDF62BDA506 ) + rom ( name "Garfield and His Nine Lives (USA) (En,Fr,Es).gba" size 4194304 crc d442f13d sha1 6BEFCC1236770EC8ED833D49B5D8DBDF62BDA506 ) ) game ( name "Garfield and His Nine Lives (Europe) (En,Fr,De,Es,It,Nl)" description "Garfield and His Nine Lives (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Garfield and His Nine Lives (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc F0BA1A8E md5 5969F2B6F8F15AFEDCDB695FD3554133 sha1 4F24065F4FFC51D1A8C9317C6006F66E1E703FF1 ) + rom ( name "Garfield and His Nine Lives (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc f0ba1a8e sha1 4F24065F4FFC51D1A8C9317C6006F66E1E703FF1 ) ) game ( name "Gauntlet - Dark Legacy (USA)" description "Gauntlet - Dark Legacy (USA)" - rom ( name "Gauntlet - Dark Legacy (USA).gba" size 8388608 crc E99DE964 md5 2C6411D76D5438DA19F193B630DA1C63 sha1 3EA608F4EA2235886FA1D7256F6A9AE88C2C0E28 ) + rom ( name "Gauntlet - Dark Legacy (USA).gba" size 8388608 crc e99de964 sha1 3EA608F4EA2235886FA1D7256F6A9AE88C2C0E28 ) ) game ( name "GBA AV Adapter (China) (Unl)" description "GBA AV Adapter (China) (Unl)" - rom ( name "GBA AV Adapter (China) (Unl).gba" size 131072 crc A1B64F16 md5 3947E65E24C82D023B94878FBEBF3BCD sha1 A824210A15E0F4538268BCFE94B6E183303B2AD5 ) + rom ( name "GBA AV Adapter (China) (Unl).gba" size 131072 crc a1b64f16 sha1 A824210A15E0F4538268BCFE94B6E183303B2AD5 ) ) game ( name "GBA Movie Player 2 CF (Spain) (Unl)" description "GBA Movie Player 2 CF (Spain) (Unl)" - rom ( name "GBA Movie Player 2 CF (Spain) (Unl).gba" size 1048576 crc C879B340 md5 4A51388C1A4B44EAE693ED03210F6A13 sha1 55CF23D0B941B68FB89E35D5EE57A78D30B54827 ) + rom ( name "GBA Movie Player 2 CF (Spain) (Unl).gba" size 1048576 crc c879b340 sha1 55CF23D0B941B68FB89E35D5EE57A78D30B54827 ) ) game ( name "GBA Personal Organizer (USA) (Unl)" description "GBA Personal Organizer (USA) (Unl)" - rom ( name "GBA Personal Organizer (USA) (Unl).gba" size 1048576 crc 424F71E5 md5 621BE236403FD8E2FC15BF4C25985837 sha1 26E7A5435372C46628985CBA57F12A322B59537B ) + rom ( name "GBA Personal Organizer (USA) (Unl).gba" size 1048576 crc 424f71e5 sha1 26E7A5435372C46628985CBA57F12A322B59537B ) ) game ( name "GBA TV Tuner PAL (China) (v1.3) (Unl)" description "GBA TV Tuner PAL (China) (v1.3) (Unl)" - rom ( name "GBA TV Tuner PAL (China) (v1.3) (Unl).gba" size 1048576 crc AF124F8C md5 06EE51D1F0C2744999145E3E6ECFC745 sha1 E0899F4097054862D33C03E21E9D4A5EEF790402 ) + rom ( name "GBA TV Tuner PAL (China) (v1.3) (Unl).gba" size 1048576 crc af124f8c sha1 E0899F4097054862D33C03E21E9D4A5EEF790402 ) ) game ( name "GBA TV Tuner PAL (China) (v2.0) (Unl)" description "GBA TV Tuner PAL (China) (v2.0) (Unl)" - rom ( name "GBA TV Tuner PAL (China) (v2.0) (Unl).gba" size 8388608 crc B511DF64 md5 0F18E00838012BA8047B87976DD6A08F sha1 5A62463CBAAA0C4586E227AD6CA6A5D54485D955 ) + rom ( name "GBA TV Tuner PAL (China) (v2.0) (Unl).gba" size 8388608 crc b511df64 sha1 5A62463CBAAA0C4586E227AD6CA6A5D54485D955 ) ) game ( name "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan)" description "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan)" - rom ( name "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan).gba" size 16777216 crc 7F2B2657 md5 9FB5863A15E8504667328D24365B31E2 sha1 C32F197F4C6049D4553D7AE7AF94011694019626 ) -) - -game ( - name "Gekido Advance - Kintaro's Revenge (USA)" - description "Gekido Advance - Kintaro's Revenge (USA)" - rom ( name "Gekido Advance - Kintaro's Revenge (USA).gba" size 8388608 crc 6BBC5F4D md5 F58A7E485676F66C1C88126675D57EFF sha1 720FE1C2AE59A19235C2045D5915D0D0565E555D ) + rom ( name "Gegege no Kitarou - Kikiippatsu! Youkai Rettou (Japan).gba" size 16777216 crc 7f2b2657 sha1 C32F197F4C6049D4553D7AE7AF94011694019626 ) ) game ( name "Gekido Advance - Kintaro's Revenge (Europe) (En,Fr,De,Es,It)" description "Gekido Advance - Kintaro's Revenge (Europe) (En,Fr,De,Es,It)" - rom ( name "Gekido Advance - Kintaro's Revenge (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2FB5B819 md5 CDDE24E4B71AC0CB1CF32BAB1374F64A sha1 BA690C0857AC235A3E3A8342E2AEC41C6E48ED94 ) + rom ( name "Gekido Advance - Kintaro's Revenge (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2fb5b819 sha1 BA690C0857AC235A3E3A8342E2AEC41C6E48ED94 ) +) + +game ( + name "Gekido Advance - Kintaro's Revenge (USA)" + description "Gekido Advance - Kintaro's Revenge (USA)" + rom ( name "Gekido Advance - Kintaro's Revenge (USA).gba" size 8388608 crc 6bbc5f4d sha1 720FE1C2AE59A19235C2045D5915D0D0565E555D ) ) game ( name "Gekitou Densetsu Noah - Dream Management (Japan)" description "Gekitou Densetsu Noah - Dream Management (Japan)" - rom ( name "Gekitou Densetsu Noah - Dream Management (Japan).gba" size 8388608 crc 3E04FDC7 md5 7D43BA3C4D15EBB5F45E6100C096FDF8 sha1 87576A7D83BC49DBC533C18363E8F6D86019583F ) + rom ( name "Gekitou Densetsu Noah - Dream Management (Japan).gba" size 8388608 crc 3e04fdc7 sha1 87576A7D83BC49DBC533C18363E8F6D86019583F ) ) game ( name "Gekitou! Car Battler Go!! (Japan)" description "Gekitou! Car Battler Go!! (Japan)" - rom ( name "Gekitou! Car Battler Go!! (Japan).gba" size 8388608 crc 321B19B6 md5 386358B358D4A578D7CDC195529016EE sha1 CD3D70E6CF3C7DEC72D4F1F3678113D44A00FACC ) + rom ( name "Gekitou! Car Battler Go!! (Japan).gba" size 8388608 crc 321b19b6 sha1 CD3D70E6CF3C7DEC72D4F1F3678113D44A00FACC ) ) game ( name "Gem Smashers (USA)" description "Gem Smashers (USA)" - rom ( name "Gem Smashers (USA).gba" size 4194304 crc 2EB60177 md5 663CA15A48BBBC8303D52FA4664A012A sha1 953401A9BD75E8E589E9DA9A97E8035606D2D912 ) + rom ( name "Gem Smashers (USA).gba" size 4194304 crc 2eb60177 sha1 953401A9BD75E8E589E9DA9A97E8035606D2D912 ) ) game ( name "Genseishin Justirisers - Souchaku! Hoshi no Senshi-tachi (Japan)" description "Genseishin Justirisers - Souchaku! Hoshi no Senshi-tachi (Japan)" - rom ( name "Genseishin Justirisers - Souchaku! Hoshi no Senshi-tachi (Japan).gba" size 16777216 crc 580A00A5 md5 8905016D29E691975EBB176DEC1DCE4E sha1 54DE19108F2B8411FF2E52F7B5BF8E68BB19AE6D ) + rom ( name "Genseishin Justirisers - Souchaku! Hoshi no Senshi-tachi (Japan).gba" size 16777216 crc 580a00a5 sha1 54DE19108F2B8411FF2E52F7B5BF8E68BB19AE6D ) ) game ( name "Gensou Maden Saiyuuki - Hangyaku no Toushin-taishi (Japan)" description "Gensou Maden Saiyuuki - Hangyaku no Toushin-taishi (Japan)" - rom ( name "Gensou Maden Saiyuuki - Hangyaku no Toushin-taishi (Japan).gba" size 8388608 crc 1DFBD741 md5 9FD0815A6C2CA0D787952FFBC0A42DE1 sha1 10710BC9E66D9C92CCAF77D3343C270A0E3F0E35 ) + rom ( name "Gensou Maden Saiyuuki - Hangyaku no Toushin-taishi (Japan).gba" size 8388608 crc 1dfbd741 sha1 10710BC9E66D9C92CCAF77D3343C270A0E3F0E35 ) ) game ( name "Gensou Suikoden - Card Stories (Japan)" description "Gensou Suikoden - Card Stories (Japan)" - rom ( name "Gensou Suikoden - Card Stories (Japan).gba" size 4194304 crc 5E67AAB4 md5 0A3523DB5FE9A0329D766D9D1FF5E654 sha1 C01772CD0416DDCA38DCD1EF63E53A4EBDA90BBC ) + rom ( name "Gensou Suikoden - Card Stories (Japan).gba" size 4194304 crc 5e67aab4 sha1 C01772CD0416DDCA38DCD1EF63E53A4EBDA90BBC flags verified ) ) game ( name "Get Ride! Amdriver - Senkou no Hero Tanjou! (Japan)" description "Get Ride! Amdriver - Senkou no Hero Tanjou! (Japan)" - rom ( name "Get Ride! Amdriver - Senkou no Hero Tanjou! (Japan).gba" size 16777216 crc 9CF6887C md5 CE9396DD3407F86A9FB303E06882AEAB sha1 93BCA01E1399780361A5620A50F166A3636E1203 ) + rom ( name "Get Ride! Amdriver - Senkou no Hero Tanjou! (Japan).gba" size 16777216 crc 9cf6887c sha1 93BCA01E1399780361A5620A50F166A3636E1203 flags verified ) ) game ( name "Get Ride! Amdriver - Shutsugeki! Battle Party (Japan)" description "Get Ride! Amdriver - Shutsugeki! Battle Party (Japan)" - rom ( name "Get Ride! Amdriver - Shutsugeki! Battle Party (Japan).gba" size 16777216 crc 66D6E299 md5 C19873CEBB5F78D77D2AF67142C1C09E sha1 14245DD8FCCF96F527A443CDA8D848CFD2BEFF2D ) + rom ( name "Get Ride! Amdriver - Shutsugeki! Battle Party (Japan).gba" size 16777216 crc 66d6e299 sha1 14245DD8FCCF96F527A443CDA8D848CFD2BEFF2D ) ) game ( name "Get! - Boku no Mushi Tsukamaete (Japan)" description "Get! - Boku no Mushi Tsukamaete (Japan)" - rom ( name "Get! - Boku no Mushi Tsukamaete (Japan).gba" size 8388608 crc 41EA70A3 md5 5A35AD68AD0AED07D7865C94DCA2F61A sha1 0491BF0E9FE5B240C1DE93460C41BFEB63B2ED1B ) + rom ( name "Get! - Boku no Mushi Tsukamaete (Japan).gba" size 8388608 crc 41ea70a3 sha1 0491BF0E9FE5B240C1DE93460C41BFEB63B2ED1B ) ) game ( name "GetBackers Dakkanya - Jagan Fuuin! (Japan)" description "GetBackers Dakkanya - Jagan Fuuin! (Japan)" - rom ( name "GetBackers Dakkanya - Jagan Fuuin! (Japan).gba" size 16777216 crc 205C9F56 md5 937FA6B7DDD554370405F13B93632715 sha1 8C9E6900E537D8D1909B3E4B512F8FBD3FF92712 ) + rom ( name "GetBackers Dakkanya - Jagan Fuuin! (Japan).gba" size 16777216 crc 205c9f56 sha1 8C9E6900E537D8D1909B3E4B512F8FBD3FF92712 ) ) game ( name "GetBackers Dakkanya - Jigoku no Scaramouche (Japan)" description "GetBackers Dakkanya - Jigoku no Scaramouche (Japan)" - rom ( name "GetBackers Dakkanya - Jigoku no Scaramouche (Japan).gba" size 4194304 crc C0A0A979 md5 34ABC009C1C6FCC8588340C9BC04BD81 sha1 522C336DD10985A8E903EDF28C8153410C792CF6 ) + rom ( name "GetBackers Dakkanya - Jigoku no Scaramouche (Japan).gba" size 4194304 crc c0a0a979 sha1 522C336DD10985A8E903EDF28C8153410C792CF6 flags verified ) ) game ( name "GetBackers Dakkanya - Metropolis Dakkan Sakusen! (Japan)" description "GetBackers Dakkanya - Metropolis Dakkan Sakusen! (Japan)" - rom ( name "GetBackers Dakkanya - Metropolis Dakkan Sakusen! (Japan).gba" size 8388608 crc 91DAD468 md5 ED71F0DC43682B3DF88161EADAA4EE44 sha1 72DCE89B9529F8A0B17FD154C915875A0C02E2D9 ) + rom ( name "GetBackers Dakkanya - Metropolis Dakkan Sakusen! (Japan).gba" size 8388608 crc 91dad468 sha1 72DCE89B9529F8A0B17FD154C915875A0C02E2D9 flags verified ) ) game ( name "Ghost Rider (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Ghost Rider (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Ghost Rider (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc CF190F2E md5 D6E41A11CFD0FA428BC43A68B5AF7BCA sha1 E1E3940EB8216DFEC8A4F112CDB26050D9CF3FA9 flags verified ) + rom ( name "Ghost Rider (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc cf190f2e sha1 E1E3940EB8216DFEC8A4F112CDB26050D9CF3FA9 flags verified ) ) game ( name "Ghost Trap (Japan)" description "Ghost Trap (Japan)" - rom ( name "Ghost Trap (Japan).gba" size 8388608 crc 81EA54E2 md5 8D9BF4766BCC96C79DBAB427FC75A2A6 sha1 00EFB5ED50127F91E2A2827926CF2D4491E4B1B3 ) + rom ( name "Ghost Trap (Japan).gba" size 8388608 crc 81ea54e2 sha1 00EFB5ED50127F91E2A2827926CF2D4491E4B1B3 flags verified ) ) game ( name "Global Star - Sudoku Fever (USA)" description "Global Star - Sudoku Fever (USA)" - rom ( name "Global Star - Sudoku Fever (USA).gba" size 4194304 crc 51A42F19 md5 836D614BE32CD350DE5E05A175DB6DA7 sha1 02BBF5ADAD90B431DA981785DBE10B273599153E ) + rom ( name "Global Star - Sudoku Fever (USA).gba" size 4194304 crc 51a42f19 sha1 02BBF5ADAD90B431DA981785DBE10B273599153E ) ) game ( name "Global Star - Sudoku Fever (Europe) (En,Fr,De,Es,It)" description "Global Star - Sudoku Fever (Europe) (En,Fr,De,Es,It)" - rom ( name "Global Star - Sudoku Fever (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 383CF600 md5 926BEBF30F7FECD6B9FA30CFD353DFEE sha1 8A6AB9E999CB9618BF169F70A9423ABDC0DE6A92 flags verified ) -) - -game ( - name "Glory Days (Europe) (En,Fr,De,Es,It)" - description "Glory Days (Europe) (En,Fr,De,Es,It)" - rom ( name "Glory Days (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 84ADB2C3 md5 ED6F287DFE987B596952671E75B7F688 sha1 D7E72D3EDFAB366962741A8959985439CBB8541B flags verified ) + rom ( name "Global Star - Sudoku Fever (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 383cf600 sha1 8A6AB9E999CB9618BF169F70A9423ABDC0DE6A92 flags verified ) ) game ( name "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It)" description "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It)" - rom ( name "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc DFF3E861 md5 B1E538380C4C0595AC47EE8059F5A614 sha1 63300C8CBB3B3622E6B5F7FEF7E552C24AEE9C86 flags verified ) + rom ( name "Go! Go! Beckham! - Adventure on Soccer Island (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc dff3e861 sha1 63300C8CBB3B3622E6B5F7FEF7E552C24AEE9C86 flags verified ) ) game ( name "Godzilla - Domination! (Europe) (En,Fr,De,Es,It)" description "Godzilla - Domination! (Europe) (En,Fr,De,Es,It)" - rom ( name "Godzilla - Domination! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7C43545E md5 047DFFED50E17E1EAAB78D69409B19BD sha1 D59D40D7DB5605F836650BFAF7069CEF7689D2C1 flags verified ) + rom ( name "Godzilla - Domination! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7c43545e sha1 D59D40D7DB5605F836650BFAF7069CEF7689D2C1 flags verified ) ) game ( name "Godzilla - Domination! (USA)" description "Godzilla - Domination! (USA)" - rom ( name "Godzilla - Domination! (USA).gba" size 4194304 crc EADE083F md5 FB0B9D0DB44EC7DE4A534C2849F8B756 sha1 DFCFC6D1AD2BC629429D9EBAAE0E9452EFA8D0D6 flags verified ) + rom ( name "Godzilla - Domination! (USA).gba" size 4194304 crc eade083f sha1 DFCFC6D1AD2BC629429D9EBAAE0E9452EFA8D0D6 flags verified ) ) game ( name "Goemon - New Age Shutsudou! (Japan)" description "Goemon - New Age Shutsudou! (Japan)" - rom ( name "Goemon - New Age Shutsudou! (Japan).gba" size 4194304 crc 86D6C574 md5 842F50E8321D16D33566839D76635448 sha1 10EEC7513511F0B891F32E44EFF383A3A090F787 flags verified ) + rom ( name "Goemon - New Age Shutsudou! (Japan).gba" size 4194304 crc 86d6c574 sha1 10EEC7513511F0B891F32E44EFF383A3A090F787 flags verified ) ) game ( name "Gojira - Kaijuu Dairantou Advance (Japan)" description "Gojira - Kaijuu Dairantou Advance (Japan)" - rom ( name "Gojira - Kaijuu Dairantou Advance (Japan).gba" size 4194304 crc 3157A4FC md5 F05F356FACB38A1C330FA3D80FF3BD28 sha1 985599E9F65D58D67170CA9AD3EB406C6ED25217 ) + rom ( name "Gojira - Kaijuu Dairantou Advance (Japan).gba" size 4194304 crc 3157a4fc sha1 985599E9F65D58D67170CA9AD3EB406C6ED25217 ) ) game ( name "Golden Nugget Casino (USA, Europe)" description "Golden Nugget Casino (USA, Europe)" - rom ( name "Golden Nugget Casino (USA, Europe).gba" size 4194304 crc 56B9E9E1 md5 4DF2176D0F881B309B9077D18A422F00 sha1 5ECF4EAD4B22A5916086A34BBF2ABF299AAF3401 flags verified ) + rom ( name "Golden Nugget Casino (USA, Europe).gba" size 4194304 crc 56b9e9e1 sha1 5ECF4EAD4B22A5916086A34BBF2ABF299AAF3401 flags verified ) ) game ( name "Golden Sun (USA, Europe)" description "Golden Sun (USA, Europe)" - rom ( name "Golden Sun (USA, Europe).gba" size 8388608 crc E1FB68E8 md5 1CDD7F33C9A27061201E1D1CE029A700 sha1 5C4695205413DF7DB52B9A184815A07783999971 flags verified ) + rom ( name "Golden Sun (USA, Europe).gba" size 8388608 crc e1fb68e8 sha1 5C4695205413DF7DB52B9A184815A07783999971 flags verified ) ) game ( name "Golden Sun (France)" description "Golden Sun (France)" - rom ( name "Golden Sun (France).gba" size 8388608 crc F6521161 md5 6540572AB503358A399861C909EE2012 sha1 42F3B262C16CFC5BDE1FA2B25016FB74046DE1B3 ) + rom ( name "Golden Sun (France).gba" size 8388608 crc f6521161 sha1 42F3B262C16CFC5BDE1FA2B25016FB74046DE1B3 ) ) game ( name "Golden Sun (Germany)" description "Golden Sun (Germany)" - rom ( name "Golden Sun (Germany).gba" size 8388608 crc 1053DCE4 md5 DA69E10FEB7472CDFA7ED76F8183B6BD sha1 C23AB91A39434623CF1A999F387D743ADE1A22A6 flags verified ) + rom ( name "Golden Sun (Germany).gba" size 8388608 crc 1053dce4 sha1 C23AB91A39434623CF1A999F387D743ADE1A22A6 flags verified ) ) game ( name "Golden Sun (Spain)" description "Golden Sun (Spain)" - rom ( name "Golden Sun (Spain).gba" size 8388608 crc C63008D6 md5 53D97150443E4449DC1959DA641D1A8E sha1 DE0BDC889594B012CAD213CA83707FEB81ADA28B flags verified ) + rom ( name "Golden Sun (Spain).gba" size 8388608 crc c63008d6 sha1 DE0BDC889594B012CAD213CA83707FEB81ADA28B flags verified ) ) game ( name "Golden Sun (Italy)" description "Golden Sun (Italy)" - rom ( name "Golden Sun (Italy).gba" size 8388608 crc F3128812 md5 3210F30E13B7BF65D4E5AB42235AD663 sha1 CA45E04B26B2F040AC63E679A459D21869F5F28D ) + rom ( name "Golden Sun (Italy).gba" size 8388608 crc f3128812 sha1 CA45E04B26B2F040AC63E679A459D21869F5F28D ) ) game ( name "Golden Sun - Die Vergessene Epoche (Germany)" description "Golden Sun - Die Vergessene Epoche (Germany)" - rom ( name "Golden Sun - Die Vergessene Epoche (Germany).gba" size 16777216 crc D981D889 md5 8B0FE9B5156781D1686B0ADD2A31B9B3 sha1 7820B4C7BA9002B0E9BE23A6F45A9AB204986438 flags verified ) + rom ( name "Golden Sun - Die Vergessene Epoche (Germany).gba" size 16777216 crc d981d889 sha1 7820B4C7BA9002B0E9BE23A6F45A9AB204986438 flags verified ) ) game ( name "Golden Sun - L'Age Perdu (France)" description "Golden Sun - L'Age Perdu (France)" - rom ( name "Golden Sun - L'Age Perdu (France).gba" size 16777216 crc 1090BD33 md5 9B067D0EE54CAAD2171A00C50E3C35CD sha1 F14855C0F8C87A95CC52189E8E3B2BD9DF186322 ) + rom ( name "Golden Sun - L'Age Perdu (France).gba" size 16777216 crc 1090bd33 sha1 F14855C0F8C87A95CC52189E8E3B2BD9DF186322 ) ) game ( name "Golden Sun - L'Era Perduta (Italy)" description "Golden Sun - L'Era Perduta (Italy)" - rom ( name "Golden Sun - L'Era Perduta (Italy).gba" size 16777216 crc A3E49743 md5 A1BE57CB0F1ACC812F46657BBFE5904B sha1 57F1D005666B81645E55412658427E27099C5907 ) + rom ( name "Golden Sun - L'Era Perduta (Italy).gba" size 16777216 crc a3e49743 sha1 57F1D005666B81645E55412658427E27099C5907 ) ) game ( name "Golden Sun - La Edad Perdida (Spain)" description "Golden Sun - La Edad Perdida (Spain)" - rom ( name "Golden Sun - La Edad Perdida (Spain).gba" size 16777216 crc EE38BA94 md5 370CC3B832F905A2B5511C1665E4A8BC sha1 A2E3E80036195343C2713410AC14F4E329E3F40D ) + rom ( name "Golden Sun - La Edad Perdida (Spain).gba" size 16777216 crc ee38ba94 sha1 A2E3E80036195343C2713410AC14F4E329E3F40D ) ) game ( name "Golden Sun - The Lost Age (USA, Europe)" description "Golden Sun - The Lost Age (USA, Europe)" - rom ( name "Golden Sun - The Lost Age (USA, Europe).gba" size 16777216 crc 606A1C4D md5 8EFE8B2AAED97149E897570CD123FF6E sha1 B500663220CB9BF56B9F8E8C0C544F1D6FA3A824 flags verified ) + rom ( name "Golden Sun - The Lost Age (USA, Europe).gba" size 16777216 crc 606a1c4d sha1 B500663220CB9BF56B9F8E8C0C544F1D6FA3A824 flags verified ) +) + +game ( + name "Golden Sun - The Lost Age (USA, Europe) (Wii U Virtual Console)" + description "Golden Sun - The Lost Age (USA, Europe) (Wii U Virtual Console)" + rom ( name "Golden Sun - The Lost Age (USA, Europe) (Wii U Virtual Console).gba" size 16777216 crc 726bb764 sha1 3C15317369ECAFCD3C018D13C297D9107790F14F flags verified ) ) game ( name "GP-1 Racing (USA) (Proto)" description "GP-1 Racing (USA) (Proto)" - rom ( name "GP-1 Racing (USA) (Proto).gba" size 2097152 crc 4851B490 md5 BB03FAF625C3FCFD8278513CE46448B4 sha1 730553F472C641DEF1762C082CF4B6F23B13AEAB ) + rom ( name "GP-1 Racing (USA) (Proto).gba" size 2097152 crc 4851b490 sha1 730553F472C641DEF1762C082CF4B6F23B13AEAB ) ) game ( name "Gradius Advance (Europe)" description "Gradius Advance (Europe)" - rom ( name "Gradius Advance (Europe).gba" size 4194304 crc 3722BDFA md5 1227EEBFF87A8B9D5E713E20CDDCB468 sha1 1F28DB5AC70AE11B2F3414369D1BE73ACCB36F3B flags verified ) + rom ( name "Gradius Advance (Europe).gba" size 4194304 crc 3722bdfa sha1 1F28DB5AC70AE11B2F3414369D1BE73ACCB36F3B flags verified ) ) game ( name "Gradius Galaxies (USA)" description "Gradius Galaxies (USA)" - rom ( name "Gradius Galaxies (USA).gba" size 4194304 crc 8103428D md5 6F16195283A6F16FC73C95C69F131B68 sha1 DC0F3C4B71C7F543D1693D2A0C356F10F39D16D9 ) + rom ( name "Gradius Galaxies (USA).gba" size 4194304 crc 8103428d sha1 DC0F3C4B71C7F543D1693D2A0C356F10F39D16D9 flags verified ) ) game ( name "Gradius Generation (Japan)" description "Gradius Generation (Japan)" - rom ( name "Gradius Generation (Japan).gba" size 4194304 crc 6C20EA42 md5 97FA8D3DEC6CAD0B75EA8063992BE6A6 sha1 B1DB63DD449153B82B16ABCADF1EEB7C7A100DBB ) + rom ( name "Gradius Generation (Japan).gba" size 4194304 crc 6c20ea42 sha1 B1DB63DD449153B82B16ABCADF1EEB7C7A100DBB ) ) game ( name "Grand Theft Auto Advance (USA)" description "Grand Theft Auto Advance (USA)" - rom ( name "Grand Theft Auto Advance (USA).gba" size 16777216 crc 1FA131E8 md5 2C8EF9CCE9F46B55247468EA449AEADE sha1 742FC0062AD930253FFEA449953061381577649E ) + rom ( name "Grand Theft Auto Advance (USA).gba" size 16777216 crc 1fa131e8 sha1 742FC0062AD930253FFEA449953061381577649E ) ) game ( name "Grand Theft Auto Advance (Europe) (En,Fr,De,Es,It)" description "Grand Theft Auto Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Grand Theft Auto Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4189E07F md5 B4D933095F1BE113F2B64F61E21B4055 sha1 06230842626DA504F92396074F7C655E100F5D44 flags verified ) + rom ( name "Grand Theft Auto Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4189e07f sha1 06230842626DA504F92396074F7C655E100F5D44 flags verified ) ) game ( name "Greatest Nine (Japan)" description "Greatest Nine (Japan)" - rom ( name "Greatest Nine (Japan).gba" size 8388608 crc 379E64D7 md5 83C4994B6EDB5ACE03864F96DDEB54AF sha1 3DCAE687A828663429B424CD54AA5A776CDDABE5 ) + rom ( name "Greatest Nine (Japan).gba" size 8388608 crc 379e64d7 sha1 3DCAE687A828663429B424CD54AA5A776CDDABE5 ) ) game ( name "Green Eggs and Ham by Dr. Seuss (USA)" description "Green Eggs and Ham by Dr. Seuss (USA)" - rom ( name "Green Eggs and Ham by Dr. Seuss (USA).gba" size 4194304 crc E4AE2CD1 md5 EBC7077768E9FC856480A80CB6BE5B2C sha1 BE062FA28DB26EC37EC96E5A7E6DC77CF4AD6907 ) + rom ( name "Green Eggs and Ham by Dr. Seuss (USA).gba" size 4194304 crc e4ae2cd1 sha1 BE062FA28DB26EC37EC96E5A7E6DC77CF4AD6907 ) ) game ( name "Greg Hastings' Tournament Paintball Max'd (USA)" description "Greg Hastings' Tournament Paintball Max'd (USA)" - rom ( name "Greg Hastings' Tournament Paintball Max'd (USA).gba" size 16777216 crc 649F7BB2 md5 86DCA228AFC2D455E958C4E52787D91E sha1 7F80CB2A3FA2C7FE2A7A1F9A7532EEC7F72A682D ) -) - -game ( - name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta)" - description "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta)" - rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta).gba" size 4194304 crc 68AE6BBB md5 4E822C3E31350A457DA3B640BC05E3AD sha1 6AA43D0624AF03214473F329FDA6334DC9C63009 ) -) - -game ( - name "Gremlins - Stripe vs Gizmo (USA)" - description "Gremlins - Stripe vs Gizmo (USA)" - rom ( name "Gremlins - Stripe vs Gizmo (USA).gba" size 4194304 crc 5E72899A md5 E1303FCCC44BDB8524E904F6B15B9856 sha1 EE32E704598D2B6A21B3DB271F9CF94578B94744 ) + rom ( name "Greg Hastings' Tournament Paintball Max'd (USA).gba" size 16777216 crc 649f7bb2 sha1 7F80CB2A3FA2C7FE2A7A1F9A7532EEC7F72A682D ) ) game ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" description "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc B6225186 md5 66C238EA31904C09E2EE06BC465A8342 sha1 A2C4BF97785E717EF45E4B73A6C66A2D4AE18192 ) + rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc b6225186 sha1 A2C4BF97785E717EF45E4B73A6C66A2D4AE18192 ) +) + +game ( + name "Gremlins - Stripe vs Gizmo (USA)" + description "Gremlins - Stripe vs Gizmo (USA)" + rom ( name "Gremlins - Stripe vs Gizmo (USA).gba" size 4194304 crc 5e72899a sha1 EE32E704598D2B6A21B3DB271F9CF94578B94744 ) +) + +game ( + name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta)" + description "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta)" + rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta).gba" size 4194304 crc 68ae6bbb sha1 6AA43D0624AF03214473F329FDA6334DC9C63009 ) ) game ( name "Grim Adventures of Billy & Mandy, The (USA)" description "Grim Adventures of Billy & Mandy, The (USA)" - rom ( name "Grim Adventures of Billy & Mandy, The (USA).gba" size 8388608 crc 155587BC md5 15E493A90D9B8CC7935F01ABD57393B2 sha1 6C4A94968E518CDE693CEC4CC91B9EAAE4406187 ) + rom ( name "Grim Adventures of Billy & Mandy, The (USA).gba" size 8388608 crc 155587bc sha1 6C4A94968E518CDE693CEC4CC91B9EAAE4406187 ) ) game ( name "Groove Adventure Rave - Hikari to Yami no Daikessen (Japan)" description "Groove Adventure Rave - Hikari to Yami no Daikessen (Japan)" - rom ( name "Groove Adventure Rave - Hikari to Yami no Daikessen (Japan).gba" size 8388608 crc E7421B14 md5 45101202229F4F91AC1F8EAD62FCBD8C sha1 37BA9EC59AF08F4F04945C928FF09A624B28275A ) + rom ( name "Groove Adventure Rave - Hikari to Yami no Daikessen (Japan).gba" size 8388608 crc e7421b14 sha1 37BA9EC59AF08F4F04945C928FF09A624B28275A flags verified ) ) game ( name "Groove Adventure Rave - Hikari to Yami no Daikessen 2 (Japan)" description "Groove Adventure Rave - Hikari to Yami no Daikessen 2 (Japan)" - rom ( name "Groove Adventure Rave - Hikari to Yami no Daikessen 2 (Japan).gba" size 8388608 crc 006F9150 md5 A06AD4812EDB8D042602FCDE222F7AB7 sha1 F5003E103A648BAB8271324BBD47DC0B4898E1FB ) + rom ( name "Groove Adventure Rave - Hikari to Yami no Daikessen 2 (Japan).gba" size 8388608 crc 006f9150 sha1 F5003E103A648BAB8271324BBD47DC0B4898E1FB ) ) game ( name "GT Advance - Championship Racing (USA, Europe)" description "GT Advance - Championship Racing (USA, Europe)" - rom ( name "GT Advance - Championship Racing (USA, Europe).gba" size 8388608 crc 8C411ACC md5 1CE4441B3142B480E03CFFE290B00CE6 sha1 3A85E462D002FF5577E4434110B17459FE6867D6 flags verified ) + rom ( name "GT Advance - Championship Racing (USA, Europe).gba" size 8388608 crc 8c411acc sha1 3A85E462D002FF5577E4434110B17459FE6867D6 flags verified ) ) game ( name "GT Advance 2 - Rally Racing (USA)" description "GT Advance 2 - Rally Racing (USA)" - rom ( name "GT Advance 2 - Rally Racing (USA).gba" size 8388608 crc F335DB88 md5 C0B296EFEA186B82F921CF0E9A6A6EF4 sha1 7A7C2A76BC5C7995B5186D90C5FDD7BC303F0E85 flags verified ) + rom ( name "GT Advance 2 - Rally Racing (USA).gba" size 8388608 crc f335db88 sha1 7A7C2A76BC5C7995B5186D90C5FDD7BC303F0E85 flags verified ) ) game ( name "GT Advance 2 - Rally Racing (Europe)" description "GT Advance 2 - Rally Racing (Europe)" - rom ( name "GT Advance 2 - Rally Racing (Europe).gba" size 8388608 crc 73411578 md5 93C6A92B841B2F3CAD5CDC4E62112E61 sha1 8185C05C709B2E1CEADEDD905F7F38107DECBDCD ) + rom ( name "GT Advance 2 - Rally Racing (Europe).gba" size 8388608 crc 73411578 sha1 8185C05C709B2E1CEADEDD905F7F38107DECBDCD ) ) game ( name "GT Advance 3 - Pro Concept Racing (USA)" description "GT Advance 3 - Pro Concept Racing (USA)" - rom ( name "GT Advance 3 - Pro Concept Racing (USA).gba" size 8388608 crc 0A331E11 md5 C283484D8F35B059BBFF9E4D852C5420 sha1 F1B9DD89D0E1151B47545EAB381FB44C8F4DCCA5 ) + rom ( name "GT Advance 3 - Pro Concept Racing (USA).gba" size 8388608 crc 0a331e11 sha1 F1B9DD89D0E1151B47545EAB381FB44C8F4DCCA5 ) ) game ( name "GT Advance 3 - Pro Concept Racing (Europe)" description "GT Advance 3 - Pro Concept Racing (Europe)" - rom ( name "GT Advance 3 - Pro Concept Racing (Europe).gba" size 8388608 crc 03898E7F md5 DF7B1D5FB2F71445497FEABF7BABB8EF sha1 1E81D7AD7A9D8C179EF9F1A2E334A155799FE788 ) + rom ( name "GT Advance 3 - Pro Concept Racing (Europe).gba" size 8388608 crc 03898e7f sha1 1E81D7AD7A9D8C179EF9F1A2E334A155799FE788 ) ) game ( name "GT Championship (Europe)" description "GT Championship (Europe)" - rom ( name "GT Championship (Europe).gba" size 4194304 crc E92EC7AA md5 09306558743C945883527D6C75FAEDA8 sha1 B49953EE8C7296205CBB5AC60DA298C9D7B3C4A2 ) + rom ( name "GT Championship (Europe).gba" size 4194304 crc e92ec7aa sha1 B49953EE8C7296205CBB5AC60DA298C9D7B3C4A2 ) ) game ( name "GT Racers (Europe) (En,Fr,De,Es,It)" description "GT Racers (Europe) (En,Fr,De,Es,It)" - rom ( name "GT Racers (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 362D9F86 md5 7BCA0C64ABE211175E7655C3F374627B sha1 B36D6AA4B88AD0FD5604BEB7D5F6FA29B9F91B31 ) + rom ( name "GT Racers (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 362d9f86 sha1 B36D6AA4B88AD0FD5604BEB7D5F6FA29B9F91B31 ) ) game ( name "GT Racers (Europe) (Beta) (2005-07-13)" description "GT Racers (Europe) (Beta) (2005-07-13)" - rom ( name "GT Racers (Europe) (Beta) (2005-07-13).gba" size 362512 crc E027657A md5 8EF186D8565C1408E653BFE5341A5FFB sha1 79E5600C34424BCEB6458CE579B8485D5F478578 ) + rom ( name "GT Racers (Europe) (Beta) (2005-07-13).gba" size 362512 crc e027657a sha1 79E5600C34424BCEB6458CE579B8485D5F478578 ) ) game ( name "GT Racers (Europe) (Beta) (2005-10-14)" description "GT Racers (Europe) (Beta) (2005-10-14)" - rom ( name "GT Racers (Europe) (Beta) (2005-10-14).gba" size 2619992 crc A0F745A0 md5 CCAA6814BCB83EC7FFF309616A2F6D40 sha1 FB10FDEB8C853CC13FDEC789B710E3B0847E8680 ) -) - -game ( - name "Guilty Gear X - Advance Edition (Japan) (Beta)" - description "Guilty Gear X - Advance Edition (Japan) (Beta)" - rom ( name "Guilty Gear X - Advance Edition (Japan) (Beta).gba" size 8388608 crc 4506ADA8 md5 AEA3115B6CE9A25AA574C9754F4FEDFB sha1 85915ECF10CE73AFE9FFFBBC8CD7A449DFE802C4 ) + rom ( name "GT Racers (Europe) (Beta) (2005-10-14).gba" size 2619992 crc a0f745a0 sha1 FB10FDEB8C853CC13FDEC789B710E3B0847E8680 ) ) game ( name "Guilty Gear X - Advance Edition (Japan)" description "Guilty Gear X - Advance Edition (Japan)" - rom ( name "Guilty Gear X - Advance Edition (Japan).gba" size 8388608 crc 160903EE md5 58D312653A7291637FA09D541544DE88 sha1 0801B7E39462527D5B650E57FCCE908711258A0C ) + rom ( name "Guilty Gear X - Advance Edition (Japan).gba" size 8388608 crc 160903ee sha1 0801B7E39462527D5B650E57FCCE908711258A0C ) ) game ( name "Guilty Gear X - Advance Edition (Europe)" description "Guilty Gear X - Advance Edition (Europe)" - rom ( name "Guilty Gear X - Advance Edition (Europe).gba" size 8388608 crc BA95861D md5 9145DED7C7FB57275B6BD23AC1E93FD5 sha1 8236A650A18DFEDC22DA7C00B5AFFD3E752EC5DE ) + rom ( name "Guilty Gear X - Advance Edition (Europe).gba" size 8388608 crc ba95861d sha1 8236A650A18DFEDC22DA7C00B5AFFD3E752EC5DE ) ) game ( name "Guilty Gear X - Advance Edition (USA)" description "Guilty Gear X - Advance Edition (USA)" - rom ( name "Guilty Gear X - Advance Edition (USA).gba" size 8388608 crc 70DB3F96 md5 509139BB43B0FA487056E6068C46AB70 sha1 BB064410C57324B25DE96D297338CC5E73262FE6 ) + rom ( name "Guilty Gear X - Advance Edition (USA).gba" size 8388608 crc 70db3f96 sha1 BB064410C57324B25DE96D297338CC5E73262FE6 ) +) + +game ( + name "Guilty Gear X - Advance Edition (Japan) (Beta)" + description "Guilty Gear X - Advance Edition (Japan) (Beta)" + rom ( name "Guilty Gear X - Advance Edition (Japan) (Beta).gba" size 8388608 crc 4506ada8 sha1 85915ECF10CE73AFE9FFFBBC8CD7A449DFE802C4 ) ) game ( name "Gumby vs. the Astrobots (USA)" description "Gumby vs. the Astrobots (USA)" - rom ( name "Gumby vs. the Astrobots (USA).gba" size 4194304 crc 2B7E3CCB md5 81528AA0F4ABABA9D4A6E1C71F6BE3F5 sha1 52A9F74901ED13F6641B6BA0335A2F9EA031063B ) + rom ( name "Gumby vs. the Astrobots (USA).gba" size 4194304 crc 2b7e3ccb sha1 52A9F74901ED13F6641B6BA0335A2F9EA031063B ) ) game ( name "Gunstar Future Heroes (Europe) (En,Ja,Fr,De,Es,It)" description "Gunstar Future Heroes (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Gunstar Future Heroes (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 8C541D13 md5 5A3DB0C384D089BDA397E395DF4270F8 sha1 F30AB501B09026AE045FAF8573220D4F9C113376 flags verified ) + rom ( name "Gunstar Future Heroes (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 8c541d13 sha1 F30AB501B09026AE045FAF8573220D4F9C113376 flags verified ) ) game ( name "Gunstar Super Heroes (Japan)" description "Gunstar Super Heroes (Japan)" - rom ( name "Gunstar Super Heroes (Japan).gba" size 8388608 crc 6D4307F7 md5 ED09ECF8C9D1AE485CF3C12CF2184756 sha1 6894ED29AF5A1603C72E3B55047A5C9F5D5DDB6B ) + rom ( name "Gunstar Super Heroes (Japan).gba" size 8388608 crc 6d4307f7 sha1 6894ED29AF5A1603C72E3B55047A5C9F5D5DDB6B ) ) game ( name "Gunstar Super Heroes (USA)" description "Gunstar Super Heroes (USA)" - rom ( name "Gunstar Super Heroes (USA).gba" size 8388608 crc 7CD86B02 md5 A5B75829DEBC9262B08076A94C8473EB sha1 5F3CE44716754BF0423AEDDE7CB1693CEA328A0D ) + rom ( name "Gunstar Super Heroes (USA).gba" size 8388608 crc 7cd86b02 sha1 5F3CE44716754BF0423AEDDE7CB1693CEA328A0D flags verified ) ) game ( name "Guranbo (Japan)" description "Guranbo (Japan)" - rom ( name "Guranbo (Japan).gba" size 8388608 crc CDD2E273 md5 752CA5B3A76784E3261CB60AF80A84E7 sha1 8CC23CB007FB24583034FCCF5F37F46D99F85747 ) + rom ( name "Guranbo (Japan).gba" size 8388608 crc cdd2e273 sha1 8CC23CB007FB24583034FCCF5F37F46D99F85747 flags verified ) ) game ( name "Guru Logic Champ (Japan)" description "Guru Logic Champ (Japan)" - rom ( name "Guru Logic Champ (Japan).gba" size 4194304 crc 30D04AD9 md5 3A7DE010D9D7BB209FE8C8670ED97FEC sha1 77588B6E802DE57D1D826C4D43E4C3B0E3AEBDAE ) + rom ( name "Guru Logic Champ (Japan).gba" size 4194304 crc 30d04ad9 sha1 77588B6E802DE57D1D826C4D43E4C3B0E3AEBDAE ) ) game ( name "Gyakuten Saiban (Japan)" description "Gyakuten Saiban (Japan)" - rom ( name "Gyakuten Saiban (Japan).gba" size 8388608 crc C88F0952 md5 A476526ADC63D7E287D905EB7251D120 sha1 15C0E3389709BB275C42E99ED25212D09E49E361 ) + rom ( name "Gyakuten Saiban (Japan).gba" size 8388608 crc c88f0952 sha1 15C0E3389709BB275C42E99ED25212D09E49E361 ) ) game ( name "Gyakuten Saiban (Japan) (Rev 1)" description "Gyakuten Saiban (Japan) (Rev 1)" - rom ( name "Gyakuten Saiban (Japan) (Rev 1).gba" size 8388608 crc A0F4801F md5 C5780D2CD4873E19434E54595722ED5D sha1 EA7DABC4F5330C89A341CA38067FB025DE73C835 ) + rom ( name "Gyakuten Saiban (Japan) (Rev 1).gba" size 8388608 crc a0f4801f sha1 EA7DABC4F5330C89A341CA38067FB025DE73C835 ) ) game ( name "Gyakuten Saiban 2 (Japan)" description "Gyakuten Saiban 2 (Japan)" - rom ( name "Gyakuten Saiban 2 (Japan).gba" size 8388608 crc 191AD26A md5 41AE841D5771E442F7FB5393906CB898 sha1 F7A156DBED52D3EDB8104112AE40E6E2AACA57F9 ) + rom ( name "Gyakuten Saiban 2 (Japan).gba" size 8388608 crc 191ad26a sha1 F7A156DBED52D3EDB8104112AE40E6E2AACA57F9 ) ) game ( name "Gyakuten Saiban 3 (Japan)" description "Gyakuten Saiban 3 (Japan)" - rom ( name "Gyakuten Saiban 3 (Japan).gba" size 8388608 crc 51B6CF22 md5 3BB63215DC9DC1ED394C9A4E2CD632DD sha1 70944B396DA3F9CE039CC96BC1661826C37B0AA2 ) + rom ( name "Gyakuten Saiban 3 (Japan).gba" size 8388608 crc 51b6cf22 sha1 70944B396DA3F9CE039CC96BC1661826C37B0AA2 flags verified ) ) game ( name "Hachiemon (Japan)" description "Hachiemon (Japan)" - rom ( name "Hachiemon (Japan).gba" size 4194304 crc 47C45B41 md5 6C8460B00A7DCADE834B0579116771DB sha1 10C16950388599846C2A61CACC315BA81A752DEB ) + rom ( name "Hachiemon (Japan).gba" size 4194304 crc 47c45b41 sha1 10C16950388599846C2A61CACC315BA81A752DEB ) ) game ( name "Hagane no Renkinjutsushi - Meisou no Rondo (Japan)" description "Hagane no Renkinjutsushi - Meisou no Rondo (Japan)" - rom ( name "Hagane no Renkinjutsushi - Meisou no Rondo (Japan).gba" size 8388608 crc A8CDA373 md5 11A1C991749EDEDFCE2CEF42E1019CC7 sha1 863E778FA08B3181440948241470EA37552D7820 ) + rom ( name "Hagane no Renkinjutsushi - Meisou no Rondo (Japan).gba" size 8388608 crc a8cda373 sha1 863E778FA08B3181440948241470EA37552D7820 ) ) game ( name "Hagane no Renkinjutsushi - Omoide no Sonata (Japan)" description "Hagane no Renkinjutsushi - Omoide no Sonata (Japan)" - rom ( name "Hagane no Renkinjutsushi - Omoide no Sonata (Japan).gba" size 8388608 crc C6144316 md5 EF9C063AB316CA610DD5A6C5C35FCA7F sha1 585B84B1A9A169FDB3ED30F9AD07D512A6A636DE ) + rom ( name "Hagane no Renkinjutsushi - Omoide no Sonata (Japan).gba" size 8388608 crc c6144316 sha1 585B84B1A9A169FDB3ED30F9AD07D512A6A636DE flags verified ) ) game ( name "Hajime no Ippo - The Fighting! (Japan)" description "Hajime no Ippo - The Fighting! (Japan)" - rom ( name "Hajime no Ippo - The Fighting! (Japan).gba" size 8388608 crc 782DC7EB md5 07C67CAEE98287F303193D837EBDB702 sha1 4B39DDE92AA2E26433A9F0C90CA6235A508BA87C ) + rom ( name "Hajime no Ippo - The Fighting! (Japan).gba" size 8388608 crc 782dc7eb sha1 4B39DDE92AA2E26433A9F0C90CA6235A508BA87C flags verified ) ) game ( name "Hamepane - Tokyo Mew Mew (Japan)" description "Hamepane - Tokyo Mew Mew (Japan)" - rom ( name "Hamepane - Tokyo Mew Mew (Japan).gba" size 4194304 crc 5875C07A md5 C45CDE25DC1427DF5896AE5ED8959FA0 sha1 0292873F7DF7ACE64B5949CFED917B36F7D86FFA ) + rom ( name "Hamepane - Tokyo Mew Mew (Japan).gba" size 4194304 crc 5875c07a sha1 0292873F7DF7ACE64B5949CFED917B36F7D86FFA ) ) game ( name "Hamster Club 3 (Japan)" description "Hamster Club 3 (Japan)" - rom ( name "Hamster Club 3 (Japan).gba" size 8388608 crc 8173F699 md5 DB526B444655E12BA12030EBD9959F3B sha1 5365EAC146114683B614D22CC9C891E998A94F40 ) + rom ( name "Hamster Club 3 (Japan).gba" size 8388608 crc 8173f699 sha1 5365EAC146114683B614D22CC9C891E998A94F40 ) ) game ( name "Hamster Club 4 - Shigetchi Daidassou (Japan)" description "Hamster Club 4 - Shigetchi Daidassou (Japan)" - rom ( name "Hamster Club 4 - Shigetchi Daidassou (Japan).gba" size 8388608 crc 69CF5AFB md5 2219CAC76173A4069C011968AB9E44DF sha1 0667122CF1A8DB827AFA221A11A364241DA1DC55 ) + rom ( name "Hamster Club 4 - Shigetchi Daidassou (Japan).gba" size 8388608 crc 69cf5afb sha1 0667122CF1A8DB827AFA221A11A364241DA1DC55 ) ) game ( name "Hamster Monogatari 2 GBA (Japan)" description "Hamster Monogatari 2 GBA (Japan)" - rom ( name "Hamster Monogatari 2 GBA (Japan).gba" size 8388608 crc 617724C5 md5 F9BB8A52A046EFC37077CC1A0C855DCF sha1 A41D7166EEDD4BB8AC1B7D21C2C16FBE3523CDAD ) + rom ( name "Hamster Monogatari 2 GBA (Japan).gba" size 8388608 crc 617724c5 sha1 A41D7166EEDD4BB8AC1B7D21C2C16FBE3523CDAD ) ) game ( name "Hamster Monogatari 3 GBA (Japan)" description "Hamster Monogatari 3 GBA (Japan)" - rom ( name "Hamster Monogatari 3 GBA (Japan).gba" size 8388608 crc C99D3787 md5 9AFD02F295A96E5E918C2A67621AD79C sha1 500483016098601C9E6E8EDB1D7B2042CAB4F091 ) + rom ( name "Hamster Monogatari 3 GBA (Japan).gba" size 8388608 crc c99d3787 sha1 500483016098601C9E6E8EDB1D7B2042CAB4F091 flags verified ) ) game ( name "Hamster Monogatari 3EX 4 Special (Japan)" description "Hamster Monogatari 3EX 4 Special (Japan)" - rom ( name "Hamster Monogatari 3EX 4 Special (Japan).gba" size 16777216 crc 5DCBCC79 md5 F4A74F7683E525FE7D7F125F0BF7834A sha1 E1289A61EAA4B7FB913F596A8E3DB8D418AEBCC4 ) + rom ( name "Hamster Monogatari 3EX 4 Special (Japan).gba" size 16777216 crc 5dcbcc79 sha1 E1289A61EAA4B7FB913F596A8E3DB8D418AEBCC4 flags verified ) ) game ( name "Hamster Monogatari Collection (Japan)" description "Hamster Monogatari Collection (Japan)" - rom ( name "Hamster Monogatari Collection (Japan).gba" size 8388608 crc 35584EA6 md5 54E147B32160AC117FB1FDECEFE35302 sha1 E92AFA9FA008283CBD2A4E143B717BA93F0EB9D2 ) + rom ( name "Hamster Monogatari Collection (Japan).gba" size 8388608 crc 35584ea6 sha1 E92AFA9FA008283CBD2A4E143B717BA93F0EB9D2 ) ) game ( name "Hamster Paradise - Pure Heart (Japan)" description "Hamster Paradise - Pure Heart (Japan)" - rom ( name "Hamster Paradise - Pure Heart (Japan).gba" size 8388608 crc 0E9D0144 md5 5C4957B6D2A4D6095C1F119C57D806D4 sha1 DA0B8DAB120C72E2DE1FF4F623E10A58F3CF177E ) + rom ( name "Hamster Paradise - Pure Heart (Japan).gba" size 8388608 crc 0e9d0144 sha1 DA0B8DAB120C72E2DE1FF4F623E10A58F3CF177E ) ) game ( name "Hamster Paradise Advanchu (Japan)" description "Hamster Paradise Advanchu (Japan)" - rom ( name "Hamster Paradise Advanchu (Japan).gba" size 8388608 crc 902BEFB0 md5 7331DEEA4C627B772D7B271B3EABB7AF sha1 747F95C137935CBB9643E818CDEBFCA9BD74D67C ) + rom ( name "Hamster Paradise Advanchu (Japan).gba" size 8388608 crc 902befb0 sha1 747F95C137935CBB9643E818CDEBFCA9BD74D67C flags verified ) ) game ( name "Hamtaro - Ham-Ham Games (Japan, USA) (En,Ja)" description "Hamtaro - Ham-Ham Games (Japan, USA) (En,Ja)" - rom ( name "Hamtaro - Ham-Ham Games (Japan, USA) (En,Ja).gba" size 16777216 crc CC1CF806 md5 9EECB3D524FE8BC2362B3F0B1045F4AB sha1 666F9182358D10355AC1A505F52569362AE794B8 ) + rom ( name "Hamtaro - Ham-Ham Games (Japan, USA) (En,Ja).gba" size 16777216 crc cc1cf806 sha1 666F9182358D10355AC1A505F52569362AE794B8 flags verified ) ) game ( name "Hamtaro - Ham-Ham Games (Europe) (En,Fr,De,Es,It)" description "Hamtaro - Ham-Ham Games (Europe) (En,Fr,De,Es,It)" - rom ( name "Hamtaro - Ham-Ham Games (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc D9341D9C md5 58495BB95BD130A980821FD1E8CA38B5 sha1 B948E4788310C19A76AF6D69847515424B618BEA flags verified ) -) - -game ( - name "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It)" - description "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It)" - rom ( name "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ECBD80EA md5 5B565A961547D6D0980C57E2529130E1 sha1 B016328E4880F0413B9335C95758BA9C09E53710 ) + rom ( name "Hamtaro - Ham-Ham Games (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc d9341d9c sha1 B948E4788310C19A76AF6D69847515424B618BEA flags verified ) ) game ( name "Hamtaro - Ham-Ham Heartbreak (USA)" description "Hamtaro - Ham-Ham Heartbreak (USA)" - rom ( name "Hamtaro - Ham-Ham Heartbreak (USA).gba" size 8388608 crc CD48B673 md5 42CCA53C94C0BB8E5146631945BF0CD9 sha1 2525CC23524068DFB3A2B4E0CE7B736F95023E82 ) + rom ( name "Hamtaro - Ham-Ham Heartbreak (USA).gba" size 8388608 crc cd48b673 sha1 2525CC23524068DFB3A2B4E0CE7B736F95023E82 ) +) + +game ( + name "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It)" + description "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It)" + rom ( name "Hamtaro - Ham-Ham Heartbreak (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ecbd80ea sha1 B016328E4880F0413B9335C95758BA9C09E53710 flags verified ) ) game ( name "Hamtaro - Rainbow Rescue (Europe) (En,Fr,De,Es,It)" description "Hamtaro - Rainbow Rescue (Europe) (En,Fr,De,Es,It)" - rom ( name "Hamtaro - Rainbow Rescue (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 5D051081 md5 4A4A77B12B463A758A143642F96B1846 sha1 B6446397744C10EB08F112F005E995DD9954A675 ) + rom ( name "Hamtaro - Rainbow Rescue (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 5d051081 sha1 B6446397744C10EB08F112F005E995DD9954A675 ) ) game ( name "Hanabi Hyakkei Advance (Japan)" description "Hanabi Hyakkei Advance (Japan)" - rom ( name "Hanabi Hyakkei Advance (Japan).gba" size 4194304 crc 173A6C4A md5 BB00226987E213BEA5217D2AB387048B sha1 92FD9C9B4556AE976E32931437EFF7F358BC07BD ) + rom ( name "Hanabi Hyakkei Advance (Japan).gba" size 4194304 crc 173a6c4a sha1 92FD9C9B4556AE976E32931437EFF7F358BC07BD ) ) game ( name "Hanafuda Trump Mahjong - Depachika Wayouchuu (Japan)" description "Hanafuda Trump Mahjong - Depachika Wayouchuu (Japan)" - rom ( name "Hanafuda Trump Mahjong - Depachika Wayouchuu (Japan).gba" size 4194304 crc DE7B8DCD md5 BF770CB831B9FB693E2EED05A4BFFC38 sha1 D36E3E75D895DBD93A2C424CA1F972C3F16417A0 ) + rom ( name "Hanafuda Trump Mahjong - Depachika Wayouchuu (Japan).gba" size 4194304 crc de7b8dcd sha1 D36E3E75D895DBD93A2C424CA1F972C3F16417A0 ) ) game ( name "Happy Feet (Europe) (En,Fr,De,Es,It)" description "Happy Feet (Europe) (En,Fr,De,Es,It)" - rom ( name "Happy Feet (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 7A53173C md5 16F26E6349E004951B34D87FA5EA7C3A sha1 CBCCCE77BB727EFA7AB4805509773121239FAF13 ) + rom ( name "Happy Feet (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 7a53173c sha1 CBCCCE77BB727EFA7AB4805509773121239FAF13 ) ) game ( name "Happy Feet (USA) (En,Fr)" description "Happy Feet (USA) (En,Fr)" - rom ( name "Happy Feet (USA) (En,Fr).gba" size 33554432 crc 682617CF md5 423482D9F0A696CB985D8143F574864C sha1 E7C95CBC076E97ED2A414ABC9F8D419E47174505 ) + rom ( name "Happy Feet (USA) (En,Fr).gba" size 33554432 crc 682617cf sha1 E7C95CBC076E97ED2A414ABC9F8D419E47174505 ) ) game ( name "Hardcore Pinball (USA, Europe)" description "Hardcore Pinball (USA, Europe)" - rom ( name "Hardcore Pinball (USA, Europe).gba" size 4194304 crc 5466C757 md5 84A1007A744A784BB16C98F1CE04F94E sha1 1C8D1E6738443239F3ACD14F0F979B3BDE274DDA flags verified ) + rom ( name "Hardcore Pinball (USA, Europe).gba" size 4194304 crc 5466c757 sha1 1C8D1E6738443239F3ACD14F0F979B3BDE274DDA flags verified ) ) game ( name "Hardcore Pool (Europe) (En,De,Es,It)" description "Hardcore Pool (Europe) (En,De,Es,It)" - rom ( name "Hardcore Pool (Europe) (En,De,Es,It).gba" size 4194304 crc 2BE4F2BC md5 A4BF3AA27A7C5C3FFD0DCAF27DA99486 sha1 F1755E575B4A8E19A7F30BCC3EF3450BA6CB31EA ) + rom ( name "Hardcore Pool (Europe) (En,De,Es,It).gba" size 4194304 crc 2be4f2bc sha1 F1755E575B4A8E19A7F30BCC3EF3450BA6CB31EA ) +) + +game ( + name "Hardcore Pool (France)" + description "Hardcore Pool (France)" + rom ( name "Hardcore Pool (France).gba" size 4194304 crc 44779175 sha1 BFB0A17C4463D73E597640AB88299ADC5F26A270 flags verified ) ) game ( name "Harlem Globetrotters - World Tour (USA)" description "Harlem Globetrotters - World Tour (USA)" - rom ( name "Harlem Globetrotters - World Tour (USA).gba" size 4194304 crc 737C286F md5 6D61C02022243C2F815E071F4A209F08 sha1 01B4041C2F7D340B9C98D018C6D10C4EB7BFA81D ) + rom ( name "Harlem Globetrotters - World Tour (USA).gba" size 4194304 crc 737c286f sha1 01B4041C2F7D340B9C98D018C6D10C4EB7BFA81D ) ) game ( name "Harlem Globetrotters - World Tour (Europe) (En,Fr,De,Es,It)" description "Harlem Globetrotters - World Tour (Europe) (En,Fr,De,Es,It)" - rom ( name "Harlem Globetrotters - World Tour (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 37B20866 md5 D015092963D9E05AFE3A552C34A81CF2 sha1 E945CEECAFA1BC78CA42560B25E141C38547391B ) + rom ( name "Harlem Globetrotters - World Tour (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 37b20866 sha1 E945CEECAFA1BC78CA42560B25E141C38547391B ) ) game ( name "Harobots - Robo Hero Battling!! (Japan)" description "Harobots - Robo Hero Battling!! (Japan)" - rom ( name "Harobots - Robo Hero Battling!! (Japan).gba" size 4194304 crc F54976C8 md5 BC292668096EE4918AE6AADCAC74AB47 sha1 BFF7E016992D3C69156E88A5D3D43DEBAC500646 ) + rom ( name "Harobots - Robo Hero Battling!! (Japan).gba" size 4194304 crc f54976c8 sha1 BFF7E016992D3C69156E88A5D3D43DEBAC500646 ) ) game ( name "Harry Potter - Quidditch World Cup (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" description "Harry Potter - Quidditch World Cup (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Harry Potter - Quidditch World Cup (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 8388608 crc 486041A4 md5 211F243E032B967E01FF97907B29F56A sha1 7B7835B655F34EFEC44ED090821257D5E1378275 flags verified ) + rom ( name "Harry Potter - Quidditch World Cup (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 8388608 crc 486041a4 sha1 7B7835B655F34EFEC44ED090821257D5E1378275 flags verified ) ) game ( name "Harry Potter - Quidditch World Cup (Japan)" description "Harry Potter - Quidditch World Cup (Japan)" - rom ( name "Harry Potter - Quidditch World Cup (Japan).gba" size 8388608 crc C1F26F37 md5 BCD9C88DFF944B4A2174BC238A628E76 sha1 0F505D02C957386A469FF77BDFBD15C92A565E6B ) + rom ( name "Harry Potter - Quidditch World Cup (Japan).gba" size 8388608 crc c1f26f37 sha1 0F505D02C957386A469FF77BDFBD15C92A565E6B ) ) game ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 8388608 crc 342816DB md5 B9B42F3E2D54921EE657BC027FA364B9 sha1 0218E3BE69334CAC752D5AD5B3763A26252CB88B flags verified ) + rom ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 8388608 crc 342816db sha1 0218E3BE69334CAC752D5AD5B3763A26252CB88B flags verified ) ) game ( name "Harry Potter and the Goblet of Fire (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" description "Harry Potter and the Goblet of Fire (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Harry Potter and the Goblet of Fire (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 33554432 crc 052708D7 md5 33D83AEC45345690FFE48AD9ED7A4FF8 sha1 05CB9E9FB38E18E6E9B547168EFEDB25343D5AD0 ) + rom ( name "Harry Potter and the Goblet of Fire (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 33554432 crc 052708d7 sha1 05CB9E9FB38E18E6E9B547168EFEDB25343D5AD0 flags verified ) ) game ( - name "Harry Potter and the Order of the Phoenix (Europe) (En,Fr,De,Es,It,Nl,Da)" - description "Harry Potter and the Order of the Phoenix (Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Harry Potter and the Order of the Phoenix (Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc 302B8B3D md5 3A92A2D56665A8AA1640FC276095659A sha1 229B01A9412E9D04EFEA02E392718FE617D5A173 ) + name "Harry Potter and the Order of the Phoenix (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" + description "Harry Potter and the Order of the Phoenix (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" + rom ( name "Harry Potter and the Order of the Phoenix (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc 302b8b3d sha1 229B01A9412E9D04EFEA02E392718FE617D5A173 ) ) game ( name "Harry Potter and the Prisoner of Azkaban (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" description "Harry Potter and the Prisoner of Azkaban (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Harry Potter and the Prisoner of Azkaban (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc C0BCCAAD md5 3FE499F2A6B141EC2959E2D109E3F321 sha1 5BE308501F0CFE0C30C60EF1FBF886707CDACD29 flags verified ) + rom ( name "Harry Potter and the Prisoner of Azkaban (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc c0bccaad sha1 5BE308501F0CFE0C30C60EF1FBF886707CDACD29 flags verified ) ) game ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 8388608 crc F755065C md5 4EAAC54BC741DAAE77975B004376174F sha1 40D3F693E444192C94A0FF3CD9ED5F64162AC777 flags verified ) + rom ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 8388608 crc f755065c sha1 40D3F693E444192C94A0FF3CD9ED5F64162AC777 flags verified ) ) game ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 33554432 crc FFA9F4FB md5 806AB316CB389EB8FAD65C0FB2BD7878 sha1 A0E1A8F0C31FFD6E82EF99C95F903347A6EAE623 ) + rom ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 33554432 crc ffa9f4fb sha1 A0E1A8F0C31FFD6E82EF99C95F903347A6EAE623 ) ) game ( name "Harry Potter to Azkaban no Shuujin (Japan)" description "Harry Potter to Azkaban no Shuujin (Japan)" - rom ( name "Harry Potter to Azkaban no Shuujin (Japan).gba" size 16777216 crc 42E590D6 md5 BEA7ECC46F1AFC41FDEB342E7BC03407 sha1 7D29E25CFE75069FFBF84A7B5B7F8E8703FE1A32 ) + rom ( name "Harry Potter to Azkaban no Shuujin (Japan).gba" size 16777216 crc 42e590d6 sha1 7D29E25CFE75069FFBF84A7B5B7F8E8703FE1A32 ) ) game ( name "Harry Potter to Himitsu no Heya (Japan)" description "Harry Potter to Himitsu no Heya (Japan)" - rom ( name "Harry Potter to Himitsu no Heya (Japan).gba" size 8388608 crc B485DABF md5 D31DB14855A0DE7EA8789F853C2AF3C6 sha1 BACF6DB02E14599F5DBC8202243EAC134566E96F ) + rom ( name "Harry Potter to Himitsu no Heya (Japan).gba" size 8388608 crc b485dabf sha1 BACF6DB02E14599F5DBC8202243EAC134566E96F ) ) game ( name "Harry Potter to Kenja no Ishi (Japan)" description "Harry Potter to Kenja no Ishi (Japan)" - rom ( name "Harry Potter to Kenja no Ishi (Japan).gba" size 8388608 crc A069750D md5 6AF04804F4FAE08202BECBBFC1CC9E98 sha1 3D377F5DDB6F2991D4E23DFF7264F1D0A3B245B8 flags verified ) + rom ( name "Harry Potter to Kenja no Ishi (Japan).gba" size 8388608 crc a069750d sha1 3D377F5DDB6F2991D4E23DFF7264F1D0A3B245B8 flags verified ) ) game ( name "Harvest Moon - Friends of Mineral Town (USA)" description "Harvest Moon - Friends of Mineral Town (USA)" - rom ( name "Harvest Moon - Friends of Mineral Town (USA).gba" size 8388608 crc 8E923168 md5 80355C831A7A25B0F70DC021EBD344F1 sha1 A2FC3574F0A65A4FCF7682FB274B9D7EEBDEF963 ) + rom ( name "Harvest Moon - Friends of Mineral Town (USA).gba" size 8388608 crc 8e923168 sha1 A2FC3574F0A65A4FCF7682FB274B9D7EEBDEF963 ) ) game ( name "Harvest Moon - Friends of Mineral Town (Germany)" description "Harvest Moon - Friends of Mineral Town (Germany)" - rom ( name "Harvest Moon - Friends of Mineral Town (Germany).gba" size 8388608 crc C11757D7 md5 61D0616B30F8E111CCB68004BE97D4EB sha1 60F2A30B55C0E32754897B4D5DF6CE06F8B71A37 flags verified ) + rom ( name "Harvest Moon - Friends of Mineral Town (Germany).gba" size 8388608 crc c11757d7 sha1 60F2A30B55C0E32754897B4D5DF6CE06F8B71A37 flags verified ) ) game ( name "Harvest Moon - Friends of Mineral Town (Europe)" description "Harvest Moon - Friends of Mineral Town (Europe)" - rom ( name "Harvest Moon - Friends of Mineral Town (Europe).gba" size 8388608 crc F50F82AD md5 02A9FDDD43013966303A043DB1C0A479 sha1 7BA1EC1E46CE424E3C6FD72E4E8D5E9EB5EDE247 ) + rom ( name "Harvest Moon - Friends of Mineral Town (Europe).gba" size 8388608 crc f50f82ad sha1 7BA1EC1E46CE424E3C6FD72E4E8D5E9EB5EDE247 ) ) game ( name "Harvest Moon - More Friends of Mineral Town (USA)" description "Harvest Moon - More Friends of Mineral Town (USA)" - rom ( name "Harvest Moon - More Friends of Mineral Town (USA).gba" size 16777216 crc 1736B957 md5 FCBF93F8859D8500319E0D80A8C02150 sha1 3AA4D46CBBF152E440942ACD5F5D37DDC7B05E1D ) + rom ( name "Harvest Moon - More Friends of Mineral Town (USA).gba" size 16777216 crc 1736b957 sha1 3AA4D46CBBF152E440942ACD5F5D37DDC7B05E1D ) ) game ( name "Hatena Satena (Japan)" description "Hatena Satena (Japan)" - rom ( name "Hatena Satena (Japan).gba" size 4194304 crc 6139E34D md5 D30A036C3BD3CB62F6029BE745910075 sha1 BCF8DE4B7828449261321FD4554E574696438176 ) + rom ( name "Hatena Satena (Japan).gba" size 4194304 crc 6139e34d sha1 BCF8DE4B7828449261321FD4554E574696438176 ) ) game ( name "Haunted Mansion, The (USA) (Proto)" description "Haunted Mansion, The (USA) (Proto)" - rom ( name "Haunted Mansion, The (USA) (Proto).gba" size 8388608 crc DEBC5439 md5 E10C33761A85410BB894696AE03F22D0 sha1 67ED68EEB1D737413F3B5CD1DA6C29A3E29CEEE4 ) + rom ( name "Haunted Mansion, The (USA) (Proto).gba" size 8388608 crc debc5439 sha1 67ED68EEB1D737413F3B5CD1DA6C29A3E29CEEE4 ) ) game ( name "Heidi - The Game (Europe) (En,Fr,De,Es,It)" description "Heidi - The Game (Europe) (En,Fr,De,Es,It)" - rom ( name "Heidi - The Game (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E8C44FB8 md5 2DD50CFF5266E703E72964FA0755E0C7 sha1 C9F29C937A46371699841FD381C6BB4701DEAC17 flags verified ) + rom ( name "Heidi - The Game (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e8c44fb8 sha1 C9F29C937A46371699841FD381C6BB4701DEAC17 flags verified ) ) game ( name "Hello Kitty - Happy Party Pals (USA)" description "Hello Kitty - Happy Party Pals (USA)" - rom ( name "Hello Kitty - Happy Party Pals (USA).gba" size 4194304 crc E49C45A0 md5 18441E53EFD724563581600A0F253879 sha1 43496B1527DBE90627AB02A54A30ACBCF42A3BDC ) + rom ( name "Hello Kitty - Happy Party Pals (USA).gba" size 4194304 crc e49c45a0 sha1 43496B1527DBE90627AB02A54A30ACBCF42A3BDC ) ) game ( name "Hello Kitty - Happy Party Pals (Europe) (En,Fr,De,Es)" description "Hello Kitty - Happy Party Pals (Europe) (En,Fr,De,Es)" - rom ( name "Hello Kitty - Happy Party Pals (Europe) (En,Fr,De,Es).gba" size 4194304 crc 1A080C10 md5 4206B6B611755DBC1557586F4077DD6C sha1 0A5D1652F05943FA2C6116D9DE07B92038BE8570 flags verified ) + rom ( name "Hello Kitty - Happy Party Pals (Europe) (En,Fr,De,Es).gba" size 4194304 crc 1a080c10 sha1 0A5D1652F05943FA2C6116D9DE07B92038BE8570 flags verified ) ) game ( name "Hello Kitty - Happy Party Pals (Europe)" description "Hello Kitty - Happy Party Pals (Europe)" - rom ( name "Hello Kitty - Happy Party Pals (Europe).gba" size 4194304 crc 9C45920E md5 74EA076A8976ACC454312F8ECD40E566 sha1 211382DEB7072F168395784F67AF28B51B265872 ) + rom ( name "Hello Kitty - Happy Party Pals (Europe).gba" size 4194304 crc 9c45920e sha1 211382DEB7072F168395784F67AF28B51B265872 ) ) game ( name "Hello Kitty Collection - Miracle Fashion Maker (Japan)" description "Hello Kitty Collection - Miracle Fashion Maker (Japan)" - rom ( name "Hello Kitty Collection - Miracle Fashion Maker (Japan).gba" size 8388608 crc C8F4D874 md5 4754AA1E077CEA418C77198270895013 sha1 5242170AD6FE8F1169E423F13F77AD18F54D3659 ) + rom ( name "Hello Kitty Collection - Miracle Fashion Maker (Japan).gba" size 8388608 crc c8f4d874 sha1 5242170AD6FE8F1169E423F13F77AD18F54D3659 flags verified ) ) game ( name "Hello! Idol Debut - Kids Idol Ikusei Game (Japan)" description "Hello! Idol Debut - Kids Idol Ikusei Game (Japan)" - rom ( name "Hello! Idol Debut - Kids Idol Ikusei Game (Japan).gba" size 8388608 crc 304BDFC3 md5 B9FB4F6D037649F4F87CC47F36D60869 sha1 7288A474B8D8EEBB6FC8FDB90FA298B031E3E1C8 ) + rom ( name "Hello! Idol Debut - Kids Idol Ikusei Game (Japan).gba" size 8388608 crc 304bdfc3 sha1 7288A474B8D8EEBB6FC8FDB90FA298B031E3E1C8 ) +) + +game ( + name "Hello! Idol Debut - Kids Idol Ikusei Game (Japan) (Rev 1)" + description "Hello! Idol Debut - Kids Idol Ikusei Game (Japan) (Rev 1)" + rom ( name "Hello! Idol Debut - Kids Idol Ikusei Game (Japan) (Rev 1).gba" size 8388608 crc 40958c2c sha1 82161A5E950DECB45049CD8075DFE40A7496CC56 flags verified ) ) game ( name "Herbie - Fully Loaded (USA)" description "Herbie - Fully Loaded (USA)" - rom ( name "Herbie - Fully Loaded (USA).gba" size 8388608 crc 9C6A3DD1 md5 9824D54E798F7985D620B41ABD722993 sha1 6A9D8F05A8517A92D1908A8A5845C128BF42A573 ) + rom ( name "Herbie - Fully Loaded (USA).gba" size 8388608 crc 9c6a3dd1 sha1 6A9D8F05A8517A92D1908A8A5845C128BF42A573 ) ) game ( name "Herbie - Fully Loaded (Europe) (En,Fr,De)" description "Herbie - Fully Loaded (Europe) (En,Fr,De)" - rom ( name "Herbie - Fully Loaded (Europe) (En,Fr,De).gba" size 8388608 crc 2521A98C md5 F74BAAB7B2516B43119D23292033C735 sha1 0A2F427CC781E0D8BC7B59D6CD05F0714795F38E flags verified ) -) - -game ( - name "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta)" - description "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta)" - rom ( name "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta).gba" size 4194304 crc 9E4773BA md5 3E96ED2991E696DB50A279E2854C0BE5 sha1 CEBE93DDCB49664F0FFB9FB70DBCB5C91E70D340 ) + rom ( name "Herbie - Fully Loaded (Europe) (En,Fr,De).gba" size 8388608 crc 2521a98c sha1 0A2F427CC781E0D8BC7B59D6CD05F0714795F38E flags verified ) ) game ( name "Hey Arnold! - The Movie (USA)" description "Hey Arnold! - The Movie (USA)" - rom ( name "Hey Arnold! - The Movie (USA).gba" size 4194304 crc 59DFAB9E md5 A234F8B94FAFC111AB29F235361BAF50 sha1 26042BBC068390246B3B01F02571659E08414A64 flags verified ) + rom ( name "Hey Arnold! - The Movie (USA).gba" size 4194304 crc 59dfab9e sha1 26042BBC068390246B3B01F02571659E08414A64 flags verified ) ) game ( name "Hey Arnold! - The Movie (Europe) (En,Fr,De)" description "Hey Arnold! - The Movie (Europe) (En,Fr,De)" - rom ( name "Hey Arnold! - The Movie (Europe) (En,Fr,De).gba" size 4194304 crc 2B666FED md5 3023F8B53D90AF1320F5B686F0F7B868 sha1 561A1B4FC09701BA1A7D25006E3A3EA5EBA43EC2 flags verified ) + rom ( name "Hey Arnold! - The Movie (Europe) (En,Fr,De).gba" size 4194304 crc 2b666fed sha1 561A1B4FC09701BA1A7D25006E3A3EA5EBA43EC2 flags verified ) +) + +game ( + name "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta)" + description "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta)" + rom ( name "Hey Arnold! - The Movie (Europe) (En,Fr,De) (Beta).gba" size 4194304 crc 9e4773ba sha1 CEBE93DDCB49664F0FFB9FB70DBCB5C91E70D340 ) ) game ( name "Hi Hi Puffy AmiYumi (Japan)" description "Hi Hi Puffy AmiYumi (Japan)" - rom ( name "Hi Hi Puffy AmiYumi (Japan).gba" size 8388608 crc 90239C3D md5 283969C5D1C1E46B94B565C6DA5ECD5C sha1 AA2107C994DABB928D31B7B2C586ABF556BB973E ) + rom ( name "Hi Hi Puffy AmiYumi (Japan).gba" size 8388608 crc 90239c3d sha1 AA2107C994DABB928D31B7B2C586ABF556BB973E flags verified ) ) game ( name "Hi Hi Puffy AmiYumi - Kaznapped! (USA)" description "Hi Hi Puffy AmiYumi - Kaznapped! (USA)" - rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (USA).gba" size 8388608 crc E613AA43 md5 80648FA0CB4FBF49A68C810FC64EDAAA sha1 517E513BD1659749BFBAB3D335DF83A2838EE789 flags verified ) + rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (USA).gba" size 8388608 crc e613aa43 sha1 517E513BD1659749BFBAB3D335DF83A2838EE789 flags verified ) ) game ( name "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De)" description "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De)" - rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De).gba" size 8388608 crc E5531D04 md5 FA70BAC809F1801F26472A023330E1DC sha1 4060BE81C5A0BC741D759F75CD83823106E5B6B9 ) + rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De).gba" size 8388608 crc e5531d04 sha1 4060BE81C5A0BC741D759F75CD83823106E5B6B9 ) ) game ( name "Higanbana (Japan) (Rev 1)" description "Higanbana (Japan) (Rev 1)" - rom ( name "Higanbana (Japan) (Rev 1).gba" size 8388608 crc C23AC287 md5 CCC940468BD911CB13E06F761D798126 sha1 515F150EF1E393E308BF98E2C1CCBBE4F598F6DF ) + rom ( name "Higanbana (Japan) (Rev 1).gba" size 8388608 crc c23ac287 sha1 515F150EF1E393E308BF98E2C1CCBBE4F598F6DF ) ) game ( name "High Heat Major League Baseball 2002 (USA, Europe)" description "High Heat Major League Baseball 2002 (USA, Europe)" - rom ( name "High Heat Major League Baseball 2002 (USA, Europe).gba" size 4194304 crc 6EA3F4E4 md5 62B5EE4401A0EEC948817A69011E71D7 sha1 D9E9B232C16214FFAEF1F706F8B16829F2700414 flags verified ) + rom ( name "High Heat Major League Baseball 2002 (USA, Europe).gba" size 4194304 crc 6ea3f4e4 sha1 D9E9B232C16214FFAEF1F706F8B16829F2700414 flags verified ) ) game ( name "High Heat Major League Baseball 2003 (USA)" description "High Heat Major League Baseball 2003 (USA)" - rom ( name "High Heat Major League Baseball 2003 (USA).gba" size 4194304 crc 59D72CB9 md5 22D31D959DE4E87160BA308C95386799 sha1 9EAEE2C694B0BE651BE0E319DF1C18FDBD721267 flags verified ) + rom ( name "High Heat Major League Baseball 2003 (USA).gba" size 4194304 crc 59d72cb9 sha1 9EAEE2C694B0BE651BE0E319DF1C18FDBD721267 flags verified ) ) game ( name "High Heat Major League Baseball 2003 (Japan) (En)" description "High Heat Major League Baseball 2003 (Japan) (En)" - rom ( name "High Heat Major League Baseball 2003 (Japan) (En).gba" size 4194304 crc 0D9043A4 md5 B433DCA158D3BC3D73CB0BA6E831B258 sha1 E51A7A07867134A790E5B5C8DB5EA8B2892A5F2D ) + rom ( name "High Heat Major League Baseball 2003 (Japan) (En).gba" size 4194304 crc 0d9043a4 sha1 E51A7A07867134A790E5B5C8DB5EA8B2892A5F2D ) ) game ( name "High School Musical - Livin' the Dream (USA)" description "High School Musical - Livin' the Dream (USA)" - rom ( name "High School Musical - Livin' the Dream (USA).gba" size 16777216 crc 7B31D4DA md5 B940EAE646950FC687E9AD29F8D43E0D sha1 BADA563635E1490E5BC81964A12331B0CCB806CF ) + rom ( name "High School Musical - Livin' the Dream (USA).gba" size 16777216 crc 7b31d4da sha1 BADA563635E1490E5BC81964A12331B0CCB806CF ) ) game ( name "High School Musical - Livin' the Dream (USA) (Beta)" description "High School Musical - Livin' the Dream (USA) (Beta)" - rom ( name "High School Musical - Livin' the Dream (USA) (Beta).gba" size 16777216 crc C340D5F7 md5 E041A99ECCF2D2B7360B6703CE73E169 sha1 163701C68771E2108202A3CFD8EFFE69CC48AEB7 ) -) - -game ( - name "Hikaru no Go (Japan) (Rev 1)" - description "Hikaru no Go (Japan) (Rev 1)" - rom ( name "Hikaru no Go (Japan) (Rev 1).gba" size 8388608 crc 53116FD7 md5 A0451DBC9FABBD40A86B76C30E60794A sha1 C61227F6CCFDC196EF810C1986322B0B1988E508 ) -) - -game ( - name "Hikaru no Go (Japan) (Demo) (Promo)" - description "Hikaru no Go (Japan) (Demo) (Promo)" - rom ( name "Hikaru no Go (Japan) (Demo) (Promo).gba" size 4194304 crc 4955FA1B md5 722C772A025767DA32AAA02D5246CD8D sha1 636C3247F455263C41FC0DEE85FD4532246B60C2 ) + rom ( name "High School Musical - Livin' the Dream (USA) (Beta).gba" size 16777216 crc c340d5f7 sha1 163701C68771E2108202A3CFD8EFFE69CC48AEB7 ) ) game ( name "Hikaru no Go (Japan)" description "Hikaru no Go (Japan)" - rom ( name "Hikaru no Go (Japan).gba" size 8388608 crc 5A6C7537 md5 889FBC49115CE1F21E89490E0A2FE457 sha1 A96299F55026B959ED806BFF0FB4A440D33E65AF ) + rom ( name "Hikaru no Go (Japan).gba" size 8388608 crc 5a6c7537 sha1 A96299F55026B959ED806BFF0FB4A440D33E65AF ) +) + +game ( + name "Hikaru no Go (Japan) (Rev 1)" + description "Hikaru no Go (Japan) (Rev 1)" + rom ( name "Hikaru no Go (Japan) (Rev 1).gba" size 8388608 crc 53116fd7 sha1 C61227F6CCFDC196EF810C1986322B0B1988E508 flags verified ) +) + +game ( + name "Hikaru no Go (Japan) (Demo) (Promo)" + description "Hikaru no Go (Japan) (Demo) (Promo)" + rom ( name "Hikaru no Go (Japan) (Demo) (Promo).gba" size 4194304 crc 4955fa1b sha1 636C3247F455263C41FC0DEE85FD4532246B60C2 ) ) game ( name "Hikaru no Go 2 (Japan)" description "Hikaru no Go 2 (Japan)" - rom ( name "Hikaru no Go 2 (Japan).gba" size 16777216 crc 04129A22 md5 3B7A7175D8BDD4A54C41E7D0BE54C6DB sha1 C2BA3A59AAA0A6F607D570500F4D085222869908 ) + rom ( name "Hikaru no Go 2 (Japan).gba" size 16777216 crc 04129a22 sha1 C2BA3A59AAA0A6F607D570500F4D085222869908 flags verified ) ) game ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" description "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan)" - rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan).gba" size 8388608 crc 8EA9AFCC md5 70351A87511A012D5985D525CFC7BAF2 sha1 FEFC7A73DDCEAF28EBB95B88F5F39A5489024D4E ) + rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan).gba" size 8388608 crc 8ea9afcc sha1 FEFC7A73DDCEAF28EBB95B88F5F39A5489024D4E ) +) + +game ( + name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan) (Rev 1)" + description "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan) (Rev 1)" + rom ( name "Himawari Doubutsu Byouin - Pet no Oishasan Ikusei Game (Japan) (Rev 1).gba" size 8388608 crc 526fdfff sha1 93B98FCF585483722240E56C01826AE5C31930E4 flags verified ) ) game ( name "Hime Kishi Monogatari - Princess Blue (Japan)" description "Hime Kishi Monogatari - Princess Blue (Japan)" - rom ( name "Hime Kishi Monogatari - Princess Blue (Japan).gba" size 8388608 crc 46810F68 md5 86E18DB544FF6281728B472E4F5DE317 sha1 BBE5BB81F05D37D4088523DC13C4682BE0736678 ) + rom ( name "Hime Kishi Monogatari - Princess Blue (Japan).gba" size 8388608 crc 46810f68 sha1 BBE5BB81F05D37D4088523DC13C4682BE0736678 ) ) game ( name "Hitsuji no Kimochi. (Japan)" description "Hitsuji no Kimochi. (Japan)" - rom ( name "Hitsuji no Kimochi. (Japan).gba" size 4194304 crc D4EAC9B1 md5 F6DEBA3B5D10F9D85306D4946EE342B4 sha1 10E3BAA340A34F6276D892C66FA3CE4002D6E5E4 ) + rom ( name "Hitsuji no Kimochi. (Japan).gba" size 4194304 crc d4eac9b1 sha1 10E3BAA340A34F6276D892C66FA3CE4002D6E5E4 ) ) game ( name "Hobbit no Bouken - Lord of the Rings - Hajimari no Monogatari (Japan)" description "Hobbit no Bouken - Lord of the Rings - Hajimari no Monogatari (Japan)" - rom ( name "Hobbit no Bouken - Lord of the Rings - Hajimari no Monogatari (Japan).gba" size 8388608 crc 65FB830A md5 653D319270776CE3B289C8BD14965C87 sha1 C12F31C9F85004EE4DFE2A469A8B801C4B379BFD ) + rom ( name "Hobbit no Bouken - Lord of the Rings - Hajimari no Monogatari (Japan).gba" size 8388608 crc 65fb830a sha1 C12F31C9F85004EE4DFE2A469A8B801C4B379BFD ) ) game ( - name "Hobbit, The (Europe) (En,Fr,De,Es,It)" - description "Hobbit, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Hobbit, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc EACDFE0F md5 C3EF5DA0B49DA2E7A124D5D94F19DAF7 sha1 46D6E59C3677CC296E053FDD1E9FC21551883589 flags verified ) + name "Hobbit, The - The Prelude to the Lord of the Rings (Europe) (En,Fr,De,Es,It)" + description "Hobbit, The - The Prelude to the Lord of the Rings (Europe) (En,Fr,De,Es,It)" + rom ( name "Hobbit, The - The Prelude to the Lord of the Rings (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc eacdfe0f sha1 46D6E59C3677CC296E053FDD1E9FC21551883589 flags verified ) ) game ( - name "Hobbit, The (USA)" - description "Hobbit, The (USA)" - rom ( name "Hobbit, The (USA).gba" size 8388608 crc D3F654B3 md5 03AAA67FCB972EC6BCE6F1C6863026DA sha1 70D04D6D3AB8A1BFC4FA1A26D55CD4F73F84D479 ) + name "Hobbit, The - The Prelude to the Lord of the Rings (USA)" + description "Hobbit, The - The Prelude to the Lord of the Rings (USA)" + rom ( name "Hobbit, The - The Prelude to the Lord of the Rings (USA).gba" size 8388608 crc d3f654b3 sha1 70D04D6D3AB8A1BFC4FA1A26D55CD4F73F84D479 ) ) game ( name "Home on the Range (USA) (En,Fr)" description "Home on the Range (USA) (En,Fr)" - rom ( name "Home on the Range (USA) (En,Fr).gba" size 8388608 crc DBD4A6CB md5 39A7715143DCB10B6E56427BEA2F7333 sha1 321BCE711714F718AC3882ACDC3C0F659DB5191D flags verified ) + rom ( name "Home on the Range (USA) (En,Fr).gba" size 8388608 crc dbd4a6cb sha1 321BCE711714F718AC3882ACDC3C0F659DB5191D flags verified ) ) game ( name "Home on the Range (Europe) (En,Fr,De,Es)" description "Home on the Range (Europe) (En,Fr,De,Es)" - rom ( name "Home on the Range (Europe) (En,Fr,De,Es).gba" size 8388608 crc D88FEB4E md5 BC03898ADA9FFDAFCA44C74C3DFEED8D sha1 003A90C031E1D1B89CA928103933C66640331979 flags verified ) + rom ( name "Home on the Range (Europe) (En,Fr,De,Es).gba" size 8388608 crc d88feb4e sha1 003A90C031E1D1B89CA928103933C66640331979 flags verified ) ) game ( name "Horsez (USA)" description "Horsez (USA)" - rom ( name "Horsez (USA).gba" size 8388608 crc 5B2B4452 md5 2AE30F703ADD1843AB2C0299076F086D sha1 1CB9F418005404A244E1E86DEDE6AFF0E58CC114 ) -) - -game ( - name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Beta)" - description "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Beta)" - rom ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Beta).gba" size 16777216 crc BF80F1A1 md5 C77F9DEAC4047B9844795B6C18E7A5C4 sha1 D84DD2AD9CAF2754DD76BC1F8F534B6A80A13B04 ) + rom ( name "Horsez (USA).gba" size 8388608 crc 5b2b4452 sha1 1CB9F418005404A244E1E86DEDE6AFF0E58CC114 ) ) game ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Rev 1)" description "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Rev 1)" - rom ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Rev 1).gba" size 16777216 crc 683D772C md5 9937B1FD45C37EEC09188C1516DA4CEA sha1 75C95413EB5BB98E8E2549BCEBCF590A0CE75C8B ) + rom ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Rev 1).gba" size 16777216 crc 683d772c sha1 75C95413EB5BB98E8E2549BCEBCF590A0CE75C8B flags verified ) +) + +game ( + name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Demo) (Kiosk, GameCube)" + description "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Demo) (Kiosk, GameCube)" + rom ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc bf80f1a1 sha1 D84DD2AD9CAF2754DD76BC1F8F534B6A80A13B04 flags verified ) +) + +game ( + name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Wii U Virtual Console)" + description "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Wii U Virtual Console)" + rom ( name "Hoshi no Kirby - Kagami no Daimeikyuu (Japan) (Wii U Virtual Console).gba" size 16777216 crc 3da3603b sha1 700006A8B919D7EE4B7DD972DBF6C429D1ADCA71 flags verified ) ) game ( name "Hoshi no Kirby - Yume no Izumi Deluxe (Japan)" description "Hoshi no Kirby - Yume no Izumi Deluxe (Japan)" - rom ( name "Hoshi no Kirby - Yume no Izumi Deluxe (Japan).gba" size 8388608 crc C55A3C2C md5 B3F6EA2A0876D9B706EF7F79A0479A32 sha1 D0E1D2578344E881780A71B9910562DA4B123964 flags verified ) + rom ( name "Hoshi no Kirby - Yume no Izumi Deluxe (Japan).gba" size 8388608 crc c55a3c2c sha1 D0E1D2578344E881780A71B9910562DA4B123964 flags verified ) ) game ( name "Hot Potato! (USA)" description "Hot Potato! (USA)" - rom ( name "Hot Potato! (USA).gba" size 4194304 crc 5ACB7A95 md5 176DA8AC357508B17BAA922352A30568 sha1 6D07C27F7D7858F177CF3C1466EA5A8858DF4F92 ) + rom ( name "Hot Potato! (USA).gba" size 4194304 crc 5acb7a95 sha1 6D07C27F7D7858F177CF3C1466EA5A8858DF4F92 flags verified ) ) game ( name "Hot Potato! (Europe) (En,Fr,De)" description "Hot Potato! (Europe) (En,Fr,De)" - rom ( name "Hot Potato! (Europe) (En,Fr,De).gba" size 4194304 crc 2EB72B95 md5 C08873913DF3C4E4739B648FA96128A4 sha1 A799B6C1619AAD52490F403D6614A0C6994EA67C ) + rom ( name "Hot Potato! (Europe) (En,Fr,De).gba" size 4194304 crc 2eb72b95 sha1 A799B6C1619AAD52490F403D6614A0C6994EA67C ) ) game ( name "Hot Potato! (Europe)" description "Hot Potato! (Europe)" - rom ( name "Hot Potato! (Europe).gba" size 4194304 crc 99175C62 md5 10E47426DA21BD7BA064A388C8498FDB sha1 D3B5D26646397168C825B3696A3D0B380AE570E1 ) + rom ( name "Hot Potato! (Europe).gba" size 4194304 crc 99175c62 sha1 D3B5D26646397168C825B3696A3D0B380AE570E1 ) ) game ( name "Hot Wheels - All Out (USA)" description "Hot Wheels - All Out (USA)" - rom ( name "Hot Wheels - All Out (USA).gba" size 4194304 crc C73658F9 md5 2A3C66736CB90DC1DAC6CB94944D0430 sha1 ADA2B78DE6914C6506489251A419FE1696C6279F ) + rom ( name "Hot Wheels - All Out (USA).gba" size 4194304 crc c73658f9 sha1 ADA2B78DE6914C6506489251A419FE1696C6279F ) ) game ( name "Hot Wheels - All Out (Europe) (En,Fr,De,Es,It)" description "Hot Wheels - All Out (Europe) (En,Fr,De,Es,It)" - rom ( name "Hot Wheels - All Out (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 74E787DC md5 E44C57A05F836D7EC7FA1C18153B151A sha1 CFD7998BA7A00E6FDC2F6D2627018BE264AAD6B0 ) + rom ( name "Hot Wheels - All Out (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 74e787dc sha1 CFD7998BA7A00E6FDC2F6D2627018BE264AAD6B0 ) ) game ( name "Hot Wheels - Burnin' Rubber (USA)" description "Hot Wheels - Burnin' Rubber (USA)" - rom ( name "Hot Wheels - Burnin' Rubber (USA).gba" size 8388608 crc 37DCBB0D md5 8EF10E6B20930B83F2EF3C11A1752793 sha1 CE370386736DE2243A078EB50D9B72362588B8B5 ) + rom ( name "Hot Wheels - Burnin' Rubber (USA).gba" size 8388608 crc 37dcbb0d sha1 CE370386736DE2243A078EB50D9B72362588B8B5 ) ) game ( name "Hot Wheels - Burnin' Rubber (Europe) (En,Fr)" description "Hot Wheels - Burnin' Rubber (Europe) (En,Fr)" - rom ( name "Hot Wheels - Burnin' Rubber (Europe) (En,Fr).gba" size 8388608 crc 4764D029 md5 218700B79A0AE3E9D69ABF00FE06EB97 sha1 4901124CEDE271B8AA552CD2079DFADC4E9A1C26 ) + rom ( name "Hot Wheels - Burnin' Rubber (Europe) (En,Fr).gba" size 8388608 crc 4764d029 sha1 4901124CEDE271B8AA552CD2079DFADC4E9A1C26 ) ) game ( name "Hot Wheels - Stunt Track Challenge (USA, Europe)" description "Hot Wheels - Stunt Track Challenge (USA, Europe)" - rom ( name "Hot Wheels - Stunt Track Challenge (USA, Europe).gba" size 8388608 crc D0AB6A37 md5 C328C11773AB3075916F6D2C0735652A sha1 3A950FA7F2979AC8B1E2E2EB628267B3146F1DA1 flags verified ) -) - -game ( - name "Hot Wheels - Velocity X (Europe)" - description "Hot Wheels - Velocity X (Europe)" - rom ( name "Hot Wheels - Velocity X (Europe).gba" size 8388608 crc A7DDBCA3 md5 B19314E2B31266364A7A12D9D4B00B85 sha1 DDA8EBBA4D68F93DBB213DE5A898864EAD18EBE8 ) + rom ( name "Hot Wheels - Stunt Track Challenge (USA, Europe).gba" size 8388608 crc d0ab6a37 sha1 3A950FA7F2979AC8B1E2E2EB628267B3146F1DA1 flags verified ) ) game ( name "Hot Wheels - Velocity X (USA)" description "Hot Wheels - Velocity X (USA)" - rom ( name "Hot Wheels - Velocity X (USA).gba" size 8388608 crc 9592F553 md5 5EA3EEC1D71C05F46321CE090CA791EE sha1 E6A3AE1E4A58E47C78719A7F6A7E1ED0C37B34E6 ) + rom ( name "Hot Wheels - Velocity X (USA).gba" size 8388608 crc 9592f553 sha1 E6A3AE1E4A58E47C78719A7F6A7E1ED0C37B34E6 ) +) + +game ( + name "Hot Wheels - Velocity X (Europe)" + description "Hot Wheels - Velocity X (Europe)" + rom ( name "Hot Wheels - Velocity X (Europe).gba" size 8388608 crc a7ddbca3 sha1 DDA8EBBA4D68F93DBB213DE5A898864EAD18EBE8 ) ) game ( name "Hot Wheels - World Race (USA)" description "Hot Wheels - World Race (USA)" - rom ( name "Hot Wheels - World Race (USA).gba" size 8388608 crc CB313505 md5 91CC97B4023B7876F4AC783C2C4DE2BD sha1 4045CB4551399537812D81B76BDD5CB46C4C7C06 ) + rom ( name "Hot Wheels - World Race (USA).gba" size 8388608 crc cb313505 sha1 4045CB4551399537812D81B76BDD5CB46C4C7C06 ) ) game ( name "Hot Wheels - World Race (Europe)" description "Hot Wheels - World Race (Europe)" - rom ( name "Hot Wheels - World Race (Europe).gba" size 8388608 crc B9F17F8F md5 43ADD71F5171685444FE591415FFAE05 sha1 224ECA09779E12908F2F30B7567DF39177CEB88E ) + rom ( name "Hot Wheels - World Race (Europe).gba" size 8388608 crc b9f17f8f sha1 224ECA09779E12908F2F30B7567DF39177CEB88E ) ) game ( name "Hot Wheels Advance (Japan) (En)" description "Hot Wheels Advance (Japan) (En)" - rom ( name "Hot Wheels Advance (Japan) (En).gba" size 8388608 crc F79FFEDF md5 24110878DD4B1D24CD824002685A5F4A sha1 4A67EBB5F9EADCB92AAEE5AF004A335B1E896F65 ) + rom ( name "Hot Wheels Advance (Japan) (En).gba" size 8388608 crc f79ffedf sha1 4A67EBB5F9EADCB92AAEE5AF004A335B1E896F65 ) ) game ( name "Hudson Best Collection Vol. 1 - Bomber Man Collection (Japan)" description "Hudson Best Collection Vol. 1 - Bomber Man Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 1 - Bomber Man Collection (Japan).gba" size 4194304 crc 9D22604D md5 20DAD766E239365D6F121DCCF79A48F1 sha1 DD0485B12AF2B7D83BEB25ACE5DD2A967B02A70F ) + rom ( name "Hudson Best Collection Vol. 1 - Bomber Man Collection (Japan).gba" size 4194304 crc 9d22604d sha1 DD0485B12AF2B7D83BEB25ACE5DD2A967B02A70F ) ) game ( name "Hudson Best Collection Vol. 2 - Lode Runner Collection (Japan)" description "Hudson Best Collection Vol. 2 - Lode Runner Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 2 - Lode Runner Collection (Japan).gba" size 4194304 crc 87390220 md5 3A7EBDEAB05E826241CF19E3A064C664 sha1 864EF85CAF2938EBF9F0CA5C49754A46CC7971D9 ) + rom ( name "Hudson Best Collection Vol. 2 - Lode Runner Collection (Japan).gba" size 4194304 crc 87390220 sha1 864EF85CAF2938EBF9F0CA5C49754A46CC7971D9 ) ) game ( name "Hudson Best Collection Vol. 3 - Action Collection (Japan)" description "Hudson Best Collection Vol. 3 - Action Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 3 - Action Collection (Japan).gba" size 4194304 crc C207A245 md5 3083072B9F5C85B5A002139D4DF5B518 sha1 93D503FD9E70CDCDC0D02F01D05C23DE93E1337A ) + rom ( name "Hudson Best Collection Vol. 3 - Action Collection (Japan).gba" size 4194304 crc c207a245 sha1 93D503FD9E70CDCDC0D02F01D05C23DE93E1337A ) ) game ( name "Hudson Best Collection Vol. 4 - Nazotoki Collection (Japan)" description "Hudson Best Collection Vol. 4 - Nazotoki Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 4 - Nazotoki Collection (Japan).gba" size 4194304 crc 6472067A md5 B8FD606BC897F26AC47169AD3522CA0F sha1 B146044AEF0DC5C3BA2137B9CF261A34392E1F35 ) + rom ( name "Hudson Best Collection Vol. 4 - Nazotoki Collection (Japan).gba" size 4194304 crc 6472067a sha1 B146044AEF0DC5C3BA2137B9CF261A34392E1F35 ) ) game ( name "Hudson Best Collection Vol. 5 - Shooting Collection (Japan)" description "Hudson Best Collection Vol. 5 - Shooting Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 5 - Shooting Collection (Japan).gba" size 4194304 crc 39D88481 md5 039975D2D1C2828A8B19B0AE0E679E3E sha1 6AA27E0392F7876C8FCD94665C94E377C0A8ECAE ) + rom ( name "Hudson Best Collection Vol. 5 - Shooting Collection (Japan).gba" size 4194304 crc 39d88481 sha1 6AA27E0392F7876C8FCD94665C94E377C0A8ECAE ) ) game ( name "Hudson Best Collection Vol. 6 - Bouken-jima Collection (Japan)" description "Hudson Best Collection Vol. 6 - Bouken-jima Collection (Japan)" - rom ( name "Hudson Best Collection Vol. 6 - Bouken-jima Collection (Japan).gba" size 4194304 crc C51CD05F md5 48910413EBAE82C218F847A78463FBAE sha1 423256898B127CE4F17C0AFD4B66E72823681350 ) + rom ( name "Hudson Best Collection Vol. 6 - Bouken-jima Collection (Japan).gba" size 4194304 crc c51cd05f sha1 423256898B127CE4F17C0AFD4B66E72823681350 ) ) game ( name "Hugo - Bukkazoom! (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" description "Hugo - Bukkazoom! (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" - rom ( name "Hugo - Bukkazoom! (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 4194304 crc B34A2071 md5 0A9E96E8273142FC5ED60511A726A14F sha1 8C16E41CD292C82869625847E7561569B1D941AA flags verified ) -) - -game ( - name "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es)" - description "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es)" - rom ( name "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es).gba" size 4194304 crc ED5CA311 md5 BBB939C3839FC2D4864FC7BE89B60CC4 sha1 9603ECC890F0D7B152214736AEFC3B98976352D8 ) + rom ( name "Hugo - Bukkazoom! (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 4194304 crc b34a2071 sha1 8C16E41CD292C82869625847E7561569B1D941AA flags verified ) ) game ( name "Hugo - The Evil Mirror Advance (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" description "Hugo - The Evil Mirror Advance (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" - rom ( name "Hugo - The Evil Mirror Advance (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 4194304 crc 9E9D5AD7 md5 086490833184CA1C3F7DB723C0A23995 sha1 083048954DA571A63ABCFBAD6E7D694C6BD48D77 ) + rom ( name "Hugo - The Evil Mirror Advance (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 4194304 crc 9e9d5ad7 sha1 083048954DA571A63ABCFBAD6E7D694C6BD48D77 flags verified ) +) + +game ( + name "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es)" + description "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es)" + rom ( name "Hugo - The Evil Mirror Advance (USA) (En,Fr,Es).gba" size 4194304 crc ed5ca311 sha1 9603ECC890F0D7B152214736AEFC3B98976352D8 ) ) game ( name "Hugo 2 in 1 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" description "Hugo 2 in 1 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl)" - rom ( name "Hugo 2 in 1 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 8388608 crc 8EAE8860 md5 3C64EE4D89DB9C12BC8F1CF329785CF8 sha1 BA780A01415AC4B814E5376C077FDA21D493F396 flags verified ) + rom ( name "Hugo 2 in 1 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi,Pl).gba" size 8388608 crc 8eae8860 sha1 BA780A01415AC4B814E5376C077FDA21D493F396 flags verified ) ) game ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" description "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan)" - rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan).gba" size 16777216 crc AF22A5EA md5 80E03339CD076A4F89C8B89653B45D8C sha1 E752CAD1FA3FFEC56C9F6CA5886F37DA0DC74240 ) + rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan).gba" size 16777216 crc af22a5ea sha1 E752CAD1FA3FFEC56C9F6CA5886F37DA0DC74240 ) +) + +game ( + name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1)" + description "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1)" + rom ( name "Hunter X Hunter - Minna Tomodachi Daisakusen!! (Japan) (Rev 1).gba" size 16777216 crc 86c21aeb sha1 5A327073C67EE6A29BDD595F0C4031F055804E32 flags verified ) +) + +game ( + name "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" + description "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" + rom ( name "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto).gba" size 16777216 crc 8cebef1e sha1 D98ACD0ED837B44D5A97228BB9F61626C96ED2CB flags verified ) ) game ( name "Hyper Sports 2002 Winter (Japan)" description "Hyper Sports 2002 Winter (Japan)" - rom ( name "Hyper Sports 2002 Winter (Japan).gba" size 4194304 crc 1A8B6863 md5 B1318E5C93AAEF441FC5E596996DF870 sha1 928628F8486E9390BEC5D039ED30751F56C40D58 ) + rom ( name "Hyper Sports 2002 Winter (Japan).gba" size 4194304 crc 1a8b6863 sha1 928628F8486E9390BEC5D039ED30751F56C40D58 flags verified ) ) game ( name "I Spy Challenger! (USA)" description "I Spy Challenger! (USA)" - rom ( name "I Spy Challenger! (USA).gba" size 8388608 crc 946D2CBB md5 A3201407F7988A563F4DFB243DB02BCB sha1 532934239EA1151927FD45298D918E0646A6BEA4 ) + rom ( name "I Spy Challenger! (USA).gba" size 8388608 crc 946d2cbb sha1 532934239EA1151927FD45298D918E0646A6BEA4 ) ) game ( name "Ice Age (USA) (En,Fr,Es)" description "Ice Age (USA) (En,Fr,Es)" - rom ( name "Ice Age (USA) (En,Fr,Es).gba" size 4194304 crc 3FC99714 md5 4235DBFAC776AC1D3C391C740CE28892 sha1 4804B2B85F9D5C94BB844C367A4ED3E05CFD3DC5 ) + rom ( name "Ice Age (USA) (En,Fr,Es).gba" size 4194304 crc 3fc99714 sha1 4804B2B85F9D5C94BB844C367A4ED3E05CFD3DC5 ) ) game ( name "Ice Age (Europe) (En,Fr,De,Es,It)" description "Ice Age (Europe) (En,Fr,De,Es,It)" - rom ( name "Ice Age (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 10179D72 md5 B6E949610FEEC32108B4BDC62D1BE4DC sha1 065BA5EE19799C4A9CAD3F0CF0E4E4C1EEC04A27 ) + rom ( name "Ice Age (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 10179d72 sha1 065BA5EE19799C4A9CAD3F0CF0E4E4C1EEC04A27 ) ) game ( name "Ice Age (Japan)" description "Ice Age (Japan)" - rom ( name "Ice Age (Japan).gba" size 4194304 crc 6D457F4C md5 32C77B409455BC4EFBFDE71D4CA4D256 sha1 6C36E22D86D89662493D8F2F9FE2A42C051168FD ) + rom ( name "Ice Age (Japan).gba" size 4194304 crc 6d457f4c sha1 6C36E22D86D89662493D8F2F9FE2A42C051168FD ) ) game ( name "Ice Age 2 - The Meltdown (USA)" description "Ice Age 2 - The Meltdown (USA)" - rom ( name "Ice Age 2 - The Meltdown (USA).gba" size 16777216 crc 000206C0 md5 11CB293EB98B1D7BAB027CDA8777C98E sha1 383B6205D688D9640CB6930C02ADD46873F8A10D ) + rom ( name "Ice Age 2 - The Meltdown (USA).gba" size 16777216 crc 000206c0 sha1 383B6205D688D9640CB6930C02ADD46873F8A10D flags verified ) ) game ( name "Ice Age 2 - The Meltdown (Europe) (En,Fr,De,Es,It,Nl)" description "Ice Age 2 - The Meltdown (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Ice Age 2 - The Meltdown (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 58043308 md5 D0452572FDFF4D290A3FF76FE0A07739 sha1 0B1384988DF2A16F0E33C25BC0ECCECE021E23B1 flags verified ) + rom ( name "Ice Age 2 - The Meltdown (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 58043308 sha1 0B1384988DF2A16F0E33C25BC0ECCECE021E23B1 flags verified ) ) game ( name "Ice Nine (USA, Europe) (En,Fr,De,Es,It)" description "Ice Nine (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Ice Nine (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 14C23257 md5 B15B6CB642868B1B92031A10E5A68DD7 sha1 47CAE2872F85D2DD56967C34F9160838166A47A6 ) + rom ( name "Ice Nine (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 14c23257 sha1 47CAE2872F85D2DD56967C34F9160838166A47A6 ) ) game ( name "Ignition Collection - Volume 1 (Europe)" description "Ignition Collection - Volume 1 (Europe)" - rom ( name "Ignition Collection - Volume 1 (Europe).gba" size 16777216 crc 164A75AC md5 96EC0F9E34CE0A2C2D0A50F793B30C26 sha1 62E598F9C6EA47626954619295107955AD7C371A flags verified ) + rom ( name "Ignition Collection - Volume 1 (Europe).gba" size 16777216 crc 164a75ac sha1 62E598F9C6EA47626954619295107955AD7C371A flags verified ) ) game ( name "Incredibili, Gli - Una 'Normale' Famiglia di Supereroi (Italy)" description "Incredibili, Gli - Una 'Normale' Famiglia di Supereroi (Italy)" - rom ( name "Incredibili, Gli - Una 'Normale' Famiglia di Supereroi (Italy).gba" size 8388608 crc 615839EF md5 BC80DC29FBDBB9C8EE9AF46F11C59665 sha1 520AEC2F41CD15F1307CC2146A47EC6095B78B64 ) -) - -game ( - name "Incredible Hulk, The (Europe) (En,Fr,De,Es,It)" - description "Incredible Hulk, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Incredible Hulk, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 7E00422C md5 3F988D8651E3EB45C4F3B6F41D4373B4 sha1 7DBA810528A861682197603ABEEDB08631914055 flags verified ) + rom ( name "Incredibili, Gli - Una 'Normale' Famiglia di Supereroi (Italy).gba" size 8388608 crc 615839ef sha1 520AEC2F41CD15F1307CC2146A47EC6095B78B64 ) ) game ( name "Incredible Hulk, The (USA)" description "Incredible Hulk, The (USA)" - rom ( name "Incredible Hulk, The (USA).gba" size 8388608 crc 0B978DFA md5 3B953C03DCC4276324B9BF95624F1C6E sha1 7076EC6B68098B9ACE9D8E5F4A6BBFDC66C32E4E ) + rom ( name "Incredible Hulk, The (USA).gba" size 8388608 crc 0b978dfa sha1 7076EC6B68098B9ACE9D8E5F4A6BBFDC66C32E4E ) +) + +game ( + name "Incredible Hulk, The (Europe) (En,Fr,De,Es,It)" + description "Incredible Hulk, The (Europe) (En,Fr,De,Es,It)" + rom ( name "Incredible Hulk, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 7e00422c sha1 7DBA810528A861682197603ABEEDB08631914055 flags verified ) ) game ( name "Incredibles, The (USA, Europe)" description "Incredibles, The (USA, Europe)" - rom ( name "Incredibles, The (USA, Europe).gba" size 8388608 crc 194D5F6C md5 97CC2AEB06142AEDC38B672E90E04A11 sha1 091F81AB8BDB4032B772B94E14292B9A2CDE5151 flags verified ) + rom ( name "Incredibles, The (USA, Europe).gba" size 8388608 crc 194d5f6c sha1 091F81AB8BDB4032B772B94E14292B9A2CDE5151 flags verified ) ) game ( name "Incredibles, The (Europe) (Fr,Nl)" description "Incredibles, The (Europe) (Fr,Nl)" - rom ( name "Incredibles, The (Europe) (Fr,Nl).gba" size 8388608 crc 77CBDC3B md5 30F5A0D49AA5672707AC5751EBD1996E sha1 2306008618B5E4B61EAC29A882F31FD11FDE02E9 ) + rom ( name "Incredibles, The (Europe) (Fr,Nl).gba" size 8388608 crc 77cbdc3b sha1 2306008618B5E4B61EAC29A882F31FD11FDE02E9 flags verified ) ) game ( name "Incredibles, The - Rise of the Underminer (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "Incredibles, The - Rise of the Underminer (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "Incredibles, The - Rise of the Underminer (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 8388608 crc 096F98B6 md5 3908543E922F3185CD0B73CB774E0738 sha1 0798223E4906584080042081AC50070BE378E82A ) + rom ( name "Incredibles, The - Rise of the Underminer (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 8388608 crc 096f98b6 sha1 0798223E4906584080042081AC50070BE378E82A ) ) game ( name "Incredibles, The - Rise of the Underminer (USA, Europe)" description "Incredibles, The - Rise of the Underminer (USA, Europe)" - rom ( name "Incredibles, The - Rise of the Underminer (USA, Europe).gba" size 8388608 crc 2D806290 md5 50D0CA20B90C0B2E46FE5A33D9EA6D8B sha1 69352C762C306CE5EFBF4606E1FB9BB1BDE6189A flags verified ) + rom ( name "Incredibles, The - Rise of the Underminer (USA, Europe).gba" size 8388608 crc 2d806290 sha1 69352C762C306CE5EFBF4606E1FB9BB1BDE6189A flags verified ) ) game ( name "Increibles, Los (Spain)" description "Increibles, Los (Spain)" - rom ( name "Increibles, Los (Spain).gba" size 8388608 crc FC6CCADB md5 EDDB8663171073186D122638D4B27F82 sha1 C87047934AE328F52EF6B01083A57C65CBBAB514 ) + rom ( name "Increibles, Los (Spain).gba" size 8388608 crc fc6ccadb sha1 C87047934AE328F52EF6B01083A57C65CBBAB514 ) ) game ( name "Initial D - Another Stage (Japan)" description "Initial D - Another Stage (Japan)" - rom ( name "Initial D - Another Stage (Japan).gba" size 8388608 crc 23110A94 md5 EAD0C0D58712A968DB6FF1C2C08F6946 sha1 ABC8A136E00E38132BF07D38CF28E52A2719FAB9 ) + rom ( name "Initial D - Another Stage (Japan).gba" size 8388608 crc 23110a94 sha1 ABC8A136E00E38132BF07D38CF28E52A2719FAB9 ) ) game ( name "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 406AA0C6 md5 F291756B7731354C0D912E8D6337B7FE sha1 3A204EA887D9ED997486E2D649148FAA4F31C335 ) + rom ( name "Inspector Gadget - Advance Mission (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 406aa0c6 sha1 3A204EA887D9ED997486E2D649148FAA4F31C335 ) ) game ( name "Inspector Gadget - Advance Mission (USA)" description "Inspector Gadget - Advance Mission (USA)" - rom ( name "Inspector Gadget - Advance Mission (USA).gba" size 4194304 crc EF131209 md5 881DD5C2D845A8FEF7FC7BADCF47D617 sha1 86D4F46980AFD3A4627FB204910D36D592684C49 ) + rom ( name "Inspector Gadget - Advance Mission (USA).gba" size 4194304 crc ef131209 sha1 86D4F46980AFD3A4627FB204910D36D592684C49 ) ) game ( name "Inspector Gadget Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget Racing (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Inspector Gadget Racing (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc B0D1C070 md5 C462C94704A3FA26D104282105DDD6ED sha1 CBE2E199F888B713B90CD0A7D06F48B999469901 flags verified ) + rom ( name "Inspector Gadget Racing (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc b0d1c070 sha1 CBE2E199F888B713B90CD0A7D06F48B999469901 flags verified ) ) game ( name "International Karate Advanced (Europe)" description "International Karate Advanced (Europe)" - rom ( name "International Karate Advanced (Europe).gba" size 4194304 crc D33A14AF md5 D1A6C9F1C78F0DF5B1395E7E679A383A sha1 BB8B12D0A446ED097FB74A9A4496980FB65164EF flags verified ) + rom ( name "International Karate Advanced (Europe).gba" size 4194304 crc d33a14af sha1 BB8B12D0A446ED097FB74A9A4496980FB65164EF flags verified ) ) game ( name "International Karate Plus (Europe)" description "International Karate Plus (Europe)" - rom ( name "International Karate Plus (Europe).gba" size 4194304 crc 1052A0EA md5 F87C40E2BE0E80DDB2C044DF9FB97069 sha1 844395914641AF431C58BBE82AB2513C5F8A60CE ) + rom ( name "International Karate Plus (Europe).gba" size 4194304 crc 1052a0ea sha1 844395914641AF431C58BBE82AB2513C5F8A60CE flags verified ) ) game ( name "International Karate Plus (USA)" description "International Karate Plus (USA)" - rom ( name "International Karate Plus (USA).gba" size 4194304 crc 31C4F03B md5 CCE22F4507CEAB482392247B74A8B55A sha1 99075504699400430E9817FEB4192A6E153FBC9A ) + rom ( name "International Karate Plus (USA).gba" size 4194304 crc 31c4f03b sha1 99075504699400430E9817FEB4192A6E153FBC9A ) ) game ( name "International Superstar Soccer (Europe)" description "International Superstar Soccer (Europe)" - rom ( name "International Superstar Soccer (Europe).gba" size 8388608 crc 9989CE55 md5 76FF83E819C83F27F02FD4D59AF155D7 sha1 86F8398FEABA9CFA0890DEFCD5301F190807838B flags verified ) + rom ( name "International Superstar Soccer (Europe).gba" size 8388608 crc 9989ce55 sha1 86F8398FEABA9CFA0890DEFCD5301F190807838B flags verified ) ) game ( name "International Superstar Soccer Advance (Europe)" description "International Superstar Soccer Advance (Europe)" - rom ( name "International Superstar Soccer Advance (Europe).gba" size 8388608 crc 7EB2F6D6 md5 101B2628C6EABBB3CAA36A5DD9A309E5 sha1 B5D8A4CD3B092BF1E2AA480412E03D17B9E26F68 flags verified ) + rom ( name "International Superstar Soccer Advance (Europe).gba" size 8388608 crc 7eb2f6d6 sha1 B5D8A4CD3B092BF1E2AA480412E03D17B9E26F68 flags verified ) ) game ( name "Inukko Club (Japan)" description "Inukko Club (Japan)" - rom ( name "Inukko Club (Japan).gba" size 8388608 crc D473B3C1 md5 FE1693B0D503FF222EBC090AC3DAB920 sha1 A528926C4AFB55279170C2EDEA1B93691409F22F ) + rom ( name "Inukko Club (Japan).gba" size 8388608 crc d473b3c1 sha1 A528926C4AFB55279170C2EDEA1B93691409F22F ) ) game ( name "Inuyasha - Naraku no Wana! Mayoi no Mori no Shoutaijou (Japan)" description "Inuyasha - Naraku no Wana! Mayoi no Mori no Shoutaijou (Japan)" - rom ( name "Inuyasha - Naraku no Wana! Mayoi no Mori no Shoutaijou (Japan).gba" size 8388608 crc 8FCDF69C md5 99C318243F594C4D84A793519A50A679 sha1 DA013846964D3EA40B9FBFF4CF129BBE75697F30 ) + rom ( name "Inuyasha - Naraku no Wana! Mayoi no Mori no Shoutaijou (Japan).gba" size 8388608 crc 8fcdf69c sha1 DA013846964D3EA40B9FBFF4CF129BBE75697F30 ) ) game ( name "Invader (Europe)" description "Invader (Europe)" - rom ( name "Invader (Europe).gba" size 8388608 crc A94D6058 md5 4EB435C43D7955E680355B94A6D39433 sha1 7C05CBC3308492B408877D321943835BB00AB43A flags verified ) + rom ( name "Invader (Europe).gba" size 8388608 crc a94d6058 sha1 7C05CBC3308492B408877D321943835BB00AB43A flags verified ) ) game ( name "Invincible Iron Man, The (USA, Europe)" description "Invincible Iron Man, The (USA, Europe)" - rom ( name "Invincible Iron Man, The (USA, Europe).gba" size 4194304 crc 39A31B68 md5 C3CAEECE33E072B537CB07670B4610EB sha1 8A7594FB7DE206CFF917DDD31E005AC24330552B ) + rom ( name "Invincible Iron Man, The (USA, Europe).gba" size 4194304 crc 39a31b68 sha1 8A7594FB7DE206CFF917DDD31E005AC24330552B ) +) + +game ( + name "iQue Reader (China)" + description "iQue Reader (China)" + rom ( name "iQue Reader (China).gba" size 4194304 crc 8724750b sha1 2192E37D069AD42834F124C66DE2DF278D330CA2 flags verified ) +) + +game ( + name "iQue Video & Audio (China)" + description "iQue Video & Audio (China)" + rom ( name "iQue Video & Audio (China).gba" size 16777216 crc 92852a72 sha1 79C7494C116E276F85A5F62D59F3A4588BD88391 flags verified ) ) game ( name "Iridion 3D (USA, Europe)" description "Iridion 3D (USA, Europe)" - rom ( name "Iridion 3D (USA, Europe).gba" size 4194304 crc 34189E74 md5 F88DF40FEDB9D31A6E59DBA4A9BE1B2A sha1 4C9E0F52078D73D5843487DE9EAB4462C5C153F7 flags verified ) + rom ( name "Iridion 3D (USA, Europe).gba" size 4194304 crc 34189e74 sha1 4C9E0F52078D73D5843487DE9EAB4462C5C153F7 flags verified ) ) game ( name "Iridion II (USA)" description "Iridion II (USA)" - rom ( name "Iridion II (USA).gba" size 8388608 crc DD8A7104 md5 553E8C9A80190617EC13FA2A06487F2D sha1 3D9A8AF95A636BE82E1AF184DF2110F20E170824 ) + rom ( name "Iridion II (USA).gba" size 8388608 crc dd8a7104 sha1 3D9A8AF95A636BE82E1AF184DF2110F20E170824 ) ) game ( name "Iridion II (Europe) (En,Fr,De)" description "Iridion II (Europe) (En,Fr,De)" - rom ( name "Iridion II (Europe) (En,Fr,De).gba" size 8388608 crc 57930C6A md5 BA5048BBFB02EBE3874B8CE1B6318CE4 sha1 661442C24404CC0727E4343F9CE570C87C797661 ) + rom ( name "Iridion II (Europe) (En,Fr,De).gba" size 8388608 crc 57930c6a sha1 661442C24404CC0727E4343F9CE570C87C797661 ) ) game ( name "Iron Kid (Korea)" description "Iron Kid (Korea)" - rom ( name "Iron Kid (Korea).gba" size 16777216 crc 326E7A8E md5 6D7D6CD0D1BDE4855B230AD510E16771 sha1 2A6F502D3F1F1C2507104A08563D1623B58ADF9D ) + rom ( name "Iron Kid (Korea).gba" size 16777216 crc 326e7a8e sha1 2A6F502D3F1F1C2507104A08563D1623B58ADF9D ) +) + +game ( + name "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" + description "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" + rom ( name "Island Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 3beb5446 sha1 4EEC876994BDEA873188FE10033C48C924D129EC flags verified ) ) game ( name "Isseki Hatchou - Kore 1ppon de 8shurui! (Japan)" description "Isseki Hatchou - Kore 1ppon de 8shurui! (Japan)" - rom ( name "Isseki Hatchou - Kore 1ppon de 8shurui! (Japan).gba" size 4194304 crc CB5EFF64 md5 677BF7D4F8788FA5C505D5DD79309D69 sha1 DEC72783BA3DCCF60AFF91B880DC6EE4E77EC644 ) + rom ( name "Isseki Hatchou - Kore 1ppon de 8shurui! (Japan).gba" size 4194304 crc cb5eff64 sha1 DEC72783BA3DCCF60AFF91B880DC6EE4E77EC644 ) ) game ( name "It's Mr. Pants (USA, Europe)" description "It's Mr. Pants (USA, Europe)" - rom ( name "It's Mr. Pants (USA, Europe).gba" size 4194304 crc 757A4EFB md5 86F3A374AF80E633531C538D9AEAF396 sha1 C49742F964A698CCCE0520E24368A9D425A29B4D flags verified ) + rom ( name "It's Mr. Pants (USA, Europe).gba" size 4194304 crc 757a4efb sha1 C49742F964A698CCCE0520E24368A9D425A29B4D flags verified ) ) game ( name "J.League Pocket (Japan)" description "J.League Pocket (Japan)" - rom ( name "J.League Pocket (Japan).gba" size 8388608 crc 51BE73B8 md5 A0EF6D6F6346D5FA888348012EB4F6C2 sha1 B4CD024B10D740F3525DDDFBCC613C04A8D4C166 ) + rom ( name "J.League Pocket (Japan).gba" size 8388608 crc 51be73b8 sha1 B4CD024B10D740F3525DDDFBCC613C04A8D4C166 ) +) + +game ( + name "J.League Pocket (Japan) (Rev 1)" + description "J.League Pocket (Japan) (Rev 1)" + rom ( name "J.League Pocket (Japan) (Rev 1).gba" size 8388608 crc 0524e9ef sha1 64C6B3F0113D91DAF41E63B2755D26B9ED0CEA3A flags verified ) ) game ( name "J.League Pocket 2 (Japan)" description "J.League Pocket 2 (Japan)" - rom ( name "J.League Pocket 2 (Japan).gba" size 8388608 crc DC7D2E4A md5 5479685BBB7459BA67159CF430C4274B sha1 A9BD4F154438D440D7C3DCD1DA1AF14C37B0AD12 ) + rom ( name "J.League Pocket 2 (Japan).gba" size 8388608 crc dc7d2e4a sha1 A9BD4F154438D440D7C3DCD1DA1AF14C37B0AD12 ) ) game ( name "J.League Pro Soccer Club o Tsukurou! Advance (Japan)" description "J.League Pro Soccer Club o Tsukurou! Advance (Japan)" - rom ( name "J.League Pro Soccer Club o Tsukurou! Advance (Japan).gba" size 8388608 crc 8BC59927 md5 02472E367D05ECA0ED719B865B5D30F4 sha1 5D6036BD565FD113C847F0B3BE6B9940DDABD492 ) + rom ( name "J.League Pro Soccer Club o Tsukurou! Advance (Japan).gba" size 8388608 crc 8bc59927 sha1 5D6036BD565FD113C847F0B3BE6B9940DDABD492 ) ) game ( name "J.League Winning Eleven Advance 2002 (Japan)" description "J.League Winning Eleven Advance 2002 (Japan)" - rom ( name "J.League Winning Eleven Advance 2002 (Japan).gba" size 8388608 crc AEE73FE7 md5 917FDBC9CB798C6EE3831A27E6A2AF6A sha1 69291E5D230A8663C1FFD0298430651E64ACAFDE ) + rom ( name "J.League Winning Eleven Advance 2002 (Japan).gba" size 8388608 crc aee73fe7 sha1 69291E5D230A8663C1FFD0298430651E64ACAFDE ) ) game ( - name "Jackie Chan Adventures - Legend of the Darkhand (USA, Europe)" - description "Jackie Chan Adventures - Legend of the Darkhand (USA, Europe)" - rom ( name "Jackie Chan Adventures - Legend of the Darkhand (USA, Europe).gba" size 4194304 crc 13247954 md5 863BB2F057959EC7B21AA0174C817FA9 sha1 F6F5C7BC566269530DDB13B76FC3D05CC22C11E3 flags verified ) + name "Jackie Chan Adventures - Legend of the Dark Hand (USA, Europe)" + description "Jackie Chan Adventures - Legend of the Dark Hand (USA, Europe)" + rom ( name "Jackie Chan Adventures - Legend of the Dark Hand (USA, Europe).gba" size 4194304 crc 13247954 sha1 F6F5C7BC566269530DDB13B76FC3D05CC22C11E3 flags verified ) ) game ( name "Jajamaru Jr. Denshouki - Jalecolle mo Arisourou (Japan)" description "Jajamaru Jr. Denshouki - Jalecolle mo Arisourou (Japan)" - rom ( name "Jajamaru Jr. Denshouki - Jalecolle mo Arisourou (Japan).gba" size 4194304 crc 8CE6BCE8 md5 74965E4A985F8A27AE12D526C032DAEA sha1 6FF9509540E71155E16B0F4FA5EE70582958DB6C ) + rom ( name "Jajamaru Jr. Denshouki - Jalecolle mo Arisourou (Japan).gba" size 4194304 crc 8ce6bce8 sha1 6FF9509540E71155E16B0F4FA5EE70582958DB6C ) ) game ( name "James Pond - Codename Robocod (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "James Pond - Codename Robocod (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "James Pond - Codename Robocod (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc 31081996 md5 36C2FF60E03639DCEF8E67D9E2AA602B sha1 9430AB35EC9D54E0D6FBC310BC9CF42EDA4A627A flags verified ) + rom ( name "James Pond - Codename Robocod (Europe) (En,Fr,De,Es,It,Nl,Pt).gba" size 4194304 crc 31081996 sha1 9430AB35EC9D54E0D6FBC310BC9CF42EDA4A627A flags verified ) ) game ( name "James Pond - Codename Robocod (USA) (En,Fr,Es,Pt)" description "James Pond - Codename Robocod (USA) (En,Fr,Es,Pt)" - rom ( name "James Pond - Codename Robocod (USA) (En,Fr,Es,Pt).gba" size 4194304 crc EB25BB5B md5 4C2CDF7E90226F7EAD473B1A2C67FBE6 sha1 9279A7C128DE12648A8180A3DCD1B53E95B1EE70 ) + rom ( name "James Pond - Codename Robocod (USA) (En,Fr,Es,Pt).gba" size 4194304 crc eb25bb5b sha1 9279A7C128DE12648A8180A3DCD1B53E95B1EE70 ) ) game ( name "Jazz Jackrabbit (USA, Europe)" description "Jazz Jackrabbit (USA, Europe)" - rom ( name "Jazz Jackrabbit (USA, Europe).gba" size 4194304 crc 948531D4 md5 693BBCAB772317E7E295A2B52DCA175D sha1 9FB012B46350615CFA4DD0FC7D11FC21903D39E0 flags verified ) + rom ( name "Jazz Jackrabbit (USA, Europe).gba" size 4194304 crc 948531d4 sha1 9FB012B46350615CFA4DD0FC7D11FC21903D39E0 flags verified ) ) game ( name "Jet Grind Radio (USA)" description "Jet Grind Radio (USA)" - rom ( name "Jet Grind Radio (USA).gba" size 8388608 crc AE4142B5 md5 FF50E8973ADF12604CA70E15ACB108DB sha1 8F10E828DFE6387BE8A1BADB1104698C54163411 ) + rom ( name "Jet Grind Radio (USA).gba" size 8388608 crc ae4142b5 sha1 8F10E828DFE6387BE8A1BADB1104698C54163411 ) ) game ( name "Jet Set Radio (Europe)" description "Jet Set Radio (Europe)" - rom ( name "Jet Set Radio (Europe).gba" size 8388608 crc 716DC010 md5 7506C14AF1C1E6B6E64A3AC393C4004D sha1 4210E8A4225A076C01C39239941E2AFF1C056F71 flags verified ) + rom ( name "Jet Set Radio (Europe).gba" size 8388608 crc 716dc010 sha1 4210E8A4225A076C01C39239941E2AFF1C056F71 flags verified ) ) game ( name "JGTO Kounin Golf Master - Japan Golf Tour Game (Japan)" description "JGTO Kounin Golf Master - Japan Golf Tour Game (Japan)" - rom ( name "JGTO Kounin Golf Master - Japan Golf Tour Game (Japan).gba" size 8388608 crc 0BA5809F md5 4AE4E0D477327CE2C1E79373E1B1CA70 sha1 E30DDA7E9141C4F06EC1494E3EADC9B3244E341D ) + rom ( name "JGTO Kounin Golf Master - Japan Golf Tour Game (Japan).gba" size 8388608 crc 0ba5809f sha1 E30DDA7E9141C4F06EC1494E3EADC9B3244E341D ) ) game ( name "JGTO Kounin Golf Master Mobile - Japan Golf Tour Game (Japan)" description "JGTO Kounin Golf Master Mobile - Japan Golf Tour Game (Japan)" - rom ( name "JGTO Kounin Golf Master Mobile - Japan Golf Tour Game (Japan).gba" size 8388608 crc B863DAE1 md5 D4E09DC235EC13E6926C5338147E350C sha1 975CFF59783CD8F5EC30CAAA9E6BEF130A6E3529 ) + rom ( name "JGTO Kounin Golf Master Mobile - Japan Golf Tour Game (Japan).gba" size 8388608 crc b863dae1 sha1 975CFF59783CD8F5EC30CAAA9E6BEF130A6E3529 ) ) game ( name "Jikkyou World Soccer Pocket (Japan)" description "Jikkyou World Soccer Pocket (Japan)" - rom ( name "Jikkyou World Soccer Pocket (Japan).gba" size 8388608 crc 8BD96DB9 md5 8A8D50C9710AD287D2691546CF40348F sha1 433F41B3C553AD9F943D9FCD2FC37ACFE564241F ) + rom ( name "Jikkyou World Soccer Pocket (Japan).gba" size 8388608 crc 8bd96db9 sha1 433F41B3C553AD9F943D9FCD2FC37ACFE564241F ) ) game ( name "Jikkyou World Soccer Pocket 2 (Japan)" description "Jikkyou World Soccer Pocket 2 (Japan)" - rom ( name "Jikkyou World Soccer Pocket 2 (Japan).gba" size 8388608 crc B80AA966 md5 36663F8C81FC13E1F3EB739292AF7941 sha1 C1354FA67E2B5BDBE647EB60D301C14392ED2B4D ) + rom ( name "Jikkyou World Soccer Pocket 2 (Japan).gba" size 8388608 crc b80aa966 sha1 C1354FA67E2B5BDBE647EB60D301C14392ED2B4D ) ) game ( name "Jimmy Neutron Boy Genius (USA)" description "Jimmy Neutron Boy Genius (USA)" - rom ( name "Jimmy Neutron Boy Genius (USA).gba" size 4194304 crc D3EE0C51 md5 2ACD2B101E2F03A3FB95ED41B187D5EC sha1 31ED7659E2E072D1C00BAF95C0EE9C770E949900 ) + rom ( name "Jimmy Neutron Boy Genius (USA).gba" size 4194304 crc d3ee0c51 sha1 31ED7659E2E072D1C00BAF95C0EE9C770E949900 flags verified ) ) game ( name "Jimmy Neutron Boy Genius (Europe) (En,Fr,De,Es)" description "Jimmy Neutron Boy Genius (Europe) (En,Fr,De,Es)" - rom ( name "Jimmy Neutron Boy Genius (Europe) (En,Fr,De,Es).gba" size 4194304 crc A9423234 md5 8002D7D8251F8A200A9D50F107D48FFD sha1 0923B6186739BA697627822EBCE04EDAA721A70F ) + rom ( name "Jimmy Neutron Boy Genius (Europe) (En,Fr,De,Es).gba" size 4194304 crc a9423234 sha1 0923B6186739BA697627822EBCE04EDAA721A70F ) ) game ( name "Jimmy Neutron un Garcon Genial - L'Attaque des Twonkies (France)" description "Jimmy Neutron un Garcon Genial - L'Attaque des Twonkies (France)" - rom ( name "Jimmy Neutron un Garcon Genial - L'Attaque des Twonkies (France).gba" size 4194304 crc 33816E51 md5 54D23B56027BF5555FDAC1D11F3BB2C3 sha1 32D8CE89D3D6E7A24B656FBC46856876732C74EA ) + rom ( name "Jimmy Neutron un Garcon Genial - L'Attaque des Twonkies (France).gba" size 4194304 crc 33816e51 sha1 32D8CE89D3D6E7A24B656FBC46856876732C74EA ) ) game ( name "Jimmy Neutron vs. Jimmy Negatron (Germany) (Beta)" description "Jimmy Neutron vs. Jimmy Negatron (Germany) (Beta)" - rom ( name "Jimmy Neutron vs. Jimmy Negatron (Germany) (Beta).gba" size 4157240 crc 220CCF25 md5 451AD2324CCE205BAB6913ABD02E5F1E sha1 C6D06002F71B3023B9D93A5D237B289CEC51242E ) + rom ( name "Jimmy Neutron vs. Jimmy Negatron (Germany) (Beta).gba" size 4157240 crc 220ccf25 sha1 C6D06002F71B3023B9D93A5D237B289CEC51242E ) ) game ( name "Jinsei Game Advance (Japan)" description "Jinsei Game Advance (Japan)" - rom ( name "Jinsei Game Advance (Japan).gba" size 4194304 crc 84A4A304 md5 859CB3DD653228060CC3AAE3D1A39333 sha1 FBE55805ADF5343B9CA6E941D513478D02262FA5 ) + rom ( name "Jinsei Game Advance (Japan).gba" size 4194304 crc 84a4a304 sha1 FBE55805ADF5343B9CA6E941D513478D02262FA5 ) ) game ( name "Jissen Pachi-Slot Hisshouhou! - Juuou Advance (Japan)" description "Jissen Pachi-Slot Hisshouhou! - Juuou Advance (Japan)" - rom ( name "Jissen Pachi-Slot Hisshouhou! - Juuou Advance (Japan).gba" size 4194304 crc 07195201 md5 158C0792EB9B050DC8DA7AB58ED2DF95 sha1 451B05CCC409B44E3C8060EF14021116103D664B ) + rom ( name "Jissen Pachi-Slot Hisshouhou! - Juuou Advance (Japan).gba" size 4194304 crc 07195201 sha1 451B05CCC409B44E3C8060EF14021116103D664B ) ) game ( name "Jisu F-Zero Weilai Saiche (China)" description "Jisu F-Zero Weilai Saiche (China)" - rom ( name "Jisu F-Zero Weilai Saiche (China).gba" size 4194304 crc 0E5C38B7 md5 C76CDEB30713CA9199788CB9AC95EEAC sha1 2BF6622398655A16A5D6B3D94241B72E63A71DE9 ) + rom ( name "Jisu F-Zero Weilai Saiche (China).gba" size 4194304 crc 0e5c38b7 sha1 2BF6622398655A16A5D6B3D94241B72E63A71DE9 ) ) game ( - name "Jonny Moseley Mad Trix (USA) (En,Fr,De,Es,It)" - description "Jonny Moseley Mad Trix (USA) (En,Fr,De,Es,It)" - rom ( name "Jonny Moseley Mad Trix (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 96488632 md5 08A64AC42E0AC926269FD2C469F7C074 sha1 6ECF01DC70782184E4E45E4DB280FB24F840FD6F flags verified ) + name "Jonny Moseley Mad Trix (USA, Europe) (En,Fr,De,Es,It)" + description "Jonny Moseley Mad Trix (USA, Europe) (En,Fr,De,Es,It)" + rom ( name "Jonny Moseley Mad Trix (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 96488632 sha1 6ECF01DC70782184E4E45E4DB280FB24F840FD6F flags verified ) ) game ( name "Juka and the Monophonic Menace (Europe) (En,Fr,De,Es,It)" description "Juka and the Monophonic Menace (Europe) (En,Fr,De,Es,It)" - rom ( name "Juka and the Monophonic Menace (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc E62BFFEB md5 7D098E6EAB2EE1CFEBDB12E60AC609BE sha1 EA476896E93DB126EA275C5240FEC3AEEC031DB0 flags verified ) + rom ( name "Juka and the Monophonic Menace (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc e62bffeb sha1 EA476896E93DB126EA275C5240FEC3AEEC031DB0 flags verified ) ) game ( name "Juka and the Monophonic Menace (USA) (En,Fr,Es)" description "Juka and the Monophonic Menace (USA) (En,Fr,Es)" - rom ( name "Juka and the Monophonic Menace (USA) (En,Fr,Es).gba" size 16777216 crc 0C04A2F9 md5 86F5DA57EC34ECF1C2710BEFA3D2C5DE sha1 3FD9AC2AF773A2D47EB024225E78C22CAFCAC9FD ) + rom ( name "Juka and the Monophonic Menace (USA) (En,Fr,Es).gba" size 16777216 crc 0c04a2f9 sha1 3FD9AC2AF773A2D47EB024225E78C22CAFCAC9FD ) ) game ( name "Jungle Book 2, The (Europe) (En,Fr,De,Es,It,Nl)" description "Jungle Book 2, The (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Jungle Book 2, The (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 9898258B md5 1A2C640094216F9D15DC7A2AC3B8C1E0 sha1 4DD4FBF9ECD755C37DFB5F6EB0094873C72AABC2 ) + rom ( name "Jungle Book 2, The (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 9898258b sha1 4DD4FBF9ECD755C37DFB5F6EB0094873C72AABC2 flags verified ) ) game ( name "Jungle Book, The (USA) (En,Fr,De,Es,It,Nl)" description "Jungle Book, The (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Jungle Book, The (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc E9A21637 md5 6073270FD16BFBAA50D87DD1204BB607 sha1 5E6BE87FEEDC1941C35BD92CC972316CCF325330 ) + rom ( name "Jungle Book, The (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc e9a21637 sha1 5E6BE87FEEDC1941C35BD92CC972316CCF325330 ) ) game ( name "Jurassic Park III - Advanced Action (Japan)" description "Jurassic Park III - Advanced Action (Japan)" - rom ( name "Jurassic Park III - Advanced Action (Japan).gba" size 8388608 crc D18F75E5 md5 5A84A1D3E9DB2C0A77B66B71F62D5120 sha1 0D2B1011AFA1124ACEF47E8D987DCD35FC3025D4 ) + rom ( name "Jurassic Park III - Advanced Action (Japan).gba" size 8388608 crc d18f75e5 sha1 0D2B1011AFA1124ACEF47E8D987DCD35FC3025D4 ) ) game ( name "Jurassic Park III - Dino Attack (Europe) (En,Fr,De,Es,It)" description "Jurassic Park III - Dino Attack (Europe) (En,Fr,De,Es,It)" - rom ( name "Jurassic Park III - Dino Attack (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc DDCEB011 md5 875C78F20AB82D8B8E72B18D4B1FE4CC sha1 71632636A8D40762BBFDCF8DEEA667629CC9E0B9 ) + rom ( name "Jurassic Park III - Dino Attack (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ddceb011 sha1 71632636A8D40762BBFDCF8DEEA667629CC9E0B9 ) ) game ( name "Jurassic Park III - Island Attack (USA)" description "Jurassic Park III - Island Attack (USA)" - rom ( name "Jurassic Park III - Island Attack (USA).gba" size 8388608 crc 1E7048D2 md5 CCAE308BACA9BAECABA1AB670DCC27C8 sha1 493349429D78EA040204F2A74526E790F3092DC2 ) + rom ( name "Jurassic Park III - Island Attack (USA).gba" size 8388608 crc 1e7048d2 sha1 493349429D78EA040204F2A74526E790F3092DC2 ) ) game ( name "Jurassic Park III - Kyouryuu ni Ainiikou! (Japan)" description "Jurassic Park III - Kyouryuu ni Ainiikou! (Japan)" - rom ( name "Jurassic Park III - Kyouryuu ni Ainiikou! (Japan).gba" size 4194304 crc F2BF8990 md5 19371AD5F797B26C5E841992339AD37D sha1 8C8115178CAEBCAB3514601974682D3229CA06E6 ) + rom ( name "Jurassic Park III - Kyouryuu ni Ainiikou! (Japan).gba" size 4194304 crc f2bf8990 sha1 8C8115178CAEBCAB3514601974682D3229CA06E6 ) ) game ( name "Jurassic Park III - Park Builder (Europe) (En,Fr,De,Es,It)" description "Jurassic Park III - Park Builder (Europe) (En,Fr,De,Es,It)" - rom ( name "Jurassic Park III - Park Builder (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 51061EFF md5 F8A7B028F2EDCFBB565EF88BB321C665 sha1 090257C3B30BB46D424258D12B542691A7FD2F62 ) + rom ( name "Jurassic Park III - Park Builder (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 51061eff sha1 090257C3B30BB46D424258D12B542691A7FD2F62 flags verified ) ) game ( name "Jurassic Park III - Park Builder (USA)" description "Jurassic Park III - Park Builder (USA)" - rom ( name "Jurassic Park III - Park Builder (USA).gba" size 4194304 crc EDDDCF19 md5 72018660652B494D553D41D5B1767F7E sha1 8A6922136F7C3E760791A67C2519E5DAC07EA837 ) + rom ( name "Jurassic Park III - Park Builder (USA).gba" size 4194304 crc edddcf19 sha1 8A6922136F7C3E760791A67C2519E5DAC07EA837 ) ) game ( name "Jurassic Park III - The DNA Factor (USA)" description "Jurassic Park III - The DNA Factor (USA)" - rom ( name "Jurassic Park III - The DNA Factor (USA).gba" size 8388608 crc F93DCC2E md5 D596B05B4F52D2880F36DB3E7EC9A8E5 sha1 AB73F66ABD86F53B24661F7319114D01C7354057 ) + rom ( name "Jurassic Park III - The DNA Factor (USA).gba" size 8388608 crc f93dcc2e sha1 AB73F66ABD86F53B24661F7319114D01C7354057 ) ) game ( name "Jurassic Park III - The DNA Factor (Europe) (En,Fr,De,Es,It)" description "Jurassic Park III - The DNA Factor (Europe) (En,Fr,De,Es,It)" - rom ( name "Jurassic Park III - The DNA Factor (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc FE89C986 md5 534B46BBA804C9A81E9C20472C292E87 sha1 54AEEC4DEC1601E85471B0D92F5158FE36AE4429 flags verified ) + rom ( name "Jurassic Park III - The DNA Factor (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc fe89c986 sha1 54AEEC4DEC1601E85471B0D92F5158FE36AE4429 flags verified ) ) game ( name "Jurassic Park III - Ushinawareta Idenshi (Japan)" description "Jurassic Park III - Ushinawareta Idenshi (Japan)" - rom ( name "Jurassic Park III - Ushinawareta Idenshi (Japan).gba" size 8388608 crc AB6786DD md5 EB0F9589F3040F59A944B0831469AE1C sha1 4603584042052A4B7C3BAFAA3CC0DE9D1F225269 ) + rom ( name "Jurassic Park III - Ushinawareta Idenshi (Japan).gba" size 8388608 crc ab6786dd sha1 4603584042052A4B7C3BAFAA3CC0DE9D1F225269 ) ) game ( name "Jurassic Park Institute Tour - Dinosaur Rescue (Japan)" description "Jurassic Park Institute Tour - Dinosaur Rescue (Japan)" - rom ( name "Jurassic Park Institute Tour - Dinosaur Rescue (Japan).gba" size 4194304 crc 7C75555E md5 8CE34B50E1B658B4C69E6BA4A100F71E sha1 318A581595E0571EFF70BAED3E0D86B7DCD70242 ) + rom ( name "Jurassic Park Institute Tour - Dinosaur Rescue (Japan).gba" size 4194304 crc 7c75555e sha1 318A581595E0571EFF70BAED3E0D86B7DCD70242 ) ) game ( - name "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It)" - description "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It)" - rom ( name "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc D71C4382 md5 8D2F6A78E9CF3210AE22C5F111624E55 sha1 7385169111585230BA62007397802A7197653447 ) -) - -game ( - name "Justice League - Injustice for All (USA) (Beta)" - description "Justice League - Injustice for All (USA) (Beta)" - rom ( name "Justice League - Injustice for All (USA) (Beta).gba" size 8388608 crc C41081CF md5 A1B0A5BA65F8287F7474E984BBFE8561 sha1 E3302C2AA5CD14BF5546A3069BC6757363EE38B4 ) + name "Justice League - Chronicles (USA)" + description "Justice League - Chronicles (USA)" + rom ( name "Justice League - Chronicles (USA).gba" size 8388608 crc 07090f67 sha1 F14A43B51D27AB5CCA63AB71B0FDACB0AFA1DEB9 ) ) game ( name "Justice League - Injustice for All (USA)" description "Justice League - Injustice for All (USA)" - rom ( name "Justice League - Injustice for All (USA).gba" size 8388608 crc B2477B72 md5 B2C954CCF09E408C55886B6686D39C6F sha1 F7D774F3D1F1436C18B044C65E574DC327AD6437 ) + rom ( name "Justice League - Injustice for All (USA).gba" size 8388608 crc b2477b72 sha1 F7D774F3D1F1436C18B044C65E574DC327AD6437 ) ) game ( - name "Justice League Chronicles (USA)" - description "Justice League Chronicles (USA)" - rom ( name "Justice League Chronicles (USA).gba" size 8388608 crc 07090F67 md5 1B953A635C3B51AECC8D74A5DEE826CD sha1 F14A43B51D27AB5CCA63AB71B0FDACB0AFA1DEB9 ) + name "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It)" + description "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It)" + rom ( name "Justice League - Injustice for All (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d71c4382 sha1 7385169111585230BA62007397802A7197653447 ) +) + +game ( + name "Justice League - Injustice for All (USA) (Beta)" + description "Justice League - Injustice for All (USA) (Beta)" + rom ( name "Justice League - Injustice for All (USA) (Beta).gba" size 8388608 crc c41081cf sha1 E3302C2AA5CD14BF5546A3069BC6757363EE38B4 ) ) game ( name "Justice League Heroes - The Flash (USA)" description "Justice League Heroes - The Flash (USA)" - rom ( name "Justice League Heroes - The Flash (USA).gba" size 8388608 crc 87A4D12C md5 61755FB44DA912FBA53F41DBCD41F81F sha1 7E8AFCEFEF6E726838921342326AEE74D5DE6E1F ) + rom ( name "Justice League Heroes - The Flash (USA).gba" size 8388608 crc 87a4d12c sha1 7E8AFCEFEF6E726838921342326AEE74D5DE6E1F ) ) game ( name "Justice League Heroes - The Flash (Europe) (En,Fr,De,Es,It)" description "Justice League Heroes - The Flash (Europe) (En,Fr,De,Es,It)" - rom ( name "Justice League Heroes - The Flash (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ACB22FFF md5 A57DD211881C6FBB7B92487AB6E3B9AF sha1 6E5AFA804B5C195F9E012862D2AF42C0D4950593 flags verified ) + rom ( name "Justice League Heroes - The Flash (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc acb22fff sha1 6E5AFA804B5C195F9E012862D2AF42C0D4950593 flags verified ) ) game ( name "K-1 Pocket Grand Prix (Japan)" description "K-1 Pocket Grand Prix (Japan)" - rom ( name "K-1 Pocket Grand Prix (Japan).gba" size 4194304 crc FBDD4384 md5 E4DE91DF422CA4C1B881B9B6288172BD sha1 E1114ED7A3AF288733C5D3E8DD038713CB7FF8D2 ) + rom ( name "K-1 Pocket Grand Prix (Japan).gba" size 4194304 crc fbdd4384 sha1 E1114ED7A3AF288733C5D3E8DD038713CB7FF8D2 ) ) game ( name "K-1 Pocket Grand Prix 2 (Japan)" description "K-1 Pocket Grand Prix 2 (Japan)" - rom ( name "K-1 Pocket Grand Prix 2 (Japan).gba" size 8388608 crc 19FDE4C8 md5 56AC080C6BB6ECBF8F8C052D29CA534C sha1 4901C3426D12ABE6257A300E742CA9AC2E9565A6 ) + rom ( name "K-1 Pocket Grand Prix 2 (Japan).gba" size 8388608 crc 19fde4c8 sha1 4901C3426D12ABE6257A300E742CA9AC2E9565A6 ) ) game ( name "Kaeru B Back (Japan)" description "Kaeru B Back (Japan)" - rom ( name "Kaeru B Back (Japan).gba" size 8388608 crc DE5987BD md5 5D71F1153E7DE86254234662770FB007 sha1 94BAD08770AC334DD713F960B7A455CE9F7EA276 ) + rom ( name "Kaeru B Back (Japan).gba" size 8388608 crc de5987bd sha1 94BAD08770AC334DD713F960B7A455CE9F7EA276 ) ) game ( name "Kaiketsu Zorori to Mahou no Yuuenchi - Ohimesama o Sukue! (Japan)" description "Kaiketsu Zorori to Mahou no Yuuenchi - Ohimesama o Sukue! (Japan)" - rom ( name "Kaiketsu Zorori to Mahou no Yuuenchi - Ohimesama o Sukue! (Japan).gba" size 4194304 crc 259CDD6F md5 EA6434C2B4B22873EFA5166D3EE086FB sha1 03953917BEAD3D30BA63676565CCB854008EF8DA flags verified ) + rom ( name "Kaiketsu Zorori to Mahou no Yuuenchi - Ohimesama o Sukue! (Japan).gba" size 4194304 crc 259cdd6f sha1 03953917BEAD3D30BA63676565CCB854008EF8DA flags verified ) ) game ( name "Kaisertal - Fight the Necronis War (Europe) (Demo)" description "Kaisertal - Fight the Necronis War (Europe) (Demo)" - rom ( name "Kaisertal - Fight the Necronis War (Europe) (Demo).gba" size 8388608 crc 62992510 md5 BDCE643A2C1162ADD50AA14FD89016C3 sha1 DB9C0819B6413D76085AC5E814953F889ABCB3AB ) + rom ( name "Kaisertal - Fight the Necronis War (Europe) (Demo).gba" size 8388608 crc 62992510 sha1 DB9C0819B6413D76085AC5E814953F889ABCB3AB ) ) game ( name "Kamaitachi no Yoru Advance (Japan)" description "Kamaitachi no Yoru Advance (Japan)" - rom ( name "Kamaitachi no Yoru Advance (Japan).gba" size 16777216 crc 82B4F3FA md5 D969B50D20655BFFB3042BAFBEFFE654 sha1 590C8E8135D1F2FB70AB6A1FCC18239CA93BD0CC ) + rom ( name "Kamaitachi no Yoru Advance (Japan).gba" size 16777216 crc 82b4f3fa sha1 590C8E8135D1F2FB70AB6A1FCC18239CA93BD0CC flags verified ) ) game ( name "Kami no Kijutsu - Illusion of the Evil Eyes (Japan)" description "Kami no Kijutsu - Illusion of the Evil Eyes (Japan)" - rom ( name "Kami no Kijutsu - Illusion of the Evil Eyes (Japan).gba" size 8388608 crc 906C73AD md5 88D6EFF7CCAC003B7CCB50878AA8E209 sha1 D0E05926076426E26083F354D5922FF79AFE8E9C ) + rom ( name "Kami no Kijutsu - Illusion of the Evil Eyes (Japan).gba" size 8388608 crc 906c73ad sha1 D0E05926076426E26083F354D5922FF79AFE8E9C ) ) game ( name "Kao the Kangaroo (USA) (En,Fr,De,Es,It,Nl)" description "Kao the Kangaroo (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Kao the Kangaroo (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc F6667B3E md5 C6926D0BBBDBED3372E6FC01C81CD52B sha1 772D323145CB7707CB8792BDFD5C7EF5E1E27C46 ) + rom ( name "Kao the Kangaroo (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc f6667b3e sha1 772D323145CB7707CB8792BDFD5C7EF5E1E27C46 ) ) game ( name "Kao the Kangaroo (Europe) (En,Fr,De,Es,It,Nl)" description "Kao the Kangaroo (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Kao the Kangaroo (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 51E7522C md5 F9D25044142E0492F09C5E60A8DA0509 sha1 5A337FCC321EAA0C350644C026767824ADD338F3 ) + rom ( name "Kao the Kangaroo (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 51e7522c sha1 5A337FCC321EAA0C350644C026767824ADD338F3 flags verified ) ) game ( name "Kappa no Kai-kata - Kaatan Daibouken! (Japan)" description "Kappa no Kai-kata - Kaatan Daibouken! (Japan)" - rom ( name "Kappa no Kai-kata - Kaatan Daibouken! (Japan).gba" size 8388608 crc BF5F326E md5 0CC444D5FDDBD08AF0663E9FB8694780 sha1 40D84B808795B9E6EFED6685C2FF6EFDD295A412 ) + rom ( name "Kappa no Kai-kata - Kaatan Daibouken! (Japan).gba" size 8388608 crc bf5f326e sha1 40D84B808795B9E6EFED6685C2FF6EFDD295A412 ) ) game ( name "Karnaaj Rally (USA, Europe)" description "Karnaaj Rally (USA, Europe)" - rom ( name "Karnaaj Rally (USA, Europe).gba" size 8388608 crc 63FE3DFE md5 923A3437FCF84A5CA26158F7FAADA412 sha1 31BB73186BB98F3D2B80089490F2EECA2861FE5E flags verified ) + rom ( name "Karnaaj Rally (USA, Europe).gba" size 8388608 crc 63fe3dfe sha1 31BB73186BB98F3D2B80089490F2EECA2861FE5E flags verified ) ) game ( name "Kawa no Nushi Tsuri 3 & 4 (Japan)" description "Kawa no Nushi Tsuri 3 & 4 (Japan)" - rom ( name "Kawa no Nushi Tsuri 3 & 4 (Japan).gba" size 4194304 crc 4F09CA00 md5 44C0354067483B5378CB28EBB1E3476E sha1 043CCD64F04FFF2CD2F19BA679DC3C7A1250B97C ) + rom ( name "Kawa no Nushi Tsuri 3 & 4 (Japan).gba" size 4194304 crc 4f09ca00 sha1 043CCD64F04FFF2CD2F19BA679DC3C7A1250B97C ) ) game ( name "Kawa no Nushi Tsuri 5 - Fushigi no Mori kara (Japan)" description "Kawa no Nushi Tsuri 5 - Fushigi no Mori kara (Japan)" - rom ( name "Kawa no Nushi Tsuri 5 - Fushigi no Mori kara (Japan).gba" size 4194304 crc 4A8F2F62 md5 161ACF52BFEDB16060DC24183DB56D23 sha1 418D61DDD992CEEAA10A102DEAF9EB15A2FB7328 ) + rom ( name "Kawa no Nushi Tsuri 5 - Fushigi no Mori kara (Japan).gba" size 4194304 crc 4a8f2f62 sha1 418D61DDD992CEEAA10A102DEAF9EB15A2FB7328 ) ) game ( name "Kawaii Koinu Wonderful (Japan)" description "Kawaii Koinu Wonderful (Japan)" - rom ( name "Kawaii Koinu Wonderful (Japan).gba" size 8388608 crc 2E23C8F5 md5 A1662B3B7EA35CF59070D98B0E7F7FFC sha1 7B7FA6D1677DDA38D7B6C6D392A97099A360C9D3 ) + rom ( name "Kawaii Koinu Wonderful (Japan).gba" size 8388608 crc 2e23c8f5 sha1 7B7FA6D1677DDA38D7B6C6D392A97099A360C9D3 ) ) game ( name "Kawaii Pet Game Gallery (Japan)" description "Kawaii Pet Game Gallery (Japan)" - rom ( name "Kawaii Pet Game Gallery (Japan).gba" size 8388608 crc BC5ABD75 md5 521F9BA996123F0AB3C4EEF83754F48E sha1 779F97C29C1003DF73BBCF7D0042C3972FD398F2 ) + rom ( name "Kawaii Pet Game Gallery (Japan).gba" size 8388608 crc bc5abd75 sha1 779F97C29C1003DF73BBCF7D0042C3972FD398F2 ) ) game ( name "Kawaii Pet Game Gallery 2 (Japan)" description "Kawaii Pet Game Gallery 2 (Japan)" - rom ( name "Kawaii Pet Game Gallery 2 (Japan).gba" size 8388608 crc C8C8C4C1 md5 776AE8434C5A946B19B91264B1F7DA86 sha1 B86A37558EB5261C84A3DD9CAD5242C8C38E8D3D ) + rom ( name "Kawaii Pet Game Gallery 2 (Japan).gba" size 8388608 crc c8c8c4c1 sha1 B86A37558EB5261C84A3DD9CAD5242C8C38E8D3D ) ) game ( name "Kawaii Pet Shop Monogatari 3 (Japan)" description "Kawaii Pet Shop Monogatari 3 (Japan)" - rom ( name "Kawaii Pet Shop Monogatari 3 (Japan).gba" size 4194304 crc 39AEFB7B md5 2836AD919DE58D933FF94EA209FFEA86 sha1 8FCB335821AAFD366431103CE2CC14E08898CF75 ) + rom ( name "Kawaii Pet Shop Monogatari 3 (Japan).gba" size 4194304 crc 39aefb7b sha1 8FCB335821AAFD366431103CE2CC14E08898CF75 flags verified ) ) game ( name "Kaze no Klonoa - Yumemiru Teikoku (Japan)" description "Kaze no Klonoa - Yumemiru Teikoku (Japan)" - rom ( name "Kaze no Klonoa - Yumemiru Teikoku (Japan).gba" size 4194304 crc B51D97DE md5 DD311F91E8792544AF395C9E3690A478 sha1 F46410EC245DBB6FA90285C6D4071C09CC983B05 flags verified ) + rom ( name "Kaze no Klonoa - Yumemiru Teikoku (Japan).gba" size 4194304 crc b51d97de sha1 F46410EC245DBB6FA90285C6D4071C09CC983B05 flags verified ) ) game ( name "Kaze no Klonoa G2 - Dream Champ Tournament (Japan)" description "Kaze no Klonoa G2 - Dream Champ Tournament (Japan)" - rom ( name "Kaze no Klonoa G2 - Dream Champ Tournament (Japan).gba" size 4194304 crc 8D98DC2C md5 37F5B0E5B014994F923AC1E9E3300643 sha1 87A89B4144E1D6B0CB88AB9B63E2892F2882AB03 ) + rom ( name "Kaze no Klonoa G2 - Dream Champ Tournament (Japan).gba" size 4194304 crc 8d98dc2c sha1 87A89B4144E1D6B0CB88AB9B63E2892F2882AB03 ) ) game ( name "Keitai Denjuu Telefang 2 - Power (Japan)" description "Keitai Denjuu Telefang 2 - Power (Japan)" - rom ( name "Keitai Denjuu Telefang 2 - Power (Japan).gba" size 8388608 crc 44DB280E md5 C6816EFAB9F789038D7399A7EBA5B37C sha1 A03F5F27854984195FF110A46755EAAA4CC92763 flags verified ) + rom ( name "Keitai Denjuu Telefang 2 - Power (Japan).gba" size 8388608 crc 44db280e sha1 A03F5F27854984195FF110A46755EAAA4CC92763 flags verified ) ) game ( name "Keitai Denjuu Telefang 2 - Speed (Japan)" description "Keitai Denjuu Telefang 2 - Speed (Japan)" - rom ( name "Keitai Denjuu Telefang 2 - Speed (Japan).gba" size 8388608 crc 8F95CA53 md5 08EAF353E753E922E8BF05FCC9A87AC0 sha1 4D399C8D52F7C1309D43CE4BB9677BA335FE50CC ) + rom ( name "Keitai Denjuu Telefang 2 - Speed (Japan).gba" size 8388608 crc 8f95ca53 sha1 4D399C8D52F7C1309D43CE4BB9677BA335FE50CC flags verified ) ) game ( name "Kelly Slater's Pro Surfer (USA, Europe)" description "Kelly Slater's Pro Surfer (USA, Europe)" - rom ( name "Kelly Slater's Pro Surfer (USA, Europe).gba" size 8388608 crc 31F85DBE md5 E6836A809FFE6AEA707231CCF830C122 sha1 73328BFD274D1EC77C9A67351C026E22F09EEFF5 ) + rom ( name "Kelly Slater's Pro Surfer (USA, Europe).gba" size 8388608 crc 31f85dbe sha1 73328BFD274D1EC77C9A67351C026E22F09EEFF5 flags verified ) ) game ( name "Keroro Gunsou - Taiketsu! Gekisou Keronprix Daisakusen de Arimasu!! (Japan)" description "Keroro Gunsou - Taiketsu! Gekisou Keronprix Daisakusen de Arimasu!! (Japan)" - rom ( name "Keroro Gunsou - Taiketsu! Gekisou Keronprix Daisakusen de Arimasu!! (Japan).gba" size 4194304 crc C026CBBB md5 6F3245A38BB2EBA60FD4AF25429F1122 sha1 C643DD7A8405A1D222B45D29B970B3FB6B91308D ) + rom ( name "Keroro Gunsou - Taiketsu! Gekisou Keronprix Daisakusen de Arimasu!! (Japan).gba" size 4194304 crc c026cbbb sha1 C643DD7A8405A1D222B45D29B970B3FB6B91308D ) ) game ( name "Kessaku Sen! - Ganbare Goemon 1, 2 - Yuki Hime to Magginesu (Japan)" description "Kessaku Sen! - Ganbare Goemon 1, 2 - Yuki Hime to Magginesu (Japan)" - rom ( name "Kessaku Sen! - Ganbare Goemon 1, 2 - Yuki Hime to Magginesu (Japan).gba" size 16777216 crc 3E7D9694 md5 4CBCECF6C44AE7376DCAA446A95D6E2E sha1 7A765916D4362E251F160C7E8CC0ECA2F405FE3D ) + rom ( name "Kessaku Sen! - Ganbare Goemon 1, 2 - Yuki Hime to Magginesu (Japan).gba" size 16777216 crc 3e7d9694 sha1 7A765916D4362E251F160C7E8CC0ECA2F405FE3D ) ) game ( name "Kid Paddle (Europe) (Fr,Nl)" description "Kid Paddle (Europe) (Fr,Nl)" - rom ( name "Kid Paddle (Europe) (Fr,Nl).gba" size 8388608 crc 69951AA9 md5 FF99DE23C20D8B8136E3AFCA53734E87 sha1 4CE6021D930FE946C512B2E5584F31D0B6435256 ) + rom ( name "Kid Paddle (Europe) (Fr,Nl).gba" size 8388608 crc 69951aa9 sha1 4CE6021D930FE946C512B2E5584F31D0B6435256 flags verified ) ) game ( name "Kid's Cards (USA)" description "Kid's Cards (USA)" - rom ( name "Kid's Cards (USA).gba" size 4194304 crc 6F931445 md5 565EDD5751FA8CA5F78E3AB732DC8F01 sha1 B13D3B91DD515B4ABCCF26B30E96D0A33954927B ) + rom ( name "Kid's Cards (USA).gba" size 4194304 crc 6f931445 sha1 B13D3B91DD515B4ABCCF26B30E96D0A33954927B ) ) game ( - name "Kidou Gekidan Haro Ichiza Haro no Puyo Puyo (Japan)" - description "Kidou Gekidan Haro Ichiza Haro no Puyo Puyo (Japan)" - rom ( name "Kidou Gekidan Haro Ichiza Haro no Puyo Puyo (Japan).gba" size 8388608 crc A7825224 md5 EA29CC92D44B5217B9810A77ECCADA2D sha1 3507A5C4DF0290B1D1935E47C2EE342D07C3DBDC ) + name "Kidou Gekidan Haro Ichiza - Haro no Puyo Puyo (Japan)" + description "Kidou Gekidan Haro Ichiza - Haro no Puyo Puyo (Japan)" + rom ( name "Kidou Gekidan Haro Ichiza - Haro no Puyo Puyo (Japan).gba" size 8388608 crc a7825224 sha1 3507A5C4DF0290B1D1935E47C2EE342D07C3DBDC ) ) game ( name "Kidou Senshi Gundam Seed - Tomo to Kimi to Koko de. (Japan)" description "Kidou Senshi Gundam Seed - Tomo to Kimi to Koko de. (Japan)" - rom ( name "Kidou Senshi Gundam Seed - Tomo to Kimi to Koko de. (Japan).gba" size 8388608 crc 73BF384B md5 449832ADA23C6BC79D1CD3978C5D9420 sha1 9F6B694A159A3D4E3DEFAAA17E58410D4228CB26 ) + rom ( name "Kidou Senshi Gundam Seed - Tomo to Kimi to Koko de. (Japan).gba" size 8388608 crc 73bf384b sha1 9F6B694A159A3D4E3DEFAAA17E58410D4228CB26 flags verified ) ) game ( name "Kidou Senshi Gundam Seed Destiny (Japan)" description "Kidou Senshi Gundam Seed Destiny (Japan)" - rom ( name "Kidou Senshi Gundam Seed Destiny (Japan).gba" size 8388608 crc AA250CCA md5 FA72EB309A2C87D0CC50A00D0775950C sha1 64EEA52CD909669A972C091869C5F47865863BC0 ) + rom ( name "Kidou Senshi Gundam Seed Destiny (Japan).gba" size 8388608 crc aa250cca sha1 64EEA52CD909669A972C091869C5F47865863BC0 ) ) game ( name "Kidou Tenshi Angelic Layer - Misaki to Yume no Tenshi-tachi (Japan)" description "Kidou Tenshi Angelic Layer - Misaki to Yume no Tenshi-tachi (Japan)" - rom ( name "Kidou Tenshi Angelic Layer - Misaki to Yume no Tenshi-tachi (Japan).gba" size 8388608 crc B21EE600 md5 1950BEC3827A706BCF603BF27794C270 sha1 1A93EDF81CA484201C97E365777186714694C077 ) + rom ( name "Kidou Tenshi Angelic Layer - Misaki to Yume no Tenshi-tachi (Japan).gba" size 8388608 crc b21ee600 sha1 1A93EDF81CA484201C97E365777186714694C077 ) ) game ( name "Kien (USA) (Proto)" description "Kien (USA) (Proto)" - rom ( name "Kien (USA) (Proto).gba" size 8388608 crc 185C2ECA md5 FE8F2D7B6B58CB78CA51F8BCEAA0F254 sha1 DA1673EC5EC35F8ECECA3F04CB6A92D61237CE72 ) + rom ( name "Kien (USA) (Proto).gba" size 8388608 crc 185c2eca sha1 DA1673EC5EC35F8ECECA3F04CB6A92D61237CE72 ) ) game ( name "Kikaika Guntai - Mech Platoon (Japan)" description "Kikaika Guntai - Mech Platoon (Japan)" - rom ( name "Kikaika Guntai - Mech Platoon (Japan).gba" size 8388608 crc A2FA4248 md5 735502D07870F82FD78FE07BADEEB33B sha1 D49FF33CD9FC488C5A018D9F3476FC96C82D778E ) + rom ( name "Kikaika Guntai - Mech Platoon (Japan).gba" size 8388608 crc a2fa4248 sha1 D49FF33CD9FC488C5A018D9F3476FC96C82D778E ) ) game ( - name "Kikikai-kai Advance (Japan)" - description "Kikikai-kai Advance (Japan)" - rom ( name "Kikikai-kai Advance (Japan).gba" size 4194304 crc 1C61225B md5 DA5B6A9F2528749BDFCD601980A5059B sha1 309F50B9B5EF0DA52CB30D049006D37697EBC033 ) + name "Kiki Kaikai Advance (Japan)" + description "Kiki Kaikai Advance (Japan)" + rom ( name "Kiki Kaikai Advance (Japan).gba" size 4194304 crc 1c61225b sha1 309F50B9B5EF0DA52CB30D049006D37697EBC033 ) ) game ( name "Kill Switch (USA)" description "Kill Switch (USA)" - rom ( name "Kill Switch (USA).gba" size 4194304 crc 2B207D1F md5 9F9E47A8B37FB27C2F387654797C95A3 sha1 49B28F83D1085592CD7207F8A157C86A9253F047 flags verified ) + rom ( name "Kill Switch (USA).gba" size 4194304 crc 2b207d1f sha1 49B28F83D1085592CD7207F8A157C86A9253F047 flags verified ) ) game ( name "Kill Switch (Europe) (En,Fr,De,Es,It)" description "Kill Switch (Europe) (En,Fr,De,Es,It)" - rom ( name "Kill Switch (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4F468670 md5 B106F85E2F6C3A460E8CA5CC2261C90B sha1 290F06607DEBD7D9CFD9BB997BCEFD03BBE8294E flags verified ) + rom ( name "Kill Switch (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4f468670 sha1 290F06607DEBD7D9CFD9BB997BCEFD03BBE8294E flags verified ) ) game ( name "Killer 3D Pool (Europe) (En,Fr,De,Es,It)" description "Killer 3D Pool (Europe) (En,Fr,De,Es,It)" - rom ( name "Killer 3D Pool (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E6FDA065 md5 E698FF3702FF76C42FC8D0BB80154D22 sha1 A4E3107F0797D42EE8888488CF0F87AF140B8652 flags verified ) + rom ( name "Killer 3D Pool (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e6fda065 sha1 A4E3107F0797D42EE8888488CF0F87AF140B8652 flags verified ) ) game ( name "Killer 3D Pool (USA)" description "Killer 3D Pool (USA)" - rom ( name "Killer 3D Pool (USA).gba" size 4194304 crc 1F12D048 md5 16BF8504460B72DB612ADC0E17831221 sha1 9E988CB32C8B56EE2C3521CE1800E82289048840 ) + rom ( name "Killer 3D Pool (USA).gba" size 4194304 crc 1f12d048 sha1 9E988CB32C8B56EE2C3521CE1800E82289048840 ) ) game ( name "Kim Possible (Europe) (En,Fr,De,Es)" description "Kim Possible (Europe) (En,Fr,De,Es)" - rom ( name "Kim Possible (Europe) (En,Fr,De,Es).gba" size 8388608 crc 0C35D0FC md5 B6AF8C28BCB17FB7564AA638EDA471EF sha1 D0B5AB22924481EFCCAFD2AC10BAB93CCA4085D6 flags verified ) + rom ( name "Kim Possible (Europe) (En,Fr,De,Es).gba" size 8388608 crc 0c35d0fc sha1 D0B5AB22924481EFCCAFD2AC10BAB93CCA4085D6 flags verified ) ) game ( name "Kim Possible (Japan)" description "Kim Possible (Japan)" - rom ( name "Kim Possible (Japan).gba" size 8388608 crc 69843F73 md5 DC10ED7D9F86453CEB1303C9585BF8FF sha1 298448C533D1733672E3CB1E6860E8443D38E643 ) + rom ( name "Kim Possible (Japan).gba" size 8388608 crc 69843f73 sha1 298448C533D1733672E3CB1E6860E8443D38E643 flags verified ) ) game ( name "Kim Possible (Europe) (En,Fr,De,Es) (Rev 1)" description "Kim Possible (Europe) (En,Fr,De,Es) (Rev 1)" - rom ( name "Kim Possible (Europe) (En,Fr,De,Es) (Rev 1).gba" size 8388608 crc 48428C2A md5 09BC6AB258B83508BE5E9A0EB11417D4 sha1 1DF47750BE1B14FAED828FAE3719CD18D3BF47FB ) + rom ( name "Kim Possible (Europe) (En,Fr,De,Es) (Rev 1).gba" size 8388608 crc 48428c2a sha1 1DF47750BE1B14FAED828FAE3719CD18D3BF47FB flags verified ) ) game ( name "Kim Possible - Revenge of Monkey Fist (USA)" description "Kim Possible - Revenge of Monkey Fist (USA)" - rom ( name "Kim Possible - Revenge of Monkey Fist (USA).gba" size 8388608 crc 1A56EFBD md5 CC2A04C4ADDCB14C30B0CED2A83C2D91 sha1 64EF958BEAE876D3A6C295D0351D671B6991774B flags verified ) -) - -game ( - name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" - description "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" - rom ( name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es).gba" size 8388608 crc 71C505C8 md5 05DA8D783575896E54F15104F1E87035 sha1 EB4099911DBD28073C554F4D4FA35CBEED82BC6B ) + rom ( name "Kim Possible - Revenge of Monkey Fist (USA).gba" size 8388608 crc 1a56efbd sha1 64EF958BEAE876D3A6C295D0351D671B6991774B flags verified ) ) game ( name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" description "Kim Possible 2 - Drakken's Demise (USA) (En,Fr)" - rom ( name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr).gba" size 8388608 crc FA946FC6 md5 5BEC89F235C7A558F7F79D1760D648DA sha1 D2BAAEC3C20B48BEBE79EBE27761CD107FD067BF flags verified ) + rom ( name "Kim Possible 2 - Drakken's Demise (USA) (En,Fr).gba" size 8388608 crc fa946fc6 sha1 D2BAAEC3C20B48BEBE79EBE27761CD107FD067BF flags verified ) ) game ( - name "Kim Possible III - Team Possible (USA) (En,Fr)" - description "Kim Possible III - Team Possible (USA) (En,Fr)" - rom ( name "Kim Possible III - Team Possible (USA) (En,Fr).gba" size 8388608 crc FDEC60EC md5 3C629E441D4842CCB9D05E1C91853F80 sha1 47E99DCDBD97238778318DFD53421690E7ACB48E ) + name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" + description "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es)" + rom ( name "Kim Possible 2 - Drakken's Demise (Europe) (En,Fr,De,Es).gba" size 8388608 crc 71c505c8 sha1 EB4099911DBD28073C554F4D4FA35CBEED82BC6B flags verified ) +) + +game ( + name "Kim Possible 3 - Team Possible (USA) (En,Fr)" + description "Kim Possible 3 - Team Possible (USA) (En,Fr)" + rom ( name "Kim Possible 3 - Team Possible (USA) (En,Fr).gba" size 8388608 crc fdec60ec sha1 47E99DCDBD97238778318DFD53421690E7ACB48E ) ) game ( name "King Kong - The Official Game of the Movie (Europe) (En,Fr,De,Es,It,Nl)" description "King Kong - The Official Game of the Movie (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "King Kong - The Official Game of the Movie (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 37387B19 md5 06DE64363CFC09AB7E5BDF4B03BBF6AC sha1 C71426B1FA93206199CA4A3F4A1324186DD275CA flags verified ) + rom ( name "King Kong - The Official Game of the Movie (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 37387b19 sha1 C71426B1FA93206199CA4A3F4A1324186DD275CA flags verified ) ) game ( - name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" - rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0F960E70 md5 6946574D398CA3AB0056AF834BCB2BB3 sha1 3031264C4B27CAC55C2DF38AB5F2BFCAFA7C301D ) + name "King Kong - The Official Game of the Movie (Europe) (En,Sv,No,Da,Fi)" + description "King Kong - The Official Game of the Movie (Europe) (En,Sv,No,Da,Fi)" + rom ( name "King Kong - The Official Game of the Movie (Europe) (En,Sv,No,Da,Fi).gba" size 8388608 crc 439a92eb sha1 ECFB6409ABB7FF429AADC65A6B953DBAEF3D09D8 flags verified ) ) game ( - name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" - rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811FFCFA md5 E9626C897AAB5BF3E9C42E0611FB4062 sha1 CDE8454951D3509F0B2BF9DE98221EEF248F5F8D ) + name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + description "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1)" + rom ( name "King of Fighters EX 2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc dc5beacd sha1 2B7EC55DE56D7F7F0932A53A0D3FCC3F36A0AF8E ) +) + +game ( + name "King of Fighters EX 2, The - Howling Blood (Europe)" + description "King of Fighters EX 2, The - Howling Blood (Europe)" + rom ( name "King of Fighters EX 2, The - Howling Blood (Europe).gba" size 8388608 crc 9e8baa87 sha1 38FEC1391A0FF02F19C10CACF8E61414C640BEBA flags verified ) +) + +game ( + name "King of Fighters EX 2, The - Howling Blood (USA)" + description "King of Fighters EX 2, The - Howling Blood (USA)" + rom ( name "King of Fighters EX 2, The - Howling Blood (USA).gba" size 8388608 crc 15f8f9d5 sha1 A1D1D6FCC6F468AE366696DFAB7B6C1BD91F1F44 flags verified ) ) game ( name "King of Fighters EX, The - NeoBlood (Japan)" description "King of Fighters EX, The - NeoBlood (Japan)" - rom ( name "King of Fighters EX, The - NeoBlood (Japan).gba" size 8388608 crc 0814C78D md5 F18631A6E0AF3301981848E521F1DE9A sha1 42F878A8EF15EBA819F1DC92827CF5DE320F7560 ) + rom ( name "King of Fighters EX, The - NeoBlood (Japan).gba" size 8388608 crc 0814c78d sha1 42F878A8EF15EBA819F1DC92827CF5DE320F7560 ) ) game ( name "King of Fighters EX, The - NeoBlood (USA)" description "King of Fighters EX, The - NeoBlood (USA)" - rom ( name "King of Fighters EX, The - NeoBlood (USA).gba" size 8388608 crc 2B92EB8E md5 1266F7F9D73252D70B25EBFE966C9A2B sha1 06A42BBA1C892F77C7D12381FBF243FB294363CC flags verified ) + rom ( name "King of Fighters EX, The - NeoBlood (USA).gba" size 8388608 crc 2b92eb8e sha1 06A42BBA1C892F77C7D12381FBF243FB294363CC flags verified ) ) game ( name "King of Fighters EX, The - NeoBlood (Europe)" description "King of Fighters EX, The - NeoBlood (Europe)" - rom ( name "King of Fighters EX, The - NeoBlood (Europe).gba" size 8388608 crc 17E66B52 md5 0632F298B6484B923C5E01D231AE4AA9 sha1 48C85734164D4D83A232B5ACA6BB9A2C5B7F5317 flags verified ) + rom ( name "King of Fighters EX, The - NeoBlood (Europe).gba" size 8388608 crc 17e66b52 sha1 48C85734164D4D83A232B5ACA6BB9A2C5B7F5317 flags verified ) ) game ( - name "King of Fighters EX2, The - Howling Blood (Japan) (Rev 1)" - description "King of Fighters EX2, The - Howling Blood (Japan) (Rev 1)" - rom ( name "King of Fighters EX2, The - Howling Blood (Japan) (Rev 1).gba" size 8388608 crc DC5BEACD md5 2AE7AE75669717E299671D26EA883F98 sha1 2B7EC55DE56D7F7F0932A53A0D3FCC3F36A0AF8E ) + name "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + description "King of Fighters EX, The - NeoBlood (USA) (Rev 1)" + rom ( name "King of Fighters EX, The - NeoBlood (USA) (Rev 1).gba" size 8388608 crc 0f960e70 sha1 3031264C4B27CAC55C2DF38AB5F2BFCAFA7C301D ) ) game ( - name "King of Fighters EX2, The - Howling Blood (Europe)" - description "King of Fighters EX2, The - Howling Blood (Europe)" - rom ( name "King of Fighters EX2, The - Howling Blood (Europe).gba" size 8388608 crc 9E8BAA87 md5 80826C4AFCBAD51231C8721118F13223 sha1 38FEC1391A0FF02F19C10CACF8E61414C640BEBA flags verified ) -) - -game ( - name "King of Fighters EX2, The - Howling Blood (USA)" - description "King of Fighters EX2, The - Howling Blood (USA)" - rom ( name "King of Fighters EX2, The - Howling Blood (USA).gba" size 8388608 crc 15F8F9D5 md5 6BE741EEA41598BAEED52E4DD7DDB9F5 sha1 A1D1D6FCC6F468AE366696DFAB7B6C1BD91F1F44 flags verified ) + name "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + description "King of Fighters EX, The - NeoBlood (Japan) (Beta)" + rom ( name "King of Fighters EX, The - NeoBlood (Japan) (Beta).gba" size 8388608 crc 811ffcfa sha1 CDE8454951D3509F0B2BF9DE98221EEF248F5F8D ) ) game ( name "Kingdom Hearts - Chain of Memories (Japan)" description "Kingdom Hearts - Chain of Memories (Japan)" - rom ( name "Kingdom Hearts - Chain of Memories (Japan).gba" size 33554432 crc 8D5A0D84 md5 90CB614E8695745F288BF2A7DE4B5922 sha1 59EC0A0A4CCD1E6ACB3BBD7BFB21D63988958CFA ) + rom ( name "Kingdom Hearts - Chain of Memories (Japan).gba" size 33554432 crc 8d5a0d84 sha1 59EC0A0A4CCD1E6ACB3BBD7BFB21D63988958CFA ) ) game ( name "Kingdom Hearts - Chain of Memories (USA)" description "Kingdom Hearts - Chain of Memories (USA)" - rom ( name "Kingdom Hearts - Chain of Memories (USA).gba" size 33554432 crc D031CE67 md5 F7B81E3F3BB3B02D973FC6F145AD4416 sha1 10729BD884F8FDCA7A310B6D606C52E46657AA48 flags verified ) + rom ( name "Kingdom Hearts - Chain of Memories (USA).gba" size 33554432 crc d031ce67 sha1 10729BD884F8FDCA7A310B6D606C52E46657AA48 flags verified ) ) game ( name "Kingdom Hearts - Chain of Memories (Europe) (En,Fr,De,Es,It)" description "Kingdom Hearts - Chain of Memories (Europe) (En,Fr,De,Es,It)" - rom ( name "Kingdom Hearts - Chain of Memories (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 772D97FB md5 D369F791D86A969778D2C3A5278D544C sha1 8DB73586CDB11B3795907EDEBF43228DBCD3E6B2 flags verified ) + rom ( name "Kingdom Hearts - Chain of Memories (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 772d97fb sha1 8DB73586CDB11B3795907EDEBF43228DBCD3E6B2 flags verified ) ) game ( name "Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan)" description "Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan)" - rom ( name "Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan).gba" size 8388608 crc 40B1DD00 md5 0E9679E9469832DB50EE23A809F54C98 sha1 A9CF3FF41AB1514B90C5A578CFAEF4BAAE2253CC ) + rom ( name "Kinniku Banzuke - Kimero! Kiseki no Kanzen Seiha (Japan).gba" size 8388608 crc 40b1dd00 sha1 A9CF3FF41AB1514B90C5A578CFAEF4BAAE2253CC ) ) game ( name "Kinniku Banzuke - Kongou-kun no Daibouken! (Japan)" description "Kinniku Banzuke - Kongou-kun no Daibouken! (Japan)" - rom ( name "Kinniku Banzuke - Kongou-kun no Daibouken! (Japan).gba" size 8388608 crc 94519D2A md5 E7939307D25E65CBECC764F55AD49E34 sha1 80824BEF46247F4B45F89FF5817CE3B35B0E74FC ) + rom ( name "Kinniku Banzuke - Kongou-kun no Daibouken! (Japan).gba" size 8388608 crc 94519d2a sha1 80824BEF46247F4B45F89FF5817CE3B35B0E74FC ) ) game ( name "Kinnikuman II-Sei - Seigi Choujin e no Michi (Japan)" description "Kinnikuman II-Sei - Seigi Choujin e no Michi (Japan)" - rom ( name "Kinnikuman II-Sei - Seigi Choujin e no Michi (Japan).gba" size 16777216 crc 3FE9C701 md5 DCCDC879ECA4DC6C16FB93BDB072226D sha1 FF28C981C004D556961DB680C7B41E52F560831A ) + rom ( name "Kinnikuman II-Sei - Seigi Choujin e no Michi (Japan).gba" size 16777216 crc 3fe9c701 sha1 FF28C981C004D556961DB680C7B41E52F560831A ) ) game ( - name "Kirby & the Amazing Mirror (Europe) (En,Fr,De,Es,It)" - description "Kirby & the Amazing Mirror (Europe) (En,Fr,De,Es,It)" - rom ( name "Kirby & the Amazing Mirror (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4F07C618 md5 1C759EDF84A20174989588664BBBEC55 sha1 6F478A455383A2A12378F292581DFD7300300700 flags verified ) + name "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It)" + description "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It)" + rom ( name "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4f07c618 sha1 6F478A455383A2A12378F292581DFD7300300700 flags verified ) ) game ( - name "Kirby & the Amazing Mirror (USA)" - description "Kirby & the Amazing Mirror (USA)" - rom ( name "Kirby & the Amazing Mirror (USA).gba" size 16777216 crc 9F2A3048 md5 DF5EFE075B35859529EBF82A4D824458 sha1 274B102B6D940F46861A92B4E65F89A51815C12C flags verified ) + name "Kirby & The Amazing Mirror (USA)" + description "Kirby & The Amazing Mirror (USA)" + rom ( name "Kirby & The Amazing Mirror (USA).gba" size 16777216 crc 9f2a3048 sha1 274B102B6D940F46861A92B4E65F89A51815C12C flags verified ) ) game ( - name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" - rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3B7A7477 md5 6DD162A103FB55DDF99B6E688019354F sha1 39B00BEEE4558E6738859CFA250E4E0FCAAE626E flags verified ) + name "Kirby & The Amazing Mirror (USA) (Wii U Virtual Console)" + description "Kirby & The Amazing Mirror (USA) (Wii U Virtual Console)" + rom ( name "Kirby & The Amazing Mirror (USA) (Wii U Virtual Console).gba" size 16777216 crc f70ebb99 sha1 A7B758C2ABF4F0EF722922EAB4D394A1579B52E8 flags verified ) ) game ( name "Kirby - Nightmare in Dream Land (USA)" description "Kirby - Nightmare in Dream Land (USA)" - rom ( name "Kirby - Nightmare in Dream Land (USA).gba" size 8388608 crc 20EF3F64 md5 35AE64B0F27E60107C14AB956F6CDF70 sha1 37A476567D133C146FEE6B5E2EB0B07A215DA6B0 flags verified ) + rom ( name "Kirby - Nightmare in Dream Land (USA).gba" size 8388608 crc 20ef3f64 sha1 37A476567D133C146FEE6B5E2EB0B07A215DA6B0 flags verified ) +) + +game ( + name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + description "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It)" + rom ( name "Kirby - Nightmare in Dream Land (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 3b7a7477 sha1 39B00BEEE4558E6738859CFA250E4E0FCAAE626E flags verified ) +) + +game ( + name "Kirby - Nightmare in Dream Land (USA) (Wii U Virtual Console)" + description "Kirby - Nightmare in Dream Land (USA) (Wii U Virtual Console)" + rom ( name "Kirby - Nightmare in Dream Land (USA) (Wii U Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3D142008D50A64C315FD2D7CBD86BA94DFFA2E12 flags verified ) ) game ( name "Kisekko Gurumii - Chesty to Nuigurumi-tachi no Mahou no Bouken (Japan)" description "Kisekko Gurumii - Chesty to Nuigurumi-tachi no Mahou no Bouken (Japan)" - rom ( name "Kisekko Gurumii - Chesty to Nuigurumi-tachi no Mahou no Bouken (Japan).gba" size 8388608 crc 34D65C0B md5 D552538ADBA7BF2BC443822265BCFE20 sha1 161B95088373FBFB2B1B40EC63ECC2B4F8D540FB ) + rom ( name "Kisekko Gurumii - Chesty to Nuigurumi-tachi no Mahou no Bouken (Japan).gba" size 8388608 crc 34d65c0b sha1 161B95088373FBFB2B1B40EC63ECC2B4F8D540FB ) ) game ( - name "Kiss x Kiss Seirei Gakuen (Japan)" - description "Kiss x Kiss Seirei Gakuen (Japan)" - rom ( name "Kiss x Kiss Seirei Gakuen (Japan).gba" size 4194304 crc 0C368530 md5 AE1AB2AEEDA397FB25536A6851F43FE1 sha1 ABBBE9355759D94E98210E91A67585D0AF8CFC8F ) + name "Kiss x Kiss - Seirei Gakuen (Japan)" + description "Kiss x Kiss - Seirei Gakuen (Japan)" + rom ( name "Kiss x Kiss - Seirei Gakuen (Japan).gba" size 4194304 crc 0c368530 sha1 ABBBE9355759D94E98210E91A67585D0AF8CFC8F ) ) game ( name "Kiwame Mahjong Deluxe - Mirai Senshi 21 (Japan)" description "Kiwame Mahjong Deluxe - Mirai Senshi 21 (Japan)" - rom ( name "Kiwame Mahjong Deluxe - Mirai Senshi 21 (Japan).gba" size 8388608 crc 66F7614B md5 02CD66823B6666B956E0BAEEAB7BA161 sha1 078AE246758971D5F763509765780CB82A96B471 ) + rom ( name "Kiwame Mahjong Deluxe - Mirai Senshi 21 (Japan).gba" size 8388608 crc 66f7614b sha1 078AE246758971D5F763509765780CB82A96B471 ) ) game ( name "Klonoa - Empire of Dreams (USA)" description "Klonoa - Empire of Dreams (USA)" - rom ( name "Klonoa - Empire of Dreams (USA).gba" size 4194304 crc F74E1036 md5 F4F23F40E29451150B46D4BBDEF63F13 sha1 A0A298D9DBA1BA15D04A42FC2EB35893D1A9569B ) + rom ( name "Klonoa - Empire of Dreams (USA).gba" size 4194304 crc f74e1036 sha1 A0A298D9DBA1BA15D04A42FC2EB35893D1A9569B flags verified ) ) game ( name "Klonoa - Empire of Dreams (Europe)" description "Klonoa - Empire of Dreams (Europe)" - rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 md5 31D227735FBC8220DE9F1A93DA10E199 sha1 E4A81713B134E0B7409708843DAD2A4948B903EF flags verified ) + rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 sha1 E4A81713B134E0B7409708843DAD2A4948B903EF flags verified ) ) game ( name "Klonoa 2 - Dream Champ Tournament (USA)" description "Klonoa 2 - Dream Champ Tournament (USA)" - rom ( name "Klonoa 2 - Dream Champ Tournament (USA).gba" size 4194304 crc 8BD23A7F md5 CB1603C3CC3ED8A37F87B3971B0270D5 sha1 35C05676E65FD4C92220861662CD3709342F36E2 ) + rom ( name "Klonoa 2 - Dream Champ Tournament (USA).gba" size 4194304 crc 8bd23a7f sha1 35C05676E65FD4C92220861662CD3709342F36E2 ) +) + +game ( + name "Klonoa 2 - Dream Champ Tournament (USA) (Wii U Virtual Console)" + description "Klonoa 2 - Dream Champ Tournament (USA) (Wii U Virtual Console)" + rom ( name "Klonoa 2 - Dream Champ Tournament (USA) (Wii U Virtual Console).gba" size 4194304 crc 766c7f9a sha1 455C6F19A703B2BD54A9A3A9588964239965E6DB flags verified ) ) game ( name "Klonoa Heroes - Densetsu no Star Medal (Japan)" description "Klonoa Heroes - Densetsu no Star Medal (Japan)" - rom ( name "Klonoa Heroes - Densetsu no Star Medal (Japan).gba" size 16777216 crc E7EADDCC md5 46D2A77E4FD8429E6B7BF79C0679770E sha1 323465C8A36517A1E8B0DDE2D500BBCD4C396D4E ) + rom ( name "Klonoa Heroes - Densetsu no Star Medal (Japan).gba" size 16777216 crc e7eaddcc sha1 323465C8A36517A1E8B0DDE2D500BBCD4C396D4E ) ) game ( name "Knights' Kingdom (USA)" description "Knights' Kingdom (USA)" - rom ( name "Knights' Kingdom (USA).gba" size 4194304 crc 88FE3F31 md5 5AD0ED7F2BBDA3DAB28D29B59F01CADE sha1 5F6E9FADA285DD4795D4103E5F97B8E714AB9099 ) + rom ( name "Knights' Kingdom (USA).gba" size 4194304 crc 88fe3f31 sha1 5F6E9FADA285DD4795D4103E5F97B8E714AB9099 ) ) game ( name "Knights' Kingdom (Europe) (En,De)" description "Knights' Kingdom (Europe) (En,De)" - rom ( name "Knights' Kingdom (Europe) (En,De).gba" size 4194304 crc F027E89F md5 8EABC44961B0E153F9E3DA94CA011847 sha1 E9754E69EAEFB7912F230826D13B743A71293600 ) + rom ( name "Knights' Kingdom (Europe) (En,De).gba" size 4194304 crc f027e89f sha1 E9754E69EAEFB7912F230826D13B743A71293600 ) ) game ( name "Koala Brothers - Outback Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Koala Brothers - Outback Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Koala Brothers - Outback Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc ABD866EA md5 116DB73B6B497253E887E4EE46B4FE3C sha1 6E037BEFF51FD108BA9C7169C571437A5325EBF4 ) + rom ( name "Koala Brothers - Outback Adventures (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc abd866ea sha1 6E037BEFF51FD108BA9C7169C571437A5325EBF4 flags verified ) ) game ( name "Koala Brothers - Outback Adventures (USA) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Koala Brothers - Outback Adventures (USA) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Koala Brothers - Outback Adventures (USA) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc 6EC76BCE md5 56AE7F3683083A70FD36EB509E68845F sha1 3304D1188F269A105808146AC05DF6FF3A597781 ) + rom ( name "Koala Brothers - Outback Adventures (USA) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc 6ec76bce sha1 3304D1188F269A105808146AC05DF6FF3A597781 ) ) game ( name "Koinu to Issho - Aijou Monogatari (Japan)" description "Koinu to Issho - Aijou Monogatari (Japan)" - rom ( name "Koinu to Issho - Aijou Monogatari (Japan).gba" size 16777216 crc 30E209AA md5 C7A9CDAA399C20A2A37ABE1A2A71B387 sha1 2954B01E045D6D9C45F994FA072261ACD19F272F ) + rom ( name "Koinu to Issho - Aijou Monogatari (Japan).gba" size 16777216 crc 30e209aa sha1 2954B01E045D6D9C45F994FA072261ACD19F272F ) ) game ( name "Koinu to Issho 2 (Japan)" description "Koinu to Issho 2 (Japan)" - rom ( name "Koinu to Issho 2 (Japan).gba" size 16777216 crc 2D2AC33B md5 323C4735D5911403CFCB810B294669A0 sha1 CC83B013670A67C2A6AAF91722972DF58B9DDB0D ) + rom ( name "Koinu to Issho 2 (Japan).gba" size 16777216 crc 2d2ac33b sha1 CC83B013670A67C2A6AAF91722972DF58B9DDB0D ) ) game ( name "Koinu-chan no Hajimete no Osanpo - Koinu no Kokoro Ikusei Game (Japan)" description "Koinu-chan no Hajimete no Osanpo - Koinu no Kokoro Ikusei Game (Japan)" - rom ( name "Koinu-chan no Hajimete no Osanpo - Koinu no Kokoro Ikusei Game (Japan).gba" size 4194304 crc 1D27165A md5 31C90DA4E415FF1ABD4BA320F3FB4A6F sha1 9452C587A00706D6758C503752F2D647D9104817 ) + rom ( name "Koinu-chan no Hajimete no Osanpo - Koinu no Kokoro Ikusei Game (Japan).gba" size 4194304 crc 1d27165a sha1 9452C587A00706D6758C503752F2D647D9104817 ) ) game ( name "Konami Arcade Game Collection (Japan)" description "Konami Arcade Game Collection (Japan)" - rom ( name "Konami Arcade Game Collection (Japan).gba" size 4194304 crc 285F652F md5 247F637C17F7C8D996A4AB48F3398F06 sha1 6B4DB5FA184D60377E9FBD269E666A19B4080101 ) + rom ( name "Konami Arcade Game Collection (Japan).gba" size 4194304 crc 285f652f sha1 6B4DB5FA184D60377E9FBD269E666A19B4080101 ) ) game ( name "Konami Collector's Series - Arcade Advanced (USA)" description "Konami Collector's Series - Arcade Advanced (USA)" - rom ( name "Konami Collector's Series - Arcade Advanced (USA).gba" size 4194304 crc 2DB31825 md5 E879E454A201EEEB31A942406048501A sha1 58BBF8C1E13E4DC594FDFE5357B4CEEAB1DC0348 flags verified ) + rom ( name "Konami Collector's Series - Arcade Advanced (USA).gba" size 4194304 crc 2db31825 sha1 58BBF8C1E13E4DC594FDFE5357B4CEEAB1DC0348 flags verified ) ) game ( name "Konami Collector's Series - Arcade Classics (Europe) (En,Fr,De,Es,It)" description "Konami Collector's Series - Arcade Classics (Europe) (En,Fr,De,Es,It)" - rom ( name "Konami Collector's Series - Arcade Classics (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6A8BE56F md5 37DE77B39B429BCE433288987F9D278A sha1 7FF9C9F0C16DA6B2724DAA10C8B782E0C81E27B3 flags verified ) + rom ( name "Konami Collector's Series - Arcade Classics (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6a8be56f sha1 7FF9C9F0C16DA6B2724DAA10C8B782E0C81E27B3 flags verified ) ) game ( name "Konami Krazy Racers (USA)" description "Konami Krazy Racers (USA)" - rom ( name "Konami Krazy Racers (USA).gba" size 4194304 crc C80D4F5C md5 C1D1BB9DA3A5566A34A92DAC25E6BC04 sha1 B64D437582526642A0D7AA83419A1367A10C91A9 ) + rom ( name "Konami Krazy Racers (USA).gba" size 4194304 crc c80d4f5c sha1 B64D437582526642A0D7AA83419A1367A10C91A9 ) ) game ( name "Konami Krazy Racers (Europe)" description "Konami Krazy Racers (Europe)" - rom ( name "Konami Krazy Racers (Europe).gba" size 4194304 crc CFEC0650 md5 CE7BB230439440AB28EA9D5D6B19CC01 sha1 90A0035818BA0AB2A0C6EA45DC7EFF2EB7296970 flags verified ) + rom ( name "Konami Krazy Racers (Europe).gba" size 4194304 crc cfec0650 sha1 90A0035818BA0AB2A0C6EA45DC7EFF2EB7296970 flags verified ) ) game ( name "Konami Krazy Racers (USA) (Beta)" description "Konami Krazy Racers (USA) (Beta)" - rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5F2AE8FE md5 253D5403FFF7E6A7C4166423F2693F8F sha1 329B82282D633D1162F9AFB3334C035B10B91E72 ) + rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329B82282D633D1162F9AFB3334C035B10B91E72 ) ) game ( name "Konami Wai Wai Racing Advance (Japan)" description "Konami Wai Wai Racing Advance (Japan)" - rom ( name "Konami Wai Wai Racing Advance (Japan).gba" size 4194304 crc AA039A8A md5 D7010827EC2382C727B9AA565E842ABE sha1 E3549B9B7D7208B88E368E7B7A59E31EEC8B1DA6 ) + rom ( name "Konami Wai Wai Racing Advance (Japan).gba" size 4194304 crc aa039a8a sha1 E3549B9B7D7208B88E368E7B7A59E31EEC8B1DA6 ) ) game ( - name "Konchuu Monster Battle Master (Japan)" - description "Konchuu Monster Battle Master (Japan)" - rom ( name "Konchuu Monster Battle Master (Japan).gba" size 8388608 crc 3AA0CE79 md5 A7AD5647F3788AE37870E6DFFE2122E7 sha1 EB352A51E2E7CD54906A60ABB4098D4B22AC6312 ) + name "Konchuu Monster - Battle Master (Japan)" + description "Konchuu Monster - Battle Master (Japan)" + rom ( name "Konchuu Monster - Battle Master (Japan).gba" size 8388608 crc 3aa0ce79 sha1 EB352A51E2E7CD54906A60ABB4098D4B22AC6312 ) ) game ( - name "Konchuu Monster Battle Stadium (Japan)" - description "Konchuu Monster Battle Stadium (Japan)" - rom ( name "Konchuu Monster Battle Stadium (Japan).gba" size 8388608 crc 5ADB68EF md5 C8BCD516D865325E976D7905B3694DBC sha1 C1EA541B031E41E6AACFB6EA16EAACDB24483E18 ) + name "Konchuu Monster - Battle Stadium (Japan)" + description "Konchuu Monster - Battle Stadium (Japan)" + rom ( name "Konchuu Monster - Battle Stadium (Japan).gba" size 8388608 crc 5adb68ef sha1 C1EA541B031E41E6AACFB6EA16EAACDB24483E18 ) ) game ( name "Konchuu no Mori no Daibouken - Fushigi na Sekai no Juunin-tachi (Japan)" description "Konchuu no Mori no Daibouken - Fushigi na Sekai no Juunin-tachi (Japan)" - rom ( name "Konchuu no Mori no Daibouken - Fushigi na Sekai no Juunin-tachi (Japan).gba" size 8388608 crc 88C56D65 md5 DCE3C14F8F704B539094734700C5A145 sha1 1ADFAFD15422B2776FF484E931A01F98DD3FB457 ) + rom ( name "Konchuu no Mori no Daibouken - Fushigi na Sekai no Juunin-tachi (Japan).gba" size 8388608 crc 88c56d65 sha1 1ADFAFD15422B2776FF484E931A01F98DD3FB457 ) ) game ( name "Kong - King of Atlantis (USA)" description "Kong - King of Atlantis (USA)" - rom ( name "Kong - King of Atlantis (USA).gba" size 4194304 crc 5E8B2644 md5 D3100683634506761D3412B728617307 sha1 E490A1A0954D349F54C60E18C66C32977C6C6E30 ) + rom ( name "Kong - King of Atlantis (USA).gba" size 4194304 crc 5e8b2644 sha1 E490A1A0954D349F54C60E18C66C32977C6C6E30 ) ) game ( name "Kong - King of Atlantis (Europe)" description "Kong - King of Atlantis (Europe)" - rom ( name "Kong - King of Atlantis (Europe).gba" size 4194304 crc 9C12CD31 md5 638785B5576628FBD39D47756779130D sha1 F235DE9845182B1C28B98FE716F3332481FB1975 ) + rom ( name "Kong - King of Atlantis (Europe).gba" size 4194304 crc 9c12cd31 sha1 F235DE9845182B1C28B98FE716F3332481FB1975 flags verified ) ) game ( name "Kong - The 8th Wonder of the World (USA) (En,Fr,Es)" description "Kong - The 8th Wonder of the World (USA) (En,Fr,Es)" - rom ( name "Kong - The 8th Wonder of the World (USA) (En,Fr,Es).gba" size 8388608 crc 06079C42 md5 33402D100218CC080C24858EC2A0D7AE sha1 EA685CC54241309D8747E2A88C6BA2B8141A776E ) -) - -game ( - name "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl)" - description "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 150BDD9E md5 78141DF5F1AF636A7F8225D15B14FC31 sha1 4ADC0E0733DB2D27F9EC4063CBB2941AD5AA4506 ) + rom ( name "Kong - The 8th Wonder of the World (USA) (En,Fr,Es).gba" size 8388608 crc 06079c42 sha1 EA685CC54241309D8747E2A88C6BA2B8141A776E ) ) game ( name "Kong - The Animated Series (Europe) (En,Fr,De,Es,It,Nl)" description "Kong - The Animated Series (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Kong - The Animated Series (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7A7B060F md5 C1AC1F6979A4CC6B66C1C5515C191BC1 sha1 548E72482B45662A094ED7F3D2501BA506D5C490 ) + rom ( name "Kong - The Animated Series (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7a7b060f sha1 548E72482B45662A094ED7F3D2501BA506D5C490 ) +) + +game ( + name "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl)" + description "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl)" + rom ( name "Kong - The Animated Series (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 150bdd9e sha1 4ADC0E0733DB2D27F9EC4063CBB2941AD5AA4506 ) ) game ( name "Konjiki no Gashbell!! - Makai no Bookmark (Japan)" description "Konjiki no Gashbell!! - Makai no Bookmark (Japan)" - rom ( name "Konjiki no Gashbell!! - Makai no Bookmark (Japan).gba" size 8388608 crc D66379E1 md5 40265E0CCEA58B86FA17F010A7E4D91F sha1 1170D8FF54E0DF09A5ED9D9534815C2B528D7979 ) + rom ( name "Konjiki no Gashbell!! - Makai no Bookmark (Japan).gba" size 8388608 crc d66379e1 sha1 1170D8FF54E0DF09A5ED9D9534815C2B528D7979 flags verified ) ) game ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru (Japan)" description "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru (Japan)" - rom ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru (Japan).gba" size 8388608 crc 64FAB050 md5 F22148E0A4298808BA05CD386D64D320 sha1 AE82F41B61A054EAC8EEC4850C0AD0E6C1A1F77A ) + rom ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru (Japan).gba" size 8388608 crc 64fab050 sha1 AE82F41B61A054EAC8EEC4850C0AD0E6C1A1F77A flags verified ) ) game ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru 2 (Japan)" description "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru 2 (Japan)" - rom ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru 2 (Japan).gba" size 16777216 crc B7827F20 md5 26C1B5796BED6222C5B41C94996C380E sha1 854A76C49F6E83D8EE9DD42098CE1FC7236AF855 ) + rom ( name "Konjiki no Gashbell!! - Unare! Yuujou no Zakeru 2 (Japan).gba" size 16777216 crc b7827f20 sha1 854A76C49F6E83D8EE9DD42098CE1FC7236AF855 flags verified ) ) game ( name "Konjiki no Gashbell!! The Card Battle for GBA (Japan)" description "Konjiki no Gashbell!! The Card Battle for GBA (Japan)" - rom ( name "Konjiki no Gashbell!! The Card Battle for GBA (Japan).gba" size 16777216 crc E1E26F2A md5 F59054EA92ECA5911AA6E3FC002FE545 sha1 5CE26F86DA63D9C662B6ACE75E327D033B152078 ) + rom ( name "Konjiki no Gashbell!! The Card Battle for GBA (Japan).gba" size 16777216 crc e1e26f2a sha1 5CE26F86DA63D9C662B6ACE75E327D033B152078 ) ) game ( name "Konjiki no Gashbell!! Yuujou no Zakeru - Dream Tag Tournament (Japan)" description "Konjiki no Gashbell!! Yuujou no Zakeru - Dream Tag Tournament (Japan)" - rom ( name "Konjiki no Gashbell!! Yuujou no Zakeru - Dream Tag Tournament (Japan).gba" size 16777216 crc FB5516AD md5 E61314983C8438A7431B40564F8D6ACB sha1 6A8562568F43E87D254E6999746C89126039A20C ) + rom ( name "Konjiki no Gashbell!! Yuujou no Zakeru - Dream Tag Tournament (Japan).gba" size 16777216 crc fb5516ad sha1 6A8562568F43E87D254E6999746C89126039A20C ) ) game ( name "Koro Koro Puzzle - Happy Panechu! (Japan)" description "Koro Koro Puzzle - Happy Panechu! (Japan)" - rom ( name "Koro Koro Puzzle - Happy Panechu! (Japan).gba" size 4194304 crc 0BFE46E9 md5 F102BE90875140F712A259A5BC533DD5 sha1 40CB751D119A49BE0CD44CF0491C93EBC8795EF0 ) + rom ( name "Koro Koro Puzzle - Happy Panechu! (Japan).gba" size 4194304 crc 0bfe46e9 sha1 40CB751D119A49BE0CD44CF0491C93EBC8795EF0 ) ) game ( name "Kotoba no Puzzle - Mojipittan Advance (Japan)" description "Kotoba no Puzzle - Mojipittan Advance (Japan)" - rom ( name "Kotoba no Puzzle - Mojipittan Advance (Japan).gba" size 8388608 crc FB67EFBC md5 25EAD20D8D3CFEDB35393740B3A36B74 sha1 58FD895F247F6AD33B751B4967124911123A6CBA ) + rom ( name "Kotoba no Puzzle - Mojipittan Advance (Japan).gba" size 8388608 crc fb67efbc sha1 58FD895F247F6AD33B751B4967124911123A6CBA ) ) game ( - name "Kouchu Ouja Mushiking (Japan)" - description "Kouchu Ouja Mushiking (Japan)" - rom ( name "Kouchu Ouja Mushiking (Japan).gba" size 33554432 crc 7AC9FFBF md5 34B0151CDC78A7A3B7CAB3CDA70BBC1D sha1 AF1908198AEB5E8E0F1D9D5C3ECDBEFEF6AFC462 ) + name "Kouchuu Ouja Mushiking - Greatest Champion e no Michi (Japan)" + description "Kouchuu Ouja Mushiking - Greatest Champion e no Michi (Japan)" + rom ( name "Kouchuu Ouja Mushiking - Greatest Champion e no Michi (Japan).gba" size 33554432 crc 7ac9ffbf sha1 AF1908198AEB5E8E0F1D9D5C3ECDBEFEF6AFC462 ) ) game ( name "Koukou Juken Advance Series Eigo Koubun Hen - 26 Units Shuuroku (Japan)" description "Koukou Juken Advance Series Eigo Koubun Hen - 26 Units Shuuroku (Japan)" - rom ( name "Koukou Juken Advance Series Eigo Koubun Hen - 26 Units Shuuroku (Japan).gba" size 8388608 crc 576DA6F6 md5 CCB5A95C335A6B3BB6113970B004A742 sha1 7A319D84C043C778D03719CE2DFABBA7D4466B1D ) + rom ( name "Koukou Juken Advance Series Eigo Koubun Hen - 26 Units Shuuroku (Japan).gba" size 8388608 crc 576da6f6 sha1 7A319D84C043C778D03719CE2DFABBA7D4466B1D ) ) game ( name "Koukou Juken Advance Series Eijukugo Hen - 650 Phrases Shuuroku (Japan)" description "Koukou Juken Advance Series Eijukugo Hen - 650 Phrases Shuuroku (Japan)" - rom ( name "Koukou Juken Advance Series Eijukugo Hen - 650 Phrases Shuuroku (Japan).gba" size 8388608 crc 7F2F5017 md5 57918E55C3470BD8CDB885E7BB769E42 sha1 4A08926B6EEFA9A1623DB4C867362A7F28E94B2B ) + rom ( name "Koukou Juken Advance Series Eijukugo Hen - 650 Phrases Shuuroku (Japan).gba" size 8388608 crc 7f2f5017 sha1 4A08926B6EEFA9A1623DB4C867362A7F28E94B2B ) ) game ( name "Koukou Juken Advance Series Eitango Hen - 2000 Words Shuuroku (Japan)" description "Koukou Juken Advance Series Eitango Hen - 2000 Words Shuuroku (Japan)" - rom ( name "Koukou Juken Advance Series Eitango Hen - 2000 Words Shuuroku (Japan).gba" size 8388608 crc D38F6A8E md5 18929912972F945DFFDB21EF5EE7C8B1 sha1 BE3BC060FEC8471D3F6F29D950837CA3B0685594 ) + rom ( name "Koukou Juken Advance Series Eitango Hen - 2000 Words Shuuroku (Japan).gba" size 8388608 crc d38f6a8e sha1 BE3BC060FEC8471D3F6F29D950837CA3B0685594 ) ) game ( name "Koutetsu Teikoku from HOT-B (Japan)" description "Koutetsu Teikoku from HOT-B (Japan)" - rom ( name "Koutetsu Teikoku from HOT-B (Japan).gba" size 4194304 crc CDFAC4EE md5 2ED6310DAC14F69F72002D9A9B6FAB6B sha1 7253D2D036429B478E4132DE4901417DD840AE1A ) + rom ( name "Koutetsu Teikoku from HOT-B (Japan).gba" size 4194304 crc cdfac4ee sha1 7253D2D036429B478E4132DE4901417DD840AE1A flags verified ) ) game ( - name "Kunio Kun Nekketsu Collection 1 (Japan)" - description "Kunio Kun Nekketsu Collection 1 (Japan)" - rom ( name "Kunio Kun Nekketsu Collection 1 (Japan).gba" size 4194304 crc 4B96B600 md5 1489B4D9DEFFF4A8A993FA6017367C8F sha1 3D51222B8DCF2306455BAA3F3DCE9B5319566C06 ) + name "Kunio-kun Nekketsu Collection 1 (Japan)" + description "Kunio-kun Nekketsu Collection 1 (Japan)" + rom ( name "Kunio-kun Nekketsu Collection 1 (Japan).gba" size 4194304 crc 4b96b600 sha1 3D51222B8DCF2306455BAA3F3DCE9B5319566C06 ) ) game ( - name "Kunio Kun Nekketsu Collection 2 (Japan)" - description "Kunio Kun Nekketsu Collection 2 (Japan)" - rom ( name "Kunio Kun Nekketsu Collection 2 (Japan).gba" size 4194304 crc 61F9A9F4 md5 913A49EA66A349FEC2AC793A4EEB93B9 sha1 05BB9BF9108A33786FDD3A523F1A3156163F6E01 ) + name "Kunio-kun Nekketsu Collection 2 (Japan)" + description "Kunio-kun Nekketsu Collection 2 (Japan)" + rom ( name "Kunio-kun Nekketsu Collection 2 (Japan).gba" size 4194304 crc 61f9a9f4 sha1 05BB9BF9108A33786FDD3A523F1A3156163F6E01 ) ) game ( - name "Kunio Kun Nekketsu Collection 3 (Japan)" - description "Kunio Kun Nekketsu Collection 3 (Japan)" - rom ( name "Kunio Kun Nekketsu Collection 3 (Japan).gba" size 4194304 crc 093054FC md5 C0E8E0770977846C7A6124FB94285F4D sha1 4853C4F69D61782A1B151553059C9546334A6555 ) + name "Kunio-kun Nekketsu Collection 3 (Japan)" + description "Kunio-kun Nekketsu Collection 3 (Japan)" + rom ( name "Kunio-kun Nekketsu Collection 3 (Japan).gba" size 4194304 crc 093054fc sha1 4853C4F69D61782A1B151553059C9546334A6555 ) ) game ( name "Kurohige no Golf Shiyouyo (Japan)" description "Kurohige no Golf Shiyouyo (Japan)" - rom ( name "Kurohige no Golf Shiyouyo (Japan).gba" size 8388608 crc ABFD7AC7 md5 D801CE9F6FA2917D7ECBC7985A34B9EF sha1 16F4DF6AF8E68FB5E0ECA534A10F4CA0FB2FE2C2 ) + rom ( name "Kurohige no Golf Shiyouyo (Japan).gba" size 8388608 crc abfd7ac7 sha1 16F4DF6AF8E68FB5E0ECA534A10F4CA0FB2FE2C2 ) ) game ( name "Kurohige no Kurutto Jintori (Japan)" description "Kurohige no Kurutto Jintori (Japan)" - rom ( name "Kurohige no Kurutto Jintori (Japan).gba" size 4194304 crc 99C917E9 md5 D5A837CE039D6F860DCDFA75D6F80A97 sha1 C09310874E687DCE9011D201F4B31E44A1F552BB ) + rom ( name "Kurohige no Kurutto Jintori (Japan).gba" size 4194304 crc 99c917e9 sha1 C09310874E687DCE9011D201F4B31E44A1F552BB ) ) game ( name "Kurukuru Kururin (Japan)" description "Kurukuru Kururin (Japan)" - rom ( name "Kurukuru Kururin (Japan).gba" size 4194304 crc 8A6A900B md5 DB7D06D0BE0B06C4A73BCF614E81C588 sha1 840BB582A66837EB55952EF2697E00E36A30BB0F ) + rom ( name "Kurukuru Kururin (Japan).gba" size 4194304 crc 8a6a900b sha1 840BB582A66837EB55952EF2697E00E36A30BB0F ) ) game ( name "Kurukuru Kururin (Europe)" description "Kurukuru Kururin (Europe)" - rom ( name "Kurukuru Kururin (Europe).gba" size 4194304 crc C4DAB956 md5 48F3BC6BF59C34F057BD98B29FD7B848 sha1 6025EF597DB2684AE064FFE22B4FD1D37941F887 flags verified ) + rom ( name "Kurukuru Kururin (Europe).gba" size 4194304 crc c4dab956 sha1 6025EF597DB2684AE064FFE22B4FD1D37941F887 flags verified ) ) game ( name "Kururin Paradise (Japan)" description "Kururin Paradise (Japan)" - rom ( name "Kururin Paradise (Japan).gba" size 8388608 crc 93D036F5 md5 B77C57C60FC0DCBA3B2DDD3E2F1C5F86 sha1 73BE3B930E2436D1C7BDB74AC281DD27C72E1F9E flags verified ) + rom ( name "Kururin Paradise (Japan).gba" size 8388608 crc 93d036f5 sha1 73BE3B930E2436D1C7BDB74AC281DD27C72E1F9E flags verified ) ) game ( name "Lady Sia (Europe) (En,Fr,De,Es,It,Nl)" description "Lady Sia (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Lady Sia (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 958097D2 md5 F4AC2D26605EBBB0D390E07810F12484 sha1 275C631804A1186AB3DAB6ABF7CB5AD84A4FF9D4 ) + rom ( name "Lady Sia (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 958097d2 sha1 275C631804A1186AB3DAB6ABF7CB5AD84A4FF9D4 ) ) game ( name "Lady Sia (USA) (En,Fr,De,Es,It,Nl)" description "Lady Sia (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Lady Sia (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 139E95BD md5 94B847814FEE8E4E5D9FDBF1D3D25107 sha1 5D5A209A16E6B5548DC1D1A0375DE8F024DFE6C3 ) + rom ( name "Lady Sia (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 139e95bd sha1 5D5A209A16E6B5548DC1D1A0375DE8F024DFE6C3 ) ) game ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It)" description "Land Before Time, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc CF0FA4D9 md5 F6D3840D1E185CB4829E8E9A9818D00D sha1 6E4153AECEE6D77CDF532C7B9B2E780CCAD0A74C ) + rom ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc cf0fa4d9 sha1 6E4153AECEE6D77CDF532C7B9B2E780CCAD0A74C ) ) game ( name "Land Before Time, The (USA) (En,Es)" description "Land Before Time, The (USA) (En,Es)" - rom ( name "Land Before Time, The (USA) (En,Es).gba" size 4194304 crc CFD8A52C md5 318FD3DEC910D491BACE987795397BB5 sha1 E546D90BEFC9FEFC0DCE4B72890791263ED40284 ) + rom ( name "Land Before Time, The (USA) (En,Es).gba" size 4194304 crc cfd8a52c sha1 E546D90BEFC9FEFC0DCE4B72890791263ED40284 ) ) game ( name "Land Before Time, The - Into the Mysterious Beyond (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Land Before Time, The - Into the Mysterious Beyond (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Land Before Time, The - Into the Mysterious Beyond (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc 5485EEFA md5 0CADD0FD31E704D01503D303B5DA8341 sha1 30820BCEB45BBF70CB78E9F66462248430444528 ) + rom ( name "Land Before Time, The - Into the Mysterious Beyond (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc 5485eefa sha1 30820BCEB45BBF70CB78E9F66462248430444528 flags verified ) ) game ( name "Land Before Time, The - Into the Mysterious Beyond (USA) (En,Fr,Es)" description "Land Before Time, The - Into the Mysterious Beyond (USA) (En,Fr,Es)" - rom ( name "Land Before Time, The - Into the Mysterious Beyond (USA) (En,Fr,Es).gba" size 8388608 crc CFF03DF3 md5 CC966F781B2C7D2B61C5111063AA3E47 sha1 90F1F16591ACEAE35AF1277B3970963ED1C7C796 ) + rom ( name "Land Before Time, The - Into the Mysterious Beyond (USA) (En,Fr,Es).gba" size 8388608 crc cff03df3 sha1 90F1F16591ACEAE35AF1277B3970963ED1C7C796 ) ) game ( name "Lara Croft Tomb Raider - Legend (Europe) (En,Fr,De,Es,It)" description "Lara Croft Tomb Raider - Legend (Europe) (En,Fr,De,Es,It)" - rom ( name "Lara Croft Tomb Raider - Legend (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc E2FF36C7 md5 D147F80B54CFB16B1DF295AABAF4C90C sha1 F844AC89327747ACB081A0F733C0125F87672AEC ) + rom ( name "Lara Croft Tomb Raider - Legend (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc e2ff36c7 sha1 F844AC89327747ACB081A0F733C0125F87672AEC ) ) game ( name "Lara Croft Tomb Raider - Legend (USA) (En,Fr,De,Es,It)" description "Lara Croft Tomb Raider - Legend (USA) (En,Fr,De,Es,It)" - rom ( name "Lara Croft Tomb Raider - Legend (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 5A3DFB37 md5 2F3F8E8D7874528ACAC3B7B89CCF98DD sha1 D808E041537AFC49885232F9F1AFA3AFF5F8E512 ) -) - -game ( - name "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It)" - description "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It)" - rom ( name "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 556F40FA md5 BA38712AD91C6C0287298D4C53AD48B1 sha1 25D1C4C412ADA421B88A88DBA89A0FFD23F6F75D ) + rom ( name "Lara Croft Tomb Raider - Legend (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 5a3dfb37 sha1 D808E041537AFC49885232F9F1AFA3AFF5F8E512 ) ) game ( name "Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It)" description "Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It)" - rom ( name "Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4235FAC3 md5 627FB1625974C4D04E9E38CED12795CE sha1 E10A28DF676334C9B10C04D054DC81C262C6DA25 flags verified ) + rom ( name "Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4235fac3 sha1 E10A28DF676334C9B10C04D054DC81C262C6DA25 flags verified ) ) game ( name "Lara Croft Tomb Raider - The Prophecy (Japan)" description "Lara Croft Tomb Raider - The Prophecy (Japan)" - rom ( name "Lara Croft Tomb Raider - The Prophecy (Japan).gba" size 8388608 crc 7799E1DA md5 49E1AF3AFE0F16CD695DEF502120B380 sha1 87C98185D2641F71589076E74227F666B2C5C2E0 ) + rom ( name "Lara Croft Tomb Raider - The Prophecy (Japan).gba" size 8388608 crc 7799e1da sha1 87C98185D2641F71589076E74227F666B2C5C2E0 ) +) + +game ( + name "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It)" + description "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It)" + rom ( name "Lara Croft Tomb Raider - The Prophecy (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 556f40fa sha1 25D1C4C412ADA421B88A88DBA89A0FFD23F6F75D ) ) game ( name "Lea - Passion Veterinaire (France) (En,Fr)" description "Lea - Passion Veterinaire (France) (En,Fr)" - rom ( name "Lea - Passion Veterinaire (France) (En,Fr).gba" size 8388608 crc 6A808027 md5 0C3FE57084BBAE258EAC8830C90A0334 sha1 3F7855C918CB7050E4EFB0355855EA14F2FBB7FA flags verified ) + rom ( name "Lea - Passion Veterinaire (France) (En,Fr).gba" size 8388608 crc 6a808027 sha1 3F7855C918CB7050E4EFB0355855EA14F2FBB7FA flags verified ) ) game ( name "Legend of Dynamic Goushouden - Houkai no Rondo (Japan)" description "Legend of Dynamic Goushouden - Houkai no Rondo (Japan)" - rom ( name "Legend of Dynamic Goushouden - Houkai no Rondo (Japan).gba" size 8388608 crc 67F18F8E md5 35EB30C1013B72DF8EC4A71A1FC1ACFF sha1 8A037EFF3A44B1667EC5E81CA8C1FF03537366B2 ) + rom ( name "Legend of Dynamic Goushouden - Houkai no Rondo (Japan).gba" size 8388608 crc 67f18f8e sha1 8A037EFF3A44B1667EC5E81CA8C1FF03537366B2 flags verified ) ) game ( name "Legend of Spyro, The - A New Beginning (USA)" description "Legend of Spyro, The - A New Beginning (USA)" - rom ( name "Legend of Spyro, The - A New Beginning (USA).gba" size 16777216 crc 1B81CC00 md5 15FB7BB864E9876537890AF774B43DBF sha1 F5EA1DE26E8E7E342B9D579ADB427934B2EC22A4 ) + rom ( name "Legend of Spyro, The - A New Beginning (USA).gba" size 16777216 crc 1b81cc00 sha1 F5EA1DE26E8E7E342B9D579ADB427934B2EC22A4 ) ) game ( name "Legend of Spyro, The - A New Beginning (Europe) (En,Fr,De,Es,It,Nl)" description "Legend of Spyro, The - A New Beginning (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Legend of Spyro, The - A New Beginning (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 63DF4D36 md5 4445A111ACE93EC2920A1EB1DD5ACCAB sha1 722B70F7AC87BE0B8B6576FE8C8A82279F955E50 ) + rom ( name "Legend of Spyro, The - A New Beginning (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 63df4d36 sha1 722B70F7AC87BE0B8B6576FE8C8A82279F955E50 flags verified ) ) game ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr)" description "Legend of Spyro, The - The Eternal Night (USA) (En,Fr)" - rom ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr).gba" size 33554432 crc BD2751E6 md5 937589BB951827B8ED1CDAC1F78F5C35 sha1 4BC88F2C7325937BBE0F16DFEBDA10F279D5ED20 ) + rom ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr).gba" size 33554432 crc bd2751e6 sha1 4BC88F2C7325937BBE0F16DFEBDA10F279D5ED20 ) ) game ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl)" description "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 93B18353 md5 FE87F3053A6579E3BCB3FEF3332AABFA sha1 4BCE80310B43882F57C7BB5B202E09CE23687473 ) + rom ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 93b18353 sha1 4BCE80310B43882F57C7BB5B202E09CE23687473 ) ) game ( - name "Legend of Zelda, The - A Link to the Past & Four Swords (USA, Australia)" - description "Legend of Zelda, The - A Link to the Past & Four Swords (USA, Australia)" - rom ( name "Legend of Zelda, The - A Link to the Past & Four Swords (USA, Australia).gba" size 8388608 crc 8E91CD13 md5 3287CA66E5CC285A9FE3A922051E84C6 sha1 A272055ABBBF6C26B0CD54C87395D01699589161 flags verified ) + name "Legend of Zelda, The - A Link to the Past & Four Swords (USA)" + description "Legend of Zelda, The - A Link to the Past & Four Swords (USA)" + rom ( name "Legend of Zelda, The - A Link to the Past & Four Swords (USA).gba" size 8388608 crc 8e91cd13 sha1 A272055ABBBF6C26B0CD54C87395D01699589161 flags verified ) ) game ( name "Legend of Zelda, The - A Link to the Past & Four Swords (Europe) (En,Fr,De,Es,It)" description "Legend of Zelda, The - A Link to the Past & Four Swords (Europe) (En,Fr,De,Es,It)" - rom ( name "Legend of Zelda, The - A Link to the Past & Four Swords (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5A164321 md5 9EDF4F6E19D901D470AA1117CB0372B3 sha1 3BB7F97ADA7D60D8D334B271084EFFD1DB853B32 flags verified ) -) - -game ( - name "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk)" - description "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk)" - rom ( name "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk).gba" size 16777216 crc 023DA338 md5 5E12B81983F6D9624143D0143ECCF815 sha1 63FCAD218F9047B6A9EDBB68C98BD0DEC322D7A1 ) + rom ( name "Legend of Zelda, The - A Link to the Past & Four Swords (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5a164321 sha1 3BB7F97ADA7D60D8D334B271084EFFD1DB853B32 flags verified ) ) game ( name "Legend of Zelda, The - The Minish Cap (Europe) (En,Fr,De,Es,It)" description "Legend of Zelda, The - The Minish Cap (Europe) (En,Fr,De,Es,It)" - rom ( name "Legend of Zelda, The - The Minish Cap (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc E8637292 md5 2AF78EDBE244B5DE44471368AE2B6F0B sha1 CFF199B36FF173FB6FAF152653D1BCCF87C26FB7 flags verified ) + rom ( name "Legend of Zelda, The - The Minish Cap (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc e8637292 sha1 CFF199B36FF173FB6FAF152653D1BCCF87C26FB7 flags verified ) ) game ( name "Legend of Zelda, The - The Minish Cap (USA)" description "Legend of Zelda, The - The Minish Cap (USA)" - rom ( name "Legend of Zelda, The - The Minish Cap (USA).gba" size 16777216 crc ABCEBBB1 md5 A104896DA0047ABE8BEE2A6E3F4C7290 sha1 B4BD50E4131B027C334547B4524E2DBBD4227130 flags verified ) + rom ( name "Legend of Zelda, The - The Minish Cap (USA).gba" size 16777216 crc abcebbb1 sha1 B4BD50E4131B027C334547B4524E2DBBD4227130 flags verified ) +) + +game ( + name "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk)" + description "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk)" + rom ( name "Legend of Zelda, The - The Minish Cap (USA) (Demo) (Kiosk).gba" size 16777216 crc 023da338 sha1 63FCAD218F9047B6A9EDBB68C98BD0DEC322D7A1 ) ) game ( name "Legends of Wrestling II (USA, Europe)" description "Legends of Wrestling II (USA, Europe)" - rom ( name "Legends of Wrestling II (USA, Europe).gba" size 8388608 crc 84440066 md5 F4260E5DE1B9D68BC8B4AB42DE2F2109 sha1 971109B549ED39F597870AAB987DBC3C34BFF497 flags verified ) + rom ( name "Legends of Wrestling II (USA, Europe).gba" size 8388608 crc 84440066 sha1 971109B549ED39F597870AAB987DBC3C34BFF497 flags verified ) ) game ( name "Legendz - Buhwarhaneun Siryeonyi Seom (Korea)" description "Legendz - Buhwarhaneun Siryeonyi Seom (Korea)" - rom ( name "Legendz - Buhwarhaneun Siryeonyi Seom (Korea).gba" size 8388608 crc 8DF9759D md5 1C2DA9F487A4834C8021D7A307A55684 sha1 B074CFF4A2A281D4602B85B9211574CBF4408A31 ) + rom ( name "Legendz - Buhwarhaneun Siryeonyi Seom (Korea).gba" size 8388608 crc 8df9759d sha1 B074CFF4A2A281D4602B85B9211574CBF4408A31 ) ) game ( name "Legendz - Sign of Nekuromu (Japan)" description "Legendz - Sign of Nekuromu (Japan)" - rom ( name "Legendz - Sign of Nekuromu (Japan).gba" size 16777216 crc 98432A11 md5 43BA75F70DC113F7F72C2CE2E7B639BB sha1 0CF507F263991315DC6D9B1FA3783030A4BA5189 ) + rom ( name "Legendz - Sign of Nekuromu (Japan).gba" size 16777216 crc 98432a11 sha1 0CF507F263991315DC6D9B1FA3783030A4BA5189 ) ) game ( name "Legendz - Yomigaeru Shiren no Shima (Japan)" description "Legendz - Yomigaeru Shiren no Shima (Japan)" - rom ( name "Legendz - Yomigaeru Shiren no Shima (Japan).gba" size 8388608 crc 33950228 md5 9C7546D2FD1399614B035EAD1D66AA8D sha1 FF1E05A2FA70933DCF58A8BE4F82FA289647C28A flags verified ) + rom ( name "Legendz - Yomigaeru Shiren no Shima (Japan).gba" size 8388608 crc 33950228 sha1 FF1E05A2FA70933DCF58A8BE4F82FA289647C28A flags verified ) ) game ( name "LEGO Bionicle (USA) (En,Fr)" description "LEGO Bionicle (USA) (En,Fr)" - rom ( name "LEGO Bionicle (USA) (En,Fr).gba" size 8388608 crc 3E5EC871 md5 0E86C0C284F2CE03ED28359A765A66CE sha1 DA643E7DC8ACDE83001FEFC46969EB6F7AB17948 ) + rom ( name "LEGO Bionicle (USA) (En,Fr).gba" size 8388608 crc 3e5ec871 sha1 DA643E7DC8ACDE83001FEFC46969EB6F7AB17948 ) ) game ( name "LEGO Bionicle (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "LEGO Bionicle (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "LEGO Bionicle (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 121AB9C3 md5 6DECD38B78A1AAB5B895C85A1D380BCF sha1 CB2653E31CC80F0671090E31A753A856E65F58D5 flags verified ) -) - -game ( - name "LEGO Island - Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - description "LEGO Island - Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "LEGO Island - Xtreme Stunts (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 4194304 crc 3BEB5446 md5 081EB069AF9E5CDC0CB7515A7249BA52 sha1 4EEC876994BDEA873188FE10033C48C924D129EC flags verified ) + rom ( name "LEGO Bionicle (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 121ab9c3 sha1 CB2653E31CC80F0671090E31A753A856E65F58D5 flags verified ) ) game ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr)" description "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr)" - rom ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr).gba" size 8388608 crc 3F513CBF md5 4F6CFF217F4941EE1C7E8D8CD082A477 sha1 00FE8D6F16A8381D25B12CD0B5A45D54FCA6AD0E flags verified ) + rom ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr).gba" size 8388608 crc 3f513cbf sha1 00FE8D6F16A8381D25B12CD0B5A45D54FCA6AD0E flags verified ) ) game ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc C7B5D987 md5 EF13ADFFD0DC94ED7E417C253E78244D sha1 DB07408DE790DA24E313688CD85ABD69EEA6A21E ) + rom ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc c7b5d987 sha1 DB07408DE790DA24E313688CD85ABD69EEA6A21E ) ) game ( name "LEGO Racers 2 (USA) (En,Fr)" description "LEGO Racers 2 (USA) (En,Fr)" - rom ( name "LEGO Racers 2 (USA) (En,Fr).gba" size 8388608 crc E13B63AD md5 35CA3B91976497CC24384F9367F16462 sha1 293FFD94F1637C49CD5E29447399CCE602C6AB2F ) -) - -game ( - name "LEGO Racers 2 (Europe) (Beta)" - description "LEGO Racers 2 (Europe) (Beta)" - rom ( name "LEGO Racers 2 (Europe) (Beta).gba" size 8388608 crc 7D05AE2C md5 D4633C1BA39D6AB290CE9C8044574906 sha1 8C7620285CFD2CA951A902BB4D7AAB532C585300 ) + rom ( name "LEGO Racers 2 (USA) (En,Fr).gba" size 8388608 crc e13b63ad sha1 293FFD94F1637C49CD5E29447399CCE602C6AB2F ) ) game ( name "LEGO Racers 2 (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "LEGO Racers 2 (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "LEGO Racers 2 (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 7A1DC458 md5 39A754C5E3F4C7624A26E5FA97A2D178 sha1 A4DA0237646A4F56296465B92C659F3E7438AD98 ) + rom ( name "LEGO Racers 2 (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 7a1dc458 sha1 A4DA0237646A4F56296465B92C659F3E7438AD98 ) +) + +game ( + name "LEGO Racers 2 (Europe) (Beta)" + description "LEGO Racers 2 (Europe) (Beta)" + rom ( name "LEGO Racers 2 (Europe) (Beta).gba" size 8388608 crc 7d05ae2c sha1 8C7620285CFD2CA951A902BB4D7AAB532C585300 ) ) game ( name "LEGO Soccer Mania (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "LEGO Soccer Mania (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "LEGO Soccer Mania (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 73EF3A35 md5 3FF6F06DE88F0646E8CF85181CA2E10D sha1 05799B99395ABA04DFE5AE8AF019E4D70CB8E61B ) + rom ( name "LEGO Soccer Mania (USA, Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 73ef3a35 sha1 05799B99395ABA04DFE5AE8AF019E4D70CB8E61B ) ) game ( name "LEGO Star Wars - The Video Game (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" description "LEGO Star Wars - The Video Game (USA, Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "LEGO Star Wars - The Video Game (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc AEABFA5F md5 CAA2D80D5C14A76D1F482F7589281C22 sha1 827307B58BA4A877F4EF7425928D738B3E8EFC02 flags verified ) + rom ( name "LEGO Star Wars - The Video Game (USA, Europe) (En,Fr,De,Es,It,Nl,Da).gba" size 16777216 crc aeabfa5f sha1 827307B58BA4A877F4EF7425928D738B3E8EFC02 flags verified ) ) game ( name "LEGO Star Wars - The Video Game (Japan)" description "LEGO Star Wars - The Video Game (Japan)" - rom ( name "LEGO Star Wars - The Video Game (Japan).gba" size 16777216 crc 55A5AAF2 md5 875112ADCEB14C80EF4E67FDB4D37826 sha1 9293D599C28BD95FD97AE799E476A6FC8027F51F ) + rom ( name "LEGO Star Wars - The Video Game (Japan).gba" size 16777216 crc 55a5aaf2 sha1 9293D599C28BD95FD97AE799E476A6FC8027F51F ) ) game ( name "LEGO Star Wars II - The Original Trilogy (USA)" description "LEGO Star Wars II - The Original Trilogy (USA)" - rom ( name "LEGO Star Wars II - The Original Trilogy (USA).gba" size 16777216 crc DA1E9444 md5 BD64515FA58EC5052CE4D231E6241F23 sha1 38F640BE68981C258D435BF103AB443346FB5953 ) + rom ( name "LEGO Star Wars II - The Original Trilogy (USA).gba" size 16777216 crc da1e9444 sha1 38F640BE68981C258D435BF103AB443346FB5953 ) ) game ( name "LEGO Star Wars II - The Original Trilogy (Europe) (En,Fr,De,Es,It,Da)" description "LEGO Star Wars II - The Original Trilogy (Europe) (En,Fr,De,Es,It,Da)" - rom ( name "LEGO Star Wars II - The Original Trilogy (Europe) (En,Fr,De,Es,It,Da).gba" size 16777216 crc BBA91C3B md5 B5296CDA1C554337E684D880D7573B99 sha1 BC27A246E03733B7B3D3CBB2D342703B7DBEEAAE ) + rom ( name "LEGO Star Wars II - The Original Trilogy (Europe) (En,Fr,De,Es,It,Da).gba" size 16777216 crc bba91c3b sha1 BC27A246E03733B7B3D3CBB2D342703B7DBEEAAE ) ) game ( name "Lemony Snicket - Raetselhafte Ereignisse (Germany)" description "Lemony Snicket - Raetselhafte Ereignisse (Germany)" - rom ( name "Lemony Snicket - Raetselhafte Ereignisse (Germany).gba" size 16777216 crc F7AC3D9E md5 1953B83685EAEB7BF713091A77569E17 sha1 B04BADFBDA753C76DDDBADC1BE2089FCAAAB4214 ) + rom ( name "Lemony Snicket - Raetselhafte Ereignisse (Germany).gba" size 16777216 crc f7ac3d9e sha1 B04BADFBDA753C76DDDBADC1BE2089FCAAAB4214 ) ) game ( name "Lemony Snicket - Una Serie di Sfortunati Eventi (Italy)" description "Lemony Snicket - Una Serie di Sfortunati Eventi (Italy)" - rom ( name "Lemony Snicket - Una Serie di Sfortunati Eventi (Italy).gba" size 16777216 crc AA6E22D7 md5 972EF647FBBBBB4D53A38DC9F56079B6 sha1 817B1A464682D088FF712C2E0ACE56948B5EED5A ) + rom ( name "Lemony Snicket - Una Serie di Sfortunati Eventi (Italy).gba" size 16777216 crc aa6e22d7 sha1 817B1A464682D088FF712C2E0ACE56948B5EED5A ) ) game ( name "Lemony Snicket's A Series of Unfortunate Events (USA, Europe)" description "Lemony Snicket's A Series of Unfortunate Events (USA, Europe)" - rom ( name "Lemony Snicket's A Series of Unfortunate Events (USA, Europe).gba" size 16777216 crc 72BA6B8C md5 49A2135D9680E86ED881BF1458FE4746 sha1 F852812F37B3FB8FAE36354E2213DA3DB4804C36 flags verified ) + rom ( name "Lemony Snicket's A Series of Unfortunate Events (USA, Europe).gba" size 16777216 crc 72ba6b8c sha1 F852812F37B3FB8FAE36354E2213DA3DB4804C36 flags verified ) ) game ( name "Lemony Snicket's A Series of Unfortunate Events (Europe) (Fr,Es)" description "Lemony Snicket's A Series of Unfortunate Events (Europe) (Fr,Es)" - rom ( name "Lemony Snicket's A Series of Unfortunate Events (Europe) (Fr,Es).gba" size 16777216 crc 63E02A0D md5 5952EE810C9D2A1203D6873B8004D24A sha1 8FB149DAF6BDDA4195CC2307C08DC75D434AE8AC ) + rom ( name "Lemony Snicket's A Series of Unfortunate Events (Europe) (Fr,Es).gba" size 16777216 crc 63e02a0d sha1 8FB149DAF6BDDA4195CC2307C08DC75D434AE8AC ) ) game ( name "Let's Ride! - Dreamer (USA)" description "Let's Ride! - Dreamer (USA)" - rom ( name "Let's Ride! - Dreamer (USA).gba" size 4194304 crc 1D96366C md5 A2F0659905664D9A6AAFCF9E7A80FCAC sha1 B8138BAA3540AA5B122FB3901770CA98517F2411 ) + rom ( name "Let's Ride! - Dreamer (USA).gba" size 4194304 crc 1d96366c sha1 B8138BAA3540AA5B122FB3901770CA98517F2411 ) ) game ( name "Let's Ride! - Friends Forever (USA)" description "Let's Ride! - Friends Forever (USA)" - rom ( name "Let's Ride! - Friends Forever (USA).gba" size 8388608 crc 8BDD13AD md5 4F842F672B681ABB0410464C762871C8 sha1 703F325EFCCBAB71E6AA16AC6D22DD9DE3E0F9B6 ) + rom ( name "Let's Ride! - Friends Forever (USA).gba" size 8388608 crc 8bdd13ad sha1 703F325EFCCBAB71E6AA16AC6D22DD9DE3E0F9B6 ) ) game ( name "Let's Ride! - Sunshine Stables (USA)" description "Let's Ride! - Sunshine Stables (USA)" - rom ( name "Let's Ride! - Sunshine Stables (USA).gba" size 4194304 crc 684EB887 md5 F323312B0676C7BF845F2F7B8E90459C sha1 29FA6CFF3DF328E45925343B8C73C1DB2C3E16C7 ) + rom ( name "Let's Ride! - Sunshine Stables (USA).gba" size 4194304 crc 684eb887 sha1 29FA6CFF3DF328E45925343B8C73C1DB2C3E16C7 ) ) game ( name "Licca-chan no Oshare Nikki (Japan)" description "Licca-chan no Oshare Nikki (Japan)" - rom ( name "Licca-chan no Oshare Nikki (Japan).gba" size 8388608 crc E9F62FE0 md5 3FAF3E72406462A47821172F48F3DC0B sha1 AD6EDC1452C1258F51B162809EDF3AA473FD371C ) + rom ( name "Licca-chan no Oshare Nikki (Japan).gba" size 8388608 crc e9f62fe0 sha1 AD6EDC1452C1258F51B162809EDF3AA473FD371C ) ) game ( name "Lilliput Oukoku - Lillimoni to Issho Puni! (Japan)" description "Lilliput Oukoku - Lillimoni to Issho Puni! (Japan)" - rom ( name "Lilliput Oukoku - Lillimoni to Issho Puni! (Japan).gba" size 8388608 crc 1AFAB451 md5 3F925CE53E5BE7627638B7D3DF80947E sha1 2398C5A41BA0DCE5467981A56CD38AF52F5A9F35 ) -) - -game ( - name "Lilo & Stitch (Japan)" - description "Lilo & Stitch (Japan)" - rom ( name "Lilo & Stitch (Japan).gba" size 8388608 crc DB1E7311 md5 7E7015A37C1A5AA3D1B626B2255D0B01 sha1 14BA561F0E6498786067ED37BA2BE703A5A77BBC ) + rom ( name "Lilliput Oukoku - Lillimoni to Issho Puni! (Japan).gba" size 8388608 crc 1afab451 sha1 2398C5A41BA0DCE5467981A56CD38AF52F5A9F35 ) ) game ( name "Lilo & Stitch (USA)" description "Lilo & Stitch (USA)" - rom ( name "Lilo & Stitch (USA).gba" size 8388608 crc 542AA4AC md5 D2D38D0CA1C3594C71213E3B5F6BD6EC sha1 B86E22F7009AE20C0D8EFC51AB7C61C0CEE21A0C ) + rom ( name "Lilo & Stitch (USA).gba" size 8388608 crc 542aa4ac sha1 B86E22F7009AE20C0D8EFC51AB7C61C0CEE21A0C ) ) game ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl)" description "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 2A10F7E4 md5 3A1325D0AFA9EC59246673FB01878A09 sha1 49455B812ED129AB57A7765D8E82253930751485 flags verified ) + rom ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 2a10f7e4 sha1 49455B812ED129AB57A7765D8E82253930751485 flags verified ) +) + +game ( + name "Lilo & Stitch (Japan)" + description "Lilo & Stitch (Japan)" + rom ( name "Lilo & Stitch (Japan).gba" size 8388608 crc db1e7311 sha1 14BA561F0E6498786067ED37BA2BE703A5A77BBC ) ) game ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" description "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" - serial "AGB-ALTP-EUR-1" - rom ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc E7BC4EF1 md5 E7EAD9536E55C3C6FF2448712CD77EFB sha1 A4E86401593C1763FDD70C6E1F7B4CCEC7101DB7 ) + rom ( name "Lilo & Stitch (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc e7bc4ef1 sha1 A4E86401593C1763FDD70C6E1F7B4CCEC7101DB7 flags verified ) ) game ( name "Lilo & Stitch 2 (Europe) (En,Fr,De,Es)" description "Lilo & Stitch 2 (Europe) (En,Fr,De,Es)" - rom ( name "Lilo & Stitch 2 (Europe) (En,Fr,De,Es).gba" size 8388608 crc A88587A6 md5 E309212ADC8DA5280235F8765649858E sha1 8A3C17617C2EE950B43616A3CF9D6279FDE21050 flags verified ) + rom ( name "Lilo & Stitch 2 (Europe) (En,Fr,De,Es).gba" size 8388608 crc a88587a6 sha1 8A3C17617C2EE950B43616A3CF9D6279FDE21050 flags verified ) ) game ( name "Lilo & Stitch 2 - Haemsterviel Havoc (USA)" description "Lilo & Stitch 2 - Haemsterviel Havoc (USA)" - rom ( name "Lilo & Stitch 2 - Haemsterviel Havoc (USA).gba" size 8388608 crc 021A5755 md5 3034C7101BCEEBDEA95300AE9ECD7453 sha1 70E0DC5A8DCDF876B5DD87A4C1BBCA03B6E30148 ) + rom ( name "Lilo & Stitch 2 - Haemsterviel Havoc (USA).gba" size 8388608 crc 021a5755 sha1 70E0DC5A8DCDF876B5DD87A4C1BBCA03B6E30148 ) ) game ( name "Lion King 1 1-2, The (USA)" description "Lion King 1 1-2, The (USA)" - rom ( name "Lion King 1 1-2, The (USA).gba" size 8388608 crc EA5ED4C0 md5 6A987DC5A8F0E87E1E055EE65F7E99C9 sha1 382DE6DA61C5DC5C2844F5FFA28A1827D15319B1 flags verified ) + rom ( name "Lion King 1 1-2, The (USA).gba" size 8388608 crc ea5ed4c0 sha1 382DE6DA61C5DC5C2844F5FFA28A1827D15319B1 flags verified ) ) game ( name "Lion King, The (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Lion King, The (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Lion King, The (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 63592451 md5 3F1CB5398649FF0C43673E73CAD3010E sha1 41EE9ED772264A2BB2EDB8ADFC7E9D3A58B00392 flags verified ) + rom ( name "Lion King, The (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 63592451 sha1 41EE9ED772264A2BB2EDB8ADFC7E9D3A58B00392 flags verified ) ) game ( name "Little Buster Q (Japan)" description "Little Buster Q (Japan)" - rom ( name "Little Buster Q (Japan).gba" size 8388608 crc D26E49F8 md5 20447EF4715492164D65EBCDF26BD568 sha1 DEB26A35E398C22801F5A7AA5E68A723E47ECC5E ) + rom ( name "Little Buster Q (Japan).gba" size 8388608 crc d26e49f8 sha1 DEB26A35E398C22801F5A7AA5E68A723E47ECC5E ) ) game ( name "Little Einsteins (USA)" description "Little Einsteins (USA)" - rom ( name "Little Einsteins (USA).gba" size 8388608 crc C8340B37 md5 5A20B7AF9D051A12D80986A2980FC1C2 sha1 77554BD4A954A34023571D5976C5F0696B6FE744 flags verified ) + rom ( name "Little Einsteins (USA).gba" size 8388608 crc c8340b37 sha1 77554BD4A954A34023571D5976C5F0696B6FE744 flags verified ) ) game ( name "Little League Baseball 2002 (USA) (En,Es)" description "Little League Baseball 2002 (USA) (En,Es)" - rom ( name "Little League Baseball 2002 (USA) (En,Es).gba" size 8388608 crc B550F8CB md5 1923216A92A9D7B4640C39A37B6A612B sha1 8CC3DA732100657568A684B27A3ED08D674E4BDB ) + rom ( name "Little League Baseball 2002 (USA) (En,Es).gba" size 8388608 crc b550f8cb sha1 8CC3DA732100657568A684B27A3ED08D674E4BDB ) ) game ( name "Little Mermaid, The - Magic in Two Kingdoms (USA, Europe) (En,Fr,De,Es,It)" description "Little Mermaid, The - Magic in Two Kingdoms (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Little Mermaid, The - Magic in Two Kingdoms (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 02E35663 md5 A05C86D8C5291049EBD22304AD9C2029 sha1 C75A4FE95BD27BAAD3D800F6F8D66603A18FFADB flags verified ) + rom ( name "Little Mermaid, The - Magic in Two Kingdoms (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 02e35663 sha1 C75A4FE95BD27BAAD3D800F6F8D66603A18FFADB flags verified ) ) game ( name "Little Patissier - Cake no Oshiro (Japan)" description "Little Patissier - Cake no Oshiro (Japan)" - rom ( name "Little Patissier - Cake no Oshiro (Japan).gba" size 8388608 crc 8FEA41C4 md5 45743F2F955F66284775CB3C23CC46E8 sha1 8D121CFEB6C88A4CF2D34F8E9979811D60543D6D ) + rom ( name "Little Patissier - Cake no Oshiro (Japan).gba" size 8388608 crc 8fea41c4 sha1 8D121CFEB6C88A4CF2D34F8E9979811D60543D6D flags verified ) ) game ( name "Lizzie McGuire (Europe) (En,Fr,De,Es)" description "Lizzie McGuire (Europe) (En,Fr,De,Es)" - rom ( name "Lizzie McGuire (Europe) (En,Fr,De,Es).gba" size 4194304 crc 7E9283F2 md5 1DE6184D96452BED659BC732915ECB0E sha1 50786B17708D91C05EC3C3058A3A1106F524FAE3 flags verified ) + rom ( name "Lizzie McGuire (Europe) (En,Fr,De,Es).gba" size 4194304 crc 7e9283f2 sha1 50786B17708D91C05EC3C3058A3A1106F524FAE3 flags verified ) ) game ( name "Lizzie McGuire - On the Go! (USA)" description "Lizzie McGuire - On the Go! (USA)" - rom ( name "Lizzie McGuire - On the Go! (USA).gba" size 4194304 crc 70DED768 md5 D6B12981296A8E3C67796F94E2D7AFF3 sha1 084ADD8893BAE03836D33A1C7BDEDE5F12741663 ) + rom ( name "Lizzie McGuire - On the Go! (USA).gba" size 4194304 crc 70ded768 sha1 084ADD8893BAE03836D33A1C7BDEDE5F12741663 ) ) game ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" description "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr)" - rom ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 4194304 crc F11009F9 md5 5F98EC175E2C67D3BA28504C1706DC07 sha1 7ACE37AEC21C058AA98E3DE12140CB691C070E00 ) + rom ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 4194304 crc f11009f9 sha1 7ACE37AEC21C058AA98E3DE12140CB691C070E00 ) ) game ( name "Lizzie McGuire 3 - Homecoming Havoc (USA)" description "Lizzie McGuire 3 - Homecoming Havoc (USA)" - rom ( name "Lizzie McGuire 3 - Homecoming Havoc (USA).gba" size 8388608 crc A2843980 md5 AEF559CA2B6F1EE37C423B46BB4FF909 sha1 991F6FA3EA46F00B3A1E553EA89C4AAFC4F2E8A6 ) + rom ( name "Lizzie McGuire 3 - Homecoming Havoc (USA).gba" size 8388608 crc a2843980 sha1 991F6FA3EA46F00B3A1E553EA89C4AAFC4F2E8A6 ) ) game ( name "Lode Runner (Japan)" description "Lode Runner (Japan)" - rom ( name "Lode Runner (Japan).gba" size 4194304 crc 3E2CF3FF md5 704943BD18075740BC9157A34D8C612F sha1 4A52758503A0B6FFF2F42277686A6D0C2DBD07F8 ) + rom ( name "Lode Runner (Japan).gba" size 4194304 crc 3e2cf3ff sha1 4A52758503A0B6FFF2F42277686A6D0C2DBD07F8 ) ) game ( name "Looney Tunes - Back in Action (USA, Europe) (En,Fr,De,Es,It)" description "Looney Tunes - Back in Action (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Looney Tunes - Back in Action (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2B8B3964 md5 C7407014742F1F2EE538F9EC8458265F sha1 4DD3450826739935DF46EF212F161B31BF38CCC3 flags verified ) + rom ( name "Looney Tunes - Back in Action (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2b8b3964 sha1 4DD3450826739935DF46EF212F161B31BF38CCC3 flags verified ) ) game ( name "Looney Tunes Double Pack (Europe)" description "Looney Tunes Double Pack (Europe)" - rom ( name "Looney Tunes Double Pack (Europe).gba" size 8388608 crc DCA23B31 md5 60782A90B8D365BF0DBE723034F8B3DA sha1 2E8A157DAA0B0031F629940846412B9F8197F8A1 ) + rom ( name "Looney Tunes Double Pack (Europe).gba" size 8388608 crc dca23b31 sha1 2E8A157DAA0B0031F629940846412B9F8197F8A1 flags verified ) ) game ( name "Looney Tunes Double Pack (USA)" description "Looney Tunes Double Pack (USA)" - rom ( name "Looney Tunes Double Pack (USA).gba" size 8388608 crc ECADD047 md5 678CFF8D9901D9C7ABEDB2272968A74E sha1 0CF436E0DB36BDC87DA7E55C6FF504969A6F1398 ) + rom ( name "Looney Tunes Double Pack (USA).gba" size 8388608 crc ecadd047 sha1 0CF436E0DB36BDC87DA7E55C6FF504969A6F1398 ) ) game ( name "Lord of the Rings, The - Futatsu no Tou (Japan)" description "Lord of the Rings, The - Futatsu no Tou (Japan)" - rom ( name "Lord of the Rings, The - Futatsu no Tou (Japan).gba" size 16777216 crc DC8D4667 md5 19C9594B78D51C9B24F5FB79E463756F sha1 93B4AD2379FCF3354B07D8847A99428D45DD3699 ) + rom ( name "Lord of the Rings, The - Futatsu no Tou (Japan).gba" size 16777216 crc dc8d4667 sha1 93B4AD2379FCF3354B07D8847A99428D45DD3699 ) ) game ( name "Lord of the Rings, The - Nakatsukuni Daisanki (Japan)" description "Lord of the Rings, The - Nakatsukuni Daisanki (Japan)" - rom ( name "Lord of the Rings, The - Nakatsukuni Daisanki (Japan).gba" size 16777216 crc CF0534F8 md5 7D7032D0E64B277F99C11F6C2D3A2289 sha1 B7127D022E185808B852C345381428AA18CF0C5D ) + rom ( name "Lord of the Rings, The - Nakatsukuni Daisanki (Japan).gba" size 16777216 crc cf0534f8 sha1 B7127D022E185808B852C345381428AA18CF0C5D ) ) game ( name "Lord of the Rings, The - Ou no Kikan (Japan)" description "Lord of the Rings, The - Ou no Kikan (Japan)" - rom ( name "Lord of the Rings, The - Ou no Kikan (Japan).gba" size 16777216 crc 465F2753 md5 555821A2C6E7E91A712EACBE92922FF5 sha1 ACA8E3DDCE987EE072B54D06A3C563E3C84F9964 ) + rom ( name "Lord of the Rings, The - Ou no Kikan (Japan).gba" size 16777216 crc 465f2753 sha1 ACA8E3DDCE987EE072B54D06A3C563E3C84F9964 ) ) game ( name "Lord of the Rings, The - The Fellowship of the Ring (USA)" description "Lord of the Rings, The - The Fellowship of the Ring (USA)" - rom ( name "Lord of the Rings, The - The Fellowship of the Ring (USA).gba" size 8388608 crc EE0C58BC md5 644712A277E801997624CECE31B661A9 sha1 4B77BA458B593CA35166E9A9792792AC92E263DF ) + rom ( name "Lord of the Rings, The - The Fellowship of the Ring (USA).gba" size 8388608 crc ee0c58bc sha1 4B77BA458B593CA35166E9A9792792AC92E263DF ) ) game ( name "Lord of the Rings, The - The Fellowship of the Ring (Europe) (En,Fr,De,Es,It)" description "Lord of the Rings, The - The Fellowship of the Ring (Europe) (En,Fr,De,Es,It)" - rom ( name "Lord of the Rings, The - The Fellowship of the Ring (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2380B93A md5 0D6241BF502D0CEF1CA57870A1024E72 sha1 F330DE5440F561E9FB0F808876261EE124230F9F ) + rom ( name "Lord of the Rings, The - The Fellowship of the Ring (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2380b93a sha1 F330DE5440F561E9FB0F808876261EE124230F9F flags verified ) +) + +game ( + name "Lord of the Rings, The - The Fellowship of the Ring (USA) (Rev 1)" + description "Lord of the Rings, The - The Fellowship of the Ring (USA) (Rev 1)" + rom ( name "Lord of the Rings, The - The Fellowship of the Ring (USA) (Rev 1).gba" size 8388608 crc 5a2b01f1 sha1 C2B709A07E8BDBAB265500EA4AE740C123BF944B flags verified ) ) game ( name "Lord of the Rings, The - The Return of the King (USA, Europe) (En,Fr,De,Es,It)" description "Lord of the Rings, The - The Return of the King (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Lord of the Rings, The - The Return of the King (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7590EBFA md5 53DCB149B4593FBA9955F842889445B4 sha1 EC3D126D37EA6E2AD7030D8A99CF87C6E46C03FD flags verified ) + rom ( name "Lord of the Rings, The - The Return of the King (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 7590ebfa sha1 EC3D126D37EA6E2AD7030D8A99CF87C6E46C03FD flags verified ) ) game ( name "Lord of the Rings, The - The Third Age (USA, Europe) (En,Fr,De,Es,It)" description "Lord of the Rings, The - The Third Age (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Lord of the Rings, The - The Third Age (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2DEF3656 md5 39D7F5579BEAFC2D3CFB0485C5BE3BDF sha1 0A7A704D2BA167EB2DC03AD5DCFA0F09EA982A54 flags verified ) + rom ( name "Lord of the Rings, The - The Third Age (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2def3656 sha1 0A7A704D2BA167EB2DC03AD5DCFA0F09EA982A54 flags verified ) ) game ( name "Lord of the Rings, The - The Two Towers (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Lord of the Rings, The - The Two Towers (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Lord of the Rings, The - The Two Towers (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc A1E3BF33 md5 E3BEBB876BF45CA598800E3A90D6B2F0 sha1 82B3B4AFB0ED0D3FCA646AA266E0BFC5BFFD49D9 flags verified ) + rom ( name "Lord of the Rings, The - The Two Towers (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc a1e3bf33 sha1 82B3B4AFB0ED0D3FCA646AA266E0BFC5BFFD49D9 flags verified ) ) game ( name "Lost Vikings, The (Europe) (En,Fr,De,Es)" description "Lost Vikings, The (Europe) (En,Fr,De,Es)" - rom ( name "Lost Vikings, The (Europe) (En,Fr,De,Es).gba" size 4194304 crc 1C008D32 md5 092721060C0261C13DE6ADE3E8C87854 sha1 3C48005F1EA64CEFA0B165793C537CA68507C572 flags verified ) + rom ( name "Lost Vikings, The (Europe) (En,Fr,De,Es).gba" size 4194304 crc 1c008d32 sha1 3C48005F1EA64CEFA0B165793C537CA68507C572 flags verified ) ) game ( name "Lost Vikings, The (USA)" description "Lost Vikings, The (USA)" - rom ( name "Lost Vikings, The (USA).gba" size 4194304 crc 8CB58997 md5 36C04FE38BA46CFF285B060907DB94F6 sha1 670AFFD3E3CF3F80F939517421ED7927C0C14310 ) + rom ( name "Lost Vikings, The (USA).gba" size 4194304 crc 8cb58997 sha1 670AFFD3E3CF3F80F939517421ED7927C0C14310 flags verified ) ) game ( name "Love Hina Advance - Shukufuku no Kane wa Naru Kana (Japan)" description "Love Hina Advance - Shukufuku no Kane wa Naru Kana (Japan)" - rom ( name "Love Hina Advance - Shukufuku no Kane wa Naru Kana (Japan).gba" size 8388608 crc B8E67449 md5 53BFC207DD7320AD7DB94E299ADCA245 sha1 C52F2F584A8DADD7130687FFEE512FAAE1AC7463 ) + rom ( name "Love Hina Advance - Shukufuku no Kane wa Naru Kana (Japan).gba" size 8388608 crc b8e67449 sha1 C52F2F584A8DADD7130687FFEE512FAAE1AC7463 ) +) + +game ( + name "Lu-Hai-Kong Dazhan (China) (Proto)" + description "Lu-Hai-Kong Dazhan (China) (Proto)" + rom ( name "Lu-Hai-Kong Dazhan (China) (Proto).gba" size 8388608 crc e166e6ed sha1 FCA8D30CB57B0602D84947B869717542E4632733 flags verified ) ) game ( name "Lucky Luke - Wanted! (Europe) (En,Fr,De,Es,It,Nl)" description "Lucky Luke - Wanted! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Lucky Luke - Wanted! (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc F12F29A9 md5 2AB4CAFACF54E34053B34527539B7E5B sha1 14326F299CCB0A7AEEF64FE68A0E6FE28CFA14CB flags verified ) + rom ( name "Lucky Luke - Wanted! (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc f12f29a9 sha1 14326F299CCB0A7AEEF64FE68A0E6FE28CFA14CB flags verified ) ) game ( name "Lufia - The Ruins of Lore (USA)" description "Lufia - The Ruins of Lore (USA)" - rom ( name "Lufia - The Ruins of Lore (USA).gba" size 8388608 crc DE5FFCBC md5 22B31AA8F66E7C6528FD4903A09F030F sha1 A2B7E80A6C7D586EBEEC77C8A2C2545FE27E0592 ) + rom ( name "Lufia - The Ruins of Lore (USA).gba" size 8388608 crc de5ffcbc sha1 A2B7E80A6C7D586EBEEC77C8A2C2545FE27E0592 flags verified ) ) game ( name "Lunar Legend (Japan)" description "Lunar Legend (Japan)" - rom ( name "Lunar Legend (Japan).gba" size 8388608 crc 4E044191 md5 1E087998D7F24A69579D107F7671F7DB sha1 483B2C37330CF914C121801ACD9F15776F92EB29 ) + rom ( name "Lunar Legend (Japan).gba" size 8388608 crc 4e044191 sha1 483B2C37330CF914C121801ACD9F15776F92EB29 ) ) game ( name "Lunar Legend (USA)" description "Lunar Legend (USA)" - rom ( name "Lunar Legend (USA).gba" size 8388608 crc 885266A2 md5 AE5EE35F0AADF386CB6918A2D83F5A3B sha1 D7109FA4A03D50E24BD9E61446BDEB03B42732FF flags verified ) + rom ( name "Lunar Legend (USA).gba" size 8388608 crc 885266a2 sha1 D7109FA4A03D50E24BD9E61446BDEB03B42732FF flags verified ) ) game ( name "M&M's - Blast! (USA)" description "M&M's - Blast! (USA)" - rom ( name "M&M's - Blast! (USA).gba" size 8388608 crc AD38C301 md5 2CE9DC7E0E3AF0BE2B1D0D487555AA6A sha1 F717D3547AEEDF19921124A647D5DC70D6B61D1E ) + rom ( name "M&M's - Blast! (USA).gba" size 8388608 crc ad38c301 sha1 F717D3547AEEDF19921124A647D5DC70D6B61D1E ) ) game ( - name "M&M's - Break 'em (USA) (Rev 1)" - description "M&M's - Break 'em (USA) (Rev 1)" - rom ( name "M&M's - Break 'em (USA) (Rev 1).gba" size 4194304 crc A4EA65C0 md5 8C5C04D6559A700903C7186E0BAEE2FE sha1 5DC56DB613A0A27B7724CBE8889FD2BA3A0993D9 ) -) - -game ( - name "Madagascar (Europe)" - description "Madagascar (Europe)" - rom ( name "Madagascar (Europe).gba" size 8388608 crc 394F2126 md5 11E59F830FEC5702011173CAC6C9C7D9 sha1 30E85193A92AE6FA4DD1C54EA76D629276789657 ) -) - -game ( - name "Madagascar (Spain)" - description "Madagascar (Spain)" - rom ( name "Madagascar (Spain).gba" size 8388608 crc 0C6070B5 md5 AA99D027561A92EB5A5AF4E48F6E560C sha1 B7EB23D81889849EE8DC74BD64341B4633E16648 ) -) - -game ( - name "Madagascar (Italy)" - description "Madagascar (Italy)" - rom ( name "Madagascar (Italy).gba" size 8388608 crc 9467225B md5 8CACC135E731B3B3E268676A8D2FC2FC sha1 2894F85AA51824FFC1A85B9B13B46628BF6F7E4A ) -) - -game ( - name "Madagascar (Japan)" - description "Madagascar (Japan)" - rom ( name "Madagascar (Japan).gba" size 8388608 crc 2D6D478C md5 1070A9C7392722B1224F6DA39096598E sha1 6CDB13F057A3C1445C0FCC4D7B362580B1EF9AD6 ) -) - -game ( - name "Madagascar (Netherlands)" - description "Madagascar (Netherlands)" - rom ( name "Madagascar (Netherlands).gba" size 8388608 crc EBFAB740 md5 12BFE2B37EB53EEC924CA2A697FC9924 sha1 FE66E53862EB6C18B2C6831DC646CEE50E2AAF70 ) + name "M&M's - Break' Em (USA) (Rev 1)" + description "M&M's - Break' Em (USA) (Rev 1)" + rom ( name "M&M's - Break' Em (USA) (Rev 1).gba" size 4194304 crc a4ea65c0 sha1 5DC56DB613A0A27B7724CBE8889FD2BA3A0993D9 flags verified ) ) game ( name "Madagascar (USA)" description "Madagascar (USA)" - rom ( name "Madagascar (USA).gba" size 8388608 crc 7503F71B md5 97AF9C00A5718832B7E5E46F9E434820 sha1 3F1E8C5ECEA68CF812ACFFA4670F0F30266C5952 ) + rom ( name "Madagascar (USA).gba" size 8388608 crc 7503f71b sha1 3F1E8C5ECEA68CF812ACFFA4670F0F30266C5952 ) ) game ( name "Madagascar (Europe) (Fr,De,Pt)" description "Madagascar (Europe) (Fr,De,Pt)" - rom ( name "Madagascar (Europe) (Fr,De,Pt).gba" size 8388608 crc 274C9135 md5 B06F2E981AA7702E7A13602F8E5013D1 sha1 E86F17CDB49BE8751EE5000E519E02F1E32D733B ) + rom ( name "Madagascar (Europe) (Fr,De,Pt).gba" size 8388608 crc 274c9135 sha1 E86F17CDB49BE8751EE5000E519E02F1E32D733B flags verified ) +) + +game ( + name "Madagascar (Europe)" + description "Madagascar (Europe)" + rom ( name "Madagascar (Europe).gba" size 8388608 crc 394f2126 sha1 30E85193A92AE6FA4DD1C54EA76D629276789657 ) +) + +game ( + name "Madagascar (Spain)" + description "Madagascar (Spain)" + rom ( name "Madagascar (Spain).gba" size 8388608 crc 0c6070b5 sha1 B7EB23D81889849EE8DC74BD64341B4633E16648 ) +) + +game ( + name "Madagascar (Italy)" + description "Madagascar (Italy)" + rom ( name "Madagascar (Italy).gba" size 8388608 crc 9467225b sha1 2894F85AA51824FFC1A85B9B13B46628BF6F7E4A ) +) + +game ( + name "Madagascar (Japan)" + description "Madagascar (Japan)" + rom ( name "Madagascar (Japan).gba" size 8388608 crc 2d6d478c sha1 6CDB13F057A3C1445C0FCC4D7B362580B1EF9AD6 ) +) + +game ( + name "Madagascar (Netherlands)" + description "Madagascar (Netherlands)" + rom ( name "Madagascar (Netherlands).gba" size 8388608 crc ebfab740 sha1 FE66E53862EB6C18B2C6831DC646CEE50E2AAF70 ) ) game ( name "Madagascar - Operacion Pinguino (Spain)" description "Madagascar - Operacion Pinguino (Spain)" - rom ( name "Madagascar - Operacion Pinguino (Spain).gba" size 8388608 crc 5B519E47 md5 85B9EE894AC4A5D21F3F9DD473EDEBDC sha1 3B9F93D67020FA5CFFCCC23D10D02C7A0B99FA7D ) + rom ( name "Madagascar - Operacion Pinguino (Spain).gba" size 8388608 crc 5b519e47 sha1 3B9F93D67020FA5CFFCCC23D10D02C7A0B99FA7D ) ) game ( name "Madagascar - Operation Penguin (USA)" description "Madagascar - Operation Penguin (USA)" - rom ( name "Madagascar - Operation Penguin (USA).gba" size 8388608 crc DA3FA501 md5 87DA43AAAD7B9FD2B8AF57E8E3C71283 sha1 D9C26B324FE29729B76C028E194DC97ADF5BCCAA ) + rom ( name "Madagascar - Operation Penguin (USA).gba" size 8388608 crc da3fa501 sha1 D9C26B324FE29729B76C028E194DC97ADF5BCCAA ) ) game ( name "Madagascar - Operation Penguin (Europe) (Fr,De)" description "Madagascar - Operation Penguin (Europe) (Fr,De)" - rom ( name "Madagascar - Operation Penguin (Europe) (Fr,De).gba" size 8388608 crc 6B5B70C5 md5 2DA2E4ACDC19C3FCC3E66F8F4CFD3606 sha1 FACA3026CBD32EDDC8B9F2FAC1A40D9CA248A065 ) + rom ( name "Madagascar - Operation Penguin (Europe) (Fr,De).gba" size 8388608 crc 6b5b70c5 sha1 FACA3026CBD32EDDC8B9F2FAC1A40D9CA248A065 ) ) game ( name "Madagascar - Operation Penguin (Europe) (It,Nl)" description "Madagascar - Operation Penguin (Europe) (It,Nl)" - rom ( name "Madagascar - Operation Penguin (Europe) (It,Nl).gba" size 8388608 crc 8D8B5808 md5 B038A9370B9A3924D38FAA4EAE6254D3 sha1 F360B9F2217E3E1739D6591EB33CC730C2879474 ) + rom ( name "Madagascar - Operation Penguin (Europe) (It,Nl).gba" size 8388608 crc 8d8b5808 sha1 F360B9F2217E3E1739D6591EB33CC730C2879474 ) ) game ( name "Madagascar - Operation Penguin (Europe)" description "Madagascar - Operation Penguin (Europe)" - rom ( name "Madagascar - Operation Penguin (Europe).gba" size 8388608 crc 15BB7278 md5 9CC7DCF1D0F07687ABEEC84995C226B2 sha1 F33187BBC0187DD3BDBAAEC6F88380BF2F107AB2 ) + rom ( name "Madagascar - Operation Penguin (Europe).gba" size 8388608 crc 15bb7278 sha1 F33187BBC0187DD3BDBAAEC6F88380BF2F107AB2 flags verified ) ) game ( name "Madden NFL 06 (USA)" description "Madden NFL 06 (USA)" - rom ( name "Madden NFL 06 (USA).gba" size 4194304 crc 374FD6F9 md5 37FE4EEAB5274D244E5E6853881307AD sha1 4771F0A36D52F59F02E9DA1F87CC89D9E179BA9F ) + rom ( name "Madden NFL 06 (USA).gba" size 4194304 crc 374fd6f9 sha1 4771F0A36D52F59F02E9DA1F87CC89D9E179BA9F ) ) game ( name "Madden NFL 07 (USA)" description "Madden NFL 07 (USA)" - rom ( name "Madden NFL 07 (USA).gba" size 4194304 crc C5805B1D md5 7CB3748CBF790D4E8B50926B28299153 sha1 FD62EDCF3C30B8F2A821A5DBFE67AA50F150FEAE ) + rom ( name "Madden NFL 07 (USA).gba" size 4194304 crc c5805b1d sha1 FD62EDCF3C30B8F2A821A5DBFE67AA50F150FEAE ) ) game ( name "Madden NFL 2002 (USA)" description "Madden NFL 2002 (USA)" - rom ( name "Madden NFL 2002 (USA).gba" size 4194304 crc 8E797ECD md5 D20405DFB7B446FBEB365A5CC11233C3 sha1 9B26D3E3E641059E93EFEB0732B413A375402339 ) + rom ( name "Madden NFL 2002 (USA).gba" size 4194304 crc 8e797ecd sha1 9B26D3E3E641059E93EFEB0732B413A375402339 ) ) game ( name "Madden NFL 2003 (USA)" description "Madden NFL 2003 (USA)" - rom ( name "Madden NFL 2003 (USA).gba" size 4194304 crc 64B93824 md5 D8C148895DC874B51F5075AEBFCEF88A sha1 E2F4E66FA582303D06F79E572E19E80462A7CC42 ) + rom ( name "Madden NFL 2003 (USA).gba" size 4194304 crc 64b93824 sha1 E2F4E66FA582303D06F79E572E19E80462A7CC42 ) ) game ( name "Madden NFL 2004 (USA)" description "Madden NFL 2004 (USA)" - rom ( name "Madden NFL 2004 (USA).gba" size 4194304 crc 170BB11A md5 197DC540682B32E2022FEC2EC543BE1A sha1 8C932F469D7D66F604FA6A34ADFA3ACEA5B7F63E flags verified ) + rom ( name "Madden NFL 2004 (USA).gba" size 4194304 crc 170bb11a sha1 8C932F469D7D66F604FA6A34ADFA3ACEA5B7F63E flags verified ) ) game ( name "Madden NFL 2005 (USA)" description "Madden NFL 2005 (USA)" - rom ( name "Madden NFL 2005 (USA).gba" size 4194304 crc 0B79A67B md5 32490CD20B8E808DA9C45AA82FA4800A sha1 8D549EACD9C6F182743FE9CE442AB3C2F9048939 ) + rom ( name "Madden NFL 2005 (USA).gba" size 4194304 crc 0b79a67b sha1 8D549EACD9C6F182743FE9CE442AB3C2F9048939 ) ) game ( name "Made in Wario (Japan)" description "Made in Wario (Japan)" - rom ( name "Made in Wario (Japan).gba" size 8388608 crc 87A0EEA0 md5 A7589564716D173192E290E9C97E040A sha1 1776D55134D373F71404E818B236462AEDFCE9E7 ) + rom ( name "Made in Wario (Japan).gba" size 8388608 crc 87a0eea0 sha1 1776D55134D373F71404E818B236462AEDFCE9E7 flags verified ) +) + +game ( + name "Made in Wario (Japan) (Wii U Virtual Console)" + description "Made in Wario (Japan) (Wii U Virtual Console)" + rom ( name "Made in Wario (Japan) (Wii U Virtual Console).gba" size 8388608 crc ee98906f sha1 B3ABD619AA358873C8E56E0499B526E7DF4BB725 flags verified ) +) + +game ( + name "Made in Wario (Japan) (Demo) (Kiosk, GameCube)" + description "Made in Wario (Japan) (Demo) (Kiosk, GameCube)" + rom ( name "Made in Wario (Japan) (Demo) (Kiosk, GameCube).gba" size 8388608 crc 11ff7a67 sha1 6CF7EF0A7BD3D270967BFC8667750A0F3A00D06F flags verified ) ) game ( name "MAER Heaven - Knockin' on Heaven's Door (Japan)" description "MAER Heaven - Knockin' on Heaven's Door (Japan)" - rom ( name "MAER Heaven - Knockin' on Heaven's Door (Japan).gba" size 16777216 crc EF6807CA md5 14371B084ED7CAA4B8E533D111254310 sha1 5ED178BFBDF459867D64E5B91A9D9C72654E4051 ) + rom ( name "MAER Heaven - Knockin' on Heaven's Door (Japan).gba" size 16777216 crc ef6807ca sha1 5ED178BFBDF459867D64E5B91A9D9C72654E4051 ) ) game ( name "Magi Nation (Japan)" description "Magi Nation (Japan)" - rom ( name "Magi Nation (Japan).gba" size 8388608 crc 6A94531B md5 27EBADFF2F3B46AE0BF7A198B5F29952 sha1 870CDE605033525BE0D250F87BFA68D7D56AE372 ) + rom ( name "Magi Nation (Japan).gba" size 8388608 crc 6a94531b sha1 870CDE605033525BE0D250F87BFA68D7D56AE372 ) ) game ( name "Magical Houshin (Japan)" description "Magical Houshin (Japan)" - rom ( name "Magical Houshin (Japan).gba" size 8388608 crc 70123550 md5 AC79EAA4C54CEC46F8D6D9878C11A390 sha1 38554B0E03FA8C0F4E220F3EA0DC58DA9D080FF4 ) + rom ( name "Magical Houshin (Japan).gba" size 8388608 crc 70123550 sha1 38554B0E03FA8C0F4E220F3EA0DC58DA9D080FF4 ) ) game ( name "Magical Quest 2 Starring Mickey & Minnie (Europe) (En,Fr,De)" description "Magical Quest 2 Starring Mickey & Minnie (Europe) (En,Fr,De)" - rom ( name "Magical Quest 2 Starring Mickey & Minnie (Europe) (En,Fr,De).gba" size 4194304 crc F9498038 md5 9A56BC96339193E7C198C20D2CA11AFE sha1 1CAC78EB9F6A9079F1A02D48DCD1CE4C7A81350B flags verified ) + rom ( name "Magical Quest 2 Starring Mickey & Minnie (Europe) (En,Fr,De).gba" size 4194304 crc f9498038 sha1 1CAC78EB9F6A9079F1A02D48DCD1CE4C7A81350B flags verified ) ) game ( name "Magical Quest 2 Starring Mickey & Minnie (USA) (En,Fr,De)" description "Magical Quest 2 Starring Mickey & Minnie (USA) (En,Fr,De)" - rom ( name "Magical Quest 2 Starring Mickey & Minnie (USA) (En,Fr,De).gba" size 4194304 crc 69F1117D md5 9397EE8E46CD0357D49AF1CFF6FD97B3 sha1 85358586E818913485DA97089910712ADAF4EB69 ) + rom ( name "Magical Quest 2 Starring Mickey & Minnie (USA) (En,Fr,De).gba" size 4194304 crc 69f1117d sha1 85358586E818913485DA97089910712ADAF4EB69 ) ) game ( name "Magical Quest 3 Starring Mickey & Donald (Europe) (En,Fr,De)" description "Magical Quest 3 Starring Mickey & Donald (Europe) (En,Fr,De)" - rom ( name "Magical Quest 3 Starring Mickey & Donald (Europe) (En,Fr,De).gba" size 8388608 crc AAD912F9 md5 941E3164CD26480ED03EEB997C7D95C3 sha1 63E7BB2812C0ABFC50F9A082251C6A86DEED3687 ) + rom ( name "Magical Quest 3 Starring Mickey & Donald (Europe) (En,Fr,De).gba" size 8388608 crc aad912f9 sha1 63E7BB2812C0ABFC50F9A082251C6A86DEED3687 flags verified ) ) game ( name "Magical Quest 3 Starring Mickey & Donald (USA) (En,Fr,De)" description "Magical Quest 3 Starring Mickey & Donald (USA) (En,Fr,De)" - rom ( name "Magical Quest 3 Starring Mickey & Donald (USA) (En,Fr,De).gba" size 8388608 crc 5A23094D md5 47FE0FE1EE054AC37E286FB909E49BE0 sha1 6FD2FFE2F1FFC25F27FAE00631AB7733D08F86EA ) + rom ( name "Magical Quest 3 Starring Mickey & Donald (USA) (En,Fr,De).gba" size 8388608 crc 5a23094d sha1 6FD2FFE2F1FFC25F27FAE00631AB7733D08F86EA ) ) game ( name "Magical Quest Starring Mickey & Minnie (USA)" description "Magical Quest Starring Mickey & Minnie (USA)" - rom ( name "Magical Quest Starring Mickey & Minnie (USA).gba" size 4194304 crc B4294FA7 md5 6B0DA7E87963D644D4DDAABE107F09BF sha1 BD4EA484E8DBDC2343FF5712BF84A6D15FB28AD3 ) + rom ( name "Magical Quest Starring Mickey & Minnie (USA).gba" size 4194304 crc b4294fa7 sha1 BD4EA484E8DBDC2343FF5712BF84A6D15FB28AD3 ) ) game ( name "Magical Quest Starring Mickey & Minnie (Europe) (En,Fr,De,Es,It)" description "Magical Quest Starring Mickey & Minnie (Europe) (En,Fr,De,Es,It)" - rom ( name "Magical Quest Starring Mickey & Minnie (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 94F3B7C0 md5 1A97A68CE320FD9EDA568A724EA1BFB4 sha1 00A58654C699FF5C45D3C5228D5ABD7C28E59EF2 ) + rom ( name "Magical Quest Starring Mickey & Minnie (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 94f3b7c0 sha1 00A58654C699FF5C45D3C5228D5ABD7C28E59EF2 flags verified ) ) game ( name "Magical Vacation (Japan)" description "Magical Vacation (Japan)" - rom ( name "Magical Vacation (Japan).gba" size 8388608 crc 59CBE914 md5 814CD6FB465041DA0C39C40D89993339 sha1 565225D6B02DA909D3CF04ADAF419170BABA35AC flags verified ) + rom ( name "Magical Vacation (Japan).gba" size 8388608 crc 59cbe914 sha1 565225D6B02DA909D3CF04ADAF419170BABA35AC flags verified ) ) game ( name "Mahjong Keiji (Japan)" description "Mahjong Keiji (Japan)" - rom ( name "Mahjong Keiji (Japan).gba" size 4194304 crc AD32A2D3 md5 6AA8F04421AD88F8F854FD0525B5A1A0 sha1 94279F146B5E62D6A29C67C6D1893137E1941270 ) + rom ( name "Mahjong Keiji (Japan).gba" size 4194304 crc ad32a2d3 sha1 94279F146B5E62D6A29C67C6D1893137E1941270 ) ) game ( name "Mahou no Pumpkin - Ann to Greg no Daibouken (Japan)" description "Mahou no Pumpkin - Ann to Greg no Daibouken (Japan)" - rom ( name "Mahou no Pumpkin - Ann to Greg no Daibouken (Japan).gba" size 4194304 crc F9652B4D md5 8DAEE9FE02459C2084D461D4F2E8E481 sha1 A42D4104E0D0D8D9B2B2196D745237D640795215 ) + rom ( name "Mahou no Pumpkin - Ann to Greg no Daibouken (Japan).gba" size 4194304 crc f9652b4d sha1 A42D4104E0D0D8D9B2B2196D745237D640795215 ) ) game ( name "Mahou Sensei Negima! - Private Lesson - Damedesuu Toshokan-jima (Japan)" description "Mahou Sensei Negima! - Private Lesson - Damedesuu Toshokan-jima (Japan)" - rom ( name "Mahou Sensei Negima! - Private Lesson - Damedesuu Toshokan-jima (Japan).gba" size 8388608 crc 79D04DAD md5 7FD1EC249C6145ADB5C2E284513B8078 sha1 087D9283AA07E69FE1B1B6F56FB780C52A7D02F8 ) + rom ( name "Mahou Sensei Negima! - Private Lesson - Damedesuu Toshokan-jima (Japan).gba" size 8388608 crc 79d04dad sha1 087D9283AA07E69FE1B1B6F56FB780C52A7D02F8 flags verified ) ) game ( name "Mahou Sensei Negima! - Private Lesson 2 - Ojamashimasuu Parasite de Chuu (Japan)" description "Mahou Sensei Negima! - Private Lesson 2 - Ojamashimasuu Parasite de Chuu (Japan)" - rom ( name "Mahou Sensei Negima! - Private Lesson 2 - Ojamashimasuu Parasite de Chuu (Japan).gba" size 16777216 crc 6357C53B md5 2047548FDB416C3EBE15CA34FC16E773 sha1 75F0E96D806B57B1667C66844AC94B1DFCB47210 ) + rom ( name "Mahou Sensei Negima! - Private Lesson 2 - Ojamashimasuu Parasite de Chuu (Japan).gba" size 16777216 crc 6357c53b sha1 75F0E96D806B57B1667C66844AC94B1DFCB47210 ) ) game ( name "Mail de Cute (Japan)" description "Mail de Cute (Japan)" - rom ( name "Mail de Cute (Japan).gba" size 8388608 crc 3B984291 md5 DB7362F49C853C61B8DE8E4CA8750C18 sha1 C153539CCCEF50E6D5F32347746381626D365268 ) -) - -game ( - name "Majesco's Rec Room Challenge (Europe)" - description "Majesco's Rec Room Challenge (Europe)" - rom ( name "Majesco's Rec Room Challenge (Europe).gba" size 4194304 crc 4FBC3F62 md5 178627A0A81F7E79F3549C4EF122E7D5 sha1 034F886B18821A00CE7F98FDD91C1C164800BDEF ) -) - -game ( - name "Majesco's Rec Room Challenge (USA)" - description "Majesco's Rec Room Challenge (USA)" - rom ( name "Majesco's Rec Room Challenge (USA).gba" size 4194304 crc AAFC9AFA md5 DCC2DB8FAFAF3BB28B8896B89B707175 sha1 A085803150CC3685B946F4C617D1D833E602A47B ) + rom ( name "Mail de Cute (Japan).gba" size 8388608 crc 3b984291 sha1 C153539CCCEF50E6D5F32347746381626D365268 ) ) game ( name "Majesco's Sports Pack (Europe)" description "Majesco's Sports Pack (Europe)" - rom ( name "Majesco's Sports Pack (Europe).gba" size 8388608 crc 99140705 md5 8CAD01D7436766CDA2734AF52189C056 sha1 73583CEBDC96398373B916F410531E88D97F87A1 ) + rom ( name "Majesco's Sports Pack (Europe).gba" size 8388608 crc 99140705 sha1 73583CEBDC96398373B916F410531E88D97F87A1 ) ) game ( name "Majesco's Sports Pack (USA)" description "Majesco's Sports Pack (USA)" - rom ( name "Majesco's Sports Pack (USA).gba" size 8388608 crc A91BEC73 md5 EEDD67A815E798E19159237A4D151D1A sha1 82A01A4395146F01B235B1ADCB266ABC96FC26EA ) + rom ( name "Majesco's Sports Pack (USA).gba" size 8388608 crc a91bec73 sha1 82A01A4395146F01B235B1ADCB266ABC96FC26EA ) ) game ( name "Majokko Cream-chan no Gokko Series 1 - Wannyan Idol Gakuen (Japan)" description "Majokko Cream-chan no Gokko Series 1 - Wannyan Idol Gakuen (Japan)" - rom ( name "Majokko Cream-chan no Gokko Series 1 - Wannyan Idol Gakuen (Japan).gba" size 4194304 crc 91BEBBEE md5 1D82AD717DE36B8025770049EF4FB934 sha1 0007603E37ADFEC491FBCE8EA510E22F777EC805 ) + rom ( name "Majokko Cream-chan no Gokko Series 1 - Wannyan Idol Gakuen (Japan).gba" size 4194304 crc 91bebbee sha1 0007603E37ADFEC491FBCE8EA510E22F777EC805 ) ) game ( name "Majokko Cream-chan no Gokko Series 2 - Kisekae Angel (Japan)" description "Majokko Cream-chan no Gokko Series 2 - Kisekae Angel (Japan)" - rom ( name "Majokko Cream-chan no Gokko Series 2 - Kisekae Angel (Japan).gba" size 8388608 crc 2ED6C55F md5 14C864DA7A500FFC5CCC7139FB7EF053 sha1 449A3599EAFEED92D6D90CBCCF3992F6FC087A4F ) + rom ( name "Majokko Cream-chan no Gokko Series 2 - Kisekae Angel (Japan).gba" size 8388608 crc 2ed6c55f sha1 449A3599EAFEED92D6D90CBCCF3992F6FC087A4F ) +) + +game ( + name "Maliou Kadingche - Chaoji Saidao (China) (Proto)" + description "Maliou Kadingche - Chaoji Saidao (China) (Proto)" + rom ( name "Maliou Kadingche - Chaoji Saidao (China) (Proto).gba" size 8388608 crc 36201d7c sha1 C3D02578DBD7F465BDFA177ED111F0DD74205C69 flags verified ) +) + +game ( + name "Maliou Yu Luyiji RPG (China) (Proto)" + description "Maliou Yu Luyiji RPG (China) (Proto)" + rom ( name "Maliou Yu Luyiji RPG (China) (Proto).gba" size 16777216 crc 5574b73e sha1 CFD0BFF1B0CA5576A58012D1BA02FFE6B9E91FA2 flags verified ) +) + +game ( + name "Mandrake the Magician (Italy) (Proto)" + description "Mandrake the Magician (Italy) (Proto)" + rom ( name "Mandrake the Magician (Italy) (Proto).gba" size 8388608 crc 7cfe1889 sha1 DDB5F0CDD5DB80C22A448650C1B05D02FEB0B831 flags verified ) ) game ( name "Manga-ka Debut Monogatari (Japan)" description "Manga-ka Debut Monogatari (Japan)" - rom ( name "Manga-ka Debut Monogatari (Japan).gba" size 4194304 crc 61A602D7 md5 9C62897F2997C1FB8919533E7AF3F1C5 sha1 5F7C1B88B8C7CAA57A0AF81CD3AE74171ABE50D1 ) + rom ( name "Manga-ka Debut Monogatari (Japan).gba" size 4194304 crc 61a602d7 sha1 5F7C1B88B8C7CAA57A0AF81CD3AE74171ABE50D1 ) ) game ( name "Manga-ka Debut Monogatari (Japan) (Rev 1)" description "Manga-ka Debut Monogatari (Japan) (Rev 1)" - rom ( name "Manga-ka Debut Monogatari (Japan) (Rev 1).gba" size 4194304 crc F0C22C62 md5 819C5498A8D6ACFB847764E296ED9CDD sha1 78C57D1062830074166DA3192B01D0D0AE9AFAEB ) + rom ( name "Manga-ka Debut Monogatari (Japan) (Rev 1).gba" size 4194304 crc f0c22c62 sha1 78C57D1062830074166DA3192B01D0D0AE9AFAEB ) ) game ( name "Maniac Racers Advance (Europe) (En,Fr,De,Es,It)" description "Maniac Racers Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Maniac Racers Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2412C5EB md5 38D7FC6D3804B6F80557096FA2AEB1FE sha1 EC8BA8E51DD42C3267DEAB0F9AD1701C53D0E763 ) + rom ( name "Maniac Racers Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2412c5eb sha1 EC8BA8E51DD42C3267DEAB0F9AD1701C53D0E763 ) ) game ( name "Manic Miner (Europe) (En,Fr,De,Es,It)" description "Manic Miner (Europe) (En,Fr,De,Es,It)" - rom ( name "Manic Miner (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 138439F4 md5 786FC5AFF6A10EFD3E3585BA10EBC863 sha1 C9F2AF2BF740A42065C585798507D925543AA512 flags verified ) + rom ( name "Manic Miner (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 138439f4 sha1 C9F2AF2BF740A42065C585798507D925543AA512 flags verified ) ) game ( name "March of the Penguins (USA)" description "March of the Penguins (USA)" - rom ( name "March of the Penguins (USA).gba" size 4194304 crc 5195429F md5 DE2924A164D2B89F5080E0003D16894C sha1 FED20DF4C0093BFDC59122362BC7B17C62B727AB ) + rom ( name "March of the Penguins (USA).gba" size 4194304 crc 5195429f sha1 FED20DF4C0093BFDC59122362BC7B17C62B727AB ) ) game ( name "March of the Penguins (Europe) (En,Fr,De,Es,It)" description "March of the Penguins (Europe) (En,Fr,De,Es,It)" - rom ( name "March of the Penguins (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc F680B0F3 md5 21D31C0F9843E08AE60419098B0105F3 sha1 E8DABCA44763139C8C148359916BE8DBE98ECF83 ) + rom ( name "March of the Penguins (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc f680b0f3 sha1 E8DABCA44763139C8C148359916BE8DBE98ECF83 ) ) game ( name "Marie, Elie & Anis no Atelier - Soyokaze kara no Dengon (Japan)" description "Marie, Elie & Anis no Atelier - Soyokaze kara no Dengon (Japan)" - rom ( name "Marie, Elie & Anis no Atelier - Soyokaze kara no Dengon (Japan).gba" size 8388608 crc 1B70A454 md5 31EDE9E787E0F60729B2898F4E18116E sha1 0DBDE8BCAA9E4BDC201674A0D66C6CE64242EB4B ) + rom ( name "Marie, Elie & Anis no Atelier - Soyokaze kara no Dengon (Japan).gba" size 8388608 crc 1b70a454 sha1 0DBDE8BCAA9E4BDC201674A0D66C6CE64242EB4B ) ) game ( name "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It)" description "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It)" - rom ( name "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 170CC574 md5 3B50B9F9E13E271EAD33EE5A234650A9 sha1 FA2314C2FBE0DB1AB17175F8BE7CCEB0AB084EFC flags verified ) + rom ( name "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 170cc574 sha1 FA2314C2FBE0DB1AB17175F8BE7CCEB0AB084EFC flags verified ) ) game ( - name "Mario & Luigi - Superstar Saga (USA, Australia)" - description "Mario & Luigi - Superstar Saga (USA, Australia)" - rom ( name "Mario & Luigi - Superstar Saga (USA, Australia).gba" size 16777216 crc E718D850 md5 4B1A5897D89D9E74EC7F630EEFDFD435 sha1 7C303CDDE5061EE329296948060B875CB50BA410 flags verified ) + name "Mario & Luigi - Superstar Saga (USA)" + description "Mario & Luigi - Superstar Saga (USA)" + rom ( name "Mario & Luigi - Superstar Saga (USA).gba" size 16777216 crc e718d850 sha1 7C303CDDE5061EE329296948060B875CB50BA410 flags verified ) ) game ( name "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk)" description "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk)" - rom ( name "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk).gba" size 8388608 crc A94B04B2 md5 0D36CEDE54581698AC841E4895DAE45B sha1 E235A9A617626CFF6B0B572D6F6144FA8FFB6719 ) + rom ( name "Mario & Luigi - Superstar Saga (USA) (Demo) (Kiosk).gba" size 8388608 crc a94b04b2 sha1 E235A9A617626CFF6B0B572D6F6144FA8FFB6719 ) +) + +game ( + name "Mario & Luigi - Superstar Saga (USA) (Wii U Virtual Console)" + description "Mario & Luigi - Superstar Saga (USA) (Wii U Virtual Console)" + rom ( name "Mario & Luigi - Superstar Saga (USA) (Wii U Virtual Console).gba" size 16777216 crc f87ea3c3 sha1 4EC07ADFF2F432BD665FAF67C6C861EDA60DE4E1 flags verified ) +) + +game ( + name "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Mario & Luigi - Superstar Saga (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 16777216 crc 6a5bd4f0 sha1 790E6241916F35EEF7AD9EF0CA238199F628B2E0 flags verified ) ) game ( name "Mario & Luigi RPG (Japan)" description "Mario & Luigi RPG (Japan)" - rom ( name "Mario & Luigi RPG (Japan).gba" size 16777216 crc 4EF93D41 md5 D571970F19FAFDBCDDDB71A02563317E sha1 EDC538AC505BFCD337ABDD03B3A6F2744D81EAAB ) + rom ( name "Mario & Luigi RPG (Japan).gba" size 16777216 crc 4ef93d41 sha1 EDC538AC505BFCD337ABDD03B3A6F2744D81EAAB ) ) game ( name "Mario Golf - Advance Tour (USA)" description "Mario Golf - Advance Tour (USA)" - rom ( name "Mario Golf - Advance Tour (USA).gba" size 16777216 crc D56C2E54 md5 2E8814E664675572A43B01900BBBB16B sha1 157058590CFB1D1CB83A3AFAC4847C2169F360A7 flags verified ) + rom ( name "Mario Golf - Advance Tour (USA).gba" size 16777216 crc d56c2e54 sha1 157058590CFB1D1CB83A3AFAC4847C2169F360A7 flags verified ) ) game ( name "Mario Golf - Advance Tour (Australia)" description "Mario Golf - Advance Tour (Australia)" - rom ( name "Mario Golf - Advance Tour (Australia).gba" size 16777216 crc D6AD422F md5 F30650403DC5BBF73037C1364D747DF5 sha1 0730CE80F2016AEF121775DF16EA35B4DFFAD240 ) + rom ( name "Mario Golf - Advance Tour (Australia).gba" size 16777216 crc d6ad422f sha1 0730CE80F2016AEF121775DF16EA35B4DFFAD240 ) ) game ( name "Mario Golf - Advance Tour (Germany)" description "Mario Golf - Advance Tour (Germany)" - rom ( name "Mario Golf - Advance Tour (Germany).gba" size 16777216 crc 3E19E279 md5 9F22C000F0134489E952348213557F0D sha1 327E98D9E48B88EAA8FEB48DF54E5411F71807DB flags verified ) + rom ( name "Mario Golf - Advance Tour (Germany).gba" size 16777216 crc 3e19e279 sha1 327E98D9E48B88EAA8FEB48DF54E5411F71807DB flags verified ) ) game ( name "Mario Golf - Advance Tour (Italy)" description "Mario Golf - Advance Tour (Italy)" - rom ( name "Mario Golf - Advance Tour (Italy).gba" size 16777216 crc 05B0454A md5 B786FD9C2D48188C7BDB32F29B742187 sha1 D1524EFE0A090580251335CE3EACF6EDBCCB0A8E ) + rom ( name "Mario Golf - Advance Tour (Italy).gba" size 16777216 crc 05b0454a sha1 D1524EFE0A090580251335CE3EACF6EDBCCB0A8E ) ) game ( name "Mario Golf - Advance Tour (France)" description "Mario Golf - Advance Tour (France)" - rom ( name "Mario Golf - Advance Tour (France).gba" size 16777216 crc BD5BE463 md5 4984C5FC1E916516728521D4E5E16036 sha1 F99DD1FB1D468FC67B46920687F890F5A14036C5 ) + rom ( name "Mario Golf - Advance Tour (France).gba" size 16777216 crc bd5be463 sha1 F99DD1FB1D468FC67B46920687F890F5A14036C5 ) ) game ( name "Mario Golf - Advance Tour (Spain)" description "Mario Golf - Advance Tour (Spain)" - rom ( name "Mario Golf - Advance Tour (Spain).gba" size 16777216 crc C35DD9F8 md5 9964136D79B1D6560E1E87957A845F3A sha1 AEFCB7F122B73B6678AE373243D62A02386CC4BC ) + rom ( name "Mario Golf - Advance Tour (Spain).gba" size 16777216 crc c35dd9f8 sha1 AEFCB7F122B73B6678AE373243D62A02386CC4BC ) ) game ( name "Mario Golf - Advance Tour (Europe)" description "Mario Golf - Advance Tour (Europe)" - rom ( name "Mario Golf - Advance Tour (Europe).gba" size 16777216 crc B483127C md5 B79C5C98E01FCF89CBA5431278C9076F sha1 D66DEFF7C2D82E033F1E39B940048B4BDAADD825 flags verified ) + rom ( name "Mario Golf - Advance Tour (Europe).gba" size 16777216 crc b483127c sha1 D66DEFF7C2D82E033F1E39B940048B4BDAADD825 flags verified ) +) + +game ( + name "Mario Golf - Advance Tour (Europe) (Wii U Virtual Console)" + description "Mario Golf - Advance Tour (Europe) (Wii U Virtual Console)" + rom ( name "Mario Golf - Advance Tour (Europe) (Wii U Virtual Console).gba" size 16777216 crc 41a4729f sha1 5D9DEF24CC44D9B58BDDF2B607B22E291B417B3D flags verified ) ) game ( name "Mario Golf - GBA Tour (Japan)" description "Mario Golf - GBA Tour (Japan)" - rom ( name "Mario Golf - GBA Tour (Japan).gba" size 16777216 crc A8342A16 md5 DE0FD2E4E4C888EED0719511095EFD22 sha1 CCD3A22C65336A65290D641C17FFD0D2A5A57BE2 flags verified ) + rom ( name "Mario Golf - GBA Tour (Japan).gba" size 16777216 crc a8342a16 sha1 CCD3A22C65336A65290D641C17FFD0D2A5A57BE2 flags verified ) +) + +game ( + name "Mario Kart - Double Dash!! (USA) (Fire Emblem GBA - Bonus Items)" + description "Mario Kart - Double Dash!! (USA) (Fire Emblem GBA - Bonus Items)" + rom ( name "Mario Kart - Double Dash!! (USA) (Fire Emblem GBA - Bonus Items).gba" size 59396 crc a4cb79e1 sha1 1248770A6798E99DE68B9D08D0E27E3F893C3047 flags verified ) ) game ( name "Mario Kart - Super Circuit (USA)" description "Mario Kart - Super Circuit (USA)" - rom ( name "Mario Kart - Super Circuit (USA).gba" size 4194304 crc ED316E37 md5 784A036FF1AAE709E90167186639B75E sha1 9D327C030C3E2D9007990518594F70C3340AC56F flags verified ) + rom ( name "Mario Kart - Super Circuit (USA).gba" size 4194304 crc ed316e37 sha1 9D327C030C3E2D9007990518594F70C3340AC56F flags verified ) ) game ( name "Mario Kart - Super Circuit (Europe)" description "Mario Kart - Super Circuit (Europe)" - rom ( name "Mario Kart - Super Circuit (Europe).gba" size 4194304 crc 20025842 md5 F99FB545AC65126E9956A7718C30D6A3 sha1 2CDFC94CBE7A7F4EFE00D98DD33EBB5F50CF91F0 flags verified ) + rom ( name "Mario Kart - Super Circuit (Europe).gba" size 4194304 crc 20025842 sha1 2CDFC94CBE7A7F4EFE00D98DD33EBB5F50CF91F0 flags verified ) +) + +game ( + name "Mario Kart - Super Circuit (USA) (Wii U Virtual Console)" + description "Mario Kart - Super Circuit (USA) (Wii U Virtual Console)" + rom ( name "Mario Kart - Super Circuit (USA) (Wii U Virtual Console).gba" size 4194304 crc c0e1cf38 sha1 BA53C107FE4F39018CFF94C0D532314FACC9AEF0 flags verified ) +) + +game ( + name "Mario Kart - Super Circuit (Europe) (Wii U Virtual Console)" + description "Mario Kart - Super Circuit (Europe) (Wii U Virtual Console)" + rom ( name "Mario Kart - Super Circuit (Europe) (Wii U Virtual Console).gba" size 4194304 crc 0dd2f94d sha1 E1DC3A1AA9A6A0FDF1726BB2728279A728101013 flags verified ) ) game ( name "Mario Kart Advance (Japan)" description "Mario Kart Advance (Japan)" - rom ( name "Mario Kart Advance (Japan).gba" size 4194304 crc 30E99FCD md5 F35D2F567EDD9C04E7F9647EDB206995 sha1 88FFDE363B05264A99A4D5ADA0C80A00196A94D7 flags verified ) + rom ( name "Mario Kart Advance (Japan).gba" size 4194304 crc 30e99fcd sha1 88FFDE363B05264A99A4D5ADA0C80A00196A94D7 flags verified ) +) + +game ( + name "Mario Kart Advance (Japan) (Wii U Virtual Console)" + description "Mario Kart Advance (Japan) (Wii U Virtual Console)" + rom ( name "Mario Kart Advance (Japan) (Wii U Virtual Console).gba" size 4194304 crc 3bd8a4f0 sha1 7061696811F424F875AF5AF837DC49EFF802A63A flags verified ) +) + +game ( + name "Mario Kart Advance (Japan) (3DS Virtual Console)" + description "Mario Kart Advance (Japan) (3DS Virtual Console)" + rom ( name "Mario Kart Advance (Japan) (3DS Virtual Console).gba" size 4194304 crc 85493f2c sha1 D740F9E662C6CB372EB141BD50160B6AB19FD1DB flags verified ) ) game ( name "Mario Party Advance (Japan)" description "Mario Party Advance (Japan)" - rom ( name "Mario Party Advance (Japan).gba" size 8388608 crc BAA4A82B md5 E4E07FCE7C412ECBB7117A58FA235409 sha1 F99EB117FF81995B22E19A34437938113E32C69A ) + rom ( name "Mario Party Advance (Japan).gba" size 8388608 crc baa4a82b sha1 F99EB117FF81995B22E19A34437938113E32C69A ) ) game ( name "Mario Party Advance (USA)" description "Mario Party Advance (USA)" - rom ( name "Mario Party Advance (USA).gba" size 8388608 crc F094A4CB md5 9D0D27345BF88DE8B025AA24D54D6BAD sha1 FA917D74D592260C3D6142A969FCBD94156F956B ) + rom ( name "Mario Party Advance (USA).gba" size 8388608 crc f094a4cb sha1 FA917D74D592260C3D6142A969FCBD94156F956B flags verified ) ) game ( name "Mario Party Advance (Europe) (En,Fr,De,Es,It)" description "Mario Party Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Mario Party Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc C8C889E2 md5 0ACBC949FC02EC0ABD9E1825C03B8973 sha1 5D67695C08AFCE4098264BD986A55739CB6636CB flags verified ) + rom ( name "Mario Party Advance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc c8c889e2 sha1 5D67695C08AFCE4098264BD986A55739CB6636CB flags verified ) +) + +game ( + name "Mario Party Advance (USA) (Wii U Virtual Console)" + description "Mario Party Advance (USA) (Wii U Virtual Console)" + rom ( name "Mario Party Advance (USA) (Wii U Virtual Console).gba" size 8388608 crc 1d910a62 sha1 F23B5792D5ECFCE966E83F7FCC7C330542DA888D flags verified ) +) + +game ( + name "Mario Party Advance (Japan) (Wii U Virtual Console)" + description "Mario Party Advance (Japan) (Wii U Virtual Console)" + rom ( name "Mario Party Advance (Japan) (Wii U Virtual Console).gba" size 8388608 crc 9cd07025 sha1 D09C3DB0CF4A4A0FA5CAD3AE00AD3B4EC8603207 flags verified ) ) game ( name "Mario Pinball Land (USA, Australia)" description "Mario Pinball Land (USA, Australia)" - rom ( name "Mario Pinball Land (USA, Australia).gba" size 8388608 crc 70A6D2C1 md5 08C41541EB69A1D652937ED3F88824BE sha1 3FDCD3BB30D61B4DD6829DBDC1A0AC116618B87D flags verified ) + rom ( name "Mario Pinball Land (USA, Australia).gba" size 8388608 crc 70a6d2c1 sha1 3FDCD3BB30D61B4DD6829DBDC1A0AC116618B87D flags verified ) ) game ( name "Mario Power Tennis (Europe) (En,Fr,De,Es,It)" description "Mario Power Tennis (Europe) (En,Fr,De,Es,It)" - rom ( name "Mario Power Tennis (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc C8DB4F60 md5 F6C0A645317D6ED90ABC4E04F7B33B46 sha1 D61990974040D405B5BF8436AC8E1E0BEB0F7964 flags verified ) + rom ( name "Mario Power Tennis (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc c8db4f60 sha1 D61990974040D405B5BF8436AC8E1E0BEB0F7964 flags verified ) ) game ( name "Mario Tennis - Power Tour (USA, Australia) (En,Fr,De,Es,It)" description "Mario Tennis - Power Tour (USA, Australia) (En,Fr,De,Es,It)" - rom ( name "Mario Tennis - Power Tour (USA, Australia) (En,Fr,De,Es,It).gba" size 16777216 crc DA192D29 md5 928C0BD4CF82B3FD6F34B53D4FD02E69 sha1 794584ACBD15A69FB9AC760C0A6F48095805BD59 flags verified ) + rom ( name "Mario Tennis - Power Tour (USA, Australia) (En,Fr,De,Es,It).gba" size 16777216 crc da192d29 sha1 794584ACBD15A69FB9AC760C0A6F48095805BD59 flags verified ) +) + +game ( + name "Mario Tennis - Power Tour (USA) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Mario Tennis - Power Tour (USA) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Mario Tennis - Power Tour (USA) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 16777216 crc f763eecc sha1 A7CCB4DDDB6A1D9008FCCD799C6CEE027CC1013F flags verified ) ) game ( name "Mario Tennis Advance (Japan)" description "Mario Tennis Advance (Japan)" - rom ( name "Mario Tennis Advance (Japan).gba" size 16777216 crc 975E8D98 md5 A3658157B02A6F5618866AF93C9B771D sha1 434CDE6974421CD75977692882BA40A6539D3E8E flags verified ) + rom ( name "Mario Tennis Advance (Japan).gba" size 16777216 crc 975e8d98 sha1 434CDE6974421CD75977692882BA40A6539D3E8E flags verified ) ) game ( name "Mario vs. Donkey Kong (USA, Australia)" description "Mario vs. Donkey Kong (USA, Australia)" - rom ( name "Mario vs. Donkey Kong (USA, Australia).gba" size 16777216 crc 25C394D1 md5 CEDA12928A686878795DEF3B413CCFC2 sha1 DA677E595C41A0C72C4E3FEB3A7E716F17CACD77 flags verified ) + rom ( name "Mario vs. Donkey Kong (USA, Australia).gba" size 16777216 crc 25c394d1 sha1 DA677E595C41A0C72C4E3FEB3A7E716F17CACD77 flags verified ) ) game ( name "Mario vs. Donkey Kong (Japan)" description "Mario vs. Donkey Kong (Japan)" - rom ( name "Mario vs. Donkey Kong (Japan).gba" size 16777216 crc 7C2B5269 md5 665F0FD0DF241841961123ECF2CA73BA sha1 5DA406AB472E9BCBF8709842731525F8FCA35559 ) + rom ( name "Mario vs. Donkey Kong (Japan).gba" size 16777216 crc 7c2b5269 sha1 5DA406AB472E9BCBF8709842731525F8FCA35559 flags verified ) ) game ( name "Mario vs. Donkey Kong (Europe) (En,Fr,De,Es,It)" description "Mario vs. Donkey Kong (Europe) (En,Fr,De,Es,It)" - rom ( name "Mario vs. Donkey Kong (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc CA030D61 md5 A3DCA1A3167CB855AACDCA650C4CE39F sha1 C645798EA9CF94E2FD8826EA96A5971A7AEB52B7 flags verified ) + rom ( name "Mario vs. Donkey Kong (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ca030d61 sha1 C645798EA9CF94E2FD8826EA96A5971A7AEB52B7 flags verified ) +) + +game ( + name "Mario vs. Donkey Kong (USA) (Demo) (Kiosk, GameCube)" + description "Mario vs. Donkey Kong (USA) (Demo) (Kiosk, GameCube)" + rom ( name "Mario vs. Donkey Kong (USA) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 25505164 sha1 68EEBE6DBCF8973ED7426A793185DB202A01288F flags verified ) ) game ( name "Marvel - Ultimate Alliance (USA)" description "Marvel - Ultimate Alliance (USA)" - rom ( name "Marvel - Ultimate Alliance (USA).gba" size 8388608 crc A74294DB md5 1A9CC177B098FA1762B0E9872590916C sha1 FE621B8D156B85ED2EE77DBC1D2B84D16F330E67 ) + rom ( name "Marvel - Ultimate Alliance (USA).gba" size 8388608 crc a74294db sha1 FE621B8D156B85ED2EE77DBC1D2B84D16F330E67 ) ) game ( name "Marvel - Ultimate Alliance (Europe) (En,It)" description "Marvel - Ultimate Alliance (Europe) (En,It)" - rom ( name "Marvel - Ultimate Alliance (Europe) (En,It).gba" size 8388608 crc C150790F md5 D64C95901C720F6DBF7B6DAB929E617F sha1 75CE19B28CDEADE8FBBFB93E284327C13F3C53F6 flags verified ) + rom ( name "Marvel - Ultimate Alliance (Europe) (En,It).gba" size 8388608 crc c150790f sha1 75CE19B28CDEADE8FBBFB93E284327C13F3C53F6 flags verified ) ) game ( - name "Mary-Kate and Ashley - Girls Night Out (USA)" - description "Mary-Kate and Ashley - Girls Night Out (USA)" - rom ( name "Mary-Kate and Ashley - Girls Night Out (USA).gba" size 4194304 crc 8AF3F3AD md5 4C3F934EA0A5C9683A8C82FA57FF1C00 sha1 4B46751B6DEB8064D58A0786D62B37206C9529AC ) + name "Mary-Kate and Ashley - Girls Night Out (USA, Europe)" + description "Mary-Kate and Ashley - Girls Night Out (USA, Europe)" + rom ( name "Mary-Kate and Ashley - Girls Night Out (USA, Europe).gba" size 4194304 crc 8af3f3ad sha1 4B46751B6DEB8064D58A0786D62B37206C9529AC flags verified ) ) game ( - name "Mary-Kate and Ashley Sweet 16 - Licensed to Drive (USA, Europe)" - description "Mary-Kate and Ashley Sweet 16 - Licensed to Drive (USA, Europe)" - rom ( name "Mary-Kate and Ashley Sweet 16 - Licensed to Drive (USA, Europe).gba" size 4194304 crc 5FE092C6 md5 E7EA7A7570B301AE1CFAB5531C7A3941 sha1 284059F03F0DDA9CE511D3C57BF0607706B9FCA3 flags verified ) + name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe)" + description "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe)" + rom ( name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe).gba" size 4194304 crc 5fe092c6 sha1 284059F03F0DDA9CE511D3C57BF0607706B9FCA3 flags verified ) ) game ( - name "Masters of the Universe He-Man - Power of Grayskull (USA)" - description "Masters of the Universe He-Man - Power of Grayskull (USA)" - rom ( name "Masters of the Universe He-Man - Power of Grayskull (USA).gba" size 8388608 crc 75491E30 md5 11C77B84B23817CDA21C24BC7DDD2605 sha1 FE6E84EA4C6F81B3F560A1D2462A898216A8D1BA ) + name "Masters of the Universe - He-Man - Power of Grayskull (USA)" + description "Masters of the Universe - He-Man - Power of Grayskull (USA)" + rom ( name "Masters of the Universe - He-Man - Power of Grayskull (USA).gba" size 8388608 crc 75491e30 sha1 FE6E84EA4C6F81B3F560A1D2462A898216A8D1BA ) ) game ( name "Mat Hoffman's Pro BMX (USA, Europe)" description "Mat Hoffman's Pro BMX (USA, Europe)" - rom ( name "Mat Hoffman's Pro BMX (USA, Europe).gba" size 4194304 crc A333FA51 md5 4F142C9621C9115D7107E7E6F02D99D3 sha1 DF0345C31CA3CAD51CEF7ADAE8C6FDADF81B3A97 flags verified ) + rom ( name "Mat Hoffman's Pro BMX (USA, Europe).gba" size 4194304 crc a333fa51 sha1 DF0345C31CA3CAD51CEF7ADAE8C6FDADF81B3A97 flags verified ) ) game ( name "Mat Hoffman's Pro BMX (Europe) (Fr,De)" description "Mat Hoffman's Pro BMX (Europe) (Fr,De)" - rom ( name "Mat Hoffman's Pro BMX (Europe) (Fr,De).gba" size 4194304 crc 78D22AE9 md5 B169016486294D9D9EB61BBF96D30400 sha1 1F5A9E9E164F9B97F55084342F331097CE623BE7 ) + rom ( name "Mat Hoffman's Pro BMX (Europe) (Fr,De).gba" size 4194304 crc 78d22ae9 sha1 1F5A9E9E164F9B97F55084342F331097CE623BE7 ) ) game ( name "Mat Hoffman's Pro BMX 2 (USA, Europe)" description "Mat Hoffman's Pro BMX 2 (USA, Europe)" - rom ( name "Mat Hoffman's Pro BMX 2 (USA, Europe).gba" size 8388608 crc E7FA71C6 md5 C786F824ED894F22166D4EB801F5F7D4 sha1 D12BC188404BFB6D012B9CE1CF7302762D934832 flags verified ) + rom ( name "Mat Hoffman's Pro BMX 2 (USA, Europe).gba" size 8388608 crc e7fa71c6 sha1 D12BC188404BFB6D012B9CE1CF7302762D934832 flags verified ) ) game ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan)" description "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan)" - rom ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan).gba" size 4194304 crc 31843E8D md5 E7F2350663D18A5EA16B644D9475D246 sha1 E969A8099E16F181FA7EE4D9CDA1A2DC0A029938 ) + rom ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan).gba" size 8388608 crc 4ebdad86 sha1 9E1D0D5D5454D544AB85B34AD0E50FAD7B54487C flags verified ) +) + +game ( + name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan) (Rev 1)" + description "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan) (Rev 1)" + rom ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan) (Rev 1).gba" size 8388608 crc d647ab18 sha1 3489569FA8A3C6A750C5CB0048915DA78C5F40AB flags verified ) ) game ( name "Matchbox Cross Town Heroes (USA)" description "Matchbox Cross Town Heroes (USA)" - rom ( name "Matchbox Cross Town Heroes (USA).gba" size 4194304 crc 0FFFB458 md5 5D8477952AC38E7DFEA3A56F7544809B sha1 6BAA6BFE76B077F365BEDFFA52346B94689B61D7 ) + rom ( name "Matchbox Cross Town Heroes (USA).gba" size 4194304 crc 0fffb458 sha1 6BAA6BFE76B077F365BEDFFA52346B94689B61D7 ) ) game ( name "Matchbox Cross Town Heroes (Europe)" description "Matchbox Cross Town Heroes (Europe)" - rom ( name "Matchbox Cross Town Heroes (Europe).gba" size 4194304 crc C9EA02F5 md5 753971AF89A797D2C0BAD3198D56963C sha1 13310B7F25A0332A8E09E722587EC79AEE11C373 ) + rom ( name "Matchbox Cross Town Heroes (Europe).gba" size 4194304 crc c9ea02f5 sha1 13310B7F25A0332A8E09E722587EC79AEE11C373 ) ) game ( name "Math Patrol - The Kleptoid Threat (USA)" description "Math Patrol - The Kleptoid Threat (USA)" - rom ( name "Math Patrol - The Kleptoid Threat (USA).gba" size 8388608 crc AECD1301 md5 1ED7F890CE33A463907CEC23F83BE7C0 sha1 4DFCB91C0C21E891EF62B4FACAB3E85B17CC1F40 ) + rom ( name "Math Patrol - The Kleptoid Threat (USA).gba" size 8388608 crc aecd1301 sha1 4DFCB91C0C21E891EF62B4FACAB3E85B17CC1F40 ) ) game ( name "Mawaru - Made in Wario (Japan)" description "Mawaru - Made in Wario (Japan)" - rom ( name "Mawaru - Made in Wario (Japan).gba" size 16777216 crc E69964F1 md5 D76D992D936C308B7D1BB70AC71A1C37 sha1 A389FA50E2E842B264B980CBE30E980C69D93A5B ) + rom ( name "Mawaru - Made in Wario (Japan).gba" size 16777216 crc e69964f1 sha1 A389FA50E2E842B264B980CBE30E980C69D93A5B ) ) game ( name "Max Payne (USA)" description "Max Payne (USA)" - rom ( name "Max Payne (USA).gba" size 16777216 crc 296E1092 md5 7B79AD84814D56986566F49AB9DE6423 sha1 BC242869661602E918B880850DFCC4EED7B43617 ) + rom ( name "Max Payne (USA).gba" size 16777216 crc 296e1092 sha1 BC242869661602E918B880850DFCC4EED7B43617 ) ) game ( name "Max Payne Advance (Europe) (En,Fr,De)" description "Max Payne Advance (Europe) (En,Fr,De)" - rom ( name "Max Payne Advance (Europe) (En,Fr,De).gba" size 16777216 crc 7D902B62 md5 AA4ACDE4D4147725F74EFBD03A1C65E4 sha1 7007F087A3022BD0D9D9B0D99489096F877794FF flags verified ) + rom ( name "Max Payne Advance (Europe) (En,Fr,De).gba" size 16777216 crc 7d902b62 sha1 7007F087A3022BD0D9D9B0D99489096F877794FF flags verified ) ) game ( name "Maya the Bee - Sweet Gold (Europe) (En,Fr,De,Es,It)" description "Maya the Bee - Sweet Gold (Europe) (En,Fr,De,Es,It)" - rom ( name "Maya the Bee - Sweet Gold (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A75778C7 md5 7B7560F2C5D48E3A922D9637AE9E50A9 sha1 36B6237D4C896AB583418F9ECAEB6B2363F42D23 ) + rom ( name "Maya the Bee - Sweet Gold (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a75778c7 sha1 36B6237D4C896AB583418F9ECAEB6B2363F42D23 ) ) game ( name "Maya the Bee - The Great Adventure (Europe) (En,Fr,De,Es,It)" description "Maya the Bee - The Great Adventure (Europe) (En,Fr,De,Es,It)" - rom ( name "Maya the Bee - The Great Adventure (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A1764F3C md5 2E28272879CED1FFFFC522C6021BF79F sha1 50AEA4C795755D03E21EB901770DDDBD42A46DDE ) + rom ( name "Maya the Bee - The Great Adventure (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a1764f3c sha1 50AEA4C795755D03E21EB901770DDDBD42A46DDE ) ) game ( name "Mazes of Fate (USA) (En,Fr,De,Es,It)" description "Mazes of Fate (USA) (En,Fr,De,Es,It)" - rom ( name "Mazes of Fate (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 0B725A08 md5 160C89D655B1DB397E419A9614144A7A sha1 2DE038BB6505458F5E70A759EACCB62253AF3132 ) + rom ( name "Mazes of Fate (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 0b725a08 sha1 2DE038BB6505458F5E70A759EACCB62253AF3132 ) ) game ( name "Mech Platoon (Europe) (En,Fr,De,Es,It)" description "Mech Platoon (Europe) (En,Fr,De,Es,It)" - rom ( name "Mech Platoon (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4B3E0531 md5 1DE4EBF40C819E8CFB20B84F6DCDF718 sha1 A5190C06F34B1617A6BD102C5D4829F8462D589B ) + rom ( name "Mech Platoon (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 4b3e0531 sha1 A5190C06F34B1617A6BD102C5D4829F8462D589B ) ) game ( name "Mech Platoon (USA)" description "Mech Platoon (USA)" - rom ( name "Mech Platoon (USA).gba" size 8388608 crc 769FDE96 md5 AB0999E2D7C13ADA9CF374CD0AA47F97 sha1 8A9BD790C9CD831366A00CDDE72A9F3FEC89CB61 ) + rom ( name "Mech Platoon (USA).gba" size 8388608 crc 769fde96 sha1 8A9BD790C9CD831366A00CDDE72A9F3FEC89CB61 ) ) game ( name "Medabots - Metabee (Europe)" description "Medabots - Metabee (Europe)" - rom ( name "Medabots - Metabee (Europe).gba" size 8388608 crc 50927F3E md5 94CE0A59F8A6A0EC40B51EF13CFE0AA0 sha1 CD3D674E88F40A0707B150C4293588A659001D29 flags verified ) + rom ( name "Medabots - Metabee (Europe).gba" size 8388608 crc 50927f3e sha1 CD3D674E88F40A0707B150C4293588A659001D29 flags verified ) ) game ( name "Medabots - Metabee (USA)" description "Medabots - Metabee (USA)" - rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59F208FC md5 B186A9BA291A156C45640CB3C6B8A710 sha1 CA185B65AB50EF89A10C8DB00D9CD76626B81610 ) + rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59f208fc sha1 CA185B65AB50EF89A10C8DB00D9CD76626B81610 ) ) game ( name "Medabots - Metabee (Spain)" description "Medabots - Metabee (Spain)" - serial "AGB-A8BS-ESP" - rom ( name "Medabots - Metabee (Spain).gba" size 8388608 crc 7E907EC8 md5 89A8EA77FC2169DD5AA0209E4C485B7C sha1 FEE2D1DB994E1A13FC2BC9943198136192412185 ) + rom ( name "Medabots - Metabee (Spain).gba" size 8388608 crc 7e907ec8 sha1 FEE2D1DB994E1A13FC2BC9943198136192412185 ) ) game ( - name "Medabots - Rokusho (Spain)" - description "Medabots - Rokusho (Spain)" - serial "AGB-A9BS-ESP" - rom ( name "Medabots - Rokusho (Spain).gba" size 8388608 crc 046D86C4 md5 F04E0DBF730276BB548498EFB2CC6DC5 sha1 90FE7F2927C592AABC9B33D0DF00D92046C5CB92 ) + name "Medabots - Metabee (USA) (Wii U Virtual Console)" + description "Medabots - Metabee (USA) (Wii U Virtual Console)" + rom ( name "Medabots - Metabee (USA) (Wii U Virtual Console).gba" size 8388608 crc dff9a0b1 sha1 51BBA24C752123598F0B194D9D07A640B3318E12 flags verified ) ) game ( name "Medabots - Rokusho (Europe)" description "Medabots - Rokusho (Europe)" - rom ( name "Medabots - Rokusho (Europe).gba" size 8388608 crc A519FEB5 md5 BB040B4D930C1FC4BE1067B9756A7C44 sha1 FC44B80F3E71EFFC33D8E05A74888CB885C32EB0 flags verified ) + rom ( name "Medabots - Rokusho (Europe).gba" size 8388608 crc a519feb5 sha1 FC44B80F3E71EFFC33D8E05A74888CB885C32EB0 flags verified ) ) game ( name "Medabots - Rokusho (USA)" description "Medabots - Rokusho (USA)" - rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc E144DED2 md5 3F8A30AA55BF6EB8ED4E7FD9528F61E3 sha1 C4572428EA97B302F699A3B4EBA2A1F0E87C1C9C ) + rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc e144ded2 sha1 C4572428EA97B302F699A3B4EBA2A1F0E87C1C9C flags verified ) +) + +game ( + name "Medabots - Rokusho (Spain)" + description "Medabots - Rokusho (Spain)" + rom ( name "Medabots - Rokusho (Spain).gba" size 8388608 crc 046d86c4 sha1 90FE7F2927C592AABC9B33D0DF00D92046C5CB92 ) ) game ( name "Medabots AX - Metabee Ver. (USA)" description "Medabots AX - Metabee Ver. (USA)" - rom ( name "Medabots AX - Metabee Ver. (USA).gba" size 8388608 crc 03294511 md5 C83C580D9AB765AF26CA3A3EAD0CD518 sha1 80C024DF6D40E499776665D7F0C494A252973048 ) + rom ( name "Medabots AX - Metabee Ver. (USA).gba" size 8388608 crc 03294511 sha1 80C024DF6D40E499776665D7F0C494A252973048 ) ) game ( name "Medabots AX - Metabee Ver. (Europe) (En,Fr,De,Es,It)" description "Medabots AX - Metabee Ver. (Europe) (En,Fr,De,Es,It)" - rom ( name "Medabots AX - Metabee Ver. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5F1E5A48 md5 F14D377341C6AFBA46D3DB0FABF12062 sha1 130C908D24BA3E422FD8DB84E683BACC87235E78 flags verified ) + rom ( name "Medabots AX - Metabee Ver. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5f1e5a48 sha1 130C908D24BA3E422FD8DB84E683BACC87235E78 flags verified ) ) game ( name "Medabots AX - Rokusho Ver. (USA)" description "Medabots AX - Rokusho Ver. (USA)" - rom ( name "Medabots AX - Rokusho Ver. (USA).gba" size 8388608 crc 92FDB8D6 md5 08A002CA5DE6E28726C3D17644137B23 sha1 EF47F8C675F1F541A0FE4BD37C8882EFC539B1C7 flags verified ) + rom ( name "Medabots AX - Rokusho Ver. (USA).gba" size 8388608 crc 92fdb8d6 sha1 EF47F8C675F1F541A0FE4BD37C8882EFC539B1C7 flags verified ) ) game ( name "Medabots AX - Rokusho Ver. (Europe) (En,Fr,De,Es,It)" description "Medabots AX - Rokusho Ver. (Europe) (En,Fr,De,Es,It)" - rom ( name "Medabots AX - Rokusho Ver. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc F5801BD8 md5 A6E3E17F96065A33C8AD3B540583FB64 sha1 35E35139E4D8D91CA52983097F3CE8FE090E3598 ) + rom ( name "Medabots AX - Rokusho Ver. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f5801bd8 sha1 35E35139E4D8D91CA52983097F3CE8FE090E3598 ) ) game ( name "Medal of Honor - Infiltrator (USA, Europe) (En,Fr,De)" description "Medal of Honor - Infiltrator (USA, Europe) (En,Fr,De)" - rom ( name "Medal of Honor - Infiltrator (USA, Europe) (En,Fr,De).gba" size 16777216 crc F23150A4 md5 78DB66A92F5F4405266E154DE49EEA8D sha1 47761911475E9548C81FED78E3D3336DDAE89A58 flags verified ) -) - -game ( - name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" - description "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" - rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital).gba" size 8388608 crc 72B4CF20 md5 2DC58CE50644D4029CD2A347F197973F sha1 ABB26D759EF729D21E41A913FC6C1CE4AB77149F ) + rom ( name "Medal of Honor - Infiltrator (USA, Europe) (En,Fr,De).gba" size 16777216 crc f23150a4 sha1 47761911475E9548C81FED78E3D3336DDAE89A58 flags verified ) ) game ( name "Medal of Honor - Underground (USA)" description "Medal of Honor - Underground (USA)" - rom ( name "Medal of Honor - Underground (USA).gba" size 8388608 crc 6DFA0F50 md5 D15113E7B1843EDFD258AD5F5051B418 sha1 B5C9B9E9DB9E4B449269ED4422F0A7800843998F flags verified ) + rom ( name "Medal of Honor - Underground (USA).gba" size 8388608 crc 6dfa0f50 sha1 B5C9B9E9DB9E4B449269ED4422F0A7800843998F flags verified ) ) game ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft)" description "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft)" - rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft).gba" size 8388608 crc 9DB145B8 md5 E84D4D9B8C1A68292E76A4C566E5040F sha1 E43AABA3F925443CFCCF9294B870024A9C71A9A9 ) + rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft).gba" size 8388608 crc 9db145b8 sha1 E43AABA3F925443CFCCF9294B870024A9C71A9A9 flags verified ) +) + +game ( + name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" + description "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital)" + rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Zoo Digital).gba" size 8388608 crc 72b4cf20 sha1 ABB26D759EF729D21E41A913FC6C1CE4AB77149F ) ) game ( name "Medal of Honor Advance (Japan)" description "Medal of Honor Advance (Japan)" - rom ( name "Medal of Honor Advance (Japan).gba" size 16777216 crc A054A4D0 md5 44CA4A4867AA57B442C43798B209F640 sha1 E482D182695AD3F7B298FD99CF56221ACB37D84D ) + rom ( name "Medal of Honor Advance (Japan).gba" size 16777216 crc a054a4d0 sha1 E482D182695AD3F7B298FD99CF56221ACB37D84D ) ) game ( name "Medarot G - Kabuto (Japan)" description "Medarot G - Kabuto (Japan)" - rom ( name "Medarot G - Kabuto (Japan).gba" size 8388608 crc B107C73D md5 6F9802A7094757A4E535F763FF9B7DE4 sha1 CF0AB638D344EA74DB39018163B12256583D556F ) + rom ( name "Medarot G - Kabuto (Japan).gba" size 8388608 crc b107c73d sha1 CF0AB638D344EA74DB39018163B12256583D556F flags verified ) ) game ( name "Medarot G - Kuwagata (Japan)" description "Medarot G - Kuwagata (Japan)" - rom ( name "Medarot G - Kuwagata (Japan).gba" size 8388608 crc 14E3EBCC md5 1E68810A62D6DB776B3E602E39601B70 sha1 4F54D7BD915AA90496725EA3928B8A0D93BC5E49 ) + rom ( name "Medarot G - Kuwagata (Japan).gba" size 8388608 crc 14e3ebcc sha1 4F54D7BD915AA90496725EA3928B8A0D93BC5E49 ) ) game ( name "Medarot Navi - Kabuto (Japan)" description "Medarot Navi - Kabuto (Japan)" - rom ( name "Medarot Navi - Kabuto (Japan).gba" size 8388608 crc 15450B63 md5 BBCD12EA6A44F220B40A196EDFD2580B sha1 3135545E02FA5557DDA0976165CF5C7F3C0B6F8E ) + rom ( name "Medarot Navi - Kabuto (Japan).gba" size 8388608 crc 15450b63 sha1 3135545E02FA5557DDA0976165CF5C7F3C0B6F8E ) ) game ( name "Medarot Navi - Kuwagata (Japan)" description "Medarot Navi - Kuwagata (Japan)" - rom ( name "Medarot Navi - Kuwagata (Japan).gba" size 8388608 crc E83D07D6 md5 2D93223A5F86759F02398226A4A8A054 sha1 DE8DE6734F0F990832988EA133FA05241946800E ) + rom ( name "Medarot Navi - Kuwagata (Japan).gba" size 8388608 crc e83d07d6 sha1 DE8DE6734F0F990832988EA133FA05241946800E flags verified ) ) game ( name "Medarot Ni Core - Kabuto (Japan)" description "Medarot Ni Core - Kabuto (Japan)" - rom ( name "Medarot Ni Core - Kabuto (Japan).gba" size 8388608 crc 3FCAF2D0 md5 C98531DEF6532B3ED048A5EBC0AB4C3C sha1 CB1E070C2CF9BA7C7CE7C102E69E7815941CA5F1 ) + rom ( name "Medarot Ni Core - Kabuto (Japan).gba" size 8388608 crc 3fcaf2d0 sha1 CB1E070C2CF9BA7C7CE7C102E69E7815941CA5F1 ) +) + +game ( + name "Medarot Ni Core - Kabuto (Japan) (Rev 1)" + description "Medarot Ni Core - Kabuto (Japan) (Rev 1) (Retail release)" + rom ( name "Medarot Ni Core - Kabuto (Japan) (Rev 1).gba" size 8388608 crc 3f15feaa sha1 4A2AA33C2B37DCE3A54CE3077974FA7F0DC26E49 flags verified ) ) game ( name "Medarot Ni Core - Kuwagata (Japan)" description "Medarot Ni Core - Kuwagata (Japan)" - rom ( name "Medarot Ni Core - Kuwagata (Japan).gba" size 8388608 crc 285FE485 md5 55198B6049BBC81860889039E93B464E sha1 868157B4D047F7F5F2A9C30577D082DC59B763B2 ) + rom ( name "Medarot Ni Core - Kuwagata (Japan).gba" size 8388608 crc 285fe485 sha1 868157B4D047F7F5F2A9C30577D082DC59B763B2 ) ) game ( name "Meet the Robinsons (USA)" description "Meet the Robinsons (USA)" - rom ( name "Meet the Robinsons (USA).gba" size 8388608 crc 3787C93C md5 CFBF47949426A8F44ECDC832D06D09A9 sha1 58AD2756F1985430E1EF605BDCBA82564099A030 flags verified ) + rom ( name "Meet the Robinsons (USA).gba" size 8388608 crc 3787c93c sha1 58AD2756F1985430E1EF605BDCBA82564099A030 flags verified ) ) game ( name "Meet the Robinsons (Europe) (En,Fr,De,Es,It,Nl)" description "Meet the Robinsons (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Meet the Robinsons (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc DF3E58D3 md5 59ABA4BBA551AA20BF7726EBA3AF13FE sha1 1B5376D0C0B64973D74434A3A7388EEBA3005AAB ) -) - -game ( - name "Mega Man & Bass (Europe)" - description "Mega Man & Bass (Europe)" - rom ( name "Mega Man & Bass (Europe).gba" size 8388608 crc 01B4D95E md5 1FF9F0809C7766F72E67378CB14A430A sha1 5D6F8FB1F52803A54E9857E53D0B88173CF8F48A flags verified ) + rom ( name "Meet the Robinsons (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc df3e58d3 sha1 1B5376D0C0B64973D74434A3A7388EEBA3005AAB flags verified ) ) game ( name "Mega Man & Bass (USA)" description "Mega Man & Bass (USA)" - rom ( name "Mega Man & Bass (USA).gba" size 8388608 crc EEA68C2E md5 88792AE1FBC74F4A5425D0C6F0482023 sha1 7610847B331870D4338E5AC894B36E55E2BEC5A0 ) + rom ( name "Mega Man & Bass (USA).gba" size 8388608 crc eea68c2e sha1 7610847B331870D4338E5AC894B36E55E2BEC5A0 flags verified ) +) + +game ( + name "Mega Man & Bass (Europe)" + description "Mega Man & Bass (Europe)" + rom ( name "Mega Man & Bass (Europe).gba" size 8388608 crc 01b4d95e sha1 5D6F8FB1F52803A54E9857E53D0B88173CF8F48A flags verified ) +) + +game ( + name "Mega Man & Bass (USA) (Wii U Virtual Console)" + description "Mega Man & Bass (USA) (Wii U Virtual Console)" + rom ( name "Mega Man & Bass (USA) (Wii U Virtual Console).gba" size 8388608 crc b61f99d4 sha1 37DB963A52AECEC8018057CEF3811860C3E889ED flags verified ) ) game ( name "Mega Man Battle Chip Challenge (USA)" description "Mega Man Battle Chip Challenge (USA)" - rom ( name "Mega Man Battle Chip Challenge (USA).gba" size 8388608 crc 26BE44FD md5 D996F6CBB36EB15063B290D8F00AD654 sha1 72309736F3820470C6F372D6A05AD1F16BC5A946 ) + rom ( name "Mega Man Battle Chip Challenge (USA).gba" size 8388608 crc 26be44fd sha1 72309736F3820470C6F372D6A05AD1F16BC5A946 ) ) game ( name "Mega Man Battle Chip Challenge (Europe)" description "Mega Man Battle Chip Challenge (Europe)" - rom ( name "Mega Man Battle Chip Challenge (Europe).gba" size 8388608 crc 5B4631F9 md5 E42148C3E79F7D5F7A9F3B63939B68C2 sha1 F54486C8A0BB22CF0ECE4297FB052D0A0F11E56D ) + rom ( name "Mega Man Battle Chip Challenge (Europe).gba" size 8388608 crc 5b4631f9 sha1 F54486C8A0BB22CF0ECE4297FB052D0A0F11E56D ) +) + +game ( + name "Mega Man Battle Chip Challenge (USA) (Wii U Virtual Console)" + description "Mega Man Battle Chip Challenge (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Chip Challenge (USA) (Wii U Virtual Console).gba" size 8388608 crc 59fc1ef6 sha1 E936DB20E9CF923DC10C6C1DC14BC7ED6B220080 flags verified ) +) + +game ( + name "Mega Man Battle Chip Challenge (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Chip Challenge (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Chip Challenge (Europe) (Wii U Virtual Console).gba" size 8388608 crc 24046bf2 sha1 F0776AD33EB01A47207A076D95B534145223371D flags verified ) ) game ( name "Mega Man Battle Network (USA)" description "Mega Man Battle Network (USA)" - rom ( name "Mega Man Battle Network (USA).gba" size 8388608 crc 1D347971 md5 9FF40CF640575211202B7BDA5487ABBB sha1 A4FBAE389654A6611D0597B1E9109CBBD32A132F flags verified ) + rom ( name "Mega Man Battle Network (USA).gba" size 8388608 crc 1d347971 sha1 A4FBAE389654A6611D0597B1E9109CBBD32A132F flags verified ) ) game ( name "Mega Man Battle Network (Europe)" description "Mega Man Battle Network (Europe)" - rom ( name "Mega Man Battle Network (Europe).gba" size 8388608 crc 1A7FB4FA md5 62E32A9CCF6C31850041555CB8151440 sha1 B017B6054FFAFC012BE9ADEE785819B17706CABC flags verified ) + rom ( name "Mega Man Battle Network (Europe).gba" size 8388608 crc 1a7fb4fa sha1 B017B6054FFAFC012BE9ADEE785819B17706CABC flags verified ) +) + +game ( + name "Mega Man Battle Network (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network (USA) (Wii U Virtual Console).gba" size 8388608 crc 1d5d0cb6 sha1 A371765E107C30DC4AC37C2F114A785305F47A4C flags verified ) +) + +game ( + name "Mega Man Battle Network (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network (Europe) (Wii U Virtual Console).gba" size 8388608 crc 1a16c13d sha1 0DCBC43D5D50401C0EAB8BB5989055523CE90B10 flags verified ) ) game ( name "Mega Man Battle Network 2 (USA)" description "Mega Man Battle Network 2 (USA)" - rom ( name "Mega Man Battle Network 2 (USA).gba" size 8388608 crc 6D961F82 md5 39F8A42133DF444EEB7BF0B2194D6286 sha1 601B5012F77001D2C5C11B31304AFAFC45A70D0B flags verified ) + rom ( name "Mega Man Battle Network 2 (USA).gba" size 8388608 crc 6d961f82 sha1 601B5012F77001D2C5C11B31304AFAFC45A70D0B flags verified ) ) game ( name "Mega Man Battle Network 2 (Europe)" description "Mega Man Battle Network 2 (Europe)" - rom ( name "Mega Man Battle Network 2 (Europe).gba" size 8388608 crc 66341F3B md5 833E55B181AC9B4DA56B6341C1F4E09A sha1 13D8C1978CBCD9CA2A127168544FDA176E0A4D6C ) + rom ( name "Mega Man Battle Network 2 (Europe).gba" size 8388608 crc 66341f3b sha1 13D8C1978CBCD9CA2A127168544FDA176E0A4D6C ) +) + +game ( + name "Mega Man Battle Network 2 (USA) (Debug Version)" + description "Mega Man Battle Network 2 (USA) (Debug Version)" + rom ( name "Mega Man Battle Network 2 (USA) (Debug Version).gba" size 33554432 crc fbdadaa7 sha1 3BC2A627A859431DB0F40F755FBC2857936E23B2 flags verified ) +) + +game ( + name "Mega Man Battle Network 2 (USA, Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 2 (USA, Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 2 (USA, Europe) (Wii U Virtual Console).gba" size 8388608 crc 5e88c34b sha1 D6B574203CC393F292A9825FCEC64E72B3B2A11B flags verified ) ) game ( name "Mega Man Battle Network 3 - Blue (Europe)" description "Mega Man Battle Network 3 - Blue (Europe)" - rom ( name "Mega Man Battle Network 3 - Blue (Europe).gba" size 8388608 crc 1F036CBA md5 C1F7ADE0EBCE39A97C6EFCAD33661E20 sha1 9CB052728CAE18864A012E7598119CA7B93EEA67 ) + rom ( name "Mega Man Battle Network 3 - Blue (Europe).gba" size 8388608 crc 1f036cba sha1 9CB052728CAE18864A012E7598119CA7B93EEA67 flags verified ) +) + +game ( + name "Mega Man Battle Network 3 - Blue (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 3 - Blue (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 3 - Blue (Europe) (Wii U Virtual Console).gba" size 8388608 crc 3213fc2d sha1 A9FE51D3FFD7488739821B895B45CF91C10A3108 flags verified ) ) game ( name "Mega Man Battle Network 3 - Blue Version (USA)" description "Mega Man Battle Network 3 - Blue Version (USA)" - rom ( name "Mega Man Battle Network 3 - Blue Version (USA).gba" size 8388608 crc C0C780F9 md5 6FE31DF0144759B34AD666BADAACC442 sha1 3D21905B6E860D39A00BA643779776DE4C73C411 flags verified ) + rom ( name "Mega Man Battle Network 3 - Blue Version (USA).gba" size 8388608 crc c0c780f9 sha1 3D21905B6E860D39A00BA643779776DE4C73C411 flags verified ) +) + +game ( + name "Mega Man Battle Network 3 - Blue Version (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 3 - Blue Version (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 3 - Blue Version (USA) (Wii U Virtual Console).gba" size 8388608 crc edd7106e sha1 6E30310F3994803E56170F6D67C5F154A5D91CCB flags verified ) ) game ( name "Mega Man Battle Network 3 - White (Europe)" description "Mega Man Battle Network 3 - White (Europe)" - rom ( name "Mega Man Battle Network 3 - White (Europe).gba" size 8388608 crc 23D0A981 md5 DEA8CB17074798C5123422836024D4C8 sha1 2942A890C369569E163A60F831150305CA0828FC ) + rom ( name "Mega Man Battle Network 3 - White (Europe).gba" size 8388608 crc 23d0a981 sha1 2942A890C369569E163A60F831150305CA0828FC ) +) + +game ( + name "Mega Man Battle Network 3 - White (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 3 - White (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 3 - White (Europe) (Wii U Virtual Console).gba" size 8388608 crc d9f1440b sha1 E0BD967C2296CA5A515E8B6231D4959336C1278D flags verified ) ) game ( name "Mega Man Battle Network 3 - White Version (USA)" description "Mega Man Battle Network 3 - White Version (USA)" - rom ( name "Mega Man Battle Network 3 - White Version (USA).gba" size 8388608 crc 0BE4410A md5 68817204A691449E655CBA739DBB0165 sha1 FF45038AE6D01CDE4EAE25A02DCB8BED29E07A6F flags verified ) + rom ( name "Mega Man Battle Network 3 - White Version (USA).gba" size 8388608 crc 0be4410a sha1 FF45038AE6D01CDE4EAE25A02DCB8BED29E07A6F flags verified ) +) + +game ( + name "Mega Man Battle Network 3 - White Version (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 3 - White Version (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 3 - White Version (USA) (Wii U Virtual Console).gba" size 8388608 crc f1c5ac80 sha1 1F0762B7C817211E855F4F50C2B11585D0893BE9 flags verified ) ) game ( name "Mega Man Battle Network 4 - Blue Moon (USA)" description "Mega Man Battle Network 4 - Blue Moon (USA)" - rom ( name "Mega Man Battle Network 4 - Blue Moon (USA).gba" size 8388608 crc 758A46E9 md5 E9DFE02B283E29D67C224AB6F86C3B9C sha1 5E017C803DDC768EFB8010314B46BC17E9757F71 flags verified ) + rom ( name "Mega Man Battle Network 4 - Blue Moon (USA).gba" size 8388608 crc 758a46e9 sha1 5E017C803DDC768EFB8010314B46BC17E9757F71 flags verified ) ) game ( name "Mega Man Battle Network 4 - Blue Moon (Europe)" description "Mega Man Battle Network 4 - Blue Moon (Europe)" - rom ( name "Mega Man Battle Network 4 - Blue Moon (Europe).gba" size 8388608 crc 48758316 md5 6C653DE4749981579252E59FCAE956D5 sha1 A05E8DCE26B5134001337E193D49958BE2081598 ) + rom ( name "Mega Man Battle Network 4 - Blue Moon (Europe).gba" size 8388608 crc 48758316 sha1 A05E8DCE26B5134001337E193D49958BE2081598 ) +) + +game ( + name "Mega Man Battle Network 4 - Blue Moon (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 4 - Blue Moon (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 4 - Blue Moon (USA) (Wii U Virtual Console).gba" size 8388608 crc 739b7ec4 sha1 62A0169F0FE00E5F8184475A20A36877D1063F63 flags verified ) +) + +game ( + name "Mega Man Battle Network 4 - Blue Moon (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 4 - Blue Moon (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 4 - Blue Moon (Europe) (Wii U Virtual Console).gba" size 8388608 crc ad89f27d sha1 0FBF2B2F53F0A32E893E2593E2D7C542B5FCAC99 flags verified ) ) game ( name "Mega Man Battle Network 4 - Red Sun (USA)" description "Mega Man Battle Network 4 - Red Sun (USA)" - rom ( name "Mega Man Battle Network 4 - Red Sun (USA).gba" size 8388608 crc 2120695C md5 D0DEE5C06972CB072391CD968A248D52 sha1 A97E96A7DA03ABD70F7953328E511B9FA29179F1 flags verified ) + rom ( name "Mega Man Battle Network 4 - Red Sun (USA).gba" size 8388608 crc 2120695c sha1 A97E96A7DA03ABD70F7953328E511B9FA29179F1 flags verified ) ) game ( name "Mega Man Battle Network 4 - Red Sun (Europe)" description "Mega Man Battle Network 4 - Red Sun (Europe)" - rom ( name "Mega Man Battle Network 4 - Red Sun (Europe).gba" size 8388608 crc 0CB136C2 md5 AC9B62069B180DA5DDF1646D4E142D59 sha1 21AF9F7805A27729E770928F939ACEDD6AE27C1C ) + rom ( name "Mega Man Battle Network 4 - Red Sun (Europe).gba" size 8388608 crc 0cb136c2 sha1 21AF9F7805A27729E770928F939ACEDD6AE27C1C ) +) + +game ( + name "Mega Man Battle Network 4 - Red Sun (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 4 - Red Sun (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 4 - Red Sun (USA) (Wii U Virtual Console).gba" size 8388608 crc 12e7ab52 sha1 07426328DBB4A3AEA763E75C8FFE6DE482FF69D0 flags verified ) +) + +game ( + name "Mega Man Battle Network 4 - Red Sun (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 4 - Red Sun (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 4 - Red Sun (Europe) (Wii U Virtual Console).gba" size 8388608 crc cb3bbf74 sha1 36D83A1509D28B0C09365466CC1481C919D84CB0 flags verified ) ) game ( name "Mega Man Battle Network 5 - Team Colonel (Europe)" description "Mega Man Battle Network 5 - Team Colonel (Europe)" - rom ( name "Mega Man Battle Network 5 - Team Colonel (Europe).gba" size 8388608 crc 8FC8CF73 md5 17FF0B3AF041F31B6C6924726C2642B8 sha1 D15BCB7C351252A8890C29A2EAAC25FF621635C9 ) + rom ( name "Mega Man Battle Network 5 - Team Colonel (Europe).gba" size 8388608 crc 8fc8cf73 sha1 D15BCB7C351252A8890C29A2EAAC25FF621635C9 ) ) game ( name "Mega Man Battle Network 5 - Team Colonel (USA)" description "Mega Man Battle Network 5 - Team Colonel (USA)" - rom ( name "Mega Man Battle Network 5 - Team Colonel (USA).gba" size 8388608 crc A552F683 md5 68D79F7C8F41F7C8009F3B85119CB1C6 sha1 5F472F78D8DE2DF01D5039E045C043CB40969A39 flags verified ) + rom ( name "Mega Man Battle Network 5 - Team Colonel (USA).gba" size 8388608 crc a552f683 sha1 5F472F78D8DE2DF01D5039E045C043CB40969A39 flags verified ) ) game ( - name "Mega Man Battle Network 5 - Team Proto Man (Europe)" - description "Mega Man Battle Network 5 - Team Proto Man (Europe)" - rom ( name "Mega Man Battle Network 5 - Team Proto Man (Europe).gba" size 8388608 crc 79F45ED8 md5 A1B8D71FA43915D37B955A2B1A0ED80A sha1 3D017ED23535E42174299FF89FFF44678EB553C3 ) + name "Mega Man Battle Network 5 - Team Colonel (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 5 - Team Colonel (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 5 - Team Colonel (USA) (Wii U Virtual Console).gba" size 8388608 crc 8e433dc8 sha1 8509F77245A03AA03C94B408BC74F7C23AD1AA1B flags verified ) ) game ( - name "Mega Man Battle Network 5 - Team Proto Man (USA)" - description "Mega Man Battle Network 5 - Team Proto Man (USA)" - rom ( name "Mega Man Battle Network 5 - Team Proto Man (USA).gba" size 8388608 crc A73E83A4 md5 71B00BA406C522D3CEC48311BD7BC760 sha1 B3774E96B1F107BB8B1DB79B216BE41B9BC5BAC0 flags verified ) + name "Mega Man Battle Network 5 - Team Proto Man (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 5 - Team Proto Man (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 5 - Team Proto Man (USA) (Wii U Virtual Console).gba" size 8388608 crc 560f6655 sha1 0F715F86FE2FF4183A655FCEB84204FC1D143245 flags verified ) +) + +game ( + name "Mega Man Battle Network 5 - Team Proto Man (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 5 - Team Proto Man (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 5 - Team Proto Man (Europe) (Wii U Virtual Console).gba" size 8388608 crc 88c5bb29 sha1 37266DBAE0AA1FAADEA21341F426E6E731308899 flags verified ) +) + +game ( + name "Mega Man Battle Network 5 - Team Protoman (Europe)" + description "Mega Man Battle Network 5 - Team Protoman (Europe)" + rom ( name "Mega Man Battle Network 5 - Team Protoman (Europe).gba" size 8388608 crc 79f45ed8 sha1 3D017ED23535E42174299FF89FFF44678EB553C3 ) +) + +game ( + name "Mega Man Battle Network 5 - Team Protoman (USA)" + description "Mega Man Battle Network 5 - Team Protoman (USA)" + rom ( name "Mega Man Battle Network 5 - Team Protoman (USA).gba" size 8388608 crc a73e83a4 sha1 B3774E96B1F107BB8B1DB79B216BE41B9BC5BAC0 flags verified ) ) game ( name "Mega Man Battle Network 6 - Cybeast Falzar (Europe)" description "Mega Man Battle Network 6 - Cybeast Falzar (Europe)" - rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (Europe).gba" size 8388608 crc 13183967 md5 56D29CAD9E26F1D7465F803ED1D1426B sha1 1F3037B33878FC66B79B4E2DCF1BB83202FA1B90 ) + rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (Europe).gba" size 8388608 crc 13183967 sha1 1F3037B33878FC66B79B4E2DCF1BB83202FA1B90 ) ) game ( name "Mega Man Battle Network 6 - Cybeast Falzar (USA)" description "Mega Man Battle Network 6 - Cybeast Falzar (USA)" - rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (USA).gba" size 8388608 crc DEE6F2A9 md5 1E8C774BA210D1C55113531C7360C737 sha1 0676ECD4D58A976AF3346CAEBB44B9B6489AD099 flags verified ) + rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (USA).gba" size 8388608 crc dee6f2a9 sha1 0676ECD4D58A976AF3346CAEBB44B9B6489AD099 flags verified ) +) + +game ( + name "Mega Man Battle Network 6 - Cybeast Falzar (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 6 - Cybeast Falzar (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (USA) (Wii U Virtual Console).gba" size 8388608 crc d2ae8993 sha1 B2C83B22B4B1E8A95259F3111419AFEFFE551825 flags verified ) +) + +game ( + name "Mega Man Battle Network 6 - Cybeast Falzar (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 6 - Cybeast Falzar (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 6 - Cybeast Falzar (Europe) (Wii U Virtual Console).gba" size 8388608 crc 1f50425d sha1 90DA73E38628AEB0100749AE65EF4738DEA35055 flags verified ) ) game ( name "Mega Man Battle Network 6 - Cybeast Gregar (USA)" description "Mega Man Battle Network 6 - Cybeast Gregar (USA)" - rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (USA).gba" size 8388608 crc 79452182 md5 5ACC75848BB1FFD3D6D8705554EE333D sha1 89FE0BAC4FD3D2AB1D2CA35E87EF8B1294A84CD6 flags verified ) + rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (USA).gba" size 8388608 crc 79452182 sha1 89FE0BAC4FD3D2AB1D2CA35E87EF8B1294A84CD6 flags verified ) ) game ( name "Mega Man Battle Network 6 - Cybeast Gregar (Europe)" description "Mega Man Battle Network 6 - Cybeast Gregar (Europe)" - rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (Europe).gba" size 8388608 crc 25C29EFB md5 5383A0D8C214F3FA64E5D8F672F6C4AA sha1 4D2E441B1BCB8438C0BEF2AE61D937DE7D04AF02 ) + rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (Europe).gba" size 8388608 crc 25c29efb sha1 4D2E441B1BCB8438C0BEF2AE61D937DE7D04AF02 ) +) + +game ( + name "Mega Man Battle Network 6 - Cybeast Gregar (USA) (Wii U Virtual Console)" + description "Mega Man Battle Network 6 - Cybeast Gregar (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (USA) (Wii U Virtual Console).gba" size 8388608 crc e7e546fe sha1 0A8DE8417B9939573DAA04F95CDECDEAAF58A79E flags verified ) +) + +game ( + name "Mega Man Battle Network 6 - Cybeast Gregar (Europe) (Wii U Virtual Console)" + description "Mega Man Battle Network 6 - Cybeast Gregar (Europe) (Wii U Virtual Console)" + rom ( name "Mega Man Battle Network 6 - Cybeast Gregar (Europe) (Wii U Virtual Console).gba" size 8388608 crc bb62f987 sha1 7106DC0469898CB5768EC76C99029B24039D7605 flags verified ) ) game ( name "Mega Man Zero (USA, Europe)" description "Mega Man Zero (USA, Europe)" - rom ( name "Mega Man Zero (USA, Europe).gba" size 8388608 crc 9707D2A1 md5 B24A17D080A01A404CBF018BA42B9803 sha1 193B14120119162518A73C70876F0B8BFFDBD96E flags verified ) + rom ( name "Mega Man Zero (USA, Europe).gba" size 8388608 crc 9707d2a1 sha1 193B14120119162518A73C70876F0B8BFFDBD96E flags verified ) +) + +game ( + name "Mega Man Zero (USA) (Wii U Virtual Console)" + description "Mega Man Zero (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Zero (USA) (Wii U Virtual Console).gba" size 8388608 crc 9c77209c sha1 7279705E24D32895DADA7F5476F68BBC33DD643B flags verified ) ) game ( name "Mega Man Zero 2 (USA)" description "Mega Man Zero 2 (USA)" - rom ( name "Mega Man Zero 2 (USA).gba" size 8388608 crc CE1E37BB md5 182363B0698322E1864CED6E9EED7EAD sha1 C4D93A58F0F82C526DEC8A3FDBDA170336303689 flags verified ) + rom ( name "Mega Man Zero 2 (USA).gba" size 8388608 crc ce1e37bb sha1 C4D93A58F0F82C526DEC8A3FDBDA170336303689 flags verified ) ) game ( name "Mega Man Zero 2 (Europe)" description "Mega Man Zero 2 (Europe)" - rom ( name "Mega Man Zero 2 (Europe).gba" size 8388608 crc 29A14B59 md5 55DCBE18E02F7D2934C537508DE532B6 sha1 C55ECA8F2C31FDF772F2605181D0B29815EA37A0 ) + rom ( name "Mega Man Zero 2 (Europe).gba" size 8388608 crc 29a14b59 sha1 C55ECA8F2C31FDF772F2605181D0B29815EA37A0 flags verified ) +) + +game ( + name "Mega Man Zero 2 (USA) (Wii U Virtual Console)" + description "Mega Man Zero 2 (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Zero 2 (USA) (Wii U Virtual Console).gba" size 8388608 crc 30d051fe sha1 D7A1EDD912F8E01BC442809B922BCEAF5A1F0176 flags verified ) ) game ( name "Mega Man Zero 3 (Europe)" description "Mega Man Zero 3 (Europe)" - rom ( name "Mega Man Zero 3 (Europe).gba" size 8388608 crc B099577F md5 9CE73FF9AA1473F250D103C1BDBBD738 sha1 EDFCB606136951374F24AA8FD7E5B4E710300301 ) + rom ( name "Mega Man Zero 3 (Europe).gba" size 8388608 crc b099577f sha1 EDFCB606136951374F24AA8FD7E5B4E710300301 ) ) game ( name "Mega Man Zero 3 (USA)" description "Mega Man Zero 3 (USA)" - rom ( name "Mega Man Zero 3 (USA).gba" size 8388608 crc 2784F3F2 md5 AA1D5EEFFCD5E4577DB9EE6D9B1100F9 sha1 403A78F2CAD93D41E4B0F2E520CE08026531664B flags verified ) + rom ( name "Mega Man Zero 3 (USA).gba" size 8388608 crc 2784f3f2 sha1 403A78F2CAD93D41E4B0F2E520CE08026531664B flags verified ) +) + +game ( + name "Mega Man Zero 3 (USA) (Wii U Virtual Console)" + description "Mega Man Zero 3 (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Zero 3 (USA) (Wii U Virtual Console).gba" size 16777216 crc cbd24ac4 sha1 DE5413481D823C53973CB29507567EF3DC6AF399 flags verified ) ) game ( name "Mega Man Zero 4 (Europe)" description "Mega Man Zero 4 (Europe)" - rom ( name "Mega Man Zero 4 (Europe).gba" size 16777216 crc B7F022B9 md5 D3A76F1C92E3044B1A21F1AAE84D21AB sha1 8E13B9EE89A2ED665212DAA401BA9331AD11BDA9 ) + rom ( name "Mega Man Zero 4 (Europe).gba" size 16777216 crc b7f022b9 sha1 8E13B9EE89A2ED665212DAA401BA9331AD11BDA9 ) ) game ( name "Mega Man Zero 4 (USA)" description "Mega Man Zero 4 (USA)" - rom ( name "Mega Man Zero 4 (USA).gba" size 16777216 crc 7EE24793 md5 0D1E88BDB09FF68ADF9877A121325F9C sha1 596993205A1895A6F51E80749407FB069B907628 flags verified ) + rom ( name "Mega Man Zero 4 (USA).gba" size 16777216 crc 7ee24793 sha1 596993205A1895A6F51E80749407FB069B907628 flags verified ) +) + +game ( + name "Mega Man Zero 4 (USA) (Wii U Virtual Console)" + description "Mega Man Zero 4 (USA) (Wii U Virtual Console)" + rom ( name "Mega Man Zero 4 (USA) (Wii U Virtual Console).gba" size 16777216 crc c4838cfa sha1 24A774446C8F652C78BB4BD938FC57C612DB3D6C flags verified ) ) game ( name "Meine Tierarztpraxis (Germany) (En,De)" description "Meine Tierarztpraxis (Germany) (En,De)" - rom ( name "Meine Tierarztpraxis (Germany) (En,De).gba" size 8388608 crc 13CE32E8 md5 09467407B4D5E62508405F6EC518E6DD sha1 B6FCF6A7985E3FF834D0BF9B384F750EAE067EFC ) + rom ( name "Meine Tierarztpraxis (Germany) (En,De).gba" size 8388608 crc 13ce32e8 sha1 B6FCF6A7985E3FF834D0BF9B384F750EAE067EFC ) ) game ( name "Meine Tierpension (Germany) (En,De)" description "Meine Tierpension (Germany) (En,De)" - rom ( name "Meine Tierpension (Germany) (En,De).gba" size 8388608 crc 78AD82FF md5 C8896F5AE10CBDF9A1D4B98166FF13C0 sha1 09D511ECB93BCEB5CC73E23B8711392F31D97A32 ) + rom ( name "Meine Tierpension (Germany) (En,De).gba" size 8388608 crc 78ad82ff sha1 09D511ECB93BCEB5CC73E23B8711392F31D97A32 ) ) game ( name "Meitantei Conan - Akatsuki no Monument (Japan)" description "Meitantei Conan - Akatsuki no Monument (Japan)" - rom ( name "Meitantei Conan - Akatsuki no Monument (Japan).gba" size 8388608 crc C048B723 md5 B3C187C391A4A75C257ECC83ABAB30A8 sha1 D971B2FBBCB0F6CB378A226902FE44F8CFEB99EB ) + rom ( name "Meitantei Conan - Akatsuki no Monument (Japan).gba" size 8388608 crc c048b723 sha1 D971B2FBBCB0F6CB378A226902FE44F8CFEB99EB ) ) game ( name "Meitantei Conan - Nerawareta Tantei (Japan)" description "Meitantei Conan - Nerawareta Tantei (Japan)" - rom ( name "Meitantei Conan - Nerawareta Tantei (Japan).gba" size 8388608 crc 5F9C7A4A md5 9D419BFA53E1C4241E076686BF9646CC sha1 3636C94C319C26903E1F05E3CD63D18F0BFC439C ) + rom ( name "Meitantei Conan - Nerawareta Tantei (Japan).gba" size 8388608 crc 5f9c7a4a sha1 3636C94C319C26903E1F05E3CD63D18F0BFC439C ) ) game ( name "Men in Black - The Series (Europe)" description "Men in Black - The Series (Europe)" - rom ( name "Men in Black - The Series (Europe).gba" size 4194304 crc 56BA6858 md5 59A449254974F537C73FB10ED5246CFA sha1 ED6081BE3E88613B9868E132B6F6206CCF349385 flags verified ) + rom ( name "Men in Black - The Series (Europe).gba" size 4194304 crc 56ba6858 sha1 ED6081BE3E88613B9868E132B6F6206CCF349385 flags verified ) ) game ( name "Men in Black - The Series (USA)" description "Men in Black - The Series (USA)" - rom ( name "Men in Black - The Series (USA).gba" size 4194304 crc 589810A5 md5 7A7D4FACA339A80BF99E96DF67C9FF24 sha1 6815F0910C5020CE7F0198DCBCB6E607F92FFA97 ) + rom ( name "Men in Black - The Series (USA).gba" size 4194304 crc 589810a5 sha1 6815F0910C5020CE7F0198DCBCB6E607F92FFA97 ) ) game ( name "Mermaid Melody - Pichi Pichi Pitch (Japan)" description "Mermaid Melody - Pichi Pichi Pitch (Japan)" - rom ( name "Mermaid Melody - Pichi Pichi Pitch (Japan).gba" size 16777216 crc 63F72589 md5 DCFB3D652C77BA9574CF42FF18EE2F30 sha1 4A0422ACF0F22DD85F35A2E040ADCFDF70DCC6EC ) + rom ( name "Mermaid Melody - Pichi Pichi Pitch (Japan).gba" size 16777216 crc 63f72589 sha1 4A0422ACF0F22DD85F35A2E040ADCFDF70DCC6EC flags verified ) ) game ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichi Party (Japan)" description "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichi Party (Japan)" - rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichi Party (Japan).gba" size 16777216 crc F786FFA7 md5 976BB334F76277357CEB33548D5E03DF sha1 79571B4D16098FF04F2C9DDB3880D67A01ADE4A7 ) + rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichi Party (Japan).gba" size 16777216 crc f786ffa7 sha1 79571B4D16098FF04F2C9DDB3880D67A01ADE4A7 ) ) game ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan)" description "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan)" - rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan).gba" size 33554432 crc 7A4FDEC3 md5 E5445BBB91FA514A63FD54BF1CE39CF8 sha1 D6BD3140B83FB9B1C2D84B6FAF21C7286E29D129 ) + rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan).gba" size 33554432 crc 7a4fdec3 sha1 D6BD3140B83FB9B1C2D84B6FAF21C7286E29D129 flags verified ) ) game ( name "Metal Max 2 Kai (Japan)" description "Metal Max 2 Kai (Japan)" - rom ( name "Metal Max 2 Kai (Japan).gba" size 4194304 crc BC1FEAF0 md5 4A7EDEE1AAFEBDCC97EE01909F14A7C7 sha1 73C58F67E1FF42CFFA30970B6F226C352635F07D ) + rom ( name "Metal Max 2 Kai (Japan).gba" size 4194304 crc bc1feaf0 sha1 73C58F67E1FF42CFFA30970B6F226C352635F07D ) ) game ( name "Metal Max 2 Kai (Japan) (Rev 1)" description "Metal Max 2 Kai (Japan) (Rev 1)" - rom ( name "Metal Max 2 Kai (Japan) (Rev 1).gba" size 4194304 crc 66725A09 md5 728D2BA4FB710CC696E401F797FF1397 sha1 B827FF8B0119F763BDC32062E77E6ED8D44985BA ) + rom ( name "Metal Max 2 Kai (Japan) (Rev 1).gba" size 4194304 crc 66725a09 sha1 B827FF8B0119F763BDC32062E77E6ED8D44985BA ) ) game ( name "Metal Slug Advance (USA)" description "Metal Slug Advance (USA)" - rom ( name "Metal Slug Advance (USA).gba" size 8388608 crc 09980880 md5 6838EB5DF807A0F3299AD76066D59D26 sha1 067E1511AB6BECF797F1BBD321A858E96A0349AF ) + rom ( name "Metal Slug Advance (USA).gba" size 8388608 crc 09980880 sha1 067E1511AB6BECF797F1BBD321A858E96A0349AF ) ) game ( name "Metal Slug Advance (Japan)" description "Metal Slug Advance (Japan)" - rom ( name "Metal Slug Advance (Japan).gba" size 8388608 crc 0CABA589 md5 4C57EB408A29A61D7C0C3F9E2CFA15EB sha1 410BF6C06DA43AB001C5B044CD71D2E992ACC6C7 ) + rom ( name "Metal Slug Advance (Japan).gba" size 8388608 crc 0caba589 sha1 410BF6C06DA43AB001C5B044CD71D2E992ACC6C7 ) ) game ( name "Metal Slug Advance (Europe)" description "Metal Slug Advance (Europe)" - rom ( name "Metal Slug Advance (Europe).gba" size 8388608 crc 3806F4AE md5 584FA297B632CFF5B54C2DEF93C0DE2F sha1 0719AEE29B0DA365E7AD52BB0AE9545BCD377152 flags verified ) + rom ( name "Metal Slug Advance (Europe).gba" size 8388608 crc 3806f4ae sha1 0719AEE29B0DA365E7AD52BB0AE9545BCD377152 flags verified ) ) game ( name "Metalgun Slinger (Japan)" description "Metalgun Slinger (Japan)" - rom ( name "Metalgun Slinger (Japan).gba" size 8388608 crc 8DFB7A2F md5 8B7A8C1E315CCF6132AFB5BCD7AA4136 sha1 DBF9E8515D9993C6FBAB921AF65CBBDEABD4AA93 ) + rom ( name "Metalgun Slinger (Japan).gba" size 8388608 crc 8dfb7a2f sha1 DBF9E8515D9993C6FBAB921AF65CBBDEABD4AA93 ) ) game ( name "Metroid - Zero Mission (USA)" description "Metroid - Zero Mission (USA)" - rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5C61A844 md5 EBBCE58109988B6DA61EBB06C7A432D5 sha1 5DE8536AFE1F0078EE6FE1089F890E8C7AA0A6E8 flags verified ) + rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5DE8536AFE1F0078EE6FE1089F890E8C7AA0A6E8 flags verified ) ) game ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It)" - rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc F1D92E63 md5 07930E72D4824BD63827A1A823CC8829 sha1 0FD107445A42E6F3A3E5CE8C865F412583179903 flags verified ) + rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f1d92e63 sha1 0FD107445A42E6F3A3E5CE8C865F412583179903 flags verified ) ) game ( name "Metroid - Zero Mission (Japan)" description "Metroid - Zero Mission (Japan)" - rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44B79E2B md5 650140CCAE6E1AB7AF44C74986002375 sha1 096F07685A3DC9286E71AA0B761F233B5EFA2FCD flags verified ) + rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096F07685A3DC9286E71AA0B761F233B5EFA2FCD flags verified ) ) game ( - name "Metroid Fusion (USA, Australia)" - description "Metroid Fusion (USA, Australia)" - rom ( name "Metroid Fusion (USA, Australia).gba" size 8388608 crc 6C75479C md5 AF5040FC0F579800151EE2A683E2E5B5 sha1 CA33F4348C2C05DD330D37B97E2C5A69531DFE87 flags verified ) + name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta)" + description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta) (Came as .srl, so probably straight from Nintendo.)" + rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta).gba" size 16777216 crc b6438226 sha1 3C0B7CCD303C30AC5C4FFC9FB0AA7137A533AD69 flags verified ) +) + +game ( + name "Metroid - Zero Mission (USA) (Beta)" + description "Metroid - Zero Mission (USA) (Beta) (Came as .srl, so probably came as a digital file originating from the developer.)" + rom ( name "Metroid - Zero Mission (USA) (Beta).gba" size 16777216 crc 922c4a10 sha1 58986C4D6F2E5CCDC04936CC8B7C9D378570710C flags verified ) +) + +game ( + name "Metroid - Zero Mission (USA) (Wii U Virtual Console)" + description "Metroid - Zero Mission (USA) (Wii U Virtual Console)" + rom ( name "Metroid - Zero Mission (USA) (Wii U Virtual Console).gba" size 8388608 crc 8825294a sha1 2EA5E30681DC7AAB3258535DEBBDDFB9AA245A8A flags verified ) +) + +game ( + name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 8388608 crc 3ab66d36 sha1 EEBA0BF63E5B55EA99BE9BA461459023AD352019 flags verified ) +) + +game ( + name "Metroid Fusion (USA)" + description "Metroid Fusion (USA)" + rom ( name "Metroid Fusion (USA).gba" size 8388608 crc 6c75479c sha1 CA33F4348C2C05DD330D37B97E2C5A69531DFE87 flags verified ) ) game ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It)" description "Metroid Fusion (Europe) (En,Fr,De,Es,It)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 974E46AB md5 EB462F708C715309D08FD7968825AE9E sha1 CC46D54B70C1EE38C856EE6E58EC712136763389 flags verified ) + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 974e46ab sha1 CC46D54B70C1EE38C856EE6E58EC712136763389 flags verified ) ) game ( name "Metroid Fusion (Japan)" description "Metroid Fusion (Japan)" - rom ( name "Metroid Fusion (Japan).gba" size 8388608 crc 817A7E9E md5 E535A6EC2EB86D183453037289527A63 sha1 5D21C668BAA84DA4A5B745BE56809BB277F947A3 ) + rom ( name "Metroid Fusion (Japan).gba" size 8388608 crc 817a7e9e sha1 5D21C668BAA84DA4A5B745BE56809BB277F947A3 flags verified ) +) + +game ( + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-11).gba" size 16777216 crc 3acbd239 sha1 A45B539BECBF10F3913255D6D624EE954DCC5593 flags verified ) +) + +game ( + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16) (Came as .srl, so probably straight from Nintendo.)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16).gba" size 8388608 crc 1605e4f7 sha1 F688F2D3186A0A90040ABB214EFD1E8E93A424CD flags verified ) +) + +game ( + name "Metroid Fusion (USA) (Wii U Virtual Console)" + description "Metroid Fusion (USA) (Wii U Virtual Console)" + rom ( name "Metroid Fusion (USA) (Wii U Virtual Console).gba" size 8388608 crc 162a46b8 sha1 C63419A4EE7C2A5E412FA16645EE04CB24027724 flags verified ) +) + +game ( + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 8388608 crc eee01b78 sha1 82E507863F647DC566BBF45227E8CD284052ECBA flags verified ) ) game ( name "Mezase! Koushien (Japan)" description "Mezase! Koushien (Japan)" - rom ( name "Mezase! Koushien (Japan).gba" size 8388608 crc 50E473A8 md5 016707A7640C82C4258B6C1D8B98FC83 sha1 9986D625CA32689B92B22F9E86AB4F8114EB92AD ) + rom ( name "Mezase! Koushien (Japan).gba" size 8388608 crc 50e473a8 sha1 9986D625CA32689B92B22F9E86AB4F8114EB92AD ) ) game ( name "Mickey no Pocket Resort (Japan)" description "Mickey no Pocket Resort (Japan)" - rom ( name "Mickey no Pocket Resort (Japan).gba" size 8388608 crc EDB264B8 md5 4398AA3E3D1F826A99F5286EFDA20488 sha1 DF700B7C594B8588462CB83623BF4008AF0CB2FF ) + rom ( name "Mickey no Pocket Resort (Japan).gba" size 8388608 crc edb264b8 sha1 DF700B7C594B8588462CB83623BF4008AF0CB2FF ) ) game ( name "Mickey to Donald no Magical Quest 3 (Japan)" description "Mickey to Donald no Magical Quest 3 (Japan)" - rom ( name "Mickey to Donald no Magical Quest 3 (Japan).gba" size 4194304 crc 32D851F7 md5 A4F50DC3B3CDD6B3D688E1B89B34703D sha1 A849EC6C383B7C5AF9CF6D6FCCC3AAD9741036D0 ) + rom ( name "Mickey to Donald no Magical Quest 3 (Japan).gba" size 4194304 crc 32d851f7 sha1 A849EC6C383B7C5AF9CF6D6FCCC3AAD9741036D0 ) ) game ( name "Mickey to Minnie no Magical Quest (Japan)" description "Mickey to Minnie no Magical Quest (Japan)" - rom ( name "Mickey to Minnie no Magical Quest (Japan).gba" size 4194304 crc BBAE85C8 md5 62977938536A270190BCB89ECD5C207D sha1 409CE308CE8B6F1DF7C361E55418E30B64FCEA78 ) + rom ( name "Mickey to Minnie no Magical Quest (Japan).gba" size 4194304 crc bbae85c8 sha1 409CE308CE8B6F1DF7C361E55418E30B64FCEA78 ) ) game ( name "Mickey to Minnie no Magical Quest 2 (Japan)" description "Mickey to Minnie no Magical Quest 2 (Japan)" - rom ( name "Mickey to Minnie no Magical Quest 2 (Japan).gba" size 4194304 crc 092A7D0A md5 E8C8A0AA40FA0C32D42EEBACA6D5412F sha1 D0E0E29C9E49835375FF865082602E304EDEF89F ) + rom ( name "Mickey to Minnie no Magical Quest 2 (Japan).gba" size 4194304 crc 092a7d0a sha1 D0E0E29C9E49835375FF865082602E304EDEF89F ) ) game ( name "Micro Machines (Europe) (En,Fr,De,Es,It)" description "Micro Machines (Europe) (En,Fr,De,Es,It)" - rom ( name "Micro Machines (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9D102C82 md5 A202EEA1B2801421714260D5E02A7492 sha1 F74261138C93B872B8F552A145D7D56E9D44D538 ) + rom ( name "Micro Machines (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9d102c82 sha1 F74261138C93B872B8F552A145D7D56E9D44D538 flags verified ) ) game ( name "Midnight Club - Street Racing (USA)" description "Midnight Club - Street Racing (USA)" - rom ( name "Midnight Club - Street Racing (USA).gba" size 4194304 crc 911BE520 md5 3A2206F7FDCB36034D9FFF753964F201 sha1 66BE392D9FB84D39DF31ED8C8779CC58612DD4AC ) + rom ( name "Midnight Club - Street Racing (USA).gba" size 4194304 crc 911be520 sha1 66BE392D9FB84D39DF31ED8C8779CC58612DD4AC ) ) game ( name "Midnight Club - Street Racing (Europe) (En,Fr,De,Es,It)" description "Midnight Club - Street Racing (Europe) (En,Fr,De,Es,It)" - rom ( name "Midnight Club - Street Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 091230C6 md5 4B67D4EDE1720FD4827AF6E7EBF3C6E6 sha1 273D472EC3646E35DB71B2DEEA3A8E9977134679 ) + rom ( name "Midnight Club - Street Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 091230c6 sha1 273D472EC3646E35DB71B2DEEA3A8E9977134679 flags verified ) ) game ( name "Midway's Greatest Arcade Hits (USA, Europe)" description "Midway's Greatest Arcade Hits (USA, Europe)" - rom ( name "Midway's Greatest Arcade Hits (USA, Europe).gba" size 4194304 crc C01C4D0A md5 CFD85C7CC23E577CD6A338E83E95D618 sha1 194913C9D5A74B9AF5F90B539828F6FA77C016ED flags verified ) + rom ( name "Midway's Greatest Arcade Hits (USA, Europe).gba" size 4194304 crc c01c4d0a sha1 194913C9D5A74B9AF5F90B539828F6FA77C016ED flags verified ) ) game ( - name "Mighty Beanz Pocket Puzzles (USA)" - description "Mighty Beanz Pocket Puzzles (USA)" - rom ( name "Mighty Beanz Pocket Puzzles (USA).gba" size 4194304 crc 54DF36DA md5 66E896522A91ECD1E45FDE5E93920BF7 sha1 78F9E56A2F22A08B1597C9C545B0474BA290C298 ) + name "Mighty Beanz - Pocket Puzzles (USA)" + description "Mighty Beanz - Pocket Puzzles (USA)" + rom ( name "Mighty Beanz - Pocket Puzzles (USA).gba" size 4194304 crc 54df36da sha1 78F9E56A2F22A08B1597C9C545B0474BA290C298 ) ) game ( name "Mijn Dierenpension (Netherlands) (En,Nl)" description "Mijn Dierenpension (Netherlands) (En,Nl)" - rom ( name "Mijn Dierenpension (Netherlands) (En,Nl).gba" size 8388608 crc 310EB2FE md5 8FA81EB18F711CE98792B8AEA919E2F4 sha1 DE0E1F47F4CBFBB1EF8EBD67289AC978E8F28317 ) + rom ( name "Mijn Dierenpension (Netherlands) (En,Nl).gba" size 8388608 crc 310eb2fe sha1 DE0E1F47F4CBFBB1EF8EBD67289AC978E8F28317 ) ) game ( name "Mijn Dierenpraktijk (Netherlands) (En,Nl)" description "Mijn Dierenpraktijk (Netherlands) (En,Nl)" - rom ( name "Mijn Dierenpraktijk (Netherlands) (En,Nl).gba" size 8388608 crc 227A5430 md5 B47DB8937426D5A23FBA3C51ACD5FE69 sha1 245D9370179D21B7EA69ECE2DC9B6CEB6294F99D ) + rom ( name "Mijn Dierenpraktijk (Netherlands) (En,Nl).gba" size 8388608 crc 227a5430 sha1 245D9370179D21B7EA69ECE2DC9B6CEB6294F99D ) ) game ( name "Mike Tyson Boxing (Europe) (En,Fr,De,Es,It)" description "Mike Tyson Boxing (Europe) (En,Fr,De,Es,It)" - rom ( name "Mike Tyson Boxing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B9566812 md5 67C69E7391F3A801E3F4F434206DD261 sha1 B35EEE5852A0BC2A96E983E4A398AD46B4900104 ) + rom ( name "Mike Tyson Boxing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b9566812 sha1 B35EEE5852A0BC2A96E983E4A398AD46B4900104 ) ) game ( name "Mike Tyson Boxing (USA) (En,Fr,De,Es,It)" description "Mike Tyson Boxing (USA) (En,Fr,De,Es,It)" - rom ( name "Mike Tyson Boxing (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 48109F8D md5 26138B868DEF156D361525DC69C2899E sha1 7B60E69296EABD98EA17836ADD7F6F8BB9A07731 ) + rom ( name "Mike Tyson Boxing (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 48109f8d sha1 7B60E69296EABD98EA17836ADD7F6F8BB9A07731 ) ) game ( name "Minami no Umi no Odyssey (Japan)" description "Minami no Umi no Odyssey (Japan)" - rom ( name "Minami no Umi no Odyssey (Japan).gba" size 4194304 crc 6E53115B md5 D59D88A73622B4DF76CF98D1554644E4 sha1 9B20EC7CEA9A5F41A0BE62333C9D70045E94E046 ) + rom ( name "Minami no Umi no Odyssey (Japan).gba" size 4194304 crc 6e53115b sha1 9B20EC7CEA9A5F41A0BE62333C9D70045E94E046 ) ) game ( name "Mini Moni. - Mika no Happy Morning Chatty (Japan)" description "Mini Moni. - Mika no Happy Morning Chatty (Japan)" - rom ( name "Mini Moni. - Mika no Happy Morning Chatty (Japan).gba" size 8388608 crc 492CF823 md5 F9AB5E9200DFAE863F30E9332D7FCD95 sha1 96A102B974E00AA27D060952A770EA49F5639EF5 ) + rom ( name "Mini Moni. - Mika no Happy Morning Chatty (Japan).gba" size 8388608 crc 492cf823 sha1 96A102B974E00AA27D060952A770EA49F5639EF5 ) ) game ( name "Mini Moni. - Onegai Ohoshi-sama! (Japan)" description "Mini Moni. - Onegai Ohoshi-sama! (Japan)" - rom ( name "Mini Moni. - Onegai Ohoshi-sama! (Japan).gba" size 8388608 crc F11C35CC md5 02D54C3ED3DAF9976F355C16FE8303FC sha1 D34795CF3679C6F259177DB52A138C0D6E9FCDFD ) + rom ( name "Mini Moni. - Onegai Ohoshi-sama! (Japan).gba" size 8388608 crc f11c35cc sha1 D34795CF3679C6F259177DB52A138C0D6E9FCDFD ) ) game ( name "Minna de Puyo Puyo (Japan) (En,Ja)" description "Minna de Puyo Puyo (Japan) (En,Ja)" - rom ( name "Minna de Puyo Puyo (Japan) (En,Ja).gba" size 8388608 crc 857FB1EF md5 62E74F9B0928B578764E8F466DAC412D sha1 927BD890ED5E1573022F9806F91E554A12DE5429 ) + rom ( name "Minna de Puyo Puyo (Japan) (En,Ja).gba" size 8388608 crc 857fb1ef sha1 927BD890ED5E1573022F9806F91E554A12DE5429 flags verified ) ) game ( name "Minna no Ouji-sama (Japan)" description "Minna no Ouji-sama (Japan)" - rom ( name "Minna no Ouji-sama (Japan).gba" size 33554432 crc 19DC05E6 md5 8F380C11BD958656AFBECA39B80C83C9 sha1 C709C2F1F439825A4F6783BE045B99F5757E8B24 ) + rom ( name "Minna no Ouji-sama (Japan).gba" size 33554432 crc 19dc05e6 sha1 C709C2F1F439825A4F6783BE045B99F5757E8B24 ) ) game ( name "Minna no Shiiku Series - Boku no Kabuto, Kuwagata (Japan)" description "Minna no Shiiku Series - Boku no Kabuto, Kuwagata (Japan)" - rom ( name "Minna no Shiiku Series - Boku no Kabuto, Kuwagata (Japan).gba" size 8388608 crc 20E296A6 md5 EB3AD3925A39E6E36EC9CB0FC3F0D535 sha1 D57D2035445683B842E6FB5C7F330C82AFB7EFCF ) + rom ( name "Minna no Shiiku Series - Boku no Kabuto, Kuwagata (Japan).gba" size 8388608 crc 20e296a6 sha1 D57D2035445683B842E6FB5C7F330C82AFB7EFCF ) ) game ( name "Minna no Shiiku Series 1 - Boku no Kabutomushi (Japan)" description "Minna no Shiiku Series 1 - Boku no Kabutomushi (Japan)" - rom ( name "Minna no Shiiku Series 1 - Boku no Kabutomushi (Japan).gba" size 4194304 crc F83FE589 md5 7ED736155CC3CC6B0EFB314FFE7D2AAE sha1 1771CF9BECA944077E4804766C31B38728CF2B7E ) + rom ( name "Minna no Shiiku Series 1 - Boku no Kabutomushi (Japan).gba" size 4194304 crc f83fe589 sha1 1771CF9BECA944077E4804766C31B38728CF2B7E ) ) game ( name "Minna no Shiiku Series 2 - Boku no Kuwagata (Japan)" description "Minna no Shiiku Series 2 - Boku no Kuwagata (Japan)" - rom ( name "Minna no Shiiku Series 2 - Boku no Kuwagata (Japan).gba" size 4194304 crc C0BA281D md5 60B681A9C1B892F12D84278B1F7732E4 sha1 64CFCA9E40194064677FC37998618DDC9206605D ) + rom ( name "Minna no Shiiku Series 2 - Boku no Kuwagata (Japan).gba" size 4194304 crc c0ba281d sha1 64CFCA9E40194064677FC37998618DDC9206605D flags verified ) ) game ( name "Minna no Soft Series - Happy Trump 20 (Japan)" description "Minna no Soft Series - Happy Trump 20 (Japan)" - rom ( name "Minna no Soft Series - Happy Trump 20 (Japan).gba" size 4194304 crc D0EF2BC4 md5 E1C7214348810C9A7B430C64A06E68B7 sha1 6FF8067D442104E2D43C9B3F66E4C4F514FCC480 ) + rom ( name "Minna no Soft Series - Happy Trump 20 (Japan).gba" size 4194304 crc d0ef2bc4 sha1 6FF8067D442104E2D43C9B3F66E4C4F514FCC480 ) ) game ( name "Minna no Soft Series - Hyokkori Hyoutan-jima - Don Gabacho Daikatsuyaku no Maki (Japan)" description "Minna no Soft Series - Hyokkori Hyoutan-jima - Don Gabacho Daikatsuyaku no Maki (Japan)" - rom ( name "Minna no Soft Series - Hyokkori Hyoutan-jima - Don Gabacho Daikatsuyaku no Maki (Japan).gba" size 4194304 crc 481D1D5F md5 9B809F779A41A24258AA9DBB34263D85 sha1 C0742BC3F716C74D72711E25BC12D7BE6D75E206 ) + rom ( name "Minna no Soft Series - Hyokkori Hyoutan-jima - Don Gabacho Daikatsuyaku no Maki (Japan).gba" size 4194304 crc 481d1d5f sha1 C0742BC3F716C74D72711E25BC12D7BE6D75E206 flags verified ) ) game ( name "Minna no Soft Series - Minna no Mahjong (Japan)" description "Minna no Soft Series - Minna no Mahjong (Japan)" - rom ( name "Minna no Soft Series - Minna no Mahjong (Japan).gba" size 4194304 crc 66B779B0 md5 40F90B4F45A78C1810C59EB066201638 sha1 B4BE9E8E8062F0764376821465B72C35D770B5EB ) + rom ( name "Minna no Soft Series - Minna no Mahjong (Japan).gba" size 4194304 crc 66b779b0 sha1 B4BE9E8E8062F0764376821465B72C35D770B5EB ) ) game ( name "Minna no Soft Series - Minna no Shougi (Japan)" description "Minna no Soft Series - Minna no Shougi (Japan)" - rom ( name "Minna no Soft Series - Minna no Shougi (Japan).gba" size 4194304 crc 08B62391 md5 612F5672AE601B796DB01DCE034A5548 sha1 7440C18668813A6FF2A51205B79FBF19AB96F09D ) + rom ( name "Minna no Soft Series - Minna no Shougi (Japan).gba" size 4194304 crc 08b62391 sha1 7440C18668813A6FF2A51205B79FBF19AB96F09D ) ) game ( name "Minna no Soft Series - Minna no Shougi (Japan) (Rev 1)" description "Minna no Soft Series - Minna no Shougi (Japan) (Rev 1)" - serial "BSGJ" - rom ( name "Minna no Soft Series - Minna no Shougi (Japan) (Rev 1).gba" size 4194304 crc C62C15C6 md5 1690C80A29F8096D50422E38517674DC sha1 1B34D8BDF085E2276E103E72E29CE58867433068 ) + rom ( name "Minna no Soft Series - Minna no Shougi (Japan) (Rev 1).gba" size 4194304 crc c62c15c6 sha1 1B34D8BDF085E2276E103E72E29CE58867433068 flags verified ) ) game ( name "Minna no Soft Series - Numpla Advance (Japan)" description "Minna no Soft Series - Numpla Advance (Japan)" - rom ( name "Minna no Soft Series - Numpla Advance (Japan).gba" size 4194304 crc 044C6F68 md5 822168FB70FD023A6E6008A59D54F99F sha1 D3B1F600EB4B0D10D144C30A5710AC2CF1E46296 ) + rom ( name "Minna no Soft Series - Numpla Advance (Japan).gba" size 4194304 crc 044c6f68 sha1 D3B1F600EB4B0D10D144C30A5710AC2CF1E46296 ) ) game ( name "Minna no Soft Series - Shanghai (Japan)" description "Minna no Soft Series - Shanghai (Japan)" - rom ( name "Minna no Soft Series - Shanghai (Japan).gba" size 4194304 crc FEEFEDDC md5 8ECB24E6711DF71241E4D52C7D1D07E0 sha1 1E2846D6998DB5C43FFA7CAFE0790A5EFDBEA3C8 ) + rom ( name "Minna no Soft Series - Shanghai (Japan).gba" size 4194304 crc feefeddc sha1 1E2846D6998DB5C43FFA7CAFE0790A5EFDBEA3C8 ) +) + +game ( + name "Minna no Soft Series - Shanghai (Japan) (Rev 1)" + description "Minna no Soft Series - Shanghai (Japan) (Rev 1)" + rom ( name "Minna no Soft Series - Shanghai (Japan) (Rev 1).gba" size 4194304 crc 28a8dc30 sha1 2D2EF5FC8131178106AF2BE5358B318D981344BD flags verified ) ) game ( name "Minna no Soft Series - Tetris Advance (Japan)" description "Minna no Soft Series - Tetris Advance (Japan)" - rom ( name "Minna no Soft Series - Tetris Advance (Japan).gba" size 4194304 crc 67C92883 md5 2166BC8D0CF08A6FE0CC44559A52C3A1 sha1 03E115DA05736E773DADB57A26E3F94002299F6C ) + rom ( name "Minna no Soft Series - Tetris Advance (Japan).gba" size 4194304 crc 67c92883 sha1 03E115DA05736E773DADB57A26E3F94002299F6C ) ) game ( name "Minna no Soft Series - Tetris Advance (Japan) (Rev 1)" description "Minna no Soft Series - Tetris Advance (Japan) (Rev 1)" - rom ( name "Minna no Soft Series - Tetris Advance (Japan) (Rev 1).gba" size 4194304 crc 524D0749 md5 469B5B94DD8E223A5FA1CD04E4E4C1DC sha1 379F524B1772AD41355B68884DF1F8BE75E388E7 ) + rom ( name "Minna no Soft Series - Tetris Advance (Japan) (Rev 1).gba" size 4194304 crc 524d0749 sha1 379F524B1772AD41355B68884DF1F8BE75E388E7 flags verified ) ) game ( name "Minna no Soft Series - Zooo (Japan)" description "Minna no Soft Series - Zooo (Japan)" - rom ( name "Minna no Soft Series - Zooo (Japan).gba" size 4194304 crc 72EB35E3 md5 AE89BFB0FE9892C92C061013BE4619A2 sha1 5DD2C153D0DEC9DF127256A0426C12F188D813D6 ) + rom ( name "Minna no Soft Series - Zooo (Japan).gba" size 4194304 crc 72eb35e3 sha1 5DD2C153D0DEC9DF127256A0426C12F188D813D6 ) ) game ( name "Minority Report - Everybody Runs (USA, Europe)" description "Minority Report - Everybody Runs (USA, Europe)" - rom ( name "Minority Report - Everybody Runs (USA, Europe).gba" size 8388608 crc 3D56EAD6 md5 582AD48ED874C3707ABBD0967A3CC6AA sha1 E3CAABD4CCA3B435B5ADB924633F183607DBDB79 ) + rom ( name "Minority Report - Everybody Runs (USA, Europe).gba" size 8388608 crc 3d56ead6 sha1 E3CAABD4CCA3B435B5ADB924633F183607DBDB79 ) ) game ( name "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan)" description "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan)" - rom ( name "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan).gba" size 4194304 crc 3A87F78B md5 6C6910864BE012D8AFE00364D6DDAA05 sha1 AD916495BBB9C3EE34B68C13F118A4CBCDB18B3B ) + rom ( name "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan).gba" size 4194304 crc 3a87f78b sha1 AD916495BBB9C3EE34B68C13F118A4CBCDB18B3B ) ) game ( name "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" description "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" - rom ( name "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 45DE1669 md5 54068C4366CE9072837003184B361A68 sha1 BD320D68873D1B0443AE39635C22E547C748E576 flags verified ) + rom ( name "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 45de1669 sha1 BD320D68873D1B0443AE39635C22E547C748E576 flags verified ) ) game ( name "Mission Impossible - Operation Surma (USA) (En,Fr,Es)" description "Mission Impossible - Operation Surma (USA) (En,Fr,Es)" - rom ( name "Mission Impossible - Operation Surma (USA) (En,Fr,Es).gba" size 4194304 crc F3DC4E3E md5 6CE6741E0A522351047B79851CD2D651 sha1 50E09660F2D9588F8CAD8C43FCA719CC78006E1A ) + rom ( name "Mission Impossible - Operation Surma (USA) (En,Fr,Es).gba" size 4194304 crc f3dc4e3e sha1 50E09660F2D9588F8CAD8C43FCA719CC78006E1A ) ) game ( name "Miteluode - Lingdian Renwu (China)" description "Miteluode - Lingdian Renwu (China)" - rom ( name "Miteluode - Lingdian Renwu (China).gba" size 8388608 crc E951865C md5 7C1AC3A3B9F0948BBCC6D5B2AFAC860C sha1 4703576C63F4C279520A1CC527937A37097A2FE6 ) + rom ( name "Miteluode - Lingdian Renwu (China).gba" size 8388608 crc e951865c sha1 4703576C63F4C279520A1CC527937A37097A2FE6 ) ) game ( name "Miteluode Ronghe (China)" description "Miteluode Ronghe (China)" - rom ( name "Miteluode Ronghe (China).gba" size 8388608 crc 042E5B07 md5 0DC8A17AF87706F54DB5B78F02C5AD12 sha1 315B94C66B8D5130006B4852B9D875B00BE4943D ) + rom ( name "Miteluode Ronghe (China).gba" size 8388608 crc 042e5b07 sha1 315B94C66B8D5130006B4852B9D875B00BE4943D ) ) game ( name "MLB SlugFest 20-04 (USA)" description "MLB SlugFest 20-04 (USA)" - rom ( name "MLB SlugFest 20-04 (USA).gba" size 4194304 crc A4E12D4B md5 3B4E5E2E7BEA27F7F0089277670B7F2C sha1 CD60F0AACDADA987F7935D7A5FA2CD3242ABC145 flags verified ) + rom ( name "MLB SlugFest 20-04 (USA).gba" size 4194304 crc a4e12d4b sha1 CD60F0AACDADA987F7935D7A5FA2CD3242ABC145 flags verified ) ) game ( name "Mobile Pro Yakyuu - Kantoku no Saihai (Japan)" description "Mobile Pro Yakyuu - Kantoku no Saihai (Japan)" - rom ( name "Mobile Pro Yakyuu - Kantoku no Saihai (Japan).gba" size 8388608 crc 8DF8A0C0 md5 85FA9B30552BCF2B5CFFA86F669DA0A1 sha1 9766AF7B47E5B63C922304D46362D1B374BDF0A0 ) + rom ( name "Mobile Pro Yakyuu - Kantoku no Saihai (Japan).gba" size 8388608 crc 8df8a0c0 sha1 9766AF7B47E5B63C922304D46362D1B374BDF0A0 flags verified ) ) game ( name "Mobile Suit Gundam Seed - Battle Assault (USA)" description "Mobile Suit Gundam Seed - Battle Assault (USA)" - rom ( name "Mobile Suit Gundam Seed - Battle Assault (USA).gba" size 4194304 crc 180D1491 md5 20BB7717258C3BD2E87B9B7617E95DF2 sha1 8287D3D336D94A85C5CB22DA0FD84918199197E1 flags verified ) + rom ( name "Mobile Suit Gundam Seed - Battle Assault (USA).gba" size 4194304 crc 180d1491 sha1 8287D3D336D94A85C5CB22DA0FD84918199197E1 flags verified ) ) game ( name "Moero!! Jaleco Collection (Japan)" description "Moero!! Jaleco Collection (Japan)" - rom ( name "Moero!! Jaleco Collection (Japan).gba" size 4194304 crc 6DA36E82 md5 CF20A09761AD3A42195694A0A34DA7C3 sha1 52D1CBEED52DE62147D13A667A9631F6D8A24865 ) + rom ( name "Moero!! Jaleco Collection (Japan).gba" size 4194304 crc 6da36e82 sha1 52D1CBEED52DE62147D13A667A9631F6D8A24865 ) ) game ( name "Momotarou Dentetsu G - Gold Deck o Tsukure! (Japan)" description "Momotarou Dentetsu G - Gold Deck o Tsukure! (Japan)" - rom ( name "Momotarou Dentetsu G - Gold Deck o Tsukure! (Japan).gba" size 16777216 crc 5F3E184E md5 80177651FAC95135F205C00A5F8AE922 sha1 ACB39C3DA3C93247E6C2FD7FBDA7DF2FC720CDD7 ) + rom ( name "Momotarou Dentetsu G - Gold Deck o Tsukure! (Japan).gba" size 16777216 crc 5f3e184e sha1 ACB39C3DA3C93247E6C2FD7FBDA7DF2FC720CDD7 flags verified ) ) game ( name "Momotarou Matsuri (Japan) (Rev 1)" description "Momotarou Matsuri (Japan) (Rev 1)" - rom ( name "Momotarou Matsuri (Japan) (Rev 1).gba" size 4194304 crc BF0523D1 md5 E876DDF9AECF8F52CAECEE2358ACD9CC sha1 DFE06BC08D2E3231815E23245A453B54B38ADA94 flags verified ) + rom ( name "Momotarou Matsuri (Japan) (Rev 1).gba" size 4194304 crc bf0523d1 sha1 DFE06BC08D2E3231815E23245A453B54B38ADA94 flags verified ) ) game ( name "Monopoly (USA)" description "Monopoly (USA)" - rom ( name "Monopoly (USA).gba" size 4194304 crc B01CBC07 md5 CE55F087D1ED4AB12A5BAD411DAE1113 sha1 81314B9FFE3C4DA5060DE098EE1394ECEF6FE9AD ) + rom ( name "Monopoly (USA).gba" size 4194304 crc b01cbc07 sha1 81314B9FFE3C4DA5060DE098EE1394ECEF6FE9AD ) ) game ( name "Monopoly (Europe) (En,Fr,De,Es)" description "Monopoly (Europe) (En,Fr,De,Es)" - rom ( name "Monopoly (Europe) (En,Fr,De,Es).gba" size 4194304 crc 7B113397 md5 5A45AE003854F9AA9C91B8E12FCF3E8B sha1 87FAE722488CC12F0FE56438B14FA50F27A844B8 ) + rom ( name "Monopoly (Europe) (En,Fr,De,Es).gba" size 4194304 crc 7b113397 sha1 87FAE722488CC12F0FE56438B14FA50F27A844B8 ) ) game ( name "Monster AG, Die (Germany)" description "Monster AG, Die (Germany)" - rom ( name "Monster AG, Die (Germany).gba" size 4194304 crc A23CB45F md5 BD1177F8F30BEF242ABA4714449092A3 sha1 24F77882D460D4EE06EAC0217F9087B0CAFCCA96 flags verified ) + rom ( name "Monster AG, Die (Germany).gba" size 4194304 crc a23cb45f sha1 24F77882D460D4EE06EAC0217F9087B0CAFCCA96 flags verified ) ) game ( name "Monster Farm Advance (Japan)" description "Monster Farm Advance (Japan)" - rom ( name "Monster Farm Advance (Japan).gba" size 8388608 crc C140FF7A md5 91C56CD17442041AF081D5A74D71E941 sha1 0AABB6272913482F4D8337F122BCF760055AC10F ) + rom ( name "Monster Farm Advance (Japan).gba" size 8388608 crc c140ff7a sha1 0AABB6272913482F4D8337F122BCF760055AC10F ) ) game ( name "Monster Farm Advance 2 (Japan)" description "Monster Farm Advance 2 (Japan)" - rom ( name "Monster Farm Advance 2 (Japan).gba" size 8388608 crc 1B14CF53 md5 E44A2AF9631DF8D957A0F3925B4DE3BA sha1 75CEF88ABCF6CBE6D667DF134900BE165905183A ) + rom ( name "Monster Farm Advance 2 (Japan).gba" size 8388608 crc 1b14cf53 sha1 75CEF88ABCF6CBE6D667DF134900BE165905183A ) ) game ( name "Monster Force (USA)" description "Monster Force (USA)" - rom ( name "Monster Force (USA).gba" size 8388608 crc AD4691D9 md5 EED661599B926EDDF6890C862C252112 sha1 3F97630914CBBB4BF45DCC42E7EB8062E9E8A271 ) + rom ( name "Monster Force (USA).gba" size 8388608 crc ad4691d9 sha1 3F97630914CBBB4BF45DCC42E7EB8062E9E8A271 ) ) game ( name "Monster Force (Europe) (En,Fr,De,Es,It)" description "Monster Force (Europe) (En,Fr,De,Es,It)" - rom ( name "Monster Force (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 137B0F9A md5 4E1B65A22EDDC145FD7EFECABFF0282E sha1 4B1578129DE4B82003806F7A9B193A8EC813DC46 flags verified ) + rom ( name "Monster Force (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 137b0f9a sha1 4B1578129DE4B82003806F7A9B193A8EC813DC46 flags verified ) ) game ( name "Monster Gate (Japan)" description "Monster Gate (Japan)" - rom ( name "Monster Gate (Japan).gba" size 8388608 crc 5B8AAA03 md5 BA1F2CD7D4EB41792103BF0A95FC0C09 sha1 4649710EB75181573D10AD059B3BC6270508CE3D ) + rom ( name "Monster Gate (Japan).gba" size 8388608 crc 5b8aaa03 sha1 4649710EB75181573D10AD059B3BC6270508CE3D ) +) + +game ( + name "Monster Gate (Japan) (Rev 1)" + description "Monster Gate (Japan) (Rev 1)" + rom ( name "Monster Gate (Japan) (Rev 1).gba" size 8388608 crc 7960926c sha1 592688731EF71246B12E775A33250B28F17028C6 flags verified ) ) game ( name "Monster Gate - Ooinaru Dungeon - Fuuin no Orb (Japan)" description "Monster Gate - Ooinaru Dungeon - Fuuin no Orb (Japan)" - rom ( name "Monster Gate - Ooinaru Dungeon - Fuuin no Orb (Japan).gba" size 8388608 crc 05AC7685 md5 2C5221FBCBD75A985D68451CF7FA6C8E sha1 A2C5E2AAC656A953A339ADC22C672BE86DF515FE ) + rom ( name "Monster Gate - Ooinaru Dungeon - Fuuin no Orb (Japan).gba" size 8388608 crc 05ac7685 sha1 A2C5E2AAC656A953A339ADC22C672BE86DF515FE ) ) game ( name "Monster Guardians (Japan)" description "Monster Guardians (Japan)" - rom ( name "Monster Guardians (Japan).gba" size 8388608 crc 93815CDE md5 A62155A1C3DD4BAD9E260A2BF527B69F sha1 350351B03349728A8FF0A5B0985AD62DF7BAACC9 ) + rom ( name "Monster Guardians (Japan).gba" size 8388608 crc 93815cde sha1 350351B03349728A8FF0A5B0985AD62DF7BAACC9 ) ) game ( name "Monster House (USA) (En,Fr)" description "Monster House (USA) (En,Fr)" - rom ( name "Monster House (USA) (En,Fr).gba" size 8388608 crc 148B5072 md5 720A562A8174C520FF1571C5E3223B39 sha1 883E66345AFA42E8736E1C29C8D493A6B99F10F3 ) + rom ( name "Monster House (USA) (En,Fr).gba" size 8388608 crc 148b5072 sha1 883E66345AFA42E8736E1C29C8D493A6B99F10F3 ) ) game ( name "Monster House (Europe) (En,Fr,De,Es)" description "Monster House (Europe) (En,Fr,De,Es)" - rom ( name "Monster House (Europe) (En,Fr,De,Es).gba" size 8388608 crc 21C84334 md5 1949B8E4A2F30F28BE71E97B4D824B22 sha1 8114523E95D01774468381900D08827C59A074D1 ) + rom ( name "Monster House (Europe) (En,Fr,De,Es).gba" size 8388608 crc 21c84334 sha1 8114523E95D01774468381900D08827C59A074D1 ) ) game ( name "Monster House (Europe)" description "Monster House (Europe)" - rom ( name "Monster House (Europe).gba" size 8388608 crc AA2C1837 md5 252037E0C434428271DC322B122612AA sha1 F4873FCBD9B141A291F6D98304CCE6D2419B0B96 flags verified ) -) - -game ( - name "Monster Jam - Maximum Destruction (Europe)" - description "Monster Jam - Maximum Destruction (Europe)" - rom ( name "Monster Jam - Maximum Destruction (Europe).gba" size 8388608 crc C3AD7701 md5 2DEC48A670F8D26B39C538FF725E2BCF sha1 0469103669DCF6271145C6AE4EE5C61A6F88D66B ) + rom ( name "Monster House (Europe).gba" size 8388608 crc aa2c1837 sha1 F4873FCBD9B141A291F6D98304CCE6D2419B0B96 flags verified ) ) game ( name "Monster Jam - Maximum Destruction (USA)" description "Monster Jam - Maximum Destruction (USA)" - rom ( name "Monster Jam - Maximum Destruction (USA).gba" size 8388608 crc 43D9B9F1 md5 8EBF0A1C78AB2A874057D32D238303FF sha1 EFCB8DA50CF62D04C1ABDEE092132E9275C12A4F ) + rom ( name "Monster Jam - Maximum Destruction (USA).gba" size 8388608 crc 43d9b9f1 sha1 EFCB8DA50CF62D04C1ABDEE092132E9275C12A4F ) +) + +game ( + name "Monster Jam - Maximum Destruction (Europe)" + description "Monster Jam - Maximum Destruction (Europe)" + rom ( name "Monster Jam - Maximum Destruction (Europe).gba" size 8388608 crc c3ad7701 sha1 0469103669DCF6271145C6AE4EE5C61A6F88D66B ) ) game ( name "Monster Maker 4 - Flash Card (Japan)" description "Monster Maker 4 - Flash Card (Japan)" - rom ( name "Monster Maker 4 - Flash Card (Japan).gba" size 8388608 crc 5E2C90AE md5 0D5F0320A5921F1FA6C74DD86234D305 sha1 D3CE5B2175125730D3F2FDD92B6F463E35220CE1 ) + rom ( name "Monster Maker 4 - Flash Card (Japan).gba" size 8388608 crc 5e2c90ae sha1 D3CE5B2175125730D3F2FDD92B6F463E35220CE1 ) ) game ( name "Monster Maker 4 - Killer Dice (Japan)" description "Monster Maker 4 - Killer Dice (Japan)" - rom ( name "Monster Maker 4 - Killer Dice (Japan).gba" size 8388608 crc F77E6ECF md5 54C109B8887BCE3EBC7FF3455646FA35 sha1 4C22E9023067C2D8246D1BC05F75D4881C411537 ) + rom ( name "Monster Maker 4 - Killer Dice (Japan).gba" size 8388608 crc f77e6ecf sha1 4C22E9023067C2D8246D1BC05F75D4881C411537 ) ) game ( name "Monster Rancher Advance (USA)" description "Monster Rancher Advance (USA)" - rom ( name "Monster Rancher Advance (USA).gba" size 8388608 crc 42CFA4B5 md5 45256CFA2C1F404CC91E6D5C34D1D4CE sha1 105463D2135FCDC1DA645A45648062C2A8CFAE7C ) + rom ( name "Monster Rancher Advance (USA).gba" size 8388608 crc 42cfa4b5 sha1 105463D2135FCDC1DA645A45648062C2A8CFAE7C ) ) game ( name "Monster Rancher Advance 2 (USA)" description "Monster Rancher Advance 2 (USA)" - rom ( name "Monster Rancher Advance 2 (USA).gba" size 8388608 crc 1D695B1B md5 C92823EC801E976852B67AC3F10723A7 sha1 2A67770024D4E292E6FA30A9C2AE40D671F2E8EA ) + rom ( name "Monster Rancher Advance 2 (USA).gba" size 8388608 crc 1d695b1b sha1 2A67770024D4E292E6FA30A9C2AE40D671F2E8EA ) ) game ( name "Monster Summoner (Japan)" description "Monster Summoner (Japan)" - rom ( name "Monster Summoner (Japan).gba" size 8388608 crc F8A085E2 md5 F39EFD645C3828875C7F5F5971A06497 sha1 2A41A90E9D317E0B02DA78E256A5F56F32426860 ) + rom ( name "Monster Summoner (Japan).gba" size 8388608 crc f8a085e2 sha1 2A41A90E9D317E0B02DA78E256A5F56F32426860 ) ) game ( name "Monster Truck Madness (USA, Europe)" description "Monster Truck Madness (USA, Europe)" - rom ( name "Monster Truck Madness (USA, Europe).gba" size 4194304 crc DD872538 md5 21F8CC99837EFBC1CB59FD75DC47BE67 sha1 5B435823A77EC1C3D6F9AEFF2286E5246967CBF1 flags verified ) + rom ( name "Monster Truck Madness (USA, Europe).gba" size 4194304 crc dd872538 sha1 5B435823A77EC1C3D6F9AEFF2286E5246967CBF1 flags verified ) ) game ( name "Monster Trucks (USA, Europe)" description "Monster Trucks (USA, Europe)" - rom ( name "Monster Trucks (USA, Europe).gba" size 4194304 crc 4A72170A md5 4F69DA882DD1B399CC9DDA3B4681FEC7 sha1 556C74E4676FF53BF3A31E0E6C3B08009BBA8581 flags verified ) + rom ( name "Monster Trucks (USA, Europe).gba" size 4194304 crc 4a72170a sha1 556C74E4676FF53BF3A31E0E6C3B08009BBA8581 flags verified ) ) game ( name "Monster Trucks Mayhem (USA)" description "Monster Trucks Mayhem (USA)" - rom ( name "Monster Trucks Mayhem (USA).gba" size 4194304 crc F47C5CF9 md5 D48340E964AA3CBE1B69019CB215C8A0 sha1 AD966ED32F69A8A714E83BC17FB20B45A9C1CF47 ) + rom ( name "Monster Trucks Mayhem (USA).gba" size 4194304 crc f47c5cf9 sha1 AD966ED32F69A8A714E83BC17FB20B45A9C1CF47 ) ) game ( name "Monster Trucks Mayhem (Europe) (En,Fr,De,Es,It)" description "Monster Trucks Mayhem (Europe) (En,Fr,De,Es,It)" - rom ( name "Monster Trucks Mayhem (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 31500381 md5 648D2CCD39BD233A841CEB966984FBAB sha1 5A72FE4B1FE63D1369DC0A74AC9CF00D293A7675 ) -) - -game ( - name "Monster! Bass Fishing (Europe)" - description "Monster! Bass Fishing (Europe)" - rom ( name "Monster! Bass Fishing (Europe).gba" size 4194304 crc 14DB186B md5 193F6184CDB4B5F6C0F9875E812E4C75 sha1 29F65A74F8E06987CE3A3C8C7A3FC6E8A45ED8C2 flags verified ) + rom ( name "Monster Trucks Mayhem (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 31500381 sha1 5A72FE4B1FE63D1369DC0A74AC9CF00D293A7675 ) ) game ( name "Monster! Bass Fishing (USA)" description "Monster! Bass Fishing (USA)" - rom ( name "Monster! Bass Fishing (USA).gba" size 4194304 crc 3EDBA390 md5 B46AB3D1332497978488243D762EF5B8 sha1 20B3BC7BA85F55F29D26C6E48B0E98777B9A95AD ) + rom ( name "Monster! Bass Fishing (USA).gba" size 4194304 crc 3edba390 sha1 20B3BC7BA85F55F29D26C6E48B0E98777B9A95AD ) +) + +game ( + name "Monster! Bass Fishing (Europe)" + description "Monster! Bass Fishing (Europe)" + rom ( name "Monster! Bass Fishing (Europe).gba" size 4194304 crc 14db186b sha1 29F65A74F8E06987CE3A3C8C7A3FC6E8A45ED8C2 flags verified ) ) game ( name "Monsters, Inc. (USA, Europe)" description "Monsters, Inc. (USA, Europe)" - rom ( name "Monsters, Inc. (USA, Europe).gba" size 4194304 crc 327834C9 md5 3E4A2E644D21654E1E5C68BAA9115DF9 sha1 21A12D54CC709EB54E6C81A3D1B9B6E7D6CF51EF flags verified ) + rom ( name "Monsters, Inc. (USA, Europe).gba" size 4194304 crc 327834c9 sha1 21A12D54CC709EB54E6C81A3D1B9B6E7D6CF51EF flags verified ) ) game ( name "Monsters, Inc. (Japan)" description "Monsters, Inc. (Japan)" - rom ( name "Monsters, Inc. (Japan).gba" size 4194304 crc 0DFFF34F md5 D94B4031B5F5B39281075AE4E0EA76D6 sha1 EBBBEEF38470F12E3735D2B6661F168B1328E10A ) + rom ( name "Monsters, Inc. (Japan).gba" size 4194304 crc 0dfff34f sha1 EBBBEEF38470F12E3735D2B6661F168B1328E10A ) ) game ( name "Monsters, Inc. (Europe) (En,Fr,It)" description "Monsters, Inc. (Europe) (En,Fr,It)" - rom ( name "Monsters, Inc. (Europe) (En,Fr,It).gba" size 4194304 crc D2C53AB8 md5 03E0114F2ED087104A007594D36F70DF sha1 7D77F57A86858E23CDF23BB383DD5F486B116A84 ) + rom ( name "Monsters, Inc. (Europe) (En,Fr,It).gba" size 4194304 crc d2c53ab8 sha1 7D77F57A86858E23CDF23BB383DD5F486B116A84 ) ) game ( name "Monsters, Inc. (Europe) (En,Es,Nl)" description "Monsters, Inc. (Europe) (En,Es,Nl)" - rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gba" size 4194304 crc D13177E0 md5 D3BC617082A50DCFA360C10F6EC5F845 sha1 36645B8DE074F0B27DBE61528E70AE3AF28FB3B9 ) + rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gba" size 4194304 crc d13177e0 sha1 36645B8DE074F0B27DBE61528E70AE3AF28FB3B9 ) ) game ( name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" description "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" - rom ( name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A16C10A8 md5 ED9B2FE7068678FEE67725EC96E98D1F sha1 B743DD4B3F1BFA169FED64F86766D5A616C5EE60 ) + rom ( name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a16c10a8 sha1 B743DD4B3F1BFA169FED64F86766D5A616C5EE60 ) ) game ( name "Morita Shougi Advance (Japan)" description "Morita Shougi Advance (Japan)" - rom ( name "Morita Shougi Advance (Japan).gba" size 4194304 crc 149E01B7 md5 D452B649E6C8F3455469030548478E81 sha1 1E0ACDD3B7B7F17FF7D68244B997EA0FF62ED0E9 ) + rom ( name "Morita Shougi Advance (Japan).gba" size 4194304 crc 149e01b7 sha1 1E0ACDD3B7B7F17FF7D68244B997EA0FF62ED0E9 ) ) game ( name "Morning Adventure, The (Spain) (Promo)" description "Morning Adventure, The (Spain) (Promo)" - rom ( name "Morning Adventure, The (Spain) (Promo).gba" size 4194304 crc B734EB4E md5 5F745975CA8B358D15D3AEEDD432DE56 sha1 2E1E22DB04DBEDFE1E98416CB9861E64E986122B ) -) - -game ( - name "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It)" - description "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It)" - rom ( name "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc FB291CCA md5 8E066C35A484308421C3EEBCC45EC329 sha1 00B63D479EFBC1EDBD2C48E2E9F93C9BC8E911BC ) + rom ( name "Morning Adventure, The (Spain) (Promo).gba" size 4194304 crc b734eb4e sha1 2E1E22DB04DBEDFE1E98416CB9861E64E986122B ) ) game ( name "Mortal Kombat - Deadly Alliance (USA) (En,Fr,De,Es,It)" description "Mortal Kombat - Deadly Alliance (USA) (En,Fr,De,Es,It)" - rom ( name "Mortal Kombat - Deadly Alliance (USA) (En,Fr,De,Es,It).gba" size 16777216 crc A29BA64F md5 78E7FF46EE220F8B6CFF4A73C0439EB4 sha1 247E0E8D10B5BE574FC800131C273FA8A52EB25F ) + rom ( name "Mortal Kombat - Deadly Alliance (USA) (En,Fr,De,Es,It).gba" size 16777216 crc a29ba64f sha1 247E0E8D10B5BE574FC800131C273FA8A52EB25F ) +) + +game ( + name "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It)" + description "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It)" + rom ( name "Mortal Kombat - Deadly Alliance (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc fb291cca sha1 00B63D479EFBC1EDBD2C48E2E9F93C9BC8E911BC flags verified ) ) game ( name "Mortal Kombat - Tournament Edition (USA) (En,Fr,De,Es,It)" description "Mortal Kombat - Tournament Edition (USA) (En,Fr,De,Es,It)" - rom ( name "Mortal Kombat - Tournament Edition (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 968BE7BC md5 4EE4B6A61D28573502010DF522A6BA91 sha1 D6AC4AC4187352BD38837989E8D0035022A17165 flags verified ) + rom ( name "Mortal Kombat - Tournament Edition (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 968be7bc sha1 D6AC4AC4187352BD38837989E8D0035022A17165 flags verified ) ) game ( name "Mortal Kombat Advance (USA)" description "Mortal Kombat Advance (USA)" - rom ( name "Mortal Kombat Advance (USA).gba" size 8388608 crc BCDABB47 md5 031C29C70DC451C121219816CFBBB527 sha1 461B6400EADE2EEEEB1FAABB3724D8B27C84361D ) + rom ( name "Mortal Kombat Advance (USA).gba" size 8388608 crc bcdabb47 sha1 461B6400EADE2EEEEB1FAABB3724D8B27C84361D ) ) game ( name "Mortal Kombat Advance (Europe)" description "Mortal Kombat Advance (Europe)" - rom ( name "Mortal Kombat Advance (Europe).gba" size 8388608 crc 78B4B5C7 md5 2B560846665F5AFD8B55405933DED4C1 sha1 C7E8E46A4A1F3D2067ECA4C850C4B1B89BEC168B ) + rom ( name "Mortal Kombat Advance (Europe).gba" size 8388608 crc 78b4b5c7 sha1 C7E8E46A4A1F3D2067ECA4C850C4B1B89BEC168B flags verified ) ) game ( name "Mother 1+2 (Japan)" description "Mother 1+2 (Japan)" - rom ( name "Mother 1+2 (Japan).gba" size 16777216 crc 0A44569C md5 F41E36204356974C94FABF7D144DD32A sha1 F27336B9C96CA2D06C34E07A61A78538DEAC32B3 ) + rom ( name "Mother 1+2 (Japan).gba" size 16777216 crc 0a44569c sha1 F27336B9C96CA2D06C34E07A61A78538DEAC32B3 flags verified ) ) game ( name "Mother 3 (Japan)" description "Mother 3 (Japan)" - rom ( name "Mother 3 (Japan).gba" size 33554432 crc 42AC9CB9 md5 AF8B0B175F7EC8914CB87B3161BA1AAA sha1 4F0F493E12C2A8C61B2D809AF03F7ABF87A85776 flags verified ) -) - -game ( - name "Moto GP (Europe) (Beta)" - description "Moto GP (Europe) (Beta)" - rom ( name "Moto GP (Europe) (Beta).gba" size 4194304 crc 508BF8DC md5 98711BC267CA910024398A1F8C078160 sha1 25554ECF8C3B534E0A70C6D4E402FA8F721DA7D8 ) -) - -game ( - name "Moto GP (Europe) (En,Fr,De,Es,It)" - description "Moto GP (Europe) (En,Fr,De,Es,It)" - rom ( name "Moto GP (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc C6D17D0D md5 FC221B4371061C27CBF6A8B08DB82543 sha1 1CE76AB502735849C8E8C1DB76422B1A62277342 flags verified ) -) - -game ( - name "Moto GP (USA) (En,Fr,De,Es,It)" - description "Moto GP (USA) (En,Fr,De,Es,It)" - rom ( name "Moto GP (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 8EE93EB8 md5 BE8E21F13E5B27D49ED097605C42F49B sha1 A543F59AEC1218E4514F7E859A587506304AB090 ) -) - -game ( - name "Moto GP (Japan) (En)" - description "Moto GP (Japan) (En)" - rom ( name "Moto GP (Japan) (En).gba" size 4194304 crc 4F6D7E49 md5 C436D71315C3CCC51C9289C74129FE2D sha1 4C6398D2BCF8B312B6E1BDAA72B31360A80C7EA1 ) + rom ( name "Mother 3 (Japan).gba" size 33554432 crc 42ac9cb9 sha1 4F0F493E12C2A8C61B2D809AF03F7ABF87A85776 flags verified ) ) game ( name "Motocross Challenge (USA) (Proto)" description "Motocross Challenge (USA) (Proto)" - rom ( name "Motocross Challenge (USA) (Proto).gba" size 4194304 crc E5A7DE43 md5 8B898CDF54095D09D9BE2CFCB43EA040 sha1 B778B784CCA09B381F2948C260355BDE0A84BC56 ) + rom ( name "Motocross Challenge (USA) (Proto).gba" size 4194304 crc e5a7de43 sha1 B778B784CCA09B381F2948C260355BDE0A84BC56 ) ) game ( name "Motocross Maniacs Advance (USA) (En,Es)" description "Motocross Maniacs Advance (USA) (En,Es)" - rom ( name "Motocross Maniacs Advance (USA) (En,Es).gba" size 4194304 crc 0A0FAEF4 md5 B0F1054D5177DD8EC5F90B63FB1C6E09 sha1 990BA3A3E1660E7DDACFE21F03014D57D1E6D6A5 ) + rom ( name "Motocross Maniacs Advance (USA) (En,Es).gba" size 4194304 crc 0a0faef4 sha1 990BA3A3E1660E7DDACFE21F03014D57D1E6D6A5 ) ) game ( name "Motocross Maniacs Advance (Japan)" description "Motocross Maniacs Advance (Japan)" - rom ( name "Motocross Maniacs Advance (Japan).gba" size 4194304 crc 043A3554 md5 36ED4C67AC05311BF3FBEDA47F3AC608 sha1 3D50E9440674C3C2A584D85CBE57E422654BF876 ) + rom ( name "Motocross Maniacs Advance (Japan).gba" size 4194304 crc 043a3554 sha1 3D50E9440674C3C2A584D85CBE57E422654BF876 ) +) + +game ( + name "MotoGP (Europe) (En,Fr,De,Es,It)" + description "MotoGP (Europe) (En,Fr,De,Es,It)" + rom ( name "MotoGP (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc c6d17d0d sha1 1CE76AB502735849C8E8C1DB76422B1A62277342 flags verified ) +) + +game ( + name "MotoGP (USA) (En,Fr,De,Es,It)" + description "MotoGP (USA) (En,Fr,De,Es,It)" + rom ( name "MotoGP (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 8ee93eb8 sha1 A543F59AEC1218E4514F7E859A587506304AB090 ) +) + +game ( + name "MotoGP (Japan) (En)" + description "MotoGP (Japan) (En)" + rom ( name "MotoGP (Japan) (En).gba" size 4194304 crc 4f6d7e49 sha1 4C6398D2BCF8B312B6E1BDAA72B31360A80C7EA1 flags verified ) +) + +game ( + name "MotoGP (Europe) (Beta)" + description "MotoGP (Europe) (Beta)" + rom ( name "MotoGP (Europe) (Beta).gba" size 4194304 crc 508bf8dc sha1 25554ECF8C3B534E0A70C6D4E402FA8F721DA7D8 ) ) game ( name "Motoracer Advance (Europe) (En,Fr,De,Es,It)" description "Motoracer Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Motoracer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8CB19DA0 md5 D3B2AB65C92E18DF21788C4B30128041 sha1 B91BAD8EE04652D71E0610F8D1A5DEAEBD4C1FD0 flags verified ) + rom ( name "Motoracer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8cb19da0 sha1 B91BAD8EE04652D71E0610F8D1A5DEAEBD4C1FD0 flags verified ) ) game ( name "Motoracer Advance (USA) (En,Fr,De,Es,It)" description "Motoracer Advance (USA) (En,Fr,De,Es,It)" - rom ( name "Motoracer Advance (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2FDBE7A8 md5 77FDFC944C31CCB0270C73E801CC20B0 sha1 351414650E6969C270B1339ADA7B3565CE80374C ) + rom ( name "Motoracer Advance (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 2fdbe7a8 sha1 351414650E6969C270B1339ADA7B3565CE80374C ) ) game ( name "Mr Nutz (Europe) (En,Fr,De,Es,It)" description "Mr Nutz (Europe) (En,Fr,De,Es,It)" - rom ( name "Mr Nutz (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7F21D693 md5 C0E95CA2DF9D1A27C91CA6956095891C sha1 BF613F71831DEEC324128498D80B0505E3CEBDB0 ) -) - -game ( - name "Mr. Driller 2 (Europe)" - description "Mr. Driller 2 (Europe)" - rom ( name "Mr. Driller 2 (Europe).gba" size 4194304 crc C0E9EEBE md5 65A9D554B74E8FBF06F3807E9D103BB8 sha1 80151D4D4421736C0C3853F88CBB3C72D3F55A1B ) -) - -game ( - name "Mr. Driller 2 (USA)" - description "Mr. Driller 2 (USA)" - rom ( name "Mr. Driller 2 (USA).gba" size 4194304 crc 02F51696 md5 D7118BE078B9A61284A99D3F1F7E972F sha1 E7009DD8418303343C4AAC2558538B8CAA28B694 ) + rom ( name "Mr Nutz (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 7f21d693 sha1 BF613F71831DEEC324128498D80B0505E3CEBDB0 ) ) game ( name "Mr. Driller 2 (Japan)" description "Mr. Driller 2 (Japan)" - rom ( name "Mr. Driller 2 (Japan).gba" size 4194304 crc 5264C730 md5 7612EE1DA917451F53E634C09A7FE838 sha1 0373318EF431B1D02708941AF261C91DE1677D9D ) + rom ( name "Mr. Driller 2 (Japan).gba" size 4194304 crc 5264c730 sha1 0373318EF431B1D02708941AF261C91DE1677D9D ) +) + +game ( + name "Mr. Driller 2 (Europe)" + description "Mr. Driller 2 (Europe)" + rom ( name "Mr. Driller 2 (Europe).gba" size 4194304 crc c0e9eebe sha1 80151D4D4421736C0C3853F88CBB3C72D3F55A1B ) +) + +game ( + name "Mr. Driller 2 (USA)" + description "Mr. Driller 2 (USA)" + rom ( name "Mr. Driller 2 (USA).gba" size 4194304 crc 02f51696 sha1 E7009DD8418303343C4AAC2558538B8CAA28B694 ) ) game ( name "Mr. Driller A - Fushigi na Pacteria (Japan)" description "Mr. Driller A - Fushigi na Pacteria (Japan)" - rom ( name "Mr. Driller A - Fushigi na Pacteria (Japan).gba" size 8388608 crc 529F06A4 md5 D7F4CB6AEA9409ACF23E2EAE5A697C5E sha1 CCFB5F3051B4D3BDEC38F0085F2A585ECF249F20 flags verified ) + rom ( name "Mr. Driller A - Fushigi na Pacteria (Japan).gba" size 8388608 crc 529f06a4 sha1 CCFB5F3051B4D3BDEC38F0085F2A585ECF249F20 flags verified ) ) game ( name "Mr. Incredible (Japan)" description "Mr. Incredible (Japan)" - rom ( name "Mr. Incredible (Japan).gba" size 8388608 crc 73FA8B2A md5 E5A317D1C71261BAAC40BBFB29453082 sha1 6289A54C3968BF7E1AE715BC7624803D2BA9F5FE ) + rom ( name "Mr. Incredible (Japan).gba" size 8388608 crc 73fa8b2a sha1 6289A54C3968BF7E1AE715BC7624803D2BA9F5FE flags verified ) ) game ( name "Mr. Incredible - Kyouteki Underminer Toujou (Japan)" description "Mr. Incredible - Kyouteki Underminer Toujou (Japan)" - rom ( name "Mr. Incredible - Kyouteki Underminer Toujou (Japan).gba" size 8388608 crc 667F54CA md5 19129E5F655BE691894551B379AC6154 sha1 36BA21C831734583DD864AA8BFA8AC115F7BB688 ) + rom ( name "Mr. Incredible - Kyouteki Underminer Toujou (Japan).gba" size 8388608 crc 667f54ca sha1 36BA21C831734583DD864AA8BFA8AC115F7BB688 ) ) game ( name "Ms. Pac-Man - Maze Madness (USA)" description "Ms. Pac-Man - Maze Madness (USA)" - rom ( name "Ms. Pac-Man - Maze Madness (USA).gba" size 4194304 crc DDE5DF02 md5 279AF1B9D55EFDCEA19593A42F8CE23D sha1 1C28602604E760FFFC09CB84DB6377A9B148D103 ) + rom ( name "Ms. Pac-Man - Maze Madness (USA).gba" size 4194304 crc dde5df02 sha1 1C28602604E760FFFC09CB84DB6377A9B148D103 ) ) game ( name "Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It)" description "Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It)" - rom ( name "Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6E03FD6A md5 2330D9D78363285A7A59A844CFE4E506 sha1 042EBFA7A5CE645C22099A276C8C6E0D2F6A1A77 ) + rom ( name "Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6e03fd6a sha1 042EBFA7A5CE645C22099A276C8C6E0D2F6A1A77 ) ) game ( name "Mucha Lucha! - Mascaritas of the Lost Code (USA) (En,Fr,Es)" description "Mucha Lucha! - Mascaritas of the Lost Code (USA) (En,Fr,Es)" - rom ( name "Mucha Lucha! - Mascaritas of the Lost Code (USA) (En,Fr,Es).gba" size 4194304 crc 03BBC0C9 md5 0B4C94EDC68FF0F0A18E09E5B11ED0DF sha1 C168D27F627B3B986CB3BA2637AC72E09BC7417E ) + rom ( name "Mucha Lucha! - Mascaritas of the Lost Code (USA) (En,Fr,Es).gba" size 4194304 crc 03bbc0c9 sha1 C168D27F627B3B986CB3BA2637AC72E09BC7417E ) ) game ( name "Mugenborg (Japan)" description "Mugenborg (Japan)" - rom ( name "Mugenborg (Japan).gba" size 8388608 crc 1C31BBEC md5 D28DCCCC93405CE5C1F29814DBD3F77F sha1 CFB8AC541D1AE3B6AF69568331572695C8BEC572 ) + rom ( name "Mugenborg (Japan).gba" size 8388608 crc 1c31bbec sha1 CFB8AC541D1AE3B6AF69568331572695C8BEC572 ) ) game ( name "Mummy, The (Europe) (En,Fr,De,Es,It)" description "Mummy, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Mummy, The (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B0F3799F md5 098AE1D09C30569E6059952E577DFBF8 sha1 3C7030896C966208F8E6F4D2809EFE1EE9C9204D ) + rom ( name "Mummy, The (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b0f3799f sha1 3C7030896C966208F8E6F4D2809EFE1EE9C9204D ) ) game ( name "Mummy, The (USA) (En,Fr,De,Es,It)" description "Mummy, The (USA) (En,Fr,De,Es,It)" - rom ( name "Mummy, The (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 55BF350B md5 9106C7ADBA0AB281A29F5AF7CAA9CDAD sha1 CC833B1398A6EA87D31712806757C2FE52FADD31 ) + rom ( name "Mummy, The (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 55bf350b sha1 CC833B1398A6EA87D31712806757C2FE52FADD31 ) ) game ( name "Muppet Pinball Mayhem (USA)" description "Muppet Pinball Mayhem (USA)" - rom ( name "Muppet Pinball Mayhem (USA).gba" size 4194304 crc 58575F65 md5 8FEEE07008288E4DF451D639168BF1D0 sha1 CBF381536AB8D8EA02814A77F46DB13CB625C72F ) + rom ( name "Muppet Pinball Mayhem (USA).gba" size 4194304 crc 58575f65 sha1 CBF381536AB8D8EA02814A77F46DB13CB625C72F ) ) game ( name "Muppet Pinball Mayhem (Europe)" description "Muppet Pinball Mayhem (Europe)" - rom ( name "Muppet Pinball Mayhem (Europe).gba" size 4194304 crc 8D5034D7 md5 3EAC9CD691229B16662A9E124C8FBF66 sha1 1C45790873605DEFC999B45EE145013E7E406A5D flags verified ) + rom ( name "Muppet Pinball Mayhem (Europe).gba" size 4194304 crc 8d5034d7 sha1 1C45790873605DEFC999B45EE145013E7E406A5D flags verified ) ) game ( name "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 17CD149A md5 8CC1DD1718B63C9675A5E5D28C14936B sha1 74B8F11A719D2EBDD36A594814AD01A9B79A115E flags verified ) + rom ( name "Muppets, The - On with the Show! (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 17cd149a sha1 74B8F11A719D2EBDD36A594814AD01A9B79A115E flags verified ) ) game ( name "Mutsu - Water Looper Mutsu (Japan)" description "Mutsu - Water Looper Mutsu (Japan)" - rom ( name "Mutsu - Water Looper Mutsu (Japan).gba" size 4194304 crc 3A45A6D9 md5 0A4B60E0F15350B991624763526A85D1 sha1 9B8E60D5BAB2E4013AFA49DA4F551AA85B0B2858 ) + rom ( name "Mutsu - Water Looper Mutsu (Japan).gba" size 4194304 crc 3a45a6d9 sha1 9B8E60D5BAB2E4013AFA49DA4F551AA85B0B2858 ) ) game ( name "MX 2002 featuring Ricky Carmichael (USA, Europe)" description "MX 2002 featuring Ricky Carmichael (USA, Europe)" - rom ( name "MX 2002 featuring Ricky Carmichael (USA, Europe).gba" size 4194304 crc 0BF1DC56 md5 0007D212D9B76A466C7CA003D50C8C74 sha1 87914981EE89219A0FA28833FB9D9F6E9B606D57 flags verified ) + rom ( name "MX 2002 featuring Ricky Carmichael (USA, Europe).gba" size 4194304 crc 0bf1dc56 sha1 87914981EE89219A0FA28833FB9D9F6E9B606D57 flags verified ) ) game ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It)" description "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It)" - rom ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 16C0E028 md5 27E653640BE9023AAE41EC53304FA4DE sha1 E85CEA8428D51E40CF1B7A90643E94604973679F ) + rom ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 16c0e028 sha1 E85CEA8428D51E40CF1B7A90643E94604973679F ) ) game ( name "My Little Pony - Crystal Princess - The Runaway Rainbow (USA)" description "My Little Pony - Crystal Princess - The Runaway Rainbow (USA)" - rom ( name "My Little Pony - Crystal Princess - The Runaway Rainbow (USA).gba" size 4194304 crc 90DBD5EB md5 DDD0670792619198933DCEF3571428B3 sha1 41C2A6940ED285C5F5C1604E01B2162FD2A8AF60 ) + rom ( name "My Little Pony - Crystal Princess - The Runaway Rainbow (USA).gba" size 4194304 crc 90dbd5eb sha1 41C2A6940ED285C5F5C1604E01B2162FD2A8AF60 ) ) game ( name "Nakayoshi Mahjong - KabuReach (Japan)" description "Nakayoshi Mahjong - KabuReach (Japan)" - rom ( name "Nakayoshi Mahjong - KabuReach (Japan).gba" size 4194304 crc D0C608F6 md5 F3E58D5622AF0D38C7DAD8FFD33635E3 sha1 CE4B239F3AC8FEDF26755213E1BFC67629CF6098 ) + rom ( name "Nakayoshi Mahjong - KabuReach (Japan).gba" size 4194304 crc d0c608f6 sha1 CE4B239F3AC8FEDF26755213E1BFC67629CF6098 ) ) game ( name "Nakayoshi Pet Advance Series 1 - Kawaii Hamster (Japan)" description "Nakayoshi Pet Advance Series 1 - Kawaii Hamster (Japan)" - rom ( name "Nakayoshi Pet Advance Series 1 - Kawaii Hamster (Japan).gba" size 4194304 crc 74930B16 md5 00BCC2D5347CF3012DD273B43AC39A6F sha1 1FB49BB2293DBBD061A5D72D65D413B22360CCED ) + rom ( name "Nakayoshi Pet Advance Series 1 - Kawaii Hamster (Japan).gba" size 4194304 crc 74930b16 sha1 1FB49BB2293DBBD061A5D72D65D413B22360CCED flags verified ) ) game ( name "Nakayoshi Pet Advance Series 2 - Kawaii Koinu (Japan)" description "Nakayoshi Pet Advance Series 2 - Kawaii Koinu (Japan)" - rom ( name "Nakayoshi Pet Advance Series 2 - Kawaii Koinu (Japan).gba" size 4194304 crc 954DA3E6 md5 13282333FF803C7C525E5512019FBB51 sha1 AEF6AAA2D351BAD2C260B85C308D584B91039A99 ) + rom ( name "Nakayoshi Pet Advance Series 2 - Kawaii Koinu (Japan).gba" size 4194304 crc 954da3e6 sha1 AEF6AAA2D351BAD2C260B85C308D584B91039A99 ) ) game ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan)" description "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan)" - rom ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan).gba" size 4194304 crc 0290DFB5 md5 AB6251B0F54CF6787FD4A6B5D5D4C5B6 sha1 B713F9658F8F5C24C1BC1C840BD74AE4B3EDD2D3 ) + rom ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan).gba" size 4194304 crc 0290dfb5 sha1 B713F9658F8F5C24C1BC1C840BD74AE4B3EDD2D3 ) ) game ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan) (Rev 1)" description "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan) (Rev 1)" - rom ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan) (Rev 1).gba" size 4194304 crc 89FBEB55 md5 A458D8CF99EE5DBF244B0900E7DF0588 sha1 F0AC77BEC4F385FEEA5305BB1C67EFEFFCFC6AC2 ) + rom ( name "Nakayoshi Pet Advance Series 3 - Kawaii Koneko (Japan) (Rev 1).gba" size 4194304 crc 89fbeb55 sha1 F0AC77BEC4F385FEEA5305BB1C67EFEFFCFC6AC2 ) ) game ( name "Nakayoshi Pet Advance Series 4 - Kawaii Koinu Mini - Wankoto Asobou!! Kogata-ken (Japan)" description "Nakayoshi Pet Advance Series 4 - Kawaii Koinu Mini - Wankoto Asobou!! Kogata-ken (Japan)" - rom ( name "Nakayoshi Pet Advance Series 4 - Kawaii Koinu Mini - Wankoto Asobou!! Kogata-ken (Japan).gba" size 4194304 crc AE2A69F3 md5 138F9DF1C5D9C7CB0B28760F92A4698E sha1 0C78A24D5A8A296D05A8B47CF5623DE0F031748E ) + rom ( name "Nakayoshi Pet Advance Series 4 - Kawaii Koinu Mini - Wankoto Asobou!! Kogata-ken (Japan).gba" size 4194304 crc ae2a69f3 sha1 0C78A24D5A8A296D05A8B47CF5623DE0F031748E flags verified ) ) game ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan)" description "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan)" - rom ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan).gba" size 4194304 crc 1276A95C md5 D6D1AEBC7605124B44F024F54D3BE293 sha1 77743DE7541E0A9D09E3AAC864C4E3F9F1A51D2B ) + rom ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan).gba" size 4194304 crc 1276a95c sha1 77743DE7541E0A9D09E3AAC864C4E3F9F1A51D2B ) ) game ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan) (Rev 1)" description "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan) (Rev 1)" - serial "AHVJ" - rom ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan) (Rev 1).gba" size 4194304 crc B46DACA0 md5 EE7A6AC20BB48E1DA9B39850BA181397 sha1 5E0CDBD4B6ABA17E26C262D8DB7C64FC3441D263 ) -) - -game ( - name "Namco Museum (Europe)" - description "Namco Museum (Europe)" - rom ( name "Namco Museum (Europe).gba" size 4194304 crc BB82460A md5 0E7E7ED17B4E8E4D09E166D3BD923B40 sha1 3E84508A0D2362A0ABF31DEDE1D55B865566213C flags verified ) + rom ( name "Nakayoshi Youchien - Sukoyaka Enji Ikusei Game (Japan) (Rev 1).gba" size 4194304 crc b46daca0 sha1 5E0CDBD4B6ABA17E26C262D8DB7C64FC3441D263 flags verified ) ) game ( name "Namco Museum (USA)" description "Namco Museum (USA)" - rom ( name "Namco Museum (USA).gba" size 4194304 crc C58A04C1 md5 60AC7A006E8A00581B832CEB8A000305 sha1 01090D75A45EB4AB326C6299646E946AFC7D0BE9 ) + rom ( name "Namco Museum (USA).gba" size 4194304 crc c58a04c1 sha1 01090D75A45EB4AB326C6299646E946AFC7D0BE9 flags verified ) ) game ( name "Namco Museum (Japan) (En)" description "Namco Museum (Japan) (En)" - rom ( name "Namco Museum (Japan) (En).gba" size 4194304 crc 818F4E4B md5 E124A5CC941C7ABA6A626F687C50FBF6 sha1 54D01CF5AC57F5FB454C0E188DE9E60F63854A97 ) + rom ( name "Namco Museum (Japan) (En).gba" size 4194304 crc 818f4e4b sha1 54D01CF5AC57F5FB454C0E188DE9E60F63854A97 ) +) + +game ( + name "Namco Museum (Europe)" + description "Namco Museum (Europe)" + rom ( name "Namco Museum (Europe).gba" size 4194304 crc bb82460a sha1 3E84508A0D2362A0ABF31DEDE1D55B865566213C flags verified ) ) game ( name "Namco Museum - 50th Anniversary (USA)" description "Namco Museum - 50th Anniversary (USA)" - rom ( name "Namco Museum - 50th Anniversary (USA).gba" size 4194304 crc 38DA81FE md5 65389F698FD274E4B9A6B799FB6FBD2B sha1 700E560AA284CF668FD84BF222E215058002910A ) + rom ( name "Namco Museum - 50th Anniversary (USA).gba" size 4194304 crc 38da81fe sha1 700E560AA284CF668FD84BF222E215058002910A ) ) game ( name "Namco Museum - 50th Anniversary (Europe) (En,Fr,De,Es,It)" description "Namco Museum - 50th Anniversary (Europe) (En,Fr,De,Es,It)" - rom ( name "Namco Museum - 50th Anniversary (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2F098A42 md5 26C807FA46179E4820318EF8D7B460DC sha1 BFD8E5C006930652A21A83C547C00DC34DC28592 ) + rom ( name "Namco Museum - 50th Anniversary (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 2f098a42 sha1 BFD8E5C006930652A21A83C547C00DC34DC28592 ) ) game ( name "Nancy Drew - Message in a Haunted Mansion (USA)" description "Nancy Drew - Message in a Haunted Mansion (USA)" - rom ( name "Nancy Drew - Message in a Haunted Mansion (USA).gba" size 4194304 crc 7652CD25 md5 F977A030AA9F5FA4C6013AE472F68B91 sha1 8D2FBFA11F43A9D4D4BEF9D68003EC689A62AFAA ) + rom ( name "Nancy Drew - Message in a Haunted Mansion (USA).gba" size 4194304 crc 7652cd25 sha1 8D2FBFA11F43A9D4D4BEF9D68003EC689A62AFAA ) ) game ( name "Napoleon (Japan)" description "Napoleon (Japan)" - rom ( name "Napoleon (Japan).gba" size 8388608 crc FA016764 md5 4E9D8454DE262002A97DBEDBDA524731 sha1 06CF9DF7445B7AA662050AD41DD946A09DBC0581 flags verified ) + rom ( name "Napoleon (Japan).gba" size 8388608 crc fa016764 sha1 06CF9DF7445B7AA662050AD41DD946A09DBC0581 flags verified ) ) game ( name "Narikiri Jockey Game - Yuushun Rhapsody (Japan)" description "Narikiri Jockey Game - Yuushun Rhapsody (Japan)" - rom ( name "Narikiri Jockey Game - Yuushun Rhapsody (Japan).gba" size 8388608 crc 0FF11189 md5 FB95BB41631CE0AB21B44575FF6C55B6 sha1 E09F676B439FC65A63BABEBC31CA371F8367F3C5 ) + rom ( name "Narikiri Jockey Game - Yuushun Rhapsody (Japan).gba" size 8388608 crc 0ff11189 sha1 E09F676B439FC65A63BABEBC31CA371F8367F3C5 ) ) game ( name "Naruto - Konoha Senki (Japan)" description "Naruto - Konoha Senki (Japan)" - rom ( name "Naruto - Konoha Senki (Japan).gba" size 8388608 crc 11829AFA md5 96E56B4CF97BE08B81750164890DF648 sha1 C8E5498F55829D342B510E0C57639984E1AC03EF ) + rom ( name "Naruto - Konoha Senki (Japan).gba" size 8388608 crc 11829afa sha1 C8E5498F55829D342B510E0C57639984E1AC03EF ) +) + +game ( + name "Naruto - Konoha Senki (Japan) (Rev 1)" + description "Naruto - Konoha Senki (Japan) (Rev 1)" + rom ( name "Naruto - Konoha Senki (Japan) (Rev 1).gba" size 8388608 crc 69cf0418 sha1 01DEFFEDD9E78544465031333BAA0EB16C1BC5BD flags verified ) ) game ( name "Naruto - Ninja Council (USA)" description "Naruto - Ninja Council (USA)" - rom ( name "Naruto - Ninja Council (USA).gba" size 8388608 crc C402878C md5 DFFC7306234751E18B163FBF3E925F1B sha1 1E4C622668C4CC0C9E86816507ADA8C17491C257 ) + rom ( name "Naruto - Ninja Council (USA).gba" size 8388608 crc c402878c sha1 1E4C622668C4CC0C9E86816507ADA8C17491C257 ) ) game ( name "Naruto - Ninja Council 2 (USA)" description "Naruto - Ninja Council 2 (USA)" - rom ( name "Naruto - Ninja Council 2 (USA).gba" size 8388608 crc 94699FCA md5 60ECA5E9057972A76361158CC7AB31B8 sha1 D6E985B7FCE0219093B644232FD4BE5ECD3DE746 ) -) - -game ( - name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1)" - description "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1)" - rom ( name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1).gba" size 8388608 crc F5F8ECB4 md5 4E6E4E85EDE139A629320DCF0613F4A6 sha1 7FCA2CFF63CF5AA2F2AD301CA254F979F723B072 ) + rom ( name "Naruto - Ninja Council 2 (USA).gba" size 8388608 crc 94699fca sha1 D6E985B7FCE0219093B644232FD4BE5ECD3DE746 ) ) game ( name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan)" description "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan)" - rom ( name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan).gba" size 8388608 crc E15875FC md5 4BF83DA83D572A0B60613767BB23E0AC sha1 BDBA5846C7615423ACD416E9EEAAB31BBFCE57DB flags verified ) + rom ( name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan).gba" size 8388608 crc e15875fc sha1 BDBA5846C7615423ACD416E9EEAAB31BBFCE57DB flags verified ) +) + +game ( + name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1)" + description "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1)" + rom ( name "Naruto - Ninjutsu Zenkai! Saikyou Ninja Daikesshuu (Japan) (Rev 1).gba" size 8388608 crc f5f8ecb4 sha1 7FCA2CFF63CF5AA2F2AD301CA254F979F723B072 flags verified ) ) game ( name "Naruto - Saikyou Ninja Daikesshuu 2 (Japan)" description "Naruto - Saikyou Ninja Daikesshuu 2 (Japan)" - rom ( name "Naruto - Saikyou Ninja Daikesshuu 2 (Japan).gba" size 8388608 crc B3D75CE1 md5 860ED03009D656568EA20D98436574C8 sha1 6176C4D3FF95B56915B4D38EFA1115C1D5520F7C ) + rom ( name "Naruto - Saikyou Ninja Daikesshuu 2 (Japan).gba" size 8388608 crc b3d75ce1 sha1 6176C4D3FF95B56915B4D38EFA1115C1D5520F7C flags verified ) ) game ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan)" description "Naruto RPG - Uketsugareshi Hi no Ishi (Japan)" - rom ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan).gba" size 8388608 crc C036D0F0 md5 EDEBADBEE7E89AEDE8BDF6D245580085 sha1 17B43AB5EB95F0169827FFD739899F8A1827E798 ) + rom ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan).gba" size 8388608 crc c036d0f0 sha1 17B43AB5EB95F0169827FFD739899F8A1827E798 ) ) game ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan) (Rev 1)" description "Naruto RPG - Uketsugareshi Hi no Ishi (Japan) (Rev 1)" - serial "BNRJ" - rom ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan) (Rev 1).gba" size 8388608 crc 2BF6555A md5 064B4A2A29134A638F4D38F3C3FD4B98 sha1 DF43AB9AC90A8A6500AC85DAEE1A15EB0F00AFDF ) + rom ( name "Naruto RPG - Uketsugareshi Hi no Ishi (Japan) (Rev 1).gba" size 8388608 crc 2bf6555a sha1 DF43AB9AC90A8A6500AC85DAEE1A15EB0F00AFDF flags verified ) ) game ( name "NASCAR Heat 2002 (USA)" description "NASCAR Heat 2002 (USA)" - rom ( name "NASCAR Heat 2002 (USA).gba" size 4194304 crc 87E15F5B md5 2FB73B874BBF4119E5CBF17B8CEAE9C1 sha1 0EB1FA43D8B0F8A6FB1E3AC04F7BBA92C7CBAC96 ) + rom ( name "NASCAR Heat 2002 (USA).gba" size 4194304 crc 87e15f5b sha1 0EB1FA43D8B0F8A6FB1E3AC04F7BBA92C7CBAC96 ) ) game ( name "Natural 2 - Duo (Japan)" description "Natural 2 - Duo (Japan)" - rom ( name "Natural 2 - Duo (Japan).gba" size 8388608 crc 0DE8B4B4 md5 22B1EC2EA8E0DA29EF2810AA4AB7B5F5 sha1 1D313B70FFA560B1A19A70455E030C04F6C38481 ) + rom ( name "Natural 2 - Duo (Japan).gba" size 8388608 crc 0de8b4b4 sha1 1D313B70FFA560B1A19A70455E030C04F6C38481 ) ) game ( name "NBA Jam 2002 (USA, Europe)" description "NBA Jam 2002 (USA, Europe)" - rom ( name "NBA Jam 2002 (USA, Europe).gba" size 4194304 crc CA428A7A md5 17ECE80A2D8609E513776E67EF0ECB15 sha1 38DE98758669B120B895661BEC3882C3474CF47E ) + rom ( name "NBA Jam 2002 (USA, Europe).gba" size 4194304 crc ca428a7a sha1 38DE98758669B120B895661BEC3882C3474CF47E ) ) game ( name "Need for Speed - Most Wanted (USA, Europe) (En,Fr,De,It)" description "Need for Speed - Most Wanted (USA, Europe) (En,Fr,De,It)" - rom ( name "Need for Speed - Most Wanted (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc EA15A16E md5 0CD601F13BE95043EB1BC10E3675F25A sha1 0987705399DCF0D8B5B2F40B46919AD3D198027B flags verified ) + rom ( name "Need for Speed - Most Wanted (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc ea15a16e sha1 0987705399DCF0D8B5B2F40B46919AD3D198027B flags verified ) ) game ( name "Need for Speed - Porsche Unleashed (Europe) (En,Fr,De,Es,It)" description "Need for Speed - Porsche Unleashed (Europe) (En,Fr,De,Es,It)" - rom ( name "Need for Speed - Porsche Unleashed (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 1B6B8F88 md5 C6A927C20FBB7B5B1570F9E6C804B54B sha1 01191BF203A21CC7E91EBC8FFA4C167625EDE952 flags verified ) + rom ( name "Need for Speed - Porsche Unleashed (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 1b6b8f88 sha1 01191BF203A21CC7E91EBC8FFA4C167625EDE952 flags verified ) ) game ( name "Need for Speed - Porsche Unleashed (USA)" description "Need for Speed - Porsche Unleashed (USA)" - rom ( name "Need for Speed - Porsche Unleashed (USA).gba" size 4194304 crc 99078AF4 md5 7406C224589F1A2F57FEFF5EB3C177C3 sha1 C57A0652017C47AC2D25A51BF351738CD634272B ) + rom ( name "Need for Speed - Porsche Unleashed (USA).gba" size 4194304 crc 99078af4 sha1 C57A0652017C47AC2D25A51BF351738CD634272B ) ) game ( name "Need for Speed - Underground (USA, Europe) (En,Fr,De,It)" description "Need for Speed - Underground (USA, Europe) (En,Fr,De,It)" - rom ( name "Need for Speed - Underground (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 828020E9 md5 0053467F8F43C893299C1C18A2E971D9 sha1 DDD304481617A748AA9F37535908A37452DD2F03 flags verified ) + rom ( name "Need for Speed - Underground (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 828020e9 sha1 DDD304481617A748AA9F37535908A37452DD2F03 flags verified ) ) game ( name "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It)" description "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It)" - rom ( name "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 9A0C5090 md5 B5509A24ACD58DDCB3D2E251A074F494 sha1 F772000FBDFB84D8D5DE9F69BD9C0DE551389929 ) + rom ( name "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 9a0c5090 sha1 F772000FBDFB84D8D5DE9F69BD9C0DE551389929 flags verified ) ) game ( name "Need for Speed Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It)" description "Need for Speed Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Need for Speed Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc F4C0D140 md5 F6670D280E7B6DC85E6C20B89EF51691 sha1 E5298B2482A769AA6458955CD6B18DB3AC3F3A20 flags verified ) -) - -game ( - name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" - description "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" - serial "ARNJ" - rom ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1).gba" size 8388608 crc E4FE52DB md5 80AFDBF1FB3A1287B7745F1A7AA473B9 sha1 B231938A269F7D9A058560BC685D13B010D81812 ) + rom ( name "Need for Speed Carbon - Own the City (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f4c0d140 sha1 E5298B2482A769AA6458955CD6B18DB3AC3F3A20 flags verified ) ) game ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan)" description "Neoromance Game - Harukanaru Toki no Naka de (Japan)" - rom ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan).gba" size 8388608 crc BF12B590 md5 2363306CB2927EE859A39BA2744D7F42 sha1 BD87E466168127D11231C75C47DFE09D42C03198 ) + rom ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan).gba" size 8388608 crc bf12b590 sha1 BD87E466168127D11231C75C47DFE09D42C03198 ) +) + +game ( + name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" + description "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" + rom ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1).gba" size 8388608 crc e4fe52db sha1 B231938A269F7D9A058560BC685D13B010D81812 flags verified ) +) + +game ( + name "NES Classics - Castlevania (Europe)" + description "NES Classics - Castlevania (Europe)" + rom ( name "NES Classics - Castlevania (Europe).gba" size 4194304 crc 2b510046 sha1 A01B809FD050749ADBAD188C58FD55E0949C1EDB flags verified ) ) game ( name "Next Generation Tennis (Europe) (En,Fr,De,Es,It,Pt)" description "Next Generation Tennis (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Next Generation Tennis (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 5297693A md5 76FF10072FBE28737918120C9021C741 sha1 2102374344073807AB26F3804D77CC4FE29B3590 flags verified ) + rom ( name "Next Generation Tennis (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 5297693a sha1 2102374344073807AB26F3804D77CC4FE29B3590 flags verified ) ) game ( name "NFL Blitz 20-02 (USA)" description "NFL Blitz 20-02 (USA)" - rom ( name "NFL Blitz 20-02 (USA).gba" size 4194304 crc 8C748DCB md5 7C9E0824A12CB0263330C43381791D64 sha1 590196C49EB4B33D933DB60D58A1D0EFD94B3F7B ) + rom ( name "NFL Blitz 20-02 (USA).gba" size 4194304 crc 8c748dcb sha1 590196C49EB4B33D933DB60D58A1D0EFD94B3F7B ) ) game ( name "NFL Blitz 20-03 (USA)" description "NFL Blitz 20-03 (USA)" - rom ( name "NFL Blitz 20-03 (USA).gba" size 4194304 crc E0B137E7 md5 CFA185AA9C5C11136E16CE519F96E3E9 sha1 6D63871ABF8016248FF7F8777D762E7C75877D40 ) + rom ( name "NFL Blitz 20-03 (USA).gba" size 4194304 crc e0b137e7 sha1 6D63871ABF8016248FF7F8777D762E7C75877D40 ) ) game ( name "NHL 2002 (USA)" description "NHL 2002 (USA)" - rom ( name "NHL 2002 (USA).gba" size 4194304 crc D1D9E515 md5 DDAC943BEBCF4160FA6AFE082E16513C sha1 47F54DA7424514CF83C794C49811EEFBB35DA72D ) + rom ( name "NHL 2002 (USA).gba" size 4194304 crc d1d9e515 sha1 47F54DA7424514CF83C794C49811EEFBB35DA72D ) ) game ( name "NHL Hitz 20-03 (USA)" description "NHL Hitz 20-03 (USA)" - rom ( name "NHL Hitz 20-03 (USA).gba" size 4194304 crc 4F1ADF75 md5 E6B4BD3C5F5B3D57C2E29C4A9B377B26 sha1 4A88CA2962FDFB7EA1B91B9E2BFFE8C69FF96519 ) + rom ( name "NHL Hitz 20-03 (USA).gba" size 4194304 crc 4f1adf75 sha1 4A88CA2962FDFB7EA1B91B9E2BFFE8C69FF96519 ) ) game ( name "Nicktoons - Attack of the Toybots (USA)" description "Nicktoons - Attack of the Toybots (USA)" - rom ( name "Nicktoons - Attack of the Toybots (USA).gba" size 4194304 crc DDA9A035 md5 ACE5DFF7D63FB765515B43E6950A455C sha1 1C33F64C2791B7766B23FAE1272036B008BDDC1A ) + rom ( name "Nicktoons - Attack of the Toybots (USA).gba" size 4194304 crc dda9a035 sha1 1C33F64C2791B7766B23FAE1272036B008BDDC1A ) ) game ( name "Nicktoons - Battle for Volcano Island (USA)" description "Nicktoons - Battle for Volcano Island (USA)" - rom ( name "Nicktoons - Battle for Volcano Island (USA).gba" size 4194304 crc FEAFBD72 md5 07F3B7415EB3779FF11E51A38D0AD3F8 sha1 AEA4C43253D2A3D03C9D17224EBE2BE49CBC95E0 ) + rom ( name "Nicktoons - Battle for Volcano Island (USA).gba" size 4194304 crc feafbd72 sha1 AEA4C43253D2A3D03C9D17224EBE2BE49CBC95E0 ) ) game ( name "Nicktoons - Freeze Frame Frenzy (USA)" description "Nicktoons - Freeze Frame Frenzy (USA)" - rom ( name "Nicktoons - Freeze Frame Frenzy (USA).gba" size 4194304 crc A8B6766E md5 7A710C9D170D28397CF36002CCE4734D sha1 A200CDAF66606BD724CE7073FD7990EA3FE6BCDD ) + rom ( name "Nicktoons - Freeze Frame Frenzy (USA).gba" size 4194304 crc a8b6766e sha1 A200CDAF66606BD724CE7073FD7990EA3FE6BCDD ) ) game ( name "Nicktoons Racing (USA)" description "Nicktoons Racing (USA)" - rom ( name "Nicktoons Racing (USA).gba" size 4194304 crc 50AB9BB6 md5 CC25621658169B41ADA436EF99C078E8 sha1 AD53FDC15C3E68A4ADA8F4D902BFD579C6313025 ) + rom ( name "Nicktoons Racing (USA).gba" size 4194304 crc 50ab9bb6 sha1 AD53FDC15C3E68A4ADA8F4D902BFD579C6313025 ) ) game ( name "Nicktoons Racing (Europe) (En,Fr,De,Es,It)" description "Nicktoons Racing (Europe) (En,Fr,De,Es,It)" - rom ( name "Nicktoons Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc BABCCEFD md5 10EAEB09B2A583574FD0C7F416C68F82 sha1 55B145DE1810A4A6A8B5716EF4C9E9333A93E3BA ) + rom ( name "Nicktoons Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc babccefd sha1 55B145DE1810A4A6A8B5716EF4C9E9333A93E3BA ) ) game ( name "Nicktoons Unite! (USA)" description "Nicktoons Unite! (USA)" - rom ( name "Nicktoons Unite! (USA).gba" size 4194304 crc 75C35F7C md5 D5A97A8360EE0EE2651DC2C5AE1F8F30 sha1 E5C1EC46087FDBDB5ECA8B3CA98F83ED4BB36620 ) + rom ( name "Nicktoons Unite! (USA).gba" size 4194304 crc 75c35f7c sha1 E5C1EC46087FDBDB5ECA8B3CA98F83ED4BB36620 ) ) game ( name "Nihon Pro Mahjong Renmei Kounin - Tetsuman Advance - Menkyo Kaiden Series (Japan)" description "Nihon Pro Mahjong Renmei Kounin - Tetsuman Advance - Menkyo Kaiden Series (Japan)" - rom ( name "Nihon Pro Mahjong Renmei Kounin - Tetsuman Advance - Menkyo Kaiden Series (Japan).gba" size 4194304 crc 085C1184 md5 3636872E128F9C64C13BCB551C8566C0 sha1 FC6C75AF338224759757AE4B884D516DBFC973AC ) + rom ( name "Nihon Pro Mahjong Renmei Kounin - Tetsuman Advance - Menkyo Kaiden Series (Japan).gba" size 4194304 crc 085c1184 sha1 FC6C75AF338224759757AE4B884D516DBFC973AC flags verified ) ) game ( name "Ninja Cop (Europe)" description "Ninja Cop (Europe)" - rom ( name "Ninja Cop (Europe).gba" size 4194304 crc C14295B1 md5 8F71CC21F97599F376B71A0953DB1847 sha1 0CFE2BCBF256299060BC4EAC51C4DAD8CED9939D ) + rom ( name "Ninja Cop (Europe).gba" size 4194304 crc c14295b1 sha1 0CFE2BCBF256299060BC4EAC51C4DAD8CED9939D ) ) game ( name "Ninja Five-0 (USA)" description "Ninja Five-0 (USA)" - rom ( name "Ninja Five-0 (USA).gba" size 4194304 crc EB3954C6 md5 04244F72A9B8F17EE33E0B5BFF2B8B1F sha1 3BC5789035C7400283B121E9FB3801AAFAE55364 flags verified ) + rom ( name "Ninja Five-0 (USA).gba" size 4194304 crc eb3954c6 sha1 3BC5789035C7400283B121E9FB3801AAFAE55364 flags verified ) ) game ( name "Nintendo MP3 Player (Europe) (En,Fr,De,Es,It)" description "Nintendo MP3 Player (Europe) (En,Fr,De,Es,It)" - rom ( name "Nintendo MP3 Player (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 867BEC76 md5 D16CE53B19EF090D134E0F6086DDC173 sha1 0C1EB4AF684F3B428766B10CDBBE62FD726E5E27 ) + rom ( name "Nintendo MP3 Player (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 867bec76 sha1 0C1EB4AF684F3B428766B10CDBBE62FD726E5E27 flags verified ) +) + +game ( + name "Nintendo Puzzle Collection - Dr. Mario (Japan) (En)" + description "Nintendo Puzzle Collection - Dr. Mario (Japan) (En)" + rom ( name "Nintendo Puzzle Collection - Dr. Mario (Japan) (En).gba" size 50092 crc 9e54f585 sha1 349FA0A7B32F57210C9087D942AF7689DFC27629 flags verified ) +) + +game ( + name "Nintendo Puzzle Collection - Panel de Pon (Japan) (GameCube)" + description "Nintendo Puzzle Collection - Panel de Pon (Japan) (GameCube)" + rom ( name "Nintendo Puzzle Collection - Panel de Pon (Japan) (GameCube).gba" size 210304 crc 53a701e8 sha1 1D96A64481007389CE46314E8B30A101F81DBFB8 flags verified ) +) + +game ( + name "Nintendo Puzzle Collection - Yoshi no Cookie (Japan)" + description "Nintendo Puzzle Collection - Yoshi no Cookie (Japan)" + rom ( name "Nintendo Puzzle Collection - Yoshi no Cookie (Japan).gba" size 100144 crc 7662d781 sha1 74651FFF0BFE50A51A70E5902A7CAA0DCAE804E7 flags verified ) ) game ( name "No No No Puzzle Chailien (Japan)" description "No No No Puzzle Chailien (Japan)" - rom ( name "No No No Puzzle Chailien (Japan).gba" size 8388608 crc 1B00BC2C md5 440C87000424A33D6C2A77B570D2D643 sha1 110A7AE6E5886C10F2018D5293E9C1430299ED42 flags verified ) + rom ( name "No No No Puzzle Chailien (Japan).gba" size 8388608 crc 1b00bc2c sha1 110A7AE6E5886C10F2018D5293E9C1430299ED42 flags verified ) ) game ( name "No Rules - Get Phat (USA, Europe) (En,Fr,De,Es,It,Nl)" description "No Rules - Get Phat (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "No Rules - Get Phat (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 966FA650 md5 01FD699B39A0CA8E84226F18CF8BAEE7 sha1 CB6F269EE34B1F93EC0CBF71549E2A83278665E5 flags verified ) + rom ( name "No Rules - Get Phat (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 966fa650 sha1 CB6F269EE34B1F93EC0CBF71549E2A83278665E5 flags verified ) ) game ( name "Nobunaga Ibun (Japan)" description "Nobunaga Ibun (Japan)" - rom ( name "Nobunaga Ibun (Japan).gba" size 8388608 crc 526AB88E md5 E32FA9F5D6DEDF8E29D65126F780D58A sha1 32A882D296602B0819B1819C7E04A144F0CE6CE1 ) + rom ( name "Nobunaga Ibun (Japan).gba" size 8388608 crc 526ab88e sha1 32A882D296602B0819B1819C7E04A144F0CE6CE1 ) ) game ( name "Nobunaga no Yabou (Japan)" description "Nobunaga no Yabou (Japan)" - rom ( name "Nobunaga no Yabou (Japan).gba" size 4194304 crc EF23C79E md5 2D1CEFFBC8C34E3101AB91EA49F43A44 sha1 FC497BCFB0800AD95ADA93C7080ED09714156576 ) + rom ( name "Nobunaga no Yabou (Japan).gba" size 4194304 crc ef23c79e sha1 FC497BCFB0800AD95ADA93C7080ED09714156576 ) ) game ( name "Noddy - A Day in Toyland (USA) (En,Fr,Es)" description "Noddy - A Day in Toyland (USA) (En,Fr,Es)" - rom ( name "Noddy - A Day in Toyland (USA) (En,Fr,Es).gba" size 4194304 crc F906C5B6 md5 FE8AAC1A517AF3EA89FD680536962DDF sha1 B796262171986494F98B0C4EBE8A7C8CCF6B25A1 ) + rom ( name "Noddy - A Day in Toyland (USA) (En,Fr,Es).gba" size 4194304 crc f906c5b6 sha1 B796262171986494F98B0C4EBE8A7C8CCF6B25A1 ) ) game ( name "Noddy - A Day in Toyland (Europe) (En,Fr,Es,It,Nl,Pt,Da)" description "Noddy - A Day in Toyland (Europe) (En,Fr,Es,It,Nl,Pt,Da)" - rom ( name "Noddy - A Day in Toyland (Europe) (En,Fr,Es,It,Nl,Pt,Da).gba" size 4194304 crc 607DDC6B md5 59AEE0A5BC39A0A026DCDE89D6CCD4A4 sha1 9A1EB8224D5BD68F0D3D2417FE233472E7B80713 flags verified ) + rom ( name "Noddy - A Day in Toyland (Europe) (En,Fr,Es,It,Nl,Pt,Da).gba" size 4194304 crc 607ddc6b sha1 9A1EB8224D5BD68F0D3D2417FE233472E7B80713 flags verified ) ) game ( name "Nos Voisins, les Hommes (France)" description "Nos Voisins, les Hommes (France)" - rom ( name "Nos Voisins, les Hommes (France).gba" size 8388608 crc EB7C8402 md5 6AC288A44178E8061005F00FE2E564BC sha1 2749295D164B75162BBF1D0823ECC1C659182751 ) + rom ( name "Nos Voisins, les Hommes (France).gba" size 8388608 crc eb7c8402 sha1 2749295D164B75162BBF1D0823ECC1C659182751 ) ) game ( name "Nyan Nyan Nyanko no NyanCollection (Japan)" description "Nyan Nyan Nyanko no NyanCollection (Japan)" - rom ( name "Nyan Nyan Nyanko no NyanCollection (Japan).gba" size 8388608 crc 685E62BA md5 2EFC09D371A77DB996D82A06E0F71062 sha1 13AE4885154DD2519A08CC69012CC0C1DBA06221 ) + rom ( name "Nyan Nyan Nyanko no NyanCollection (Japan).gba" size 8388608 crc 685e62ba sha1 13AE4885154DD2519A08CC69012CC0C1DBA06221 ) ) game ( name "Ochaken Kururin - Honwaka Puzzle de Hotto Shiyo (Japan)" description "Ochaken Kururin - Honwaka Puzzle de Hotto Shiyo (Japan)" - rom ( name "Ochaken Kururin - Honwaka Puzzle de Hotto Shiyo (Japan).gba" size 4194304 crc EECDD3EF md5 73A3D8F718DD371836632B8E30DF4DE0 sha1 CD74254A24EF872C2EFD4F7AB206615D299CE0C0 ) + rom ( name "Ochaken Kururin - Honwaka Puzzle de Hotto Shiyo (Japan).gba" size 4194304 crc eecdd3ef sha1 CD74254A24EF872C2EFD4F7AB206615D299CE0C0 ) ) game ( name "Ochaken no Bouken-jima - Honwaka Yume no Island (Japan)" description "Ochaken no Bouken-jima - Honwaka Yume no Island (Japan)" - rom ( name "Ochaken no Bouken-jima - Honwaka Yume no Island (Japan).gba" size 8388608 crc 61E2799A md5 92751433CB0290A86D0BD57A1A150423 sha1 690A6F8A08B2D45C4E37C6FF28C90DDA85D91174 ) + rom ( name "Ochaken no Bouken-jima - Honwaka Yume no Island (Japan).gba" size 8388608 crc 61e2799a sha1 690A6F8A08B2D45C4E37C6FF28C90DDA85D91174 ) ) game ( name "Ochaken no Heya (Japan)" description "Ochaken no Heya (Japan)" - rom ( name "Ochaken no Heya (Japan).gba" size 8388608 crc C22CE53E md5 B8B1BFFEA715392586D6A549CED8F0E2 sha1 F1F801B08351808A64C30194CAD719A520087A71 ) + rom ( name "Ochaken no Heya (Japan).gba" size 8388608 crc c22ce53e sha1 F1F801B08351808A64C30194CAD719A520087A71 ) ) game ( name "Ochaken no Yume Bouken (Japan)" description "Ochaken no Yume Bouken (Japan)" - rom ( name "Ochaken no Yume Bouken (Japan).gba" size 8388608 crc 2937A9CD md5 0079F558708A0CC61D3D38C7134EE199 sha1 22B69B6683B7AE08CB2428662B8672618EE77FA0 ) + rom ( name "Ochaken no Yume Bouken (Japan).gba" size 8388608 crc 2937a9cd sha1 22B69B6683B7AE08CB2428662B8672618EE77FA0 ) ) game ( name "Oddworld - Munch's Oddysee (USA, Europe)" description "Oddworld - Munch's Oddysee (USA, Europe)" - rom ( name "Oddworld - Munch's Oddysee (USA, Europe).gba" size 8388608 crc 97367887 md5 277A144D9B4392A6C80F23B979C9C8F3 sha1 CC6BF19E5D6A35C2A745BEA4E3B2A210A9EBD296 flags verified ) + rom ( name "Oddworld - Munch's Oddysee (USA, Europe).gba" size 8388608 crc 97367887 sha1 CC6BF19E5D6A35C2A745BEA4E3B2A210A9EBD296 flags verified ) ) game ( name "Oddworld - Munch's Oddysee (Germany)" description "Oddworld - Munch's Oddysee (Germany)" - rom ( name "Oddworld - Munch's Oddysee (Germany).gba" size 8388608 crc FCC570A7 md5 4BA8BF225317BD0F51D8487B0A428460 sha1 A61BA72FF73C40EDFC7000724BF066897CA49066 ) + rom ( name "Oddworld - Munch's Oddysee (Germany).gba" size 8388608 crc fcc570a7 sha1 A61BA72FF73C40EDFC7000724BF066897CA49066 ) ) game ( name "Ohanaya-san Monogatari GBA - Iyashikei Ohanaya-san Ikusei Game (Japan)" description "Ohanaya-san Monogatari GBA - Iyashikei Ohanaya-san Ikusei Game (Japan)" - rom ( name "Ohanaya-san Monogatari GBA - Iyashikei Ohanaya-san Ikusei Game (Japan).gba" size 8388608 crc D5059733 md5 4F5F2463F25B4EE75B948C11D6312B91 sha1 36EF5248F9873C7812D93572242D01512D67F41C ) + rom ( name "Ohanaya-san Monogatari GBA - Iyashikei Ohanaya-san Ikusei Game (Japan).gba" size 8388608 crc d5059733 sha1 36EF5248F9873C7812D93572242D01512D67F41C ) ) game ( name "Ojarumaru - Gekkouchou Sanpo de Ojaru (Japan)" description "Ojarumaru - Gekkouchou Sanpo de Ojaru (Japan)" - rom ( name "Ojarumaru - Gekkouchou Sanpo de Ojaru (Japan).gba" size 4194304 crc 6043595E md5 FD1D6711A0CCA4C15A627183AEC0A854 sha1 694CACC60F4B9ABF82356A9DCFA127406262C8C8 ) + rom ( name "Ojarumaru - Gekkouchou Sanpo de Ojaru (Japan).gba" size 4194304 crc 6043595e sha1 694CACC60F4B9ABF82356A9DCFA127406262C8C8 flags verified ) ) game ( name "Okumanchouja Game - Nottori Daisakusen! (Japan)" description "Okumanchouja Game - Nottori Daisakusen! (Japan)" - rom ( name "Okumanchouja Game - Nottori Daisakusen! (Japan).gba" size 4194304 crc 07022C3A md5 247EC2C581B6C5D9BAFBDA6C51D7C119 sha1 16DF457ACA6B402D1042205CF7940D7F0A759C8E ) + rom ( name "Okumanchouja Game - Nottori Daisakusen! (Japan).gba" size 4194304 crc 07022c3a sha1 16DF457ACA6B402D1042205CF7940D7F0A759C8E ) ) game ( name "One Piece (USA)" description "One Piece (USA)" - rom ( name "One Piece (USA).gba" size 8388608 crc 7D2CF2A1 md5 CE153A5CE176B608EDD035E3B9A27DAD sha1 6DFE6572AA6B51E2C550DDEEF7CA04C35FCDF299 flags verified ) + rom ( name "One Piece (USA).gba" size 8388608 crc 7d2cf2a1 sha1 6DFE6572AA6B51E2C550DDEEF7CA04C35FCDF299 flags verified ) ) game ( name "One Piece - Dragon Dream (Japan)" description "One Piece - Dragon Dream (Japan)" - rom ( name "One Piece - Dragon Dream (Japan).gba" size 16777216 crc 08CFF461 md5 C939D218192E534472423557D6FB1571 sha1 883277CD8926FCEF9418B59F3F64E7A5BB218206 ) + rom ( name "One Piece - Dragon Dream (Japan).gba" size 16777216 crc 08cff461 sha1 883277CD8926FCEF9418B59F3F64E7A5BB218206 flags verified ) ) game ( name "One Piece - Going Baseball - Haejeok Yaku (Korea)" description "One Piece - Going Baseball - Haejeok Yaku (Korea)" - rom ( name "One Piece - Going Baseball - Haejeok Yaku (Korea).gba" size 8388608 crc 66928F27 md5 799A13E6DF8C577E5E49FB1F0B217A0B sha1 F33C77986A7F6CF461A71933D0006E18736F7E17 ) + rom ( name "One Piece - Going Baseball - Haejeok Yaku (Korea).gba" size 8388608 crc 66928f27 sha1 F33C77986A7F6CF461A71933D0006E18736F7E17 ) ) game ( name "One Piece - Going Baseball - Kaizoku Yakyuu (Japan)" description "One Piece - Going Baseball - Kaizoku Yakyuu (Japan)" - rom ( name "One Piece - Going Baseball - Kaizoku Yakyuu (Japan).gba" size 8388608 crc 0B77BCB8 md5 9BB9E68CA6D9A2F0C4BC9052321FBEE8 sha1 18CF10529BB6E2D113CA586D2DAE3EB23AD496CF ) + rom ( name "One Piece - Going Baseball - Kaizoku Yakyuu (Japan).gba" size 8388608 crc 0b77bcb8 sha1 18CF10529BB6E2D113CA586D2DAE3EB23AD496CF ) ) game ( name "One Piece - Ilgop Seomui Debomool (Korea)" description "One Piece - Ilgop Seomui Debomool (Korea)" - rom ( name "One Piece - Ilgop Seomui Debomool (Korea).gba" size 8388608 crc 05E56A4D md5 3C1304AD6651E0E2C2D6741D949E4A31 sha1 E03387FB73A2DD64ECBBA5ED1749DC12599150E1 ) + rom ( name "One Piece - Ilgop Seomui Debomool (Korea).gba" size 8388608 crc 05e56a4d sha1 E03387FB73A2DD64ECBBA5ED1749DC12599150E1 ) ) game ( name "Onimusha Tactics (Japan)" description "Onimusha Tactics (Japan)" - rom ( name "Onimusha Tactics (Japan).gba" size 8388608 crc B521C635 md5 4EC9300D15C45CF476705AF1869C444E sha1 F652C211CC64D578B7F15D6AFD112E2916181E7C ) + rom ( name "Onimusha Tactics (Japan).gba" size 8388608 crc b521c635 sha1 F652C211CC64D578B7F15D6AFD112E2916181E7C ) ) game ( name "Onimusha Tactics (USA)" description "Onimusha Tactics (USA)" - rom ( name "Onimusha Tactics (USA).gba" size 8388608 crc 70475D7F md5 7C8E479F4C4E46F406B1DA5E786358C0 sha1 83ABEE3AA535590F666D7E9A6971640D8A41AA9D ) + rom ( name "Onimusha Tactics (USA).gba" size 8388608 crc 70475d7f sha1 83ABEE3AA535590F666D7E9A6971640D8A41AA9D ) ) game ( name "Onimusha Tactics (Europe)" description "Onimusha Tactics (Europe)" - rom ( name "Onimusha Tactics (Europe).gba" size 8388608 crc 63AA930A md5 1E0B41FBB6F338DC44932625446DF20C sha1 247853BAE3771F75725E5D212F6B3A416B749E07 ) + rom ( name "Onimusha Tactics (Europe).gba" size 8388608 crc 63aa930a sha1 247853BAE3771F75725E5D212F6B3A416B749E07 flags verified ) ) game ( - name "Onmyou Taisenki Zeroshiki (Japan)" - description "Onmyou Taisenki Zeroshiki (Japan)" - rom ( name "Onmyou Taisenki Zeroshiki (Japan).gba" size 8388608 crc 66C29472 md5 89B14322FDD974AC1FE06C7B77C9DBFF sha1 47B04F671AF34E8449856BDFC3ACC76076C2273A ) + name "Onmyou Taisenki - Zeroshiki (Japan)" + description "Onmyou Taisenki - Zeroshiki (Japan)" + rom ( name "Onmyou Taisenki - Zeroshiki (Japan).gba" size 8388608 crc 66c29472 sha1 47B04F671AF34E8449856BDFC3ACC76076C2273A ) ) game ( name "Open Season (USA) (En,Fr,Es)" description "Open Season (USA) (En,Fr,Es)" - rom ( name "Open Season (USA) (En,Fr,Es).gba" size 8388608 crc E6A1D5B2 md5 64B19ADCA4BA8EBFCA983C39C7F21C8C sha1 B12757E5315BC384CF40B5E621F956CA536A3E66 ) + rom ( name "Open Season (USA) (En,Fr,Es).gba" size 8388608 crc e6a1d5b2 sha1 B12757E5315BC384CF40B5E621F956CA536A3E66 ) ) game ( name "Open Season (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi)" description "Open Season (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi)" - rom ( name "Open Season (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi).gba" size 8388608 crc 4C8F6FDC md5 5048D3110F72B4BA40F0B98936413A0B sha1 5122C50C14BF115B2356DA3A6A0E8E4CC119B866 ) + rom ( name "Open Season (Europe) (En,Fr,De,Es,It,Sv,No,Da,Fi).gba" size 8388608 crc 4c8f6fdc sha1 5122C50C14BF115B2356DA3A6A0E8E4CC119B866 ) ) game ( name "Open Season (Europe) (En,Fr,Es,Nl)" description "Open Season (Europe) (En,Fr,Es,Nl)" - rom ( name "Open Season (Europe) (En,Fr,Es,Nl).gba" size 8388608 crc 51B0A94B md5 0FFA05E57CFEECA8807B62578FD80FB1 sha1 51F40BDEF5C7F30FA070757C6853AA38CD72E89D ) + rom ( name "Open Season (Europe) (En,Fr,Es,Nl).gba" size 8388608 crc 51b0a94b sha1 51F40BDEF5C7F30FA070757C6853AA38CD72E89D ) ) game ( name "Operation Armored Liberty (USA)" description "Operation Armored Liberty (USA)" - rom ( name "Operation Armored Liberty (USA).gba" size 4194304 crc 8F289E0B md5 2293E67087AE9C5FB0AB6ABB25179C0E sha1 319B3C401A6623273C2819087CB5FE9E5D15808A ) + rom ( name "Operation Armored Liberty (USA).gba" size 4194304 crc 8f289e0b sha1 319B3C401A6623273C2819087CB5FE9E5D15808A ) ) game ( name "Oriental Blue - Ao no Tengai (Japan)" description "Oriental Blue - Ao no Tengai (Japan)" - rom ( name "Oriental Blue - Ao no Tengai (Japan).gba" size 16777216 crc 05E80ECC md5 4BB1D95611B7CFDADA71F2B6A4BF961C sha1 414CAD1AEE67AB20F3C133F0259DA7E8C3073BBC flags verified ) + rom ( name "Oriental Blue - Ao no Tengai (Japan).gba" size 16777216 crc 05e80ecc sha1 414CAD1AEE67AB20F3C133F0259DA7E8C3073BBC flags verified ) ) game ( name "Oshaberi Inko Club (Japan)" description "Oshaberi Inko Club (Japan)" - rom ( name "Oshaberi Inko Club (Japan).gba" size 8388608 crc DF6901F0 md5 E83C6421A55F4AF4394FC8B5FB47EFDD sha1 82E48090B9615282C58747A1F7B105196866F8C9 ) + rom ( name "Oshaberi Inko Club (Japan).gba" size 8388608 crc df6901f0 sha1 82E48090B9615282C58747A1F7B105196866F8C9 ) ) game ( name "Oshare Princess (Japan)" description "Oshare Princess (Japan)" - rom ( name "Oshare Princess (Japan).gba" size 4194304 crc 5A2299E1 md5 1AA6A1651FA5AD8A002CA41E5EA9DB30 sha1 CF47E9FDB8DEC4833D8DD1AE00FA2F222BD1D7DA ) + rom ( name "Oshare Princess (Japan).gba" size 4194304 crc 5a2299e1 sha1 CF47E9FDB8DEC4833D8DD1AE00FA2F222BD1D7DA ) ) game ( name "Oshare Princess 2 (Japan)" description "Oshare Princess 2 (Japan)" - rom ( name "Oshare Princess 2 (Japan).gba" size 8388608 crc 8383FCDA md5 38B69A345ED3A000E390645AAF6E51FC sha1 649001F85CDCD2515183FC1364D08DE52C918FEB ) + rom ( name "Oshare Princess 2 (Japan).gba" size 8388608 crc 8383fcda sha1 649001F85CDCD2515183FC1364D08DE52C918FEB ) ) game ( name "Oshare Princess 3 (Japan)" description "Oshare Princess 3 (Japan)" - rom ( name "Oshare Princess 3 (Japan).gba" size 8388608 crc F1E8A261 md5 CD26AD539926810E5812CCC1105732CC sha1 923E4B22C5A9DE6C95A02A4B948A962B09DBE8C3 ) + rom ( name "Oshare Princess 3 (Japan).gba" size 8388608 crc f1e8a261 sha1 923E4B22C5A9DE6C95A02A4B948A962B09DBE8C3 flags verified ) ) game ( name "Oshare Princess 5 (Japan)" description "Oshare Princess 5 (Japan)" - rom ( name "Oshare Princess 5 (Japan).gba" size 8388608 crc 38AF35C1 md5 3433A199B6C8360C998DE05F54FC25BF sha1 94DF7104875F2E22CDFEF882E82B0534DA56D31C ) + rom ( name "Oshare Princess 5 (Japan).gba" size 8388608 crc 38af35c1 sha1 94DF7104875F2E22CDFEF882E82B0534DA56D31C ) ) game ( name "Oshare Wanko (Japan)" description "Oshare Wanko (Japan)" - rom ( name "Oshare Wanko (Japan).gba" size 8388608 crc 1CC60C27 md5 85EB280639D3C2BAB9FA8444E861E461 sha1 262389579D4D60337097015F236C9AA098364E69 ) + rom ( name "Oshare Wanko (Japan).gba" size 8388608 crc 1cc60c27 sha1 262389579D4D60337097015F236C9AA098364E69 ) ) game ( name "Ottifanten Pinball (Germany)" description "Ottifanten Pinball (Germany)" - rom ( name "Ottifanten Pinball (Germany).gba" size 4194304 crc 77A84969 md5 C9AFFF5C7245894071C7191DF4B1749F sha1 C294D0756FE6AB211488B582DACE3282887DCBD5 ) + rom ( name "Ottifanten Pinball (Germany).gba" size 4194304 crc 77a84969 sha1 C294D0756FE6AB211488B582DACE3282887DCBD5 ) ) game ( name "Ougon no Taiyou - Hirakareshi Fuuin (Japan)" description "Ougon no Taiyou - Hirakareshi Fuuin (Japan)" - rom ( name "Ougon no Taiyou - Hirakareshi Fuuin (Japan).gba" size 8388608 crc FB96D9DE md5 CF33E45E59B0EE3801B5CF18A9E58524 sha1 35EF9E4C9F38183EBD6A3E3923A11CE9A4333718 ) + rom ( name "Ougon no Taiyou - Hirakareshi Fuuin (Japan).gba" size 8388608 crc fb96d9de sha1 35EF9E4C9F38183EBD6A3E3923A11CE9A4333718 flags verified ) ) game ( name "Ougon no Taiyou - Ushinawareshi Toki (Japan)" description "Ougon no Taiyou - Ushinawareshi Toki (Japan)" - rom ( name "Ougon no Taiyou - Ushinawareshi Toki (Japan).gba" size 16777216 crc 830B795F md5 9D84AD590D1DFFA33B1B1E2E1D64FB4D sha1 4C79E60962299654981628CCD99B122EF27043F7 ) + rom ( name "Ougon no Taiyou - Ushinawareshi Toki (Japan).gba" size 16777216 crc 830b795f sha1 4C79E60962299654981628CCD99B122EF27043F7 flags verified ) ) game ( name "Over the Hedge (USA)" description "Over the Hedge (USA)" - rom ( name "Over the Hedge (USA).gba" size 8388608 crc 5F3A7BB7 md5 123978146274E2C7711209ABA22EE244 sha1 BE86490D8161FD934A122020300CE6898EF81D45 ) + rom ( name "Over the Hedge (USA).gba" size 8388608 crc 5f3a7bb7 sha1 BE86490D8161FD934A122020300CE6898EF81D45 ) ) game ( name "Over the Hedge (Europe)" description "Over the Hedge (Europe)" - rom ( name "Over the Hedge (Europe).gba" size 8388608 crc C7023309 md5 0F7F9DC0C967029F8686ECE3B9385C71 sha1 1BF3F24207969D83C93A0BFE0293F83B07EF94F4 ) + rom ( name "Over the Hedge (Europe).gba" size 8388608 crc c7023309 sha1 1BF3F24207969D83C93A0BFE0293F83B07EF94F4 flags verified ) ) game ( name "Over the Hedge - Beesten bij de Buren (Netherlands)" description "Over the Hedge - Beesten bij de Buren (Netherlands)" - rom ( name "Over the Hedge - Beesten bij de Buren (Netherlands).gba" size 8388608 crc CF0F07C7 md5 369AAC3167D1F83C70A671B8FEBC2751 sha1 BD92BB903258FA2FF1552B99A757072510D37337 ) + rom ( name "Over the Hedge - Beesten bij de Buren (Netherlands).gba" size 8388608 crc cf0f07c7 sha1 BD92BB903258FA2FF1552B99A757072510D37337 ) ) game ( name "Over the Hedge - Hammy Goes Nuts! (USA)" description "Over the Hedge - Hammy Goes Nuts! (USA)" - rom ( name "Over the Hedge - Hammy Goes Nuts! (USA).gba" size 8388608 crc B9D4E9E7 md5 691EA58D7B3C1ADB7C6E01792BD2D140 sha1 6AB82FA0763BF8AC6E837A83075BCF0609EB2127 ) + rom ( name "Over the Hedge - Hammy Goes Nuts! (USA).gba" size 8388608 crc b9d4e9e7 sha1 6AB82FA0763BF8AC6E837A83075BCF0609EB2127 ) ) game ( name "Over the Hedge - Hammy Goes Nuts! (Europe) (En,Fr,De,Es,It,Nl)" description "Over the Hedge - Hammy Goes Nuts! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Over the Hedge - Hammy Goes Nuts! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 8F1B100D md5 EC77810214F9B39FDC7FE1F2F1CF5CC3 sha1 F616DFFA5A4BE92C75AF8952218946893921436D ) + rom ( name "Over the Hedge - Hammy Goes Nuts! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 8f1b100d sha1 F616DFFA5A4BE92C75AF8952218946893921436D flags verified ) ) game ( name "Overstorm (Unknown) (Proto)" description "Overstorm (Unknown) (Proto)" - rom ( name "Overstorm (Unknown) (Proto).gba" size 3470916 crc EE764CF6 md5 5EE1AD6DC6974ECFC9DC3CC93B17FBB0 sha1 88129A07E9DFB556C38A5C61C6E96FBFB4D23FEA ) + rom ( name "Overstorm (Unknown) (Proto).gba" size 3470916 crc ee764cf6 sha1 88129A07E9DFB556C38A5C61C6E96FBFB4D23FEA flags verified ) ) game ( name "Ozzy & Drix (USA)" description "Ozzy & Drix (USA)" - rom ( name "Ozzy & Drix (USA).gba" size 8388608 crc D7245280 md5 DFAE85CBB4E9825BEE214FF73CA9BBAA sha1 11491A5298CCAD1CBC75749A5187525C73AF5A1D flags verified ) + rom ( name "Ozzy & Drix (USA).gba" size 8388608 crc d7245280 sha1 11491A5298CCAD1CBC75749A5187525C73AF5A1D flags verified ) ) game ( name "Paard & Pony - Mijn Manege (Netherlands) (En,Nl)" description "Paard & Pony - Mijn Manege (Netherlands) (En,Nl)" - rom ( name "Paard & Pony - Mijn Manege (Netherlands) (En,Nl).gba" size 4194304 crc 1F2708D5 md5 657823B16014BC265AB93757564E0BE5 sha1 0C5261A97FE9555C5705D78BE73402D4FA34EBF8 ) + rom ( name "Paard & Pony - Mijn Manege (Netherlands) (En,Nl).gba" size 4194304 crc 1f2708d5 sha1 0C5261A97FE9555C5705D78BE73402D4FA34EBF8 ) ) game ( name "Paard & Pony - Paard in Galop (Netherlands) (En,Nl)" description "Paard & Pony - Paard in Galop (Netherlands) (En,Nl)" - rom ( name "Paard & Pony - Paard in Galop (Netherlands) (En,Nl).gba" size 4194304 crc B6FC77F3 md5 6532702B7ED355F25F4AE6AF3DC5DDEA sha1 38AE3B180AD31E7FD0787F5B7FE983A4BACD6C03 ) + rom ( name "Paard & Pony - Paard in Galop (Netherlands) (En,Nl).gba" size 4194304 crc b6fc77f3 sha1 38AE3B180AD31E7FD0787F5B7FE983A4BACD6C03 ) ) game ( name "Pac-Man Collection (USA)" description "Pac-Man Collection (USA)" - rom ( name "Pac-Man Collection (USA).gba" size 4194304 crc 6E5C16F4 md5 ED4304CC4F5BAC34ADFAA750316784A8 sha1 AAAF5496411CDD9315DEBE866E69CA8665468F9B ) + rom ( name "Pac-Man Collection (USA).gba" size 4194304 crc 6e5c16f4 sha1 AAAF5496411CDD9315DEBE866E69CA8665468F9B flags verified ) ) game ( name "Pac-Man Collection (Japan) (En)" description "Pac-Man Collection (Japan) (En)" - rom ( name "Pac-Man Collection (Japan) (En).gba" size 4194304 crc B0FDDB8F md5 4CE8A88300A6D1EFA22E34271C60FC64 sha1 73C395F79A2615AB2C8FDD4F865219FE2FC5184A ) + rom ( name "Pac-Man Collection (Japan) (En).gba" size 4194304 crc b0fddb8f sha1 73C395F79A2615AB2C8FDD4F865219FE2FC5184A ) ) game ( name "Pac-Man Collection (Europe)" description "Pac-Man Collection (Europe)" - rom ( name "Pac-Man Collection (Europe).gba" size 4194304 crc E1578D25 md5 3B0DAE8CD1DD848FE201F7CBAF94CED1 sha1 750A6B6C36F75B2605A1DFCEEFCE7F27AA2191E3 flags verified ) + rom ( name "Pac-Man Collection (Europe).gba" size 4194304 crc e1578d25 sha1 750A6B6C36F75B2605A1DFCEEFCE7F27AA2191E3 flags verified ) ) game ( - name "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It)" - description "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3E70BF4D md5 30E7A35F23B2259B65844A667191C556 sha1 9BBFFE9FF2524D679EF9E8CEB46362F3602D7584 ) + name "Pac-Man Collection (USA) (Wii U Virtual Console)" + description "Pac-Man Collection (USA) (Wii U Virtual Console)" + rom ( name "Pac-Man Collection (USA) (Wii U Virtual Console).gba" size 4194304 crc 9a8e2eaa sha1 AFE4A9DFD653AE2B3589297889105D55EB775C81 flags verified ) +) + +game ( + name "Pac-Man Collection (Europe) (Wii U Virtual Console)" + description "Pac-Man Collection (Europe) (Wii U Virtual Console)" + rom ( name "Pac-Man Collection (Europe) (Wii U Virtual Console).gba" size 4194304 crc 1585b57b sha1 A12ACC97936DBE32FB10F58B2585C6189182153F flags verified ) ) game ( name "Pac-Man Pinball Advance (USA)" description "Pac-Man Pinball Advance (USA)" - rom ( name "Pac-Man Pinball Advance (USA).gba" size 4194304 crc DA4E1109 md5 4D7B955B9C19B13D1D776E35CE007F78 sha1 DFD93F861E571153E0AE0A65799C5D44E5154373 ) + rom ( name "Pac-Man Pinball Advance (USA).gba" size 4194304 crc da4e1109 sha1 DFD93F861E571153E0AE0A65799C5D44E5154373 ) +) + +game ( + name "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It)" + description "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It)" + rom ( name "Pac-Man Pinball Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3e70bf4d sha1 9BBFFE9FF2524D679EF9E8CEB46362F3602D7584 ) ) game ( name "Pac-Man World (USA)" description "Pac-Man World (USA)" - rom ( name "Pac-Man World (USA).gba" size 8388608 crc B2A4FC78 md5 3EDA36856917A9AB80B9BB7A930BE834 sha1 7E9F23753C10494A3F0BBDF0905F3C7AC052B1B3 ) + rom ( name "Pac-Man World (USA).gba" size 8388608 crc b2a4fc78 sha1 7E9F23753C10494A3F0BBDF0905F3C7AC052B1B3 ) ) game ( name "Pac-Man World (Europe) (En,Fr,De,Es,It)" description "Pac-Man World (Europe) (En,Fr,De,Es,It)" - rom ( name "Pac-Man World (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1F92814E md5 83511ED734D5BF842B9062EBC574A434 sha1 F6D4B1B9E7BAF758888FA5958914A82B4A8EF4BF ) + rom ( name "Pac-Man World (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1f92814e sha1 F6D4B1B9E7BAF758888FA5958914A82B4A8EF4BF ) ) game ( name "Pac-Man World & Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It)" description "Pac-Man World & Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It)" - rom ( name "Pac-Man World & Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B68B84C1 md5 DB8327CE52EF65EBD4D0629B5FEBE178 sha1 224B3FA5083268DDD75983207D060EAC6A93B62B ) + rom ( name "Pac-Man World & Ms. Pac-Man - Maze Madness (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b68b84c1 sha1 224B3FA5083268DDD75983207D060EAC6A93B62B ) ) game ( name "Pac-Man World 2 (Europe) (En,Fr,De,Es,It)" description "Pac-Man World 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Pac-Man World 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A45EB4D2 md5 3755C0A785A829114C543393ECF0CB4E sha1 DE9852C4B07941EC83FAECDAAFD538E1CDE8C804 ) + rom ( name "Pac-Man World 2 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a45eb4d2 sha1 DE9852C4B07941EC83FAECDAAFD538E1CDE8C804 ) ) game ( name "Pac-Man World 2 (USA)" description "Pac-Man World 2 (USA)" - rom ( name "Pac-Man World 2 (USA).gba" size 4194304 crc 814A7D33 md5 86E6497272F39B19AF6750D699569531 sha1 A3DA2AD5CF120CB53E663C2290EB8872F5650BA7 ) + rom ( name "Pac-Man World 2 (USA).gba" size 4194304 crc 814a7d33 sha1 A3DA2AD5CF120CB53E663C2290EB8872F5650BA7 ) ) game ( name "Paws & Claws - Best Friends - Dogs & Cats (USA)" description "Paws & Claws - Best Friends - Dogs & Cats (USA)" - rom ( name "Paws & Claws - Best Friends - Dogs & Cats (USA).gba" size 8388608 crc 6ECF40A0 md5 2B679F61361AD3040086D8684D58E8E7 sha1 2D024EA3621486DD0CF59B801A364649FB751C49 ) + rom ( name "Paws & Claws - Best Friends - Dogs & Cats (USA).gba" size 8388608 crc 6ecf40a0 sha1 2D024EA3621486DD0CF59B801A364649FB751C49 ) ) game ( name "Paws & Claws - Pet Resort (USA)" description "Paws & Claws - Pet Resort (USA)" - rom ( name "Paws & Claws - Pet Resort (USA).gba" size 4194304 crc E58DA71E md5 B0118C3619B732C172CE9770393D8A06 sha1 5C75C67DAE18BD77CA2BB05A76782A14806D45A7 ) + rom ( name "Paws & Claws - Pet Resort (USA).gba" size 4194304 crc e58da71e sha1 5C75C67DAE18BD77CA2BB05A76782A14806D45A7 ) +) + +game ( + name "Paws & Claws - Pet Vet (USA)" + description "Paws & Claws - Pet Vet (USA)" + rom ( name "Paws & Claws - Pet Vet (USA).gba" size 8388608 crc efee1ddf sha1 C121EEA8F816C4F8CBAB32058D6B9BAC57F0D7E3 flags verified ) ) game ( name "Payback (Europe) (En,Fr,De,Es,It)" description "Payback (Europe) (En,Fr,De,Es,It)" - rom ( name "Payback (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 962DD201 md5 7E43EE7B00269D5F0FDDB55E8BB747CC sha1 08DF2C6F1B932B8C6E5E1BC9C6CCBE738832D2B7 ) + rom ( name "Payback (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 962dd201 sha1 08DF2C6F1B932B8C6E5E1BC9C6CCBE738832D2B7 ) ) game ( name "Pazuninn - Umininn no Puzzle de Nimu (Japan)" description "Pazuninn - Umininn no Puzzle de Nimu (Japan)" - rom ( name "Pazuninn - Umininn no Puzzle de Nimu (Japan).gba" size 4194304 crc 8DAA89C9 md5 A1D050C200887E57004413A62DCC5D89 sha1 5F1F0F73593C2257EC723E39F3C0E4407EF1B223 ) + rom ( name "Pazuninn - Umininn no Puzzle de Nimu (Japan).gba" size 4194304 crc 8daa89c9 sha1 5F1F0F73593C2257EC723E39F3C0E4407EF1B223 ) ) game ( name "Penny Racers (Europe)" description "Penny Racers (Europe)" - rom ( name "Penny Racers (Europe).gba" size 4194304 crc 8FDDD48B md5 B48F441DC1D55A69A325AD812AEF764F sha1 7C097634FADC6270873A4A5CF2EB0A8BEB3C9E6E flags verified ) + rom ( name "Penny Racers (Europe).gba" size 4194304 crc 8fddd48b sha1 7C097634FADC6270873A4A5CF2EB0A8BEB3C9E6E flags verified ) ) game ( name "Peter Pan - Return to Neverland (USA)" description "Peter Pan - Return to Neverland (USA)" - rom ( name "Peter Pan - Return to Neverland (USA).gba" size 8388608 crc 4CAFCCBD md5 D7C540384EFF184DBD81292F3F7F8C29 sha1 57317B9C6C2075B7D39D85D949EFB49DB85AAD13 ) + rom ( name "Peter Pan - Return to Neverland (USA).gba" size 8388608 crc 4cafccbd sha1 57317B9C6C2075B7D39D85D949EFB49DB85AAD13 ) ) game ( name "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl)" description "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc BE7D574C md5 989135C9DD288D2C5731C2563C7863EA sha1 CCF431F78F749360DC385271A806F2CF1141CEA8 flags verified ) + rom ( name "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc be7d574c sha1 CCF431F78F749360DC385271A806F2CF1141CEA8 flags verified ) +) + +game ( + name "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" + description "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" + rom ( name "Peter Pan - Return to Neverland (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 4c682cc3 sha1 A3A45EABC4CB7EF00C5CAF36EEF6B22C2261EF14 flags verified ) +) + +game ( + name "Peter Pan - Return to Neverland (USA) (Rev 1)" + description "Peter Pan - Return to Neverland (USA) (Rev 1)" + rom ( name "Peter Pan - Return to Neverland (USA) (Rev 1).gba" size 8388608 crc 431dfea8 sha1 DAF2EA149BDD74E15A66710D29646F2142777102 flags verified ) ) game ( name "Peter Pan - The Motion Picture Event (USA)" description "Peter Pan - The Motion Picture Event (USA)" - rom ( name "Peter Pan - The Motion Picture Event (USA).gba" size 4194304 crc 8AC558CE md5 FC7542EF483C03EB22000837C38BFC1D sha1 598363C18F903616EBA15F7AA818C89AA4CB6A9D ) + rom ( name "Peter Pan - The Motion Picture Event (USA).gba" size 4194304 crc 8ac558ce sha1 598363C18F903616EBA15F7AA818C89AA4CB6A9D ) ) game ( name "Peter Pan - The Motion Picture Event (Europe) (En,Fr,De,Es,It)" description "Peter Pan - The Motion Picture Event (Europe) (En,Fr,De,Es,It)" - rom ( name "Peter Pan - The Motion Picture Event (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 98C27E8A md5 07826E89F368FDCFE22590D578B63B4B sha1 DD8B3399E6DC2EF72A0BE2D10A17E0CC96999356 flags verified ) + rom ( name "Peter Pan - The Motion Picture Event (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 98c27e8a sha1 DD8B3399E6DC2EF72A0BE2D10A17E0CC96999356 flags verified ) ) game ( name "Petz - Hamsterz Life 2 (USA)" description "Petz - Hamsterz Life 2 (USA)" - rom ( name "Petz - Hamsterz Life 2 (USA).gba" size 8388608 crc 9F0E4A6A md5 859A2612F2229BD78C74FADFEDDCC852 sha1 E0CAD11E08A9D72357B2548B3ABC252B3D2F6890 ) + rom ( name "Petz - Hamsterz Life 2 (USA).gba" size 8388608 crc 9f0e4a6a sha1 E0CAD11E08A9D72357B2548B3ABC252B3D2F6890 ) ) game ( name "Petz Vet (USA)" description "Petz Vet (USA)" - rom ( name "Petz Vet (USA).gba" size 8388608 crc 1DBF4D3D md5 43CF1C2B7601DB441295F12C538AE3A3 sha1 9755A6EAF65D10131E591C4C75B9C77554CD1DAD ) + rom ( name "Petz Vet (USA).gba" size 8388608 crc 1dbf4d3d sha1 9755A6EAF65D10131E591C4C75B9C77554CD1DAD ) ) game ( name "Pferd & Pony - Best Friends - Mein Pferd (Germany) (En,De)" description "Pferd & Pony - Best Friends - Mein Pferd (Germany) (En,De)" - rom ( name "Pferd & Pony - Best Friends - Mein Pferd (Germany) (En,De).gba" size 8388608 crc AA02CB0C md5 7B434547EF9EA4F55AD3885181D3CDD4 sha1 87332FF941902A413D3AA0A4E3951122BA111A96 ) + rom ( name "Pferd & Pony - Best Friends - Mein Pferd (Germany) (En,De).gba" size 8388608 crc aa02cb0c sha1 87332FF941902A413D3AA0A4E3951122BA111A96 ) ) game ( name "Pferd & Pony - Lass Uns Reiten 2 (Germany) (En,De)" description "Pferd & Pony - Lass Uns Reiten 2 (Germany) (En,De)" - rom ( name "Pferd & Pony - Lass Uns Reiten 2 (Germany) (En,De).gba" size 4194304 crc 6217469F md5 7D2E6BB7047468ED61F9C31C48C27EEA sha1 32EC6383F46A3195BE58ABB82D8FF391B1634371 flags verified ) + rom ( name "Pferd & Pony - Lass Uns Reiten 2 (Germany) (En,De).gba" size 4194304 crc 6217469f sha1 32EC6383F46A3195BE58ABB82D8FF391B1634371 flags verified ) ) game ( name "Pferd & Pony - Mein Gestuet (Germany) (En,De)" description "Pferd & Pony - Mein Gestuet (Germany) (En,De)" - rom ( name "Pferd & Pony - Mein Gestuet (Germany) (En,De).gba" size 8388608 crc 2819BDF5 md5 1CD1385407BFB06D4EE222650E633735 sha1 27F5E01E2BDDEC90E26C853A29405FE113F87180 ) + rom ( name "Pferd & Pony - Mein Gestuet (Germany) (En,De).gba" size 8388608 crc 2819bdf5 sha1 27F5E01E2BDDEC90E26C853A29405FE113F87180 ) ) game ( name "Pferd & Pony - Mein Pferdehof (Germany) (En,De)" description "Pferd & Pony - Mein Pferdehof (Germany) (En,De)" - rom ( name "Pferd & Pony - Mein Pferdehof (Germany) (En,De).gba" size 4194304 crc CC74B433 md5 40264B9C9EAB1B8D1CDF834DBC05F16E sha1 51152C4CA5A2E8C8680DB8F70501452C967D8320 ) + rom ( name "Pferd & Pony - Mein Pferdehof (Germany) (En,De).gba" size 4194304 crc cc74b433 sha1 51152C4CA5A2E8C8680DB8F70501452C967D8320 ) ) game ( name "Pferd & Pony 2 in 1 (Germany)" description "Pferd & Pony 2 in 1 (Germany)" - rom ( name "Pferd & Pony 2 in 1 (Germany).gba" size 8388608 crc 965391EA md5 BA7F3C1078471EEED0D3EE39C092578A sha1 EC0307C819B41FF0F3F5AA9212A6E333B2242675 ) + rom ( name "Pferd & Pony 2 in 1 (Germany).gba" size 8388608 crc 965391ea sha1 EC0307C819B41FF0F3F5AA9212A6E333B2242675 ) ) game ( name "Phalanx (Japan)" description "Phalanx (Japan)" - rom ( name "Phalanx (Japan).gba" size 4194304 crc 5F419F32 md5 C79AA5315644D3463C91F2DD7FA08202 sha1 4E3AFF0D03E12D9F486B514DEF3267B1127851DA ) + rom ( name "Phalanx (Japan).gba" size 4194304 crc 5f419f32 sha1 4E3AFF0D03E12D9F486B514DEF3267B1127851DA ) ) game ( name "Phalanx (Europe) (En,Fr,De,Es,It,Nl)" description "Phalanx (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Phalanx (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc DFCFE06C md5 BC15F4E82A86854175442D32218E2B14 sha1 83067B4574A49AE8D89B79D91E7CE4AAD8141E67 flags verified ) + rom ( name "Phalanx (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc dfcfe06c sha1 83067B4574A49AE8D89B79D91E7CE4AAD8141E67 flags verified ) ) game ( name "Phalanx (USA)" description "Phalanx (USA)" - rom ( name "Phalanx (USA).gba" size 4194304 crc EB733713 md5 6E2FC7FC2915AFB2C0F3A833C62F4C20 sha1 1994B54A0F08854E39B698273F1944B75659542B ) + rom ( name "Phalanx (USA).gba" size 4194304 crc eb733713 sha1 1994B54A0F08854E39B698273F1944B75659542B ) ) game ( name "Phantasy Star Collection (USA)" description "Phantasy Star Collection (USA)" - rom ( name "Phantasy Star Collection (USA).gba" size 8388608 crc E5A7FE17 md5 AF7E218EB4A7F28F1887B3504647854E sha1 9F2DC591C9B1526F9F965B1C375FB4EA7101FD16 ) + rom ( name "Phantasy Star Collection (USA).gba" size 8388608 crc e5a7fe17 sha1 9F2DC591C9B1526F9F965B1C375FB4EA7101FD16 flags verified ) ) game ( name "Phantasy Star Collection (Europe)" description "Phantasy Star Collection (Europe)" - rom ( name "Phantasy Star Collection (Europe).gba" size 8388608 crc 4D9C671B md5 6C36961DC125F8507C941888640A0272 sha1 8B8B31A2BC023121205F4BB87F20240FC0A98C66 flags verified ) + rom ( name "Phantasy Star Collection (Europe).gba" size 8388608 crc 4d9c671b sha1 8B8B31A2BC023121205F4BB87F20240FC0A98C66 flags verified ) +) + +game ( + name "Phantom, The (Italy) (Proto)" + description "Phantom, The (Italy) (Proto)" + rom ( name "Phantom, The (Italy) (Proto).gba" size 8388608 crc 5833169c sha1 CCD8E9D092A9DED9C3785AC776D40DF66512B9B5 flags verified ) ) game ( name "Phil of the Future (USA)" description "Phil of the Future (USA)" - rom ( name "Phil of the Future (USA).gba" size 8388608 crc E199E132 md5 8DD015022218C0DF89BDD4A1A1FC4E7B sha1 BA123AF9938484CF1E2EA0FD191C75C90078F035 ) + rom ( name "Phil of the Future (USA).gba" size 8388608 crc e199e132 sha1 BA123AF9938484CF1E2EA0FD191C75C90078F035 ) ) game ( name "Pia Carrot e Youkoso!! 3.3 (Japan)" description "Pia Carrot e Youkoso!! 3.3 (Japan)" - rom ( name "Pia Carrot e Youkoso!! 3.3 (Japan).gba" size 8388608 crc 254E6F31 md5 503DF54CE026CB71B6F6665D3EC50074 sha1 4BAFBC7A57851DDD330620E9F448714FFA7ACB3B ) -) - -game ( - name "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl)" - description "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc FF5C9636 md5 E524B9C64A98CDC79CF88CBDEA5EE39A sha1 04000316F19ED5647BB1C87A830D37A29B201687 ) + rom ( name "Pia Carrot e Youkoso!! 3.3 (Japan).gba" size 8388608 crc 254e6f31 sha1 4BAFBC7A57851DDD330620E9F448714FFA7ACB3B ) ) game ( name "Piglet's Big Game (USA)" description "Piglet's Big Game (USA)" - rom ( name "Piglet's Big Game (USA).gba" size 8388608 crc 52919538 md5 7AA675F783554E6734239DF89E2B7CBE sha1 85B3319DFDABFBFCB2EA6B82B0606DDEF2EAB935 flags verified ) + rom ( name "Piglet's Big Game (USA).gba" size 8388608 crc 52919538 sha1 85B3319DFDABFBFCB2EA6B82B0606DDEF2EAB935 flags verified ) +) + +game ( + name "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl)" + description "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Piglet's Big Game (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc ff5c9636 sha1 04000316F19ED5647BB1C87A830D37A29B201687 flags verified ) ) game ( name "Pikapika Nurse Monogatari - Nurse Ikusei Game (Japan)" description "Pikapika Nurse Monogatari - Nurse Ikusei Game (Japan)" - rom ( name "Pikapika Nurse Monogatari - Nurse Ikusei Game (Japan).gba" size 4194304 crc 80A081FE md5 CB04B88ECD0ADFE5690FA75A551DCD74 sha1 58B8D9468FD43E876D234491B2BF1A6775D95D23 ) + rom ( name "Pikapika Nurse Monogatari - Nurse Ikusei Game (Japan).gba" size 4194304 crc 80a081fe sha1 58B8D9468FD43E876D234491B2BF1A6775D95D23 flags verified ) ) game ( name "Pinball Advance (Europe) (En,Fr,De,Es,It)" description "Pinball Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Pinball Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 39479369 md5 1E5F91DB7B8FA135CC3B118A3F8E686C sha1 CFC7F55DBBE2C0AC4096C76AEFB516CB96C69895 ) + rom ( name "Pinball Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 39479369 sha1 CFC7F55DBBE2C0AC4096C76AEFB516CB96C69895 flags verified ) ) game ( name "Pinball Challenge Deluxe (Europe)" description "Pinball Challenge Deluxe (Europe)" - rom ( name "Pinball Challenge Deluxe (Europe).gba" size 4194304 crc BCB204B7 md5 331CE7F78B6A56FA50B9A329B56DA658 sha1 49FF583FB49D13046FAC5B2A11D9BD00C159FA08 ) + rom ( name "Pinball Challenge Deluxe (Europe).gba" size 4194304 crc bcb204b7 sha1 49FF583FB49D13046FAC5B2A11D9BD00C159FA08 ) ) game ( name "Pinball of the Dead, The (USA)" description "Pinball of the Dead, The (USA)" - rom ( name "Pinball of the Dead, The (USA).gba" size 8388608 crc 0A09C517 md5 627B22D7E3C4DBCE8191C7765C58E17A sha1 A685C3E88ABE3A008FD2C721D75BBEC14FBE0401 ) + rom ( name "Pinball of the Dead, The (USA).gba" size 8388608 crc 0a09c517 sha1 A685C3E88ABE3A008FD2C721D75BBEC14FBE0401 ) ) game ( name "Pinball of the Dead, The (Japan)" description "Pinball of the Dead, The (Japan)" - rom ( name "Pinball of the Dead, The (Japan).gba" size 8388608 crc 1A7EFBD0 md5 FD844C83C46C99046204678F60646302 sha1 72E54B0D7B305DEEF719087299A80C763E9DEBDF ) + rom ( name "Pinball of the Dead, The (Japan).gba" size 8388608 crc 1a7efbd0 sha1 72E54B0D7B305DEEF719087299A80C763E9DEBDF ) ) game ( name "Pinball of the Dead, The (Europe) (En,Fr,De,Es,It)" description "Pinball of the Dead, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Pinball of the Dead, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc A9DD7EFA md5 1B6AF74F06AC7982E32F4F9803BA5F7C sha1 CC63FE2263EA43F6AE73D7FA06FC11148657623F ) + rom ( name "Pinball of the Dead, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc a9dd7efa sha1 CC63FE2263EA43F6AE73D7FA06FC11148657623F ) ) game ( name "Pinball Tycoon (USA)" description "Pinball Tycoon (USA)" - rom ( name "Pinball Tycoon (USA).gba" size 4194304 crc 1C4D3FDF md5 E0ADFF6EBE33CD13B57A7041F14599D8 sha1 FAC76A646D112A775F9877B53F1386716D968A79 ) + rom ( name "Pinball Tycoon (USA).gba" size 4194304 crc 1c4d3fdf sha1 FAC76A646D112A775F9877B53F1386716D968A79 ) ) game ( name "Pinball Tycoon (Europe)" description "Pinball Tycoon (Europe)" - rom ( name "Pinball Tycoon (Europe).gba" size 4194304 crc 5D52BE1E md5 4FB2B65A3388A137A681530EC11494E7 sha1 7FE9334B8FA8930393E70732BE8187D00BB95236 ) + rom ( name "Pinball Tycoon (Europe).gba" size 4194304 crc 5d52be1e sha1 7FE9334B8FA8930393E70732BE8187D00BB95236 flags verified ) ) game ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" description "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" - rom ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8859B808 md5 9BF9CD93BF32F6F6661B266E8ADF9F2E sha1 624157219BEF246D484AB4738662E4EB4E7DE308 ) + rom ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 8859b808 sha1 624157219BEF246D484AB4738662E4EB4E7DE308 flags verified ) ) game ( name "Pink Panther - Pinkadelic Pursuit (USA)" description "Pink Panther - Pinkadelic Pursuit (USA)" - rom ( name "Pink Panther - Pinkadelic Pursuit (USA).gba" size 8388608 crc 1762A578 md5 BA7746952E87A2C85927FA691E7230DD sha1 208C1BCF84856F1F2425CDC32ABC10D618FCA71D ) + rom ( name "Pink Panther - Pinkadelic Pursuit (USA).gba" size 8388608 crc 1762a578 sha1 208C1BCF84856F1F2425CDC32ABC10D618FCA71D ) ) game ( - name "Pinky and the Brain - The Masterplan (Europe) (En,Fr,De,Es,It)" - description "Pinky and the Brain - The Masterplan (Europe) (En,Fr,De,Es,It)" - rom ( name "Pinky and the Brain - The Masterplan (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc FF7D5F62 md5 E7C65F9930B6E7580565AD3713C303B1 sha1 05B61E4FE58AE614352F29705FAE9C53393685CB ) + name "Pinky and the Brain - The Master Plan (Europe) (En,Fr,De,Es,It)" + description "Pinky and the Brain - The Master Plan (Europe) (En,Fr,De,Es,It)" + rom ( name "Pinky and the Brain - The Master Plan (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ff7d5f62 sha1 05B61E4FE58AE614352F29705FAE9C53393685CB ) ) game ( name "Pinky Monkey Town (Japan)" description "Pinky Monkey Town (Japan)" - rom ( name "Pinky Monkey Town (Japan).gba" size 4194304 crc 9F75B077 md5 CC73A1BBA4CDA50F818581DB3DD7B661 sha1 39963429361B42438D3BC1106AF0D345F3146B52 ) + rom ( name "Pinky Monkey Town (Japan).gba" size 4194304 crc 9f75b077 sha1 39963429361B42438D3BC1106AF0D345F3146B52 flags verified ) ) game ( name "Pinobee & Phoebee (Japan)" description "Pinobee & Phoebee (Japan)" - rom ( name "Pinobee & Phoebee (Japan).gba" size 8388608 crc E989A4AE md5 39BF2BBB87FB25E3C4DF8475EE527199 sha1 E5CB92C2ADB0B1715CE80D7562B562E527EE2E1F ) + rom ( name "Pinobee & Phoebee (Japan).gba" size 8388608 crc e989a4ae sha1 E5CB92C2ADB0B1715CE80D7562B562E527EE2E1F ) ) game ( name "Pinobee - Wings of Adventure (USA, Europe)" description "Pinobee - Wings of Adventure (USA, Europe)" - rom ( name "Pinobee - Wings of Adventure (USA, Europe).gba" size 8388608 crc D9385207 md5 211AF14AC83A170A0E60FE8D0A48E37E sha1 CB1549B6DD8070770B1A00928EEB7D458309E200 flags verified ) + rom ( name "Pinobee - Wings of Adventure (USA, Europe).gba" size 8388608 crc d9385207 sha1 CB1549B6DD8070770B1A00928EEB7D458309E200 flags verified ) ) game ( name "Pinobee no Daibouken (Japan)" description "Pinobee no Daibouken (Japan)" - rom ( name "Pinobee no Daibouken (Japan).gba" size 8388608 crc FEBF9045 md5 CE194375C105DC51582F47E7435103D0 sha1 BECD5AF773A5607E94288C6BA412A901AF0E0470 ) + rom ( name "Pinobee no Daibouken (Japan).gba" size 8388608 crc febf9045 sha1 BECD5AF773A5607E94288C6BA412A901AF0E0470 ) ) game ( name "Pippa Funnell - Stable Adventure (Europe) (En,Fr)" description "Pippa Funnell - Stable Adventure (Europe) (En,Fr)" - rom ( name "Pippa Funnell - Stable Adventure (Europe) (En,Fr).gba" size 4194304 crc 1C1846C2 md5 8D37B40CCBFED23E7A2B677CED5BDE2F sha1 D48F95CB74D8097C143870CF3026B9426D15E4F8 ) + rom ( name "Pippa Funnell - Stable Adventure (Europe) (En,Fr).gba" size 4194304 crc 1c1846c2 sha1 D48F95CB74D8097C143870CF3026B9426D15E4F8 ) ) game ( name "Pippa Funnell 2 (Europe) (En,Fr)" description "Pippa Funnell 2 (Europe) (En,Fr)" - rom ( name "Pippa Funnell 2 (Europe) (En,Fr).gba" size 4194304 crc F3C274C2 md5 48DF7CDC6444D804CEDF290A6EDD048F sha1 B7FD71D22DA6BDC16B8F780FC8D10587C3DFF41A ) + rom ( name "Pippa Funnell 2 (Europe) (En,Fr).gba" size 4194304 crc f3c274c2 sha1 B7FD71D22DA6BDC16B8F780FC8D10587C3DFF41A ) ) game ( name "Pirates of the Caribbean - Dead Man's Chest (USA, Europe) (En,Fr,De,Es,It)" description "Pirates of the Caribbean - Dead Man's Chest (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Pirates of the Caribbean - Dead Man's Chest (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc D1A67BE8 md5 C13785F8C7F0342D4C96C294E600E338 sha1 3A11C76EDAAD8FA0845B7DA55E8ED26E26E09883 flags verified ) + rom ( name "Pirates of the Caribbean - Dead Man's Chest (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc d1a67be8 sha1 3A11C76EDAAD8FA0845B7DA55E8ED26E26E09883 flags verified ) ) game ( name "Pirates of the Caribbean - The Curse of the Black Pearl (USA) (En,Fr,De,Es,It)" description "Pirates of the Caribbean - The Curse of the Black Pearl (USA) (En,Fr,De,Es,It)" - rom ( name "Pirates of the Caribbean - The Curse of the Black Pearl (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 8F15BF4C md5 FC393954C63FA0E82CCFD7334491C2A7 sha1 034E5206C3ED8275E4BBB249EDF305D14948BF8F ) + rom ( name "Pirates of the Caribbean - The Curse of the Black Pearl (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 8f15bf4c sha1 034E5206C3ED8275E4BBB249EDF305D14948BF8F ) ) game ( name "Pirates of the Caribbean - The Curse of the Black Pearl (Europe) (En,Fr,De,Es,It)" description "Pirates of the Caribbean - The Curse of the Black Pearl (Europe) (En,Fr,De,Es,It)" - rom ( name "Pirates of the Caribbean - The Curse of the Black Pearl (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2DF9D7F0 md5 DEF28C154A93987DF372F1000A1584F2 sha1 A91F0843E310A169BBE39DCE208F98535A735C2B ) + rom ( name "Pirates of the Caribbean - The Curse of the Black Pearl (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2df9d7f0 sha1 A91F0843E310A169BBE39DCE208F98535A735C2B ) ) game ( name "Pitfall - L'Expedition Perdue (France)" description "Pitfall - L'Expedition Perdue (France)" - rom ( name "Pitfall - L'Expedition Perdue (France).gba" size 8388608 crc 846F43F3 md5 69C1871AD475586884F8F438C8FDFA68 sha1 2203F307115653805BAEDB7285C07624BC12EB76 ) + rom ( name "Pitfall - L'Expedition Perdue (France).gba" size 8388608 crc 846f43f3 sha1 2203F307115653805BAEDB7285C07624BC12EB76 ) ) game ( name "Pitfall - The Lost Expedition (Europe)" description "Pitfall - The Lost Expedition (Europe)" - rom ( name "Pitfall - The Lost Expedition (Europe).gba" size 8388608 crc DC6512D6 md5 4D424166FAB5FE230B46793F8659E8A5 sha1 29285189FB416332A042DD108D8F26FF7A6E49B2 ) + rom ( name "Pitfall - The Lost Expedition (Europe).gba" size 8388608 crc dc6512d6 sha1 29285189FB416332A042DD108D8F26FF7A6E49B2 ) ) game ( name "Pitfall - The Lost Expedition (USA)" description "Pitfall - The Lost Expedition (USA)" - rom ( name "Pitfall - The Lost Expedition (USA).gba" size 8388608 crc 5C11DC26 md5 E1B65755D37A64D3AB7605D5DAC86B56 sha1 EDB205A04E694786F8159AC99FB4BFD72E34E4E3 ) + rom ( name "Pitfall - The Lost Expedition (USA).gba" size 8388608 crc 5c11dc26 sha1 EDB205A04E694786F8159AC99FB4BFD72E34E4E3 ) ) game ( name "Pitfall - The Mayan Adventure (USA, Europe)" description "Pitfall - The Mayan Adventure (USA, Europe)" - rom ( name "Pitfall - The Mayan Adventure (USA, Europe).gba" size 4194304 crc 2CEDBB31 md5 D307133FF4A778517AB0C00B8CA9379A sha1 0DE39E1CF6B199721069E8750E94ABCCC2E4B97D flags verified ) + rom ( name "Pitfall - The Mayan Adventure (USA, Europe).gba" size 4194304 crc 2cedbb31 sha1 0DE39E1CF6B199721069E8750E94ABCCC2E4B97D flags verified ) ) game ( name "Pixeline i Pixieland (Denmark)" description "Pixeline i Pixieland (Denmark)" - rom ( name "Pixeline i Pixieland (Denmark).gba" size 8388608 crc 20B72D17 md5 BE2CC5F427F01CBE18F630C5B4E4D7C7 sha1 88E2F17D109841E5DE6EBEE54B51A1BAB559F451 ) + rom ( name "Pixeline i Pixieland (Denmark).gba" size 8388608 crc 20b72d17 sha1 88E2F17D109841E5DE6EBEE54B51A1BAB559F451 ) ) game ( name "Planet Monsters (USA) (En,Fr,De,Es,It,Nl)" description "Planet Monsters (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet Monsters (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 9B182354 md5 385DC0869879128BEFC52C0B30FF03FF sha1 8F130BD74644A36F3CF28AA8566FA21700D371DF ) + rom ( name "Planet Monsters (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 9b182354 sha1 8F130BD74644A36F3CF28AA8566FA21700D371DF ) ) game ( name "Planet Monsters (Europe) (En,Fr,De,Es,It,Nl)" description "Planet Monsters (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet Monsters (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc D4D77BCE md5 8F254384C3B1AA8FF118B4782D089267 sha1 2999D28F3950C1DE0B82204A5F79601E63ECBE4E ) + rom ( name "Planet Monsters (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc d4d77bce sha1 2999D28F3950C1DE0B82204A5F79601E63ECBE4E ) ) game ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl)" description "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 6E378BF3 md5 18A0F7CFE44DE29FEFF9EFB2F18634F9 sha1 CA706341DAB90C4998E9EB7871650075A0036C29 flags verified ) + rom ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 6e378bf3 sha1 CA706341DAB90C4998E9EB7871650075A0036C29 flags verified ) ) game ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl)" description "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc A0F0269B md5 23A5CF12DDA1BD5EF4D3E03FA6112C19 sha1 574A047AB79431E05E716DB2688A3A012A6BC85D ) + rom ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc a0f0269b sha1 574A047AB79431E05E716DB2688A3A012A6BC85D ) ) game ( name "Play Novel - Silent Hill (Japan)" description "Play Novel - Silent Hill (Japan)" - rom ( name "Play Novel - Silent Hill (Japan).gba" size 8388608 crc 318A1E9B md5 DF9BD674970714489629E97A8BCD32F7 sha1 04F5F6F796672501AE05C879A77ADC73F5A7EDE7 ) + rom ( name "Play Novel - Silent Hill (Japan).gba" size 8388608 crc 318a1e9b sha1 04F5F6F796672501AE05C879A77ADC73F5A7EDE7 ) ) game ( name "Play-Yan (Japan)" description "Play-Yan (Japan)" - rom ( name "Play-Yan (Japan).gba" size 4194304 crc BA997CFA md5 669D72D84CD0BBC820C6D0640759CFC8 sha1 B950F9B1E5EAA81B653BE6DA5CDD7A1BF1E548E6 flags verified ) + rom ( name "Play-Yan (Japan).gba" size 4194304 crc ba997cfa sha1 B950F9B1E5EAA81B653BE6DA5CDD7A1BF1E548E6 flags verified ) ) game ( name "Play-Yan Micro (Japan)" description "Play-Yan Micro (Japan)" - rom ( name "Play-Yan Micro (Japan).gba" size 4194304 crc E24F6A15 md5 4073A47136F2CE4F2AB6D53A16EB75FB sha1 41A0C7C7AC492ECF94A4270099C5371B851377C4 ) + rom ( name "Play-Yan Micro (Japan).gba" size 4194304 crc e24f6a15 sha1 41A0C7C7AC492ECF94A4270099C5371B851377C4 ) ) game ( name "Pocket Dogs (USA)" description "Pocket Dogs (USA)" - rom ( name "Pocket Dogs (USA).gba" size 8388608 crc BEDDC67F md5 480117B99FF0CE0934D5F4E3B5A952B4 sha1 79A90B119EA84C5812575D20BA6107BE7EDBFEE7 ) + rom ( name "Pocket Dogs (USA).gba" size 8388608 crc beddc67f sha1 79A90B119EA84C5812575D20BA6107BE7EDBFEE7 ) ) game ( name "Pocket Monsters - Emerald (Japan)" description "Pocket Monsters - Emerald (Japan)" - rom ( name "Pocket Monsters - Emerald (Japan).gba" size 16777216 crc 4881F3F8 md5 92EECF93F1AB828BDF2A83DADDACF3E5 sha1 D7CF8F156BA9C455D164E1EA780A6BF1945465C2 flags verified ) + rom ( name "Pocket Monsters - Emerald (Japan).gba" size 16777216 crc 4881f3f8 sha1 D7CF8F156BA9C455D164E1EA780A6BF1945465C2 flags verified ) ) game ( name "Pocket Monsters - FireRed (Japan)" description "Pocket Monsters - FireRed (Japan)" - rom ( name "Pocket Monsters - FireRed (Japan).gba" size 16777216 crc 3B2056E9 md5 47596DB5A16556C60027E7BF372EC917 sha1 04139887B6CD8F53269ACA098295B006DDBA6CFE flags verified ) + rom ( name "Pocket Monsters - FireRed (Japan).gba" size 16777216 crc 3b2056e9 sha1 04139887B6CD8F53269ACA098295B006DDBA6CFE flags verified ) ) game ( name "Pocket Monsters - FireRed (Japan) (Rev 1)" description "Pocket Monsters - FireRed (Japan) (Rev 1)" - rom ( name "Pocket Monsters - FireRed (Japan) (Rev 1).gba" size 16777216 crc BB640DF7 md5 FF25067B591BA324CD44689A9BA8AA48 sha1 7C7107B87C3CCF6E3DBCEB9CF80CEEFFB25A1857 ) + rom ( name "Pocket Monsters - FireRed (Japan) (Rev 1).gba" size 16777216 crc bb640df7 sha1 7C7107B87C3CCF6E3DBCEB9CF80CEEFFB25A1857 ) ) game ( name "Pocket Monsters - LeafGreen (Japan)" description "Pocket Monsters - LeafGreen (Japan)" - rom ( name "Pocket Monsters - LeafGreen (Japan).gba" size 16777216 crc 0A48556B md5 138A71A5BE83F3F3D7AF3D31916A5FC7 sha1 5946F1B59E8D71CC61249661464D864185C92A5F flags verified ) + rom ( name "Pocket Monsters - LeafGreen (Japan).gba" size 16777216 crc 0a48556b sha1 5946F1B59E8D71CC61249661464D864185C92A5F flags verified ) +) + +game ( + name "Pocket Monsters - LeafGreen (Japan) (Rev 1)" + description "Pocket Monsters - LeafGreen (Japan) (Rev 1)" + rom ( name "Pocket Monsters - LeafGreen (Japan) (Rev 1).gba" size 16777216 crc 8da4601a sha1 DE9D5A844F9BFB63A4448CCCD4A2D186ECF455C3 flags verified ) ) game ( name "Pocket Monsters - Ruby (Japan)" description "Pocket Monsters - Ruby (Japan)" - rom ( name "Pocket Monsters - Ruby (Japan).gba" size 8388608 crc CEE9471A md5 27C9F37193977828F9808F3F76FF8C76 sha1 5C5E546720300B99AE45D2AA35C646C8B8FF5C56 flags verified ) + rom ( name "Pocket Monsters - Ruby (Japan).gba" size 8388608 crc cee9471a sha1 5C5E546720300B99AE45D2AA35C646C8B8FF5C56 flags verified ) ) game ( name "Pocket Monsters - Sapphire (Japan)" description "Pocket Monsters - Sapphire (Japan)" - rom ( name "Pocket Monsters - Sapphire (Japan).gba" size 8388608 crc FD1EEB78 md5 5323F95F70F5D4F21BED6EC000332BDA sha1 3233342C2F3087E6FFE6C1791CD5867DB07DF842 flags verified ) + rom ( name "Pocket Monsters - Sapphire (Japan).gba" size 8388608 crc fd1eeb78 sha1 3233342C2F3087E6FFE6C1791CD5867DB07DF842 flags verified ) ) game ( name "Pocket Music (Europe) (En,Fr,De,Es,It)" description "Pocket Music (Europe) (En,Fr,De,Es,It)" - rom ( name "Pocket Music (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc A3FD418A md5 50F42C3690D985026252F3A90CC87517 sha1 3484CA53D9BEE6CF258DF44C8825E18E128A2821 flags verified ) + rom ( name "Pocket Music (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc a3fd418a sha1 3484CA53D9BEE6CF258DF44C8825E18E128A2821 flags verified ) ) game ( - name "Pocket Professor - Kwik Notes - Vol. 1 (USA)" - description "Pocket Professor - Kwik Notes - Vol. 1 (USA)" - rom ( name "Pocket Professor - Kwik Notes - Vol. 1 (USA).gba" size 4194304 crc 07B824B1 md5 8A0577DFEA5FDB41B8B8C0554AC877C8 sha1 237709303A93F7CBA9321A0A4464F4A7CA3AB796 ) + name "Pocket Professor - Kwik Notes - Volume One (USA)" + description "Pocket Professor - Kwik Notes - Volume One (USA)" + rom ( name "Pocket Professor - Kwik Notes - Volume One (USA).gba" size 4194304 crc 07b824b1 sha1 237709303A93F7CBA9321A0A4464F4A7CA3AB796 ) ) game ( name "Pocky & Rocky with Becky (USA)" description "Pocky & Rocky with Becky (USA)" - rom ( name "Pocky & Rocky with Becky (USA).gba" size 4194304 crc 53A8EE86 md5 0F796B33898E0F7C3B001136E6A1C28B sha1 B24C3E299622EA7E249CFDAAA06146B5276834E9 ) + rom ( name "Pocky & Rocky with Becky (USA).gba" size 4194304 crc 53a8ee86 sha1 B24C3E299622EA7E249CFDAAA06146B5276834E9 flags verified ) ) game ( name "Poke Inu (Japan)" description "Poke Inu (Japan)" - rom ( name "Poke Inu (Japan).gba" size 8388608 crc 1D379DCC md5 B468236A140DA4EE89286878A0964E9F sha1 094FD4CC7D176BCB32E6ED4D667C4C9D3C354C92 ) + rom ( name "Poke Inu (Japan).gba" size 8388608 crc 1d379dcc sha1 094FD4CC7D176BCB32E6ED4D667C4C9D3C354C92 ) +) + +game ( + name "Pokemon - 10th Anniversary Distribution (Europe)" + description "Pokemon - 10th Anniversary Distribution (Europe)" + rom ( name "Pokemon - 10th Anniversary Distribution (Europe).gba" size 4194304 crc de1ad834 sha1 1E47989071DA83F250FAB6C20CABA96E5D15A732 flags verified ) +) + +game ( + name "Pokemon - Aura Mew Distribution (Europe)" + description "Pokemon - Aura Mew Distribution (Europe)" + rom ( name "Pokemon - Aura Mew Distribution (Europe).gba" size 4194304 crc 2912e76e sha1 DE5637F89AEB5D2D5F82B863F48BB0AB23E51715 ) +) + +game ( + name "Pokemon - Aurora Ticket Distribution (USA)" + description "Pokemon - Aurora Ticket Distribution (USA)" + rom ( name "Pokemon - Aurora Ticket Distribution (USA).gba" size 4194304 crc b1f7c41b sha1 7457980320775F69E75DE5BBB8357C88F7C752C8 flags verified ) ) game ( name "Pokemon - Blattgruene Edition (Germany)" description "Pokemon - Blattgruene Edition (Germany)" - rom ( name "Pokemon - Blattgruene Edition (Germany).gba" size 16777216 crc D12F1FDD md5 4DD5E72F942A921D3FE53D21A39F4CBA sha1 0802D1FB185EE3ED48D9A22AFB25E66424076DAC flags verified ) + rom ( name "Pokemon - Blattgruene Edition (Germany).gba" size 16777216 crc d12f1fdd sha1 0802D1FB185EE3ED48D9A22AFB25E66424076DAC flags verified ) ) game ( name "Pokemon - Edicion Esmeralda (Spain)" description "Pokemon - Edicion Esmeralda (Spain)" - rom ( name "Pokemon - Edicion Esmeralda (Spain).gba" size 16777216 crc 8C4D3108 md5 67B770405F7B87589E0342513B25FE9B sha1 FE1558A3DCB0360AB558969E09B690888B846DD9 flags verified ) + rom ( name "Pokemon - Edicion Esmeralda (Spain).gba" size 16777216 crc 8c4d3108 sha1 FE1558A3DCB0360AB558969E09B690888B846DD9 flags verified ) ) game ( name "Pokemon - Edicion Rojo Fuego (Spain)" description "Pokemon - Edicion Rojo Fuego (Spain)" - rom ( name "Pokemon - Edicion Rojo Fuego (Spain).gba" size 16777216 crc 9F08064E md5 C629272C5E0111930A240623B6C239F0 sha1 AB8F6BFE0CCDAF41188CD015C8C74C314D02296A ) + rom ( name "Pokemon - Edicion Rojo Fuego (Spain).gba" size 16777216 crc 9f08064e sha1 AB8F6BFE0CCDAF41188CD015C8C74C314D02296A ) ) game ( name "Pokemon - Edicion Rubi (Spain)" description "Pokemon - Edicion Rubi (Spain)" - rom ( name "Pokemon - Edicion Rubi (Spain).gba" size 16777216 crc EB0729CF md5 E15EFF9DF4CDB078896E7EE894DC98F6 sha1 1F49F7289253DCBFECBC4C5BA3E67AA0652EC83C flags verified ) + rom ( name "Pokemon - Edicion Rubi (Spain).gba" size 16777216 crc eb0729cf sha1 1F49F7289253DCBFECBC4C5BA3E67AA0652EC83C flags verified ) ) game ( name "Pokemon - Edicion Rubi (Spain) (Rev 1)" description "Pokemon - Edicion Rubi (Spain) (Rev 1)" - rom ( name "Pokemon - Edicion Rubi (Spain) (Rev 1).gba" size 16777216 crc B980FFF5 md5 61623A55AC0FF4CB97DB7C9A78A477AD sha1 9AC73481D7F5D150A018309BBA91D185CE99FB7C ) + rom ( name "Pokemon - Edicion Rubi (Spain) (Rev 1).gba" size 16777216 crc b980fff5 sha1 9AC73481D7F5D150A018309BBA91D185CE99FB7C flags verified ) ) game ( name "Pokemon - Edicion Verde Hoja (Spain)" description "Pokemon - Edicion Verde Hoja (Spain)" - rom ( name "Pokemon - Edicion Verde Hoja (Spain).gba" size 16777216 crc 2CA11D59 md5 765178ED4D402033EF7ED6B82D059F5A sha1 F9EBEE5D228CB695F18EF2CED41630A09FA9EB05 ) + rom ( name "Pokemon - Edicion Verde Hoja (Spain).gba" size 16777216 crc 2ca11d59 sha1 F9EBEE5D228CB695F18EF2CED41630A09FA9EB05 flags verified ) ) game ( name "Pokemon - Edicion Zafiro (Spain)" description "Pokemon - Edicion Zafiro (Spain)" - rom ( name "Pokemon - Edicion Zafiro (Spain).gba" size 16777216 crc A04F5F0B md5 CC87721BB3DFA680F15E875EDCF0B4DD sha1 3A6489189E581C4B29914071B79207883B8C16D8 ) + rom ( name "Pokemon - Edicion Zafiro (Spain).gba" size 16777216 crc a04f5f0b sha1 3A6489189E581C4B29914071B79207883B8C16D8 flags verified ) ) game ( name "Pokemon - Edicion Zafiro (Spain) (Rev 1)" description "Pokemon - Edicion Zafiro (Spain) (Rev 1)" - rom ( name "Pokemon - Edicion Zafiro (Spain) (Rev 1).gba" size 16777216 crc F2C88931 md5 A40E90F68309AD1FD0B9EFE33DCC6BA8 sha1 0FE9AD1E602E2FAFA090AEE25E43D6980625173C ) + rom ( name "Pokemon - Edicion Zafiro (Spain) (Rev 1).gba" size 16777216 crc f2c88931 sha1 0FE9AD1E602E2FAFA090AEE25E43D6980625173C ) ) game ( name "Pokemon - Emerald Version (USA, Europe)" description "Pokemon - Emerald Version (USA, Europe)" - rom ( name "Pokemon - Emerald Version (USA, Europe).gba" size 16777216 crc 1F1C08FB md5 605B89B67018ABCEA91E693A4DD25BE3 sha1 F3AE088181BF583E55DAF962A92BB46F4F1D07B7 flags verified ) + rom ( name "Pokemon - Emerald Version (USA, Europe).gba" size 16777216 crc 1f1c08fb sha1 F3AE088181BF583E55DAF962A92BB46F4F1D07B7 flags verified ) ) game ( name "Pokemon - Feuerrote Edition (Germany)" description "Pokemon - Feuerrote Edition (Germany)" - rom ( name "Pokemon - Feuerrote Edition (Germany).gba" size 16777216 crc 1A81EEDF md5 6648A0484A56097CA75D6AF87EBCE225 sha1 18A3758CEEEF2C77B315144BE2C3910D6F1F69FE flags verified ) + rom ( name "Pokemon - Feuerrote Edition (Germany).gba" size 16777216 crc 1a81eedf sha1 18A3758CEEEF2C77B315144BE2C3910D6F1F69FE flags verified ) ) game ( name "Pokemon - FireRed Version (USA)" description "Pokemon - FireRed Version (USA)" - rom ( name "Pokemon - FireRed Version (USA).gba" size 16777216 crc DD88761C md5 E26EE0D44E809351C8CE2D73C7400CDD sha1 41CB23D8DCCC8EBD7C649CD8FBB58EEACE6E2FDC ) + rom ( name "Pokemon - FireRed Version (USA).gba" size 16777216 crc dd88761c sha1 41CB23D8DCCC8EBD7C649CD8FBB58EEACE6E2FDC ) ) game ( name "Pokemon - FireRed Version (USA, Europe) (Rev 1)" description "Pokemon - FireRed Version (USA, Europe) (Rev 1)" - rom ( name "Pokemon - FireRed Version (USA, Europe) (Rev 1).gba" size 16777216 crc 84EE4776 md5 51901A6E40661B3914AA333C802E24E8 sha1 DD5945DB9B930750CB39D00C84DA8571FEEBF417 flags verified ) + rom ( name "Pokemon - FireRed Version (USA, Europe) (Rev 1).gba" size 16777216 crc 84ee4776 sha1 DD5945DB9B930750CB39D00C84DA8571FEEBF417 flags verified ) ) game ( name "Pokemon - LeafGreen Version (USA)" description "Pokemon - LeafGreen Version (USA)" - rom ( name "Pokemon - LeafGreen Version (USA).gba" size 16777216 crc D69C96CC md5 612CA9473451FA42B51D1711031ED5F6 sha1 574FA542FFEBB14BE69902D1D36F1EC0A4AFD71E flags verified ) + rom ( name "Pokemon - LeafGreen Version (USA).gba" size 16777216 crc d69c96cc sha1 574FA542FFEBB14BE69902D1D36F1EC0A4AFD71E flags verified ) ) game ( name "Pokemon - LeafGreen Version (USA, Europe) (Rev 1)" description "Pokemon - LeafGreen Version (USA, Europe) (Rev 1)" - rom ( name "Pokemon - LeafGreen Version (USA, Europe) (Rev 1).gba" size 16777216 crc DAFFECEC md5 9D33A02159E018D09073E700E1FD10FD sha1 7862C67BDECBE21D1D69CE082CE34327E1C6ED5E flags verified ) + rom ( name "Pokemon - LeafGreen Version (USA, Europe) (Rev 1).gba" size 16777216 crc daffecec sha1 7862C67BDECBE21D1D69CE082CE34327E1C6ED5E flags verified ) +) + +game ( + name "Pokemon - Liechi Berry Glitch Fix & Shiny Zigzagoon Distribution (Europe)" + description "Pokemon - Liechi Berry Glitch Fix & Shiny Zigzagoon Distribution (Europe)" + rom ( name "Pokemon - Liechi Berry Glitch Fix & Shiny Zigzagoon Distribution (Europe).gba" size 4194304 crc 13aa8b70 sha1 9DEDAE5BC6EDAFDAF61056ACF3AEDBFFECB837DC flags verified ) ) game ( name "Pokemon - Rubin-Edition (Germany)" description "Pokemon - Rubin-Edition (Germany)" - rom ( name "Pokemon - Rubin-Edition (Germany).gba" size 16777216 crc 15E1E280 md5 1AF28EA547D4116DC752C93F7F694239 sha1 1C2A53332382E14DAB8815E3A6DD81AD89534050 flags verified ) + rom ( name "Pokemon - Rubin-Edition (Germany).gba" size 16777216 crc 15e1e280 sha1 1C2A53332382E14DAB8815E3A6DD81AD89534050 flags verified ) ) game ( name "Pokemon - Rubin-Edition (Germany) (Rev 1)" description "Pokemon - Rubin-Edition (Germany) (Rev 1)" - rom ( name "Pokemon - Rubin-Edition (Germany) (Rev 1).gba" size 16777216 crc CAE89464 md5 9AA6AC6FD369A686373A2E1BF8BB6AA3 sha1 424740BE1FC67A5DDB954794443646E6AEEE2C1B ) + rom ( name "Pokemon - Rubin-Edition (Germany) (Rev 1).gba" size 16777216 crc cae89464 sha1 424740BE1FC67A5DDB954794443646E6AEEE2C1B ) ) game ( name "Pokemon - Rubin-Edition (Germany) (Debug Version)" description "Pokemon - Rubin-Edition (Germany) (Debug Version)" - rom ( name "Pokemon - Rubin-Edition (Germany) (Debug Version).gba" size 16777216 crc 40686C47 md5 A93C24B102F9FFBD5676E18F2E4CB33C sha1 CA5E3D415C4B47353A73A616878BA833F3648B7A ) -) - -game ( - name "Pokemon - Ruby Version (Europe) (Rev 1)" - description "Pokemon - Ruby Version (Europe) (Rev 1)" - rom ( name "Pokemon - Ruby Version (Europe) (Rev 1).gba" size 16777216 crc 61641576 md5 E0503182A2E699678BCF25A6897A24D6 sha1 610B96A9C9A7D03D2BAFB655E7560CCFF1A6D894 flags verified ) -) - -game ( - name "Pokemon - Ruby Version (USA, Europe) (Rev 2)" - description "Pokemon - Ruby Version (USA, Europe) (Rev 2)" - rom ( name "Pokemon - Ruby Version (USA, Europe) (Rev 2).gba" size 16777216 crc AEAC73E6 md5 3E1B2065B3837C14FFBD03FE205FDFD7 sha1 5B64EACF892920518DB4EC664E62A086DD5F5BC8 ) + rom ( name "Pokemon - Rubin-Edition (Germany) (Debug Version).gba" size 16777216 crc 40686c47 sha1 CA5E3D415C4B47353A73A616878BA833F3648B7A flags verified ) ) game ( name "Pokemon - Ruby Version (USA)" description "Pokemon - Ruby Version (USA)" - rom ( name "Pokemon - Ruby Version (USA).gba" size 16777216 crc F0815EE7 md5 53D1A2027AB49DF34A689FAA1FB14726 sha1 F28B6FFC97847E94A6C21A63CACF633EE5C8DF1E flags verified ) + rom ( name "Pokemon - Ruby Version (USA).gba" size 16777216 crc f0815ee7 sha1 F28B6FFC97847E94A6C21A63CACF633EE5C8DF1E flags verified ) +) + +game ( + name "Pokemon - Ruby Version (USA, Europe) (Rev 1)" + description "Pokemon - Ruby Version (USA, Europe) (Rev 1)" + rom ( name "Pokemon - Ruby Version (USA, Europe) (Rev 1).gba" size 16777216 crc 61641576 sha1 610B96A9C9A7D03D2BAFB655E7560CCFF1A6D894 flags verified ) +) + +game ( + name "Pokemon - Ruby Version (USA, Europe) (Rev 2)" + description "Pokemon - Ruby Version (USA, Europe) (Rev 2)" + rom ( name "Pokemon - Ruby Version (USA, Europe) (Rev 2).gba" size 16777216 crc aeac73e6 sha1 5B64EACF892920518DB4EC664E62A086DD5F5BC8 flags verified ) ) game ( name "Pokemon - Saphir-Edition (Germany)" description "Pokemon - Saphir-Edition (Germany)" - rom ( name "Pokemon - Saphir-Edition (Germany).gba" size 16777216 crc 6FCD7A98 md5 43906C58AFAF0760F62EC698EF10EAFC sha1 5A087835009D552D4C5C1F96BE3BE3206E378153 flags verified ) + rom ( name "Pokemon - Saphir-Edition (Germany).gba" size 16777216 crc 6fcd7a98 sha1 5A087835009D552D4C5C1F96BE3BE3206E378153 flags verified ) ) game ( name "Pokemon - Saphir-Edition (Germany) (Rev 1)" description "Pokemon - Saphir-Edition (Germany) (Rev 1)" - rom ( name "Pokemon - Saphir-Edition (Germany) (Rev 1).gba" size 16777216 crc B0C40C7C md5 9D816B369343D39B94AF9A8B0CE7F63B sha1 7E6E034F9CDCA6D2C4A270FDB50A94DEF5883D17 ) -) - -game ( - name "Pokemon - Sapphire Version (Europe) (Rev 1)" - description "Pokemon - Sapphire Version (Europe) (Rev 1)" - rom ( name "Pokemon - Sapphire Version (Europe) (Rev 1).gba" size 16777216 crc BAFEDAE5 md5 3A32FD98B065283D09EEBA1CE0542888 sha1 4722EFB8CD45772CA32555B98FD3B9719F8E60A9 flags verified ) -) - -game ( - name "Pokemon - Sapphire Version (USA, Europe) (Rev 2)" - description "Pokemon - Sapphire Version (USA, Europe) (Rev 2)" - rom ( name "Pokemon - Sapphire Version (USA, Europe) (Rev 2).gba" size 16777216 crc 9CC4410E md5 9BC2B765CA6997175FAC51E6CDC29089 sha1 89B45FB172E6B55D51FC0E61989775187F6FE63C ) + rom ( name "Pokemon - Saphir-Edition (Germany) (Rev 1).gba" size 16777216 crc b0c40c7c sha1 7E6E034F9CDCA6D2C4A270FDB50A94DEF5883D17 ) ) game ( name "Pokemon - Sapphire Version (USA)" description "Pokemon - Sapphire Version (USA)" - rom ( name "Pokemon - Sapphire Version (USA).gba" size 16777216 crc 554DEDC4 md5 F34E91399C719812E66E2C828A2E93D7 sha1 3CCBBD45F8553C36463F13B938E833F652B793E4 ) + rom ( name "Pokemon - Sapphire Version (USA).gba" size 16777216 crc 554dedc4 sha1 3CCBBD45F8553C36463F13B938E833F652B793E4 ) +) + +game ( + name "Pokemon - Sapphire Version (USA, Europe) (Rev 1)" + description "Pokemon - Sapphire Version (USA, Europe) (Rev 1)" + rom ( name "Pokemon - Sapphire Version (USA, Europe) (Rev 1).gba" size 16777216 crc bafedae5 sha1 4722EFB8CD45772CA32555B98FD3B9719F8E60A9 flags verified ) +) + +game ( + name "Pokemon - Sapphire Version (USA, Europe) (Rev 2)" + description "Pokemon - Sapphire Version (USA, Europe) (Rev 2)" + rom ( name "Pokemon - Sapphire Version (USA, Europe) (Rev 2).gba" size 16777216 crc 9cc4410e sha1 89B45FB172E6B55D51FC0E61989775187F6FE63C flags verified ) +) + +game ( + name "Pokemon - Slot 2 Distribution (Japan) (Unreleased)" + description "Pokemon - Slot 2 Distribution (Japan) (Unreleased)" + rom ( name "Pokemon - Slot 2 Distribution (Japan) (Unreleased).gba" size 1065216 crc e4d657eb sha1 057B15E50EF70599FB3CC4F2D9A296831576D695 flags verified ) ) game ( name "Pokemon - Smaragd-Edition (Germany)" description "Pokemon - Smaragd-Edition (Germany)" - rom ( name "Pokemon - Smaragd-Edition (Germany).gba" size 16777216 crc 34C9DF89 md5 F793A854654B467211FC32C4062CB183 sha1 61C2EB2B380B1A75F0C94B767A2D4C26CD7CE4E3 ) + rom ( name "Pokemon - Smaragd-Edition (Germany).gba" size 16777216 crc 34c9df89 sha1 61C2EB2B380B1A75F0C94B767A2D4C26CD7CE4E3 flags verified ) ) game ( name "Pokemon - Version Emeraude (France)" description "Pokemon - Version Emeraude (France)" - rom ( name "Pokemon - Version Emeraude (France).gba" size 16777216 crc A3FDCCB1 md5 2C00E335288A96650E34785B5E2A7588 sha1 CA666651374D89CA439007BED54D839EB7BD14D0 ) + rom ( name "Pokemon - Version Emeraude (France).gba" size 16777216 crc a3fdccb1 sha1 CA666651374D89CA439007BED54D839EB7BD14D0 ) ) game ( name "Pokemon - Version Rouge Feu (France)" description "Pokemon - Version Rouge Feu (France)" - rom ( name "Pokemon - Version Rouge Feu (France).gba" size 16777216 crc 5DC668F6 md5 B8663B80EEF5A1E9B41B683AA1234902 sha1 FC663907256F06A3A09E2D6B967BC9AF4919F111 ) + rom ( name "Pokemon - Version Rouge Feu (France).gba" size 16777216 crc 5dc668f6 sha1 FC663907256F06A3A09E2D6B967BC9AF4919F111 flags verified ) ) game ( name "Pokemon - Version Rubis (France)" description "Pokemon - Version Rubis (France)" - rom ( name "Pokemon - Version Rubis (France).gba" size 16777216 crc 690FD310 md5 3C971EA747A4BBDBD305C6F85C1C99FF sha1 A6EE94202BEC0641C55D242757E84DC89336D4CB ) + rom ( name "Pokemon - Version Rubis (France).gba" size 16777216 crc 690fd310 sha1 A6EE94202BEC0641C55D242757E84DC89336D4CB ) ) game ( name "Pokemon - Version Rubis (France) (Rev 1)" description "Pokemon - Version Rubis (France) (Rev 1)" - rom ( name "Pokemon - Version Rubis (France) (Rev 1).gba" size 16777216 crc 9F981F72 md5 C014449536D7D32E5B6A3B91D10C0FE9 sha1 BA888DFBA231A231CBD60FE228E894B54FB1ED79 ) + rom ( name "Pokemon - Version Rubis (France) (Rev 1).gba" size 16777216 crc 9f981f72 sha1 BA888DFBA231A231CBD60FE228E894B54FB1ED79 ) ) game ( name "Pokemon - Version Saphir (France)" description "Pokemon - Version Saphir (France)" - rom ( name "Pokemon - Version Saphir (France).gba" size 16777216 crc 3581A05F md5 2E6E9E3B87F99F04A1AC44B01BFA6ECD sha1 C269B5692B2D0E5800BA1DDF117FDA95AC648634 ) + rom ( name "Pokemon - Version Saphir (France).gba" size 16777216 crc 3581a05f sha1 C269B5692B2D0E5800BA1DDF117FDA95AC648634 ) ) game ( name "Pokemon - Version Saphir (France) (Rev 1)" description "Pokemon - Version Saphir (France) (Rev 1)" - rom ( name "Pokemon - Version Saphir (France) (Rev 1).gba" size 16777216 crc 2AE49146 md5 C59C79D8BFACD27A1C3FAFDA2BD801D0 sha1 860E93F5EA44F4278132F6C1EE5650D07B852FD8 ) + rom ( name "Pokemon - Version Saphir (France) (Rev 1).gba" size 16777216 crc 2ae49146 sha1 860E93F5EA44F4278132F6C1EE5650D07B852FD8 ) ) game ( name "Pokemon - Version Vert Feuille (France)" description "Pokemon - Version Vert Feuille (France)" - rom ( name "Pokemon - Version Vert Feuille (France).gba" size 16777216 crc BA3285E3 md5 C5BC831107F459816508B45D9392AFC9 sha1 4B5758C14D0A07B70EF3EF0BD7FA5E7CE6978672 ) + rom ( name "Pokemon - Version Vert Feuille (France).gba" size 16777216 crc ba3285e3 sha1 4B5758C14D0A07B70EF3EF0BD7FA5E7CE6978672 ) ) game ( name "Pokemon - Versione Rosso Fuoco (Italy)" description "Pokemon - Versione Rosso Fuoco (Italy)" - rom ( name "Pokemon - Versione Rosso Fuoco (Italy).gba" size 16777216 crc 73A72167 md5 FCE3C39E7BA452EDDB2279B454B66416 sha1 66A9D415205321376B4318534C0DCE5F69D28362 ) + rom ( name "Pokemon - Versione Rosso Fuoco (Italy).gba" size 16777216 crc 73a72167 sha1 66A9D415205321376B4318534C0DCE5F69D28362 flags verified ) ) game ( name "Pokemon - Versione Rubino (Italy)" description "Pokemon - Versione Rubino (Italy)" - rom ( name "Pokemon - Versione Rubino (Italy).gba" size 16777216 crc C18231A9 md5 4D3E531ABCBBE530C0543C91D1D7D63F sha1 2B3134224392F58DA00F802FAA1BF4B5CF6270BE ) + rom ( name "Pokemon - Versione Rubino (Italy).gba" size 16777216 crc c18231a9 sha1 2B3134224392F58DA00F802FAA1BF4B5CF6270BE flags verified ) ) game ( name "Pokemon - Versione Rubino (Italy) (Rev 1)" description "Pokemon - Versione Rubino (Italy) (Rev 1)" - rom ( name "Pokemon - Versione Rubino (Italy) (Rev 1).gba" size 16777216 crc 9305E793 md5 1191848184916ADE8DF270FA27D2555F sha1 015A5D380AFE316A2A6FCC561798EBFF9DFB3009 ) + rom ( name "Pokemon - Versione Rubino (Italy) (Rev 1).gba" size 16777216 crc 9305e793 sha1 015A5D380AFE316A2A6FCC561798EBFF9DFB3009 ) ) game ( name "Pokemon - Versione Smeraldo (Italy)" description "Pokemon - Versione Smeraldo (Italy)" - rom ( name "Pokemon - Versione Smeraldo (Italy).gba" size 16777216 crc A0AEC80A md5 C3E85BE7372BBD5E43F6334A565968C1 sha1 1692DB322400C3141C5DE2DB38469913CEB1F4D4 ) + rom ( name "Pokemon - Versione Smeraldo (Italy).gba" size 16777216 crc a0aec80a sha1 1692DB322400C3141C5DE2DB38469913CEB1F4D4 ) ) game ( name "Pokemon - Versione Verde Foglia (Italy)" description "Pokemon - Versione Verde Foglia (Italy)" - rom ( name "Pokemon - Versione Verde Foglia (Italy).gba" size 16777216 crc 16974506 md5 1E52F38082B252E04173EFB340A9286E sha1 A1DFEA1493D26D1F024BE8BA1DE3D193FCFC651E ) + rom ( name "Pokemon - Versione Verde Foglia (Italy).gba" size 16777216 crc 16974506 sha1 A1DFEA1493D26D1F024BE8BA1DE3D193FCFC651E flags verified ) ) game ( name "Pokemon - Versione Zaffiro (Italy)" description "Pokemon - Versione Zaffiro (Italy)" - rom ( name "Pokemon - Versione Zaffiro (Italy).gba" size 16777216 crc 0C7992A9 md5 F42847FA81D5D1CF30D1DD5B64924561 sha1 F729DD571FB2C09E72C5C1D68FE0A21E72713D34 ) + rom ( name "Pokemon - Versione Zaffiro (Italy).gba" size 16777216 crc 0c7992a9 sha1 F729DD571FB2C09E72C5C1D68FE0A21E72713D34 flags verified ) ) game ( name "Pokemon - Versione Zaffiro (Italy) (Rev 1)" description "Pokemon - Versione Zaffiro (Italy) (Rev 1)" - rom ( name "Pokemon - Versione Zaffiro (Italy) (Rev 1).gba" size 16777216 crc 5EFE4493 md5 B075DCF2B63A992E10204B553800FF40 sha1 73EDF67B9B82FF12795622DCA412733755D2C0FE ) + rom ( name "Pokemon - Versione Zaffiro (Italy) (Rev 1).gba" size 16777216 crc 5efe4493 sha1 73EDF67B9B82FF12795622DCA412733755D2C0FE ) ) game ( name "Pokemon Fushigi no Dungeon - Aka no Kyuujotai (Japan)" description "Pokemon Fushigi no Dungeon - Aka no Kyuujotai (Japan)" - rom ( name "Pokemon Fushigi no Dungeon - Aka no Kyuujotai (Japan).gba" size 33554432 crc 1A1BAA50 md5 F3647154D85D20F9C8BA66ED8F0A609E sha1 4BC9370EDEBB3DA5BDF768EECED689FDA3F8B77B flags verified ) + rom ( name "Pokemon Fushigi no Dungeon - Aka no Kyuujotai (Japan).gba" size 33554432 crc 1a1baa50 sha1 4BC9370EDEBB3DA5BDF768EECED689FDA3F8B77B flags verified ) ) game ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)" description "Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia)" - rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia).gba" size 33554432 crc DD0AC86C md5 2100CF6F17E12CD34F1513647DFA506B sha1 9F4CFC5B5F4859D17169A485462E977C7AAC2B89 flags verified ) + rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA, Australia).gba" size 33554432 crc dd0ac86c sha1 9F4CFC5B5F4859D17169A485462E977C7AAC2B89 flags verified ) ) game ( name "Pokemon Mystery Dungeon - Red Rescue Team (Europe) (En,Fr,De,Es,It)" description "Pokemon Mystery Dungeon - Red Rescue Team (Europe) (En,Fr,De,Es,It)" - rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc C1D18FE4 md5 9837DA1FDFE900C52F2109D9718D4E85 sha1 AFEE3B060DD5FD4A68AFB1B003456AEF3A2AF073 flags verified ) + rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc c1d18fe4 sha1 AFEE3B060DD5FD4A68AFB1B003456AEF3A2AF073 flags verified ) ) game ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA) (Demo) (Kiosk)" description "Pokemon Mystery Dungeon - Red Rescue Team (USA) (Demo) (Kiosk)" - rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA) (Demo) (Kiosk).gba" size 16777216 crc F12F908E md5 779A2A4435E0093A7846798270705C76 sha1 AA2AB3352E4BCC5069BB11DB85432825DA61303B ) -) - -game ( - name "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1)" - description "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1)" - rom ( name "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1).gba" size 8388608 crc 925A5684 md5 BE2CA0C6F898C5C453924D69732AABBB sha1 2C7F8BC4CE37043A8F62713038591E861F812499 ) + rom ( name "Pokemon Mystery Dungeon - Red Rescue Team (USA) (Demo) (Kiosk).gba" size 16777216 crc f12f908e sha1 AA2AB3352E4BCC5069BB11DB85432825DA61303B ) ) game ( name "Pokemon Pinball - Ruby & Sapphire (Japan)" description "Pokemon Pinball - Ruby & Sapphire (Japan)" - rom ( name "Pokemon Pinball - Ruby & Sapphire (Japan).gba" size 8388608 crc 8AF1EC73 md5 3CEBD1599FBC2CBEA21BC940445E8F2C sha1 FDD86F127982769941379054EF73CB344DB61AE1 ) + rom ( name "Pokemon Pinball - Ruby & Sapphire (Japan).gba" size 8388608 crc 8af1ec73 sha1 FDD86F127982769941379054EF73CB344DB61AE1 flags verified ) ) game ( name "Pokemon Pinball - Ruby & Sapphire (USA)" description "Pokemon Pinball - Ruby & Sapphire (USA)" - rom ( name "Pokemon Pinball - Ruby & Sapphire (USA).gba" size 8388608 crc B992A3C0 md5 BA6D0FBFF297B8937D3C8E7F2C25FA0F sha1 9FEC81CE2C5DF589E0371A0BF2F92A5FE8DB730B ) + rom ( name "Pokemon Pinball - Ruby & Sapphire (USA).gba" size 8388608 crc b992a3c0 sha1 9FEC81CE2C5DF589E0371A0BF2F92A5FE8DB730B flags verified ) ) game ( name "Pokemon Pinball - Ruby & Sapphire (Europe) (En,Fr,De,Es,It)" description "Pokemon Pinball - Ruby & Sapphire (Europe) (En,Fr,De,Es,It)" - rom ( name "Pokemon Pinball - Ruby & Sapphire (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc A53AC14B md5 98B421421F79E774231B65DF7B1B3C47 sha1 B8B7881EAA9856B5ADA99078AD1053D31CB79827 flags verified ) + rom ( name "Pokemon Pinball - Ruby & Sapphire (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc a53ac14b sha1 B8B7881EAA9856B5ADA99078AD1053D31CB79827 flags verified ) +) + +game ( + name "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1)" + description "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1)" + rom ( name "Pokemon Pinball - Ruby & Sapphire (Japan) (Rev 1).gba" size 8388608 crc 925a5684 sha1 2C7F8BC4CE37043A8F62713038591E861F812499 ) ) game ( name "Polar Express, The (USA, Europe) (En,Fr,De,Es,It)" description "Polar Express, The (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Polar Express, The (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 62CA5620 md5 D325F3B46025EC8DF4A3761CB529E7B8 sha1 A2F940AE658D2527F78A901A2EF5A66929397579 flags verified ) + rom ( name "Polar Express, The (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 62ca5620 sha1 A2F940AE658D2527F78A901A2EF5A66929397579 flags verified ) ) game ( name "Polarium Advance (Europe) (En,Fr,De,Es,It)" description "Polarium Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Polarium Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8F2DEBB8 md5 6B658DF91F3FFC3A97DB7E2BF9753A16 sha1 BE1528581F209F1EE36156DA5BE29E57B5C6CB02 flags verified ) + rom ( name "Polarium Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8f2debb8 sha1 BE1528581F209F1EE36156DA5BE29E57B5C6CB02 flags verified ) ) game ( name "Polarium Advance (USA)" description "Polarium Advance (USA)" - rom ( name "Polarium Advance (USA).gba" size 4194304 crc 02D62CE9 md5 A3E8563F64AE52332C7A7ECEEC73F5FF sha1 7F9ACBBB2977214C86C5130FE8AFE708943C82BA ) + rom ( name "Polarium Advance (USA).gba" size 4194304 crc 02d62ce9 sha1 7F9ACBBB2977214C86C5130FE8AFE708943C82BA ) ) game ( - name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Destination Software)" - description "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Destination Software)" - rom ( name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Destination Software).gba" size 4194304 crc 13E2A64F md5 24BC3D8A0AE721D6BDC745C761422B50 sha1 5D4DEDDC0BCA1043BBC28DE16D10AB427E193622 ) -) - -game ( - name "Polly Pocket! - Super Splash Island (USA) (Destination Software)" - description "Polly Pocket! - Super Splash Island (USA) (Destination Software)" - rom ( name "Polly Pocket! - Super Splash Island (USA) (Destination Software).gba" size 4194304 crc F120ECA2 md5 0D2A4B08C87137212EF39A4C7E9D44CC sha1 333CF7C32E017F25C1674313B15F05C62676335B ) + name "Polarium Advance (USA) (Wii U Virtual Console)" + description "Polarium Advance (USA) (Wii U Virtual Console)" + rom ( name "Polarium Advance (USA) (Wii U Virtual Console).gba" size 4194304 crc d2d36c5f sha1 EB300D18AEF0F9C5E55CD5D7AC0F3BD402F7DC47 flags verified ) ) game ( name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Vivendi)" description "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Vivendi)" - rom ( name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Vivendi).gba" size 4194304 crc A654CBA9 md5 FB55CC8AE270AA9A18871602D3AE36CC sha1 3A9DD9DCDC3B0F6D64B5241C970EC2BBAC25A951 ) + rom ( name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (Vivendi).gba" size 4194304 crc a654cba9 sha1 3A9DD9DCDC3B0F6D64B5241C970EC2BBAC25A951 ) ) game ( name "Polly Pocket! - Super Splash Island (USA) (Vivendi)" description "Polly Pocket! - Super Splash Island (USA) (Vivendi)" - rom ( name "Polly Pocket! - Super Splash Island (USA) (Vivendi).gba" size 4194304 crc B5DE8C6E md5 D53CA7A7F09E222722E110445E1A4E6C sha1 E8DF35F71CBA359A077522815CA5C4887D0CE161 ) + rom ( name "Polly Pocket! - Super Splash Island (USA) (Vivendi).gba" size 4194304 crc b5de8c6e sha1 E8DF35F71CBA359A077522815CA5C4887D0CE161 ) +) + +game ( + name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (DSI)" + description "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (DSI)" + rom ( name "Polly Pocket! - Super Splash Island (Europe) (En,Fr,De,Es,It) (DSI).gba" size 4194304 crc 13e2a64f sha1 5D4DEDDC0BCA1043BBC28DE16D10AB427E193622 ) +) + +game ( + name "Polly Pocket! - Super Splash Island (USA) (DSI)" + description "Polly Pocket! - Super Splash Island (USA) (DSI)" + rom ( name "Polly Pocket! - Super Splash Island (USA) (DSI).gba" size 4194304 crc f120eca2 sha1 333CF7C32E017F25C1674313B15F05C62676335B ) ) game ( name "Pop Idol (Europe)" description "Pop Idol (Europe)" - rom ( name "Pop Idol (Europe).gba" size 16777216 crc B9A7E60D md5 B86876FDB1125CC3132DAB1CC0D6EB74 sha1 01FD660267705ED2A290734941B1305478DF183F ) + rom ( name "Pop Idol (Europe).gba" size 16777216 crc b9a7e60d sha1 01FD660267705ED2A290734941B1305478DF183F ) ) game ( name "Popeye - Rush for Spinach (USA, Europe) (En,Fr,De,Es,It)" description "Popeye - Rush for Spinach (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Popeye - Rush for Spinach (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc CFFC52DD md5 A5BF85CD40533D76A1FB2B0B2F8D5B19 sha1 25ECBA1D1D14F497DEC7FDC67F6666BB83127077 flags verified ) + rom ( name "Popeye - Rush for Spinach (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc cffc52dd sha1 25ECBA1D1D14F497DEC7FDC67F6666BB83127077 flags verified ) ) game ( name "Postman Pat and the Greendale Rocket (Europe) (En,No,Da)" description "Postman Pat and the Greendale Rocket (Europe) (En,No,Da)" - rom ( name "Postman Pat and the Greendale Rocket (Europe) (En,No,Da).gba" size 4194304 crc 566CF164 md5 E682F89B0A9C991B5E16CEB188FA7E87 sha1 45B53D406078729F8A1773FC001FFEF79259384C ) + rom ( name "Postman Pat and the Greendale Rocket (Europe) (En,No,Da).gba" size 4194304 crc 566cf164 sha1 45B53D406078729F8A1773FC001FFEF79259384C ) ) game ( name "Power Poke Dash (Japan)" description "Power Poke Dash (Japan)" - rom ( name "Power Poke Dash (Japan).gba" size 8388608 crc 59E7AB4C md5 527153AE575AEFE5E48ED9CCC191BA66 sha1 598DB3DD414EC3ACB8BEA47192761816E401DF15 ) -) - -game ( - name "Power Pro Kun Pocket 1, 2 (Japan) (Promo)" - description "Power Pro Kun Pocket 1, 2 (Japan) (Promo)" - rom ( name "Power Pro Kun Pocket 1, 2 (Japan) (Promo).gba" size 8388608 crc 46493FA1 md5 45EF3C56FB1D7E33144D3517133E1CED sha1 43BADCEFE8CAD127F8F8655EE89262517399A20B ) + rom ( name "Power Poke Dash (Japan).gba" size 8388608 crc 59e7ab4c sha1 598DB3DD414EC3ACB8BEA47192761816E401DF15 flags verified ) ) game ( name "Power Pro Kun Pocket 1, 2 (Japan)" description "Power Pro Kun Pocket 1, 2 (Japan)" - rom ( name "Power Pro Kun Pocket 1, 2 (Japan).gba" size 8388608 crc A84032AA md5 1C71095F65234AD3649E6C685B1E61F4 sha1 844512DB89FCA8476C0C585D8699B3446495EABC ) + rom ( name "Power Pro Kun Pocket 1, 2 (Japan).gba" size 8388608 crc a84032aa sha1 844512DB89FCA8476C0C585D8699B3446495EABC flags verified ) +) + +game ( + name "Power Pro Kun Pocket 1, 2 (Japan) (Promo)" + description "Power Pro Kun Pocket 1, 2 (Japan) (Promo)" + rom ( name "Power Pro Kun Pocket 1, 2 (Japan) (Promo).gba" size 8388608 crc 46493fa1 sha1 43BADCEFE8CAD127F8F8655EE89262517399A20B ) ) game ( name "Power Pro Kun Pocket 3 (Japan)" description "Power Pro Kun Pocket 3 (Japan)" - rom ( name "Power Pro Kun Pocket 3 (Japan).gba" size 8388608 crc 4314D8BC md5 D8635A000FFFB777F91137993D439EE3 sha1 C6D7317D945F96034699501AC33B1966C5D2C3DE ) + rom ( name "Power Pro Kun Pocket 3 (Japan).gba" size 8388608 crc 4314d8bc sha1 C6D7317D945F96034699501AC33B1966C5D2C3DE flags verified ) ) game ( name "Power Pro Kun Pocket 3 (Japan) (Rev 1)" description "Power Pro Kun Pocket 3 (Japan) (Rev 1)" - serial "AP3J" - rom ( name "Power Pro Kun Pocket 3 (Japan) (Rev 1).gba" size 8388608 crc D8397194 md5 22B69C5C0108766BE33AD23340F387E2 sha1 AB501BA0C07E7FECBFB15E837B94A08252203C12 ) + rom ( name "Power Pro Kun Pocket 3 (Japan) (Rev 1).gba" size 8388608 crc d8397194 sha1 AB501BA0C07E7FECBFB15E837B94A08252203C12 flags verified ) ) game ( name "Power Pro Kun Pocket 4 (Japan)" description "Power Pro Kun Pocket 4 (Japan)" - rom ( name "Power Pro Kun Pocket 4 (Japan).gba" size 8388608 crc 30B4A347 md5 4D5F240B6A56582F7743287726E6242B sha1 6AB43FD731C1D8B6388D6719B8BCBCE698DA51DE ) + rom ( name "Power Pro Kun Pocket 4 (Japan).gba" size 8388608 crc 30b4a347 sha1 6AB43FD731C1D8B6388D6719B8BCBCE698DA51DE flags verified ) +) + +game ( + name "Power Pro Kun Pocket 4 (Japan) (Rev 1)" + description "Power Pro Kun Pocket 4 (Japan) (Rev 1)" + rom ( name "Power Pro Kun Pocket 4 (Japan) (Rev 1).gba" size 8388608 crc 89a3a2c7 sha1 AF8006B7EF649CA35F21D53137F48DC5E6209F5E flags verified ) ) game ( name "Power Pro Kun Pocket 5 (Japan)" description "Power Pro Kun Pocket 5 (Japan)" - rom ( name "Power Pro Kun Pocket 5 (Japan).gba" size 8388608 crc 06F0F8D4 md5 7CC95CFFCB5835B1CDE52C805BE8461A sha1 15BC24F0F47E0317C849C1C33A36357A43DEF74C ) + rom ( name "Power Pro Kun Pocket 5 (Japan).gba" size 8388608 crc 06f0f8d4 sha1 15BC24F0F47E0317C849C1C33A36357A43DEF74C ) ) game ( name "Power Pro Kun Pocket 5 (Japan) (Promo)" description "Power Pro Kun Pocket 5 (Japan) (Promo)" - rom ( name "Power Pro Kun Pocket 5 (Japan) (Promo).gba" size 8388608 crc 969AC691 md5 F8282772301A8AFC2C6979B447FA9C55 sha1 F9FD4C8EE4F274C751551F056DC868ABD0355390 ) + rom ( name "Power Pro Kun Pocket 5 (Japan) (Promo).gba" size 8388608 crc 969ac691 sha1 F9FD4C8EE4F274C751551F056DC868ABD0355390 ) ) game ( - name "Power Pro Kun Pocket 6 (Japan) (Promo)" - description "Power Pro Kun Pocket 6 (Japan) (Promo)" - rom ( name "Power Pro Kun Pocket 6 (Japan) (Promo).gba" size 8388608 crc 023A9A75 md5 17D463E3E82827C38EE8FC301790D279 sha1 066D2086D776C66AA566EAC211A0E9B45F1942F6 ) + name "Power Pro Kun Pocket 5 (Japan) (Rev 1)" + description "Power Pro Kun Pocket 5 (Japan) (Rev 1)" + rom ( name "Power Pro Kun Pocket 5 (Japan) (Rev 1).gba" size 8388608 crc b2d8732d sha1 29101619EF0EDE2FE0174BA2AB6BD2427C1FE0A1 flags verified ) ) game ( name "Power Pro Kun Pocket 6 (Japan)" description "Power Pro Kun Pocket 6 (Japan)" - rom ( name "Power Pro Kun Pocket 6 (Japan).gba" size 8388608 crc 88513763 md5 128F71AA30E3435283DF66B77A361672 sha1 43E030499A3E8AC631B3A03D78B7E52C1C7445FB ) + rom ( name "Power Pro Kun Pocket 6 (Japan).gba" size 8388608 crc 88513763 sha1 43E030499A3E8AC631B3A03D78B7E52C1C7445FB ) +) + +game ( + name "Power Pro Kun Pocket 6 (Japan) (Promo)" + description "Power Pro Kun Pocket 6 (Japan) (Promo)" + rom ( name "Power Pro Kun Pocket 6 (Japan) (Promo).gba" size 8388608 crc 023a9a75 sha1 066D2086D776C66AA566EAC211A0E9B45F1942F6 ) ) game ( name "Power Pro Kun Pocket 7 (Japan)" description "Power Pro Kun Pocket 7 (Japan)" - rom ( name "Power Pro Kun Pocket 7 (Japan).gba" size 8388608 crc 073047DF md5 845DC86C7D1869BBE0B984D19D9BA01F sha1 A14CD63079C1E4652BFF1F1D7FE784714341B1E9 ) + rom ( name "Power Pro Kun Pocket 7 (Japan).gba" size 8388608 crc 073047df sha1 A14CD63079C1E4652BFF1F1D7FE784714341B1E9 ) ) game ( name "Power Rangers - Dino Thunder (USA, Europe)" description "Power Rangers - Dino Thunder (USA, Europe)" - rom ( name "Power Rangers - Dino Thunder (USA, Europe).gba" size 4194304 crc BC193EE7 md5 343C3CEB2CF89C5334F325EDC4C4CAE3 sha1 A294B761979BDBEC34F975B56A0D88E919236B5F flags verified ) + rom ( name "Power Rangers - Dino Thunder (USA, Europe).gba" size 4194304 crc bc193ee7 sha1 A294B761979BDBEC34F975B56A0D88E919236B5F flags verified ) ) game ( name "Power Rangers - Dino Thunder (Europe) (Fr,De)" description "Power Rangers - Dino Thunder (Europe) (Fr,De)" - rom ( name "Power Rangers - Dino Thunder (Europe) (Fr,De).gba" size 4194304 crc 414BFE31 md5 D867844AD81A900ABA625A5075275247 sha1 48E9B2A64528CB6E0FBA330F8342B87A96357C41 ) + rom ( name "Power Rangers - Dino Thunder (Europe) (Fr,De).gba" size 4194304 crc 414bfe31 sha1 48E9B2A64528CB6E0FBA330F8342B87A96357C41 ) ) game ( name "Power Rangers - La Force du Temps (France)" description "Power Rangers - La Force du Temps (France)" - rom ( name "Power Rangers - La Force du Temps (France).gba" size 4194304 crc EB54D898 md5 A85ABD253B9716A6266442B6F26362C4 sha1 687D257DA2BB5946C2AA07A7F6E28649505186A8 ) + rom ( name "Power Rangers - La Force du Temps (France).gba" size 4194304 crc eb54d898 sha1 687D257DA2BB5946C2AA07A7F6E28649505186A8 ) ) game ( name "Power Rangers - Ninja Storm (USA)" description "Power Rangers - Ninja Storm (USA)" - rom ( name "Power Rangers - Ninja Storm (USA).gba" size 4194304 crc E8691A0F md5 B9C2FAD1C168BFD5D0B5A6930E4E1AD2 sha1 16A719D35358C44A9560C83E19EB5F1BCA3A1182 flags verified ) + rom ( name "Power Rangers - Ninja Storm (USA).gba" size 4194304 crc e8691a0f sha1 16A719D35358C44A9560C83E19EB5F1BCA3A1182 flags verified ) ) game ( name "Power Rangers - Ninja Storm (Europe) (En,Fr,De)" description "Power Rangers - Ninja Storm (Europe) (En,Fr,De)" - rom ( name "Power Rangers - Ninja Storm (Europe) (En,Fr,De).gba" size 4194304 crc 09D8ED5E md5 F0D1A7BB650EA304B9AF7BFC1567A19B sha1 9B131CE8FE535A5B5EEF62E725FB41411C3CAD88 ) + rom ( name "Power Rangers - Ninja Storm (Europe) (En,Fr,De).gba" size 4194304 crc 09d8ed5e sha1 9B131CE8FE535A5B5EEF62E725FB41411C3CAD88 ) ) game ( name "Power Rangers - Time Force (USA, Europe)" description "Power Rangers - Time Force (USA, Europe)" - rom ( name "Power Rangers - Time Force (USA, Europe).gba" size 4194304 crc 70359B35 md5 21B6D4D9631896145F94B869DE43F543 sha1 F43B94941A8D5EA87E15130BEDF3DC2E5D893F36 flags verified ) + rom ( name "Power Rangers - Time Force (USA, Europe).gba" size 4194304 crc 70359b35 sha1 F43B94941A8D5EA87E15130BEDF3DC2E5D893F36 flags verified ) ) game ( name "Power Rangers - Time Force (Germany)" description "Power Rangers - Time Force (Germany)" - rom ( name "Power Rangers - Time Force (Germany).gba" size 4194304 crc 933F5477 md5 F29FE8CAE0ACB618D7C48FB5E292B367 sha1 085FE6DF7A7D30B2CABF62DF5B03EAE21982382C ) + rom ( name "Power Rangers - Time Force (Germany).gba" size 4194304 crc 933f5477 sha1 085FE6DF7A7D30B2CABF62DF5B03EAE21982382C ) ) game ( name "Power Rangers - Wild Force (USA, Europe)" description "Power Rangers - Wild Force (USA, Europe)" - rom ( name "Power Rangers - Wild Force (USA, Europe).gba" size 4194304 crc 54C31AFB md5 577A14EF8E3646A2A8B3F39D9BEB199E sha1 852D5EAE2C6601A3EA0D17ECBFF54D4D0A8CF8E4 ) + rom ( name "Power Rangers - Wild Force (USA, Europe).gba" size 4194304 crc 54c31afb sha1 852D5EAE2C6601A3EA0D17ECBFF54D4D0A8CF8E4 ) ) game ( name "Power Rangers S.P.D. (USA, Europe)" description "Power Rangers S.P.D. (USA, Europe)" - rom ( name "Power Rangers S.P.D. (USA, Europe).gba" size 4194304 crc 921B66E2 md5 2892A0FCEFC0C183BF725B0A2540A83A sha1 494156A4799D3C19DE58D34917B6DEF7B15986E1 flags verified ) + rom ( name "Power Rangers S.P.D. (USA, Europe).gba" size 4194304 crc 921b66e2 sha1 494156A4799D3C19DE58D34917B6DEF7B15986E1 flags verified ) ) game ( name "Power Rangers S.P.D. (Europe) (En,Fr,De)" description "Power Rangers S.P.D. (Europe) (En,Fr,De)" - rom ( name "Power Rangers S.P.D. (Europe) (En,Fr,De).gba" size 4194304 crc CB59CF7D md5 5871ED8E3984E4353F892761B4920AD5 sha1 F10A8C31D8874FA65D5676786591893682DCE942 ) + rom ( name "Power Rangers S.P.D. (Europe) (En,Fr,De).gba" size 4194304 crc cb59cf7d sha1 F10A8C31D8874FA65D5676786591893682DCE942 ) ) game ( name "Power Rangers S.P.D. (Europe) (En,Es,It)" description "Power Rangers S.P.D. (Europe) (En,Es,It)" - rom ( name "Power Rangers S.P.D. (Europe) (En,Es,It).gba" size 4194304 crc DCA64F27 md5 E284D5C93A8E6A3DD4F3587F0836AA4C sha1 3099CB26CAE98CCCC264D168AC8D47FC134CBF36 ) + rom ( name "Power Rangers S.P.D. (Europe) (En,Es,It).gba" size 4194304 crc dca64f27 sha1 3099CB26CAE98CCCC264D168AC8D47FC134CBF36 ) ) game ( name "Powerpuff Girls, The - Him and Seek (USA)" description "Powerpuff Girls, The - Him and Seek (USA)" - rom ( name "Powerpuff Girls, The - Him and Seek (USA).gba" size 8388608 crc 4D22B35E md5 E5911E8365D3FE871C7D58560A302938 sha1 BCF894B5819169640329C93178F5C8727D3D812E ) + rom ( name "Powerpuff Girls, The - Him and Seek (USA).gba" size 8388608 crc 4d22b35e sha1 BCF894B5819169640329C93178F5C8727D3D812E ) ) game ( name "Powerpuff Girls, The - Him and Seek (Europe) (En,Fr,De,Es)" description "Powerpuff Girls, The - Him and Seek (Europe) (En,Fr,De,Es)" - rom ( name "Powerpuff Girls, The - Him and Seek (Europe) (En,Fr,De,Es).gba" size 8388608 crc 0BFED765 md5 A668A8F0847A99D34463661563B4FC0F sha1 F2599724F104EFB8877A34F96A0D7290E8C01D5E ) + rom ( name "Powerpuff Girls, The - Him and Seek (Europe) (En,Fr,De,Es).gba" size 8388608 crc 0bfed765 sha1 F2599724F104EFB8877A34F96A0D7290E8C01D5E ) ) game ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (USA) (En,Fr,De,Es,It,Nl)" description "Powerpuff Girls, The - Mojo Jojo A-Go-Go (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc DFB57DCF md5 28A2B3E44952944E29A168E5F17B5696 sha1 E6D3537F4E95E578DCDC84200578E77FBDC381B1 ) + rom ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc dfb57dcf sha1 E6D3537F4E95E578DCDC84200578E77FBDC381B1 ) ) game ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (Europe) (En,Fr,De,Es,It,Nl)" description "Powerpuff Girls, The - Mojo Jojo A-Go-Go (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 1172D0A7 md5 59240DA663C9537307A05E0A465DA198 sha1 A3D9260A80A6E38165587265405D892C3F87039B ) -) - -game ( - name "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta)" - description "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta)" - rom ( name "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc ABB50D93 md5 2A141847EE3DC1E13ADA211A8C2537CC sha1 DC789663025C8E5122622CE4FC6D0953A5656BD6 ) + rom ( name "Powerpuff Girls, The - Mojo Jojo A-Go-Go (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 1172d0a7 sha1 A3D9260A80A6E38165587265405D892C3F87039B ) ) game ( name "Prehistorik Man (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Prehistorik Man (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Prehistorik Man (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0D3B922B md5 6CE9BB835428A17300FD191C7B9D8ECE sha1 B1731D8C326128C10ED5D4C6DDCF452A8B8EE72E flags verified ) + rom ( name "Prehistorik Man (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0d3b922b sha1 B1731D8C326128C10ED5D4C6DDCF452A8B8EE72E flags verified ) +) + +game ( + name "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta)" + description "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta)" + rom ( name "Prehistorik Man (USA) (En,Fr,De,Es,It,Nl) (Beta).gba" size 4194304 crc abb50d93 sha1 DC789663025C8E5122622CE4FC6D0953A5656BD6 ) ) game ( name "Premier Action Soccer (Europe) (En,Fr,De,Es,It)" description "Premier Action Soccer (Europe) (En,Fr,De,Es,It)" - rom ( name "Premier Action Soccer (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B5432FA4 md5 8BAC13CF55656A7D66AB32482FD7A323 sha1 3F066EB236E8FA22E8507CA9DC502BE85CCAFEC3 flags verified ) + rom ( name "Premier Action Soccer (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b5432fa4 sha1 3F066EB236E8FA22E8507CA9DC502BE85CCAFEC3 flags verified ) ) game ( name "Premier Manager 2003-04 (Europe) (En,Fr,De,It)" description "Premier Manager 2003-04 (Europe) (En,Fr,De,It)" - rom ( name "Premier Manager 2003-04 (Europe) (En,Fr,De,It).gba" size 4194304 crc A959F638 md5 563F3B87205C05E7167DE68A99A80C4D sha1 674F9259E3F24C81AECD14A19103E90606077FB9 ) + rom ( name "Premier Manager 2003-04 (Europe) (En,Fr,De,It).gba" size 4194304 crc a959f638 sha1 674F9259E3F24C81AECD14A19103E90606077FB9 ) ) game ( name "Premier Manager 2004-2005 (Europe) (En,Fr,De,It)" description "Premier Manager 2004-2005 (Europe) (En,Fr,De,It)" - rom ( name "Premier Manager 2004-2005 (Europe) (En,Fr,De,It).gba" size 4194304 crc 2706DFF2 md5 729069EE00DAD63007EB77CB892E4627 sha1 8994DA41D86A3FD8CD67E79C5DB5853A420A6E39 flags verified ) + rom ( name "Premier Manager 2004-2005 (Europe) (En,Fr,De,It).gba" size 4194304 crc 2706dff2 sha1 8994DA41D86A3FD8CD67E79C5DB5853A420A6E39 flags verified ) ) game ( name "Premier Manager 2005-2006 (Europe) (En,Fr,De,It)" description "Premier Manager 2005-2006 (Europe) (En,Fr,De,It)" - rom ( name "Premier Manager 2005-2006 (Europe) (En,Fr,De,It).gba" size 4194304 crc 3B04673B md5 3DD4126B95D3796201149ECDE2EEEB9D sha1 B601870153037897C00602D3C0C7C08B68A16B1F ) + rom ( name "Premier Manager 2005-2006 (Europe) (En,Fr,De,It).gba" size 4194304 crc 3b04673b sha1 B601870153037897C00602D3C0C7C08B68A16B1F flags verified ) ) game ( name "Prince of Persia - The Sands of Time (USA) (En,Fr,Es)" description "Prince of Persia - The Sands of Time (USA) (En,Fr,Es)" - rom ( name "Prince of Persia - The Sands of Time (USA) (En,Fr,Es).gba" size 8388608 crc 0C043BA6 md5 6D820B583B6AB2CC5C901D56B43E38CB sha1 C169E0C60D3E2DD01B09C478DE7BB62CADB516D6 flags verified ) + rom ( name "Prince of Persia - The Sands of Time (USA) (En,Fr,Es).gba" size 8388608 crc 0c043ba6 sha1 C169E0C60D3E2DD01B09C478DE7BB62CADB516D6 flags verified ) ) game ( name "Prince of Persia - The Sands of Time (Europe) (En,Fr,De,Es,It,Nl)" description "Prince of Persia - The Sands of Time (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Prince of Persia - The Sands of Time (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc F0F16B7E md5 69A9F59169766CDA7EBC29BE820A78A3 sha1 BF6A2B3BDB1FA3C010046306ECF4B2B5E67CCEAE flags verified ) + rom ( name "Prince of Persia - The Sands of Time (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc f0f16b7e sha1 BF6A2B3BDB1FA3C010046306ECF4B2B5E67CCEAE flags verified ) +) + +game ( + name "Prince of Persia - The Sands of Time (USA) (En,Fr,Es) (Rev 1)" + description "Prince of Persia - The Sands of Time (USA) (En,Fr,Es) (Rev 1)" + rom ( name "Prince of Persia - The Sands of Time (USA) (En,Fr,Es) (Rev 1).gba" size 8388608 crc 5adf72e6 sha1 3F379CD2E598CA69BA68649C81CF425ED284AE27 flags verified ) ) game ( name "Prince of Persia - The Sands of Time & Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It)" description "Prince of Persia - The Sands of Time & Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It)" - rom ( name "Prince of Persia - The Sands of Time & Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It).gba" size 16777216 crc 2A3E1A8D md5 3EC6B4CD475B62B2351A1B5EA6772311 sha1 7719FA244055BFE994E6ECF32B92966FF2A3FC72 ) + rom ( name "Prince of Persia - The Sands of Time & Lara Croft Tomb Raider - The Prophecy (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It).gba" size 16777216 crc 2a3e1a8d sha1 7719FA244055BFE994E6ECF32B92966FF2A3FC72 ) ) game ( name "Princess Natasha - Student, Secret Agent, Princess (USA)" description "Princess Natasha - Student, Secret Agent, Princess (USA)" - rom ( name "Princess Natasha - Student, Secret Agent, Princess (USA).gba" size 4194304 crc B07CB7BA md5 F8435F531C69C258841A985FF1E8072F sha1 C8B9C073C06F2B8F7AB55A4DDF6A4EB8B4F93680 ) + rom ( name "Princess Natasha - Student, Secret Agent, Princess (USA).gba" size 4194304 crc b07cb7ba sha1 C8B9C073C06F2B8F7AB55A4DDF6A4EB8B4F93680 ) ) game ( name "Princess Natasha - Student, Secret Agent, Princess (Europe) (En,Fr,De,Es,It)" description "Princess Natasha - Student, Secret Agent, Princess (Europe) (En,Fr,De,Es,It)" - rom ( name "Princess Natasha - Student, Secret Agent, Princess (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E6567686 md5 5909DAF13D2B2E2EC30723777E7654F4 sha1 82377408E6D621F8A224A6BB2016E8AA88009C8B ) + rom ( name "Princess Natasha - Student, Secret Agent, Princess (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e6567686 sha1 82377408E6D621F8A224A6BB2016E8AA88009C8B ) ) game ( name "Pro Action Replay (Japan) (Unl)" description "Pro Action Replay (Japan) (Unl)" - rom ( name "Pro Action Replay (Japan) (Unl).gba" size 1048576 crc 9C249666 md5 3D72E4064493E22AA7BD61A6E5B9E2DD sha1 1FA4A127C9EF14A65F2EFB5FE36165237ED13683 ) + rom ( name "Pro Action Replay (Japan) (Unl).gba" size 1048576 crc 9c249666 sha1 1FA4A127C9EF14A65F2EFB5FE36165237ED13683 ) ) game ( name "Pro Beach Soccer (Europe) (En,Fr,De,Es,It,Pt)" description "Pro Beach Soccer (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Pro Beach Soccer (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 7623E41A md5 F0507E4E45D9643B4749EC3854557872 sha1 635504FFFD667670DF858F76F38FDAE7A797B835 ) + rom ( name "Pro Beach Soccer (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 7623e41a sha1 635504FFFD667670DF858F76F38FDAE7A797B835 ) ) game ( name "Pro Mahjong Tsuwamono GBA (Japan)" description "Pro Mahjong Tsuwamono GBA (Japan)" - rom ( name "Pro Mahjong Tsuwamono GBA (Japan).gba" size 4194304 crc E4D9AE55 md5 76873C9AAAF31D1B6E520145BDD9A8A6 sha1 709071848ABD706FD172381C27516C79F8EB796B ) + rom ( name "Pro Mahjong Tsuwamono GBA (Japan).gba" size 4194304 crc e4d9ae55 sha1 709071848ABD706FD172381C27516C79F8EB796B ) ) game ( name "Pro Tennis WTA Tour (Europe)" description "Pro Tennis WTA Tour (Europe)" - rom ( name "Pro Tennis WTA Tour (Europe).gba" size 4194304 crc F7171521 md5 4990745BA11881CF35A4C860FAA7038D sha1 9D901C2BB81C2546D09A743E336EB398F166BF0E ) + rom ( name "Pro Tennis WTA Tour (Europe).gba" size 4194304 crc f7171521 sha1 9D901C2BB81C2546D09A743E336EB398F166BF0E ) ) game ( name "Pro Yakyuu Team o Tsukurou! Advance (Japan)" description "Pro Yakyuu Team o Tsukurou! Advance (Japan)" - rom ( name "Pro Yakyuu Team o Tsukurou! Advance (Japan).gba" size 8388608 crc A8A3AA8B md5 50A4EC7CC71EA0620629610E6306F299 sha1 BB5CFD9F3B5CF2F14ED4AAF37553EED87A301FC4 flags verified ) + rom ( name "Pro Yakyuu Team o Tsukurou! Advance (Japan).gba" size 8388608 crc a8a3aa8b sha1 BB5CFD9F3B5CF2F14ED4AAF37553EED87A301FC4 flags verified ) ) game ( name "Proud Family, The (USA)" description "Proud Family, The (USA)" - rom ( name "Proud Family, The (USA).gba" size 8388608 crc C92BDE6E md5 487704C5D9978E88E8468D127561948C sha1 AEE1BE6432A1B6FA50564B593F4D4D2D0201D528 ) + rom ( name "Proud Family, The (USA).gba" size 8388608 crc c92bde6e sha1 AEE1BE6432A1B6FA50564B593F4D4D2D0201D528 ) ) game ( name "PukuPuku Tennen Kairanban (Japan)" description "PukuPuku Tennen Kairanban (Japan)" - rom ( name "PukuPuku Tennen Kairanban (Japan).gba" size 4194304 crc 91C4C334 md5 521D5E856A5420D69FF3B9752F106F7F sha1 E2A86CEB717D56C882AD4EEBC015DC1329D8F1BC ) + rom ( name "PukuPuku Tennen Kairanban (Japan).gba" size 4194304 crc 91c4c334 sha1 E2A86CEB717D56C882AD4EEBC015DC1329D8F1BC flags verified ) ) game ( name "PukuPuku Tennen Kairanban - Koi no Cupid Daisakusen (Japan)" description "PukuPuku Tennen Kairanban - Koi no Cupid Daisakusen (Japan)" - rom ( name "PukuPuku Tennen Kairanban - Koi no Cupid Daisakusen (Japan).gba" size 4194304 crc B57FEC3A md5 FA8D5832ED9CCAD0FBCAE7A147755AE9 sha1 AD0A0693FF0C6B4E14150F68BC094851E4927322 ) + rom ( name "PukuPuku Tennen Kairanban - Koi no Cupid Daisakusen (Japan).gba" size 4194304 crc b57fec3a sha1 AD0A0693FF0C6B4E14150F68BC094851E4927322 ) ) game ( name "PukuPuku Tennen Kairanban - Youkoso! Illusion Land he (Japan)" description "PukuPuku Tennen Kairanban - Youkoso! Illusion Land he (Japan)" - rom ( name "PukuPuku Tennen Kairanban - Youkoso! Illusion Land he (Japan).gba" size 8388608 crc E98CF9C3 md5 BEE8F511ABC2235061D9FDB2171C620C sha1 B2BD07BF70D3BBD05C031BAA482E891F245EBAD2 ) -) - -game ( - name "Punch King - Arcade Boxing (Europe) (En,Fr,Es)" - description "Punch King - Arcade Boxing (Europe) (En,Fr,Es)" - rom ( name "Punch King - Arcade Boxing (Europe) (En,Fr,Es).gba" size 8388608 crc 3E4CB21C md5 06F7FF2DB5ABCBD59E4F4816B1890DD9 sha1 4E1B38303DA8A11BD7ADFA50E4ED45216020793D ) + rom ( name "PukuPuku Tennen Kairanban - Youkoso! Illusion Land he (Japan).gba" size 8388608 crc e98cf9c3 sha1 B2BD07BF70D3BBD05C031BAA482E891F245EBAD2 ) ) game ( name "Punch King - Arcade Boxing (USA)" description "Punch King - Arcade Boxing (USA)" - rom ( name "Punch King - Arcade Boxing (USA).gba" size 8388608 crc 540B6CC1 md5 74D3FD11921E0CD02955A6B59FE75E0F sha1 021FDD9420A81A3AA8F37DE884AC2B8F42E691ED flags verified ) + rom ( name "Punch King - Arcade Boxing (USA).gba" size 8388608 crc 540b6cc1 sha1 021FDD9420A81A3AA8F37DE884AC2B8F42E691ED flags verified ) +) + +game ( + name "Punch King - Arcade Boxing (Europe) (En,Fr,Es)" + description "Punch King - Arcade Boxing (Europe) (En,Fr,Es)" + rom ( name "Punch King - Arcade Boxing (Europe) (En,Fr,Es).gba" size 8388608 crc 3e4cb21c sha1 4E1B38303DA8A11BD7ADFA50E4ED45216020793D ) ) game ( name "Puppy Luv - Spa and Resort (USA)" description "Puppy Luv - Spa and Resort (USA)" - rom ( name "Puppy Luv - Spa and Resort (USA).gba" size 4194304 crc 04146DD6 md5 F333B1026273DD9B49DAD0F912510496 sha1 50A7CA21A2EAEC9B1BB56843C4DC7761F8E2C5A4 ) -) - -game ( - name "Puyo Pop (Europe) (En,Ja)" - description "Puyo Pop (Europe) (En,Ja)" - rom ( name "Puyo Pop (Europe) (En,Ja).gba" size 8388608 crc C85DE50E md5 2EA8794792B610DC216324F056000F29 sha1 DF931351D42D92C0D4CA1623D77D8255A1861819 flags verified ) + rom ( name "Puppy Luv - Spa and Resort (USA).gba" size 4194304 crc 04146dd6 sha1 50A7CA21A2EAEC9B1BB56843C4DC7761F8E2C5A4 ) ) game ( name "Puyo Pop (USA) (En,Ja)" description "Puyo Pop (USA) (En,Ja)" - rom ( name "Puyo Pop (USA) (En,Ja).gba" size 8388608 crc 0901BE49 md5 3EE8E61DFE10BBFC15F51FD52EEF8E14 sha1 338702EA961B17C46A1DEB960F5D0DF19D7912F9 ) + rom ( name "Puyo Pop (USA) (En,Ja).gba" size 8388608 crc 0901be49 sha1 338702EA961B17C46A1DEB960F5D0DF19D7912F9 ) +) + +game ( + name "Puyo Pop (Europe) (En,Ja)" + description "Puyo Pop (Europe) (En,Ja)" + rom ( name "Puyo Pop (Europe) (En,Ja).gba" size 8388608 crc c85de50e sha1 DF931351D42D92C0D4CA1623D77D8255A1861819 flags verified ) ) game ( name "Puyo Pop Fever (Europe) (En,Fr,De,Es,It)" description "Puyo Pop Fever (Europe) (En,Fr,De,Es,It)" - rom ( name "Puyo Pop Fever (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6E5880ED md5 8D7C792D3C715F48833D0390B4EEBC45 sha1 92C4A55E04FF3311854EC5D2952F35D38A2BE59C flags verified ) + rom ( name "Puyo Pop Fever (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6e5880ed sha1 92C4A55E04FF3311854EC5D2952F35D38A2BE59C flags verified ) ) game ( name "Puyo Puyo Fever (Japan) (En,Ja,Fr,De,Es,It)" description "Puyo Puyo Fever (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Puyo Puyo Fever (Japan) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 3FFD621A md5 9B9B31E30D7EBCC22BCBD7132E142292 sha1 565BEE29956ABED2C9AFEF8A86A8B2AB60B440FC ) + rom ( name "Puyo Puyo Fever (Japan) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 3ffd621a sha1 565BEE29956ABED2C9AFEF8A86A8B2AB60B440FC flags verified ) ) game ( name "Puzzle & Tantei Collection (Japan)" description "Puzzle & Tantei Collection (Japan)" - rom ( name "Puzzle & Tantei Collection (Japan).gba" size 8388608 crc 893551BB md5 919041D04CE811A6060044D579180C66 sha1 4E81530B84BDEFD3D4BA7AF878F19301FCA3CE91 ) + rom ( name "Puzzle & Tantei Collection (Japan).gba" size 8388608 crc 893551bb sha1 4E81530B84BDEFD3D4BA7AF878F19301FCA3CE91 ) ) game ( name "Pyuu to Fuku! Jaguar - Byoo to Deru! Megane-kun (Japan)" description "Pyuu to Fuku! Jaguar - Byoo to Deru! Megane-kun (Japan)" - rom ( name "Pyuu to Fuku! Jaguar - Byoo to Deru! Megane-kun (Japan).gba" size 8388608 crc 1F67BD36 md5 09BDBC2B8190566335B4C27CD20C8B8E sha1 74B0564E01158CEAF6F4C22EBE8870FDF5A752DD ) + rom ( name "Pyuu to Fuku! Jaguar - Byoo to Deru! Megane-kun (Japan).gba" size 8388608 crc 1f67bd36 sha1 74B0564E01158CEAF6F4C22EBE8870FDF5A752DD ) ) game ( name "Quad Desert Fury (USA, Europe)" description "Quad Desert Fury (USA, Europe)" - rom ( name "Quad Desert Fury (USA, Europe).gba" size 4194304 crc 95BE56E6 md5 E003F4C06AD7F01D50DCDADA5075A234 sha1 70525638035FAF22614676BD6FDFB69F03934737 flags verified ) + rom ( name "Quad Desert Fury (USA, Europe).gba" size 4194304 crc 95be56e6 sha1 70525638035FAF22614676BD6FDFB69F03934737 flags verified ) ) game ( name "Qui Veut Gagner des Millions (France)" description "Qui Veut Gagner des Millions (France)" - rom ( name "Qui Veut Gagner des Millions (France).gba" size 4194304 crc 8F33BD3F md5 3DEDF95B5692ABF4A3487BB2500DD566 sha1 4E069EB2DED73B07D8B87836A7F2FAC05E62DB86 ) + rom ( name "Qui Veut Gagner des Millions (France).gba" size 4194304 crc 8f33bd3f sha1 4E069EB2DED73B07D8B87836A7F2FAC05E62DB86 ) ) game ( name "Quiere Ser Millonario (Spain)" description "Quiere Ser Millonario (Spain)" - rom ( name "Quiere Ser Millonario (Spain).gba" size 4194304 crc 43514D44 md5 4C67C2E4202FCF805E3BB006853CA677 sha1 578A58E929EFD8A2694898EB2CCBE115E6E7F3C1 ) + rom ( name "Quiere Ser Millonario (Spain).gba" size 4194304 crc 43514d44 sha1 578A58E929EFD8A2694898EB2CCBE115E6E7F3C1 ) ) game ( name "Qwak (Europe) (Demo) (Unl)" description "Qwak (Europe) (Demo) (Unl)" - rom ( name "Qwak (Europe) (Demo) (Unl).gba" size 564192 crc 09C59E6B md5 0F05D7A1EAC546B2C66C902FF97B4CE1 sha1 760145639C82C75E21D648C946211B962D7E254A ) + rom ( name "Qwak (Europe) (Demo) (Unl).gba" size 564192 crc 09c59e6b sha1 760145639C82C75E21D648C946211B962D7E254A ) ) game ( name "Qwak (Europe) (En,Fr,De,Es,It) (Unl)" description "Qwak (Europe) (En,Fr,De,Es,It) (Unl)" - rom ( name "Qwak (Europe) (En,Fr,De,Es,It) (Unl).gba" size 8388608 crc 9027917F md5 2C464384922D5A145559C61ED8664113 sha1 A5F5DDE3D0D3F58F8903E44461E17A7001591649 flags verified ) + rom ( name "Qwak (Europe) (En,Fr,De,Es,It) (Unl).gba" size 8388608 crc 9027917f sha1 A5F5DDE3D0D3F58F8903E44461E17A7001591649 flags verified ) ) game ( name "R-Type III - The Third Lightning (USA)" description "R-Type III - The Third Lightning (USA)" - rom ( name "R-Type III - The Third Lightning (USA).gba" size 4194304 crc EA863F4D md5 188E4A01BF62230B7B50EAEB9355BD42 sha1 A69527BB63E76F72F2E5E471E171E24A3043E2D9 ) + rom ( name "R-Type III - The Third Lightning (USA).gba" size 4194304 crc ea863f4d sha1 A69527BB63E76F72F2E5E471E171E24A3043E2D9 ) ) game ( name "R-Type III - The Third Lightning (Europe) (En,Fr,De,Es,It)" description "R-Type III - The Third Lightning (Europe) (En,Fr,De,Es,It)" - rom ( name "R-Type III - The Third Lightning (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 41BB7F8A md5 FB85F8209FE4EA11E6578B11E8194546 sha1 7CC8D40C5244BAA22B94DD382C5AE39F894DAAAB ) + rom ( name "R-Type III - The Third Lightning (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 41bb7f8a sha1 7CC8D40C5244BAA22B94DD382C5AE39F894DAAAB ) ) game ( name "Racing Fever (Europe) (En,De,Es,It)" description "Racing Fever (Europe) (En,De,Es,It)" - rom ( name "Racing Fever (Europe) (En,De,Es,It).gba" size 4194304 crc E40EC737 md5 F1040F25E06DD1F4B5FA2967A2996FFC sha1 9BB5C036BCA8F0D2E06013CAC7EA6148A4F7F512 ) + rom ( name "Racing Fever (Europe) (En,De,Es,It).gba" size 4194304 crc e40ec737 sha1 9BB5C036BCA8F0D2E06013CAC7EA6148A4F7F512 ) +) + +game ( + name "Racing Fever (France)" + description "Racing Fever (France)" + rom ( name "Racing Fever (France).gba" size 4194304 crc 4f61dedb sha1 67EB3051C7527692CFD7515EA367796FAB3A1362 flags verified ) ) game ( name "Racing Gears Advance (Europe) (En,Fr,De,Es,It)" description "Racing Gears Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Racing Gears Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 49A88E52 md5 072F378E3AE2D271F384B886BE067031 sha1 E5D3ABAA47A3527CF2EC148D724AD9AC8ED6F827 ) + rom ( name "Racing Gears Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 49a88e52 sha1 E5D3ABAA47A3527CF2EC148D724AD9AC8ED6F827 ) ) game ( name "Racing Gears Advance (USA)" description "Racing Gears Advance (USA)" - rom ( name "Racing Gears Advance (USA).gba" size 8388608 crc BF648E5C md5 1DAC1484F1D66158B1CFAE3DA7C79AF9 sha1 3F053865F9A687A75927172CD281390B2560201C ) + rom ( name "Racing Gears Advance (USA).gba" size 8388608 crc bf648e5c sha1 3F053865F9A687A75927172CD281390B2560201C ) ) game ( name "Rampage - Puzzle Attack (USA, Europe)" description "Rampage - Puzzle Attack (USA, Europe)" - rom ( name "Rampage - Puzzle Attack (USA, Europe).gba" size 4194304 crc 8ECA2B0F md5 580CC4C0A87DD4C40901DDADD90CA76F sha1 35C4ACE4044F2171DC90A1195EC83AE57324FC83 ) + rom ( name "Rampage - Puzzle Attack (USA, Europe).gba" size 4194304 crc 8eca2b0f sha1 35C4ACE4044F2171DC90A1195EC83AE57324FC83 ) ) game ( name "Rapala Pro Fishing (USA, Europe)" description "Rapala Pro Fishing (USA, Europe)" - rom ( name "Rapala Pro Fishing (USA, Europe).gba" size 4194304 crc 964D39A7 md5 1A92E287F154D62C136EBE524E75C7F2 sha1 E3DF6FE7A447AB30FAF6FD7D4C57E88F987A5639 flags verified ) + rom ( name "Rapala Pro Fishing (USA, Europe).gba" size 4194304 crc 964d39a7 sha1 E3DF6FE7A447AB30FAF6FD7D4C57E88F987A5639 flags verified ) ) game ( name "Ratatouille (USA)" description "Ratatouille (USA)" - rom ( name "Ratatouille (USA).gba" size 8388608 crc AA2EB686 md5 E669167A9A053A9D19BF92AA2A2CB2F3 sha1 D6C5BE053BC8A8263A2BE9639B5C60F82A5FB0C1 ) + rom ( name "Ratatouille (USA).gba" size 8388608 crc aa2eb686 sha1 D6C5BE053BC8A8263A2BE9639B5C60F82A5FB0C1 ) ) game ( name "Ratatouille (Europe) (Es,Pt)" description "Ratatouille (Europe) (Es,Pt)" - rom ( name "Ratatouille (Europe) (Es,Pt).gba" size 8388608 crc 7A80B515 md5 663BAE5C5EB52177530B339441D48BAF sha1 B76FF3727E614EA9FFBAE7221B496FB65D32B26E ) + rom ( name "Ratatouille (Europe) (Es,Pt).gba" size 8388608 crc 7a80b515 sha1 B76FF3727E614EA9FFBAE7221B496FB65D32B26E ) ) game ( name "Ratatouille (Europe) (Fr,De,Nl)" description "Ratatouille (Europe) (Fr,De,Nl)" - rom ( name "Ratatouille (Europe) (Fr,De,Nl).gba" size 8388608 crc 5C48C362 md5 75119296DE2C0024AF1AE9C5542AB80A sha1 C9069887763173C76EC7B4852CB02098354C76EE ) + rom ( name "Ratatouille (Europe) (Fr,De,Nl).gba" size 8388608 crc 5c48c362 sha1 C9069887763173C76EC7B4852CB02098354C76EE ) ) game ( name "Ratatouille (Europe) (En,It,Sv,No,Da)" description "Ratatouille (Europe) (En,It,Sv,No,Da)" - rom ( name "Ratatouille (Europe) (En,It,Sv,No,Da).gba" size 8388608 crc 82F9C596 md5 DDEBBF0F61891B4E26448AE672CCC8E4 sha1 A5C4A636979C06670A81428C778FF76ED2C65EEE ) + rom ( name "Ratatouille (Europe) (En,It,Sv,No,Da).gba" size 8388608 crc 82f9c596 sha1 A5C4A636979C06670A81428C778FF76ED2C65EEE ) ) game ( name "Rave Master - Special Attack Force! (USA)" description "Rave Master - Special Attack Force! (USA)" - rom ( name "Rave Master - Special Attack Force! (USA).gba" size 8388608 crc C39B9418 md5 2C1E1DB8121B8EB26A55EABBB960BD67 sha1 5CF4FA61626E4D0A887EFAB249DBD682FC770211 ) + rom ( name "Rave Master - Special Attack Force! (USA).gba" size 8388608 crc c39b9418 sha1 5CF4FA61626E4D0A887EFAB249DBD682FC770211 ) ) game ( name "Rayman - 10th Anniversary (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" description "Rayman - 10th Anniversary (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" - rom ( name "Rayman - 10th Anniversary (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 16777216 crc 437E95B9 md5 59CBD3C4AEC998B58FE947682CE16FE5 sha1 37714E724942C9C0882D1F7FC48A8DC449A68F83 ) + rom ( name "Rayman - 10th Anniversary (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 16777216 crc 437e95b9 sha1 37714E724942C9C0882D1F7FC48A8DC449A68F83 flags verified ) ) game ( name "Rayman - 10th Anniversary (USA) (En,Fr,De,Es,It)" description "Rayman - 10th Anniversary (USA) (En,Fr,De,Es,It)" - rom ( name "Rayman - 10th Anniversary (USA) (En,Fr,De,Es,It).gba" size 16777216 crc AE72B0EE md5 5087E6801CF5269976968026127A3288 sha1 1983C17260F5707B26702C3AB1B6C86332365E05 ) + rom ( name "Rayman - 10th Anniversary (USA) (En,Fr,De,Es,It).gba" size 16777216 crc ae72b0ee sha1 1983C17260F5707B26702C3AB1B6C86332365E05 ) ) game ( name "Rayman - Hoodlum's Revenge (USA) (En,Fr,Es)" description "Rayman - Hoodlum's Revenge (USA) (En,Fr,Es)" - rom ( name "Rayman - Hoodlum's Revenge (USA) (En,Fr,Es).gba" size 8388608 crc 025A9998 md5 A31D19D40A70646EAEAA233AC46FE8D7 sha1 F65700DCFC827A3E84C9DD19D6F5E55AF019AC81 ) + rom ( name "Rayman - Hoodlum's Revenge (USA) (En,Fr,Es).gba" size 8388608 crc 025a9998 sha1 F65700DCFC827A3E84C9DD19D6F5E55AF019AC81 ) ) game ( name "Rayman - Hoodlums' Revenge (Europe) (En,Fr,De,Es,It,Nl)" description "Rayman - Hoodlums' Revenge (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Rayman - Hoodlums' Revenge (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc C221C419 md5 7B06540616A35CA1CF4465F1FABE50B6 sha1 586557ABB81333B1153D534E9720537672228E24 ) + rom ( name "Rayman - Hoodlums' Revenge (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc c221c419 sha1 586557ABB81333B1153D534E9720537672228E24 ) ) game ( name "Rayman - Raving Rabbids (USA) (En,Fr,Es)" description "Rayman - Raving Rabbids (USA) (En,Fr,Es)" - rom ( name "Rayman - Raving Rabbids (USA) (En,Fr,Es).gba" size 16777216 crc 751EF0D2 md5 E51AF95BF10261E95814527F05AADDD0 sha1 F671E7FDE8B4A3CD6B5A4DFC19A17A74F1743353 ) + rom ( name "Rayman - Raving Rabbids (USA) (En,Fr,Es).gba" size 16777216 crc 751ef0d2 sha1 F671E7FDE8B4A3CD6B5A4DFC19A17A74F1743353 ) ) game ( name "Rayman - Raving Rabbids (Europe) (En,Fr,De,Es,It,Nl)" description "Rayman - Raving Rabbids (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Rayman - Raving Rabbids (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 9914DA23 md5 9630EAE3565E47174448D3380850C7A9 sha1 78E51CB33F52EBD17383FAF0F153D91E677DCAC9 flags verified ) -) - -game ( - name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta)" - description "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta)" - rom ( name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta).gba" size 8388608 crc 8F34B14F md5 870CFBF9950EEA5DB33C118564233DB3 sha1 064F6B09732F4225F5964D0E8BD386AFFB83E3D7 ) + rom ( name "Rayman - Raving Rabbids (Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc 9914da23 sha1 78E51CB33F52EBD17383FAF0F153D91E677DCAC9 flags verified ) ) game ( name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" description "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" - rom ( name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 8388608 crc 29F83314 md5 14D8DDDF41901B02DB25A04AB587664B sha1 21B7296D29486CCAB68BDFA45AB24B9D370D052C ) + rom ( name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 8388608 crc 29f83314 sha1 21B7296D29486CCAB68BDFA45AB24B9D370D052C ) ) game ( name "Rayman 3 (USA) (En,Fr,Es)" description "Rayman 3 (USA) (En,Fr,Es)" - rom ( name "Rayman 3 (USA) (En,Fr,Es).gba" size 8388608 crc D1613266 md5 A8C8FF92A6B366FC0E363EB80201C367 sha1 1A8FB488AAC9AF4D3D42046750BDF429F48AC391 ) + rom ( name "Rayman 3 (USA) (En,Fr,Es).gba" size 8388608 crc d1613266 sha1 1A8FB488AAC9AF4D3D42046750BDF429F48AC391 ) +) + +game ( + name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta)" + description "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta)" + rom ( name "Rayman 3 (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da,Fi) (Beta).gba" size 8388608 crc 8f34b14f sha1 064F6B09732F4225F5964D0E8BD386AFFB83E3D7 ) ) game ( name "Rayman Advance (USA) (En,Fr,De,Es,It)" description "Rayman Advance (USA) (En,Fr,De,Es,It)" - rom ( name "Rayman Advance (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 8ABA5AB8 md5 616F80F482ADE86D88021B41587AA600 sha1 FF8A41C781735D2B4FE6CDE65E82FB5A68F77F8B ) + rom ( name "Rayman Advance (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 8aba5ab8 sha1 FF8A41C781735D2B4FE6CDE65E82FB5A68F77F8B flags verified ) ) game ( name "Rayman Advance (Europe) (En,Fr,De,Es,It)" description "Rayman Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B43783B4 md5 F2391BA88F816726E5A2CE4D321C5ABF sha1 6A32D270848AE302A3E4FB873E53B663C2DB4811 ) + rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b43783b4 sha1 6A32D270848AE302A3E4FB873E53B663C2DB4811 flags verified ) ) game ( name "Rayman Advance (Europe) (En,Fr,De,Es,It) (Beta)" description "Rayman Advance (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc 4B1B4E02 md5 39551D9B694CD4FEC703E661CA08BD5F sha1 2A473E6A0664412EAD33AA9889912DC25DB93714 ) + rom ( name "Rayman Advance (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc 4b1b4e02 sha1 2A473E6A0664412EAD33AA9889912DC25DB93714 ) ) game ( name "Razbitume! - Restez Branches! (Europe) (En,Fr)" description "Razbitume! - Restez Branches! (Europe) (En,Fr)" - rom ( name "Razbitume! - Restez Branches! (Europe) (En,Fr).gba" size 4194304 crc A169B3B5 md5 3B6875AB215097E8210B618A2AEF1A60 sha1 17A5E6533312CD3DB742E894CC411B3BF77F007D ) + rom ( name "Razbitume! - Restez Branches! (Europe) (En,Fr).gba" size 4194304 crc a169b3b5 sha1 17A5E6533312CD3DB742E894CC411B3BF77F007D ) ) game ( name "Razmoket Rencontrent les Delajungle, Les (France)" description "Razmoket Rencontrent les Delajungle, Les (France)" - rom ( name "Razmoket Rencontrent les Delajungle, Les (France).gba" size 4194304 crc 720B7FF2 md5 EBB31E3FE75CA8FCAE960D3588EF767D sha1 457BE286CB043E1A8EAF7A9A7929B2CBFB56FCDA ) + rom ( name "Razmoket Rencontrent les Delajungle, Les (France).gba" size 4194304 crc 720b7ff2 sha1 457BE286CB043E1A8EAF7A9A7929B2CBFB56FCDA ) ) game ( name "Razmoket, Les - A Moi la Fiesta (France)" description "Razmoket, Les - A Moi la Fiesta (France)" - rom ( name "Razmoket, Les - A Moi la Fiesta (France).gba" size 4194304 crc 4130F7D0 md5 365BCE291E2ED017AE5585489E036CB2 sha1 96A156840EAAFB0F7BF78D99DEE49C90C0DAFD74 ) + rom ( name "Razmoket, Les - A Moi la Fiesta (France).gba" size 4194304 crc 4130f7d0 sha1 96A156840EAAFB0F7BF78D99DEE49C90C0DAFD74 ) ) game ( name "Razmoket, Les - Voler N'Est Pas Jouer (France)" description "Razmoket, Les - Voler N'Est Pas Jouer (France)" - rom ( name "Razmoket, Les - Voler N'Est Pas Jouer (France).gba" size 4194304 crc 809A103A md5 5856C031F9A9DC4C3E395FE336858D9D sha1 C5A9A630A3F3EBD2EA858D127A1CE830350361EE ) + rom ( name "Razmoket, Les - Voler N'Est Pas Jouer (France).gba" size 4194304 crc 809a103a sha1 C5A9A630A3F3EBD2EA858D127A1CE830350361EE ) ) game ( name "Razor Freestyle Scooter (USA)" description "Razor Freestyle Scooter (USA)" - rom ( name "Razor Freestyle Scooter (USA).gba" size 4194304 crc FFE38431 md5 180A4C25CB809435F85F7FB81BC2495F sha1 8B946E0727CE428E3E75C1B19E4E7749BCC19FE4 ) + rom ( name "Razor Freestyle Scooter (USA).gba" size 4194304 crc ffe38431 sha1 8B946E0727CE428E3E75C1B19E4E7749BCC19FE4 ) ) game ( name "Ready 2 Rumble Boxing - Round 2 (USA)" description "Ready 2 Rumble Boxing - Round 2 (USA)" - rom ( name "Ready 2 Rumble Boxing - Round 2 (USA).gba" size 4194304 crc 5DFCC5E5 md5 BA428F9D19ECAD3A4297B8E23481E6B0 sha1 D6114CD4BB6B580437C5C2D6E4C3A51EAA0DE76E ) + rom ( name "Ready 2 Rumble Boxing - Round 2 (USA).gba" size 4194304 crc 5dfcc5e5 sha1 D6114CD4BB6B580437C5C2D6E4C3A51EAA0DE76E ) ) game ( name "Ready 2 Rumble Boxing - Round 2 (Europe) (En,Fr,De)" description "Ready 2 Rumble Boxing - Round 2 (Europe) (En,Fr,De)" - rom ( name "Ready 2 Rumble Boxing - Round 2 (Europe) (En,Fr,De).gba" size 4194304 crc E418E962 md5 ED8221D6853E1C7B070866D3CA3267EA sha1 57D06E405B281F68800B986BD9FF1257E4466939 flags verified ) + rom ( name "Ready 2 Rumble Boxing - Round 2 (Europe) (En,Fr,De).gba" size 4194304 crc e418e962 sha1 57D06E405B281F68800B986BD9FF1257E4466939 flags verified ) ) game ( name "Rebelstar - Tactical Command (USA)" description "Rebelstar - Tactical Command (USA)" - rom ( name "Rebelstar - Tactical Command (USA).gba" size 4194304 crc FB6C590F md5 C4874D3F181E4293F27F25AD52763E50 sha1 E2556BCE89C4B542786C741DC49EF28AFAB917FF ) + rom ( name "Rebelstar - Tactical Command (USA).gba" size 4194304 crc fb6c590f sha1 E2556BCE89C4B542786C741DC49EF28AFAB917FF ) ) game ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It)" description "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It)" - rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc E448C5D4 md5 7812B2E8A0AC8F77E8347D6499AB0160 sha1 669C47E62F2388CE0BA676F3DC641B5AD2DDB5C5 flags verified ) + rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e448c5d4 sha1 669C47E62F2388CE0BA676F3DC641B5AD2DDB5C5 flags verified ) ) game ( name "Recca no Honoo - The Game (Japan)" description "Recca no Honoo - The Game (Japan)" - rom ( name "Recca no Honoo - The Game (Japan).gba" size 8388608 crc B29BEE34 md5 AC593798DFB4A39C4502BA3EA9092680 sha1 35FE535E24DDDE1428D359A95BF114B0968911E9 ) + rom ( name "Recca no Honoo - The Game (Japan).gba" size 8388608 crc b29bee34 sha1 35FE535E24DDDE1428D359A95BF114B0968911E9 ) ) game ( name "Reign of Fire (USA) (En,Fr,De,Es,It)" description "Reign of Fire (USA) (En,Fr,De,Es,It)" - rom ( name "Reign of Fire (USA) (En,Fr,De,Es,It).gba" size 8388608 crc B48F8D57 md5 97E46F72CE3CCDAA76BEE1EB60342BC7 sha1 315B517C6E933E2137DD5385E8F3F564936540E8 ) + rom ( name "Reign of Fire (USA) (En,Fr,De,Es,It).gba" size 8388608 crc b48f8d57 sha1 315B517C6E933E2137DD5385E8F3F564936540E8 ) ) game ( name "Reign of Fire (Europe) (En,Fr,De,Es,It)" description "Reign of Fire (Europe) (En,Fr,De,Es,It)" - rom ( name "Reign of Fire (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 79D7F4BC md5 241E85AD00EAF8CF43499EEB437CF009 sha1 72420D99849B0218CA8FEE4C74E5CF2DA7B82A03 ) + rom ( name "Reign of Fire (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 79d7f4bc sha1 72420D99849B0218CA8FEE4C74E5CF2DA7B82A03 ) ) game ( name "Relaxuma na Mainichi (Japan)" description "Relaxuma na Mainichi (Japan)" - rom ( name "Relaxuma na Mainichi (Japan).gba" size 4194304 crc 9F333017 md5 6A52067A659DF5E992F4323965C06C27 sha1 E6E649605603DC84B20934AC00F99A13DC8FF8CC ) + rom ( name "Relaxuma na Mainichi (Japan).gba" size 4194304 crc 9f333017 sha1 E6E649605603DC84B20934AC00F99A13DC8FF8CC ) ) game ( name "Rescue Heroes - Billy Blazes! (USA)" description "Rescue Heroes - Billy Blazes! (USA)" - rom ( name "Rescue Heroes - Billy Blazes! (USA).gba" size 4194304 crc 8111261C md5 4261AD698A20C73552BA8B75D184A4C9 sha1 481FD8AB9E8E980039E244BA31A6DFF057235210 flags verified ) + rom ( name "Rescue Heroes - Billy Blazes! (USA).gba" size 4194304 crc 8111261c sha1 481FD8AB9E8E980039E244BA31A6DFF057235210 flags verified ) +) + +game ( + name "Resident Evil 2 (Unknown) (Proto)" + description "Resident Evil 2 (Unknown) (Proto)" + rom ( name "Resident Evil 2 (Unknown) (Proto).gba" size 2908576 crc 26b5cf8b sha1 A70CF38071F639E783734BC9875ACE0EBD2C5180 ) ) game ( name "Revenge of Shinobi, The (USA)" description "Revenge of Shinobi, The (USA)" - rom ( name "Revenge of Shinobi, The (USA).gba" size 8388608 crc E9339304 md5 95B8CB63649F7BB62A2F9A6A39BF7388 sha1 22ADB84902A1D1B3B63986EDED3CC2A1BC9AA0B4 ) + rom ( name "Revenge of Shinobi, The (USA).gba" size 8388608 crc e9339304 sha1 22ADB84902A1D1B3B63986EDED3CC2A1BC9AA0B4 ) ) game ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It)" description "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc DDB4496A md5 DA720531328FC7F37EEF8C9B07D30A91 sha1 3340D93161D979544D3BB1BE7D7771C59964E409 flags verified ) + rom ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ddb4496a sha1 3340D93161D979544D3BB1BE7D7771C59964E409 flags verified ) ) game ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It) (Beta)" description "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc 58A3F0E1 md5 836C290E70DD96DB342B73D92B758B57 sha1 8C94CB30B7C870DE02C6D9BA72BD346C11326CF2 ) + rom ( name "Revenge of Shinobi, The (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc 58a3f0e1 sha1 8C94CB30B7C870DE02C6D9BA72BD346C11326CF2 ) +) + +game ( + name "Revenge of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" + description "Revenge of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Revenge of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 516ce770 sha1 846996F49910121B1DD2915C3BF203A767C6408A flags verified ) ) game ( name "Rhythm Tengoku (Japan)" description "Rhythm Tengoku (Japan)" - rom ( name "Rhythm Tengoku (Japan).gba" size 16777216 crc 349D7025 md5 F81F60FDB2FD774C72A170A1805DB52E sha1 67F8ADACFF79C15D028FFFD90DE3A77D9AD0602D flags verified ) + rom ( name "Rhythm Tengoku (Japan).gba" size 16777216 crc 349d7025 sha1 67F8ADACFF79C15D028FFFD90DE3A77D9AD0602D flags verified ) ) game ( name "Rhythm Tengoku (Japan) (Rev 1)" description "Rhythm Tengoku (Japan) (Rev 1)" - rom ( name "Rhythm Tengoku (Japan) (Rev 1).gba" size 16777216 crc A6CD88E1 md5 5B2D4704CE570D89AE956025BD1036DB sha1 E0AACA45045E408E7E1072BDE5B39278111E1952 ) + rom ( name "Rhythm Tengoku (Japan) (Rev 1).gba" size 16777216 crc a6cd88e1 sha1 E0AACA45045E408E7E1072BDE5B39278111E1952 ) ) game ( - name "Ripping Friends, The (USA, Europe)" - description "Ripping Friends, The (USA, Europe)" - rom ( name "Ripping Friends, The (USA, Europe).gba" size 4194304 crc 9850BF21 md5 8A23378FDCECACA9A648D378C1D9609D sha1 2688F1253C8E09EF3D5A3699AE2C015C82B1B16D flags verified ) + name "Rhythm Tengoku (Japan) (Demo) (Kiosk)" + description "Rhythm Tengoku (Japan) (Demo) (Kiosk)" + rom ( name "Rhythm Tengoku (Japan) (Demo) (Kiosk).gba" size 16777216 crc d6c7dc21 sha1 9EFDB1B03853CD45D056D8BC9FB2EFB4D97460D6 flags verified ) +) + +game ( + name "Ripping Friends, The - The World's Most Manly Men! (USA, Europe)" + description "Ripping Friends, The - The World's Most Manly Men! (USA, Europe)" + rom ( name "Ripping Friends, The - The World's Most Manly Men! (USA, Europe).gba" size 4194304 crc 9850bf21 sha1 2688F1253C8E09EF3D5A3699AE2C015C82B1B16D flags verified ) ) game ( name "River City Ransom EX (USA)" description "River City Ransom EX (USA)" - rom ( name "River City Ransom EX (USA).gba" size 4194304 crc 8686436E md5 0B95FB20B9F487EB64431E9DB9F75C7F sha1 64D0B723AE4EB3F3589B535FB935618F2769229F ) + rom ( name "River City Ransom EX (USA).gba" size 4194304 crc 8686436e sha1 64D0B723AE4EB3F3589B535FB935618F2769229F flags verified ) ) game ( name "Riviera - The Promised Land (USA)" description "Riviera - The Promised Land (USA)" - rom ( name "Riviera - The Promised Land (USA).gba" size 33554432 crc 4FB6958D md5 16B5F1C6F8567CBE42F7562FCCBB6426 sha1 30EE6610AAA77BCE2FFD8911058078147D61B925 ) + rom ( name "Riviera - The Promised Land (USA).gba" size 33554432 crc 4fb6958d sha1 30EE6610AAA77BCE2FFD8911058078147D61B925 flags verified ) ) game ( name "Riviera - Yakusoku no Chi Riviera (Japan)" description "Riviera - Yakusoku no Chi Riviera (Japan)" - rom ( name "Riviera - Yakusoku no Chi Riviera (Japan).gba" size 16777216 crc F73B840F md5 865B424538C65F2E5A96255408752EEF sha1 A29BCBDF6829561E78433C4A4F93DDDDC8BA0BCA ) + rom ( name "Riviera - Yakusoku no Chi Riviera (Japan).gba" size 16777216 crc f73b840f sha1 A29BCBDF6829561E78433C4A4F93DDDDC8BA0BCA flags verified ) +) + +game ( + name "Riviera - Yakusoku no Chi Riviera (Japan) (Rev 1)" + description "Riviera - Yakusoku no Chi Riviera (Japan) (Rev 1)" + rom ( name "Riviera - Yakusoku no Chi Riviera (Japan) (Rev 1).gba" size 16777216 crc 146097f2 sha1 7A053463964AF2FE03FAAA541B35A5F15E5E7BD9 flags verified ) ) game ( name "Road Rash - Jailbreak (USA)" description "Road Rash - Jailbreak (USA)" - rom ( name "Road Rash - Jailbreak (USA).gba" size 4194304 crc 8834AF99 md5 0A4DA0BBDAD29F2FAA5584B49B0A4F5D sha1 48150529172FF411E3E1BD38B9A74D8B32E5FA59 ) + rom ( name "Road Rash - Jailbreak (USA).gba" size 4194304 crc 8834af99 sha1 48150529172FF411E3E1BD38B9A74D8B32E5FA59 ) ) game ( name "Road Rash - Jailbreak (Europe) (En,Fr,De,Es,It)" description "Road Rash - Jailbreak (Europe) (En,Fr,De,Es,It)" - rom ( name "Road Rash - Jailbreak (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc F4693458 md5 CAA90EFA07194408BE977CFFF5F985BF sha1 414EEFF87DBC7196C6A8BCE60702DEE07DD4B006 ) -) - -game ( - name "Road Trip - Shifting Gears (USA)" - description "Road Trip - Shifting Gears (USA)" - rom ( name "Road Trip - Shifting Gears (USA).gba" size 4194304 crc 549BF1C5 md5 740F84915F53447D3AFB111ACDFB0677 sha1 9A332CEC82DFF9130248A2525D0151FAE52DD258 ) + rom ( name "Road Rash - Jailbreak (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc f4693458 sha1 414EEFF87DBC7196C6A8BCE60702DEE07DD4B006 ) ) game ( name "Robopon 2 - Cross Version (USA)" description "Robopon 2 - Cross Version (USA)" - rom ( name "Robopon 2 - Cross Version (USA).gba" size 8388608 crc 68D3023A md5 22A4E57B85F7413C1973D4BD5A19D5A3 sha1 85E0D6D154FAAE65CF70C5AD513C9267FCA8799D ) + rom ( name "Robopon 2 - Cross Version (USA).gba" size 8388608 crc 68d3023a sha1 85E0D6D154FAAE65CF70C5AD513C9267FCA8799D flags verified ) ) game ( name "Robopon 2 - Ring Version (USA)" description "Robopon 2 - Ring Version (USA)" - rom ( name "Robopon 2 - Ring Version (USA).gba" size 8388608 crc CA73E17A md5 6BCD924EEC542998CC12B6C3533EFB58 sha1 9667FE6F11B9C5D24B38A3E220E51D3A60B25444 ) + rom ( name "Robopon 2 - Ring Version (USA).gba" size 8388608 crc ca73e17a sha1 9667FE6F11B9C5D24B38A3E220E51D3A60B25444 ) ) game ( name "Robot Poncots 2 - Cross Version (Japan)" description "Robot Poncots 2 - Cross Version (Japan)" - rom ( name "Robot Poncots 2 - Cross Version (Japan).gba" size 8388608 crc 0C6F2B1B md5 3CF63F7903DC07CC6B0AFF9EFAB0886A sha1 CBB35559B4A9D79EFEE38F3AC3CF827281EF16B8 ) + rom ( name "Robot Poncots 2 - Cross Version (Japan).gba" size 8388608 crc 0c6f2b1b sha1 CBB35559B4A9D79EFEE38F3AC3CF827281EF16B8 ) ) game ( name "Robot Poncots 2 - Ring Version (Japan)" description "Robot Poncots 2 - Ring Version (Japan)" - rom ( name "Robot Poncots 2 - Ring Version (Japan).gba" size 8388608 crc 6002159C md5 3FBA6CB4144501BB21FD89789D21B23B sha1 614F2D7A798068E67EA8B81C0D472B693C4019C6 ) + rom ( name "Robot Poncots 2 - Ring Version (Japan).gba" size 8388608 crc 6002159c sha1 614F2D7A798068E67EA8B81C0D472B693C4019C6 ) ) game ( name "Robot Wars - Advanced Destruction (Europe) (En,Fr,De,Es,It)" description "Robot Wars - Advanced Destruction (Europe) (En,Fr,De,Es,It)" - rom ( name "Robot Wars - Advanced Destruction (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc CF8231BE md5 E506CC1B94AB876B7CAE86D4AD42A600 sha1 532F5FD5E22C140FC7CFBA519F6E50C786C8BC85 ) + rom ( name "Robot Wars - Advanced Destruction (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc cf8231be sha1 532F5FD5E22C140FC7CFBA519F6E50C786C8BC85 ) ) game ( name "Robot Wars - Advanced Destruction (USA)" description "Robot Wars - Advanced Destruction (USA)" - rom ( name "Robot Wars - Advanced Destruction (USA).gba" size 4194304 crc E6CB567D md5 677A6CC065D29722F5CE39CFECF863EC sha1 952ADF4E17865ABC2B983C79AD4080E9B4867370 ) + rom ( name "Robot Wars - Advanced Destruction (USA).gba" size 4194304 crc e6cb567d sha1 952ADF4E17865ABC2B983C79AD4080E9B4867370 ) ) game ( name "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl)" description "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 5EE9D6C5 md5 A4DA40EFE56A8CA4190B4F8F6B7B4F60 sha1 D9484E947D41D03DD3A5FE447872304B04106626 flags verified ) + rom ( name "Robot Wars - Extreme Destruction (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 5ee9d6c5 sha1 D9484E947D41D03DD3A5FE447872304B04106626 flags verified ) ) game ( name "Robotech - The Macross Saga (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Robotech - The Macross Saga (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Robotech - The Macross Saga (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 325A6596 md5 38AAC4616BB56F14DE9C0E7E8F86F0B9 sha1 3DBFE433A2376589A24754BB7337306C43176B34 flags verified ) + rom ( name "Robotech - The Macross Saga (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 325a6596 sha1 3DBFE433A2376589A24754BB7337306C43176B34 flags verified ) ) game ( name "Robots (USA)" description "Robots (USA)" - rom ( name "Robots (USA).gba" size 16777216 crc 5370AE1F md5 D41363A54AA5AC45ECAFF2DAFCB9372B sha1 D69A60A4BF7FCA1DC4204C959143524274CC826A ) + rom ( name "Robots (USA).gba" size 16777216 crc 5370ae1f sha1 D69A60A4BF7FCA1DC4204C959143524274CC826A ) ) game ( name "Robots (Europe) (En,Fr,De,Es,It)" description "Robots (Europe) (En,Fr,De,Es,It)" - rom ( name "Robots (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2ACBDB64 md5 538D0758F7D09A03F6631466B4D5A317 sha1 26BE826817F35433B3609D13EE75A3872E94D616 flags verified ) + rom ( name "Robots (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2acbdb64 sha1 26BE826817F35433B3609D13EE75A3872E94D616 flags verified ) ) game ( name "Robots (Japan)" description "Robots (Japan)" - rom ( name "Robots (Japan).gba" size 16777216 crc 1BEB9E91 md5 155753526498F1A93B7A2850368DA3E4 sha1 B1A670DAF53D47F237A4078388178C16C843D4DC ) + rom ( name "Robots (Japan).gba" size 16777216 crc 1beb9e91 sha1 B1A670DAF53D47F237A4078388178C16C843D4DC ) ) game ( - name "Rock n' Roll Racing (USA)" - description "Rock n' Roll Racing (USA)" - rom ( name "Rock n' Roll Racing (USA).gba" size 4194304 crc 15F2DD16 md5 25A0842E3DB8B40EEB39DE83285CC13A sha1 44BE0A6869F3495C23A5770993116AC80B554BAC ) + name "Rock 'N Roll Racing (USA)" + description "Rock 'N Roll Racing (USA)" + rom ( name "Rock 'N Roll Racing (USA).gba" size 4194304 crc 15f2dd16 sha1 44BE0A6869F3495C23A5770993116AC80B554BAC ) ) game ( - name "Rock n' Roll Racing (Europe)" - description "Rock n' Roll Racing (Europe)" - rom ( name "Rock n' Roll Racing (Europe).gba" size 4194304 crc 53D1A142 md5 4C56E0D7FD251AB8EBE562C25E0DDFDF sha1 384C95D541E3BAE37194304D615BEFB8242A1F54 ) + name "Rock 'N Roll Racing (Europe)" + description "Rock 'N Roll Racing (Europe)" + rom ( name "Rock 'N Roll Racing (Europe).gba" size 4194304 crc 53d1a142 sha1 384C95D541E3BAE37194304D615BEFB8242A1F54 ) ) game ( name "Rock'em Sock'em Robots (USA)" description "Rock'em Sock'em Robots (USA)" - rom ( name "Rock'em Sock'em Robots (USA).gba" size 4194304 crc C8896C62 md5 567B56A215FF295ACA69AC85C4F08273 sha1 77CDE5839DD0DBEC2DFDA4062CAAB969B7308672 ) + rom ( name "Rock'em Sock'em Robots (USA).gba" size 4194304 crc c8896c62 sha1 77CDE5839DD0DBEC2DFDA4062CAAB969B7308672 ) ) game ( name "Rock'em Sock'em Robots (Europe) (En,Fr,De,Es,It)" description "Rock'em Sock'em Robots (Europe) (En,Fr,De,Es,It)" - rom ( name "Rock'em Sock'em Robots (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6AD6E952 md5 5539D5A40407F017FE2999663FE919D5 sha1 841AC8FF060AD9634E5407CD599F0D0E49630894 ) -) - -game ( - name "Rocket Power - Beach Bandits (USA) (v0.14) (Beta)" - description "Rocket Power - Beach Bandits (USA) (v0.14) (Beta)" - rom ( name "Rocket Power - Beach Bandits (USA) (v0.14) (Beta).gba" size 4101616 crc D3755452 md5 A9CB22CD3729B8116C00DE9881BB9CAE sha1 E69CEE154B563358952DCAA6731B5D76F43EA8A7 ) + rom ( name "Rock'em Sock'em Robots (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6ad6e952 sha1 841AC8FF060AD9634E5407CD599F0D0E49630894 ) ) game ( name "Rocket Power - Beach Bandits (USA, Europe)" description "Rocket Power - Beach Bandits (USA, Europe)" - rom ( name "Rocket Power - Beach Bandits (USA, Europe).gba" size 4194304 crc 13695669 md5 6C1DE42661CA9CA859620753D8E12083 sha1 7D2D12E7F85793FE787A342B00D63685A56230B6 flags verified ) + rom ( name "Rocket Power - Beach Bandits (USA, Europe).gba" size 4194304 crc 13695669 sha1 7D2D12E7F85793FE787A342B00D63685A56230B6 flags verified ) +) + +game ( + name "Rocket Power - Beach Bandits (USA, Europe) (v0.14) (Beta)" + description "Rocket Power - Beach Bandits (USA, Europe) (v0.14) (Beta)" + rom ( name "Rocket Power - Beach Bandits (USA, Europe) (v0.14) (Beta).gba" size 4101616 crc d3755452 sha1 E69CEE154B563358952DCAA6731B5D76F43EA8A7 ) ) game ( name "Rocket Power - Dream Scheme (USA, Europe)" description "Rocket Power - Dream Scheme (USA, Europe)" - rom ( name "Rocket Power - Dream Scheme (USA, Europe).gba" size 4194304 crc 93961CB2 md5 B14194832A55A7197916EDB0BB92BEA3 sha1 1552DD95A0352A45353292A1A4AE711857FB7510 flags verified ) + rom ( name "Rocket Power - Dream Scheme (USA, Europe).gba" size 4194304 crc 93961cb2 sha1 1552DD95A0352A45353292A1A4AE711857FB7510 flags verified ) ) game ( name "Rocket Power - Le Cauchemar d'Otto (France)" description "Rocket Power - Le Cauchemar d'Otto (France)" - rom ( name "Rocket Power - Le Cauchemar d'Otto (France).gba" size 4194304 crc 17B8B786 md5 29680A4AA183EB50AA888AB49CB2FF8B sha1 92D89A22A0246F5E04F32B4527E4CD3D839D257F ) + rom ( name "Rocket Power - Le Cauchemar d'Otto (France).gba" size 4194304 crc 17b8b786 sha1 92D89A22A0246F5E04F32B4527E4CD3D839D257F ) ) game ( name "Rocket Power - Zero Gravity Zone (USA)" description "Rocket Power - Zero Gravity Zone (USA)" - rom ( name "Rocket Power - Zero Gravity Zone (USA).gba" size 8388608 crc 26D62D32 md5 ACAC2E3C7752F2407D787F084C0BF6F8 sha1 2E8FCF7AFE49B57C2527F31288198A4B93DF8BEC flags verified ) + rom ( name "Rocket Power - Zero Gravity Zone (USA).gba" size 8388608 crc 26d62d32 sha1 2E8FCF7AFE49B57C2527F31288198A4B93DF8BEC flags verified ) ) game ( name "Rockman & Forte (Japan)" description "Rockman & Forte (Japan)" - rom ( name "Rockman & Forte (Japan).gba" size 8388608 crc CE2B48C4 md5 93D1BA78096704C5DCFA993337469542 sha1 F8EB056745E8B58C1EF4BFEF995C77A27AADC57A ) + rom ( name "Rockman & Forte (Japan).gba" size 8388608 crc ce2b48c4 sha1 F8EB056745E8B58C1EF4BFEF995C77A27AADC57A flags verified ) ) game ( name "Rockman EXE 4 - Tournament Blue Moon (Japan)" description "Rockman EXE 4 - Tournament Blue Moon (Japan)" - rom ( name "Rockman EXE 4 - Tournament Blue Moon (Japan).gba" size 8388608 crc ED7C5B50 md5 73DDEA9ABD509F650ADDD4998E86976F sha1 C4302ADA1FF652C740DFF51DF6DEC801FD5B7854 ) + rom ( name "Rockman EXE 4 - Tournament Blue Moon (Japan).gba" size 8388608 crc ed7c5b50 sha1 C4302ADA1FF652C740DFF51DF6DEC801FD5B7854 flags verified ) ) game ( name "Rockman EXE 4 - Tournament Red Sun (Japan)" description "Rockman EXE 4 - Tournament Red Sun (Japan)" - rom ( name "Rockman EXE 4 - Tournament Red Sun (Japan).gba" size 8388608 crc 6A51907D md5 60F4B5B05656DC3760A3EAB6CED61E31 sha1 7EFE1B77C39B58E1400AF5392BEC313003FA7861 ) + rom ( name "Rockman EXE 4 - Tournament Red Sun (Japan).gba" size 8388608 crc 6a51907d sha1 7EFE1B77C39B58E1400AF5392BEC313003FA7861 flags verified ) ) game ( name "Rockman EXE 4 - Tournament Red Sun (Japan) (Rev 1)" description "Rockman EXE 4 - Tournament Red Sun (Japan) (Rev 1)" - rom ( name "Rockman EXE 4 - Tournament Red Sun (Japan) (Rev 1).gba" size 8388608 crc CF0E8B05 md5 A2492CA979C2C616AD38E81E5DC3E655 sha1 03A22270B7068EE7762726DA4519C20F584951B7 ) + rom ( name "Rockman EXE 4 - Tournament Red Sun (Japan) (Rev 1).gba" size 8388608 crc cf0e8b05 sha1 03A22270B7068EE7762726DA4519C20F584951B7 ) ) game ( name "Rockman EXE 4.5 - Real Operation (Japan)" description "Rockman EXE 4.5 - Real Operation (Japan)" - rom ( name "Rockman EXE 4.5 - Real Operation (Japan).gba" size 8388608 crc A646601B md5 0F82BB24585C9EC64E99394C9D316315 sha1 F89EF4CA8EC1823EB75FA184F2D0F9E66CC78A59 ) + rom ( name "Rockman EXE 4.5 - Real Operation (Japan).gba" size 8388608 crc a646601b sha1 F89EF4CA8EC1823EB75FA184F2D0F9E66CC78A59 flags verified ) +) + +game ( + name "Rockman EXE 4.5 - Real Operation (Japan) (Wii U Virtual Console)" + description "Rockman EXE 4.5 - Real Operation (Japan) (Wii U Virtual Console)" + rom ( name "Rockman EXE 4.5 - Real Operation (Japan) (Wii U Virtual Console).gba" size 8388608 crc 9ad45607 sha1 6EFCD1F8EF84F6F90F265A33CA3D469FB6C41E7F flags verified ) ) game ( name "Rockman EXE 5 - Team of Blues (Japan)" description "Rockman EXE 5 - Team of Blues (Japan)" - rom ( name "Rockman EXE 5 - Team of Blues (Japan).gba" size 8388608 crc C73F23C0 md5 0A4F344622606FB7E6470C169CF934F6 sha1 85870CCFC3B26EE12A65EB95A844123033D7F47E ) + rom ( name "Rockman EXE 5 - Team of Blues (Japan).gba" size 8388608 crc c73f23c0 sha1 85870CCFC3B26EE12A65EB95A844123033D7F47E ) ) game ( name "Rockman EXE 5 - Team of Colonel (Japan)" description "Rockman EXE 5 - Team of Colonel (Japan)" - rom ( name "Rockman EXE 5 - Team of Colonel (Japan).gba" size 8388608 crc 16842635 md5 504DC19D9F102F1F202AE76DECB12998 sha1 2FA0CF264166848BEDFDDB8077CA1177C424A11A ) + rom ( name "Rockman EXE 5 - Team of Colonel (Japan).gba" size 8388608 crc 16842635 sha1 2FA0CF264166848BEDFDDB8077CA1177C424A11A flags verified ) ) game ( name "Rockman EXE 6 - Dennoujuu Falzar (Japan)" description "Rockman EXE 6 - Dennoujuu Falzar (Japan)" - rom ( name "Rockman EXE 6 - Dennoujuu Falzar (Japan).gba" size 8388608 crc 2DFB603E md5 0E3ED3A6CC2F201897C58CB31D43A35F sha1 D1CE0ECC8E241A716274B9FB1B6EB07FB42DD166 ) + rom ( name "Rockman EXE 6 - Dennoujuu Falzar (Japan).gba" size 8388608 crc 2dfb603e sha1 D1CE0ECC8E241A716274B9FB1B6EB07FB42DD166 ) +) + +game ( + name "Rockman EXE 6 - Dennoujuu Falzar (Japan) (Wii U Virtual Console)" + description "Rockman EXE 6 - Dennoujuu Falzar (Japan) (Wii U Virtual Console)" + rom ( name "Rockman EXE 6 - Dennoujuu Falzar (Japan) (Wii U Virtual Console).gba" size 16777216 crc 36c9dd6f sha1 5BBE25423A3042209B16389E2D1EDDDA4A803DFD flags verified ) ) game ( name "Rockman EXE 6 - Dennoujuu Gregar (Japan)" description "Rockman EXE 6 - Dennoujuu Gregar (Japan)" - rom ( name "Rockman EXE 6 - Dennoujuu Gregar (Japan).gba" size 8388608 crc 6285918A md5 053CF73404DCC39BE7CBD77C8E833150 sha1 48472EFA4657DB47CD3B6D146D9FE9FE730C4439 ) + rom ( name "Rockman EXE 6 - Dennoujuu Gregar (Japan).gba" size 8388608 crc 6285918a sha1 48472EFA4657DB47CD3B6D146D9FE9FE730C4439 flags verified ) +) + +game ( + name "Rockman EXE 6 - Dennoujuu Gregar (Japan) (Wii U Virtual Console)" + description "Rockman EXE 6 - Dennoujuu Gregar (Japan) (Wii U Virtual Console)" + rom ( name "Rockman EXE 6 - Dennoujuu Gregar (Japan) (Wii U Virtual Console).gba" size 8388608 crc d0fdbefb sha1 678787C7D7CBEE119EB524211487FB5DCD01426B flags verified ) ) game ( name "Rockman EXE Battle Chip GP (Japan)" description "Rockman EXE Battle Chip GP (Japan)" - rom ( name "Rockman EXE Battle Chip GP (Japan).gba" size 8388608 crc 9217FB18 md5 E7970A74B423E6B4E842EC640EBA3630 sha1 F39992851257A1567F3BFCA81DD269F37469BB67 ) + rom ( name "Rockman EXE Battle Chip GP (Japan).gba" size 8388608 crc 9217fb18 sha1 F39992851257A1567F3BFCA81DD269F37469BB67 ) ) game ( name "Rockman Zero (Japan)" description "Rockman Zero (Japan)" - rom ( name "Rockman Zero (Japan).gba" size 8388608 crc FF2A67B1 md5 A8110C3928CAFFB9A73B48A009F9044F sha1 B07DFD200C49739D33598F6142157D659997E097 ) + rom ( name "Rockman Zero (Japan).gba" size 8388608 crc ff2a67b1 sha1 B07DFD200C49739D33598F6142157D659997E097 flags verified ) ) game ( name "Rockman Zero 2 (Japan)" description "Rockman Zero 2 (Japan)" - rom ( name "Rockman Zero 2 (Japan).gba" size 8388608 crc 9B5C8A4C md5 4B59CEEA0351DEFB6EB4BAD1DCFB38BD sha1 4D5063C9729EF32F6470088FE4D3CDE5375BAF3C flags verified ) + rom ( name "Rockman Zero 2 (Japan).gba" size 8388608 crc 9b5c8a4c sha1 4D5063C9729EF32F6470088FE4D3CDE5375BAF3C flags verified ) ) game ( name "Rockman Zero 3 (Japan)" description "Rockman Zero 3 (Japan)" - rom ( name "Rockman Zero 3 (Japan).gba" size 8388608 crc 5A2C41A9 md5 AA9AEEA52DE34B25351E76D70BFBE2B8 sha1 FF7A801776DC76E6D8C7EF73A6660AE732934A3F flags verified ) + rom ( name "Rockman Zero 3 (Japan).gba" size 8388608 crc 5a2c41a9 sha1 FF7A801776DC76E6D8C7EF73A6660AE732934A3F flags verified ) ) game ( name "Rockman Zero 4 (Japan)" description "Rockman Zero 4 (Japan)" - rom ( name "Rockman Zero 4 (Japan).gba" size 16777216 crc ECE42D0E md5 D4E3855B1E6630921DE0E188AC974EBF sha1 DC554ADCD18EB78132B4FB724A1C69779F75D114 ) -) - -game ( - name "Rocky (Europe) (En,Fr,De,Es,It)" - description "Rocky (Europe) (En,Fr,De,Es,It)" - rom ( name "Rocky (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc D2E55FB5 md5 5AE5F07BD435A1BAB5AD2D505AAAF035 sha1 AE6A9B231CD155E1F1EC0EB3F02A5C2C9CB08636 ) + rom ( name "Rockman Zero 4 (Japan).gba" size 16777216 crc ece42d0e sha1 DC554ADCD18EB78132B4FB724A1C69779F75D114 ) ) game ( name "Rocky (USA) (En,Fr,De,Es,It)" description "Rocky (USA) (En,Fr,De,Es,It)" - rom ( name "Rocky (USA) (En,Fr,De,Es,It).gba" size 8388608 crc C8F4FF1B md5 D275E7110627F4456DC8D544166B55E9 sha1 50A2B4D10542274D5A37C6CD5C8541A3BA8D5681 ) + rom ( name "Rocky (USA) (En,Fr,De,Es,It).gba" size 8388608 crc c8f4ff1b sha1 50A2B4D10542274D5A37C6CD5C8541A3BA8D5681 ) +) + +game ( + name "Rocky (Europe) (En,Fr,De,Es,It)" + description "Rocky (Europe) (En,Fr,De,Es,It)" + rom ( name "Rocky (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d2e55fb5 sha1 AE6A9B231CD155E1F1EC0EB3F02A5C2C9CB08636 ) ) game ( name "RPG Tsukuru Advance (Japan)" description "RPG Tsukuru Advance (Japan)" - rom ( name "RPG Tsukuru Advance (Japan).gba" size 8388608 crc E7FC81D0 md5 2DD88E9133F723098C6E8107217EC0C4 sha1 BB8781959C82E58963B40263061D4A3155F6E880 ) + rom ( name "RPG Tsukuru Advance (Japan).gba" size 8388608 crc e7fc81d0 sha1 BB8781959C82E58963B40263061D4A3155F6E880 ) ) game ( name "Rugrats - Castle Capers (USA, Europe)" description "Rugrats - Castle Capers (USA, Europe)" - rom ( name "Rugrats - Castle Capers (USA, Europe).gba" size 4194304 crc 8AABD86A md5 01529E7A20314AB1479AB2B91CCFCF49 sha1 A9D37415567B3D441C9C9312C75FD8ECAEB9ECE1 flags verified ) + rom ( name "Rugrats - Castle Capers (USA, Europe).gba" size 4194304 crc 8aabd86a sha1 A9D37415567B3D441C9C9312C75FD8ECAEB9ECE1 flags verified ) ) game ( name "Rugrats - Go Wild (USA, Europe)" description "Rugrats - Go Wild (USA, Europe)" - rom ( name "Rugrats - Go Wild (USA, Europe).gba" size 4194304 crc 52A33375 md5 95ECB39A21E97BA21B1A992EAD24767E sha1 4691B090846530C7AE4CE43562F63B3E543AEFD9 flags verified ) + rom ( name "Rugrats - Go Wild (USA, Europe).gba" size 4194304 crc 52a33375 sha1 4691B090846530C7AE4CE43562F63B3E543AEFD9 flags verified ) ) game ( name "Rugrats - I Gotta Go Party (USA, Europe)" description "Rugrats - I Gotta Go Party (USA, Europe)" - rom ( name "Rugrats - I Gotta Go Party (USA, Europe).gba" size 4194304 crc DF167D1D md5 9E7798ABBD16A87548C380891ACCAE28 sha1 32B9B14C7ECBF57C07866B070C209047A481B584 flags verified ) + rom ( name "Rugrats - I Gotta Go Party (USA, Europe).gba" size 4194304 crc df167d1d sha1 32B9B14C7ECBF57C07866B070C209047A481B584 flags verified ) ) game ( name "Rugrats - Travesuras en el Castillo (Spain)" description "Rugrats - Travesuras en el Castillo (Spain)" - rom ( name "Rugrats - Travesuras en el Castillo (Spain).gba" size 4194304 crc 0BCAB7D0 md5 C05CCE26A2E6D11E9185B91515A19228 sha1 89448F91091A46DEAEBADDBAAADA43522F387465 ) + rom ( name "Rugrats - Travesuras en el Castillo (Spain).gba" size 4194304 crc 0bcab7d0 sha1 89448F91091A46DEAEBADDBAAADA43522F387465 ) ) game ( name "Sabre Wulf (Europe) (En,Fr,De)" description "Sabre Wulf (Europe) (En,Fr,De)" - rom ( name "Sabre Wulf (Europe) (En,Fr,De).gba" size 8388608 crc 9E3EAB8D md5 6714CE5D3C2F6988776EC92E36B9DDDA sha1 49084091F79DFEC46B4FBCE62E897985CAFBC147 flags verified ) + rom ( name "Sabre Wulf (Europe) (En,Fr,De).gba" size 8388608 crc 9e3eab8d sha1 49084091F79DFEC46B4FBCE62E897985CAFBC147 flags verified ) ) game ( name "Sabre Wulf (USA)" description "Sabre Wulf (USA)" - rom ( name "Sabre Wulf (USA).gba" size 8388608 crc 73787A16 md5 B4B8E9FBB47A947850F127465C8BEE40 sha1 D8803E742253E4B6712BDF07D49D3D7ED7FB23D6 ) + rom ( name "Sabre Wulf (USA).gba" size 8388608 crc 73787a16 sha1 D8803E742253E4B6712BDF07D49D3D7ED7FB23D6 ) ) game ( - name "Sabrina - The Teenage Witch - Potion Commotion (USA) (En,Fr,Es)" - description "Sabrina - The Teenage Witch - Potion Commotion (USA) (En,Fr,Es)" - rom ( name "Sabrina - The Teenage Witch - Potion Commotion (USA) (En,Fr,Es).gba" size 4194304 crc A39EDD2F md5 30AF5EF768089D20FF9BC0D13EFFDAFF sha1 2E4554C5F26F0DAC826F8A5B527595A00C83551C flags verified ) + name "Sabrina the Teenage Witch - Potion Commotion (USA) (En,Fr,Es)" + description "Sabrina the Teenage Witch - Potion Commotion (USA) (En,Fr,Es)" + rom ( name "Sabrina the Teenage Witch - Potion Commotion (USA) (En,Fr,Es).gba" size 4194304 crc a39edd2f sha1 2E4554C5F26F0DAC826F8A5B527595A00C83551C flags verified ) ) game ( - name "Sabrina - The Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl)" - description "Sabrina - The Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sabrina - The Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc CAA8225B md5 10EBB8E13D6639E9425D172888389FA0 sha1 686E0C03B7729A2904A851BE3091CBCC98CAFFC6 ) + name "Sabrina the Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl)" + description "Sabrina the Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Sabrina the Teenage Witch - Potion Commotion (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc caa8225b sha1 686E0C03B7729A2904A851BE3091CBCC98CAFFC6 flags verified ) ) game ( name "Saibara Rieko no Dendou Mahjong (Japan)" description "Saibara Rieko no Dendou Mahjong (Japan)" - rom ( name "Saibara Rieko no Dendou Mahjong (Japan).gba" size 4194304 crc 02B9F82D md5 F4D468093CF7800C97F5AA8B38D03962 sha1 ED18C7D4FDAB368A32DE27C0379BF77EDA3D3F91 ) + rom ( name "Saibara Rieko no Dendou Mahjong (Japan).gba" size 4194304 crc 02b9f82d sha1 ED18C7D4FDAB368A32DE27C0379BF77EDA3D3F91 ) ) game ( name "Sakura Momoko no UkiUki Carnival (Japan)" description "Sakura Momoko no UkiUki Carnival (Japan)" - rom ( name "Sakura Momoko no UkiUki Carnival (Japan).gba" size 8388608 crc B0A75590 md5 3CD35AE85906BFEA4BB5A46A5E7879BC sha1 67D86EE85F2959DDC376188223EA264062EC9952 ) + rom ( name "Sakura Momoko no UkiUki Carnival (Japan).gba" size 8388608 crc b0a75590 sha1 67D86EE85F2959DDC376188223EA264062EC9952 ) ) game ( name "Salt Lake 2002 (USA) (En,Fr,De,Es,It,Nl)" description "Salt Lake 2002 (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Salt Lake 2002 (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 4603205A md5 7A5B0F8F5CCC714DC754CEF30190159E sha1 377DBCE06068147260D9CF05225E2504230FFF2B ) + rom ( name "Salt Lake 2002 (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 4603205a sha1 377DBCE06068147260D9CF05225E2504230FFF2B ) ) game ( name "Salt Lake 2002 (Europe) (En,Fr,De,Es,It,Nl)" description "Salt Lake 2002 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Salt Lake 2002 (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 68836DF9 md5 75C1C26D74BF1ECD4E8C2D1E84DB804F sha1 24A5692CECDB2AB80E8D35435071EB3F4A38EFF2 flags verified ) -) - -game ( - name "Samsara Naga 1x2 (Japan) (Rev 2)" - description "Samsara Naga 1x2 (Japan) (Rev 2)" - rom ( name "Samsara Naga 1x2 (Japan) (Rev 2).gba" size 8388608 crc B3780A4F md5 0EB87D04C5BE8AB25E8F2CF211650683 sha1 B18E525A3A4B008D76A9C5A7B47CDD4A03B0BAEC ) + rom ( name "Salt Lake 2002 (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 68836df9 sha1 24A5692CECDB2AB80E8D35435071EB3F4A38EFF2 flags verified ) ) game ( name "Samsara Naga 1x2 (Japan)" description "Samsara Naga 1x2 (Japan)" - rom ( name "Samsara Naga 1x2 (Japan).gba" size 8388608 crc 68076B62 md5 BBE5C39533AAF3C912CF1B3EE9FEE2EA sha1 D4023E0A54A48999A46BF6B63C3BB91E3A795738 ) + rom ( name "Samsara Naga 1x2 (Japan).gba" size 8388608 crc 68076b62 sha1 D4023E0A54A48999A46BF6B63C3BB91E3A795738 ) +) + +game ( + name "Samsara Naga 1x2 (Japan) (Rev 2)" + description "Samsara Naga 1x2 (Japan) (Rev 2)" + rom ( name "Samsara Naga 1x2 (Japan) (Rev 2).gba" size 8388608 crc b3780a4f sha1 B18E525A3A4B008D76A9C5A7B47CDD4A03B0BAEC flags verified ) +) + +game ( + name "Samsara Naga 1x2 (Japan) (Rev 1)" + description "Samsara Naga 1x2 (Japan) (Rev 1)" + rom ( name "Samsara Naga 1x2 (Japan) (Rev 1).gba" size 8388608 crc a79872fe sha1 2C0ECC0FE283DD1F912C5CA24D1272795109398F flags verified ) ) game ( name "Samurai Deeper Kyo (Japan)" description "Samurai Deeper Kyo (Japan)" - rom ( name "Samurai Deeper Kyo (Japan).gba" size 8388608 crc 56EAD477 md5 447BD53611AD8CF526895CCB46303F03 sha1 AE8C413EFDB57EE4D4AA2BEDD6C2C91CCE4F711D flags verified ) + rom ( name "Samurai Deeper Kyo (Japan).gba" size 8388608 crc 56ead477 sha1 AE8C413EFDB57EE4D4AA2BEDD6C2C91CCE4F711D flags verified ) ) game ( name "Samurai Deeper Kyo (USA)" description "Samurai Deeper Kyo (USA)" - rom ( name "Samurai Deeper Kyo (USA).gba" size 8388608 crc 4AB65478 md5 9D01C59ABE3149CA2A9C0900571E6914 sha1 57FEAABCCB511280D18C44C5F2011E45321ECD29 ) + rom ( name "Samurai Deeper Kyo (USA).gba" size 8388608 crc 4ab65478 sha1 57FEAABCCB511280D18C44C5F2011E45321ECD29 ) ) game ( name "Samurai Evolution - Oukoku Geist (Japan)" description "Samurai Evolution - Oukoku Geist (Japan)" - rom ( name "Samurai Evolution - Oukoku Geist (Japan).gba" size 4194304 crc C0F54C65 md5 B21148257D0AEADAF9C6CB35B857473E sha1 13AEF211CF2DA6FCD942CADD6A887EB4FE600610 ) + rom ( name "Samurai Evolution - Oukoku Geist (Japan).gba" size 4194304 crc c0f54c65 sha1 13AEF211CF2DA6FCD942CADD6A887EB4FE600610 flags verified ) ) game ( name "Samurai Jack - The Amulet of Time (USA, Europe)" description "Samurai Jack - The Amulet of Time (USA, Europe)" - rom ( name "Samurai Jack - The Amulet of Time (USA, Europe).gba" size 8388608 crc B250366C md5 473C1F5BD97F5F96A5B19F3E18121D81 sha1 27A5604B4AA89D2FEC216AEAC2B99E76165F531F ) + rom ( name "Samurai Jack - The Amulet of Time (USA, Europe).gba" size 8388608 crc b250366c sha1 27A5604B4AA89D2FEC216AEAC2B99E76165F531F flags verified ) ) game ( name "Sangokushi (Japan)" description "Sangokushi (Japan)" - rom ( name "Sangokushi (Japan).gba" size 8388608 crc F3D3C239 md5 10E33FD51BAC0B0C3523EDDBCD0EAF56 sha1 8A22032C016F876753EC50CC194E90D9397E297B ) + rom ( name "Sangokushi (Japan).gba" size 8388608 crc f3d3c239 sha1 8A22032C016F876753EC50CC194E90D9397E297B ) ) game ( name "Sangokushi - Eiketsuden (Japan)" description "Sangokushi - Eiketsuden (Japan)" - rom ( name "Sangokushi - Eiketsuden (Japan).gba" size 4194304 crc A4A1C956 md5 76CCCC133899422854687E672F335CBD sha1 32B5EEB82B0FFA14ADC54223FB9E423EFE8A1AA4 ) + rom ( name "Sangokushi - Eiketsuden (Japan).gba" size 4194304 crc a4a1c956 sha1 32B5EEB82B0FFA14ADC54223FB9E423EFE8A1AA4 ) ) game ( name "Sangokushi - Koumeiden (Japan)" description "Sangokushi - Koumeiden (Japan)" - rom ( name "Sangokushi - Koumeiden (Japan).gba" size 8388608 crc 765043FF md5 4481174EBB5DC407F2BCB5FCB0C01BEE sha1 0C9D3354E13E9EE2E35BDFB564714B960101EA0D ) + rom ( name "Sangokushi - Koumeiden (Japan).gba" size 8388608 crc 765043ff sha1 0C9D3354E13E9EE2E35BDFB564714B960101EA0D ) ) game ( name "Sanrio Puroland - All Characters (Japan)" description "Sanrio Puroland - All Characters (Japan)" - rom ( name "Sanrio Puroland - All Characters (Japan).gba" size 4194304 crc 5257BD92 md5 48822A0B1D0D90B842F6EE1C80AB08C1 sha1 1BA3B2D7A34488CDA9645A3D470CF6249DE6C5D8 ) + rom ( name "Sanrio Puroland - All Characters (Japan).gba" size 4194304 crc 5257bd92 sha1 1BA3B2D7A34488CDA9645A3D470CF6249DE6C5D8 ) ) game ( name "Santa Claus Jr. Advance (Europe)" description "Santa Claus Jr. Advance (Europe)" - rom ( name "Santa Claus Jr. Advance (Europe).gba" size 4194304 crc FE3E6769 md5 C0DFC8C07F3ABA36BE5F40EDB996F679 sha1 60D6B482C4BE9FB61A172F3864C9B35AFC275980 flags verified ) + rom ( name "Santa Claus Jr. Advance (Europe).gba" size 4194304 crc fe3e6769 sha1 60D6B482C4BE9FB61A172F3864C9B35AFC275980 flags verified ) ) game ( name "Santa Claus Jr. Advance (Europe) (Beta)" description "Santa Claus Jr. Advance (Europe) (Beta)" - rom ( name "Santa Claus Jr. Advance (Europe) (Beta).gba" size 4194304 crc 38D896BD md5 27D0A58227E4C5C6E8481FAA4D541FC0 sha1 E94D0845B3B1BA5A275652E5043F0A49C2F23CDC ) + rom ( name "Santa Claus Jr. Advance (Europe) (Beta).gba" size 4194304 crc 38d896bd sha1 E94D0845B3B1BA5A275652E5043F0A49C2F23CDC ) ) game ( name "Santa Claus Saves the Earth (Europe)" description "Santa Claus Saves the Earth (Europe)" - rom ( name "Santa Claus Saves the Earth (Europe).gba" size 4194304 crc 49E012A8 md5 FBD187500572B8AF52C505F4F8A4BD9B sha1 11F04E0655F0C2617706744FA3D27ECD2A382F8B ) + rom ( name "Santa Claus Saves the Earth (Europe).gba" size 4194304 crc 49e012a8 sha1 11F04E0655F0C2617706744FA3D27ECD2A382F8B ) ) game ( name "Santa Clause 3, The - The Escape Clause (USA)" description "Santa Clause 3, The - The Escape Clause (USA)" - rom ( name "Santa Clause 3, The - The Escape Clause (USA).gba" size 8388608 crc 206933F5 md5 B3A719F647A84F5496C0AD97D5DE6370 sha1 2163907F0A197F4164C9B9041FB1175D3C608750 ) + rom ( name "Santa Clause 3, The - The Escape Clause (USA).gba" size 8388608 crc 206933f5 sha1 2163907F0A197F4164C9B9041FB1175D3C608750 ) ) game ( name "Scan Hunter - Sennen Kaigyo o Oe! (Japan)" description "Scan Hunter - Sennen Kaigyo o Oe! (Japan)" - rom ( name "Scan Hunter - Sennen Kaigyo o Oe! (Japan).gba" size 8388608 crc BCD9AA71 md5 A6CF95A910AC4039DCC49F5C89401B79 sha1 3C7F06C68935A8FFC19C5D091C4F0798E9465C3D ) + rom ( name "Scan Hunter - Sennen Kaigyo o Oe! (Japan).gba" size 8388608 crc dcfddff7 sha1 9D5B7C26242F98EBC175675EBFF6F75DBC792247 flags verified ) ) game ( name "Scooby-Doo (USA)" description "Scooby-Doo (USA)" - rom ( name "Scooby-Doo (USA).gba" size 4194304 crc 22D993C6 md5 F41B1B8BC38289DC25082D0FD7D376D1 sha1 BC641955E8BEA6B55CBB4FCAC5C21031CE274188 ) + rom ( name "Scooby-Doo (USA).gba" size 4194304 crc 22d993c6 sha1 BC641955E8BEA6B55CBB4FCAC5C21031CE274188 ) ) game ( name "Scooby-Doo (France)" description "Scooby-Doo (France)" - rom ( name "Scooby-Doo (France).gba" size 4194304 crc CEEFC038 md5 365A0A06F8374809EC225AB2CFC255E4 sha1 3EBFAF2FF28310E138A8CF38A32708AA26217659 ) + rom ( name "Scooby-Doo (France).gba" size 4194304 crc ceefc038 sha1 3EBFAF2FF28310E138A8CF38A32708AA26217659 ) ) game ( name "Scooby-Doo (Germany)" description "Scooby-Doo (Germany)" - rom ( name "Scooby-Doo (Germany).gba" size 4194304 crc 03A07291 md5 83DB8A484F48D8FAB9638FDE47853800 sha1 E46D519804732B8298E171A31FEDCB46CBA8DD29 ) + rom ( name "Scooby-Doo (Germany).gba" size 4194304 crc 03a07291 sha1 E46D519804732B8298E171A31FEDCB46CBA8DD29 ) ) game ( name "Scooby-Doo (Europe)" description "Scooby-Doo (Europe)" - rom ( name "Scooby-Doo (Europe).gba" size 4194304 crc E5AC4BB9 md5 7FCA5F2C94769DB36CACF8BC599F659E sha1 00C6EC5C8283F27B36BD302BD11D8169D1CFC502 ) + rom ( name "Scooby-Doo (Europe).gba" size 4194304 crc e5ac4bb9 sha1 00C6EC5C8283F27B36BD302BD11D8169D1CFC502 ) ) game ( name "Scooby-Doo (Spain)" description "Scooby-Doo (Spain)" - rom ( name "Scooby-Doo (Spain).gba" size 4194304 crc E5261946 md5 F15C91BC7484532FB4A762250BF6D48A sha1 9EEDC6C336A4F1CD3B54A2D5E63E63BABE82E162 ) + rom ( name "Scooby-Doo (Spain).gba" size 4194304 crc e5261946 sha1 9EEDC6C336A4F1CD3B54A2D5E63E63BABE82E162 ) ) game ( name "Scooby-Doo 2 - Monsters Unleashed (USA, Europe)" description "Scooby-Doo 2 - Monsters Unleashed (USA, Europe)" - rom ( name "Scooby-Doo 2 - Monsters Unleashed (USA, Europe).gba" size 8388608 crc 9FF01DDD md5 36A7BB733C433AFAF9E416E2C8C0AC9D sha1 98BF2BF16E3CB40569A9692680CA048FDAB6CD29 flags verified ) + rom ( name "Scooby-Doo 2 - Monsters Unleashed (USA, Europe).gba" size 8388608 crc 9ff01ddd sha1 98BF2BF16E3CB40569A9692680CA048FDAB6CD29 flags verified ) ) game ( name "Scooby-Doo 2 - Monsters Unleashed (Europe) (En,Fr,De,Es,It)" description "Scooby-Doo 2 - Monsters Unleashed (Europe) (En,Fr,De,Es,It)" - rom ( name "Scooby-Doo 2 - Monsters Unleashed (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 7BDAB2CF md5 49C6C446C5F7BC6B61E158994F8896B0 sha1 C3DA5A04D11CAB4E377B1B32C81109D6EA6FD39A ) + rom ( name "Scooby-Doo 2 - Monsters Unleashed (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 7bdab2cf sha1 C3DA5A04D11CAB4E377B1B32C81109D6EA6FD39A ) ) game ( name "Scooby-Doo and the Cyber Chase (USA, Europe)" description "Scooby-Doo and the Cyber Chase (USA, Europe)" - rom ( name "Scooby-Doo and the Cyber Chase (USA, Europe).gba" size 4194304 crc CF2DBA97 md5 1E3FD614DC43EDBBF9DF51262057F2CC sha1 739F47323CE7E2DBE7E9BF9D553CB97F4692ECC3 ) + rom ( name "Scooby-Doo and the Cyber Chase (USA, Europe).gba" size 4194304 crc cf2dba97 sha1 739F47323CE7E2DBE7E9BF9D553CB97F4692ECC3 flags verified ) ) game ( name "Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De)" description "Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De)" - rom ( name "Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De).gba" size 4194304 crc 8B0079CB md5 09E8523914AFF2D72B1B4B840827829C sha1 444CF64593EF7A9EF7A2BEF56271AD154A1E9FA7 flags verified ) + rom ( name "Scooby-Doo and the Cyber Chase (Europe) (En,Fr,De).gba" size 4194304 crc 8b0079cb sha1 444CF64593EF7A9EF7A2BEF56271AD154A1E9FA7 flags verified ) ) game ( name "Scooby-Doo! - Mystery Mayhem (USA) (En,Fr)" description "Scooby-Doo! - Mystery Mayhem (USA) (En,Fr)" - rom ( name "Scooby-Doo! - Mystery Mayhem (USA) (En,Fr).gba" size 4194304 crc 3D389A12 md5 C8E45043D61075471F8EE3D05862D960 sha1 45E50EAA1EE8773168E36CD05145F3505C3DBC6C ) + rom ( name "Scooby-Doo! - Mystery Mayhem (USA) (En,Fr).gba" size 4194304 crc 3d389a12 sha1 45E50EAA1EE8773168E36CD05145F3505C3DBC6C ) ) game ( name "Scooby-Doo! - Mystery Mayhem (Europe) (En,Fr,De)" description "Scooby-Doo! - Mystery Mayhem (Europe) (En,Fr,De)" - rom ( name "Scooby-Doo! - Mystery Mayhem (Europe) (En,Fr,De).gba" size 4194304 crc 5348A655 md5 9CFF0577973C0219738DA5995EDCF3AE sha1 25FE359DE5F546CADE53D9097D6F11D10FD00FE2 ) + rom ( name "Scooby-Doo! - Mystery Mayhem (Europe) (En,Fr,De).gba" size 4194304 crc 5348a655 sha1 25FE359DE5F546CADE53D9097D6F11D10FD00FE2 flags verified ) ) game ( name "Scooby-Doo! - Unmasked (USA) (En,Fr)" description "Scooby-Doo! - Unmasked (USA) (En,Fr)" - rom ( name "Scooby-Doo! - Unmasked (USA) (En,Fr).gba" size 8388608 crc 96BDD6C1 md5 803FF345F4DF60A7F00DB44FD25730BC sha1 6851A6088CCCAFCD8F1E49A31546AAC6B27CA076 ) + rom ( name "Scooby-Doo! - Unmasked (USA) (En,Fr).gba" size 8388608 crc 96bdd6c1 sha1 6851A6088CCCAFCD8F1E49A31546AAC6B27CA076 ) ) game ( name "Scooby-Doo! - Unmasked (Europe) (En,Fr)" description "Scooby-Doo! - Unmasked (Europe) (En,Fr)" - rom ( name "Scooby-Doo! - Unmasked (Europe) (En,Fr).gba" size 8388608 crc D21B8344 md5 6544C0E0B23BB831DDF42895CFC6A528 sha1 58870A50438E2C58626D16225354C9F6BEC75B98 ) + rom ( name "Scooby-Doo! - Unmasked (Europe) (En,Fr).gba" size 8388608 crc d21b8344 sha1 58870A50438E2C58626D16225354C9F6BEC75B98 ) ) game ( name "Scooby-Doo! - Unmasked (Europe) (Es,It)" description "Scooby-Doo! - Unmasked (Europe) (Es,It)" - rom ( name "Scooby-Doo! - Unmasked (Europe) (Es,It).gba" size 8388608 crc AF42F90F md5 00E44D439CDEF2014C67FFCED1CB90D7 sha1 4871524C40A46862C06FA8A1E83618413369E962 ) + rom ( name "Scooby-Doo! - Unmasked (Europe) (Es,It).gba" size 8388608 crc af42f90f sha1 4871524C40A46862C06FA8A1E83618413369E962 ) ) game ( name "Scorpion King, The - Sword of Osiris (USA)" description "Scorpion King, The - Sword of Osiris (USA)" - rom ( name "Scorpion King, The - Sword of Osiris (USA).gba" size 4194304 crc 6E0A8585 md5 8620AEB89F00DD3E3C2A500BA75CE2DE sha1 2224C8080F48073E568D1B75EEC32E18BC1F5A09 ) + rom ( name "Scorpion King, The - Sword of Osiris (USA).gba" size 4194304 crc 6e0a8585 sha1 2224C8080F48073E568D1B75EEC32E18BC1F5A09 ) ) game ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It)" description "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It)" - rom ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc D5410D32 md5 BF8FAC941521947C92BA860D570927C4 sha1 9A483E98D72B1D7D8579511CC9344E5D27BCEE61 flags verified ) + rom ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc d5410d32 sha1 9A483E98D72B1D7D8579511CC9344E5D27BCEE61 flags verified ) ) game ( name "Scrabble (Europe) (En,Fr,De,Es)" description "Scrabble (Europe) (En,Fr,De,Es)" - rom ( name "Scrabble (Europe) (En,Fr,De,Es).gba" size 8388608 crc C5C9B31B md5 1F86E54C43BA68C9211E76816D88927F sha1 BD982790FABDA6C2CC24C890CEEE123B4C0E8AE4 ) + rom ( name "Scrabble (Europe) (En,Fr,De,Es).gba" size 8388608 crc c5c9b31b sha1 BD982790FABDA6C2CC24C890CEEE123B4C0E8AE4 ) ) game ( name "Scrabble Blast! (USA)" description "Scrabble Blast! (USA)" - rom ( name "Scrabble Blast! (USA).gba" size 4194304 crc 5D31A1F9 md5 29AE328B85FEDEE67E1CD68B86006C5B sha1 B12AA409E69001694E523315A3E28D39FDAF94C5 ) + rom ( name "Scrabble Blast! (USA).gba" size 4194304 crc 5d31a1f9 sha1 B12AA409E69001694E523315A3E28D39FDAF94C5 ) ) game ( name "Scrabble Scramble! (Europe) (En,Fr,De,Es,It,Nl)" description "Scrabble Scramble! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Scrabble Scramble! (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc E8EB2E3A md5 822CD888EDFE00DEA8CF75A848C64988 sha1 97040955445C32F0872BBCDA18DCAB8DC0A7C8C1 flags verified ) + rom ( name "Scrabble Scramble! (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc e8eb2e3a sha1 97040955445C32F0872BBCDA18DCAB8DC0A7C8C1 flags verified ) ) game ( name "Scrabble Scramble! (Europe)" description "Scrabble Scramble! (Europe)" - rom ( name "Scrabble Scramble! (Europe).gba" size 4194304 crc 0ED5F375 md5 B0D1A5D5633E521DC9116F866B3E3CD4 sha1 28846F9A21DDEC18D7CDA51B6491B80C7E904F68 ) + rom ( name "Scrabble Scramble! (Europe).gba" size 4194304 crc 0ed5f375 sha1 28846F9A21DDEC18D7CDA51B6491B80C7E904F68 ) ) game ( name "Screw Breaker - Goushin DoriRureRo (Japan)" description "Screw Breaker - Goushin DoriRureRo (Japan)" - rom ( name "Screw Breaker - Goushin DoriRureRo (Japan).gba" size 8388608 crc B17532EE md5 1455D99497A4D004AA0EDC0E50BD2530 sha1 84AFA7108E4D604E7B1A6D105DF5760869A247FA flags verified ) + rom ( name "Screw Breaker - Goushin DoriRureRo (Japan).gba" size 8388608 crc b17532ee sha1 84AFA7108E4D604E7B1A6D105DF5760869A247FA flags verified ) ) game ( name "Scurge - Hive (Europe) (En,Fr,De,Es,It)" description "Scurge - Hive (Europe) (En,Fr,De,Es,It)" - rom ( name "Scurge - Hive (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2C119783 md5 777AAE9F6CB431FA3F2654BD1E3B1EF0 sha1 A550DD941450EA256D2DA056D7084B039DF553A0 ) + rom ( name "Scurge - Hive (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 2c119783 sha1 A550DD941450EA256D2DA056D7084B039DF553A0 ) ) game ( name "Scurge - Hive (USA) (En,Fr,Es)" description "Scurge - Hive (USA) (En,Fr,Es)" - rom ( name "Scurge - Hive (USA) (En,Fr,Es).gba" size 16777216 crc 1AE38AC0 md5 2CD38E2E2D2BBC3EEEE2833B8667E962 sha1 312304EDD060723EA31979F1F5FA5C66848E29A1 ) + rom ( name "Scurge - Hive (USA) (En,Fr,Es).gba" size 16777216 crc 1ae38ac0 sha1 312304EDD060723EA31979F1F5FA5C66848E29A1 flags verified ) ) game ( name "SD Gundam Force (Japan) (En)" description "SD Gundam Force (Japan) (En)" - rom ( name "SD Gundam Force (Japan) (En).gba" size 8388608 crc 83417478 md5 39DE567A848AF58C088C621C89007C4E sha1 7D1B467392A8417DD41C3FFD85C26D9387EB285F ) + rom ( name "SD Gundam Force (Japan) (En).gba" size 8388608 crc 83417478 sha1 7D1B467392A8417DD41C3FFD85C26D9387EB285F flags verified ) ) game ( name "SD Gundam Force (USA)" description "SD Gundam Force (USA)" - rom ( name "SD Gundam Force (USA).gba" size 8388608 crc 68B21289 md5 9530A3E226B2FDFBFB8FD72242793635 sha1 F45AF1FABFA9C95BC98C6D3CC986CC68AFD7EA61 ) + rom ( name "SD Gundam Force (USA).gba" size 8388608 crc 68b21289 sha1 F45AF1FABFA9C95BC98C6D3CC986CC68AFD7EA61 ) ) game ( name "SD Gundam G Generation Advance (Japan)" description "SD Gundam G Generation Advance (Japan)" - rom ( name "SD Gundam G Generation Advance (Japan).gba" size 16777216 crc 7DAF215C md5 275EA9783E76AF29846CC3EE5675C62A sha1 7DD42BEAACBD24CB832745A18E57CEFDA4A76827 ) + rom ( name "SD Gundam G Generation Advance (Japan).gba" size 16777216 crc 7daf215c sha1 7DD42BEAACBD24CB832745A18E57CEFDA4A76827 ) ) game ( name "Sea Trader - Rise of Taipan (USA)" description "Sea Trader - Rise of Taipan (USA)" - rom ( name "Sea Trader - Rise of Taipan (USA).gba" size 4194304 crc 7597E8C1 md5 AC807E619878B8219240D908BD7D5ED6 sha1 B4EF625996F413FC563BD3319AFF1DC6C1D2DCFE flags verified ) + rom ( name "Sea Trader - Rise of Taipan (USA).gba" size 4194304 crc 7597e8c1 sha1 B4EF625996F413FC563BD3319AFF1DC6C1D2DCFE flags verified ) ) game ( name "Secret Agent Barbie - Royal Jewels Mission (USA)" description "Secret Agent Barbie - Royal Jewels Mission (USA)" - rom ( name "Secret Agent Barbie - Royal Jewels Mission (USA).gba" size 4194304 crc 610913E0 md5 B5DA52577265DBB1D98977DA249C4E20 sha1 78B2D7A05998918F047BA2AD68DC00086CBF3FF2 ) + rom ( name "Secret Agent Barbie - Royal Jewels Mission (USA).gba" size 4194304 crc 610913e0 sha1 78B2D7A05998918F047BA2AD68DC00086CBF3FF2 ) ) game ( name "Secret Agent Barbie - Royal Jewels Mission (Europe) (En,Fr,De,Es,It)" description "Secret Agent Barbie - Royal Jewels Mission (Europe) (En,Fr,De,Es,It)" - rom ( name "Secret Agent Barbie - Royal Jewels Mission (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc DA3133C3 md5 065B12AB5B43E941FA0011A5483A47DF sha1 D0E9C2D804D2F47BF8AC22E99C31289E2167A18D ) -) - -game ( - name "Sega Arcade Gallery (USA)" - description "Sega Arcade Gallery (USA)" - rom ( name "Sega Arcade Gallery (USA).gba" size 8388608 crc 3B8FFDF4 md5 0BB34790A91D40F7AFC437C528102496 sha1 6CE77309C2CAACF466F9A2C37C3FE84E4CE23242 ) + rom ( name "Secret Agent Barbie - Royal Jewels Mission (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc da3133c3 sha1 D0E9C2D804D2F47BF8AC22E99C31289E2167A18D ) ) game ( name "Sega Arcade Gallery (Europe) (En,Fr,De,Es,It)" description "Sega Arcade Gallery (Europe) (En,Fr,De,Es,It)" - rom ( name "Sega Arcade Gallery (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc F92140C0 md5 4F7CBADB74DD6426F91429398ECA5374 sha1 C99FE39973B33BE64749F27CE6B454E0C3C15D05 ) + rom ( name "Sega Arcade Gallery (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f92140c0 sha1 C99FE39973B33BE64749F27CE6B454E0C3C15D05 flags verified ) +) + +game ( + name "Sega Arcade Gallery (USA)" + description "Sega Arcade Gallery (USA)" + rom ( name "Sega Arcade Gallery (USA).gba" size 8388608 crc 3b8ffdf4 sha1 6CE77309C2CAACF466F9A2C37C3FE84E4CE23242 ) ) game ( name "Sega Rally Championship (Japan) (En)" description "Sega Rally Championship (Japan) (En)" - rom ( name "Sega Rally Championship (Japan) (En).gba" size 8388608 crc E57C16F7 md5 BF1D31E4558E574C751E9886DAA5C23D sha1 3F65A322F562D5B2D74A608FDE0D068B90C63B67 ) + rom ( name "Sega Rally Championship (Japan) (En).gba" size 8388608 crc e57c16f7 sha1 3F65A322F562D5B2D74A608FDE0D068B90C63B67 ) ) game ( name "Sega Rally Championship (USA)" description "Sega Rally Championship (USA)" - rom ( name "Sega Rally Championship (USA).gba" size 8388608 crc 1AE3EB16 md5 F4326BDE4B5E9F53F5FC58CE24D7B137 sha1 5EC86056CCEF168B57BE8E609AADA2B1DA11F733 ) + rom ( name "Sega Rally Championship (USA).gba" size 8388608 crc 1ae3eb16 sha1 5EC86056CCEF168B57BE8E609AADA2B1DA11F733 ) ) game ( name "Sega Rally Championship (Europe)" description "Sega Rally Championship (Europe)" - rom ( name "Sega Rally Championship (Europe).gba" size 8388608 crc D125A6BB md5 8C40604A9A39F081408CBE3991AC0626 sha1 BFBF823E2979E122B984AC04A9EA7FA996AFAE28 flags verified ) + rom ( name "Sega Rally Championship (Europe).gba" size 8388608 crc d125a6bb sha1 BFBF823E2979E122B984AC04A9EA7FA996AFAE28 flags verified ) ) game ( name "Sega Smash Pack (USA)" description "Sega Smash Pack (USA)" - rom ( name "Sega Smash Pack (USA).gba" size 8388608 crc 5C2E97BA md5 763FC686E0E12DDB53E0CF9C0F27854A sha1 612A1A10C769BEFF1559F4FC81CD71366EE954B3 ) + rom ( name "Sega Smash Pack (USA).gba" size 8388608 crc 5c2e97ba sha1 612A1A10C769BEFF1559F4FC81CD71366EE954B3 flags verified ) ) game ( name "Sega Smash Pack (Europe)" description "Sega Smash Pack (Europe)" - rom ( name "Sega Smash Pack (Europe).gba" size 8388608 crc 09310FEC md5 D76D995CEF14FCE9129D8B7C9F049568 sha1 F3F48AF79F6CCD3E10123ACF87CCAEB4EB1C916D ) + rom ( name "Sega Smash Pack (Europe).gba" size 8388608 crc 09310fec sha1 F3F48AF79F6CCD3E10123ACF87CCAEB4EB1C916D flags verified ) ) game ( name "Sengoku Kakumei Gaiden (Japan)" description "Sengoku Kakumei Gaiden (Japan)" - rom ( name "Sengoku Kakumei Gaiden (Japan).gba" size 8388608 crc 3DD25FD7 md5 C6420001B019120CF0606DCBED749137 sha1 6C2A464465855E7E8E9D8E02262CE44B61E34921 ) + rom ( name "Sengoku Kakumei Gaiden (Japan).gba" size 8388608 crc 3dd25fd7 sha1 6C2A464465855E7E8E9D8E02262CE44B61E34921 ) ) game ( name "Sennen Kazoku (Japan)" description "Sennen Kazoku (Japan)" - rom ( name "Sennen Kazoku (Japan).gba" size 16777216 crc A2F6976C md5 914BD4B83AD1A0B426CB183132526431 sha1 4DCD7CEE46D3A5E848A22EB371BEBBBC2FB8D488 flags verified ) + rom ( name "Sennen Kazoku (Japan).gba" size 16777216 crc a2f6976c sha1 4DCD7CEE46D3A5E848A22EB371BEBBBC2FB8D488 flags verified ) +) + +game ( + name "Sennen Kazoku (Japan) (Rev 1)" + description "Sennen Kazoku (Japan) (Rev 1)" + rom ( name "Sennen Kazoku (Japan) (Rev 1).gba" size 16777216 crc dcaae075 sha1 18F9F8A25207AAECD3EBA55A358CFAF11ABD4897 flags verified ) ) game ( name "Sentouin Yamada Hajime (Japan)" description "Sentouin Yamada Hajime (Japan)" - rom ( name "Sentouin Yamada Hajime (Japan).gba" size 8388608 crc 596C5D4C md5 BE824A74553013BCB38BA79C460B001C sha1 0FE36E94B48E67E06285C60329C62512C5C0137C ) + rom ( name "Sentouin Yamada Hajime (Japan).gba" size 8388608 crc 596c5d4c sha1 0FE36E94B48E67E06285C60329C62512C5C0137C ) ) game ( name "Serious Sam Advance (USA) (En,Fr,De)" description "Serious Sam Advance (USA) (En,Fr,De)" - rom ( name "Serious Sam Advance (USA) (En,Fr,De).gba" size 8388608 crc FDF4ECA7 md5 327F1553F9C9BC510069D9EAABB0F6FB sha1 61FC645024D61EAD7526B971E507A1786B358F68 ) + rom ( name "Serious Sam Advance (USA) (En,Fr,De).gba" size 8388608 crc fdf4eca7 sha1 61FC645024D61EAD7526B971E507A1786B358F68 ) ) game ( name "Serious Sam Advance (Europe) (En,Fr,De)" description "Serious Sam Advance (Europe) (En,Fr,De)" - rom ( name "Serious Sam Advance (Europe) (En,Fr,De).gba" size 8388608 crc 58199232 md5 B57E44B1F52647510CAA08F09CFB8E1B sha1 4FF48D8C18B70A5184758F1917343AE85A70858E ) + rom ( name "Serious Sam Advance (Europe) (En,Fr,De).gba" size 8388608 crc 58199232 sha1 4FF48D8C18B70A5184758F1917343AE85A70858E ) ) game ( name "Shaman King - Legacy of the Spirits - Soaring Hawk (USA)" description "Shaman King - Legacy of the Spirits - Soaring Hawk (USA)" - rom ( name "Shaman King - Legacy of the Spirits - Soaring Hawk (USA).gba" size 16777216 crc 798593A5 md5 42C232AAAB6F088E339953D94A91E6BB sha1 4D95E192B45A7AF79028E5FA850A90310A2D1F28 ) + rom ( name "Shaman King - Legacy of the Spirits - Soaring Hawk (USA).gba" size 16777216 crc 798593a5 sha1 4D95E192B45A7AF79028E5FA850A90310A2D1F28 ) ) game ( name "Shaman King - Legacy of the Spirits - Sprinting Wolf (USA)" description "Shaman King - Legacy of the Spirits - Sprinting Wolf (USA)" - rom ( name "Shaman King - Legacy of the Spirits - Sprinting Wolf (USA).gba" size 16777216 crc FA1AA3F6 md5 8DD93526E6568B174355153FE946BD0C sha1 41459C757B792FCCB2DFD5552007DC5A52B5E053 ) + rom ( name "Shaman King - Legacy of the Spirits - Sprinting Wolf (USA).gba" size 16777216 crc fa1aa3f6 sha1 41459C757B792FCCB2DFD5552007DC5A52B5E053 ) ) game ( name "Shaman King - Master of Spirits (USA)" description "Shaman King - Master of Spirits (USA)" - rom ( name "Shaman King - Master of Spirits (USA).gba" size 16777216 crc 10E554AE md5 1C92EDBAD07A372EE382D16CF624DC4B sha1 4A0FECDF90055FE1934B54D10E47B46AC399AECD ) + rom ( name "Shaman King - Master of Spirits (USA).gba" size 16777216 crc 10e554ae sha1 4A0FECDF90055FE1934B54D10E47B46AC399AECD ) ) game ( name "Shaman King - Master of Spirits (Europe) (En,Fr,De)" description "Shaman King - Master of Spirits (Europe) (En,Fr,De)" - rom ( name "Shaman King - Master of Spirits (Europe) (En,Fr,De).gba" size 16777216 crc 4864B878 md5 959F4E677160366F356742016427595D sha1 F077F6295EF443B99E2C7E45526EDBB476DC2BEC ) + rom ( name "Shaman King - Master of Spirits (Europe) (En,Fr,De).gba" size 16777216 crc 4864b878 sha1 F077F6295EF443B99E2C7E45526EDBB476DC2BEC ) ) game ( name "Shaman King - Master of Spirits 2 (USA)" description "Shaman King - Master of Spirits 2 (USA)" - rom ( name "Shaman King - Master of Spirits 2 (USA).gba" size 16777216 crc 201E3412 md5 5AF6A63F85FA386C7889695308DC32A4 sha1 9EF1DF2ABF95D356933592292A1DBC9C128133DA ) + rom ( name "Shaman King - Master of Spirits 2 (USA).gba" size 16777216 crc 201e3412 sha1 9EF1DF2ABF95D356933592292A1DBC9C128133DA ) ) game ( name "Shaman King - Master of Spirits 2 (Europe) (En,Fr,De)" description "Shaman King - Master of Spirits 2 (Europe) (En,Fr,De)" - rom ( name "Shaman King - Master of Spirits 2 (Europe) (En,Fr,De).gba" size 16777216 crc 4A74E038 md5 971E4440CB014DC10C4C834EFAEF5114 sha1 CB52EF70400C8B09B51CBB967EF022F5F6F9D757 ) + rom ( name "Shaman King - Master of Spirits 2 (Europe) (En,Fr,De).gba" size 16777216 crc 4a74e038 sha1 CB52EF70400C8B09B51CBB967EF022F5F6F9D757 ) ) game ( name "Shaman King Card Game - Chou Senjiryakketsu 2 (Japan)" description "Shaman King Card Game - Chou Senjiryakketsu 2 (Japan)" - rom ( name "Shaman King Card Game - Chou Senjiryakketsu 2 (Japan).gba" size 8388608 crc CB9A390A md5 838911E3C706D4F4377E0AD318676D2D sha1 956DFBC2BA50214D99D01532F460E2FABEC4125F ) + rom ( name "Shaman King Card Game - Chou Senjiryakketsu 2 (Japan).gba" size 8388608 crc cb9a390a sha1 956DFBC2BA50214D99D01532F460E2FABEC4125F flags verified ) ) game ( name "Shaman King Card Game - Chou Senjiryakketsu 3 (Japan)" description "Shaman King Card Game - Chou Senjiryakketsu 3 (Japan)" - rom ( name "Shaman King Card Game - Chou Senjiryakketsu 3 (Japan).gba" size 16777216 crc 2BCF66D4 md5 223D4DA54D60F28FC13124BF03C75734 sha1 92C5284A1B6340777BA5C0B409E128C315F00A99 ) + rom ( name "Shaman King Card Game - Chou Senjiryakketsu 3 (Japan).gba" size 16777216 crc 2bcf66d4 sha1 92C5284A1B6340777BA5C0B409E128C315F00A99 flags verified ) ) game ( name "Shamu's Deep Sea Adventures (USA)" description "Shamu's Deep Sea Adventures (USA)" - rom ( name "Shamu's Deep Sea Adventures (USA).gba" size 33554432 crc 4E9426EB md5 DE6656C00FBEFF59E77209D0BDF03063 sha1 0BCA9C4DD35D02C52A5DB98B2097A50EF159DE32 ) + rom ( name "Shamu's Deep Sea Adventures (USA).gba" size 33554432 crc 4e9426eb sha1 0BCA9C4DD35D02C52A5DB98B2097A50EF159DE32 ) ) game ( name "Shamu's Deep Sea Adventures (Europe)" description "Shamu's Deep Sea Adventures (Europe)" - rom ( name "Shamu's Deep Sea Adventures (Europe).gba" size 33554432 crc 6A0F2C8B md5 C4F814E961A3B4594B7CBED5C382F2DF sha1 89032A8C88CA82519E3F432EDC08F1E500D60F10 ) + rom ( name "Shamu's Deep Sea Adventures (Europe).gba" size 33554432 crc 6a0f2c8b sha1 89032A8C88CA82519E3F432EDC08F1E500D60F10 ) ) game ( name "Shanghai Advance (Japan)" description "Shanghai Advance (Japan)" - rom ( name "Shanghai Advance (Japan).gba" size 4194304 crc 9AEEA9B7 md5 52F25A25CA0DEBB6AA708A1A2867F271 sha1 F8C17010DE03172B7D17192A3F0FD65CBE323F8E ) + rom ( name "Shanghai Advance (Japan).gba" size 4194304 crc 9aeea9b7 sha1 F8C17010DE03172B7D17192A3F0FD65CBE323F8E ) ) game ( name "Shark Tale (USA, Europe)" description "Shark Tale (USA, Europe)" - rom ( name "Shark Tale (USA, Europe).gba" size 8388608 crc 7B68D93E md5 56301FEBE066A6C4402A8AF346B0426C sha1 D56755D3FCD2FD942CC54F62F9BA7DF38347799F flags verified ) + rom ( name "Shark Tale (USA, Europe).gba" size 8388608 crc 7b68d93e sha1 D56755D3FCD2FD942CC54F62F9BA7DF38347799F flags verified ) ) game ( name "Shark Tale (Europe) (Fr,De,Es)" description "Shark Tale (Europe) (Fr,De,Es)" - rom ( name "Shark Tale (Europe) (Fr,De,Es).gba" size 8388608 crc DF2518E9 md5 552871DE5CB6BBFFB69A567C05A7A665 sha1 2EB477465B8D6F4680D49C92D0B7C1FB36E53574 ) + rom ( name "Shark Tale (Europe) (Fr,De,Es).gba" size 8388608 crc df2518e9 sha1 2EB477465B8D6F4680D49C92D0B7C1FB36E53574 flags verified ) ) game ( name "Shark Tale (Italy)" description "Shark Tale (Italy)" - rom ( name "Shark Tale (Italy).gba" size 8388608 crc 804A01B1 md5 88DE1A21AF5663EF1F85F5445E559562 sha1 A0ECD59CBDEBB2A345FA264480578C57066C061C ) + rom ( name "Shark Tale (Italy).gba" size 8388608 crc 804a01b1 sha1 A0ECD59CBDEBB2A345FA264480578C57066C061C ) ) game ( name "Shark Tale (Japan)" description "Shark Tale (Japan)" - rom ( name "Shark Tale (Japan).gba" size 8388608 crc 128BE27C md5 B7315DD0A12A56B0147B3FB8169D33F0 sha1 D03AAC6A2563861AEE99E677E8A2549A7BF5A8FA ) + rom ( name "Shark Tale (Japan).gba" size 8388608 crc 128be27c sha1 D03AAC6A2563861AEE99E677E8A2549A7BF5A8FA ) ) game ( name "Shaun Palmer's Pro Snowboarder (USA, Europe)" description "Shaun Palmer's Pro Snowboarder (USA, Europe)" - rom ( name "Shaun Palmer's Pro Snowboarder (USA, Europe).gba" size 8388608 crc 66265AD9 md5 E08250206B5CF301C15417112F306A16 sha1 C27BF70516D25040F63C937E5F5446847CF41B48 ) + rom ( name "Shaun Palmer's Pro Snowboarder (USA, Europe).gba" size 8388608 crc 66265ad9 sha1 C27BF70516D25040F63C937E5F5446847CF41B48 flags verified ) ) game ( name "Shaun Palmer's Pro Snowboarder (Germany)" description "Shaun Palmer's Pro Snowboarder (Germany)" - rom ( name "Shaun Palmer's Pro Snowboarder (Germany).gba" size 8388608 crc 6D545FED md5 15C95E0D6067D9F60B4BABA4C6FFD02C sha1 F4516BD9880E9247DAA611D9ACE7C8549D8B22A4 flags verified ) + rom ( name "Shaun Palmer's Pro Snowboarder (Germany).gba" size 8388608 crc 6d545fed sha1 F4516BD9880E9247DAA611D9ACE7C8549D8B22A4 flags verified ) ) game ( name "Sheep (Europe) (En,Fr,De,Es,It)" description "Sheep (Europe) (En,Fr,De,Es,It)" - rom ( name "Sheep (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 75A92925 md5 2D457F68782271E833B1469EC7308502 sha1 CB200350B4DC01DCDB0A52AF11286AACA15CD786 ) + rom ( name "Sheep (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 75a92925 sha1 CB200350B4DC01DCDB0A52AF11286AACA15CD786 ) +) + +game ( + name "Shifting Gears - Road Trip (USA)" + description "Shifting Gears - Road Trip (USA)" + rom ( name "Shifting Gears - Road Trip (USA).gba" size 4194304 crc 549bf1c5 sha1 9A332CEC82DFF9130248A2525D0151FAE52DD258 ) ) game ( name "Shikakui Atama o Maruku Suru. Advance - Kanji, Keisan (Japan)" description "Shikakui Atama o Maruku Suru. Advance - Kanji, Keisan (Japan)" - rom ( name "Shikakui Atama o Maruku Suru. Advance - Kanji, Keisan (Japan).gba" size 4194304 crc E0A452A8 md5 B41A755562A4128829C6DC12C8ABA3E3 sha1 FF674A429E8A76CAB47ACCAF6CA579194866733F ) + rom ( name "Shikakui Atama o Maruku Suru. Advance - Kanji, Keisan (Japan).gba" size 4194304 crc e0a452a8 sha1 FF674A429E8A76CAB47ACCAF6CA579194866733F ) ) game ( name "Shikakui Atama o Maruku Suru. Advance - Kokugo, Sansuu, Shakai, Rika (Japan)" description "Shikakui Atama o Maruku Suru. Advance - Kokugo, Sansuu, Shakai, Rika (Japan)" - rom ( name "Shikakui Atama o Maruku Suru. Advance - Kokugo, Sansuu, Shakai, Rika (Japan).gba" size 4194304 crc 07695A6C md5 878DC37944B93347E220CA68936402E0 sha1 C1CF1478D79DAF6C2717DF6F19CAD806BD7F6429 ) + rom ( name "Shikakui Atama o Maruku Suru. Advance - Kokugo, Sansuu, Shakai, Rika (Japan).gba" size 4194304 crc 07695a6c sha1 C1CF1478D79DAF6C2717DF6F19CAD806BD7F6429 flags verified ) ) game ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan)" description "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan)" - rom ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan).gba" size 4194304 crc F29E6E2D md5 710AC1EB3062A922652505E055ECB7B1 sha1 B2F100650AF2C8D6EC02C0A71774EEBA22D6BE2F ) + rom ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan).gba" size 4194304 crc f29e6e2d sha1 B2F100650AF2C8D6EC02C0A71774EEBA22D6BE2F ) ) game ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan) (Rev 1)" description "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan) (Rev 1)" - rom ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan) (Rev 1).gba" size 4194304 crc 5546B016 md5 A8E39C39EF1E7D2005ADB624C6B0FA2F sha1 C7C94199BAC6A1F69356413031B5A49CB30C93D1 ) + rom ( name "Shimura Ken no Baka Tonosama - Bakushou Tenka Touitsu Game (Japan) (Rev 1).gba" size 4194304 crc 5546b016 sha1 C7C94199BAC6A1F69356413031B5A49CB30C93D1 flags verified ) ) game ( name "Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)" description "Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan)" - rom ( name "Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan).gba" size 16777216 crc AF453162 md5 FBAD88C14DCEDEFE6C70B06ADCD0A0DB sha1 2651C5E6875AC60ABFF734510D152166D211C87C ) + rom ( name "Shin Bokura no Taiyou - Gyakushuu no Sabata (Japan).gba" size 16777216 crc af453162 sha1 2651C5E6875AC60ABFF734510D152166D211C87C flags verified ) ) game ( name "Shin chan - Aventuras en Cineland (Spain)" description "Shin chan - Aventuras en Cineland (Spain)" - rom ( name "Shin chan - Aventuras en Cineland (Spain).gba" size 16777216 crc 769A7666 md5 0DBC85A954ABA764A3BBAE2E078D26F0 sha1 069B7E991A35A78B321959F2F19470952C331DFC flags verified ) + rom ( name "Shin chan - Aventuras en Cineland (Spain).gba" size 16777216 crc 769a7666 sha1 069B7E991A35A78B321959F2F19470952C331DFC flags verified ) ) game ( name "Shin chan contra los Munecos de Shock Gahn (Spain)" description "Shin chan contra los Munecos de Shock Gahn (Spain)" - rom ( name "Shin chan contra los Munecos de Shock Gahn (Spain).gba" size 16777216 crc FD47A2FE md5 8F3D9095C1D0B281BA12A4BAC17C29D1 sha1 A328AE26F28D9500DD98C8484E35F44EDC5EF4EA ) + rom ( name "Shin chan contra los Munecos de Shock Gahn (Spain).gba" size 16777216 crc fd47a2fe sha1 A328AE26F28D9500DD98C8484E35F44EDC5EF4EA ) ) game ( name "Shin Kisekae Monogatari (Japan)" description "Shin Kisekae Monogatari (Japan)" - rom ( name "Shin Kisekae Monogatari (Japan).gba" size 8388608 crc B65095BF md5 055B47930BA47D234D91BDBF63DD974E sha1 F1B56632820E51D5D11331574D3118DD7D1CCC80 ) + rom ( name "Shin Kisekae Monogatari (Japan).gba" size 8388608 crc b65095bf sha1 F1B56632820E51D5D11331574D3118DD7D1CCC80 ) ) game ( name "Shin Megami Tensei (Japan)" description "Shin Megami Tensei (Japan)" - rom ( name "Shin Megami Tensei (Japan).gba" size 8388608 crc B857C3C5 md5 25B2D758E9ABC435441414AAB6D43431 sha1 7851F7F061693D664672F47F2D2D714829CF52AC ) + rom ( name "Shin Megami Tensei (Japan).gba" size 8388608 crc b857c3c5 sha1 7851F7F061693D664672F47F2D2D714829CF52AC flags verified ) ) game ( name "Shin Megami Tensei Devil Children - Hikari no Sho (Japan)" description "Shin Megami Tensei Devil Children - Hikari no Sho (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Hikari no Sho (Japan).gba" size 8388608 crc 5D7EE5AF md5 F69CED586DC3DFB4705B69F42ADE2B06 sha1 9B32F90AE40C33AE3405928DF9AAFC86248DC90B ) + rom ( name "Shin Megami Tensei Devil Children - Hikari no Sho (Japan).gba" size 8388608 crc 5d7ee5af sha1 9B32F90AE40C33AE3405928DF9AAFC86248DC90B ) ) game ( name "Shin Megami Tensei Devil Children - Honoo no Sho (Japan)" description "Shin Megami Tensei Devil Children - Honoo no Sho (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Honoo no Sho (Japan).gba" size 8388608 crc 9A0903BC md5 6207CB2C18A77CC408C6E42CC7F0CF10 sha1 8C29D6921E7DB8B0E71094D32E32066AC13C500D ) + rom ( name "Shin Megami Tensei Devil Children - Honoo no Sho (Japan).gba" size 8388608 crc 9a0903bc sha1 8C29D6921E7DB8B0E71094D32E32066AC13C500D ) ) game ( name "Shin Megami Tensei Devil Children - Koori no Sho (Japan)" description "Shin Megami Tensei Devil Children - Koori no Sho (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Koori no Sho (Japan).gba" size 8388608 crc AD80D5F9 md5 625D77A12509CD5635E357D89AADFA02 sha1 8470A93BDED96270D1403BB485F32C42EDF1462A ) + rom ( name "Shin Megami Tensei Devil Children - Koori no Sho (Japan).gba" size 8388608 crc ad80d5f9 sha1 8470A93BDED96270D1403BB485F32C42EDF1462A ) ) game ( name "Shin Megami Tensei Devil Children - Messiah Riser (Japan)" description "Shin Megami Tensei Devil Children - Messiah Riser (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Messiah Riser (Japan).gba" size 8388608 crc 0EC98C51 md5 2761B40BD27082BD75B752B47CAFACEC sha1 9387947BAA410C748EC5FAB1CE9A07AE8047E398 ) + rom ( name "Shin Megami Tensei Devil Children - Messiah Riser (Japan).gba" size 8388608 crc 0ec98c51 sha1 9387947BAA410C748EC5FAB1CE9A07AE8047E398 ) ) game ( name "Shin Megami Tensei Devil Children - Puzzle de Call! (Japan)" description "Shin Megami Tensei Devil Children - Puzzle de Call! (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Puzzle de Call! (Japan).gba" size 4194304 crc EA8A185A md5 1C04FF63C5D5B1A1EB62C1DCA639E87F sha1 E70FC457B56C8E27AB63E491706B88232F598452 ) + rom ( name "Shin Megami Tensei Devil Children - Puzzle de Call! (Japan).gba" size 4194304 crc ea8a185a sha1 E70FC457B56C8E27AB63E491706B88232F598452 ) ) game ( name "Shin Megami Tensei Devil Children - Yami no Sho (Japan)" description "Shin Megami Tensei Devil Children - Yami no Sho (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Yami no Sho (Japan).gba" size 8388608 crc E0E153B7 md5 8A8DC5DC9BC9A49D35BA263E1BA9F4A7 sha1 236FD0E7C14F5D6DB7FA2083766324341B9E5B39 ) + rom ( name "Shin Megami Tensei Devil Children - Yami no Sho (Japan).gba" size 8388608 crc e0e153b7 sha1 236FD0E7C14F5D6DB7FA2083766324341B9E5B39 ) ) game ( name "Shin Megami Tensei II (Japan)" description "Shin Megami Tensei II (Japan)" - rom ( name "Shin Megami Tensei II (Japan).gba" size 8388608 crc AF40CC99 md5 57AF4CA36D8036A483AE0D98C27BF544 sha1 8A4A52EB5538D52762337CA045E5C85E00F19FF0 ) + rom ( name "Shin Megami Tensei II (Japan).gba" size 8388608 crc af40cc99 sha1 8A4A52EB5538D52762337CA045E5C85E00F19FF0 ) ) game ( name "Shin Nihon Pro Wrestling - Toukon Retsuden Advance (Japan)" description "Shin Nihon Pro Wrestling - Toukon Retsuden Advance (Japan)" - rom ( name "Shin Nihon Pro Wrestling - Toukon Retsuden Advance (Japan).gba" size 8388608 crc 9F0B8B79 md5 998875B640543E2E9207101B18A5F517 sha1 8C7D119F4E9AC6DAB2C308D1DFAD5EABB0837014 ) + rom ( name "Shin Nihon Pro Wrestling - Toukon Retsuden Advance (Japan).gba" size 8388608 crc 9f0b8b79 sha1 8C7D119F4E9AC6DAB2C308D1DFAD5EABB0837014 flags verified ) ) game ( name "Shin Sangoku Musou Advance (Japan)" description "Shin Sangoku Musou Advance (Japan)" - rom ( name "Shin Sangoku Musou Advance (Japan).gba" size 16777216 crc FE1BE6C1 md5 B4DA8D96A5701F91EF8934EE84B8358F sha1 677CD51C1ECDDE73A6F40EC2CD30D35C77DB459A ) + rom ( name "Shin Sangoku Musou Advance (Japan).gba" size 16777216 crc fe1be6c1 sha1 677CD51C1ECDDE73A6F40EC2CD30D35C77DB459A flags verified ) +) + +game ( + name "Shin Sangoku Musou Advance (Japan) (Rev 1)" + description "Shin Sangoku Musou Advance (Japan) (Rev 1)" + rom ( name "Shin Sangoku Musou Advance (Japan) (Rev 1).gba" size 16777216 crc 7ceded10 sha1 BE2BFA709478DC482E80FB476C1EE846B703BCBB flags verified ) ) game ( name "Shingata Medarot - Kabuto Version (Japan)" description "Shingata Medarot - Kabuto Version (Japan)" - rom ( name "Shingata Medarot - Kabuto Version (Japan).gba" size 8388608 crc 54AF534D md5 7AB12DB7382122998AAF2756DCBAC498 sha1 C14E7612698342CCD495E4AEF764D4083C5A4765 ) + rom ( name "Shingata Medarot - Kabuto Version (Japan).gba" size 8388608 crc 54af534d sha1 C14E7612698342CCD495E4AEF764D4083C5A4765 ) ) game ( name "Shingata Medarot - Kuwagata Version (Japan)" description "Shingata Medarot - Kuwagata Version (Japan)" - rom ( name "Shingata Medarot - Kuwagata Version (Japan).gba" size 8388608 crc 0FD35628 md5 D1415B84B039A978BDB920F917959779 sha1 573E980DFFDEE50D53B6F2A79D1DB2D650731558 ) + rom ( name "Shingata Medarot - Kuwagata Version (Japan).gba" size 8388608 crc 0fd35628 sha1 573E980DFFDEE50D53B6F2A79D1DB2D650731558 ) ) game ( name "Shining Force - Kuroki Ryuu no Fukkatsu (Japan)" description "Shining Force - Kuroki Ryuu no Fukkatsu (Japan)" - rom ( name "Shining Force - Kuroki Ryuu no Fukkatsu (Japan).gba" size 8388608 crc 4A643CC4 md5 F053F23D0FB4AE82952C6A0E84048FC3 sha1 4A5A91F3FB99B4012A7FABEA3585F38EDEF6B8A6 ) + rom ( name "Shining Force - Kuroki Ryuu no Fukkatsu (Japan).gba" size 8388608 crc 4a643cc4 sha1 4A5A91F3FB99B4012A7FABEA3585F38EDEF6B8A6 ) ) game ( name "Shining Force - Resurrection of the Dark Dragon (Europe) (En,Fr,De,Es,It)" description "Shining Force - Resurrection of the Dark Dragon (Europe) (En,Fr,De,Es,It)" - rom ( name "Shining Force - Resurrection of the Dark Dragon (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 07B06994 md5 17A986AF456ED994F556F23C330666A8 sha1 CBE41FBE05E3212C301487A87F6A654C2814196E ) + rom ( name "Shining Force - Resurrection of the Dark Dragon (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 07b06994 sha1 CBE41FBE05E3212C301487A87F6A654C2814196E ) ) game ( name "Shining Force - Resurrection of the Dark Dragon (USA)" description "Shining Force - Resurrection of the Dark Dragon (USA)" - rom ( name "Shining Force - Resurrection of the Dark Dragon (USA).gba" size 8388608 crc 563AA3A0 md5 6A1B056D8A006E069466C08C69DE56C0 sha1 1BBDA9142806265CC42645DF433EDE5D8DB46E3E ) -) - -game ( - name "Shining Soul (USA)" - description "Shining Soul (USA)" - rom ( name "Shining Soul (USA).gba" size 8388608 crc E95BBA0C md5 D9B338EFE2C15F9493CA0B28714A679B sha1 14723EAD8634959B4FAD027D9618C0860B82EA67 ) + rom ( name "Shining Force - Resurrection of the Dark Dragon (USA).gba" size 8388608 crc 563aa3a0 sha1 1BBDA9142806265CC42645DF433EDE5D8DB46E3E flags verified ) ) game ( name "Shining Soul (Japan)" description "Shining Soul (Japan)" - rom ( name "Shining Soul (Japan).gba" size 8388608 crc 521450D1 md5 0CB9989BEB289F843CDB69BB0BD8C8BE sha1 5FE69468DC1ECD9FB40F0AB3CA361963006DBB02 ) + rom ( name "Shining Soul (Japan).gba" size 8388608 crc 521450d1 sha1 5FE69468DC1ECD9FB40F0AB3CA361963006DBB02 flags verified ) ) game ( name "Shining Soul (Europe) (En,Fr,De,Es,It)" description "Shining Soul (Europe) (En,Fr,De,Es,It)" - rom ( name "Shining Soul (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 74B5D069 md5 5931B0B58D9DA9B9AA1F82D28643E2F2 sha1 6E80A65CCA65236E405940C880B144D77F3F4F08 flags verified ) + rom ( name "Shining Soul (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 74b5d069 sha1 6E80A65CCA65236E405940C880B144D77F3F4F08 flags verified ) +) + +game ( + name "Shining Soul (USA)" + description "Shining Soul (USA)" + rom ( name "Shining Soul (USA).gba" size 8388608 crc e95bba0c sha1 14723EAD8634959B4FAD027D9618C0860B82EA67 ) ) game ( name "Shining Soul II (Japan)" description "Shining Soul II (Japan)" - rom ( name "Shining Soul II (Japan).gba" size 16777216 crc 7B39A7B2 md5 3BAE05647BBEE8565E3993FADE2CA5BA sha1 19856388CAF5140F7527728BD09E20BCB8924EEB ) + rom ( name "Shining Soul II (Japan).gba" size 16777216 crc 7b39a7b2 sha1 19856388CAF5140F7527728BD09E20BCB8924EEB ) ) game ( name "Shining Soul II (Europe) (En,Fr,De,Es,It)" description "Shining Soul II (Europe) (En,Fr,De,Es,It)" - rom ( name "Shining Soul II (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 55E503C1 md5 49AA688745111AAA51076A345F8F18C3 sha1 AA1288BE9257337ABDFE3034898CF6C7AA778FBC ) + rom ( name "Shining Soul II (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 55e503c1 sha1 AA1288BE9257337ABDFE3034898CF6C7AA778FBC flags verified ) ) game ( name "Shining Soul II (USA)" description "Shining Soul II (USA)" - rom ( name "Shining Soul II (USA).gba" size 16777216 crc 4038E282 md5 F4A655E23638E79EACF44A456FAEE6A4 sha1 541469B319A72EF4BC262483745526AC3EDDD925 ) + rom ( name "Shining Soul II (USA).gba" size 16777216 crc 4038e282 sha1 541469B319A72EF4BC262483745526AC3EDDD925 ) ) game ( name "Shinyaku Seiken Densetsu (Japan)" description "Shinyaku Seiken Densetsu (Japan)" - rom ( name "Shinyaku Seiken Densetsu (Japan).gba" size 16777216 crc 31B220E5 md5 B697E95BB90B9DC670CA4872C72BD36C sha1 2970BD5CC070C989B6C0D486263366EE718E7AEA ) + rom ( name "Shinyaku Seiken Densetsu (Japan).gba" size 16777216 crc 31b220e5 sha1 2970BD5CC070C989B6C0D486263366EE718E7AEA ) ) game ( - name "Shiren Monsters Netsal (Japan)" - description "Shiren Monsters Netsal (Japan)" - rom ( name "Shiren Monsters Netsal (Japan).gba" size 16777216 crc C1F2B5EC md5 F238CF012FEC263050F77BB01460404E sha1 D0E522435E453CA33018B6B9D19778873F67B695 ) + name "Shiren Monsters - Netsal (Japan)" + description "Shiren Monsters - Netsal (Japan)" + rom ( name "Shiren Monsters - Netsal (Japan).gba" size 16777216 crc c1f2b5ec sha1 D0E522435E453CA33018B6B9D19778873F67B695 ) ) game ( name "Shrek - Hassle at the Castle (USA) (En,Fr,De,Es,It,Nl)" description "Shrek - Hassle at the Castle (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Hassle at the Castle (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 09E7472C md5 F986D79271E685679F0B5ECB673E9DEA sha1 AFEB14671FAD093FEC0B3AB0E95E01A01DE9F4D8 ) + rom ( name "Shrek - Hassle at the Castle (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 09e7472c sha1 AFEB14671FAD093FEC0B3AB0E95E01A01DE9F4D8 ) ) game ( name "Shrek - Hassle at the Castle (Europe) (En,Fr,De,Es,It,Nl)" description "Shrek - Hassle at the Castle (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Hassle at the Castle (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc CD8E4F85 md5 0AF58674E0FEF09CA529A0A27AECF17A sha1 BE08132BC94FF89BE2BE3B60F9DF6C4AC48ED2B2 ) + rom ( name "Shrek - Hassle at the Castle (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc cd8e4f85 sha1 BE08132BC94FF89BE2BE3B60F9DF6C4AC48ED2B2 flags verified ) ) game ( name "Shrek - Reekin' Havoc (USA) (En,Fr,De,Es,It,Nl)" description "Shrek - Reekin' Havoc (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Reekin' Havoc (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 63F49BA9 md5 05D2D50F8AAC9D4D6E1889432E197167 sha1 AF0BC8338E49BE78CE6E85B59D1DDFCA8A10F290 ) + rom ( name "Shrek - Reekin' Havoc (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 63f49ba9 sha1 AF0BC8338E49BE78CE6E85B59D1DDFCA8A10F290 flags verified ) ) game ( name "Shrek - Reekin' Havoc (Europe) (En,Fr,De,Es,It,Nl)" description "Shrek - Reekin' Havoc (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Reekin' Havoc (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1E4D4813 md5 57709C330EDF8FE50CC52CE5FBFEB2F6 sha1 D044C5C52D52BBAA940AD4622E77EFF075512D2E ) + rom ( name "Shrek - Reekin' Havoc (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1e4d4813 sha1 D044C5C52D52BBAA940AD4622E77EFF075512D2E ) ) game ( name "Shrek - Smash n' Crash Racing (USA)" description "Shrek - Smash n' Crash Racing (USA)" - rom ( name "Shrek - Smash n' Crash Racing (USA).gba" size 8388608 crc EA8AE3B2 md5 B13292B1D67976F9ABF8A318743E88D5 sha1 A7BAB40D1E4E1348E95458BA2E6252562B360D38 ) + rom ( name "Shrek - Smash n' Crash Racing (USA).gba" size 8388608 crc ea8ae3b2 sha1 A7BAB40D1E4E1348E95458BA2E6252562B360D38 ) ) game ( name "Shrek - Smash n' Crash Racing (Europe) (En,Fr,De,Es,It)" description "Shrek - Smash n' Crash Racing (Europe) (En,Fr,De,Es,It)" - rom ( name "Shrek - Smash n' Crash Racing (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc A45857C4 md5 B7BD37B2B39B8AAAD6F297423DB2D2A2 sha1 6ECF2663C30491FA99CCEA3E202D1FF5D0D498C8 ) + rom ( name "Shrek - Smash n' Crash Racing (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc a45857c4 sha1 6ECF2663C30491FA99CCEA3E202D1FF5D0D498C8 ) ) game ( name "Shrek - Super Slam (USA)" description "Shrek - Super Slam (USA)" - rom ( name "Shrek - Super Slam (USA).gba" size 8388608 crc E2EC9EED md5 5578B19468EA4F4281E9D299D67777D8 sha1 39FE7E57E34FBCB65C3D7FD68CE0F09763571718 ) + rom ( name "Shrek - Super Slam (USA).gba" size 8388608 crc e2ec9eed sha1 39FE7E57E34FBCB65C3D7FD68CE0F09763571718 ) ) game ( name "Shrek - Super Slam (Europe) (En,Fr,De,Es,It,Nl)" description "Shrek - Super Slam (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Super Slam (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc DF73101E md5 EC43565BFFB4D418164B85E007DE7E17 sha1 40AB4F4A252963677C39EAC7F5363897696676D1 flags verified ) + rom ( name "Shrek - Super Slam (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc df73101e sha1 40AB4F4A252963677C39EAC7F5363897696676D1 flags verified ) ) game ( name "Shrek - Swamp Kart Speedway (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Shrek - Swamp Kart Speedway (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek - Swamp Kart Speedway (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 91483D87 md5 BE807A4D9DFE2F283760CEE1ECD28A5B sha1 E4897B897EAC0D852789D5FCA2CC587FAEC04B6E flags verified ) + rom ( name "Shrek - Swamp Kart Speedway (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 91483d87 sha1 E4897B897EAC0D852789D5FCA2CC587FAEC04B6E flags verified ) +) + +game ( + name "Shrek - Swamp Kart Speedway (USA) (En,Fr,De,Es,It,Nl) (Rev 1)" + description "Shrek - Swamp Kart Speedway (USA) (En,Fr,De,Es,It,Nl) (Rev 1)" + rom ( name "Shrek - Swamp Kart Speedway (USA) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 41f55560 sha1 86E88EFE3E8C8D7341A990B1DA40EA6C7E66D9A7 flags verified ) ) game ( name "Shrek 2 (USA, Europe)" description "Shrek 2 (USA, Europe)" - rom ( name "Shrek 2 (USA, Europe).gba" size 8388608 crc 52FF42D4 md5 9EF8E30824DB751F3D42E048514A3624 sha1 D3C3201F4A401B337009E667F5B001D5E12ECE83 flags verified ) + rom ( name "Shrek 2 (USA, Europe).gba" size 8388608 crc 52ff42d4 sha1 D3C3201F4A401B337009E667F5B001D5E12ECE83 flags verified ) ) game ( name "Shrek 2 (Europe) (Fr,De,Es,It,Sv)" description "Shrek 2 (Europe) (Fr,De,Es,It,Sv)" - rom ( name "Shrek 2 (Europe) (Fr,De,Es,It,Sv).gba" size 8388608 crc AC1D8C97 md5 2E9B5EC5BB6BE065D2F52AF20BF8ACA3 sha1 1F28AB954789F3946E851D5A132CDA4EDB9B74DD flags verified ) + rom ( name "Shrek 2 (Europe) (Fr,De,Es,It,Sv).gba" size 8388608 crc ac1d8c97 sha1 1F28AB954789F3946E851D5A132CDA4EDB9B74DD flags verified ) ) game ( name "Shrek 2 - Beg for Mercy (USA, Europe)" description "Shrek 2 - Beg for Mercy (USA, Europe)" - rom ( name "Shrek 2 - Beg for Mercy (USA, Europe).gba" size 8388608 crc F1861610 md5 C8A0CE6010243C1B4A05458344C9FC31 sha1 C5873294BB79B9252DA82B02CC53EE7E8F4E663C flags verified ) + rom ( name "Shrek 2 - Beg for Mercy (USA, Europe).gba" size 8388608 crc f1861610 sha1 C5873294BB79B9252DA82B02CC53EE7E8F4E663C flags verified ) ) game ( name "Shrek 2 - Beg for Mercy (Europe) (Fr,De,Es,It)" description "Shrek 2 - Beg for Mercy (Europe) (Fr,De,Es,It)" - rom ( name "Shrek 2 - Beg for Mercy (Europe) (Fr,De,Es,It).gba" size 8388608 crc B6E091CE md5 B81B9913A787699CF76B0B4807518956 sha1 E0699FEA7E3BC400675DBBEE6AAF961C55B8B083 ) + rom ( name "Shrek 2 - Beg for Mercy (Europe) (Fr,De,Es,It).gba" size 8388608 crc b6e091ce sha1 E0699FEA7E3BC400675DBBEE6AAF961C55B8B083 ) ) game ( name "Shrek the Third (USA)" description "Shrek the Third (USA)" - rom ( name "Shrek the Third (USA).gba" size 8388608 crc D7D1DA8D md5 968C5DAA71E6B41C71143852B27AE0B5 sha1 7B87C84C746BE668E89CE94500A3F22DBC206E55 ) + rom ( name "Shrek the Third (USA).gba" size 8388608 crc d7d1da8d sha1 7B87C84C746BE668E89CE94500A3F22DBC206E55 ) ) game ( name "Shrek the Third (Europe) (En,Fr,De,Es,It,Nl)" description "Shrek the Third (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Shrek the Third (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc DA1EE1E5 md5 62A40EA4F49B7DFD192696732306FBA9 sha1 172100399F6F9F3367C251C2C9302073AE57F1C7 ) + rom ( name "Shrek the Third (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc da1ee1e5 sha1 172100399F6F9F3367C251C2C9302073AE57F1C7 ) ) game ( name "Sigma Star Saga (USA, Europe)" description "Sigma Star Saga (USA, Europe)" - rom ( name "Sigma Star Saga (USA, Europe).gba" size 8388608 crc A8B80A7C md5 29B048B4B36B3FDA168850003F2EE844 sha1 132222E0C0DDACB6281CC2EB4489ED6C8719DAC2 flags verified ) + rom ( name "Sigma Star Saga (USA, Europe).gba" size 8388608 crc a8b80a7c sha1 132222E0C0DDACB6281CC2EB4489ED6C8719DAC2 flags verified ) ) game ( name "Silent Scope (USA) (En,Fr,De,Es,It)" description "Silent Scope (USA) (En,Fr,De,Es,It)" - rom ( name "Silent Scope (USA) (En,Fr,De,Es,It).gba" size 8388608 crc C5CE1B2C md5 164E42954FE047552701FF62836642AE sha1 22D8D57AC4B274933ADB492FEE2B32BBC7B6E9BB ) + rom ( name "Silent Scope (USA) (En,Fr,De,Es,It).gba" size 8388608 crc c5ce1b2c sha1 22D8D57AC4B274933ADB492FEE2B32BBC7B6E9BB ) ) game ( name "Silent Scope (Japan)" description "Silent Scope (Japan)" - rom ( name "Silent Scope (Japan).gba" size 8388608 crc 8AB024E0 md5 E953331481A9D72101DB59ED98DCF57A sha1 7C8362369188E41DF4C4E1F737D95906947C09C2 ) + rom ( name "Silent Scope (Japan).gba" size 8388608 crc 8ab024e0 sha1 7C8362369188E41DF4C4E1F737D95906947C09C2 ) ) game ( name "Silent Scope (Europe) (En,Fr,De,Es,It)" description "Silent Scope (Europe) (En,Fr,De,Es,It)" - rom ( name "Silent Scope (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc F03728F3 md5 6116D8CCA2087FDAACBF6F4390C21FFD sha1 53A2F56D21FD7C7ECDD021C26C5D4A768002AB30 ) + rom ( name "Silent Scope (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc f03728f3 sha1 53A2F56D21FD7C7ECDD021C26C5D4A768002AB30 flags verified ) ) game ( name "Silk to Cotton (Japan)" description "Silk to Cotton (Japan)" - rom ( name "Silk to Cotton (Japan).gba" size 8388608 crc 515E2127 md5 88A5225F93074C0445EC912523DA4538 sha1 4F8DDC1FA2C8B00355AD9F09F1BC994A7D5575C7 ) -) - -game ( - name "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1)" - description "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 95C79648 md5 19DFC661C5A3563E001AAAEC36B33B90 sha1 C5EBA83DB30B6B9AA2B770070F729D8D194A55B9 ) + rom ( name "Silk to Cotton (Japan).gba" size 8388608 crc 515e2127 sha1 4F8DDC1FA2C8B00355AD9F09F1BC994A7D5575C7 ) ) game ( name "SimCity 2000 (Europe) (En,Fr,De,Es,It)" description "SimCity 2000 (Europe) (En,Fr,De,Es,It)" - rom ( name "SimCity 2000 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc A74187D3 md5 C37E6A339DCF314BB0C014B737C972D6 sha1 AD31CB6237A888B51585CCD58077B5F8317CE192 ) + rom ( name "SimCity 2000 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc a74187d3 sha1 AD31CB6237A888B51585CCD58077B5F8317CE192 ) ) game ( name "SimCity 2000 (USA)" description "SimCity 2000 (USA)" - rom ( name "SimCity 2000 (USA).gba" size 4194304 crc 733751B3 md5 139B7E51D2F49DFFEEDE13E464BAFEEA sha1 8999C32301EF811DA086E9599D7E7D6CF1533A70 ) + rom ( name "SimCity 2000 (USA).gba" size 4194304 crc 733751b3 sha1 8999C32301EF811DA086E9599D7E7D6CF1533A70 ) +) + +game ( + name "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1)" + description "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1)" + rom ( name "SimCity 2000 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 4194304 crc 95c79648 sha1 C5EBA83DB30B6B9AA2B770070F729D8D194A55B9 flags verified ) +) + +game ( + name "SimCity 2000 (USA) (Rev 1)" + description "SimCity 2000 (USA) (Rev 1)" + rom ( name "SimCity 2000 (USA) (Rev 1).gba" size 4194304 crc 097e8628 sha1 D3842F8EE2F82998FC3BAF0C6DD18F7CFC442B11 flags verified ) ) game ( name "Simple 2960 Tomodachi Series Vol. 1 - The Table Game Collection - Mahjong, Shougi, Hanafuda, Reversi (Japan)" description "Simple 2960 Tomodachi Series Vol. 1 - The Table Game Collection - Mahjong, Shougi, Hanafuda, Reversi (Japan)" - rom ( name "Simple 2960 Tomodachi Series Vol. 1 - The Table Game Collection - Mahjong, Shougi, Hanafuda, Reversi (Japan).gba" size 4194304 crc 8B72BA3C md5 5EAC207F6584CFE026E2094C82AFCF8C sha1 D72780A63B98DEE8EAB14B71896D21237BA44DF4 ) + rom ( name "Simple 2960 Tomodachi Series Vol. 1 - The Table Game Collection - Mahjong, Shougi, Hanafuda, Reversi (Japan).gba" size 4194304 crc 8b72ba3c sha1 D72780A63B98DEE8EAB14B71896D21237BA44DF4 ) ) game ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan)" description "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan)" - rom ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan).gba" size 4194304 crc E731FD45 md5 147EA6FE88F1E2BB50B51E19F5F54CB9 sha1 6435A2492072864FED7C43FF4792328F981C036F ) + rom ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan).gba" size 4194304 crc e731fd45 sha1 6435A2492072864FED7C43FF4792328F981C036F ) ) game ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan) (Rev 1)" description "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan) (Rev 1)" - rom ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan) (Rev 1).gba" size 4194304 crc 180901E3 md5 6834BA555490BE1DEDAE5B13F9BE238D sha1 442DF022B9F4FA748F6AC471B222ECDF3448C667 ) + rom ( name "Simple 2960 Tomodachi Series Vol. 2 - The Block Kuzushi (Japan) (Rev 1).gba" size 4194304 crc 180901e3 sha1 442DF022B9F4FA748F6AC471B222ECDF3448C667 flags verified ) ) game ( name "Simple 2960 Tomodachi Series Vol. 3 - The Itsudemo Puzzle - Massugu Soroete Straws (Japan)" description "Simple 2960 Tomodachi Series Vol. 3 - The Itsudemo Puzzle - Massugu Soroete Straws (Japan)" - rom ( name "Simple 2960 Tomodachi Series Vol. 3 - The Itsudemo Puzzle - Massugu Soroete Straws (Japan).gba" size 4194304 crc 49B92627 md5 D9A3D6AE2EC335FE8CF8008539AC14E7 sha1 4454F88BFB6F04C5A3F231C8983FC22BCC61FDE2 ) + rom ( name "Simple 2960 Tomodachi Series Vol. 3 - The Itsudemo Puzzle - Massugu Soroete Straws (Japan).gba" size 4194304 crc 49b92627 sha1 4454F88BFB6F04C5A3F231C8983FC22BCC61FDE2 ) ) game ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan)" description "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan)" - rom ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan).gba" size 4194304 crc A6FC701F md5 57D3AC8D32B263592B600DC69939B973 sha1 E487E3DB4498C27DD37D601AD973EC9D1BDE5677 ) + rom ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan).gba" size 4194304 crc a6fc701f sha1 E487E3DB4498C27DD37D601AD973EC9D1BDE5677 ) ) game ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan) (Rev 1)" description "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan) (Rev 1)" - serial "BS4J" - rom ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan) (Rev 1).gba" size 4194304 crc 07C2D7ED md5 CA3500BEDD93475C210D4DD16A968D08 sha1 4881CEFC73D6B5D8DAF7079C1B93CB261533E4C4 ) + rom ( name "Simple 2960 Tomodachi Series Vol. 4 - The Trump - Minna de Asoberu 12 Shurui no Trump Game (Japan) (Rev 1).gba" size 4194304 crc 07c2d7ed sha1 4881CEFC73D6B5D8DAF7079C1B93CB261533E4C4 flags verified ) ) game ( name "Simpsons, The - Road Rage (USA, Europe)" description "Simpsons, The - Road Rage (USA, Europe)" - rom ( name "Simpsons, The - Road Rage (USA, Europe).gba" size 8388608 crc 409E8252 md5 8F0FDAEDA361783EE74ABD980B418388 sha1 46347F021F0829EF70A4F52A9B8836D444F9551A flags verified ) + rom ( name "Simpsons, The - Road Rage (USA, Europe).gba" size 8388608 crc 409e8252 sha1 46347F021F0829EF70A4F52A9B8836D444F9551A flags verified ) ) game ( name "Simpsons, The - Road Rage (Europe) (En,Fr,De,Es,It)" description "Simpsons, The - Road Rage (Europe) (En,Fr,De,Es,It)" - rom ( name "Simpsons, The - Road Rage (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 44548B33 md5 D3A5A53A283DE179F8B65B0B5B90D413 sha1 7DE6CBC559AF86DD3C39A80EF89FD4CABE6C0044 ) + rom ( name "Simpsons, The - Road Rage (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 44548b33 sha1 7DE6CBC559AF86DD3C39A80EF89FD4CABE6C0044 ) ) game ( name "Sims 2, The (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Sims 2, The (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sims 2, The (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 8B1BC7DF md5 51455002B0DAA27DE8EAA5D9AD1AFD6F sha1 702A109BD60D2E288814968D49CAACDFD14AE2C6 flags verified ) + rom ( name "Sims 2, The (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 8b1bc7df sha1 702A109BD60D2E288814968D49CAACDFD14AE2C6 flags verified ) ) game ( name "Sims 2, The - Pets (USA, Europe)" description "Sims 2, The - Pets (USA, Europe)" - rom ( name "Sims 2, The - Pets (USA, Europe).gba" size 33554432 crc EC1F4029 md5 1D1BB23346B8A9592316A63647C70D76 sha1 2E95EFA31441F7EFFAF4DD5F9DB97143CA53232D flags verified ) + rom ( name "Sims 2, The - Pets (USA, Europe).gba" size 33554432 crc ec1f4029 sha1 2E95EFA31441F7EFFAF4DD5F9DB97143CA53232D flags verified ) ) game ( name "Sims 2, The - Pets (Europe) (En,Fr,De,Es,It,Nl)" description "Sims 2, The - Pets (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sims 2, The - Pets (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 87F8599C md5 58180E01EAE5278B9A8DC355D80D21CD sha1 C708FB879BD42407F06441258FF5FE4CF733FB68 flags verified ) + rom ( name "Sims 2, The - Pets (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 87f8599c sha1 C708FB879BD42407F06441258FF5FE4CF733FB68 flags verified ) ) game ( name "Sims, The (Japan)" description "Sims, The (Japan)" - rom ( name "Sims, The (Japan).gba" size 16777216 crc 89956199 md5 2B05EF0AF7A48729A665A86573AE70B4 sha1 227857E4AE380668CBC467F5A7A30C6A3A77A180 ) + rom ( name "Sims, The (Japan).gba" size 16777216 crc 89956199 sha1 227857E4AE380668CBC467F5A7A30C6A3A77A180 ) ) game ( name "Sims, The - Bustin' Out (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Sims, The - Bustin' Out (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sims, The - Bustin' Out (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc ABAF519C md5 E429CE307FE06DBCD7724552FF0339D7 sha1 FB5662172FADEBF4577F6F6F163741FC041C11E6 flags verified ) + rom ( name "Sims, The - Bustin' Out (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 16777216 crc abaf519c sha1 FB5662172FADEBF4577F6F6F163741FC041C11E6 flags verified ) +) + +game ( + name "Sims, The - Bustin' Out (USA) (En,Fr,De,Es,It,Nl) (Rev 1)" + description "Sims, The - Bustin' Out (USA) (En,Fr,De,Es,It,Nl) (Rev 1)" + rom ( name "Sims, The - Bustin' Out (USA) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 16777216 crc d1183501 sha1 7038FA0E4CB8AEAC9E48A0B45574DB66CBA39E73 flags verified ) ) game ( name "Sister Princess - RePure (Japan)" description "Sister Princess - RePure (Japan)" - rom ( name "Sister Princess - RePure (Japan).gba" size 8388608 crc 6845C671 md5 9D4AF1CE1B242538B52BDFDF30B5B257 sha1 957DD040F00167D82A497D62AC23984F1DE00450 ) + rom ( name "Sister Princess - RePure (Japan).gba" size 8388608 crc 6845c671 sha1 957DD040F00167D82A497D62AC23984F1DE00450 ) +) + +game ( + name "Sitafei De Chuanshuo (China) (Proto)" + description "Sitafei De Chuanshuo (China) (Proto)" + rom ( name "Sitafei De Chuanshuo (China) (Proto).gba" size 8388608 crc 6f2df7c4 sha1 C10913D0139048FEB1C14DA03A949F5572855DAA flags verified ) +) + +game ( + name "Sitafei De Chuanshuo 2 (China) (Proto)" + description "Sitafei De Chuanshuo 2 (China) (Proto)" + rom ( name "Sitafei De Chuanshuo 2 (China) (Proto).gba" size 16777216 crc e8e756ca sha1 8DFE8DA91357D4CE39793700BCA0ED56FFBB4BD0 flags verified ) ) game ( name "Sitting Ducks (Europe) (En,Fr,De,Es,It,Nl)" description "Sitting Ducks (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sitting Ducks (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc B92A8A88 md5 478DEBC8B8AC10F23A67196180DA8050 sha1 0A329C22BBD92E05DA5496CDFE0837913EDDBDFB flags verified ) + rom ( name "Sitting Ducks (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc b92a8a88 sha1 0A329C22BBD92E05DA5496CDFE0837913EDDBDFB flags verified ) ) game ( name "Sitting Ducks (USA) (En,Fr,De,Es,It,Nl)" description "Sitting Ducks (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Sitting Ducks (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 8BC90ADB md5 747B6E33299DEED3E9FE71C4352F5966 sha1 30B888A0AF86EB0313BE8F34E00C912C569BF51D ) + rom ( name "Sitting Ducks (USA) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 8bc90adb sha1 30B888A0AF86EB0313BE8F34E00C912C569BF51D ) ) game ( name "SK8 - Tony Hawk's Pro Skater 2 (Japan)" description "SK8 - Tony Hawk's Pro Skater 2 (Japan)" - rom ( name "SK8 - Tony Hawk's Pro Skater 2 (Japan).gba" size 8388608 crc 91F93500 md5 E43C13764AF931EC97E828EB15E2BC04 sha1 1B90FB68A7FB15B5EFA6BED5080639229C77977A ) + rom ( name "SK8 - Tony Hawk's Pro Skater 2 (Japan).gba" size 8388608 crc 91f93500 sha1 1B90FB68A7FB15B5EFA6BED5080639229C77977A ) ) game ( name "Sky Dancers - They Magically Fly! (USA)" description "Sky Dancers - They Magically Fly! (USA)" - rom ( name "Sky Dancers - They Magically Fly! (USA).gba" size 4194304 crc CADD57DD md5 FEDF94E93A79D35F70EA85A78FDEE5AA sha1 A757F4A0586081C1058F7E82BBBB5CEDE2819036 ) + rom ( name "Sky Dancers - They Magically Fly! (USA).gba" size 4194304 crc cadd57dd sha1 A757F4A0586081C1058F7E82BBBB5CEDE2819036 ) ) game ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It)" description "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It)" - rom ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3AF1063B md5 3841DE81F12BB38566934A3657F09372 sha1 DF749AC7E33A1C7EDE3FAADB6648A8E53FA77048 ) + rom ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3af1063b sha1 DF749AC7E33A1C7EDE3FAADB6648A8E53FA77048 ) ) game ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" description "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" - rom ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan).gba" size 8388608 crc 1194D33B md5 3608B6CA5D044759903C08C8206F8EE4 sha1 2AED7C064911CD726CBFCCF0131DA69CAA27F48F flags verified ) + rom ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan).gba" size 8388608 crc 1194d33b sha1 2AED7C064911CD726CBFCCF0131DA69CAA27F48F flags verified ) ) game ( name "Slot! Pro 2 Advance - GoGo Juggler & New Tairyou (Japan)" description "Slot! Pro 2 Advance - GoGo Juggler & New Tairyou (Japan)" - rom ( name "Slot! Pro 2 Advance - GoGo Juggler & New Tairyou (Japan).gba" size 4194304 crc 4DA0B936 md5 4F903FB4F60F42E8F12CF77475543738 sha1 B3677ED0C4DDC146897A449C03DF996E8FC0DF3C ) + rom ( name "Slot! Pro 2 Advance - GoGo Juggler & New Tairyou (Japan).gba" size 4194304 crc 4da0b936 sha1 B3677ED0C4DDC146897A449C03DF996E8FC0DF3C flags verified ) ) game ( name "Slot! Pro Advance - Takarabune & Ooedo Sakurafubuki 2 (Japan)" description "Slot! Pro Advance - Takarabune & Ooedo Sakurafubuki 2 (Japan)" - rom ( name "Slot! Pro Advance - Takarabune & Ooedo Sakurafubuki 2 (Japan).gba" size 8388608 crc D9A8D01F md5 8893DCD52C5E4C3A7B8991A4CA7FB73E sha1 47440FA1DC5525595A1D95BDE4CCDD5755365138 flags verified ) + rom ( name "Slot! Pro Advance - Takarabune & Ooedo Sakurafubuki 2 (Japan).gba" size 8388608 crc d9a8d01f sha1 47440FA1DC5525595A1D95BDE4CCDD5755365138 flags verified ) ) game ( name "Smashing Drive (USA)" description "Smashing Drive (USA)" - rom ( name "Smashing Drive (USA).gba" size 8388608 crc 2390ACA6 md5 5E2E52C6BC979AA50EFB59D9386FAF08 sha1 BB47246DC6882037DAA778FCDFDAF34E8715E7FB ) + rom ( name "Smashing Drive (USA).gba" size 8388608 crc 2390aca6 sha1 BB47246DC6882037DAA778FCDFDAF34E8715E7FB ) ) game ( name "Smashing Drive (Europe) (En,Fr,De,Es,It)" description "Smashing Drive (Europe) (En,Fr,De,Es,It)" - rom ( name "Smashing Drive (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1034D672 md5 A0A932C70A245ED923125D7E62B10F01 sha1 EF2657C476294983430E8E8A6C119C847133C932 ) + rom ( name "Smashing Drive (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1034d672 sha1 EF2657C476294983430E8E8A6C119C847133C932 ) ) game ( name "Smuggler's Run (USA)" description "Smuggler's Run (USA)" - rom ( name "Smuggler's Run (USA).gba" size 8388608 crc 1A6AEA5E md5 E639EF65C3638C0B5927A4D3FC947E3D sha1 A14EFB987BFCF3F547DB2650CD2CC6DCA3ADCF73 ) + rom ( name "Smuggler's Run (USA).gba" size 8388608 crc 1a6aea5e sha1 A14EFB987BFCF3F547DB2650CD2CC6DCA3ADCF73 ) ) game ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It)" description "Smuggler's Run (Europe) (En,Fr,De,Es,It)" - rom ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3AE0AFC8 md5 3FDA0C02E17C83B4B71487B13780816C sha1 E87067719DA93F0D7C8136CDF5717612A6C15034 ) + rom ( name "Smuggler's Run (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3ae0afc8 sha1 E87067719DA93F0D7C8136CDF5717612A6C15034 flags verified ) ) game ( - name "Smurfs, The - The Revenge of the Smurfs (Europe) (En,Fr,De,Es,It,Nl)" - description "Smurfs, The - The Revenge of the Smurfs (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Smurfs, The - The Revenge of the Smurfs (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 516CE770 md5 3F9EA1E569FC4405974537224BD522CB sha1 846996F49910121B1DD2915C3BF203A767C6408A flags verified ) + name "SN Systems (Europe)" + description "SN Systems (Europe)" + rom ( name "SN Systems (Europe).GBA" size 33554432 crc 00f5687a sha1 7FF5A2CA66562F3FA53AB2EFCA5D7AD435ADBA3D flags verified ) ) game ( name "Snap Kid's (Japan)" description "Snap Kid's (Japan)" - rom ( name "Snap Kid's (Japan).gba" size 16777216 crc 41E35C6A md5 A9C50293AC1C9C2FC59308F0EC1BA892 sha1 3E1D536762344D46E6948CC4D9C18B00D5284164 ) + rom ( name "Snap Kid's (Japan).gba" size 16777216 crc 41e35c6a sha1 3E1D536762344D46E6948CC4D9C18B00D5284164 ) ) game ( name "Snood (USA)" description "Snood (USA)" - rom ( name "Snood (USA).gba" size 4194304 crc F1F1F148 md5 66F4A5A101822A779FDFECF366E73C96 sha1 2C09548AE924AC0C1A3E15412D9A7AAE7707A753 ) + rom ( name "Snood (USA).gba" size 4194304 crc f1f1f148 sha1 2C09548AE924AC0C1A3E15412D9A7AAE7707A753 ) ) game ( name "Snood (Europe) (En,Fr,De,Es,It)" description "Snood (Europe) (En,Fr,De,Es,It)" - rom ( name "Snood (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 32BD1486 md5 A9572991316AC2E105ABFEC80AAEB02E sha1 722998B2DBDE669CACF8071E3A466E2C0CB9BAFB ) + rom ( name "Snood (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 32bd1486 sha1 722998B2DBDE669CACF8071E3A466E2C0CB9BAFB ) ) game ( name "Snood 2 - On Vacation (Europe) (En,Fr,De,Es,It)" description "Snood 2 - On Vacation (Europe) (En,Fr,De,Es,It)" - rom ( name "Snood 2 - On Vacation (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6470252F md5 1205D76449958F1D204F380499C7CFFF sha1 603E5DB33FF80F953211276CAB729D82077ACE72 ) + rom ( name "Snood 2 - On Vacation (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6470252f sha1 603E5DB33FF80F953211276CAB729D82077ACE72 ) ) game ( name "Snood 2 - On Vacation (USA)" description "Snood 2 - On Vacation (USA)" - rom ( name "Snood 2 - On Vacation (USA).gba" size 4194304 crc D8E05727 md5 1D15CD3454A3566DC51D9321563D8C12 sha1 29E86415F5B3DA0171F4DAC895005FBCDD373447 ) + rom ( name "Snood 2 - On Vacation (USA).gba" size 4194304 crc d8e05727 sha1 29E86415F5B3DA0171F4DAC895005FBCDD373447 ) ) game ( name "Soccer Kid (USA, Europe)" description "Soccer Kid (USA, Europe)" - rom ( name "Soccer Kid (USA, Europe).gba" size 4194304 crc D3485F5A md5 DEDC14EAC17A4BB6E043F09D5B793F99 sha1 4E7DC4D47EF064131990FE3EBB340EDEAED321EF flags verified ) + rom ( name "Soccer Kid (USA, Europe).gba" size 4194304 crc d3485f5a sha1 4E7DC4D47EF064131990FE3EBB340EDEAED321EF flags verified ) ) game ( name "Sonic Advance (Japan) (En,Ja)" description "Sonic Advance (Japan) (En,Ja)" - rom ( name "Sonic Advance (Japan) (En,Ja).gba" size 8388608 crc 5F512223 md5 B62F11B1D014D5C5C2DD703676CB443D sha1 8DAB4C2D38BD13ED88F98A9210CD0CB4FF11520C ) + rom ( name "Sonic Advance (Japan) (En,Ja).gba" size 8388608 crc 5f512223 sha1 8DAB4C2D38BD13ED88F98A9210CD0CB4FF11520C ) ) game ( name "Sonic Advance (USA) (En,Ja)" description "Sonic Advance (USA) (En,Ja)" - rom ( name "Sonic Advance (USA) (En,Ja).gba" size 8388608 crc 63F70FD8 md5 49ECC8EF1988E7AE81FBDA1B4CF71EED sha1 D842AFA7DD1E84DE08ADDB94A51506F1BCAFD551 ) + rom ( name "Sonic Advance (USA) (En,Ja).gba" size 8388608 crc 63f70fd8 sha1 D842AFA7DD1E84DE08ADDB94A51506F1BCAFD551 ) ) game ( name "Sonic Advance (Europe) (En,Ja,Fr,De,Es)" description "Sonic Advance (Europe) (En,Ja,Fr,De,Es)" - rom ( name "Sonic Advance (Europe) (En,Ja,Fr,De,Es).gba" size 8388608 crc 6232839B md5 93A2F28339858E955E4F17060E038BCD sha1 EB00F101AF23D728075AC2117E27ECD8A4B4C3E9 flags verified ) + rom ( name "Sonic Advance (Europe) (En,Ja,Fr,De,Es).gba" size 8388608 crc 6232839b sha1 EB00F101AF23D728075AC2117E27ECD8A4B4C3E9 flags verified ) ) game ( name "Sonic Advance (Japan) (En,Ja) (Rev 1)" description "Sonic Advance (Japan) (En,Ja) (Rev 1)" - rom ( name "Sonic Advance (Japan) (En,Ja) (Rev 1).gba" size 8388608 crc 85957A24 md5 9E02F1C9F26F40905D43188B2BD2D98E sha1 F43FACA5D8DF354A63471AEBFEA3BE125E797E51 ) + rom ( name "Sonic Advance (Japan) (En,Ja) (Rev 1).gba" size 8388608 crc 85957a24 sha1 F43FACA5D8DF354A63471AEBFEA3BE125E797E51 flags verified ) ) game ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 513804FF md5 A219B3042EB65899BAAFA5143C53560C sha1 DFFD0188FC78154B42B401398A224AE0713EDF23 flags verified ) + rom ( name "Sonic Advance 2 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 513804ff sha1 DFFD0188FC78154B42B401398A224AE0713EDF23 flags verified ) ) game ( name "Sonic Advance 2 (USA) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 2 (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 2 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 7EFEE7F7 md5 3FB865C5F142A8FC1F82105BFC6B8935 sha1 7BCD6A07AF7C894746FA28073FE0C0E34408022D ) + rom ( name "Sonic Advance 2 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 7efee7f7 sha1 7BCD6A07AF7C894746FA28073FE0C0E34408022D flags verified ) ) game ( name "Sonic Advance 2 (Europe) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 2 (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 2 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 89509891 md5 6664B43C51935EA8F06F5B37CE83FECA sha1 B0F64BDCA097F2DE8F05AC4C8CAEA2B80C5FAEB1 flags verified ) -) - -game ( - name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" - description "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" - rom ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta).gba" size 16777216 crc 4C93DAC6 md5 EDD737AA42CBC7FA7D8B86C249F06CA1 sha1 DCDD05854B47C52A74FF13F8D50CB1C7F612E376 ) + rom ( name "Sonic Advance 2 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 89509891 sha1 B0F64BDCA097F2DE8F05AC4C8CAEA2B80C5FAEB1 flags verified ) ) game ( name "Sonic Advance 3 (USA) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 3 (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 3 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 49DDA5E6 md5 E0533FAF6AA36E3111669574F1C5DF92 sha1 30DB467EFFA5014806D42DB57E2299398A51355B ) + rom ( name "Sonic Advance 3 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 49dda5e6 sha1 30DB467EFFA5014806D42DB57E2299398A51355B flags verified ) ) game ( name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 4375F1D6 md5 A2BD14F0B57836FE7288E03A6FC154FA sha1 BF8A4A7DB9B5F45DD4FFEBCE67585D6556055ED4 ) + rom ( name "Sonic Advance 3 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 4375f1d6 sha1 BF8A4A7DB9B5F45DD4FFEBCE67585D6556055ED4 flags verified ) ) game ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It)" description "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 5BF83456 md5 E6B78109C11D82F621DB846DA70BC30A sha1 685AF3A2DC0F1B3F8922E73EC42C1DC92E210E39 flags verified ) + rom ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 5bf83456 sha1 685AF3A2DC0F1B3F8922E73EC42C1DC92E210E39 flags verified ) +) + +game ( + name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" + description "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta)" + rom ( name "Sonic Advance 3 (Europe) (En,Ja,Fr,De,Es,It) (Beta).gba" size 16777216 crc 4c93dac6 sha1 DCDD05854B47C52A74FF13F8D50CB1C7F612E376 ) ) game ( name "Sonic Battle (Japan) (En,Ja)" description "Sonic Battle (Japan) (En,Ja)" - rom ( name "Sonic Battle (Japan) (En,Ja).gba" size 16777216 crc 7305AC30 md5 1C694783ACDFD013BDD980A4D8F8F546 sha1 EC68166A437895953BBBCE256EBEFAEBB77C0156 ) + rom ( name "Sonic Battle (Japan) (En,Ja).gba" size 16777216 crc 7305ac30 sha1 EC68166A437895953BBBCE256EBEFAEBB77C0156 ) ) game ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It)" description "Sonic Battle (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 9EC9D86F md5 100579EF01225C620560F88E65CA423A sha1 8CF4FBBE73F6B1907AB9997CAAB4C4E7D9708937 ) + rom ( name "Sonic Battle (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 9ec9d86f sha1 8CF4FBBE73F6B1907AB9997CAAB4C4E7D9708937 ) ) game ( name "Sonic Battle (Europe) (En,Ja,Fr,De,Es,It)" description "Sonic Battle (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Battle (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc D0F65125 md5 7194F25DA6BE4548F7E0C80F73E3F628 sha1 29F19B564020BD4667C33827B39ADAE7ADE74679 flags verified ) + rom ( name "Sonic Battle (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc d0f65125 sha1 29F19B564020BD4667C33827B39ADAE7ADE74679 flags verified ) ) game ( name "Sonic Pinball Party (USA) (En,Ja,Fr,De,Es,It)" description "Sonic Pinball Party (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Pinball Party (USA) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 08794743 md5 DE40B1738A7C670CA28DDF44BB908DF6 sha1 92B5C19CB4DEE8FDFC15A8ABDC699822D5373042 flags verified ) + rom ( name "Sonic Pinball Party (USA) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 08794743 sha1 92B5C19CB4DEE8FDFC15A8ABDC699822D5373042 flags verified ) ) game ( name "Sonic Pinball Party (Japan) (En,Ja,Fr,De,Es,It)" description "Sonic Pinball Party (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Pinball Party (Japan) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 43B5F167 md5 0C8060D8231B01FB2B6670A5E059122D sha1 B458F8C15178025960974FC520A9B28E8A7C25EE ) + rom ( name "Sonic Pinball Party (Japan) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 43b5f167 sha1 B458F8C15178025960974FC520A9B28E8A7C25EE ) ) game ( name "Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" description "Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 4435917E md5 95CE5443198044F4546A42D9D67BE0E2 sha1 153CBDF30D133F92FA811A212B3D8BF6857FD29C flags verified ) + rom ( name "Sonic Pinball Party (Europe) (En,Ja,Fr,De,Es,It).gba" size 8388608 crc 4435917e sha1 153CBDF30D133F92FA811A212B3D8BF6857FD29C flags verified ) ) game ( name "Sonic The Hedgehog - Genesis (USA)" description "Sonic The Hedgehog - Genesis (USA)" - rom ( name "Sonic The Hedgehog - Genesis (USA).gba" size 4194304 crc 027BC70D md5 8105A6012737AAC2907B27E4A05AD794 sha1 31B9DEE3B9289A32218F0E39667A6C2504E3F3D0 ) + rom ( name "Sonic The Hedgehog - Genesis (USA).gba" size 4194304 crc 027bc70d sha1 31B9DEE3B9289A32218F0E39667A6C2504E3F3D0 ) ) game ( name "Sound of Thunder, A (Europe) (En,Fr,De,Es,It)" description "Sound of Thunder, A (Europe) (En,Fr,De,Es,It)" - rom ( name "Sound of Thunder, A (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc CF404AEE md5 4A0E450C74E3E07F261A9A8F5624B788 sha1 DE11AB261FDE7548DB244206DD712E50AC486B7B ) + rom ( name "Sound of Thunder, A (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc cf404aee sha1 DE11AB261FDE7548DB244206DD712E50AC486B7B ) ) game ( name "Sound of Thunder, A (USA) (En,Fr,De,Es,It)" description "Sound of Thunder, A (USA) (En,Fr,De,Es,It)" - rom ( name "Sound of Thunder, A (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 72894E1B md5 26B44C6F29E95B1AAE1B79F37725D959 sha1 6EEB95555C432E2A28E29438711F2FDEE4D9CF7F ) + rom ( name "Sound of Thunder, A (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 72894e1b sha1 6EEB95555C432E2A28E29438711F2FDEE4D9CF7F ) ) game ( name "Space Channel 5 - Ulala's Cosmic Attack (USA)" description "Space Channel 5 - Ulala's Cosmic Attack (USA)" - rom ( name "Space Channel 5 - Ulala's Cosmic Attack (USA).gba" size 8388608 crc 0666F37A md5 B50707AD72A97B131F4D620483287F95 sha1 B5401223641A45DD7CCDE5504D517ED765D34484 ) + rom ( name "Space Channel 5 - Ulala's Cosmic Attack (USA).gba" size 8388608 crc 0666f37a sha1 B5401223641A45DD7CCDE5504D517ED765D34484 ) ) game ( name "Space Channel 5 - Ulala's Cosmic Attack (Europe)" description "Space Channel 5 - Ulala's Cosmic Attack (Europe)" - rom ( name "Space Channel 5 - Ulala's Cosmic Attack (Europe).gba" size 8388608 crc 0F105694 md5 B8CAEB3B81D7D5EB7B6924D5C37DF19E sha1 876CB25DF118B29E37006BD3894ABFC79F229B82 ) + rom ( name "Space Channel 5 - Ulala's Cosmic Attack (Europe).gba" size 8388608 crc 0f105694 sha1 876CB25DF118B29E37006BD3894ABFC79F229B82 ) ) game ( name "Space Hexcite - Maetel Legend EX (Japan)" description "Space Hexcite - Maetel Legend EX (Japan)" - rom ( name "Space Hexcite - Maetel Legend EX (Japan).gba" size 4194304 crc BD4E6008 md5 39564BB823B7286AD977D6428A020E5F sha1 7154E2F38137CE6F51FFFF4F1E25C94AABD1FBF5 flags verified ) + rom ( name "Space Hexcite - Maetel Legend EX (Japan).gba" size 4194304 crc bd4e6008 sha1 7154E2F38137CE6F51FFFF4F1E25C94AABD1FBF5 flags verified ) ) game ( name "Space Invaders (USA, Europe)" description "Space Invaders (USA, Europe)" - rom ( name "Space Invaders (USA, Europe).gba" size 4194304 crc 5EA3F3B5 md5 2AE83E668D4098F60A686962AE8EA71A sha1 DBB39EADEF98A3F8C7DE0DE889B2932DBE293283 flags verified ) + rom ( name "Space Invaders (USA, Europe).gba" size 4194304 crc 5ea3f3b5 sha1 DBB39EADEF98A3F8C7DE0DE889B2932DBE293283 flags verified ) ) game ( name "Space Invaders (France)" description "Space Invaders (France)" - rom ( name "Space Invaders (France).gba" size 4194304 crc 59372656 md5 581120B8E9BBE9B3409FF219EE3D1B78 sha1 899D6760C40B52351B7EFE7A155304AAFE2A77F7 ) + rom ( name "Space Invaders (France).gba" size 4194304 crc 59372656 sha1 899D6760C40B52351B7EFE7A155304AAFE2A77F7 ) ) game ( name "Space Invaders EX (Japan) (En)" description "Space Invaders EX (Japan) (En)" - rom ( name "Space Invaders EX (Japan) (En).gba" size 4194304 crc 297B9854 md5 59FACFA52DC4730F506A3FE41466F657 sha1 AE8CACE77BACCDB8F25C9B44EA3CF64D881B91A8 ) + rom ( name "Space Invaders EX (Japan) (En).gba" size 4194304 crc 297b9854 sha1 AE8CACE77BACCDB8F25C9B44EA3CF64D881B91A8 ) ) game ( name "Speedball 2 - Brutal Deluxe (Europe) (En,Fr,De,Es,It)" description "Speedball 2 - Brutal Deluxe (Europe) (En,Fr,De,Es,It)" - rom ( name "Speedball 2 - Brutal Deluxe (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 051F3D0D md5 EF51D33FD8473D11C3B8083937E6CDF5 sha1 82113A8EA6E70AB347DC2778B0FE98AB9E142E55 ) + rom ( name "Speedball 2 - Brutal Deluxe (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 051f3d0d sha1 82113A8EA6E70AB347DC2778B0FE98AB9E142E55 ) ) game ( name "Spider-Man (USA, Europe)" description "Spider-Man (USA, Europe)" - rom ( name "Spider-Man (USA, Europe).gba" size 8388608 crc 406265B8 md5 6EA428EABF05D2C51ED21B5608C5DB21 sha1 C81EFC39DE8349D63AD30E72BBF3B049F37E542A flags verified ) + rom ( name "Spider-Man (USA, Europe).gba" size 8388608 crc 406265b8 sha1 C81EFC39DE8349D63AD30E72BBF3B049F37E542A flags verified ) ) game ( name "Spider-Man (France)" description "Spider-Man (France)" - rom ( name "Spider-Man (France).gba" size 8388608 crc 832EA2B1 md5 46E6CC0BEEBB0DF7077540866AB98BF3 sha1 4F59528790E57CC469925AC933FB0F758BBE4D67 ) + rom ( name "Spider-Man (France).gba" size 8388608 crc 832ea2b1 sha1 4F59528790E57CC469925AC933FB0F758BBE4D67 ) ) game ( name "Spider-Man (Germany)" description "Spider-Man (Germany)" - rom ( name "Spider-Man (Germany).gba" size 8388608 crc E9D9B35F md5 7452F7A8E88435A3C4010262A78037E6 sha1 DA1B9D0C430A1967DE37798F245FFC9EF1F05E47 ) + rom ( name "Spider-Man (Germany).gba" size 8388608 crc e9d9b35f sha1 DA1B9D0C430A1967DE37798F245FFC9EF1F05E47 ) ) game ( name "Spider-Man - Battle for New York (USA)" description "Spider-Man - Battle for New York (USA)" - rom ( name "Spider-Man - Battle for New York (USA).gba" size 16777216 crc 6310BA16 md5 833C3FAC4BA420D0A3E4ADE9184E2BF0 sha1 66561B33AF0F427B74950ED0AB33AFD0EC68957E ) + rom ( name "Spider-Man - Battle for New York (USA).gba" size 16777216 crc 6310ba16 sha1 66561B33AF0F427B74950ED0AB33AFD0EC68957E ) ) game ( name "Spider-Man - Battle for New York (Europe) (En,Fr,De,Es,It)" description "Spider-Man - Battle for New York (Europe) (En,Fr,De,Es,It)" - rom ( name "Spider-Man - Battle for New York (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc AD2C404C md5 02A1D4F4EFD3553D9A890CAD60AD62C4 sha1 FF31B61ECAE695B7E67E39A9FB46999D3CFD4632 flags verified ) + rom ( name "Spider-Man - Battle for New York (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ad2c404c sha1 FF31B61ECAE695B7E67E39A9FB46999D3CFD4632 flags verified ) ) game ( name "Spider-Man - Mysterio no Kyoui (Japan)" description "Spider-Man - Mysterio no Kyoui (Japan)" - rom ( name "Spider-Man - Mysterio no Kyoui (Japan).gba" size 8388608 crc F8125C4B md5 E2026EACC69F10684DD4D370C4ABEDEC sha1 4E7504A3692A56819398D1C79A9A0FFB84507864 ) + rom ( name "Spider-Man - Mysterio no Kyoui (Japan).gba" size 8388608 crc f8125c4b sha1 4E7504A3692A56819398D1C79A9A0FFB84507864 ) ) game ( name "Spider-Man - Mysterio's Menace (USA, Europe)" description "Spider-Man - Mysterio's Menace (USA, Europe)" - rom ( name "Spider-Man - Mysterio's Menace (USA, Europe).gba" size 8388608 crc 6E135B4D md5 FBDA16CBC7E3F81AA5B90DA955D3E114 sha1 EF80933054D6BE9532D5D35BEE6F715438301755 flags verified ) + rom ( name "Spider-Man - Mysterio's Menace (USA, Europe).gba" size 8388608 crc 6e135b4d sha1 EF80933054D6BE9532D5D35BEE6F715438301755 flags verified ) ) game ( name "Spider-Man 2 (USA, Europe)" description "Spider-Man 2 (USA, Europe)" - rom ( name "Spider-Man 2 (USA, Europe).gba" size 16777216 crc 0145F3F4 md5 7914EA9BED5D6936CEC9B1C240247BDA sha1 BB4A913F73139754DDA95EB6B63D3B07501DA970 flags verified ) + rom ( name "Spider-Man 2 (USA, Europe).gba" size 16777216 crc 0145f3f4 sha1 BB4A913F73139754DDA95EB6B63D3B07501DA970 flags verified ) ) game ( name "Spider-Man 2 (Europe) (En,Fr,De,Es)" description "Spider-Man 2 (Europe) (En,Fr,De,Es)" - rom ( name "Spider-Man 2 (Europe) (En,Fr,De,Es).gba" size 16777216 crc 821838BC md5 22695F0E188ADEBAA5F7B865C9719DAA sha1 042CBC4C7F720A4B0C9A2CB3E77B2339DB346A1E ) + rom ( name "Spider-Man 2 (Europe) (En,Fr,De,Es).gba" size 16777216 crc 821838bc sha1 042CBC4C7F720A4B0C9A2CB3E77B2339DB346A1E ) ) game ( name "Spider-Man 2 (Italy)" description "Spider-Man 2 (Italy)" - rom ( name "Spider-Man 2 (Italy).gba" size 16777216 crc 66340F23 md5 DDD7EA535FBD95D05686186A4B15AEF6 sha1 FE8CEA2389676D965051368AABD6CC614FFABD28 ) + rom ( name "Spider-Man 2 (Italy).gba" size 16777216 crc 66340f23 sha1 FE8CEA2389676D965051368AABD6CC614FFABD28 ) ) game ( name "Spider-Man 3 (Germany)" description "Spider-Man 3 (Germany)" - rom ( name "Spider-Man 3 (Germany).gba" size 8388608 crc FDA3C9DD md5 98F96E81826945FAD686B08FE7D10E0C sha1 F67AF0A5C0A37C48F808DD74EEE6E95724A9A5D7 ) + rom ( name "Spider-Man 3 (Germany).gba" size 8388608 crc fda3c9dd sha1 F67AF0A5C0A37C48F808DD74EEE6E95724A9A5D7 ) ) game ( name "Spider-Man 3 (USA)" description "Spider-Man 3 (USA)" - rom ( name "Spider-Man 3 (USA).gba" size 8388608 crc AD0228A1 md5 7D2C4F995B82825AA63FE224733D769B sha1 F3F7F759D345EED0F5FAEE3488B86916C6AE1EFE ) + rom ( name "Spider-Man 3 (USA).gba" size 8388608 crc ad0228a1 sha1 F3F7F759D345EED0F5FAEE3488B86916C6AE1EFE ) ) game ( name "Spider-Man 3 (Europe)" description "Spider-Man 3 (Europe)" - rom ( name "Spider-Man 3 (Europe).gba" size 8388608 crc 6BE8D68C md5 228FCA59CBDCFF493F207271411E15A5 sha1 1645FAF08ABE193CE910BBF6A6AF5EDE3DCECA62 ) + rom ( name "Spider-Man 3 (Europe).gba" size 8388608 crc 6be8d68c sha1 1645FAF08ABE193CE910BBF6A6AF5EDE3DCECA62 ) ) game ( name "Spider-Man 3 (Spain)" description "Spider-Man 3 (Spain)" - rom ( name "Spider-Man 3 (Spain).gba" size 8388608 crc E6251FD3 md5 8557791A1F72183A1AB451DF4AD032B9 sha1 2A8E6A5E71BD670ED7803CCD9FFCF7F9897CB4C5 ) + rom ( name "Spider-Man 3 (Spain).gba" size 8388608 crc e6251fd3 sha1 2A8E6A5E71BD670ED7803CCD9FFCF7F9897CB4C5 ) ) game ( name "Spider-Man 3 (Italy)" description "Spider-Man 3 (Italy)" - rom ( name "Spider-Man 3 (Italy).gba" size 8388608 crc E8FB4B9A md5 337B64F47229B4284DF404A69E9D17AE sha1 9BB721ED726F6CD523C064BCE4A863BA096B2980 ) + rom ( name "Spider-Man 3 (Italy).gba" size 8388608 crc e8fb4b9a sha1 9BB721ED726F6CD523C064BCE4A863BA096B2980 ) ) game ( name "Spider-Man 3 (France)" description "Spider-Man 3 (France)" - rom ( name "Spider-Man 3 (France).gba" size 8388608 crc 450D1D48 md5 7C970129793C2987574CBBA45E12871B sha1 12720C39F1DD44837CCDE15F5B347977879A63A8 ) -) - -game ( - name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" - description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" - rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta).gba" size 4183576 crc CAAAEFB6 md5 AC7714CEEAB8964EA40CFAC5C52AFD5F sha1 53C4BB950D9B92918F26AEB7B0105604D0263BA1 ) + rom ( name "Spider-Man 3 (France).gba" size 8388608 crc 450d1d48 sha1 12720C39F1DD44837CCDE15F5B347977879A63A8 ) ) game ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany)" description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany)" - rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany).gba" size 4194304 crc 4785EEE0 md5 9A2CB830688554BE22077F7337A0B614 sha1 CE8F271E143456616A9649FEE7D47EF1602EE497 ) + rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany).gba" size 4194304 crc 4785eee0 sha1 CE8F271E143456616A9649FEE7D47EF1602EE497 ) +) + +game ( + name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" + description "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta)" + rom ( name "Spirit - Der Wilde Mustang - Auf der Suche nach Homeland (Germany) (Beta).gba" size 4183576 crc caaaefb6 sha1 53C4BB950D9B92918F26AEB7B0105604D0263BA1 ) ) game ( name "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France)" description "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France)" - rom ( name "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France).gba" size 4194304 crc C8C76255 md5 DE5D47CD1D1632127C6D1FA8CF90C849 sha1 0AA4FEDC71F168F19E3263E7C0347A6CA81B80D0 ) + rom ( name "Spirit - L'Etalon des Plaines - A la Recherche de la Terre Natale (France).gba" size 4194304 crc c8c76255 sha1 0AA4FEDC71F168F19E3263E7C0347A6CA81B80D0 ) ) game ( name "Spirit - Stallion of the Cimarron - Search for Homeland (USA)" description "Spirit - Stallion of the Cimarron - Search for Homeland (USA)" - rom ( name "Spirit - Stallion of the Cimarron - Search for Homeland (USA).gba" size 4194304 crc 9A457633 md5 9B5B46FF73E5746F753747B79D2AFD66 sha1 220791A2A4DB7D45FC6FB0BD259CF7A8D24E3A6D ) + rom ( name "Spirit - Stallion of the Cimarron - Search for Homeland (USA).gba" size 4194304 crc 9a457633 sha1 220791A2A4DB7D45FC6FB0BD259CF7A8D24E3A6D ) ) game ( name "Spirit - Stallion of the Cimarron - Search for Homeland (Europe)" description "Spirit - Stallion of the Cimarron - Search for Homeland (Europe)" - rom ( name "Spirit - Stallion of the Cimarron - Search for Homeland (Europe).gba" size 4194304 crc AEE21783 md5 B77BAC65FFE2931764ADBAEC3A8CD995 sha1 9158B8A2998C6BB78DF8904C2E230B51F82C9531 ) + rom ( name "Spirit - Stallion of the Cimarron - Search for Homeland (Europe).gba" size 4194304 crc aee21783 sha1 9158B8A2998C6BB78DF8904C2E230B51F82C9531 ) ) game ( name "Spirits & Spells (USA)" description "Spirits & Spells (USA)" - rom ( name "Spirits & Spells (USA).gba" size 4194304 crc 2FA6DB95 md5 DCE828E687F05511C1AD70E936B5EF25 sha1 5B4764AF4F7D0DF24ADF0DF0AE486F33BD905DC7 ) + rom ( name "Spirits & Spells (USA).gba" size 4194304 crc 2fa6db95 sha1 5B4764AF4F7D0DF24ADF0DF0AE486F33BD905DC7 ) ) game ( name "SpongeBob and Friends - Attack of the Toybots (Europe) (En,De)" description "SpongeBob and Friends - Attack of the Toybots (Europe) (En,De)" - rom ( name "SpongeBob and Friends - Attack of the Toybots (Europe) (En,De).gba" size 4194304 crc F0B0F53C md5 A7511D8A3982F175ADF8EF683B96B24B sha1 7D698125B0441638953A0E10057B6B29F779CB61 ) + rom ( name "SpongeBob and Friends - Attack of the Toybots (Europe) (En,De).gba" size 4194304 crc f0b0f53c sha1 7D698125B0441638953A0E10057B6B29F779CB61 ) ) game ( name "SpongeBob SquarePants - Battle for Bikini Bottom (USA)" description "SpongeBob SquarePants - Battle for Bikini Bottom (USA)" - rom ( name "SpongeBob SquarePants - Battle for Bikini Bottom (USA).gba" size 8388608 crc 235628C3 md5 3992A0D8089401553CE3478BD9863AAC sha1 DB3A7B838149765A28E939BA162F72202D302B40 flags verified ) + rom ( name "SpongeBob SquarePants - Battle for Bikini Bottom (USA).gba" size 8388608 crc 235628c3 sha1 DB3A7B838149765A28E939BA162F72202D302B40 flags verified ) ) game ( name "SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En,Fr,De)" description "SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En,Fr,De)" - rom ( name "SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En,Fr,De).gba" size 8388608 crc DE4A85C0 md5 E84DE432672187D3D0B8F4D4D654013B sha1 FD66FA65ED2351C4493D4C3E32768FAD9701E822 ) + rom ( name "SpongeBob SquarePants - Battle for Bikini Bottom (Europe) (En,Fr,De).gba" size 8388608 crc de4a85c0 sha1 FD66FA65ED2351C4493D4C3E32768FAD9701E822 ) ) game ( name "SpongeBob SquarePants - Creature from the Krusty Krab (USA)" description "SpongeBob SquarePants - Creature from the Krusty Krab (USA)" - rom ( name "SpongeBob SquarePants - Creature from the Krusty Krab (USA).gba" size 8388608 crc 51CE91D6 md5 45E6E3088C5C9006175AAF045E8795E8 sha1 1EC8B5D234ECDC8FA61A5850A76D1D407DAC3333 ) + rom ( name "SpongeBob SquarePants - Creature from the Krusty Krab (USA).gba" size 8388608 crc 51ce91d6 sha1 1EC8B5D234ECDC8FA61A5850A76D1D407DAC3333 ) ) game ( name "SpongeBob SquarePants - Creature from the Krusty Krab (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "SpongeBob SquarePants - Creature from the Krusty Krab (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "SpongeBob SquarePants - Creature from the Krusty Krab (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 7580FBD6 md5 7F22C443EC71A696D84AE46A9FE61980 sha1 A2543C78C3D97D08A50646A2646B1B171FACCCB9 ) + rom ( name "SpongeBob SquarePants - Creature from the Krusty Krab (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc 7580fbd6 sha1 A2543C78C3D97D08A50646A2646B1B171FACCCB9 ) ) game ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA)" description "SpongeBob SquarePants - Lights, Camera, Pants! (USA)" - rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA).gba" size 4194304 crc 23297579 md5 9A5A6C940BBF141D8C2838CF7C818080 sha1 4C3C7AE6D1BF3D46BAB640911AA2BB9094CC31F2 ) + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA).gba" size 4194304 crc 23297579 sha1 4C3C7AE6D1BF3D46BAB640911AA2BB9094CC31F2 ) ) game ( name "SpongeBob SquarePants - Lights, Camera, Pants! (Europe) (En,Fr,De,Es,It,Nl,Sv)" description "SpongeBob SquarePants - Lights, Camera, Pants! (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (Europe) (En,Fr,De,Es,It,Nl,Sv).gba" size 8388608 crc C189013D md5 24A24025A5E3B15512D4B5858B07C662 sha1 09D945ACC251000C49539A3F18B21E48520EC8AD flags verified ) -) - -game ( - name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" - description "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" - rom ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta).gba" size 8166400 crc 4F21757D md5 F3F8DE4D9497FDE3BE0A950A10BB2F5B sha1 7D59035ECD7F7DB78368DE499667B79FF4899237 ) + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (Europe) (En,Fr,De,Es,It,Nl,Sv).gba" size 8388608 crc c189013d sha1 09D945ACC251000C49539A3F18B21E48520EC8AD flags verified ) ) game ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA, Europe)" description "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA, Europe)" - rom ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA, Europe).gba" size 8388608 crc 30D6C979 md5 0BE6C13AF62A0F75651BB2ACBC397A56 sha1 F5E28F897EDB62019ADDCF3635AB89DF032186A0 flags verified ) + rom ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA, Europe).gba" size 8388608 crc 30d6c979 sha1 F5E28F897EDB62019ADDCF3635AB89DF032186A0 flags verified ) +) + +game ( + name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" + description "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" + rom ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta).gba" size 8166400 crc 4f21757d sha1 7D59035ECD7F7DB78368DE499667B79FF4899237 ) ) game ( name "SpongeBob SquarePants - SuperSponge (USA, Europe)" description "SpongeBob SquarePants - SuperSponge (USA, Europe)" - rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe).gba" size 4194304 crc 98AD67E6 md5 C2BFA5C822F33EAED02AD2F94A0414B4 sha1 B67CAAB6316A8478129F43672572277F411F211D flags verified ) + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe).gba" size 4194304 crc 98ad67e6 sha1 B67CAAB6316A8478129F43672572277F411F211D flags verified ) ) game ( name "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl)" description "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 033229A7 md5 22AB0C3096981C511A4698E16D8E067B sha1 7BD6DE4D9F93DD531A7B4ACF9BE14D38CC73BC85 ) + rom ( name "SpongeBob SquarePants and Friends - Battle for Volcano Island (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 033229a7 sha1 7BD6DE4D9F93DD531A7B4ACF9BE14D38CC73BC85 ) ) game ( name "SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,Nl)" description "SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,Nl)" - rom ( name "SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,Nl).gba" size 4194304 crc FC339FC7 md5 A27DB836275AA6F0BA559C6FCFBCDE0B sha1 68E3393496E93704A9484E544AEC87CDB81ACB04 ) + rom ( name "SpongeBob SquarePants and Friends in Freeze Frame Frenzy (Europe) (En,Fr,De,Es,Nl).gba" size 4194304 crc fc339fc7 sha1 68E3393496E93704A9484E544AEC87CDB81ACB04 ) ) game ( name "SpongeBob SquarePants and Friends Unite! (Europe) (En,Fr,De,Es,It)" description "SpongeBob SquarePants and Friends Unite! (Europe) (En,Fr,De,Es,It)" - rom ( name "SpongeBob SquarePants and Friends Unite! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 611CC620 md5 B8A651F0FC9080BF42044C93A746B5E7 sha1 0B597CE175F42E8FABB64FC278BDA50C4357EDFA ) + rom ( name "SpongeBob SquarePants and Friends Unite! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 611cc620 sha1 0B597CE175F42E8FABB64FC278BDA50C4357EDFA ) ) game ( - name "SpongeBob SquarePants Movie, The (USA) (Beta)" - description "SpongeBob SquarePants Movie, The (USA) (Beta)" - rom ( name "SpongeBob SquarePants Movie, The (USA) (Beta).gba" size 6871418 crc DF3D16A1 md5 EFFA1B8AE6A342DC47F1AD1228C78965 sha1 68C7BE5BE01DB6D428A4FE7C5B54EC58F6F793E4 ) -) - -game ( - name "SpongeBob SquarePants Movie, The (USA)" - description "SpongeBob SquarePants Movie, The (USA)" - rom ( name "SpongeBob SquarePants Movie, The (USA).gba" size 8388608 crc E1068687 md5 17DD0E3E76207E30614768482078CC3F sha1 3E7A5A0F62A7319D0EBF3D302377B08F3F4CDD8E ) + name "SpongeBob SquarePants Movie, The (USA) (Beta 2)" + description "SpongeBob SquarePants Movie, The (USA) (Beta 2)" + rom ( name "SpongeBob SquarePants Movie, The (USA) (Beta 2).gba" size 8388608 crc e1068687 sha1 3E7A5A0F62A7319D0EBF3D302377B08F3F4CDD8E ) ) game ( name "SpongeBob SquarePants Movie, The (Europe) (En,Fr,De,Es,It,Nl)" description "SpongeBob SquarePants Movie, The (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "SpongeBob SquarePants Movie, The (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 5D9D52DE md5 8EA169D37C038EA5F0CF9A1FB39554B7 sha1 08161F0F5CA8884A94E73A526AFD5A35A5DA93DE flags verified ) + rom ( name "SpongeBob SquarePants Movie, The (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 5d9d52de sha1 08161F0F5CA8884A94E73A526AFD5A35A5DA93DE flags verified ) +) + +game ( + name "SpongeBob SquarePants Movie, The (USA) (Beta 1)" + description "SpongeBob SquarePants Movie, The (USA) (Beta 1)" + rom ( name "SpongeBob SquarePants Movie, The (USA) (Beta 1).gba" size 6871418 crc df3d16a1 sha1 68C7BE5BE01DB6D428A4FE7C5B54EC58F6F793E4 ) +) + +game ( + name "SpongeBob SquarePants Movie, The (USA)" + description "SpongeBob SquarePants Movie, The (USA)" + rom ( name "SpongeBob SquarePants Movie, The (USA).gba" size 8388608 crc 3622da11 sha1 4509E7C3F2EA17D98A3CD3974D9C936713B45F67 flags verified ) ) game ( name "SpongeBob's Atlantis SquarePantis (USA)" description "SpongeBob's Atlantis SquarePantis (USA)" - rom ( name "SpongeBob's Atlantis SquarePantis (USA).gba" size 4194304 crc 190B1653 md5 6CF0014CF59609E976D4A82B01DB90BE sha1 24596F49FB46CF5E3624450F599DF670ACC72967 ) + rom ( name "SpongeBob's Atlantis SquarePantis (USA).gba" size 4194304 crc 190b1653 sha1 24596F49FB46CF5E3624450F599DF670ACC72967 ) ) game ( name "Sports Illustrated for Kids - Baseball (USA)" description "Sports Illustrated for Kids - Baseball (USA)" - rom ( name "Sports Illustrated for Kids - Baseball (USA).gba" size 4194304 crc 616088DF md5 FC40BAFF09563B7E1187BCB987BB541A sha1 A262D54F5F9FC35E7CE410B834F3BCD2AA163F10 ) + rom ( name "Sports Illustrated for Kids - Baseball (USA).gba" size 4194304 crc 616088df sha1 A262D54F5F9FC35E7CE410B834F3BCD2AA163F10 ) ) game ( name "Sports Illustrated for Kids - Football (USA)" description "Sports Illustrated for Kids - Football (USA)" - rom ( name "Sports Illustrated for Kids - Football (USA).gba" size 4194304 crc 9972779D md5 F3485ED77AFC6FC2ACB2DA935CA4D6B4 sha1 6EC5D8929961CA01BBE10208025C72A15DBBEDAB ) + rom ( name "Sports Illustrated for Kids - Football (USA).gba" size 4194304 crc 9972779d sha1 6EC5D8929961CA01BBE10208025C72A15DBBEDAB ) ) game ( - name "Sportsman's Pack (USA)" - description "Sportsman's Pack (USA)" - rom ( name "Sportsman's Pack (USA).gba" size 8388608 crc 2E725460 md5 C00051B2FF50552C66B31EBE3296031C sha1 90F0D361AA0282968E2E1320F9E6200CC3D843D3 ) -) - -game ( - name "Spy Hunter (Europe) (En,Ja,Fr,De,Es)" - description "Spy Hunter (Europe) (En,Ja,Fr,De,Es)" - rom ( name "Spy Hunter (Europe) (En,Ja,Fr,De,Es).gba" size 8388608 crc 4F196612 md5 95A6ED2862986666933B0AD73291C5DA sha1 40AFC8143490745D8724EE1436ACF0601F178D3F ) + name "Sportsmans Pack 2 in 1 - Cabela's Big Game Hunter + Rapala Pro Fishing (USA)" + description "Sportsmans Pack 2 in 1 - Cabela's Big Game Hunter + Rapala Pro Fishing (USA)" + rom ( name "Sportsmans Pack 2 in 1 - Cabela's Big Game Hunter + Rapala Pro Fishing (USA).gba" size 8388608 crc 2e725460 sha1 90F0D361AA0282968E2E1320F9E6200CC3D843D3 ) ) game ( name "Spy Hunter (USA) (En,Ja,Fr,De,Es)" description "Spy Hunter (USA) (En,Ja,Fr,De,Es)" - rom ( name "Spy Hunter (USA) (En,Ja,Fr,De,Es).gba" size 8388608 crc B04892C9 md5 5A6F98EBCA34B1D19870481DBE3E3089 sha1 0CD7527B1AC7E23F14C1EEA8B7C58D800D859B38 ) + rom ( name "Spy Hunter (USA) (En,Ja,Fr,De,Es).gba" size 8388608 crc b04892c9 sha1 0CD7527B1AC7E23F14C1EEA8B7C58D800D859B38 ) +) + +game ( + name "Spy Hunter (Europe) (En,Ja,Fr,De,Es)" + description "Spy Hunter (Europe) (En,Ja,Fr,De,Es)" + rom ( name "Spy Hunter (Europe) (En,Ja,Fr,De,Es).gba" size 8388608 crc 4f196612 sha1 40AFC8143490745D8724EE1436ACF0601F178D3F ) ) game ( name "Spy Kids 3-D - Game Over (USA)" description "Spy Kids 3-D - Game Over (USA)" - rom ( name "Spy Kids 3-D - Game Over (USA).gba" size 8388608 crc 96128B31 md5 087A7620A5C7B7F69E09FD3B97A68C2F sha1 5E722DEDDBAC98A9206278C914A16CF9CCAB7AE4 ) + rom ( name "Spy Kids 3-D - Game Over (USA).gba" size 8388608 crc 96128b31 sha1 5E722DEDDBAC98A9206278C914A16CF9CCAB7AE4 ) ) game ( name "Spy Kids 3-D - Game Over (Europe)" description "Spy Kids 3-D - Game Over (Europe)" - rom ( name "Spy Kids 3-D - Game Over (Europe).gba" size 8388608 crc A93601F5 md5 8C2A7E2605A29F88349E9A91FB773557 sha1 37DCE24E68A0BAAC5705FB370C05EBD3784E71FB flags verified ) + rom ( name "Spy Kids 3-D - Game Over (Europe).gba" size 8388608 crc a93601f5 sha1 37DCE24E68A0BAAC5705FB370C05EBD3784E71FB flags verified ) ) game ( name "Spy Kids Challenger (USA)" description "Spy Kids Challenger (USA)" - rom ( name "Spy Kids Challenger (USA).gba" size 4194304 crc E8227E41 md5 387089984F98893405B805068FEC89BD sha1 3F208388A94E14B34B95155FDB488128283D2DA3 ) + rom ( name "Spy Kids Challenger (USA).gba" size 4194304 crc e8227e41 sha1 3F208388A94E14B34B95155FDB488128283D2DA3 ) ) game ( name "Spy Muppets - License to Croak (USA) (En,Fr,De,Es,It,Nl)" description "Spy Muppets - License to Croak (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Spy Muppets - License to Croak (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 848F9D42 md5 905067B56274608B4BE2E805491B624D sha1 C6971A3E9282DF988B24E9AF4AC0D42A9B59D0C6 ) + rom ( name "Spy Muppets - License to Croak (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 848f9d42 sha1 C6971A3E9282DF988B24E9AF4AC0D42A9B59D0C6 ) ) game ( name "Spyro - Attack of the Rhynocs (USA)" description "Spyro - Attack of the Rhynocs (USA)" - rom ( name "Spyro - Attack of the Rhynocs (USA).gba" size 8388608 crc 13F10A1E md5 4A15B07B4DC292E9003C377C55372287 sha1 286FE14E15BC34E3605186876878E655EF43294C ) + rom ( name "Spyro - Attack of the Rhynocs (USA).gba" size 8388608 crc 13f10a1e sha1 286FE14E15BC34E3605186876878E655EF43294C ) ) game ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It)" description "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It)" - rom ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc AFD25827 md5 02CA69D4CA90BC8DA7CA48D59BB0035D sha1 854E788E5E1316B7D5CDF6B961D0969E5CD62119 ) + rom ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc afd25827 sha1 854E788E5E1316B7D5CDF6B961D0969E5CD62119 flags verified ) ) game ( name "Spyro - Season of Ice (USA)" description "Spyro - Season of Ice (USA)" - rom ( name "Spyro - Season of Ice (USA).gba" size 8388608 crc 2F2389D2 md5 76AAD0726BE3AC24F3C5A7A8E64379D3 sha1 A9768FA99AE74034AB19A45B30004306F1DEFF89 flags verified ) + rom ( name "Spyro - Season of Ice (USA).gba" size 8388608 crc 2f2389d2 sha1 A9768FA99AE74034AB19A45B30004306F1DEFF89 flags verified ) ) game ( name "Spyro 2 - Season of Flame (USA)" description "Spyro 2 - Season of Flame (USA)" - rom ( name "Spyro 2 - Season of Flame (USA).gba" size 8388608 crc 37E120E7 md5 8D9FBF8BDE7941CA97DCBA7757D60E81 sha1 53E77C7E4A895E0652EC2CA2C9B4A590E84ABDCA ) + rom ( name "Spyro 2 - Season of Flame (USA).gba" size 8388608 crc 37e120e7 sha1 53E77C7E4A895E0652EC2CA2C9B4A590E84ABDCA ) ) game ( name "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It)" description "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It)" - rom ( name "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 104B4CAA md5 B7236BF34D66EAD26BA5B6C1CB16C5F0 sha1 923EDAAF9CF7DBBD3C68CC4FFB171C4E308687AC ) + rom ( name "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 104b4caa sha1 923EDAAF9CF7DBBD3C68CC4FFB171C4E308687AC flags verified ) +) + +game ( + name "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It) (Beta)" + description "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It) (Beta)" + rom ( name "Spyro 2 - Season of Flame (Europe) (En,Fr,De,Es,It) (Beta).gba" size 8388608 crc d05c86bb sha1 64608522B649F54C1E7678FB54FFEB8246F0342F ) ) game ( name "Spyro Advance (Japan)" description "Spyro Advance (Japan)" - rom ( name "Spyro Advance (Japan).gba" size 8388608 crc 42DD5DD9 md5 976A59EB7378EB92ED184969CA428DB2 sha1 B6C54447B0256A6E0CA0B6D3DC6FAAE1C1DF54D7 ) + rom ( name "Spyro Advance (Japan).gba" size 8388608 crc 42dd5dd9 sha1 B6C54447B0256A6E0CA0B6D3DC6FAAE1C1DF54D7 flags verified ) ) game ( name "Spyro Advance - Wakuwaku Tomodachi Daisakusen! (Japan)" description "Spyro Advance - Wakuwaku Tomodachi Daisakusen! (Japan)" - rom ( name "Spyro Advance - Wakuwaku Tomodachi Daisakusen! (Japan).gba" size 16777216 crc 91A9E2CC md5 4A6A7498B3BE68B67C323B57FD8AC0D5 sha1 19BC078DFA9CB3C15D1042C6CFDC7FFFA4E165CE ) + rom ( name "Spyro Advance - Wakuwaku Tomodachi Daisakusen! (Japan).gba" size 16777216 crc 91a9e2cc sha1 19BC078DFA9CB3C15D1042C6CFDC7FFFA4E165CE ) ) game ( name "Spyro Adventure (Europe) (En,Fr,De,Es,It,Nl)" description "Spyro Adventure (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Spyro Adventure (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1F62D660 md5 36E7D6E276C0E4F56984A2F8491B9364 sha1 0F4AA43D6E0AD5B5007A6114F679EE0FDF77793F ) + rom ( name "Spyro Adventure (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 1f62d660 sha1 0F4AA43D6E0AD5B5007A6114F679EE0FDF77793F ) ) game ( name "Spyro Fusion (Europe) (En,Fr,De,Es,It)" description "Spyro Fusion (Europe) (En,Fr,De,Es,It)" - rom ( name "Spyro Fusion (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc E53BA082 md5 44FAF5BA9C3025AD59F53E82C8243631 sha1 AFC4A0AFF7255D74FE3D24C4146A11BD573DC12F flags verified ) + rom ( name "Spyro Fusion (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc e53ba082 sha1 AFC4A0AFF7255D74FE3D24C4146A11BD573DC12F flags verified ) ) game ( name "Spyro Orange - The Cortex Conspiracy (USA)" description "Spyro Orange - The Cortex Conspiracy (USA)" - rom ( name "Spyro Orange - The Cortex Conspiracy (USA).gba" size 16777216 crc A9915BAF md5 6A496546576101291A97A93846F0D9DD sha1 E76783D027FB1CD6426BFE3D482C595B585E32AE ) + rom ( name "Spyro Orange - The Cortex Conspiracy (USA).gba" size 16777216 crc a9915baf sha1 E76783D027FB1CD6426BFE3D482C595B585E32AE flags verified ) ) game ( name "Spyro Orange - The Cortex Conspiracy (USA) (Rev 1)" description "Spyro Orange - The Cortex Conspiracy (USA) (Rev 1)" - rom ( name "Spyro Orange - The Cortex Conspiracy (USA) (Rev 1).gba" size 16777216 crc BBF2549D md5 0CB99D064F970B580A8F0C1B87BD643B sha1 EED93EBE63A99DE8490D05AE1BC122DBFE5F8596 ) + rom ( name "Spyro Orange - The Cortex Conspiracy (USA) (Rev 1).gba" size 16777216 crc bbf2549d sha1 EED93EBE63A99DE8490D05AE1BC122DBFE5F8596 flags verified ) ) game ( - name "Spyro Superpack (USA)" - description "Spyro Superpack (USA)" - rom ( name "Spyro Superpack (USA).gba" size 16777216 crc 7EF359ED md5 B517B393437FAA7B1DFB65BA5DCA7BAF sha1 32BD09927E3B7446A9B1B964A363ED5EA17A57FC ) + name "Spyro Superpack - Spyro - Season of Ice + Spyro 2 - Season of Flame (USA)" + description "Spyro Superpack - Spyro - Season of Ice + Spyro 2 - Season of Flame (USA)" + rom ( name "Spyro Superpack - Spyro - Season of Ice + Spyro 2 - Season of Flame (USA).gba" size 16777216 crc 7ef359ed sha1 32BD09927E3B7446A9B1B964A363ED5EA17A57FC ) ) game ( name "SSX 3 (USA, Europe)" description "SSX 3 (USA, Europe)" - rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232F58A md5 D0D33104D62F81108214F9A328CE0A9E sha1 4F2BD55BCD3118E10520179E285AAE897AA21898 flags verified ) + rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232f58a sha1 4F2BD55BCD3118E10520179E285AAE897AA21898 flags verified ) ) game ( name "SSX Tricky (USA, Europe) (En,Fr,De)" description "SSX Tricky (USA, Europe) (En,Fr,De)" - rom ( name "SSX Tricky (USA, Europe) (En,Fr,De).gba" size 8388608 crc E0988123 md5 512DACE284790F3A5CA14838459DF5A6 sha1 E7A07A86B09514F76213AFC4AA2F416475A1E2F8 flags verified ) + rom ( name "SSX Tricky (USA, Europe) (En,Fr,De).gba" size 8388608 crc e0988123 sha1 E7A07A86B09514F76213AFC4AA2F416475A1E2F8 flags verified ) ) game ( name "Stadium Games (Europe)" description "Stadium Games (Europe)" - rom ( name "Stadium Games (Europe).gba" size 4194304 crc DB146CC3 md5 9A8A6131E217CB00B270648EE1697A55 sha1 7B95503131390683E179CD7740DE244B9B3A9D6D ) + rom ( name "Stadium Games (Europe).gba" size 4194304 crc db146cc3 sha1 7B95503131390683E179CD7740DE244B9B3A9D6D ) ) game ( name "Stadium Games (USA)" description "Stadium Games (USA)" - rom ( name "Stadium Games (USA).gba" size 4194304 crc 4BF6E9E8 md5 47E02AC1A4CC0D5F7441426469015DD7 sha1 71CB60817329AE94023FB1DCD5E70D379A4D3344 ) + rom ( name "Stadium Games (USA).gba" size 4194304 crc 4bf6e9e8 sha1 71CB60817329AE94023FB1DCD5E70D379A4D3344 ) ) game ( name "Star Wars - Episode II - Attack of the Clones (USA)" description "Star Wars - Episode II - Attack of the Clones (USA)" - rom ( name "Star Wars - Episode II - Attack of the Clones (USA).gba" size 8388608 crc 8FB5E2C6 md5 F0D3E68E554E44D1DF20A16359F13F5F sha1 F02F2A1246D593582436EEBA4090F4048671079A ) + rom ( name "Star Wars - Episode II - Attack of the Clones (USA).gba" size 8388608 crc 8fb5e2c6 sha1 F02F2A1246D593582436EEBA4090F4048671079A ) ) game ( name "Star Wars - Episode II - Attack of the Clones (Europe) (En,Fr,De,Es,It)" description "Star Wars - Episode II - Attack of the Clones (Europe) (En,Fr,De,Es,It)" - rom ( name "Star Wars - Episode II - Attack of the Clones (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc C492C46D md5 61AA3EABB062688C15CE723546DFC0E8 sha1 469D32D6F0EC58F71CDF120BC85B9F18C04FD396 ) + rom ( name "Star Wars - Episode II - Attack of the Clones (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc c492c46d sha1 469D32D6F0EC58F71CDF120BC85B9F18C04FD396 ) ) game ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl)" description "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc FD49236B md5 8942D8C65E680853E1407108857BB732 sha1 4BA5E5A6174BAD9369F088F801C743F88616C5F4 ) + rom ( name "Star Wars - Episode III - Revenge of the Sith (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc fd49236b sha1 4BA5E5A6174BAD9369F088F801C743F88616C5F4 ) ) game ( name "Star Wars - Episode III - Revenge of the Sith (USA) (En,Fr,Es)" description "Star Wars - Episode III - Revenge of the Sith (USA) (En,Fr,Es)" - rom ( name "Star Wars - Episode III - Revenge of the Sith (USA) (En,Fr,Es).gba" size 8388608 crc 3E34AAB7 md5 6C44B49D69E6C0576197742F20250C40 sha1 146A5AE97832131D41698C182CE58176B7BB848F ) + rom ( name "Star Wars - Episode III - Revenge of the Sith (USA) (En,Fr,Es).gba" size 8388608 crc 3e34aab7 sha1 146A5AE97832131D41698C182CE58176B7BB848F ) ) game ( name "Star Wars - Flight of the Falcon (USA)" description "Star Wars - Flight of the Falcon (USA)" - rom ( name "Star Wars - Flight of the Falcon (USA).gba" size 8388608 crc 94D2737A md5 A6CC5B4377DC7396FA275113E1B958B4 sha1 4CE7C96146456B10DB85D7BF4A6B0F588EA370B9 ) + rom ( name "Star Wars - Flight of the Falcon (USA).gba" size 8388608 crc 94d2737a sha1 4CE7C96146456B10DB85D7BF4A6B0F588EA370B9 ) ) game ( name "Star Wars - Flight of the Falcon (Europe) (En,Fr,De)" description "Star Wars - Flight of the Falcon (Europe) (En,Fr,De)" - rom ( name "Star Wars - Flight of the Falcon (Europe) (En,Fr,De).gba" size 8388608 crc A41D22AD md5 20170A5739AFF291FA8ADC67B682AB15 sha1 88298B1E1FFEA42579D75EEB7074107362C08E5E ) + rom ( name "Star Wars - Flight of the Falcon (Europe) (En,Fr,De).gba" size 8388608 crc a41d22ad sha1 88298B1E1FFEA42579D75EEB7074107362C08E5E ) ) game ( name "Star Wars - Jedi Power Battles (USA)" description "Star Wars - Jedi Power Battles (USA)" - rom ( name "Star Wars - Jedi Power Battles (USA).gba" size 8388608 crc 3F19E156 md5 2D2A6725DA37285D65C34205D08754D7 sha1 5D5DBFC9C0ED1F89629114429C93EF1B2E1165E5 ) + rom ( name "Star Wars - Jedi Power Battles (USA).gba" size 8388608 crc 3f19e156 sha1 5D5DBFC9C0ED1F89629114429C93EF1B2E1165E5 ) ) game ( name "Star Wars - Jedi Power Battles (Europe) (En,Fr,De,Es)" description "Star Wars - Jedi Power Battles (Europe) (En,Fr,De,Es)" - rom ( name "Star Wars - Jedi Power Battles (Europe) (En,Fr,De,Es).gba" size 8388608 crc FA0F055D md5 4DBF397FFDAD3CF7E2B23CDADEC02539 sha1 9C61DDFF8E0F31268244636E412FAAA7FB73E8B0 ) + rom ( name "Star Wars - Jedi Power Battles (Europe) (En,Fr,De,Es).gba" size 8388608 crc fa0f055d sha1 9C61DDFF8E0F31268244636E412FAAA7FB73E8B0 ) ) game ( name "Star Wars - The New Droid Army (USA)" description "Star Wars - The New Droid Army (USA)" - rom ( name "Star Wars - The New Droid Army (USA).gba" size 8388608 crc 59C52F98 md5 E3D1F21B756890E2A68424173AA8CEE5 sha1 7770E5CAAC078460EBAEEADDBD183C2973365C47 ) + rom ( name "Star Wars - The New Droid Army (USA).gba" size 8388608 crc 59c52f98 sha1 7770E5CAAC078460EBAEEADDBD183C2973365C47 ) ) game ( name "Star Wars - The New Droid Army (Europe) (En,Fr,De,Es)" description "Star Wars - The New Droid Army (Europe) (En,Fr,De,Es)" - rom ( name "Star Wars - The New Droid Army (Europe) (En,Fr,De,Es).gba" size 8388608 crc 677854AF md5 B7112785DAA196847E610783CC2E9D8A sha1 4966CE40938DF2B0FFD262C6AA6C4461B9FA8922 ) + rom ( name "Star Wars - The New Droid Army (Europe) (En,Fr,De,Es).gba" size 8388608 crc 677854af sha1 4966CE40938DF2B0FFD262C6AA6C4461B9FA8922 flags verified ) ) game ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl)" description "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc C9F0C492 md5 D02B4E547E916A20BC7CEBCB41CBA8AB sha1 51FFD3684D9BD8140D8C7969D7EB2096DD2424A5 ) + rom ( name "Star Wars Trilogy - Apprentice of the Force (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc c9f0c492 sha1 51FFD3684D9BD8140D8C7969D7EB2096DD2424A5 flags verified ) ) game ( name "Star Wars Trilogy - Apprentice of the Force (USA) (En,Fr,Es)" description "Star Wars Trilogy - Apprentice of the Force (USA) (En,Fr,Es)" - rom ( name "Star Wars Trilogy - Apprentice of the Force (USA) (En,Fr,Es).gba" size 8388608 crc 714A0D3A md5 6B423FD7F0B4CC280A6208F66671A9C1 sha1 B6C09B9F5588FF81AEB4BD5ED886933993F4575F ) + rom ( name "Star Wars Trilogy - Apprentice of the Force (USA) (En,Fr,Es).gba" size 8388608 crc 714a0d3a sha1 B6C09B9F5588FF81AEB4BD5ED886933993F4575F ) ) game ( name "Star X (USA) (En,Fr,De,Es,It,Nl)" description "Star X (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Star X (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 8B02B2B1 md5 2C18D1FA4D943439CA17CEEF984EA7D4 sha1 EDAC3E0A09DD6A501C923A6B01017B48B1CBE7EE ) + rom ( name "Star X (USA) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 8b02b2b1 sha1 EDAC3E0A09DD6A501C923A6B01017B48B1CBE7EE ) ) game ( name "Star X (Europe) (En,Fr,De,Es,It,Nl)" description "Star X (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Star X (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 9DCA9C3C md5 49DAC3774E92DC924BD4FCEE69F3F7E1 sha1 038169C4B3A5254067701B5EBE43D8A3A005F6B6 flags verified ) -) - -game ( - name "Starsky & Hutch (USA) (Beta)" - description "Starsky & Hutch (USA) (Beta)" - rom ( name "Starsky & Hutch (USA) (Beta).gba" size 4231928 crc AB142D2E md5 177CBECF21922A3D5F19D160816C31C2 sha1 861066DDF8B52BE194B30CBB70E959989F0A2F76 ) + rom ( name "Star X (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 9dca9c3c sha1 038169C4B3A5254067701B5EBE43D8A3A005F6B6 flags verified ) ) game ( name "Starsky & Hutch (Europe) (En,Fr,De,Es,It)" description "Starsky & Hutch (Europe) (En,Fr,De,Es,It)" - rom ( name "Starsky & Hutch (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 209958E5 md5 47CDD40B09021B6A7283E37B94185979 sha1 C36BFB2C0D5050BE17CB66210ADDE3851D80E878 flags verified ) + rom ( name "Starsky & Hutch (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 209958e5 sha1 C36BFB2C0D5050BE17CB66210ADDE3851D80E878 flags verified ) ) game ( name "Starsky & Hutch (USA)" description "Starsky & Hutch (USA)" - rom ( name "Starsky & Hutch (USA).gba" size 4194304 crc B3993252 md5 7642F18E0D52AAA52245D20692827DE9 sha1 6704673F62034B2599CEC9EF3520A52E68EB8FBA flags verified ) + rom ( name "Starsky & Hutch (USA).gba" size 4194304 crc b3993252 sha1 6704673F62034B2599CEC9EF3520A52E68EB8FBA flags verified ) +) + +game ( + name "Starsky & Hutch (USA) (Beta)" + description "Starsky & Hutch (USA) (Beta)" + rom ( name "Starsky & Hutch (USA) (Beta).gba" size 4231928 crc ab142d2e sha1 861066DDF8B52BE194B30CBB70E959989F0A2F76 ) ) game ( name "Steel Empire (Europe)" description "Steel Empire (Europe)" - rom ( name "Steel Empire (Europe).gba" size 4194304 crc CB91922E md5 F39B607DC13C4D8C4353B7981F5F6CB6 sha1 B280937636A533020BF42591CC246B221A16F94E ) + rom ( name "Steel Empire (Europe).gba" size 4194304 crc cb91922e sha1 B280937636A533020BF42591CC246B221A16F94E ) ) game ( name "Steven Gerrard's Total Soccer 2002 (Europe) (En,Fr,De,Es,It,Nl)" description "Steven Gerrard's Total Soccer 2002 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Steven Gerrard's Total Soccer 2002 (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc B94DDC93 md5 52C07DA7DB84B23B687CAC98499A95A4 sha1 1F37ABE2A70FF0027ABE714CB4CD93F168925753 flags verified ) + rom ( name "Steven Gerrard's Total Soccer 2002 (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc b94ddc93 sha1 1F37ABE2A70FF0027ABE714CB4CD93F168925753 flags verified ) ) game ( name "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" description "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da)" - rom ( name "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc C40220CF md5 FB1E889CF258CD014FBB08E5F8554A35 sha1 ABF63B6DEE8368B06B3E6DBEE5844314F1F292F3 ) + rom ( name "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da).gba" size 8388608 crc c40220cf sha1 ABF63B6DEE8368B06B3E6DBEE5844314F1F292F3 ) +) + +game ( + name "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da) (Rev 1)" + description "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da) (Rev 1)" + rom ( name "Strawberry Shortcake - Ice Cream Island - Riding Camp (Europe) (En,Fr,De,Es,It,Nl,Pt,Da) (Rev 1).gba" size 8388608 crc f3f2e465 sha1 DBCE7927E477FEAFA0D624B91EBED490A786BF08 flags verified ) ) game ( name "Strawberry Shortcake - Summertime Adventure (USA)" description "Strawberry Shortcake - Summertime Adventure (USA)" - rom ( name "Strawberry Shortcake - Summertime Adventure (USA).gba" size 4194304 crc 7FEC3419 md5 71C5D8E089D0C1B15B4E376515BD4F18 sha1 6DDB65DD3B80ACF4F24A6AE2568DFA6C8DA6B007 ) + rom ( name "Strawberry Shortcake - Summertime Adventure (USA).gba" size 4194304 crc 7fec3419 sha1 6DDB65DD3B80ACF4F24A6AE2568DFA6C8DA6B007 ) ) game ( name "Strawberry Shortcake - Summertime Adventure - Special Edition (USA)" description "Strawberry Shortcake - Summertime Adventure - Special Edition (USA)" - rom ( name "Strawberry Shortcake - Summertime Adventure - Special Edition (USA).gba" size 16777216 crc 5A66CAFA md5 8DC907977F47486569F863F99B81F567 sha1 2CC31F8899D933A12D27CB6F52C0DD90C06DB27E ) + rom ( name "Strawberry Shortcake - Summertime Adventure - Special Edition (USA).gba" size 16777216 crc 5a66cafa sha1 2CC31F8899D933A12D27CB6F52C0DD90C06DB27E ) ) game ( name "Strawberry Shortcake - Sweet Dreams (USA)" description "Strawberry Shortcake - Sweet Dreams (USA)" - rom ( name "Strawberry Shortcake - Sweet Dreams (USA).gba" size 4194304 crc 53384966 md5 6889044339203F0BEC9F20C478772079 sha1 77210297D7D2890E0D2C34B5A8AA933857486B57 ) + rom ( name "Strawberry Shortcake - Sweet Dreams (USA).gba" size 4194304 crc 53384966 sha1 77210297D7D2890E0D2C34B5A8AA933857486B57 ) ) game ( name "Street Fighter Alpha 3 (Europe)" description "Street Fighter Alpha 3 (Europe)" - rom ( name "Street Fighter Alpha 3 (Europe).gba" size 8388608 crc 93C5CF69 md5 901D68257B8BEDA85240D55725529FE2 sha1 335C216BEC0FF27BCCDADB4E97C623485EA5902A flags verified ) + rom ( name "Street Fighter Alpha 3 (Europe).gba" size 8388608 crc 93c5cf69 sha1 335C216BEC0FF27BCCDADB4E97C623485EA5902A flags verified ) ) game ( name "Street Fighter Alpha 3 (USA)" description "Street Fighter Alpha 3 (USA)" - rom ( name "Street Fighter Alpha 3 (USA).gba" size 8388608 crc 80B707C2 md5 91D5986BCB918E636F17E99EB73B923B sha1 7FD4258BCD2BF639E1EC98B7A7EC7218FCF5859E flags verified ) + rom ( name "Street Fighter Alpha 3 (USA).gba" size 8388608 crc 80b707c2 sha1 7FD4258BCD2BF639E1EC98B7A7EC7218FCF5859E flags verified ) ) game ( name "Street Fighter Zero 3 Upper (Japan)" description "Street Fighter Zero 3 Upper (Japan)" - rom ( name "Street Fighter Zero 3 Upper (Japan).gba" size 8388608 crc 8D5D0EAB md5 929F06F714454B66CEC42585462DB598 sha1 5E8233351ED25A6879F5FF7596B29B45DCA24C12 ) + rom ( name "Street Fighter Zero 3 Upper (Japan).gba" size 8388608 crc 8d5d0eab sha1 5E8233351ED25A6879F5FF7596B29B45DCA24C12 ) ) game ( name "Street Jam Basketball (USA, Europe)" description "Street Jam Basketball (USA, Europe)" - rom ( name "Street Jam Basketball (USA, Europe).gba" size 4194304 crc 3F20A970 md5 482E89458D0154EC7231E98C61378C0A sha1 7716D661CC8027F2A59C53DBF301365B82E86624 flags verified ) + rom ( name "Street Jam Basketball (USA, Europe).gba" size 4194304 crc 3f20a970 sha1 7716D661CC8027F2A59C53DBF301365B82E86624 flags verified ) ) game ( name "Street Racing Syndicate (USA)" description "Street Racing Syndicate (USA)" - rom ( name "Street Racing Syndicate (USA).gba" size 4194304 crc F44B6A70 md5 3EDF62C20E5C70401C3FA78EF6489055 sha1 4981BE37D8CD402DE5A80F17F754C207BD5CFEA8 ) + rom ( name "Street Racing Syndicate (USA).gba" size 4194304 crc f44b6a70 sha1 4981BE37D8CD402DE5A80F17F754C207BD5CFEA8 ) ) game ( name "Street Racing Syndicate (Europe) (En,Fr,De,Es,It)" description "Street Racing Syndicate (Europe) (En,Fr,De,Es,It)" - rom ( name "Street Racing Syndicate (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc AC24888B md5 9B8016741DAD6774241CCC78571DF4DA sha1 0536C9D6B0732337EAA6764D918F3B314B96C063 ) -) - -game ( - name "Strike Force Hydra (USA)" - description "Strike Force Hydra (USA)" - rom ( name "Strike Force Hydra (USA).gba" size 4194304 crc 5AEEA1DE md5 531B1F6688E0C646B23F78D4019DD42E sha1 39FCDD20CB253D9A0292208902994381A3BA7C27 ) + rom ( name "Street Racing Syndicate (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc ac24888b sha1 0536C9D6B0732337EAA6764D918F3B314B96C063 ) ) game ( name "Strike Force Hydra (Europe)" description "Strike Force Hydra (Europe)" - rom ( name "Strike Force Hydra (Europe).gba" size 4194304 crc 277D2C89 md5 468FBA45DBD02710705E3FDBDDB3A6DF sha1 4203315BE9E7CE1801CDDF294CD18E98C9C9E8B0 ) + rom ( name "Strike Force Hydra (Europe).gba" size 4194304 crc 277d2c89 sha1 4203315BE9E7CE1801CDDF294CD18E98C9C9E8B0 ) +) + +game ( + name "Strike Force Hydra (USA)" + description "Strike Force Hydra (USA)" + rom ( name "Strike Force Hydra (USA).gba" size 4194304 crc 5aeea1de sha1 39FCDD20CB253D9A0292208902994381A3BA7C27 ) ) game ( name "Stuart Little 2 (USA, Europe)" description "Stuart Little 2 (USA, Europe)" - rom ( name "Stuart Little 2 (USA, Europe).gba" size 8388608 crc 6EB7C688 md5 2170CE3D59A6F69D6D5B002088BEED7C sha1 FDB6D8098340966456CD05C7BABE77B5A204608C flags verified ) + rom ( name "Stuart Little 2 (USA, Europe).gba" size 8388608 crc 6eb7c688 sha1 FDB6D8098340966456CD05C7BABE77B5A204608C flags verified ) ) game ( name "Stuart Little 2 (France)" description "Stuart Little 2 (France)" - rom ( name "Stuart Little 2 (France).gba" size 8388608 crc 0827D896 md5 0269F1346CFA7942F43039E12AC5F26C sha1 59AB956EF920BDF2A75B36448F557DF8538D558A ) + rom ( name "Stuart Little 2 (France).gba" size 8388608 crc 0827d896 sha1 59AB956EF920BDF2A75B36448F557DF8538D558A ) ) game ( name "Stuntman (Europe) (En,Fr,De,Es,It)" description "Stuntman (Europe) (En,Fr,De,Es,It)" - rom ( name "Stuntman (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 62A678AB md5 DFD7387E205C01A4F044E3A1D4AAEA68 sha1 FB61638E964A02E3DBDA9F4C1B3BBE7B195BBA9C flags verified ) + rom ( name "Stuntman (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 62a678ab sha1 FB61638E964A02E3DBDA9F4C1B3BBE7B195BBA9C flags verified ) ) game ( name "Stuntman (USA) (En,Fr,Es)" description "Stuntman (USA) (En,Fr,Es)" - rom ( name "Stuntman (USA) (En,Fr,Es).gba" size 4194304 crc 0D58BA07 md5 870AAEDB84A214FA52B167A37C94B591 sha1 B9F5FDC3BC755490439440FFCD95E53B3F9F6C06 ) + rom ( name "Stuntman (USA) (En,Fr,Es).gba" size 4194304 crc 0d58ba07 sha1 B9F5FDC3BC755490439440FFCD95E53B3F9F6C06 ) ) game ( name "Sugar Sugar Rune - Heart Ga Ippai! Moegi Gakuen (Japan)" description "Sugar Sugar Rune - Heart Ga Ippai! Moegi Gakuen (Japan)" - rom ( name "Sugar Sugar Rune - Heart Ga Ippai! Moegi Gakuen (Japan).gba" size 8388608 crc 0A4E0ED2 md5 7FC2AFF8E9663F1613336CA662F5A112 sha1 D98F17F4D276E179A057326507636DA1D5BE93F4 ) + rom ( name "Sugar Sugar Rune - Heart Ga Ippai! Moegi Gakuen (Japan).gba" size 8388608 crc 0a4e0ed2 sha1 D98F17F4D276E179A057326507636DA1D5BE93F4 ) ) game ( name "Suite Life of Zack & Cody, The - Tipton Caper (USA) (En,Fr)" description "Suite Life of Zack & Cody, The - Tipton Caper (USA) (En,Fr)" - rom ( name "Suite Life of Zack & Cody, The - Tipton Caper (USA) (En,Fr).gba" size 8388608 crc 1D33DD2C md5 37811411C46CF9A5EE91B418C6E67930 sha1 13BD8F4FA4C08B8F1B9D400D0917C0E62CF666FD ) + rom ( name "Suite Life of Zack & Cody, The - Tipton Caper (USA) (En,Fr).gba" size 8388608 crc 1d33dd2c sha1 13BD8F4FA4C08B8F1B9D400D0917C0E62CF666FD ) ) game ( name "Sum of All Fears, The (Europe) (En,Fr,De,Es,It)" description "Sum of All Fears, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Sum of All Fears, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc AEA15C21 md5 55EED735151B69EF84E673EF8DC42AAB sha1 062D29417972DA4279E8E9069631F5B9F6C0E612 flags verified ) + rom ( name "Sum of All Fears, The (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc aea15c21 sha1 062D29417972DA4279E8E9069631F5B9F6C0E612 flags verified ) ) game ( name "Sum of All Fears, The (USA) (En,Fr,De,Es,It)" description "Sum of All Fears, The (USA) (En,Fr,De,Es,It)" - rom ( name "Sum of All Fears, The (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 166391D1 md5 E2970509F5671DD267F1C5C5902710E3 sha1 364B880A0457CEC827929247B4885D0351FA2982 flags verified ) + rom ( name "Sum of All Fears, The (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 166391d1 sha1 364B880A0457CEC827929247B4885D0351FA2982 flags verified ) ) game ( name "Summon Night - Craft Sword Monogatari (Japan)" description "Summon Night - Craft Sword Monogatari (Japan)" - rom ( name "Summon Night - Craft Sword Monogatari (Japan).gba" size 8388608 crc A5D38236 md5 54F4EE802DF00B77617ED7E2E75C27C6 sha1 B137E310696BE2A148E6201320FCDA3551F32E8A ) + rom ( name "Summon Night - Craft Sword Monogatari (Japan).gba" size 8388608 crc a5d38236 sha1 B137E310696BE2A148E6201320FCDA3551F32E8A ) ) game ( name "Summon Night - Craft Sword Monogatari - Hajimari no Ishi (Japan)" description "Summon Night - Craft Sword Monogatari - Hajimari no Ishi (Japan)" - rom ( name "Summon Night - Craft Sword Monogatari - Hajimari no Ishi (Japan).gba" size 33554432 crc 12AFAE5D md5 6D676A8CB2D528A647E62110653418A8 sha1 3F5253FCF57E07CE52472BD29A61D16B98A12376 ) + rom ( name "Summon Night - Craft Sword Monogatari - Hajimari no Ishi (Japan).gba" size 33554432 crc 12afae5d sha1 3F5253FCF57E07CE52472BD29A61D16B98A12376 ) ) game ( name "Summon Night - Craft Sword Monogatari 2 (Japan)" description "Summon Night - Craft Sword Monogatari 2 (Japan)" - rom ( name "Summon Night - Craft Sword Monogatari 2 (Japan).gba" size 16777216 crc 8CD98F6F md5 BB4423037D0DC62B5282E1D3ECE2B592 sha1 738C64FEC6ECF9BCCB91500641FBB8BA37E865DA ) + rom ( name "Summon Night - Craft Sword Monogatari 2 (Japan).gba" size 16777216 crc 8cd98f6f sha1 738C64FEC6ECF9BCCB91500641FBB8BA37E865DA ) ) game ( name "Summon Night - Swordcraft Story (USA)" description "Summon Night - Swordcraft Story (USA)" - rom ( name "Summon Night - Swordcraft Story (USA).gba" size 8388608 crc 3EA860C2 md5 ABFA372F860D0F10037BF28CC78DE409 sha1 3FA7E703D48E070D9C762C2404E91A566A50166E ) + rom ( name "Summon Night - Swordcraft Story (USA).gba" size 8388608 crc 3ea860c2 sha1 3FA7E703D48E070D9C762C2404E91A566A50166E flags verified ) ) game ( name "Summon Night - Swordcraft Story 2 (USA)" description "Summon Night - Swordcraft Story 2 (USA)" - rom ( name "Summon Night - Swordcraft Story 2 (USA).gba" size 16777216 crc 1EAC1F48 md5 03EEA2D57DE9C16B5F10055E8E4E2893 sha1 CBC4382B1FFF2E1B2D3112AE8FBF290AEC662121 ) + rom ( name "Summon Night - Swordcraft Story 2 (USA).gba" size 16777216 crc 1eac1f48 sha1 CBC4382B1FFF2E1B2D3112AE8FBF290AEC662121 flags verified ) ) game ( name "Super Army War (USA)" description "Super Army War (USA)" - rom ( name "Super Army War (USA).gba" size 4194304 crc BAF484BE md5 1B93EF2E096D7EB72E76B8662A3E74EC sha1 2840446005BAA66E8B224F756D07CAA7DE25A5DC ) + rom ( name "Super Army War (USA).gba" size 4194304 crc baf484be sha1 2840446005BAA66E8B224F756D07CAA7DE25A5DC ) ) game ( name "Super Black Bass Advance (Japan)" description "Super Black Bass Advance (Japan)" - rom ( name "Super Black Bass Advance (Japan).gba" size 4194304 crc 67C4E470 md5 624A73D3CB69E50C0A1CC9DE726083EC sha1 2D71D6D29729AC5D3302F1D14E2E774AFE7A06A8 ) + rom ( name "Super Black Bass Advance (Japan).gba" size 4194304 crc 67c4e470 sha1 2D71D6D29729AC5D3302F1D14E2E774AFE7A06A8 ) ) game ( name "Super Black Bass Advance (Europe)" description "Super Black Bass Advance (Europe)" - rom ( name "Super Black Bass Advance (Europe).gba" size 4194304 crc 91238AD1 md5 FE1BD7D414D0A710EF17D38CEC1A76CC sha1 F29FA04BCD4C1A2BFD466D6046AC6EB86071B2FC ) + rom ( name "Super Black Bass Advance (Europe).gba" size 4194304 crc 91238ad1 sha1 F29FA04BCD4C1A2BFD466D6046AC6EB86071B2FC ) ) game ( name "Super Bubble Pop (USA)" description "Super Bubble Pop (USA)" - rom ( name "Super Bubble Pop (USA).gba" size 4194304 crc 5EC8EA61 md5 89C947C27346212A2FF412B5D46A51AF sha1 0D6D267229FDB4A9877FB5A7E768BD27254C4140 ) + rom ( name "Super Bubble Pop (USA).gba" size 4194304 crc 5ec8ea61 sha1 0D6D267229FDB4A9877FB5A7E768BD27254C4140 ) ) game ( name "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" description "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" - rom ( name "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gba" size 4194304 crc 25123D97 md5 1FB0B1A3DF41397795ACF99D8AADA8D6 sha1 F62396B5502437651D26E1AD27A8EC8C18B4268E ) + rom ( name "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gba" size 4194304 crc 25123d97 sha1 F62396B5502437651D26E1AD27A8EC8C18B4268E ) ) game ( name "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" description "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" - rom ( name "Super Bust-A-Move (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6BFD2915 md5 063F1A5C5DC09CE899C983DB8CC28C01 sha1 E4DD4BB3691444FFF595A926B2C06313F2E69751 ) + rom ( name "Super Bust-A-Move (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 6bfd2915 sha1 E4DD4BB3691444FFF595A926B2C06313F2E69751 flags verified ) ) game ( name "Super Bust-A-Move (USA) (En,Fr,Es)" description "Super Bust-A-Move (USA) (En,Fr,Es)" - rom ( name "Super Bust-A-Move (USA) (En,Fr,Es).gba" size 4194304 crc 2FB4B14D md5 00B3169C025D8000F8944E2E8B81C2B5 sha1 BF8F61B61E1A8F4A32AE27D4483A44FDD08477FB ) + rom ( name "Super Bust-A-Move (USA) (En,Fr,Es).gba" size 4194304 crc 2fb4b14d sha1 BF8F61B61E1A8F4A32AE27D4483A44FDD08477FB ) ) game ( name "Super Chinese 1, 2 Advance (Japan)" description "Super Chinese 1, 2 Advance (Japan)" - rom ( name "Super Chinese 1, 2 Advance (Japan).gba" size 4194304 crc 35448DF4 md5 8A0E456A01130C8F4B800A0376681782 sha1 933B1EA387ED73B5F18DA7B2353B4BCC1A8C4E9E ) + rom ( name "Super Chinese 1, 2 Advance (Japan).gba" size 4194304 crc 35448df4 sha1 933B1EA387ED73B5F18DA7B2353B4BCC1A8C4E9E ) ) game ( name "Super Collapse! II (USA)" description "Super Collapse! II (USA)" - rom ( name "Super Collapse! II (USA).gba" size 4194304 crc F4634DBD md5 4529B2BFB0B9A2303C45BFC7F15F466E sha1 72B62B363D04A363908D5428549E84F37DB6C397 ) -) - -game ( - name "Super Dodge Ball Advance (USA) (Beta)" - description "Super Dodge Ball Advance (USA) (Beta)" - rom ( name "Super Dodge Ball Advance (USA) (Beta).gba" size 4194304 crc 626603B5 md5 2221038E601E260C39B5B5937064D4E4 sha1 66405CB265A5DF8EA33B3C1E287B9B1098E90FBD ) + rom ( name "Super Collapse! II (USA).gba" size 4194304 crc f4634dbd sha1 72B62B363D04A363908D5428549E84F37DB6C397 ) ) game ( name "Super Dodge Ball Advance (USA)" description "Super Dodge Ball Advance (USA)" - rom ( name "Super Dodge Ball Advance (USA).gba" size 4194304 crc 1D31DC6B md5 816DB888CAE935E71A74A4AE6C461BEE sha1 5FC95814EA7695D1301DF4B545614A1FFAE95218 ) + rom ( name "Super Dodge Ball Advance (USA).gba" size 4194304 crc 1d31dc6b sha1 5FC95814EA7695D1301DF4B545614A1FFAE95218 ) ) game ( name "Super Dodge Ball Advance (Europe)" description "Super Dodge Ball Advance (Europe)" - rom ( name "Super Dodge Ball Advance (Europe).gba" size 4194304 crc 4CA4F528 md5 B4863030186E7E1DA0A6009DADA06CD5 sha1 A0AC6BE19F385EEF6BC48BCA8D54520D4E8A00E7 ) + rom ( name "Super Dodge Ball Advance (Europe).gba" size 4194304 crc 4ca4f528 sha1 A0AC6BE19F385EEF6BC48BCA8D54520D4E8A00E7 ) +) + +game ( + name "Super Dodge Ball Advance (USA) (Beta)" + description "Super Dodge Ball Advance (USA) (Beta)" + rom ( name "Super Dodge Ball Advance (USA) (Beta).gba" size 4194304 crc 626603b5 sha1 66405CB265A5DF8EA33B3C1E287B9B1098E90FBD ) +) + +game ( + name "Super Dodge Ball Advance (USA) (Rev 1)" + description "Super Dodge Ball Advance (USA) (Rev 1)" + rom ( name "Super Dodge Ball Advance (USA) (Rev 1).gba" size 4194304 crc 63ca5050 sha1 29561789FCB3BCD106A5D27DEA47F29B393191F6 flags verified ) ) game ( name "Super Donkey Kong (Japan)" description "Super Donkey Kong (Japan)" - rom ( name "Super Donkey Kong (Japan).gba" size 8388608 crc 2206B04D md5 67B7E6FAB2A954ABA194BE3C60AEACEE sha1 FCA4288A99046DFD7DD193EE9F4F8114E3758FCD ) + rom ( name "Super Donkey Kong (Japan).gba" size 8388608 crc 2206b04d sha1 FCA4288A99046DFD7DD193EE9F4F8114E3758FCD flags verified ) ) game ( name "Super Donkey Kong 2 (Japan)" description "Super Donkey Kong 2 (Japan)" - rom ( name "Super Donkey Kong 2 (Japan).gba" size 8388608 crc 27A1CC75 md5 EC9FDBF2EC32B7D5AF4FBEBE9AA60A56 sha1 CD2A45C2AF945D5861684060F087DB44024DFE59 ) + rom ( name "Super Donkey Kong 2 (Japan).gba" size 8388608 crc 27a1cc75 sha1 CD2A45C2AF945D5861684060F087DB44024DFE59 ) ) game ( name "Super Donkey Kong 3 (Japan)" description "Super Donkey Kong 3 (Japan)" - rom ( name "Super Donkey Kong 3 (Japan).gba" size 16777216 crc 4DCF6E20 md5 69CE1ADB9A8BE5C49CA2044C97FA24CB sha1 4657C3070BD7AD8CE89F0491FC0F19A4F14ADA88 flags verified ) + rom ( name "Super Donkey Kong 3 (Japan).gba" size 16777216 crc 4dcf6e20 sha1 4657C3070BD7AD8CE89F0491FC0F19A4F14ADA88 flags verified ) ) game ( name "Super Dropzone - Intergalactic Rescue Mission (Europe)" description "Super Dropzone - Intergalactic Rescue Mission (Europe)" - rom ( name "Super Dropzone - Intergalactic Rescue Mission (Europe).gba" size 4194304 crc BAB43D5C md5 0C5D34497C80CE931A91238C54C7E668 sha1 07BD1FA75C322E682784DB7260EA96FABA6B9256 ) + rom ( name "Super Dropzone - Intergalactic Rescue Mission (Europe).gba" size 4194304 crc bab43d5c sha1 07BD1FA75C322E682784DB7260EA96FABA6B9256 ) ) game ( name "Super Dropzone - Intergalactic Rescue Mission (USA)" description "Super Dropzone - Intergalactic Rescue Mission (USA)" - rom ( name "Super Dropzone - Intergalactic Rescue Mission (USA).gba" size 4194304 crc 2B4843FE md5 82F6103C5FC2315E7F11128B9940602F sha1 3ACD2595DBCA9802583F9DE2C789DB2E87561B05 ) + rom ( name "Super Dropzone - Intergalactic Rescue Mission (USA).gba" size 4194304 crc 2b4843fe sha1 3ACD2595DBCA9802583F9DE2C789DB2E87561B05 ) ) game ( name "Super Duper Sumos (USA)" description "Super Duper Sumos (USA)" - rom ( name "Super Duper Sumos (USA).gba" size 4194304 crc 8E20043F md5 F78DFF6FA36F9BCF38CD9E4740ECC9C3 sha1 7943CCDA4313DD4F4C3B99E29564E28EA5D610FB ) + rom ( name "Super Duper Sumos (USA).gba" size 4194304 crc 8e20043f sha1 7943CCDA4313DD4F4C3B99E29564E28EA5D610FB ) ) game ( name "Super Ghouls'n Ghosts (USA, Europe)" description "Super Ghouls'n Ghosts (USA, Europe)" - rom ( name "Super Ghouls'n Ghosts (USA, Europe).gba" size 4194304 crc 1EF2ACF3 md5 37FF7A1DE0322B72A6B41DEA0BA53673 sha1 31E7D1D405185BA2D7A9FFCC2B847D4457088CF0 ) + rom ( name "Super Ghouls'n Ghosts (USA, Europe).gba" size 4194304 crc 1ef2acf3 sha1 31E7D1D405185BA2D7A9FFCC2B847D4457088CF0 ) +) + +game ( + name "Super Ghouls'n Ghosts (USA) (Wii U Virtual Console)" + description "Super Ghouls'n Ghosts (USA) (Wii U Virtual Console)" + rom ( name "Super Ghouls'n Ghosts (USA) (Wii U Virtual Console).gba" size 4194304 crc e279ec31 sha1 D323FAEAAACD0C09157EF62128BCCB541DD0AC39 ) ) game ( name "Super Hornet FA 18F (USA, Europe)" description "Super Hornet FA 18F (USA, Europe)" - rom ( name "Super Hornet FA 18F (USA, Europe).gba" size 4194304 crc 9653BAC5 md5 ACCE7EE3388D135AAA8C5EC88E568182 sha1 038B533BB09845ADE7B0A13C7CA9923348EB1100 flags verified ) -) - -game ( - name "Super Mario Advance (USA) (Demo) (Kiosk)" - description "Super Mario Advance (USA) (Demo) (Kiosk)" - rom ( name "Super Mario Advance (USA) (Demo) (Kiosk).gba" size 4194304 crc 69924CBD md5 7B0C63D4080F79396C0545A86CC1ADBA sha1 05E41B04CDCD73194C0F836639C5774779F50A3F flags verified ) + rom ( name "Super Hornet FA 18F (USA, Europe).gba" size 4194304 crc 9653bac5 sha1 038B533BB09845ADE7B0A13C7CA9923348EB1100 flags verified ) ) game ( name "Super Mario Advance (USA, Europe)" description "Super Mario Advance (USA, Europe)" - rom ( name "Super Mario Advance (USA, Europe).gba" size 4194304 crc 1E4C6D6A md5 FF6B0C48065389B888C7A78731D4B58D sha1 F071D45D8F5CB05B48D7D2B804C6CB6A79AD96FB flags verified ) + rom ( name "Super Mario Advance (USA, Europe).gba" size 4194304 crc 1e4c6d6a sha1 F071D45D8F5CB05B48D7D2B804C6CB6A79AD96FB flags verified ) +) + +game ( + name "Super Mario Advance (USA) (Demo) (Kiosk)" + description "Super Mario Advance (USA) (Demo) (Kiosk)" + rom ( name "Super Mario Advance (USA) (Demo) (Kiosk).gba" size 4194304 crc 69924cbd sha1 05E41B04CDCD73194C0F836639C5774779F50A3F flags verified ) +) + +game ( + name "Super Mario Advance (USA, Europe) (Wii U Virtual Console)" + description "Super Mario Advance (USA, Europe) (Wii U Virtual Console)" + rom ( name "Super Mario Advance (USA, Europe) (Wii U Virtual Console).gba" size 4194304 crc 5251f2bf sha1 B646CE9765A5061AAC9F1A52346A1F5E42B3D871 flags verified ) ) game ( name "Super Mario Advance - Super Mario USA + Mario Brothers (Japan)" description "Super Mario Advance - Super Mario USA + Mario Brothers (Japan)" - rom ( name "Super Mario Advance - Super Mario USA + Mario Brothers (Japan).gba" size 4194304 crc B993B92F md5 C5240B871426F8BEF985A540B9FCADFE sha1 5AB5ADE42EA0C5F255B3FBF00CDCC07B71BA20B8 flags verified ) + rom ( name "Super Mario Advance - Super Mario USA + Mario Brothers (Japan).gba" size 4194304 crc b993b92f sha1 5AB5ADE42EA0C5F255B3FBF00CDCC07B71BA20B8 flags verified ) ) game ( - name "Super Mario Advance 2 - Super Mario World (USA, Australia)" - description "Super Mario Advance 2 - Super Mario World (USA, Australia)" - rom ( name "Super Mario Advance 2 - Super Mario World (USA, Australia).gba" size 4194304 crc 5206880A md5 2F660377581B7E48C06131F56C791B72 sha1 5101DDF223D1D918928FE1F306B63A42ADA14A5E flags verified ) + name "Super Mario Advance 2 - Super Mario World (USA)" + description "Super Mario Advance 2 - Super Mario World (USA)" + rom ( name "Super Mario Advance 2 - Super Mario World (USA).gba" size 4194304 crc 5206880a sha1 5101DDF223D1D918928FE1F306B63A42ADA14A5E flags verified ) ) game ( name "Super Mario Advance 2 - Super Mario World (Europe) (En,Fr,De,Es)" description "Super Mario Advance 2 - Super Mario World (Europe) (En,Fr,De,Es)" - rom ( name "Super Mario Advance 2 - Super Mario World (Europe) (En,Fr,De,Es).gba" size 4194304 crc FCFEF343 md5 F877B87F140945AD93CFCE50411507C0 sha1 199A5A01BD3F56FBA9A701062EDBCF57E1528A0C flags verified ) + rom ( name "Super Mario Advance 2 - Super Mario World (Europe) (En,Fr,De,Es).gba" size 4194304 crc fcfef343 sha1 199A5A01BD3F56FBA9A701062EDBCF57E1528A0C flags verified ) ) game ( name "Super Mario Advance 2 - Super Mario World + Mario Brothers (Japan)" description "Super Mario Advance 2 - Super Mario World + Mario Brothers (Japan)" - rom ( name "Super Mario Advance 2 - Super Mario World + Mario Brothers (Japan).gba" size 4194304 crc 901CE373 md5 261BAA7A487C97BCF1DF6C2464F7E9E3 sha1 8F3D3C33C77872DB9818620F5E581EC0FA342D72 flags verified ) + rom ( name "Super Mario Advance 2 - Super Mario World + Mario Brothers (Japan).gba" size 4194304 crc 901ce373 sha1 8F3D3C33C77872DB9818620F5E581EC0FA342D72 flags verified ) ) game ( name "Super Mario Advance 3 - Yoshi's Island (USA)" description "Super Mario Advance 3 - Yoshi's Island (USA)" - rom ( name "Super Mario Advance 3 - Yoshi's Island (USA).gba" size 4194304 crc 40A48276 md5 BB09508C782F37934C9519C5F8A7350C sha1 7352D2BD064D9EBAEC579E264228AA21C7345B80 flags verified ) + rom ( name "Super Mario Advance 3 - Yoshi's Island (USA).gba" size 4194304 crc 40a48276 sha1 7352D2BD064D9EBAEC579E264228AA21C7345B80 flags verified ) ) game ( name "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It)" description "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It)" - rom ( name "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 639E9D3B md5 5A0BD0EC784823F2C45FDAA5DD914BEA sha1 BD52EB4B4EBE438E9B9ECAAC792BD389725CDE41 flags verified ) + rom ( name "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 639e9d3b sha1 BD52EB4B4EBE438E9B9ECAAC792BD389725CDE41 flags verified ) +) + +game ( + name "Super Mario Advance 3 - Yoshi's Island (USA) (Wii U Virtual Console)" + description "Super Mario Advance 3 - Yoshi's Island (USA) (Wii U Virtual Console)" + rom ( name "Super Mario Advance 3 - Yoshi's Island (USA) (Wii U Virtual Console).gba" size 4194304 crc 3d803e41 sha1 DC7868B5300584E7970FE628CC35090E72F98A39 flags verified ) +) + +game ( + name "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + description "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console)" + rom ( name "Super Mario Advance 3 - Yoshi's Island (Europe) (En,Fr,De,Es,It) (Wii U Virtual Console).gba" size 8388608 crc 2c79c2de sha1 52C2541C7B369C2894F5F4B045DAC14D41C67FE0 flags verified ) ) game ( name "Super Mario Advance 3 - Yoshi's Island + Mario Brothers (Japan)" description "Super Mario Advance 3 - Yoshi's Island + Mario Brothers (Japan)" - rom ( name "Super Mario Advance 3 - Yoshi's Island + Mario Brothers (Japan).gba" size 4194304 crc 26321120 md5 9F0877F89CB43331C36F7EDBE8C9BA46 sha1 8E6D22AD9E4634E43F3AA0D2A1A33330E2EB1E04 flags verified ) + rom ( name "Super Mario Advance 3 - Yoshi's Island + Mario Brothers (Japan).gba" size 4194304 crc 26321120 sha1 8E6D22AD9E4634E43F3AA0D2A1A33330E2EB1E04 flags verified ) ) game ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan)" description "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan)" - rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan).gba" size 4194304 crc F3C87306 md5 E559E292AA9D44287B052342D6469967 sha1 19F7928BC4FFD733D71884DAE9AD9B7F4007D38D flags verified ) + rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan).gba" size 4194304 crc f3c87306 sha1 19F7928BC4FFD733D71884DAE9AD9B7F4007D38D flags verified ) ) game ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2)" description "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2)" - rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2).gba" size 4194304 crc 7B1A4C22 md5 9B7B3E2567FE71B6F488EE254209E25E sha1 B3349AD79D20F1AE77D3E120F60D60EDDDBBC2D2 ) + rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2).gba" size 4194304 crc 7b1a4c22 sha1 B3349AD79D20F1AE77D3E120F60D60EDDDBBC2D2 ) ) game ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 1)" description "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 1)" - rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 1).gba" size 4194304 crc 5A676424 md5 F45348CC19783709D04AC0C12175B222 sha1 FB38A1284013AB4E2480A1AADCEC9400D3A63A1D ) + rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 1).gba" size 4194304 crc 5a676424 sha1 FB38A1284013AB4E2480A1AADCEC9400D3A63A1D ) ) game ( - name "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1)" - description "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1)" - rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1).gba" size 4194304 crc 88DAB27F md5 605286B3AEDEFFBA70BF46B834B120B1 sha1 532F3307021637474B6DD37DA059CA360F612337 flags verified ) + name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2) (Wii U Virtual Console)" + description "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2) (Wii U Virtual Console)" + rom ( name "Super Mario Advance 4 - Super Mario 3 + Mario Brothers (Japan) (Rev 2) (Wii U Virtual Console).gba" size 8388608 crc 4aee9c77 sha1 72CCC0ECCE6CE08EADCE1B3DA4873CDD91851496 flags verified ) ) game ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It)" description "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 37141F32 md5 761668B5D01EE9B8E52174EADB5FD2CF sha1 B7F3D6DC014E2F0DDC996137BDEFBB8167A77E66 ) + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 37141f32 sha1 B7F3D6DC014E2F0DDC996137BDEFBB8167A77E66 flags verified ) ) game ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA)" description "Super Mario Advance 4 - Super Mario Bros. 3 (USA)" - rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA).gba" size 4194304 crc A44BA79F md5 4E5FDE12DBD0441150A9C177E545F56F sha1 69E81F41394F02D64CAD206ADB26B3CD43690770 ) + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA).gba" size 4194304 crc a44ba79f sha1 69E81F41394F02D64CAD206ADB26B3CD43690770 flags verified ) ) game ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1)" description "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1)" - rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 8388608 crc 8D84ACFC md5 AE8AF6B539D509019BDD06565C10804A sha1 2E5CE11A893464DC0CCE0A6B451580BA35A7E5DE flags verified ) + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1).gba" size 8388608 crc 8d84acfc sha1 2E5CE11A893464DC0CCE0A6B451580BA35A7E5DE flags verified ) +) + +game ( + name "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1)" + description "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1)" + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA, Australia) (Rev 1).gba" size 4194304 crc 88dab27f sha1 532F3307021637474B6DD37DA059CA360F612337 flags verified ) +) + +game ( + name "Super Mario Advance 4 - Super Mario Bros. 3 (USA) (Rev 1) (Wii U Virtual Console)" + description "Super Mario Advance 4 - Super Mario Bros. 3 (USA) (Rev 1) (Wii U Virtual Console)" + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (USA) (Rev 1) (Wii U Virtual Console).gba" size 8388608 crc d4c13ac3 sha1 DD2879329EC52BD5372F26B75297A67F1A81215A flags verified ) +) + +game ( + name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1) (Wii U Virtual Console)" + description "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1) (Wii U Virtual Console)" + rom ( name "Super Mario Advance 4 - Super Mario Bros. 3 (Europe) (En,Fr,De,Es,It) (Rev 1) (Wii U Virtual Console).gba" size 8388608 crc d4f45b01 sha1 00667CE3DA4BFEE3182C4445AC2F5483870BE97C flags verified ) ) game ( name "Super Mario Ball (Japan)" description "Super Mario Ball (Japan)" - rom ( name "Super Mario Ball (Japan).gba" size 8388608 crc 7EB4A336 md5 342040B3D6E19F72E6D22D7F54A169C5 sha1 3BAA3735AED4CFC6C7C5A157E7EA0285AC40B1EF flags verified ) + rom ( name "Super Mario Ball (Japan).gba" size 8388608 crc 7eb4a336 sha1 3BAA3735AED4CFC6C7C5A157E7EA0285AC40B1EF flags verified ) ) game ( name "Super Mario Ball (Europe)" description "Super Mario Ball (Europe)" - rom ( name "Super Mario Ball (Europe).gba" size 8388608 crc 3B035681 md5 CDD0D1BC1B95577662DBF561C8E77F34 sha1 D53FBC63E08C15BFDC045B5664FE24E8E2718469 flags verified ) + rom ( name "Super Mario Ball (Europe).gba" size 8388608 crc 3b035681 sha1 D53FBC63E08C15BFDC045B5664FE24E8E2718469 flags verified ) +) + +game ( + name "Super Mario Ball (Japan) (Wii U Virtual Console)" + description "Super Mario Ball (Japan) (Wii U Virtual Console)" + rom ( name "Super Mario Ball (Japan) (Wii U Virtual Console).gba" size 8388608 crc cf9914ae sha1 0C7F6D50787B93B59FF505B3D16712B60DB63CE7 flags verified ) ) game ( name "Super Mario Bros. (Japan) (Hot Mario Campaign)" description "Super Mario Bros. (Japan) (Hot Mario Campaign)" - rom ( name "Super Mario Bros. (Japan) (Hot Mario Campaign).gba" size 4194304 crc 085B271B md5 071C28E42EB8DDCCA7BF8E81CED22B1D sha1 03D9257BD0EE161FDE3B512F8E522A4B8C075745 ) + rom ( name "Super Mario Bros. (Japan) (Hot Mario Campaign).gba" size 4194304 crc 085b271b sha1 03D9257BD0EE161FDE3B512F8E522A4B8C075745 ) ) game ( name "Super Monkey Ball Jr. (USA)" description "Super Monkey Ball Jr. (USA)" - rom ( name "Super Monkey Ball Jr. (USA).gba" size 4194304 crc 0A8031F0 md5 77EDF4F506B3343E15EFE61D64944EBA sha1 0D994A58B7ACDFE9357E5405ACEBE232128B80FE ) + rom ( name "Super Monkey Ball Jr. (USA).gba" size 4194304 crc 0a8031f0 sha1 0D994A58B7ACDFE9357E5405ACEBE232128B80FE ) ) game ( name "Super Monkey Ball Jr. (Europe) (En,Fr,De,Es,It)" description "Super Monkey Ball Jr. (Europe) (En,Fr,De,Es,It)" - rom ( name "Super Monkey Ball Jr. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc D75DA09D md5 1E5A3679BB64A87EA2E23774A672CA7D sha1 9C87FCF42A27644AE5BEC273AC3AFC3F672B4F94 ) + rom ( name "Super Monkey Ball Jr. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc d75da09d sha1 9C87FCF42A27644AE5BEC273AC3AFC3F672B4F94 ) ) game ( name "Super Puzzle Bobble Advance (Japan) (En)" description "Super Puzzle Bobble Advance (Japan) (En)" - rom ( name "Super Puzzle Bobble Advance (Japan) (En).gba" size 4194304 crc F2BC49CE md5 D2A5A5CCD519B50603ECBA358D085EF4 sha1 133D8844449CB11961297E517B82EEEC2C034433 ) + rom ( name "Super Puzzle Bobble Advance (Japan) (En).gba" size 4194304 crc f2bc49ce sha1 133D8844449CB11961297E517B82EEEC2C034433 ) ) game ( - name "Super Puzzle Fighter II Turbo (Europe)" - description "Super Puzzle Fighter II Turbo (Europe)" - rom ( name "Super Puzzle Fighter II Turbo (Europe).gba" size 8388608 crc AAC3E9CA md5 622ADDBA536F937A1C5B66DDDB20C8B7 sha1 54426EBD60D910F604A32405B439EFF3C43C74CE ) + name "Super Puzzle Fighter II (Europe)" + description "Super Puzzle Fighter II (Europe)" + rom ( name "Super Puzzle Fighter II (Europe).gba" size 8388608 crc aac3e9ca sha1 54426EBD60D910F604A32405B439EFF3C43C74CE ) ) game ( - name "Super Puzzle Fighter II Turbo (USA)" - description "Super Puzzle Fighter II Turbo (USA)" - rom ( name "Super Puzzle Fighter II Turbo (USA).gba" size 8388608 crc 9CD25C7E md5 14D0771C15676E2B3B75C4C149879586 sha1 801DF7F69FC574A17E8C5EFCE6CA18AE5749AA97 ) + name "Super Puzzle Fighter II (USA)" + description "Super Puzzle Fighter II (USA)" + rom ( name "Super Puzzle Fighter II (USA).gba" size 8388608 crc 9cd25c7e sha1 801DF7F69FC574A17E8C5EFCE6CA18AE5749AA97 ) +) + +game ( + name "Super Puzzle Fighter II (USA) (Rev 1)" + description "Super Puzzle Fighter II (USA) (Rev 1)" + rom ( name "Super Puzzle Fighter II (USA) (Rev 1).gba" size 8388608 crc 62066fc9 sha1 02DD6145BCF6647D9C8A68C5B56C44D190A6BD92 flags verified ) ) game ( name "Super Real Mahjong Dousoukai (Japan)" description "Super Real Mahjong Dousoukai (Japan)" - rom ( name "Super Real Mahjong Dousoukai (Japan).gba" size 8388608 crc 9E90456B md5 6700959EE0F02EAC47A8E273787EFAAE sha1 604375F14B62891B42A46B908A8A976717F7AAEA ) -) - -game ( - name "Super Robot Taisen - Original Generation (USA)" - description "Super Robot Taisen - Original Generation (USA)" - rom ( name "Super Robot Taisen - Original Generation (USA).gba" size 16777216 crc 58E86266 md5 7146102BB4D37865198DBE6881D2AF9A sha1 8512206D86B3E25D86E71FBFF6C56705B1BB6428 ) -) - -game ( - name "Super Robot Taisen - Original Generation (Europe)" - description "Super Robot Taisen - Original Generation (Europe)" - rom ( name "Super Robot Taisen - Original Generation (Europe).gba" size 16777216 crc BDB86CAA md5 4E641232755D9C8CF08C7D678BF7C570 sha1 0ED59C7DC4A68987BA6F1D2E3CE8AF776F868044 flags verified ) + rom ( name "Super Real Mahjong Dousoukai (Japan).gba" size 8388608 crc 9e90456b sha1 604375F14B62891B42A46B908A8A976717F7AAEA ) ) game ( name "Super Robot Taisen - Original Generation (Japan)" description "Super Robot Taisen - Original Generation (Japan)" - rom ( name "Super Robot Taisen - Original Generation (Japan).gba" size 8388608 crc 75127EC4 md5 BE2ED0AE2D2DA48BFE6F9E49EE2DAF7B sha1 15C9A5D9DE4EE2B8D247543C1B0BC73B00138683 ) + rom ( name "Super Robot Taisen - Original Generation (Japan).gba" size 8388608 crc 75127ec4 sha1 15C9A5D9DE4EE2B8D247543C1B0BC73B00138683 ) +) + +game ( + name "Super Robot Taisen - Original Generation (USA)" + description "Super Robot Taisen - Original Generation (USA)" + rom ( name "Super Robot Taisen - Original Generation (USA).gba" size 16777216 crc 58e86266 sha1 8512206D86B3E25D86E71FBFF6C56705B1BB6428 ) +) + +game ( + name "Super Robot Taisen - Original Generation (Europe)" + description "Super Robot Taisen - Original Generation (Europe)" + rom ( name "Super Robot Taisen - Original Generation (Europe).gba" size 16777216 crc bdb86caa sha1 0ED59C7DC4A68987BA6F1D2E3CE8AF776F868044 flags verified ) ) game ( name "Super Robot Taisen - Original Generation 2 (Japan)" description "Super Robot Taisen - Original Generation 2 (Japan)" - rom ( name "Super Robot Taisen - Original Generation 2 (Japan).gba" size 16777216 crc A608800F md5 B817219C91FAEDD9FE53F7C226FF0364 sha1 2254B7EF4C3E16062797EE872510941249F173C5 ) + rom ( name "Super Robot Taisen - Original Generation 2 (Japan).gba" size 16777216 crc a608800f sha1 2254B7EF4C3E16062797EE872510941249F173C5 ) ) game ( name "Super Robot Taisen - Original Generation 2 (USA)" description "Super Robot Taisen - Original Generation 2 (USA)" - rom ( name "Super Robot Taisen - Original Generation 2 (USA).gba" size 16777216 crc 2AEE0380 md5 F3D168D87D3E2AE25DBEC012471CD9B5 sha1 7610191AB48B27D368C5FBC1DCF2672EE49F408C ) + rom ( name "Super Robot Taisen - Original Generation 2 (USA).gba" size 16777216 crc 2aee0380 sha1 7610191AB48B27D368C5FBC1DCF2672EE49F408C ) ) game ( name "Super Robot Taisen A (Japan)" description "Super Robot Taisen A (Japan)" - rom ( name "Super Robot Taisen A (Japan).gba" size 8388608 crc 2F6E9788 md5 A5A84AC11DE577F929C19996FA15A25E sha1 D8A9D7579C0F27CF77F04F01AB69267C859C4F34 ) + rom ( name "Super Robot Taisen A (Japan).gba" size 8388608 crc 2f6e9788 sha1 D8A9D7579C0F27CF77F04F01AB69267C859C4F34 ) ) game ( name "Super Robot Taisen D (Japan)" description "Super Robot Taisen D (Japan)" - rom ( name "Super Robot Taisen D (Japan).gba" size 8388608 crc EFB45117 md5 885CFE05F516278BE9678A6345C8F485 sha1 0A839D151D2E82B972DB7C5D3651061866F133D4 ) + rom ( name "Super Robot Taisen D (Japan).gba" size 8388608 crc efb45117 sha1 0A839D151D2E82B972DB7C5D3651061866F133D4 ) ) game ( name "Super Robot Taisen J (Japan)" description "Super Robot Taisen J (Japan)" - rom ( name "Super Robot Taisen J (Japan).gba" size 16777216 crc C956FD37 md5 EF32F93816B6DBCF788F08FAF1E71450 sha1 27445302AE9EB0AA09F9365C5BA6F45655FE4200 ) + rom ( name "Super Robot Taisen J (Japan).gba" size 16777216 crc c956fd37 sha1 27445302AE9EB0AA09F9365C5BA6F45655FE4200 flags verified ) ) game ( name "Super Robot Taisen R (Japan)" description "Super Robot Taisen R (Japan)" - rom ( name "Super Robot Taisen R (Japan).gba" size 8388608 crc DF7F91BC md5 D379B595D04446ABF5335AACCD336FCF sha1 AB96D573933598E6CBEA19654A0E5CF85D746BA2 ) + rom ( name "Super Robot Taisen R (Japan).gba" size 8388608 crc df7f91bc sha1 AB96D573933598E6CBEA19654A0E5CF85D746BA2 flags verified ) ) game ( name "Super Street Fighter II Turbo - Revival (Europe)" description "Super Street Fighter II Turbo - Revival (Europe)" - rom ( name "Super Street Fighter II Turbo - Revival (Europe).gba" size 8388608 crc 461B4590 md5 B9E0B9A3D0B7AFBDE1AAF9A26A827723 sha1 3EBFDCEA237844B027C05080F5FB175D7809876F flags verified ) + rom ( name "Super Street Fighter II Turbo - Revival (Europe).gba" size 8388608 crc 461b4590 sha1 3EBFDCEA237844B027C05080F5FB175D7809876F flags verified ) ) game ( name "Super Street Fighter II Turbo - Revival (USA)" description "Super Street Fighter II Turbo - Revival (USA)" - rom ( name "Super Street Fighter II Turbo - Revival (USA).gba" size 8388608 crc 063045AA md5 7A36A7486EF2C534111EE417B8ACF9B7 sha1 00B0508E2774D0BBCB8F0994766CB362E62D7537 ) + rom ( name "Super Street Fighter II Turbo - Revival (USA).gba" size 8388608 crc 063045aa sha1 00B0508E2774D0BBCB8F0994766CB362E62D7537 ) +) + +game ( + name "Super Street Fighter II Turbo - Revival (USA) (Wii U Virtual Console)" + description "Super Street Fighter II Turbo - Revival (USA) (Wii U Virtual Console)" + rom ( name "Super Street Fighter II Turbo - Revival (USA) (Wii U Virtual Console).gba" size 8388608 crc 17d7636a sha1 2DAB7651F2E8692D0E1FA21867A980FE4FC56EAE flags verified ) ) game ( name "Super Street Fighter II X - Revival (Japan)" description "Super Street Fighter II X - Revival (Japan)" - rom ( name "Super Street Fighter II X - Revival (Japan).gba" size 8388608 crc 7A2C0D61 md5 FAC044FE59B25AE95471A85C072F716A sha1 9B1BB641E9804F472444FD35C32F34140A6C12DC ) + rom ( name "Super Street Fighter II X - Revival (Japan).gba" size 8388608 crc 7a2c0d61 sha1 9B1BB641E9804F472444FD35C32F34140A6C12DC ) ) game ( name "Superman - Countdown to Apokolips (USA)" description "Superman - Countdown to Apokolips (USA)" - rom ( name "Superman - Countdown to Apokolips (USA).gba" size 8388608 crc 43017D47 md5 F74B2B6665C687F5EC1EF2ED21120EE2 sha1 D10C346F4A818443454E565752A9165822160936 flags verified ) + rom ( name "Superman - Countdown to Apokolips (USA).gba" size 8388608 crc 43017d47 sha1 D10C346F4A818443454E565752A9165822160936 flags verified ) ) game ( name "Superman - Countdown to Apokolips (Europe) (En,Fr,De,Es,It)" description "Superman - Countdown to Apokolips (Europe) (En,Fr,De,Es,It)" - rom ( name "Superman - Countdown to Apokolips (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2BF26A56 md5 550247E8A3045024392BCABC0EA124D2 sha1 B42CB62F1CF7BF8DB3553E02EA448077BF5536EF ) + rom ( name "Superman - Countdown to Apokolips (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2bf26a56 sha1 B42CB62F1CF7BF8DB3553E02EA448077BF5536EF flags verified ) ) game ( name "Superman Returns - Fortress of Solitude (USA, Europe) (En,Fr,De,Es,It)" description "Superman Returns - Fortress of Solitude (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Superman Returns - Fortress of Solitude (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 68215047 md5 F9A91A30F730E8482A73EA0C0A71A4FB sha1 1FF9D19032466227AE7AAEBB0161C531AAF60428 ) + rom ( name "Superman Returns - Fortress of Solitude (USA, Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 68215047 sha1 1FF9D19032466227AE7AAEBB0161C531AAF60428 ) ) game ( name "Surf's Up (USA) (En,Fr,Es)" description "Surf's Up (USA) (En,Fr,Es)" - rom ( name "Surf's Up (USA) (En,Fr,Es).gba" size 8388608 crc 0ADF57C5 md5 F005987FEAC9BA8AA100658FADC72039 sha1 577E9967FD924372972741F3007CF49A26537552 ) + rom ( name "Surf's Up (USA) (En,Fr,Es).gba" size 8388608 crc 0adf57c5 sha1 577E9967FD924372972741F3007CF49A26537552 ) ) game ( name "Surf's Up (Europe) (En,Fr,De,Es,It)" description "Surf's Up (Europe) (En,Fr,De,Es,It)" - rom ( name "Surf's Up (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc B225AE1A md5 2E097B1EABED460F60B4E7D10A8B5C78 sha1 FF6F985EA71800245BE755F34A411F41113F718A ) + rom ( name "Surf's Up (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc b225ae1a sha1 FF6F985EA71800245BE755F34A411F41113F718A ) ) game ( name "Surf's Up (Europe) (En,Fr,Es)" description "Surf's Up (Europe) (En,Fr,Es)" - rom ( name "Surf's Up (Europe) (En,Fr,Es).gba" size 8388608 crc 317326B0 md5 D8ED69627A467814FB3F053FBA5D567C sha1 B0A2BA2A7D042CC9426EC1ABDBD912613C4AE191 ) + rom ( name "Surf's Up (Europe) (En,Fr,Es).gba" size 8388608 crc 317326b0 sha1 B0A2BA2A7D042CC9426EC1ABDBD912613C4AE191 ) ) game ( name "Sutakomi - Star Communicator (Japan)" description "Sutakomi - Star Communicator (Japan)" - rom ( name "Sutakomi - Star Communicator (Japan).gba" size 8388608 crc 260683C7 md5 1B52DBDDDD84D20F1FAF32234EE31E6B sha1 822D8CC1E82A2187108679448F31B25260E1F203 ) + rom ( name "Sutakomi - Star Communicator (Japan).gba" size 8388608 crc 260683c7 sha1 822D8CC1E82A2187108679448F31B25260E1F203 ) ) game ( name "Sweet Cookie Pie (Japan)" description "Sweet Cookie Pie (Japan)" - rom ( name "Sweet Cookie Pie (Japan).gba" size 4194304 crc 63F45849 md5 6DEFEE926D517F2821DFB5E7E16EB565 sha1 96610003FDB49A14B35AEEDF0C8CEBF5F80D8E4A ) + rom ( name "Sweet Cookie Pie (Japan).gba" size 4194304 crc 63f45849 sha1 96610003FDB49A14B35AEEDF0C8CEBF5F80D8E4A flags verified ) ) game ( name "Sword of Mana (USA, Australia)" description "Sword of Mana (USA, Australia)" - rom ( name "Sword of Mana (USA, Australia).gba" size 16777216 crc 7F1EAC75 md5 C7E5D28E7C430454AEFF766961095561 sha1 A7FF0B4482C7C3B19467AF37C3E277321CD9F1CD flags verified ) + rom ( name "Sword of Mana (USA, Australia).gba" size 16777216 crc 7f1eac75 sha1 A7FF0B4482C7C3B19467AF37C3E277321CD9F1CD flags verified ) ) game ( name "Sword of Mana (Europe) (Fr,De)" description "Sword of Mana (Europe) (Fr,De)" - rom ( name "Sword of Mana (Europe) (Fr,De).gba" size 16777216 crc 5EE17ED1 md5 1FB4A4B0891ED489183BA487E2F9046E sha1 7F7055642417D4526F63F49C21CD40A9DF24A11D ) + rom ( name "Sword of Mana (Europe) (Fr,De).gba" size 16777216 crc 5ee17ed1 sha1 7F7055642417D4526F63F49C21CD40A9DF24A11D ) ) game ( name "Sword of Mana (Europe) (Es,It)" description "Sword of Mana (Europe) (Es,It)" - rom ( name "Sword of Mana (Europe) (Es,It).gba" size 16777216 crc 11A0AF49 md5 CB24766D8E3E10B9A087DC52740DAEB0 sha1 390DFF3EC37D24A5D00165DEB17EB64C0ACE32B1 ) + rom ( name "Sword of Mana (Europe) (Es,It).gba" size 16777216 crc 11a0af49 sha1 390DFF3EC37D24A5D00165DEB17EB64C0ACE32B1 ) ) game ( name "Sword of Mana (Europe)" description "Sword of Mana (Europe)" - rom ( name "Sword of Mana (Europe).gba" size 16777216 crc 88E64A8A md5 15A038B656BCE4A0D293AD1B47737F9F sha1 129712CE98646C89136CEE01902DD20EF6541978 flags verified ) + rom ( name "Sword of Mana (Europe).gba" size 16777216 crc 88e64a8a sha1 129712CE98646C89136CEE01902DD20EF6541978 flags verified ) ) game ( name "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan)" description "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan)" - rom ( name "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan).gba" size 8388608 crc 58DC532E md5 F46708740D18D280466D6311DAFD0906 sha1 17E0F822E2CE33A27B809C592DC47F1BB4C0277F ) + rom ( name "Sylvanian Families - Fashion Designer ni Naritai! - Kurumi-risu no Onnanoko (Japan).gba" size 8388608 crc 58dc532e sha1 17E0F822E2CE33A27B809C592DC47F1BB4C0277F ) ) game ( name "Sylvanian Families - Yousei no Stick to Fushigi no Ki - Marron-inu no Onnanoko (Japan)" description "Sylvanian Families - Yousei no Stick to Fushigi no Ki - Marron-inu no Onnanoko (Japan)" - rom ( name "Sylvanian Families - Yousei no Stick to Fushigi no Ki - Marron-inu no Onnanoko (Japan).gba" size 8388608 crc 00911694 md5 FE3D96F30E5D72C969606CC957B581C0 sha1 E52C6B7076BC291035F5D68BEFA6F579E6B4DCF1 ) + rom ( name "Sylvanian Families - Yousei no Stick to Fushigi no Ki - Marron-inu no Onnanoko (Japan).gba" size 8388608 crc 00911694 sha1 E52C6B7076BC291035F5D68BEFA6F579E6B4DCF1 ) ) game ( name "Sylvanian Families 4 - Meguru Kisetsu no Tapestry (Japan)" description "Sylvanian Families 4 - Meguru Kisetsu no Tapestry (Japan)" - rom ( name "Sylvanian Families 4 - Meguru Kisetsu no Tapestry (Japan).gba" size 8388608 crc 3BFBF110 md5 D31B3A260356F4E5A3C9566D022E83A2 sha1 2667F3F61E9AA5A2852299DEE6BC66D222549C0A ) + rom ( name "Sylvanian Families 4 - Meguru Kisetsu no Tapestry (Japan).gba" size 8388608 crc 3bfbf110 sha1 2667F3F61E9AA5A2852299DEE6BC66D222549C0A ) ) game ( name "Tactics Ogre - The Knight of Lodis (USA)" description "Tactics Ogre - The Knight of Lodis (USA)" - rom ( name "Tactics Ogre - The Knight of Lodis (USA).gba" size 8388608 crc 6649D2CE md5 5D4F385E4E1CFA4A057D0AC828993906 sha1 85A46320A31F16F5C6DDA27FC094EDD078DBE43D flags verified ) + rom ( name "Tactics Ogre - The Knight of Lodis (USA).gba" size 8388608 crc 6649d2ce sha1 85A46320A31F16F5C6DDA27FC094EDD078DBE43D flags verified ) ) game ( name "Tactics Ogre Gaiden - The Knight of Lodis (Japan)" description "Tactics Ogre Gaiden - The Knight of Lodis (Japan)" - rom ( name "Tactics Ogre Gaiden - The Knight of Lodis (Japan).gba" size 8388608 crc 0167A878 md5 FEEC4136348094034B648677EA0B82AB sha1 EC257D645C601E439F1AB34D9B598C0443AEC3DA ) + rom ( name "Tactics Ogre Gaiden - The Knight of Lodis (Japan).gba" size 8388608 crc 0167a878 sha1 EC257D645C601E439F1AB34D9B598C0443AEC3DA ) ) game ( name "Taiketsu! Ultra Hero (Japan)" description "Taiketsu! Ultra Hero (Japan)" - rom ( name "Taiketsu! Ultra Hero (Japan).gba" size 8388608 crc 4E6BDF8B md5 FAB7A0CA0E546FC80D886F11390DD9AC sha1 C1EEFA86425C3C898FCC0BF98D4C848297140CA7 ) + rom ( name "Taiketsu! Ultra Hero (Japan).gba" size 8388608 crc 4e6bdf8b sha1 C1EEFA86425C3C898FCC0BF98D4C848297140CA7 ) ) game ( name "Tak - The Great Juju Challenge (USA, Europe)" description "Tak - The Great Juju Challenge (USA, Europe)" - rom ( name "Tak - The Great Juju Challenge (USA, Europe).gba" size 8388608 crc 881C8416 md5 4328ABD6EF7FFE7C75323DB46B91EBDD sha1 0999A8EE2BAE78A223C992408E987422BA0C0AF9 flags verified ) + rom ( name "Tak - The Great Juju Challenge (USA, Europe).gba" size 8388608 crc 881c8416 sha1 0999A8EE2BAE78A223C992408E987422BA0C0AF9 flags verified ) ) game ( name "Tak - The Great Juju Challenge (Europe) (En,Fr,De,Nl)" description "Tak - The Great Juju Challenge (Europe) (En,Fr,De,Nl)" - rom ( name "Tak - The Great Juju Challenge (Europe) (En,Fr,De,Nl).gba" size 8388608 crc 4AD90EC1 md5 BC8CC593779C21C7A8CFB71BB8784D26 sha1 EC460CADC74A0ED81838355797AFE53DC7010845 ) + rom ( name "Tak - The Great Juju Challenge (Europe) (En,Fr,De,Nl).gba" size 8388608 crc 4ad90ec1 sha1 EC460CADC74A0ED81838355797AFE53DC7010845 ) ) game ( name "Tak 2 - The Staff of Dreams (USA)" description "Tak 2 - The Staff of Dreams (USA)" - rom ( name "Tak 2 - The Staff of Dreams (USA).gba" size 8388608 crc 8F7EB026 md5 05B2267BDF77E3D36D0B96C22D3AF844 sha1 F90219DB6359332EB997A2717986A8C66EADED2B ) + rom ( name "Tak 2 - The Staff of Dreams (USA).gba" size 8388608 crc 8f7eb026 sha1 F90219DB6359332EB997A2717986A8C66EADED2B flags verified ) ) game ( name "Tak 2 - The Staff of Dreams (Europe) (En,Fr,De,Es,It)" description "Tak 2 - The Staff of Dreams (Europe) (En,Fr,De,Es,It)" - rom ( name "Tak 2 - The Staff of Dreams (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 91DD701D md5 C7174179FDB9D5DCA2A150351ADC3A58 sha1 C288C5FD548D2DDE5E03B41E221BB9D6B2EFF28A ) + rom ( name "Tak 2 - The Staff of Dreams (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 91dd701d sha1 C288C5FD548D2DDE5E03B41E221BB9D6B2EFF28A ) ) game ( name "Tak and the Power of Juju (USA)" description "Tak and the Power of Juju (USA)" - rom ( name "Tak and the Power of Juju (USA).gba" size 8388608 crc A9AF1381 md5 438BE22C9E03529E2A03779A00D17B62 sha1 6D34590D88C541650A7BD2E17A338DE82C5E84CB ) + rom ( name "Tak and the Power of Juju (USA).gba" size 8388608 crc a9af1381 sha1 6D34590D88C541650A7BD2E17A338DE82C5E84CB ) ) game ( name "Tak and the Power of Juju (Europe) (En,Fr,De)" description "Tak and the Power of Juju (Europe) (En,Fr,De)" - rom ( name "Tak and the Power of Juju (Europe) (En,Fr,De).gba" size 8388608 crc 0D483AA6 md5 AB74D01622E145A4687FFC3E8AF5F86B sha1 1C1BD37EEA1EFF3FE83B902B55362EFDE51A723B flags verified ) + rom ( name "Tak and the Power of Juju (Europe) (En,Fr,De).gba" size 8388608 crc 0d483aa6 sha1 1C1BD37EEA1EFF3FE83B902B55362EFDE51A723B flags verified ) ) game ( name "Tak and the Power of Juju (Europe) (Es,It)" description "Tak and the Power of Juju (Europe) (Es,It)" - rom ( name "Tak and the Power of Juju (Europe) (Es,It).gba" size 8388608 crc 4D0C3680 md5 DCE9D2624293EC80BD9E2937D9D3D0F1 sha1 D9E93F0ECF548B0ADB31194D44BF1D3D070F680F ) + rom ( name "Tak and the Power of Juju (Europe) (Es,It).gba" size 8388608 crc 4d0c3680 sha1 D9E93F0ECF548B0ADB31194D44BF1D3D070F680F ) ) game ( name "Tales of Phantasia (Japan)" description "Tales of Phantasia (Japan)" - rom ( name "Tales of Phantasia (Japan).gba" size 8388608 crc D08819C1 md5 68BDD417DD5BF3D1C88FD0B2A800E17C sha1 77823C36966C2330628CA2F03FCF681A1D3F9AFA ) + rom ( name "Tales of Phantasia (Japan).gba" size 8388608 crc d08819c1 sha1 77823C36966C2330628CA2F03FCF681A1D3F9AFA ) ) game ( name "Tales of Phantasia (USA, Australia)" description "Tales of Phantasia (USA, Australia)" - rom ( name "Tales of Phantasia (USA, Australia).gba" size 8388608 crc 01A0FCA8 md5 70FA9E5D34134D1B46D9ABDB43FEA624 sha1 262E9393119CB1991A27A3DDD5A070AE3C60CEE9 flags verified ) + rom ( name "Tales of Phantasia (USA, Australia).gba" size 8388608 crc 01a0fca8 sha1 262E9393119CB1991A27A3DDD5A070AE3C60CEE9 flags verified ) ) game ( name "Tales of Phantasia (Europe) (En,Fr,De,Es,It)" description "Tales of Phantasia (Europe) (En,Fr,De,Es,It)" - rom ( name "Tales of Phantasia (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc FA172A4A md5 C3439DFD940ADEAB78B4F9D13599FD49 sha1 2CC3C21C99C48DC445F499E6CC8AA9B90B2C795B flags verified ) + rom ( name "Tales of Phantasia (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc fa172a4a sha1 2CC3C21C99C48DC445F499E6CC8AA9B90B2C795B flags verified ) ) game ( name "Tales of the World - Narikiri Dungeon 2 (Japan)" description "Tales of the World - Narikiri Dungeon 2 (Japan)" - rom ( name "Tales of the World - Narikiri Dungeon 2 (Japan).gba" size 8388608 crc 231B9FCA md5 1933352FDCC12B8BDB603EE7ED8F9027 sha1 2FEB4CFF9485C68758C1FAC847C6EB907E747A01 flags verified ) + rom ( name "Tales of the World - Narikiri Dungeon 2 (Japan).gba" size 8388608 crc 231b9fca sha1 2FEB4CFF9485C68758C1FAC847C6EB907E747A01 flags verified ) ) game ( name "Tales of the World - Narikiri Dungeon 3 (Japan)" description "Tales of the World - Narikiri Dungeon 3 (Japan)" - rom ( name "Tales of the World - Narikiri Dungeon 3 (Japan).gba" size 16777216 crc 1867CCEF md5 289BBB2E151A6CA11F896CA4712C9835 sha1 263B5BA40B1E0AFBC2C23F478CC83F794846A47F flags verified ) + rom ( name "Tales of the World - Narikiri Dungeon 3 (Japan).gba" size 16777216 crc 1867ccef sha1 263B5BA40B1E0AFBC2C23F478CC83F794846A47F flags verified ) ) game ( name "Tales of the World - Summoner's Lineage (Japan)" description "Tales of the World - Summoner's Lineage (Japan)" - rom ( name "Tales of the World - Summoner's Lineage (Japan).gba" size 8388608 crc 9C534023 md5 7BBD6798ACFBE798D1E458938AFC7A1A sha1 C7BDA17313FDEF597CCEC98502E71C7E61281C9B ) + rom ( name "Tales of the World - Summoner's Lineage (Japan).gba" size 8388608 crc 9c534023 sha1 C7BDA17313FDEF597CCEC98502E71C7E61281C9B flags verified ) ) game ( name "Tanbi Musou - Meine Liebe (Japan)" description "Tanbi Musou - Meine Liebe (Japan)" - rom ( name "Tanbi Musou - Meine Liebe (Japan).gba" size 8388608 crc 2785CB89 md5 48FAEEB4917A9A9721D3D8769F4F4FB5 sha1 01FBF8CB72B35B97571DD63EEA63B31AEB9AE495 ) + rom ( name "Tanbi Musou - Meine Liebe (Japan).gba" size 8388608 crc 2785cb89 sha1 01FBF8CB72B35B97571DD63EEA63B31AEB9AE495 ) ) game ( name "Tang Tang (USA)" description "Tang Tang (USA)" - rom ( name "Tang Tang (USA).gba" size 4194304 crc F5F0C143 md5 B8F6082B8F1A88B9DAB0565CA19A2E64 sha1 E39F7F1851A662A422D31F2B5DE94704A6AC6FE7 ) + rom ( name "Tang Tang (USA).gba" size 4194304 crc f5f0c143 sha1 E39F7F1851A662A422D31F2B5DE94704A6AC6FE7 ) ) game ( name "Tang Tang (Europe) (En,Fr,De,Es,It,Fi)" description "Tang Tang (Europe) (En,Fr,De,Es,It,Fi)" - rom ( name "Tang Tang (Europe) (En,Fr,De,Es,It,Fi).gba" size 4194304 crc 8BFB4CFE md5 4F6D310CC67AFAA9424269904229EA3B sha1 4C4852ECDF5A31FB8C72E552575335267FDD1296 flags verified ) + rom ( name "Tang Tang (Europe) (En,Fr,De,Es,It,Fi).gba" size 4194304 crc 8bfb4cfe sha1 4C4852ECDF5A31FB8C72E552575335267FDD1296 flags verified ) ) game ( name "Tantei Gakuen Q - Kyuukyoku Trick ni Idome! (Japan)" description "Tantei Gakuen Q - Kyuukyoku Trick ni Idome! (Japan)" - rom ( name "Tantei Gakuen Q - Kyuukyoku Trick ni Idome! (Japan).gba" size 16777216 crc 77C172BD md5 6DA3B3FBE2049ECB796FC7486A7E140E sha1 ADEF60A4063CC141749A07F6544BB0B93F5F30B8 ) + rom ( name "Tantei Gakuen Q - Kyuukyoku Trick ni Idome! (Japan).gba" size 16777216 crc 77c172bd sha1 ADEF60A4063CC141749A07F6544BB0B93F5F30B8 flags verified ) ) game ( name "Tantei Gakuen Q - Meitantei wa Kimi da! (Japan)" description "Tantei Gakuen Q - Meitantei wa Kimi da! (Japan)" - rom ( name "Tantei Gakuen Q - Meitantei wa Kimi da! (Japan).gba" size 16777216 crc 552F0D90 md5 A3F7EF5C049C16A450037D5AA51F25E7 sha1 B3F70A634263C9512DCFF53DECF6EDE48F94C037 ) + rom ( name "Tantei Gakuen Q - Meitantei wa Kimi da! (Japan).gba" size 16777216 crc 552f0d90 sha1 B3F70A634263C9512DCFF53DECF6EDE48F94C037 flags verified ) ) game ( name "Tantei Jinguuji Saburou - Shiroi Kage no Shoujo (Japan)" description "Tantei Jinguuji Saburou - Shiroi Kage no Shoujo (Japan)" - rom ( name "Tantei Jinguuji Saburou - Shiroi Kage no Shoujo (Japan).gba" size 8388608 crc 3C21D7E0 md5 F43C3CC85F221533FDA3C279A45CE8EA sha1 B84BD4C83AB1EF78BC659B3917EF7C89DEF8BA6C flags verified ) + rom ( name "Tantei Jinguuji Saburou - Shiroi Kage no Shoujo (Japan).gba" size 8388608 crc 3c21d7e0 sha1 B84BD4C83AB1EF78BC659B3917EF7C89DEF8BA6C flags verified ) ) game ( name "Tarzan - L'Appel de la Jungle (France)" description "Tarzan - L'Appel de la Jungle (France)" - rom ( name "Tarzan - L'Appel de la Jungle (France).gba" size 8388608 crc 35AB002E md5 BE0EC34001B26921491D630DF83401F2 sha1 8FBA1312DA36BB212027B00D4932EEC11FEC0224 ) + rom ( name "Tarzan - L'Appel de la Jungle (France).gba" size 8388608 crc 35ab002e sha1 8FBA1312DA36BB212027B00D4932EEC11FEC0224 ) ) game ( name "Tarzan - Return to the Jungle (USA, Europe)" description "Tarzan - Return to the Jungle (USA, Europe)" - rom ( name "Tarzan - Return to the Jungle (USA, Europe).gba" size 8388608 crc 32C6DF3F md5 355AD9613487D0EBC64AB75399AC075B sha1 A5E21E954DD17D853FCC418CA6ACAC17EBBA262B flags verified ) + rom ( name "Tarzan - Return to the Jungle (USA, Europe).gba" size 8388608 crc 32c6df3f sha1 A5E21E954DD17D853FCC418CA6ACAC17EBBA262B flags verified ) ) game ( name "Tarzan - Rueckkehr in den Dschungel (Germany)" description "Tarzan - Rueckkehr in den Dschungel (Germany)" - rom ( name "Tarzan - Rueckkehr in den Dschungel (Germany).gba" size 8388608 crc 59733B26 md5 6FD5903FB649CB05007052999F2BDBF3 sha1 811EA3788F0783E3D4F9CC4ECD21C277D839E6BE ) + rom ( name "Tarzan - Rueckkehr in den Dschungel (Germany).gba" size 8388608 crc 59733b26 sha1 811EA3788F0783E3D4F9CC4ECD21C277D839E6BE ) ) game ( name "Taxi 3 (France)" description "Taxi 3 (France)" - rom ( name "Taxi 3 (France).gba" size 8388608 crc 2D2B0C11 md5 577E264B8B907C407E8D03DAC71500C6 sha1 1140FEADEE8E5CD85F83FD6E98EF6685C1093945 ) + rom ( name "Taxi 3 (France).gba" size 8388608 crc 2d2b0c11 sha1 1140FEADEE8E5CD85F83FD6E98EF6685C1093945 ) ) game ( name "Teen Titans (USA) (En,Fr)" description "Teen Titans (USA) (En,Fr)" - rom ( name "Teen Titans (USA) (En,Fr).gba" size 8388608 crc 12A0442C md5 148C4190C830886BECE41EB380EA3533 sha1 94BF3FC459321450FF2B1E75A0B98EFACFFD2D0B ) + rom ( name "Teen Titans (USA) (En,Fr).gba" size 8388608 crc 12a0442c sha1 94BF3FC459321450FF2B1E75A0B98EFACFFD2D0B ) ) game ( name "Teen Titans 2 (USA) (En,Fr)" description "Teen Titans 2 (USA) (En,Fr)" - rom ( name "Teen Titans 2 (USA) (En,Fr).gba" size 8388608 crc CCACD823 md5 C9CE90B98C6CC2F60847D6F39ECF11C5 sha1 1CFCA926300DB1719AA671404386A19B55316054 ) + rom ( name "Teen Titans 2 (USA) (En,Fr).gba" size 8388608 crc ccacd823 sha1 1CFCA926300DB1719AA671404386A19B55316054 ) ) game ( name "Teenage Mutant Ninja Turtles (USA)" description "Teenage Mutant Ninja Turtles (USA)" - rom ( name "Teenage Mutant Ninja Turtles (USA).gba" size 8388608 crc F6C36783 md5 660B52E20C76807F03BB97BF49E15AA1 sha1 EDFDEA2BEF553AEE1915E7C900977520D9E6FC0A ) + rom ( name "Teenage Mutant Ninja Turtles (USA).gba" size 8388608 crc f6c36783 sha1 EDFDEA2BEF553AEE1915E7C900977520D9E6FC0A ) ) game ( name "Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It)" description "Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It)" - rom ( name "Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 15BDF0AD md5 DC4EA1EB92D51B8C18B58611AD652CCC sha1 F425099C7BDDE046A78EEB2A963612343D8D2EE5 flags verified ) + rom ( name "Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 15bdf0ad sha1 F425099C7BDDE046A78EEB2A963612343D8D2EE5 flags verified ) ) game ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (USA)" description "Teenage Mutant Ninja Turtles 2 - Battle Nexus (USA)" - rom ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (USA).gba" size 8388608 crc 802FC7C1 md5 DA96CE67D0DDAD72E032632C8FD9994A sha1 F42D0131E908942BF84D2323739CE015EE930142 ) + rom ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (USA).gba" size 8388608 crc 802fc7c1 sha1 F42D0131E908942BF84D2323739CE015EE930142 ) ) game ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (Europe) (En,Fr,De,Es,It)" description "Teenage Mutant Ninja Turtles 2 - Battle Nexus (Europe) (En,Fr,De,Es,It)" - rom ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ADA00A65 md5 EEF855D3F529AD51A0EF8BB6F028F31D sha1 EB7741AA8E5A26DC3426AC4E541638122496E8C1 flags verified ) + rom ( name "Teenage Mutant Ninja Turtles 2 - Battle Nexus (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ada00a65 sha1 EB7741AA8E5A26DC3426AC4E541638122496E8C1 flags verified ) ) game ( name "Teenage Mutant Ninja Turtles Double Pack (Europe) (En,Fr,De,Es,It)" description "Teenage Mutant Ninja Turtles Double Pack (Europe) (En,Fr,De,Es,It)" - rom ( name "Teenage Mutant Ninja Turtles Double Pack (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc E902880F md5 C0DC262C0199F86E97EB6B1F4540ECCC sha1 68309670F0BB0A5496DDE3FCBB193EEF10C06F87 ) + rom ( name "Teenage Mutant Ninja Turtles Double Pack (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc e902880f sha1 68309670F0BB0A5496DDE3FCBB193EEF10C06F87 flags verified ) ) game ( name "Teenage Mutant Ninja Turtles Double Pack (USA) (En,Fr,De,Es,It)" description "Teenage Mutant Ninja Turtles Double Pack (USA) (En,Fr,De,Es,It)" - rom ( name "Teenage Mutant Ninja Turtles Double Pack (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 176A42E5 md5 F80CAD97ED415ABA1EC81D983FB4AE56 sha1 15CBFF45CE0CB35F3E6A6059ADA2710F0CEC05C3 ) + rom ( name "Teenage Mutant Ninja Turtles Double Pack (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 176a42e5 sha1 15CBFF45CE0CB35F3E6A6059ADA2710F0CEC05C3 ) ) game ( name "Tekken Advance (Japan)" description "Tekken Advance (Japan)" - rom ( name "Tekken Advance (Japan).gba" size 8388608 crc C2EEAE53 md5 A5968BC058EA60A1E389BCD9306D9C7D sha1 F3107B1F0210D782BD3A6A38922ADEF69F9B13F4 flags verified ) + rom ( name "Tekken Advance (Japan).gba" size 8388608 crc c2eeae53 sha1 F3107B1F0210D782BD3A6A38922ADEF69F9B13F4 flags verified ) ) game ( name "Tekken Advance (USA)" description "Tekken Advance (USA)" - rom ( name "Tekken Advance (USA).gba" size 8388608 crc C59EA73B md5 5D8788E5F864D576846C5FBF0A4C827A sha1 8B21CD57CACF172F963DFC7EAD4FA127A8A63870 ) + rom ( name "Tekken Advance (USA).gba" size 8388608 crc c59ea73b sha1 8B21CD57CACF172F963DFC7EAD4FA127A8A63870 ) ) game ( name "Tekken Advance (Europe)" description "Tekken Advance (Europe)" - rom ( name "Tekken Advance (Europe).gba" size 8388608 crc 4628C1B8 md5 6D9C1A92C3B43E833676E7A2FBC0C5FE sha1 0A8665FE4E1F33427F710793DB2937485A1C9418 flags verified ) + rom ( name "Tekken Advance (Europe).gba" size 8388608 crc 4628c1b8 sha1 0A8665FE4E1F33427F710793DB2937485A1C9418 flags verified ) ) game ( name "Ten Pin Alley 2 (USA)" description "Ten Pin Alley 2 (USA)" - rom ( name "Ten Pin Alley 2 (USA).gba" size 4194304 crc 3C225943 md5 45880F41CFE125320E65B76BB05EDAAA sha1 BCD146D58D74F054553996BBC4319C4FF3A2EF1B ) + rom ( name "Ten Pin Alley 2 (USA).gba" size 4194304 crc 3c225943 sha1 BCD146D58D74F054553996BBC4319C4FF3A2EF1B ) ) game ( name "Tennis Masters Series 2003 (Europe) (En,Fr,De,Es,It,Pt)" description "Tennis Masters Series 2003 (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Tennis Masters Series 2003 (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 28E6BD52 md5 6E1D30AEC9AB1CC56A3740129D5AD75C sha1 04C64BCF4524697ACA4E42D3D353DB75209C4235 ) + rom ( name "Tennis Masters Series 2003 (Europe) (En,Fr,De,Es,It,Pt).gba" size 4194304 crc 28e6bd52 sha1 04C64BCF4524697ACA4E42D3D353DB75209C4235 ) ) game ( name "Tennis no Ouji-sama - Aim at the Victory! (Japan)" description "Tennis no Ouji-sama - Aim at the Victory! (Japan)" - rom ( name "Tennis no Ouji-sama - Aim at the Victory! (Japan).gba" size 16777216 crc AFC3FCF7 md5 45E326ABF113E3B265C99FA031FDCED0 sha1 D296C8BEDAE7D8542C7A1A45EE4DB84460433C71 ) + rom ( name "Tennis no Ouji-sama - Aim at the Victory! (Japan).gba" size 16777216 crc afc3fcf7 sha1 D296C8BEDAE7D8542C7A1A45EE4DB84460433C71 flags verified ) ) game ( name "Tennis no Ouji-sama - Genius Boys Academy (Japan)" description "Tennis no Ouji-sama - Genius Boys Academy (Japan)" - rom ( name "Tennis no Ouji-sama - Genius Boys Academy (Japan).gba" size 8388608 crc DD244C9A md5 ECAD3A5F95C034F51641231A33B76C8C sha1 1A823655E41943A9177F7A3BFDD7A40F276F288F flags verified ) + rom ( name "Tennis no Ouji-sama - Genius Boys Academy (Japan).gba" size 8388608 crc dd244c9a sha1 1A823655E41943A9177F7A3BFDD7A40F276F288F flags verified ) ) game ( name "Tennis no Ouji-sama 2003 - Cool Blue (Japan)" description "Tennis no Ouji-sama 2003 - Cool Blue (Japan)" - rom ( name "Tennis no Ouji-sama 2003 - Cool Blue (Japan).gba" size 16777216 crc 9F7FC898 md5 AE17A09073DC708469E6A77C537D3F21 sha1 B1D30F38AD28FA456BD5E44FD9F9BF97C9BA8C92 ) + rom ( name "Tennis no Ouji-sama 2003 - Cool Blue (Japan).gba" size 16777216 crc 9f7fc898 sha1 B1D30F38AD28FA456BD5E44FD9F9BF97C9BA8C92 flags verified ) ) game ( name "Tennis no Ouji-sama 2003 - Passion Red (Japan)" description "Tennis no Ouji-sama 2003 - Passion Red (Japan)" - rom ( name "Tennis no Ouji-sama 2003 - Passion Red (Japan).gba" size 16777216 crc 59D1DC73 md5 A8ADFB32C1D57A1071ACC7B9A47733CE sha1 9AF7C88E3EAE428C41A7E7D8E66CA6EA9D4B7AE4 ) + rom ( name "Tennis no Ouji-sama 2003 - Passion Red (Japan).gba" size 16777216 crc 59d1dc73 sha1 9AF7C88E3EAE428C41A7E7D8E66CA6EA9D4B7AE4 ) ) game ( name "Tennis no Ouji-sama 2004 - Glorious Gold (Japan)" description "Tennis no Ouji-sama 2004 - Glorious Gold (Japan)" - rom ( name "Tennis no Ouji-sama 2004 - Glorious Gold (Japan).gba" size 33554432 crc 26A4EE5C md5 6A9F7047118AC9B10DE1B570A9B8EA77 sha1 8DA569C0E410E81EC16134D472FAAD6397C97B0F ) + rom ( name "Tennis no Ouji-sama 2004 - Glorious Gold (Japan).gba" size 33554432 crc 26a4ee5c sha1 8DA569C0E410E81EC16134D472FAAD6397C97B0F ) ) game ( name "Tennis no Ouji-sama 2004 - Stylish Silver (Japan)" description "Tennis no Ouji-sama 2004 - Stylish Silver (Japan)" - rom ( name "Tennis no Ouji-sama 2004 - Stylish Silver (Japan).gba" size 33554432 crc 750D579D md5 4F7E62E01838CC6CA736A7B2E3DBA495 sha1 C0519724CE36117E343F31ECD549D7DF6DFEB11B ) + rom ( name "Tennis no Ouji-sama 2004 - Stylish Silver (Japan).gba" size 33554432 crc 750d579d sha1 C0519724CE36117E343F31ECD549D7DF6DFEB11B ) ) game ( name "Terminator 3 - Rise of the Machines (Europe) (En,Fr,De,Es,It)" description "Terminator 3 - Rise of the Machines (Europe) (En,Fr,De,Es,It)" - rom ( name "Terminator 3 - Rise of the Machines (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 16C3CAC3 md5 BA4F3EFC9D451376211F46119E28DE9C sha1 48EE4CB5C17ED1DBCAE0CB9BDF9E54210CEED93C flags verified ) + rom ( name "Terminator 3 - Rise of the Machines (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 16c3cac3 sha1 48EE4CB5C17ED1DBCAE0CB9BDF9E54210CEED93C flags verified ) ) game ( name "Terminator 3 - Rise of the Machines (USA)" description "Terminator 3 - Rise of the Machines (USA)" - rom ( name "Terminator 3 - Rise of the Machines (USA).gba" size 8388608 crc F74B3C7D md5 AFA8A9E3D7A2CD86C6CE8331532825B0 sha1 D7935449C72EB1BEB4A9F7E9007855D4357E3155 ) -) - -game ( - name "Tetris Worlds (Europe) (En,Es,It)" - description "Tetris Worlds (Europe) (En,Es,It)" - rom ( name "Tetris Worlds (Europe) (En,Es,It).gba" size 4194304 crc 4A834FC2 md5 08AECB6882D9A73B2CAC1316A5FBF31B sha1 2DE4D4C3D239B2E56AD4CC3000BB1AD2FDDDD987 ) -) - -game ( - name "Tetris Worlds (Japan) (Rev 1)" - description "Tetris Worlds (Japan) (Rev 1)" - rom ( name "Tetris Worlds (Japan) (Rev 1).gba" size 4194304 crc FCF2D471 md5 9861AB21A881684A50EC5CEAEF04558C sha1 BE44036E39F95FB9FEB93630720D46570BA1A42F ) + rom ( name "Terminator 3 - Rise of the Machines (USA).gba" size 8388608 crc f74b3c7d sha1 D7935449C72EB1BEB4A9F7E9007855D4357E3155 ) ) game ( name "Tetris Worlds (USA)" description "Tetris Worlds (USA)" - rom ( name "Tetris Worlds (USA).gba" size 4194304 crc 7B729804 md5 0C4FD4CF211B2B712FD090EF1B95ADFD sha1 3FD4735EDC6B9E1EE04243C24280D14475B9A191 ) + rom ( name "Tetris Worlds (USA).gba" size 4194304 crc 7b729804 sha1 3FD4735EDC6B9E1EE04243C24280D14475B9A191 flags verified ) ) game ( name "Tetris Worlds (Europe) (En,Fr,De,Nl)" description "Tetris Worlds (Europe) (En,Fr,De,Nl)" - rom ( name "Tetris Worlds (Europe) (En,Fr,De,Nl).gba" size 4194304 crc AD97EB3F md5 3C29C1A26C74B8B1511E17FDD66956A6 sha1 4A1297B44208366A178CC1F2541F5EA8386F6F3E flags verified ) + rom ( name "Tetris Worlds (Europe) (En,Fr,De,Nl).gba" size 4194304 crc ad97eb3f sha1 4A1297B44208366A178CC1F2541F5EA8386F6F3E flags verified ) ) game ( name "Tetris Worlds (Japan)" description "Tetris Worlds (Japan)" - rom ( name "Tetris Worlds (Japan).gba" size 4194304 crc DD271470 md5 0C1605D8447BF69A74DBD715D5FBE70F sha1 F916A9017068E6B4D18D911B049215A5072C4054 ) + rom ( name "Tetris Worlds (Japan).gba" size 4194304 crc dd271470 sha1 F916A9017068E6B4D18D911B049215A5072C4054 ) +) + +game ( + name "Tetris Worlds (Europe) (En,Es,It)" + description "Tetris Worlds (Europe) (En,Es,It)" + rom ( name "Tetris Worlds (Europe) (En,Es,It).gba" size 4194304 crc 4a834fc2 sha1 2DE4D4C3D239B2E56AD4CC3000BB1AD2FDDDD987 ) +) + +game ( + name "Tetris Worlds (Japan) (Rev 1)" + description "Tetris Worlds (Japan) (Rev 1)" + rom ( name "Tetris Worlds (Japan) (Rev 1).gba" size 4194304 crc fcf2d471 sha1 BE44036E39F95FB9FEB93630720D46570BA1A42F flags verified ) ) game ( name "Texas Hold 'em Poker (USA, Europe)" description "Texas Hold 'em Poker (USA, Europe)" - rom ( name "Texas Hold 'em Poker (USA, Europe).gba" size 4194304 crc 78B59AAC md5 07397D508982F2C340C296D2C057DB8A sha1 5FCC9958210D8BDE94A429516B15CA669427FE6D flags verified ) + rom ( name "Texas Hold 'em Poker (USA, Europe).gba" size 4194304 crc 78b59aac sha1 5FCC9958210D8BDE94A429516B15CA669427FE6D flags verified ) ) game ( name "Texas Hold 'em Poker (Europe) (Rev 1)" description "Texas Hold 'em Poker (Europe) (Rev 1)" - serial "AGB-BXAP-UKV" - rom ( name "Texas Hold 'em Poker (Europe) (Rev 1).gba" size 4194304 crc 1A13DF6B md5 855CDF29FC72A4C55026AEACA8480BB9 sha1 F6D018D9174BF04FD8C90B3173570391F2D11B19 ) + rom ( name "Texas Hold 'em Poker (Europe) (Rev 1).gba" size 4194304 crc 1a13df6b sha1 F6D018D9174BF04FD8C90B3173570391F2D11B19 flags verified ) ) game ( name "TG Rally (Europe)" description "TG Rally (Europe)" - rom ( name "TG Rally (Europe).gba" size 4194304 crc BE67D878 md5 5B8EB6080AE3DE50D9734DAACD6B92FE sha1 051FD2B0D38D293583BF76A1DCE7C4FA532F6EC5 ) + rom ( name "TG Rally (Europe).gba" size 4194304 crc be67d878 sha1 051FD2B0D38D293583BF76A1DCE7C4FA532F6EC5 ) ) game ( name "That's So Raven (USA)" description "That's So Raven (USA)" - rom ( name "That's So Raven (USA).gba" size 8388608 crc 8E190698 md5 6FF16E52B08129B6BB1A650F9ADFD603 sha1 87D8CC357CBACE0539FB5A4520FAC8B4A4AAA6C4 ) + rom ( name "That's So Raven (USA).gba" size 8388608 crc 8e190698 sha1 87D8CC357CBACE0539FB5A4520FAC8B4A4AAA6C4 ) ) game ( name "That's So Raven 2 - Supernatural Style (USA) (En,Fr)" description "That's So Raven 2 - Supernatural Style (USA) (En,Fr)" - rom ( name "That's So Raven 2 - Supernatural Style (USA) (En,Fr).gba" size 8388608 crc 5495CBE1 md5 DA7FA09CA99FA6C7E6462A29494D991E sha1 1BCD8C3B455B4D1F8F850FDC8D25B0257BD3B5BE ) + rom ( name "That's So Raven 2 - Supernatural Style (USA) (En,Fr).gba" size 8388608 crc 5495cbe1 sha1 1BCD8C3B455B4D1F8F850FDC8D25B0257BD3B5BE ) ) game ( name "Three Stooges, The (USA)" description "Three Stooges, The (USA)" - rom ( name "Three Stooges, The (USA).gba" size 4194304 crc C3C855EA md5 C0C2FEC6B1CA631C49896290C7410D49 sha1 85328AF6D239C32F7B540118CA276D35201D1E02 ) + rom ( name "Three Stooges, The (USA).gba" size 4194304 crc c3c855ea sha1 85328AF6D239C32F7B540118CA276D35201D1E02 ) ) game ( name "Three-in-One Pack - Connect Four + Perfection + Trouble (USA)" description "Three-in-One Pack - Connect Four + Perfection + Trouble (USA)" - rom ( name "Three-in-One Pack - Connect Four + Perfection + Trouble (USA).gba" size 4194304 crc D482421E md5 9BB3381CAEDEBFF8DA5304112FC9039D sha1 8348577753B79BFDAD998C75C1FDA0D6569F240E ) + rom ( name "Three-in-One Pack - Connect Four + Perfection + Trouble (USA).gba" size 4194304 crc d482421e sha1 8348577753B79BFDAD998C75C1FDA0D6569F240E ) ) game ( name "Three-in-One Pack - Risk + Battleship + Clue (USA)" description "Three-in-One Pack - Risk + Battleship + Clue (USA)" - rom ( name "Three-in-One Pack - Risk + Battleship + Clue (USA).gba" size 4194304 crc F6F70922 md5 1CD909A6837E4175244B71B83D2FDD1F sha1 35D7FE8C1A36A4F924C28FF0E9C728C819B52405 ) + rom ( name "Three-in-One Pack - Risk + Battleship + Clue (USA).gba" size 4194304 crc f6f70922 sha1 35D7FE8C1A36A4F924C28FF0E9C728C819B52405 ) ) game ( name "Three-in-One Pack - Risk + Battleship + Clue (USA) (Rev 1)" description "Three-in-One Pack - Risk + Battleship + Clue (USA) (Rev 1)" - rom ( name "Three-in-One Pack - Risk + Battleship + Clue (USA) (Rev 1).gba" size 4194304 crc 15C24091 md5 DB41A36EE67ABB52CDC7623F1763EF05 sha1 06F95762BC56E11C984AF71E197D146F95EA4F70 ) + rom ( name "Three-in-One Pack - Risk + Battleship + Clue (USA) (Rev 1).gba" size 4194304 crc 15c24091 sha1 06F95762BC56E11C984AF71E197D146F95EA4F70 flags verified ) ) game ( name "Three-in-One Pack - Sorry! + Aggravation + Scrabble Junior (USA)" description "Three-in-One Pack - Sorry! + Aggravation + Scrabble Junior (USA)" - rom ( name "Three-in-One Pack - Sorry! + Aggravation + Scrabble Junior (USA).gba" size 4194304 crc 111EB61A md5 74439CFEBABB5616FBC00C8F7F9F747E sha1 CBC5BB55D4951E884E65EA2CAB36957EE51AAADB ) + rom ( name "Three-in-One Pack - Sorry! + Aggravation + Scrabble Junior (USA).gba" size 4194304 crc 111eb61a sha1 CBC5BB55D4951E884E65EA2CAB36957EE51AAADB ) ) game ( name "Thunder Alley (USA)" description "Thunder Alley (USA)" - rom ( name "Thunder Alley (USA).gba" size 4194304 crc 25E8E649 md5 AFCD7BCFDC31AE934333DA25DB6107C0 sha1 D63AAF9AC4468F1D0EAD35606D9A4F56327B2537 flags verified ) + rom ( name "Thunder Alley (USA).gba" size 4194304 crc 25e8e649 sha1 D63AAF9AC4468F1D0EAD35606D9A4F56327B2537 flags verified ) ) game ( name "Thunderbirds (USA, Europe)" description "Thunderbirds (USA, Europe)" - rom ( name "Thunderbirds (USA, Europe).gba" size 4194304 crc F09B7BB0 md5 BFF321BA7052247F9A6936E3ED0C75DA sha1 08C4B9B924F5CF0404CAB5CD7FB6064FCA872250 ) + rom ( name "Thunderbirds (USA, Europe).gba" size 4194304 crc f09b7bb0 sha1 08C4B9B924F5CF0404CAB5CD7FB6064FCA872250 flags verified ) ) game ( name "Thunderbirds - International Rescue (Europe)" description "Thunderbirds - International Rescue (Europe)" - rom ( name "Thunderbirds - International Rescue (Europe).gba" size 8388608 crc 9A6CB678 md5 38CFA461202A2B32E2CCC92CB6178AF6 sha1 2A1221C4B2A341D31062FC94CA5C2530E8157179 ) + rom ( name "Thunderbirds - International Rescue (Europe).gba" size 8388608 crc 9a6cb678 sha1 2A1221C4B2A341D31062FC94CA5C2530E8157179 ) ) game ( name "Tiger Woods PGA Tour 2004 (USA, Europe)" description "Tiger Woods PGA Tour 2004 (USA, Europe)" - rom ( name "Tiger Woods PGA Tour 2004 (USA, Europe).gba" size 16777216 crc 0E38108B md5 AA571C3F25128F4B1CBFAC89A7AE5D99 sha1 89F93BF10314C4094A96036B4F5DF95E7D80B37C flags verified ) + rom ( name "Tiger Woods PGA Tour 2004 (USA, Europe).gba" size 16777216 crc 0e38108b sha1 89F93BF10314C4094A96036B4F5DF95E7D80B37C flags verified ) ) game ( name "Tiger Woods PGA Tour Golf (USA, Europe)" description "Tiger Woods PGA Tour Golf (USA, Europe)" - rom ( name "Tiger Woods PGA Tour Golf (USA, Europe).gba" size 8388608 crc F3F26ACC md5 1040F372F0D2ED64F01E582DFFA6D89B sha1 88B204B7B51995E41459B532580B3956D7DB55AD flags verified ) + rom ( name "Tiger Woods PGA Tour Golf (USA, Europe).gba" size 8388608 crc f3f26acc sha1 88B204B7B51995E41459B532580B3956D7DB55AD flags verified ) ) game ( name "Tiger Woods PGA Tour Golf (Europe) (En,Fr,De,Es,It)" description "Tiger Woods PGA Tour Golf (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiger Woods PGA Tour Golf (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 38934732 md5 41A75032E074D588CD043CDD73BD9019 sha1 9D77F693C141D97A9E659997744C50087BF1FE4F ) + rom ( name "Tiger Woods PGA Tour Golf (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 38934732 sha1 9D77F693C141D97A9E659997744C50087BF1FE4F ) ) game ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (Japan)" description "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (Japan)" - rom ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (Japan).gba" size 8388608 crc 9F16857D md5 19237FA5628F80A4239D817EBA82FAA6 sha1 43F6D6E7FBBAE7A930A494AA43CED54FCAA4D594 ) + rom ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (Japan).gba" size 8388608 crc 9f16857d sha1 43F6D6E7FBBAE7A930A494AA43CED54FCAA4D594 ) ) game ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (USA, Europe) (En,Fr,De,Es,It)" description "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3C247C14 md5 2DE53BF040953AD79CC8135C37B47AA0 sha1 8E713FA3E3CC5AA8C1836FBA9D81BBF80DE20638 ) + rom ( name "Tim Burton's The Nightmare Before Christmas - The Pumpkin King (USA, Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 3c247c14 sha1 8E713FA3E3CC5AA8C1836FBA9D81BBF80DE20638 ) ) game ( name "Tiny Toon Adventures - Buster's Bad Dream (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Buster's Bad Dream (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiny Toon Adventures - Buster's Bad Dream (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3246A8BD md5 9BA9BA05BE9BFF52143E07CDF962D0AD sha1 B81C1336531CC1DD8B603E05B8FAD5333B7CFCBB ) + rom ( name "Tiny Toon Adventures - Buster's Bad Dream (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3246a8bd sha1 B81C1336531CC1DD8B603E05B8FAD5333B7CFCBB ) ) game ( name "Tiny Toon Adventures - Scary Dreams (USA)" description "Tiny Toon Adventures - Scary Dreams (USA)" - rom ( name "Tiny Toon Adventures - Scary Dreams (USA).gba" size 4194304 crc FCD7A7C0 md5 508EFC4282582038FACDEF65A57F70D9 sha1 305C6CF66E47508DEEE4B9FC12C8917302F2ED39 ) -) - -game ( - name "Tiny Toon Adventures - Wacky Stackers (USA)" - description "Tiny Toon Adventures - Wacky Stackers (USA)" - rom ( name "Tiny Toon Adventures - Wacky Stackers (USA).gba" size 4194304 crc E03C633E md5 ED37A03EF4B1DF0BEE663751CC021AA2 sha1 FD9D10006BD29945AC16C6F88608A27E15F8F7DA ) + rom ( name "Tiny Toon Adventures - Scary Dreams (USA).gba" size 4194304 crc fcd7a7c0 sha1 305C6CF66E47508DEEE4B9FC12C8917302F2ED39 ) ) game ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4AC770B6 md5 342E05B38859D830E83722CDA6E41409 sha1 CD9D810B29070D9F37DF219BFD7E52CE9D52D2B0 ) + rom ( name "Tiny Toon Adventures - Wacky Stackers (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4ac770b6 sha1 CD9D810B29070D9F37DF219BFD7E52CE9D52D2B0 flags verified ) +) + +game ( + name "Tiny Toon Adventures - Wacky Stackers (USA)" + description "Tiny Toon Adventures - Wacky Stackers (USA)" + rom ( name "Tiny Toon Adventures - Wacky Stackers (USA).gba" size 4194304 crc e03c633e sha1 FD9D10006BD29945AC16C6F88608A27E15F8F7DA ) ) game ( name "Tir et But - Edition Champions du Monde (France)" description "Tir et But - Edition Champions du Monde (France)" - rom ( name "Tir et But - Edition Champions du Monde (France).gba" size 4194304 crc 7782A204 md5 A8D1FD87AD24B27327F3974881BFC193 sha1 E097AA37AB67146D544AE1438A19F8CD9E3A8F7C ) + rom ( name "Tir et But - Edition Champions du Monde (France).gba" size 4194304 crc 7782a204 sha1 E097AA37AB67146D544AE1438A19F8CD9E3A8F7C ) ) game ( name "Titeuf - Mega Compet (France)" description "Titeuf - Mega Compet (France)" - rom ( name "Titeuf - Mega Compet (France).gba" size 4194304 crc FFD0A045 md5 8735E3AAAB28D157CD5CB0B0C6666B0D sha1 FF59A9810ADC3270295763282C9D86D549F58A6F ) + rom ( name "Titeuf - Mega Compet (France).gba" size 4194304 crc ffd0a045 sha1 FF59A9810ADC3270295763282C9D86D549F58A6F ) ) game ( - name "Titeuf - Ze Gagmachine (France)" - description "Titeuf - Ze Gagmachine (France)" - rom ( name "Titeuf - Ze Gagmachine (France).gba" size 4194304 crc 47BC61B5 md5 6C09CBD11AE826B83FE54E3F99A17477 sha1 1802756418EA97FDE2F9A685F56C6FE6EF0418B6 ) + name "Titeuf - Ze Gag Machine (France)" + description "Titeuf - Ze Gag Machine (France)" + rom ( name "Titeuf - Ze Gag Machine (France).gba" size 4194304 crc 47bc61b5 sha1 1802756418EA97FDE2F9A685F56C6FE6EF0418B6 ) ) game ( name "Titi et les Bijoux Magiques (France)" description "Titi et les Bijoux Magiques (France)" - rom ( name "Titi et les Bijoux Magiques (France).gba" size 4194304 crc C66E14A4 md5 739DD0F3A4DC829600643FD2C00FC23C sha1 7D89C5589286AEDE0884B993407C7943B73A9366 ) + rom ( name "Titi et les Bijoux Magiques (France).gba" size 4194304 crc c66e14a4 sha1 7D89C5589286AEDE0884B993407C7943B73A9366 ) ) game ( name "TMNT (USA) (En,Fr,Es)" description "TMNT (USA) (En,Fr,Es)" - rom ( name "TMNT (USA) (En,Fr,Es).gba" size 8388608 crc 916DB9D5 md5 3DAC0A2FB322EEBBDAD45ECC1EC8A943 sha1 6DAE74B04CDFE25C4C4535C4553541C71A102357 ) + rom ( name "TMNT (USA) (En,Fr,Es).gba" size 8388608 crc 916db9d5 sha1 6DAE74B04CDFE25C4C4535C4553541C71A102357 ) ) game ( name "TMNT - Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It)" description "TMNT - Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It)" - rom ( name "TMNT - Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 89103893 md5 164B2A21AFA59D6DEDAD07117296C8E7 sha1 3FBB10B419BCD6327C5BDB678A8EBE149D160B6F flags verified ) + rom ( name "TMNT - Teenage Mutant Ninja Turtles (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 89103893 sha1 3FBB10B419BCD6327C5BDB678A8EBE149D160B6F flags verified ) ) game ( name "TOCA World Touring Cars (Europe)" description "TOCA World Touring Cars (Europe)" - rom ( name "TOCA World Touring Cars (Europe).gba" size 8388608 crc D8125874 md5 BCF9DCACA7C0BAB4D75184D900D27D50 sha1 6E4360B9D123ED9784DB40E7B07E7941D3DF5401 ) + rom ( name "TOCA World Touring Cars (Europe).gba" size 8388608 crc d8125874 sha1 6E4360B9D123ED9784DB40E7B07E7941D3DF5401 flags verified ) ) game ( name "Tokimeki Yume Series 1 - Ohanaya-san ni Narou! (Japan)" description "Tokimeki Yume Series 1 - Ohanaya-san ni Narou! (Japan)" - rom ( name "Tokimeki Yume Series 1 - Ohanaya-san ni Narou! (Japan).gba" size 4194304 crc 6EEA16BD md5 3CA08A13ED9BCD779BF5DA07645F3E38 sha1 76AD4D03B90ED8E2C1E657BC43954942C1FED18B ) + rom ( name "Tokimeki Yume Series 1 - Ohanaya-san ni Narou! (Japan).gba" size 4194304 crc 6eea16bd sha1 76AD4D03B90ED8E2C1E657BC43954942C1FED18B flags verified ) ) game ( name "Tokyo Majin Gakuen - Fuju Houroku (Japan)" description "Tokyo Majin Gakuen - Fuju Houroku (Japan)" - rom ( name "Tokyo Majin Gakuen - Fuju Houroku (Japan).gba" size 16777216 crc E05CEF9D md5 607CC417603B39C571E851EB4B498103 sha1 8D9EFB85A8F22EA72C17E4CFCAC6877E16B9D5AC ) + rom ( name "Tokyo Majin Gakuen - Fuju Houroku (Japan).gba" size 16777216 crc e05cef9d sha1 8D9EFB85A8F22EA72C17E4CFCAC6877E16B9D5AC ) ) game ( name "Tokyo Xtreme Racer Advance (USA)" description "Tokyo Xtreme Racer Advance (USA)" - rom ( name "Tokyo Xtreme Racer Advance (USA).gba" size 4194304 crc AB272800 md5 51664A136B5C9383258E58B384A8D9A8 sha1 4197339D4ADD74BB40ED02A8FBA5E58096AFB487 ) + rom ( name "Tokyo Xtreme Racer Advance (USA).gba" size 4194304 crc ab272800 sha1 4197339D4ADD74BB40ED02A8FBA5E58096AFB487 ) ) game ( name "Tokyo Xtreme Racer Advance (Europe) (En,Fr,De,Es,It)" description "Tokyo Xtreme Racer Advance (Europe) (En,Fr,De,Es,It)" - rom ( name "Tokyo Xtreme Racer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc BD5F5F4C md5 540379FC48A27BAAFBD1571DEA34C9DA sha1 15A306794EFDD64651387C1447AE4713892E4B87 flags verified ) + rom ( name "Tokyo Xtreme Racer Advance (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc bd5f5f4c sha1 15A306794EFDD64651387C1447AE4713892E4B87 flags verified ) ) game ( name "Tom and Jerry - The Magic Ring (USA) (En,Fr,De,Es,It)" description "Tom and Jerry - The Magic Ring (USA) (En,Fr,De,Es,It)" - rom ( name "Tom and Jerry - The Magic Ring (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 7DC8E08E md5 C3C7E4250EBFE4CE6020CABD42F08AFE sha1 19ED73F1EA71454ED804ED758A697D5E3FEDA8BE ) + rom ( name "Tom and Jerry - The Magic Ring (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 7dc8e08e sha1 19ED73F1EA71454ED804ED758A697D5E3FEDA8BE ) ) game ( name "Tom and Jerry - The Magic Ring (Europe) (En,Fr,De,Es,It)" description "Tom and Jerry - The Magic Ring (Europe) (En,Fr,De,Es,It)" - rom ( name "Tom and Jerry - The Magic Ring (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1B7A3819 md5 12F06DF6FF6D6895DC87665FC4C79144 sha1 A221C261B973C9BC859B4C3F45B05C7D77DDF009 flags verified ) + rom ( name "Tom and Jerry - The Magic Ring (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 1b7a3819 sha1 A221C261B973C9BC859B4C3F45B05C7D77DDF009 flags verified ) ) game ( name "Tom and Jerry in Infurnal Escape (USA)" description "Tom and Jerry in Infurnal Escape (USA)" - rom ( name "Tom and Jerry in Infurnal Escape (USA).gba" size 4194304 crc 11156D88 md5 C63EA91402E560B3EDE1242884D72F73 sha1 FC27897D063720867FB21E41FD6642218257A6FB ) + rom ( name "Tom and Jerry in Infurnal Escape (USA).gba" size 4194304 crc 11156d88 sha1 FC27897D063720867FB21E41FD6642218257A6FB ) ) game ( name "Tom and Jerry in Infurnal Escape (Europe) (En,Fr,De,Es,It)" description "Tom and Jerry in Infurnal Escape (Europe) (En,Fr,De,Es,It)" - rom ( name "Tom and Jerry in Infurnal Escape (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2DB83271 md5 72602C894450147CED8161EF48F784D8 sha1 578122AB783D4EE2E35A9B127DAE68D80D1DE2D8 flags verified ) + rom ( name "Tom and Jerry in Infurnal Escape (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 2db83271 sha1 578122AB783D4EE2E35A9B127DAE68D80D1DE2D8 flags verified ) ) game ( name "Tom and Jerry Tales (USA) (En,Fr,Es)" description "Tom and Jerry Tales (USA) (En,Fr,Es)" - rom ( name "Tom and Jerry Tales (USA) (En,Fr,Es).gba" size 8388608 crc AF494F20 md5 37F0505935E85C9CF7EEBDAE533536EF sha1 9412BBB9F2210B840F618B2DC2AA91D60933FEA2 ) + rom ( name "Tom and Jerry Tales (USA) (En,Fr,Es).gba" size 8388608 crc af494f20 sha1 9412BBB9F2210B840F618B2DC2AA91D60933FEA2 ) ) game ( name "Tom and Jerry Tales (Europe) (En,Fr,De,Es,It)" description "Tom and Jerry Tales (Europe) (En,Fr,De,Es,It)" - rom ( name "Tom and Jerry Tales (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5A8D5736 md5 85B02EE02E0FFDA069CCDC9531248CB6 sha1 006A0DB571A9AD376621B0522830B2A8AD60F867 ) + rom ( name "Tom and Jerry Tales (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 5a8d5736 sha1 006A0DB571A9AD376621B0522830B2A8AD60F867 ) ) game ( name "Tom Clancy's Rainbow Six - Rogue Spear (USA) (En,Fr,De,Es,It)" description "Tom Clancy's Rainbow Six - Rogue Spear (USA) (En,Fr,De,Es,It)" - rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 23575BF2 md5 509E3A1FE6284A75C84315A64BD33F43 sha1 6862D369DAF3709A5DE9458CEB3F8200B78B8160 ) + rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (USA) (En,Fr,De,Es,It).gba" size 8388608 crc 23575bf2 sha1 6862D369DAF3709A5DE9458CEB3F8200B78B8160 ) ) game ( name "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It)" description "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It)" - rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6863CE1A md5 E58339B1D1426D9B51AD0B8BAD3E87C3 sha1 092179CD51657A4572FA855EB3E5BC3F46C1D76F flags verified ) + rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6863ce1a sha1 092179CD51657A4572FA855EB3E5BC3F46C1D76F flags verified ) ) game ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" description "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" - rom ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es).gba" size 8388608 crc 308BA69C md5 A980189CFB6200A8A092ECA53C85AF80 sha1 DBD089CBDD79C26B2F0B651F74DF59B6CBFAFBCB flags verified ) + rom ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es).gba" size 8388608 crc 308ba69c sha1 DBD089CBDD79C26B2F0B651F74DF59B6CBFAFBCB flags verified ) ) game ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" description "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7ECD29CE md5 AB7B66435BCECB60A786FD62A532E4AB sha1 D623CBD1019665EEE78846A2A60D17ADAF8EC0FE flags verified ) + rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 7ecd29ce sha1 D623CBD1019665EEE78846A2A60D17ADAF8EC0FE flags verified ) ) game ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta)" - rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 16777216 crc E07BA799 md5 8C130964502931BA6C3D14E1F719A986 sha1 3A55F6ED66A3EC7C019221FA2660E2F85954EBAE ) + rom ( name "Tom Clancy's Splinter Cell (Europe) (En,Fr,De,Es,It,Nl) (Beta).gba" size 16777216 crc e07ba799 sha1 3A55F6ED66A3EC7C019221FA2660E2F85954EBAE ) ) game ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl)" description "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc F007DFE1 md5 5DD27560673DD339F43584F8301A7364 sha1 A9A39953F9C3ADACBB8D75FF5CAF2D828F57CB2B flags verified ) + rom ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc f007dfe1 sha1 A9A39953F9C3ADACBB8D75FF5CAF2D828F57CB2B flags verified ) ) game ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (USA) (En,Fr,Es)" description "Tom Clancy's Splinter Cell - Pandora Tomorrow (USA) (En,Fr,Es)" - rom ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (USA) (En,Fr,Es).gba" size 8388608 crc AEFB7B54 md5 F7B81F0A57DB7206A0F2486491F8A99D sha1 56343BA81D3B83941541E682BE19C34119DFFFF9 ) + rom ( name "Tom Clancy's Splinter Cell - Pandora Tomorrow (USA) (En,Fr,Es).gba" size 8388608 crc aefb7b54 sha1 56343BA81D3B83941541E682BE19C34119DFFFF9 ) ) game ( name "Tomato Adventure (Japan)" description "Tomato Adventure (Japan)" - rom ( name "Tomato Adventure (Japan).gba" size 8388608 crc 3482AD03 md5 19D1378D5EEB4748231BFE03B5D0D6F7 sha1 8772376A8F30DB060915CDC2C19EAECC17BAC043 flags verified ) + rom ( name "Tomato Adventure (Japan).gba" size 8388608 crc e37ca939 sha1 80F7968343E49E4D8A22AFC2771EF26564506F17 flags verified ) +) + +game ( + name "Tongqin Yi Bi (China) (Proto)" + description "Tongqin Yi Bi (China) (Proto)" + rom ( name "Tongqin Yi Bi (China) (Proto).gba" size 4194304 crc d57f7b40 sha1 2D5F1B6DF4CB355E1C3B27CCB83584B9B56EB67F flags verified ) ) game ( name "Tonka - On the Job (USA)" description "Tonka - On the Job (USA)" - rom ( name "Tonka - On the Job (USA).gba" size 4194304 crc DBCD4541 md5 EE91C4582D9B0CC494FCB71173B43E17 sha1 A09C92B9F21D21F58D7C8D3DFFC49F24E210B190 ) + rom ( name "Tonka - On the Job (USA).gba" size 4194304 crc dbcd4541 sha1 A09C92B9F21D21F58D7C8D3DFFC49F24E210B190 ) ) game ( name "Tony Hawk's American Sk8land (USA)" description "Tony Hawk's American Sk8land (USA)" - rom ( name "Tony Hawk's American Sk8land (USA).gba" size 8388608 crc 7B089F4A md5 6408C0C1AF0E89D5408970CFEB744644 sha1 9EF930C0DBF6EA2AE3C0DA95659CA0E2F4FA7B88 ) + rom ( name "Tony Hawk's American Sk8land (USA).gba" size 8388608 crc 7b089f4a sha1 9EF930C0DBF6EA2AE3C0DA95659CA0E2F4FA7B88 ) ) game ( name "Tony Hawk's American Sk8land (Europe) (Fr,De,Es,It)" description "Tony Hawk's American Sk8land (Europe) (Fr,De,Es,It)" - rom ( name "Tony Hawk's American Sk8land (Europe) (Fr,De,Es,It).gba" size 8388608 crc 9633084A md5 5B2675FB3B642CDBEB563672E96480C7 sha1 A51F1D72F136EB43F70620350F7487CC57D7A695 ) + rom ( name "Tony Hawk's American Sk8land (Europe) (Fr,De,Es,It).gba" size 8388608 crc 9633084a sha1 A51F1D72F136EB43F70620350F7487CC57D7A695 ) ) game ( name "Tony Hawk's American Sk8land (Europe)" description "Tony Hawk's American Sk8land (Europe)" - rom ( name "Tony Hawk's American Sk8land (Europe).gba" size 8388608 crc A824DF3F md5 C95509097D14323904489A65D51014AC sha1 14D46D7544F8503273223CAB91DBB2C698987A54 ) + rom ( name "Tony Hawk's American Sk8land (Europe).gba" size 8388608 crc a824df3f sha1 14D46D7544F8503273223CAB91DBB2C698987A54 ) ) game ( name "Tony Hawk's Downhill Jam (USA)" description "Tony Hawk's Downhill Jam (USA)" - rom ( name "Tony Hawk's Downhill Jam (USA).gba" size 16777216 crc 37B0B53D md5 4088FAD3D25305C46072B8865E095EEF sha1 0D40F012093838B667CD3B79CAABB43ADCA8F034 ) + rom ( name "Tony Hawk's Downhill Jam (USA).gba" size 16777216 crc 37b0b53d sha1 0D40F012093838B667CD3B79CAABB43ADCA8F034 ) ) game ( name "Tony Hawk's Downhill Jam (Europe) (En,Fr,De,Es,It)" description "Tony Hawk's Downhill Jam (Europe) (En,Fr,De,Es,It)" - rom ( name "Tony Hawk's Downhill Jam (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4A975F48 md5 A6C6879B9DCF9A67991F4CF81462498C sha1 1D50C04EB8EDE1CF9776E392F0275688ED7F69CB flags verified ) + rom ( name "Tony Hawk's Downhill Jam (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 4a975f48 sha1 1D50C04EB8EDE1CF9776E392F0275688ED7F69CB flags verified ) ) game ( name "Tony Hawk's Pro Skater 2 (USA, Europe)" description "Tony Hawk's Pro Skater 2 (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater 2 (USA, Europe).gba" size 8388608 crc 812DC57A md5 B658A9B8641DB5C1A94D61B6FCC05DA5 sha1 029F8FCABEE3E4E0339DB77C80961191B5BB84E9 flags verified ) + rom ( name "Tony Hawk's Pro Skater 2 (USA, Europe).gba" size 8388608 crc 812dc57a sha1 029F8FCABEE3E4E0339DB77C80961191B5BB84E9 flags verified ) ) game ( name "Tony Hawk's Pro Skater 2 (Germany)" description "Tony Hawk's Pro Skater 2 (Germany)" - rom ( name "Tony Hawk's Pro Skater 2 (Germany).gba" size 8388608 crc 6D236181 md5 111715B064A0DE33D49034937DBC48D8 sha1 81B4562347F1148DB07E48795BDA56F1B1B0A2FA ) + rom ( name "Tony Hawk's Pro Skater 2 (Germany).gba" size 8388608 crc 6d236181 sha1 81B4562347F1148DB07E48795BDA56F1B1B0A2FA ) ) game ( name "Tony Hawk's Pro Skater 2 (France)" description "Tony Hawk's Pro Skater 2 (France)" - rom ( name "Tony Hawk's Pro Skater 2 (France).gba" size 8388608 crc F0EFC9D8 md5 7F9A6636189A1C57276CA6E0A352565B sha1 C66ABC5D705DDBD75359991ECB5CF586471D9D9F ) + rom ( name "Tony Hawk's Pro Skater 2 (France).gba" size 8388608 crc f0efc9d8 sha1 C66ABC5D705DDBD75359991ECB5CF586471D9D9F ) ) game ( name "Tony Hawk's Pro Skater 3 (USA, Europe)" description "Tony Hawk's Pro Skater 3 (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater 3 (USA, Europe).gba" size 8388608 crc F669A368 md5 36916861E921121015366B7D5EC45F3E sha1 D1D6806AC99A29DD3195491A213BEC9023A3ADB4 flags verified ) + rom ( name "Tony Hawk's Pro Skater 3 (USA, Europe).gba" size 8388608 crc f669a368 sha1 D1D6806AC99A29DD3195491A213BEC9023A3ADB4 flags verified ) ) game ( name "Tony Hawk's Pro Skater 3 (France)" description "Tony Hawk's Pro Skater 3 (France)" - rom ( name "Tony Hawk's Pro Skater 3 (France).gba" size 8388608 crc 8D132067 md5 27E4B87CE096AAEA17CC8A63BF9DEEEF sha1 62BA6F28F5BBD8FE42ECABECDCFF4D6B96AE4F21 ) + rom ( name "Tony Hawk's Pro Skater 3 (France).gba" size 8388608 crc 8d132067 sha1 62BA6F28F5BBD8FE42ECABECDCFF4D6B96AE4F21 ) ) game ( name "Tony Hawk's Pro Skater 3 (Germany)" description "Tony Hawk's Pro Skater 3 (Germany)" - rom ( name "Tony Hawk's Pro Skater 3 (Germany).gba" size 8388608 crc 74174675 md5 91926690793D2A63CD382797EB1B35C2 sha1 FBDEF1C6C4704EAE2103BBA4DC85F9284C785DFD ) + rom ( name "Tony Hawk's Pro Skater 3 (Germany).gba" size 8388608 crc 74174675 sha1 FBDEF1C6C4704EAE2103BBA4DC85F9284C785DFD ) ) game ( name "Tony Hawk's Pro Skater 4 (USA, Europe)" description "Tony Hawk's Pro Skater 4 (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater 4 (USA, Europe).gba" size 8388608 crc 8CB0AA77 md5 E78E1F6C6FBE9A614E0406802FC6A7FD sha1 F4BA0BE44899EB8D52869120FBBC4F46E2A3C668 flags verified ) + rom ( name "Tony Hawk's Pro Skater 4 (USA, Europe).gba" size 8388608 crc 8cb0aa77 sha1 F4BA0BE44899EB8D52869120FBBC4F46E2A3C668 flags verified ) ) game ( name "Tony Hawk's Underground (USA, Europe)" description "Tony Hawk's Underground (USA, Europe)" - rom ( name "Tony Hawk's Underground (USA, Europe).gba" size 8388608 crc 1F5149BC md5 CF489B93E646C5F102EF2C8CC8FA64CF sha1 54584741D76D2BD136CC56D5B858F6A3BCD81E0B flags verified ) + rom ( name "Tony Hawk's Underground (USA, Europe).gba" size 8388608 crc 1f5149bc sha1 54584741D76D2BD136CC56D5B858F6A3BCD81E0B flags verified ) ) game ( name "Tony Hawk's Underground 2 (USA, Europe)" description "Tony Hawk's Underground 2 (USA, Europe)" - rom ( name "Tony Hawk's Underground 2 (USA, Europe).gba" size 8388608 crc BF864083 md5 2768C7C1A8478B245CB9B7B6615D50CA sha1 C684D839C32515A99E62B183B607E2259120CFC9 ) + rom ( name "Tony Hawk's Underground 2 (USA, Europe).gba" size 8388608 crc bf864083 sha1 C684D839C32515A99E62B183B607E2259120CFC9 ) ) game ( - name "Tootuff - The Gagmachine (Europe) (En,Fr,De,Es,It) (Proto)" - description "Tootuff - The Gagmachine (Europe) (En,Fr,De,Es,It) (Proto)" - rom ( name "Tootuff - The Gagmachine (Europe) (En,Fr,De,Es,It) (Proto).gba" size 4194304 crc 3E69A610 md5 904F77BB71669AE4E525857AF2C0D23C sha1 C58BDD97903F0B61742516A0CD21BC4551868C30 ) + name "Tootuff - The Gag Machine (Europe) (En,Fr,De,Es,It) (Proto)" + description "Tootuff - The Gag Machine (Europe) (En,Fr,De,Es,It) (Proto)" + rom ( name "Tootuff - The Gag Machine (Europe) (En,Fr,De,Es,It) (Proto).gba" size 4194304 crc 3e69a610 sha1 C58BDD97903F0B61742516A0CD21BC4551868C30 ) ) game ( name "Top Gear GT Championship (Europe)" description "Top Gear GT Championship (Europe)" - rom ( name "Top Gear GT Championship (Europe).gba" size 4194304 crc 391C0497 md5 D2937931C759F1D3F9A4C7F49DCA7261 sha1 C5AF760E0D1269DB4D9799DDA98666F881EF8E5E ) + rom ( name "Top Gear GT Championship (Europe).gba" size 4194304 crc 391c0497 sha1 C5AF760E0D1269DB4D9799DDA98666F881EF8E5E flags verified ) ) game ( name "Top Gear GT Championship (USA)" description "Top Gear GT Championship (USA)" - rom ( name "Top Gear GT Championship (USA).gba" size 4194304 crc 0A9C9968 md5 AD0952BFB34DFEDB56B1A009EA1656DE sha1 B57938E9FD51EFBD88FEBCA6938B961FB7353366 ) + rom ( name "Top Gear GT Championship (USA).gba" size 4194304 crc 0a9c9968 sha1 B57938E9FD51EFBD88FEBCA6938B961FB7353366 ) ) game ( name "Top Gear Rally (Japan)" description "Top Gear Rally (Japan)" - rom ( name "Top Gear Rally (Japan).gba" size 4194304 crc C457C5DB md5 2E368F0E94916E946554B8F3ADE01CA5 sha1 B80EC4CDB53DA2297D234F4A9913DF1CDF01A327 ) + rom ( name "Top Gear Rally (Japan).gba" size 4194304 crc c457c5db sha1 B80EC4CDB53DA2297D234F4A9913DF1CDF01A327 ) ) game ( name "Top Gear Rally (Europe) (En,Fr,De,Es,It)" description "Top Gear Rally (Europe) (En,Fr,De,Es,It)" - rom ( name "Top Gear Rally (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 86AD4007 md5 8D8D61533EE0EBF56AB63ED4BEBF1CCD sha1 5168ED1B2030DF98CD4645A05696E8C5441B5F6F flags verified ) + rom ( name "Top Gear Rally (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 86ad4007 sha1 5168ED1B2030DF98CD4645A05696E8C5441B5F6F flags verified ) ) game ( name "Top Gear Rally (USA)" description "Top Gear Rally (USA)" - rom ( name "Top Gear Rally (USA).gba" size 4194304 crc 4DD90762 md5 53750C05649F7344A5E2FC62C6172C48 sha1 9A6C5D013370E7B3545D5231CFAEE12D0EDC8A7D ) + rom ( name "Top Gear Rally (USA).gba" size 4194304 crc 4dd90762 sha1 9A6C5D013370E7B3545D5231CFAEE12D0EDC8A7D ) ) game ( name "Top Gun - Combat Zones (USA) (En,Fr,De,Es,It)" description "Top Gun - Combat Zones (USA) (En,Fr,De,Es,It)" - rom ( name "Top Gun - Combat Zones (USA) (En,Fr,De,Es,It).gba" size 4194304 crc DFC88D3E md5 F9D40D7C6C31991F44527A236107ACDA sha1 4F6AE177D236657A075E3366ED4F90C97B03F10D ) + rom ( name "Top Gun - Combat Zones (USA) (En,Fr,De,Es,It).gba" size 4194304 crc dfc88d3e sha1 4F6AE177D236657A075E3366ED4F90C97B03F10D ) ) game ( name "Top Gun - Firestorm Advance (USA, Europe) (En,Fr,De,Es,It)" description "Top Gun - Firestorm Advance (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Top Gun - Firestorm Advance (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc FDBE5A26 md5 248D9FA9903D27CD9890E6A08DBD97CF sha1 68CCB866BCB82A1C884EF40D74540E63CE0D5BD1 flags verified ) + rom ( name "Top Gun - Firestorm Advance (USA, Europe) (En,Fr,De,Es,It).gba" size 4194304 crc fdbe5a26 sha1 68CCB866BCB82A1C884EF40D74540E63CE0D5BD1 flags verified ) ) game ( name "Top Spin 2 (USA) (En,Fr,De,Es,It)" description "Top Spin 2 (USA) (En,Fr,De,Es,It)" - rom ( name "Top Spin 2 (USA) (En,Fr,De,Es,It).gba" size 16777216 crc A960D63B md5 94C6EC2DAD53EF7D7EC44B7E438833B8 sha1 16B9FD8CCDDB9853B35138621AB3B7DBC2695089 flags verified ) + rom ( name "Top Spin 2 (USA) (En,Fr,De,Es,It).gba" size 16777216 crc a960d63b sha1 16B9FD8CCDDB9853B35138621AB3B7DBC2695089 flags verified ) ) game ( name "Top Spin 2 (Europe) (En,Fr,De,Es,It)" description "Top Spin 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Top Spin 2 (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc A8E8618B md5 DB472400AD072DFB2BE28C08468A7984 sha1 192BB233840382E410FD242F6B6BFBD33AB24D38 ) + rom ( name "Top Spin 2 (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc a8e8618b sha1 192BB233840382E410FD242F6B6BFBD33AB24D38 ) ) game ( name "Total Soccer Advance (Japan)" description "Total Soccer Advance (Japan)" - rom ( name "Total Soccer Advance (Japan).gba" size 4194304 crc 28C3E211 md5 5635C7E6414AAA49E323436B6313AF3A sha1 3A45D03AC6B098B70641C222F684ABD13EF02500 ) + rom ( name "Total Soccer Advance (Japan).gba" size 4194304 crc 28c3e211 sha1 3A45D03AC6B098B70641C222F684ABD13EF02500 ) ) game ( name "Totally Spies! (Europe) (En,Fr,De,Es,It,Nl)" description "Totally Spies! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Totally Spies! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 06992F1D md5 39E615DDC9695DEB0DAB06DBD98B7841 sha1 359F879F8D4D91101A3C0F6EBC3C97520508AF95 ) + rom ( name "Totally Spies! (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc 06992f1d sha1 359F879F8D4D91101A3C0F6EBC3C97520508AF95 flags verified ) ) game ( name "Totally Spies! (USA)" description "Totally Spies! (USA)" - rom ( name "Totally Spies! (USA).gba" size 8388608 crc AAA6E141 md5 0309E2DDA3EC19EE11C2AFB0C22FF3EF sha1 6452E8F16DEC8DB3D46F24BB242F8223E337CE40 ) + rom ( name "Totally Spies! (USA).gba" size 8388608 crc aaa6e141 sha1 6452E8F16DEC8DB3D46F24BB242F8223E337CE40 ) ) game ( name "Totally Spies! 2 - Undercover (USA) (En,Fr)" description "Totally Spies! 2 - Undercover (USA) (En,Fr)" - rom ( name "Totally Spies! 2 - Undercover (USA) (En,Fr).gba" size 8388608 crc 2C8EB8A1 md5 27AB3AB9D8C3FEE6A38E95BA03FDE194 sha1 C45561593BF49F70A9BFD509009746F795E1121A ) + rom ( name "Totally Spies! 2 - Undercover (USA) (En,Fr).gba" size 8388608 crc 2c8eb8a1 sha1 C45561593BF49F70A9BFD509009746F795E1121A ) ) game ( name "Totally Spies! 2 - Undercover (Europe) (En,Fr,De,Es,It,Nl)" description "Totally Spies! 2 - Undercover (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Totally Spies! 2 - Undercover (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc CA245559 md5 A5775A65801CCDD6C88778262D9A4D0A sha1 FCA3563C20334B215966B4A4F270A03F413517B7 ) + rom ( name "Totally Spies! 2 - Undercover (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc ca245559 sha1 FCA3563C20334B215966B4A4F270A03F413517B7 ) ) game ( name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan)" description "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan)" - rom ( name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan).gba" size 8388608 crc C2945D42 md5 CA4A01416F5528FE6F165981658A4B03 sha1 E9C2B72A88FECB8703D48DA0EA67BF4032BABC96 ) + rom ( name "Tottoko Hamutarou 3 - Love Love Daibouken Dechu (Japan).gba" size 8388608 crc c2945d42 sha1 E9C2B72A88FECB8703D48DA0EA67BF4032BABC96 ) ) game ( name "Tottoko Hamutarou 4 - Nijiiro Daikoushin Dechu (Japan)" description "Tottoko Hamutarou 4 - Nijiiro Daikoushin Dechu (Japan)" - rom ( name "Tottoko Hamutarou 4 - Nijiiro Daikoushin Dechu (Japan).gba" size 8388608 crc 1B6E5617 md5 44A73FF6AC352C860EBB08625D1ABDB2 sha1 B18C228E45D4CC8F0E1F58FA139AF18E966C55F6 ) + rom ( name "Tottoko Hamutarou 4 - Nijiiro Daikoushin Dechu (Japan).gba" size 8388608 crc 1b6e5617 sha1 B18C228E45D4CC8F0E1F58FA139AF18E966C55F6 flags verified ) ) game ( name "Touhai Densetsu Akagi - Yami ni Mai Orita Tensai (Japan)" description "Touhai Densetsu Akagi - Yami ni Mai Orita Tensai (Japan)" - rom ( name "Touhai Densetsu Akagi - Yami ni Mai Orita Tensai (Japan).gba" size 16777216 crc 14EB6587 md5 E711F571AE5BDBACB4ED497C759D074D sha1 EA25201B0DB54C18E0476ACB017DAF57BCDD2AB0 ) + rom ( name "Touhai Densetsu Akagi - Yami ni Mai Orita Tensai (Japan).gba" size 16777216 crc 14eb6587 sha1 EA25201B0DB54C18E0476ACB017DAF57BCDD2AB0 ) ) game ( name "Toukon Heat (Japan)" description "Toukon Heat (Japan)" - rom ( name "Toukon Heat (Japan).gba" size 8388608 crc 4043F1E0 md5 7BCE16D42E091BF43CDAA01054DB6757 sha1 5DC55476F13E941B5464E3ECB7C67299FDE681AD ) + rom ( name "Toukon Heat (Japan).gba" size 8388608 crc 4043f1e0 sha1 5DC55476F13E941B5464E3ECB7C67299FDE681AD ) ) game ( name "Tower SP, The (Japan)" description "Tower SP, The (Japan)" - rom ( name "Tower SP, The (Japan).gba" size 8388608 crc EC325C92 md5 A5B5B2B18363D37560F48A2FFF83F471 sha1 287286F6FB0E405FCF57B35EEF99139445B663C6 flags verified ) + rom ( name "Tower SP, The (Japan).gba" size 8388608 crc ec325c92 sha1 287286F6FB0E405FCF57B35EEF99139445B663C6 flags verified ) ) game ( name "Tower SP, The (USA)" description "Tower SP, The (USA)" - rom ( name "Tower SP, The (USA).gba" size 8388608 crc 95E05895 md5 8E825B6048A72649A9B672858BFC388C sha1 5E338F55B4D2604F381165CC693E4D774C82AEDB ) + rom ( name "Tower SP, The (USA).gba" size 8388608 crc 95e05895 sha1 5E338F55B4D2604F381165CC693E4D774C82AEDB ) ) game ( name "Toyrobo Force (Japan)" description "Toyrobo Force (Japan)" - rom ( name "Toyrobo Force (Japan).gba" size 4194304 crc 227FC16B md5 8E5B4BB736B5030CF13052634D01EF69 sha1 6EF30145099D09CF1A1F2B3BC6618A985DABDAAE ) + rom ( name "Toyrobo Force (Japan).gba" size 4194304 crc 227fc16b sha1 6EF30145099D09CF1A1F2B3BC6618A985DABDAAE ) ) game ( name "Treasure Planet (USA)" description "Treasure Planet (USA)" - rom ( name "Treasure Planet (USA).gba" size 8388608 crc 8B14F9EC md5 2A47D9DA2A8653F65F2A23D8052EFE8C sha1 5D76AB06E6433604F5070BA78B5448F81C6C7A04 ) + rom ( name "Treasure Planet (USA).gba" size 8388608 crc 8b14f9ec sha1 5D76AB06E6433604F5070BA78B5448F81C6C7A04 ) ) game ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl)" description "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc D52DDCE1 md5 D90C08EE30985BF120D394BDD98E2693 sha1 D89A2515F4FE0D0AC90B20E4633A80A2549175FC ) + rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc d52ddce1 sha1 D89A2515F4FE0D0AC90B20E4633A80A2549175FC ) ) game ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" description "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1)" - rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 794B2602 md5 FA19435D7060761379F5583FD95E1D24 sha1 C703EDAEE8A2BAD09C2298E2C92A14D459FE664A ) + rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl) (Rev 1).gba" size 8388608 crc 794b2602 sha1 C703EDAEE8A2BAD09C2298E2C92A14D459FE664A flags verified ) ) game ( name "Trick Star (Europe) (En,Fr,De,Es,It)" description "Trick Star (Europe) (En,Fr,De,Es,It)" - rom ( name "Trick Star (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 961260AE md5 4BFCCB544DC5F02581CC574859A82BCB sha1 9B5F40C8855583084D321A05F7C18453514E1B34 ) + rom ( name "Trick Star (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 961260ae sha1 9B5F40C8855583084D321A05F7C18453514E1B34 ) ) game ( name "Tringo (USA)" description "Tringo (USA)" - rom ( name "Tringo (USA).gba" size 4194304 crc 2956A0DA md5 E352BCEA86303C8CD501BECA590D2087 sha1 75052EDA6A929C1BF41EB5566FCD854A6D0F1FC9 ) + rom ( name "Tringo (USA).gba" size 4194304 crc 2956a0da sha1 75052EDA6A929C1BF41EB5566FCD854A6D0F1FC9 ) ) game ( name "Tringo (Europe) (En,Fr,De,Es,It)" description "Tringo (Europe) (En,Fr,De,Es,It)" - rom ( name "Tringo (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc B5F7BF43 md5 702ADCEEC8C8AB1EE27917E75448BBF6 sha1 67E4AF4D3C06FCF07F8C1A97F47F8BDCF5A3AC73 ) + rom ( name "Tringo (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc b5f7bf43 sha1 67E4AF4D3C06FCF07F8C1A97F47F8BDCF5A3AC73 ) ) game ( name "Trollz - Hair Affair! (USA)" description "Trollz - Hair Affair! (USA)" - rom ( name "Trollz - Hair Affair! (USA).gba" size 8388608 crc C5CD2C22 md5 243CD8CE513DA13EEED632A3A8D3D153 sha1 5AB8BBEDE98A46BC24D6532F837482C3BBFF9762 ) + rom ( name "Trollz - Hair Affair! (USA).gba" size 8388608 crc c5cd2c22 sha1 5AB8BBEDE98A46BC24D6532F837482C3BBFF9762 ) ) game ( name "Trollz - Hair Affair! (Europe) (En,De,It)" description "Trollz - Hair Affair! (Europe) (En,De,It)" - rom ( name "Trollz - Hair Affair! (Europe) (En,De,It).gba" size 8388608 crc FB2284EF md5 BD2163EC09C9986FFFDCFEDB94C46C34 sha1 EE8653A4DA6402554413580258EB2A04D5C17384 ) + rom ( name "Trollz - Hair Affair! (Europe) (En,De,It).gba" size 8388608 crc fb2284ef sha1 EE8653A4DA6402554413580258EB2A04D5C17384 ) ) game ( name "Trollz - Hair Affair! (Europe) (En,Fr,Es)" description "Trollz - Hair Affair! (Europe) (En,Fr,Es)" - rom ( name "Trollz - Hair Affair! (Europe) (En,Fr,Es).gba" size 8388608 crc 14FEA5C0 md5 003A6851C61CC1981427248D57BA41FE sha1 F51CA82847EF40F31A4BBBEF726921B310EAF72B ) + rom ( name "Trollz - Hair Affair! (Europe) (En,Fr,Es).gba" size 8388608 crc 14fea5c0 sha1 F51CA82847EF40F31A4BBBEF726921B310EAF72B ) ) game ( name "Trollz - Hair Affair! (Europe)" description "Trollz - Hair Affair! (Europe)" - rom ( name "Trollz - Hair Affair! (Europe).gba" size 8388608 crc 3E0ED609 md5 A573F9A77A0A118F111E63880569BF1D sha1 3F55B91D085347A4E3DD80DEE17C2E4FC899151D ) + rom ( name "Trollz - Hair Affair! (Europe).gba" size 8388608 crc 3e0ed609 sha1 3F55B91D085347A4E3DD80DEE17C2E4FC899151D ) ) game ( name "Tron 2.0 - Killer App (USA)" description "Tron 2.0 - Killer App (USA)" - rom ( name "Tron 2.0 - Killer App (USA).gba" size 16777216 crc 77D50EC6 md5 5C332A3E712B41E8CF61240034B8D4C4 sha1 F75BB043C627A5E2DF99CBF6B55DDA5574738358 ) + rom ( name "Tron 2.0 - Killer App (USA).gba" size 16777216 crc 77d50ec6 sha1 F75BB043C627A5E2DF99CBF6B55DDA5574738358 ) ) game ( name "Tron 2.0 - Killer App (Europe)" description "Tron 2.0 - Killer App (Europe)" - rom ( name "Tron 2.0 - Killer App (Europe).gba" size 16777216 crc 3BF38352 md5 6D36B3E2EA32702BBE2C9FF16426A644 sha1 1153F6D3E60D481D71A6741B1F869CA26BC17C54 ) + rom ( name "Tron 2.0 - Killer App (Europe).gba" size 16777216 crc 3bf38352 sha1 1153F6D3E60D481D71A6741B1F869CA26BC17C54 ) ) game ( name "Tsuukin Hitofude (Japan)" description "Tsuukin Hitofude (Japan)" - rom ( name "Tsuukin Hitofude (Japan).gba" size 4194304 crc 5A7E762B md5 68C38C871CB58802077D3AC695113F15 sha1 18DFEE7E1ED1E53C70F3686276524A0723EEC741 flags verified ) + rom ( name "Tsuukin Hitofude (Japan).gba" size 4194304 crc 5a7e762b sha1 18DFEE7E1ED1E53C70F3686276524A0723EEC741 flags verified ) +) + +game ( + name "Tsuukin Hitofude (Japan) (Wii U Virtual Console)" + description "Tsuukin Hitofude (Japan) (Wii U Virtual Console)" + rom ( name "Tsuukin Hitofude (Japan) (Wii U Virtual Console).gba" size 4194304 crc f4c7a95b sha1 906DBF246CB40954FC27942763048BC09783B1F8 flags verified ) ) game ( name "Turbo Turtle Adventure (USA)" description "Turbo Turtle Adventure (USA)" - rom ( name "Turbo Turtle Adventure (USA).gba" size 4194304 crc E5E0B0F1 md5 9B72E0259BE5E4ADDDD2FED212C9FDE7 sha1 92AAE76DEB40A3D63E99C4981DEC7E790A67EBCA ) + rom ( name "Turbo Turtle Adventure (USA).gba" size 4194304 crc e5e0b0f1 sha1 92AAE76DEB40A3D63E99C4981DEC7E790A67EBCA ) ) game ( - name "Turok Evolution (Europe) (En,Fr,De,Es,It)" - description "Turok Evolution (Europe) (En,Fr,De,Es,It)" - rom ( name "Turok Evolution (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 07A32299 md5 74EB3F183512C83C72473A6A03662E03 sha1 30489D1C72FAAB5ED7A7B86C459D750DAE0208E4 flags verified ) + name "Turok - Evolution (Europe) (En,Fr,De,Es,It)" + description "Turok - Evolution (Europe) (En,Fr,De,Es,It)" + rom ( name "Turok - Evolution (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 07a32299 sha1 30489D1C72FAAB5ED7A7B86C459D750DAE0208E4 flags verified ) ) game ( - name "Turok Evolution (USA)" - description "Turok Evolution (USA)" - rom ( name "Turok Evolution (USA).gba" size 8388608 crc 4EDAC27A md5 04524B68642568798AF10A69FC199AAD sha1 F7B9BF3C3509581FA5ECBA92897FBBDF5221BB39 ) + name "Turok - Evolution (USA)" + description "Turok - Evolution (USA)" + rom ( name "Turok - Evolution (USA).gba" size 8388608 crc 4edac27a sha1 F7B9BF3C3509581FA5ECBA92897FBBDF5221BB39 ) +) + +game ( + name "Turok Advance (Unknown) (Proto) (Earlier)" + description "Turok Advance (Unknown) (Proto) (Earlier)" + rom ( name "Turok Advance (Unknown) (Proto) (Earlier).gba" size 3690631 crc 401e10ea sha1 74BAEBEF55A8D7A8801EF8A0A657C4E00D5CF003 flags verified ) +) + +game ( + name "Turok Advance (Unknown) (Proto) (Dark Version)" + description "Turok Advance (Unknown) (Proto) (Dark Version)" + rom ( name "Turok Advance (Unknown) (Proto) (Dark Version).gba" size 4830098 crc 378d6da7 sha1 F5271FA4EBD4765E773B3F50AC07A302F4DC962F flags verified ) +) + +game ( + name "Turok Advance (Unknown) (Proto) (Bright Version)" + description "Turok Advance (Unknown) (Proto) (Bright Version)" + rom ( name "Turok Advance (Unknown) (Proto) (Bright Version).gba" size 4830066 crc 9ef46f34 sha1 0AC2516AF0EE72136D104E159482353E3E228C7F flags verified ) ) game ( name "Tweety and the Magic Gems (Europe)" description "Tweety and the Magic Gems (Europe)" - rom ( name "Tweety and the Magic Gems (Europe).gba" size 4194304 crc 024A1914 md5 8E4687980914D70581C376F084ED8E06 sha1 CB84C231D1FE8DDE73D4D2E7F0F9BE72699FF8CF flags verified ) + rom ( name "Tweety and the Magic Gems (Europe).gba" size 4194304 crc 024a1914 sha1 CB84C231D1FE8DDE73D4D2E7F0F9BE72699FF8CF flags verified ) ) game ( name "Tweety and the Magic Gems (Germany)" description "Tweety and the Magic Gems (Germany)" - rom ( name "Tweety and the Magic Gems (Germany).gba" size 4194304 crc 8AA6E91A md5 8AD8A16C66C9A755137635D84B08D5E9 sha1 2FCB5D25C0F31F2C3247C2743F5A635159AA528B ) + rom ( name "Tweety and the Magic Gems (Germany).gba" size 4194304 crc 8aa6e91a sha1 2FCB5D25C0F31F2C3247C2743F5A635159AA528B ) ) game ( name "Tweety and the Magic Gems (USA)" description "Tweety and the Magic Gems (USA)" - rom ( name "Tweety and the Magic Gems (USA).gba" size 4194304 crc 2DA5C91E md5 2A76E96BE1FDB58EA4E4BAFA62556A5A sha1 CB892AC87EE4FCD627949D23CE66ACD56EC00FEB ) + rom ( name "Tweety and the Magic Gems (USA).gba" size 4194304 crc 2da5c91e sha1 CB892AC87EE4FCD627949D23CE66ACD56EC00FEB ) +) + +game ( + name "Tweety and the Magic Gems (Netherlands)" + description "Tweety and the Magic Gems (Netherlands)" + rom ( name "Tweety and the Magic Gems (Netherlands).gba" size 4194304 crc f1a49d56 sha1 BEE090519538CB539FC1A5A9F66130F53418888A flags verified ) ) game ( name "Tweety no Hearty Party (Japan)" description "Tweety no Hearty Party (Japan)" - rom ( name "Tweety no Hearty Party (Japan).gba" size 4194304 crc D38672BF md5 0EA86808A1E0201968357E8B9BF282E8 sha1 0D657EA9F3BA15968659DDDB61C223D004C02DEC ) + rom ( name "Tweety no Hearty Party (Japan).gba" size 4194304 crc d38672bf sha1 0D657EA9F3BA15968659DDDB61C223D004C02DEC ) ) game ( name "Twin Series 1 - Mezase Debut! - Fashion Designer Monogatari + Kawaii Pet Game Gallery 2 (Japan)" description "Twin Series 1 - Mezase Debut! - Fashion Designer Monogatari + Kawaii Pet Game Gallery 2 (Japan)" - rom ( name "Twin Series 1 - Mezase Debut! - Fashion Designer Monogatari + Kawaii Pet Game Gallery 2 (Japan).gba" size 16777216 crc 09F5E672 md5 822D86DF5F0E5A04B051142A53F16820 sha1 E7BD515074DB9785255CA9E7CB70FF92944257B4 flags verified ) + rom ( name "Twin Series 1 - Mezase Debut! - Fashion Designer Monogatari + Kawaii Pet Game Gallery 2 (Japan).gba" size 16777216 crc 09f5e672 sha1 E7BD515074DB9785255CA9E7CB70FF92944257B4 flags verified ) ) game ( name "Twin Series 2 - Oshare Princess 4 + Renai Uranai Daisakusen! + Renai Party Game - Sweet Heart (Japan)" description "Twin Series 2 - Oshare Princess 4 + Renai Uranai Daisakusen! + Renai Party Game - Sweet Heart (Japan)" - rom ( name "Twin Series 2 - Oshare Princess 4 + Renai Uranai Daisakusen! + Renai Party Game - Sweet Heart (Japan).gba" size 8388608 crc 8B0EB948 md5 19BF7F61B8F684B92CD746A8575A6A83 sha1 A53453524F152317BA974DB0A45E00719A19203A ) + rom ( name "Twin Series 2 - Oshare Princess 4 + Renai Uranai Daisakusen! + Renai Party Game - Sweet Heart (Japan).gba" size 8388608 crc 8b0eb948 sha1 A53453524F152317BA974DB0A45E00719A19203A ) ) game ( name "Twin Series 3 - Konchuu Monster - Ouja Ketteisen + Super Chinese Labyrinth (Japan)" description "Twin Series 3 - Konchuu Monster - Ouja Ketteisen + Super Chinese Labyrinth (Japan)" - rom ( name "Twin Series 3 - Konchuu Monster - Ouja Ketteisen + Super Chinese Labyrinth (Japan).gba" size 8388608 crc 68237519 md5 03B199DB52C1470618FAAD2CF93EEEA0 sha1 528CD638479B2568E1CA633641ADA447D2B1D2A7 ) + rom ( name "Twin Series 3 - Konchuu Monster - Ouja Ketteisen + Super Chinese Labyrinth (Japan).gba" size 8388608 crc 68237519 sha1 528CD638479B2568E1CA633641ADA447D2B1D2A7 ) ) game ( name "Twin Series 4 - Hamu Hamu Monster EX - Hamster Monogatari RPG + Fantasy Puzzle - Hamster Monogatari - Mahou no Meikyuu 1.2.3 (Japan)" description "Twin Series 4 - Hamu Hamu Monster EX - Hamster Monogatari RPG + Fantasy Puzzle - Hamster Monogatari - Mahou no Meikyuu 1.2.3 (Japan)" - rom ( name "Twin Series 4 - Hamu Hamu Monster EX - Hamster Monogatari RPG + Fantasy Puzzle - Hamster Monogatari - Mahou no Meikyuu 1.2.3 (Japan).gba" size 16777216 crc FA643377 md5 5EDE045A084EF5EEB5D46807BDF16D57 sha1 8B9F58C8C8A596DE233A97E7E104E6C2DF3B9595 ) + rom ( name "Twin Series 4 - Hamu Hamu Monster EX - Hamster Monogatari RPG + Fantasy Puzzle - Hamster Monogatari - Mahou no Meikyuu 1.2.3 (Japan).gba" size 16777216 crc fa643377 sha1 8B9F58C8C8A596DE233A97E7E104E6C2DF3B9595 ) ) game ( name "Twin Series 5 - Mahou no Kuni no Cake-ya-san Monogatari + Wanwan Meitantei EX (Japan)" description "Twin Series 5 - Mahou no Kuni no Cake-ya-san Monogatari + Wanwan Meitantei EX (Japan)" - rom ( name "Twin Series 5 - Mahou no Kuni no Cake-ya-san Monogatari + Wanwan Meitantei EX (Japan).gba" size 16777216 crc 2C582FF3 md5 113022C562FBD4EB723341B4B05CC7EC sha1 EAF8E1918BCD2AB3A0ABB6A88B63BA0C98EFC1FF ) + rom ( name "Twin Series 5 - Mahou no Kuni no Cake-ya-san Monogatari + Wanwan Meitantei EX (Japan).gba" size 16777216 crc 2c582ff3 sha1 EAF8E1918BCD2AB3A0ABB6A88B63BA0C98EFC1FF flags verified ) ) game ( name "Twin Series 6 - Wannyan Idol Gakuen + Koinu to Issho Special (Japan)" description "Twin Series 6 - Wannyan Idol Gakuen + Koinu to Issho Special (Japan)" - rom ( name "Twin Series 6 - Wannyan Idol Gakuen + Koinu to Issho Special (Japan).gba" size 8388608 crc 9370623D md5 A37AACE8FEF3098138B045EB26493730 sha1 6BCFC89B73E70A14AE14F97A73ED1CF4CBDF5763 ) + rom ( name "Twin Series 6 - Wannyan Idol Gakuen + Koinu to Issho Special (Japan).gba" size 8388608 crc 9370623d sha1 6BCFC89B73E70A14AE14F97A73ED1CF4CBDF5763 ) ) game ( name "Twin Series 7 - Twin Puzzle - Kisekae Wanko EX + Nyaa to Chuu no Rainbow Magic 2 (Japan)" description "Twin Series 7 - Twin Puzzle - Kisekae Wanko EX + Nyaa to Chuu no Rainbow Magic 2 (Japan)" - rom ( name "Twin Series 7 - Twin Puzzle - Kisekae Wanko EX + Nyaa to Chuu no Rainbow Magic 2 (Japan).gba" size 4194304 crc 3C91B0A0 md5 E6340417ACFFD03920F9C8211ABD72C5 sha1 126F42A9C73F65B634D5948CBD1796CEB92B87E9 ) + rom ( name "Twin Series 7 - Twin Puzzle - Kisekae Wanko EX + Nyaa to Chuu no Rainbow Magic 2 (Japan).gba" size 4194304 crc 3c91b0a0 sha1 126F42A9C73F65B634D5948CBD1796CEB92B87E9 ) ) game ( name "Ty the Tasmanian Tiger 2 - Bush Rescue (USA, Europe) (En,Fr,De)" description "Ty the Tasmanian Tiger 2 - Bush Rescue (USA, Europe) (En,Fr,De)" - rom ( name "Ty the Tasmanian Tiger 2 - Bush Rescue (USA, Europe) (En,Fr,De).gba" size 8388608 crc 108C3535 md5 56424A475E1171E608FDAAF3883C3CF9 sha1 84267CE3D86100688048A8D4F166FA1B2D50E6D5 ) + rom ( name "Ty the Tasmanian Tiger 2 - Bush Rescue (USA, Europe) (En,Fr,De).gba" size 8388608 crc 108c3535 sha1 84267CE3D86100688048A8D4F166FA1B2D50E6D5 ) ) game ( name "Ty the Tasmanian Tiger 3 - Night of the Quinkan (USA)" description "Ty the Tasmanian Tiger 3 - Night of the Quinkan (USA)" - rom ( name "Ty the Tasmanian Tiger 3 - Night of the Quinkan (USA).gba" size 8388608 crc CF467E1B md5 5CBCA58A164385A5B256FFF5C27B7F38 sha1 07FAFA1C96CC039A1788D6526D52F7D3EC0BA3C3 ) + rom ( name "Ty the Tasmanian Tiger 3 - Night of the Quinkan (USA).gba" size 8388608 crc cf467e1b sha1 07FAFA1C96CC039A1788D6526D52F7D3EC0BA3C3 ) ) game ( name "Tyrian 2000 (USA) (Proto)" description "Tyrian 2000 (USA) (Proto)" - rom ( name "Tyrian 2000 (USA) (Proto).gba" size 2681544 crc E5ACBA28 md5 15B3055351B71B4AE9F17431D1E8707A sha1 5148F40A58BC3D4512ACED0F052F64B8C883BA87 ) + rom ( name "Tyrian 2000 (USA) (Proto).gba" size 2681544 crc e5acba28 sha1 5148F40A58BC3D4512ACED0F052F64B8C883BA87 flags verified ) ) game ( name "Uchuu Daisakusen Choco Vader - Uchuu kara no Shinryakusha (Japan)" description "Uchuu Daisakusen Choco Vader - Uchuu kara no Shinryakusha (Japan)" - rom ( name "Uchuu Daisakusen Choco Vader - Uchuu kara no Shinryakusha (Japan).gba" size 8388608 crc 5A211B60 md5 BB5DEE8FC2975C9EF1EDFEE65CBBC566 sha1 54DFF080E83B5C09FA314AFBE710205CBC30C28D ) + rom ( name "Uchuu Daisakusen Choco Vader - Uchuu kara no Shinryakusha (Japan).gba" size 8388608 crc 5a211b60 sha1 54DFF080E83B5C09FA314AFBE710205CBC30C28D flags verified ) ) game ( name "Uchuu no Stellvia (Japan)" description "Uchuu no Stellvia (Japan)" - rom ( name "Uchuu no Stellvia (Japan).gba" size 8388608 crc A00A4530 md5 BD02742B2822021FFB3C2D87929F1571 sha1 E2A0A51281D4444357A9C94C678A8DF66E710C3F ) + rom ( name "Uchuu no Stellvia (Japan).gba" size 8388608 crc a00a4530 sha1 E2A0A51281D4444357A9C94C678A8DF66E710C3F ) ) game ( name "Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle (Japan)" description "Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle (Japan)" - rom ( name "Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle (Japan).gba" size 8388608 crc ED368EF1 md5 D428B84DCE8F74A485A3F6C8A20DC4B3 sha1 9CCB015395BA5CECDFB33D1C50EB44B6AD4D86A8 ) + rom ( name "Ueki no Housoku - Jingi Sakuretsu! Nouryokusha Battle (Japan).gba" size 8388608 crc ed368ef1 sha1 9CCB015395BA5CECDFB33D1C50EB44B6AD4D86A8 ) ) game ( name "Ui-Ire - World Soccer Winning Eleven (Japan)" description "Ui-Ire - World Soccer Winning Eleven (Japan)" - rom ( name "Ui-Ire - World Soccer Winning Eleven (Japan).gba" size 8388608 crc 31B1A586 md5 187A5494F83D9E31E0485DC971A727D4 sha1 CE7BE617DE6558C823B6CA77AF8CE2E14EA230C7 ) + rom ( name "Ui-Ire - World Soccer Winning Eleven (Japan).gba" size 8388608 crc 31b1a586 sha1 CE7BE617DE6558C823B6CA77AF8CE2E14EA230C7 ) ) game ( name "Ultimate Arcade Games (USA)" description "Ultimate Arcade Games (USA)" - rom ( name "Ultimate Arcade Games (USA).gba" size 4194304 crc 264F7A95 md5 2F681730742C52625D237E610CE6DE7E sha1 74650C32D727C85D5E78C903949F6937EA9F3EE7 ) + rom ( name "Ultimate Arcade Games (USA).gba" size 4194304 crc 264f7a95 sha1 74650C32D727C85D5E78C903949F6937EA9F3EE7 ) ) game ( name "Ultimate Beach Soccer (USA)" description "Ultimate Beach Soccer (USA)" - rom ( name "Ultimate Beach Soccer (USA).gba" size 4194304 crc 5D4D88C5 md5 D14CF631928FC1523B49C9AE0A2CDD2F sha1 8D21A404042C2B3C5FD1F6F1B6A28C7C6FF72DD7 ) + rom ( name "Ultimate Beach Soccer (USA).gba" size 4194304 crc 5d4d88c5 sha1 8D21A404042C2B3C5FD1F6F1B6A28C7C6FF72DD7 ) ) game ( name "Ultimate Brain Games (USA, Europe)" description "Ultimate Brain Games (USA, Europe)" - rom ( name "Ultimate Brain Games (USA, Europe).gba" size 4194304 crc B6C9F401 md5 AB1BB302CA8DBBB2066491E686F32D3E sha1 A33672E32622E417C9EA93B381D18BD48A93C7E7 flags verified ) + rom ( name "Ultimate Brain Games (USA, Europe).gba" size 4194304 crc b6c9f401 sha1 A33672E32622E417C9EA93B381D18BD48A93C7E7 flags verified ) ) game ( name "Ultimate Card Games (USA, Europe)" description "Ultimate Card Games (USA, Europe)" - rom ( name "Ultimate Card Games (USA, Europe).gba" size 4194304 crc 8A0831BD md5 05271B3C67AAA0A36FCDF723364A8C46 sha1 22FB775D4B2673FF00877170FBC028B9696E4F8E flags verified ) + rom ( name "Ultimate Card Games (USA, Europe).gba" size 4194304 crc 8a0831bd sha1 22FB775D4B2673FF00877170FBC028B9696E4F8E flags verified ) +) + +game ( + name "Ultimate Card Games (USA) (Rev 2)" + description "Ultimate Card Games (USA) (Rev 2)" + rom ( name "Ultimate Card Games (USA) (Rev 2).gba" size 4194304 crc 94863423 sha1 B44A36EF8B76D220172750650095ED2A3F3693EA flags verified ) +) + +game ( + name "Ultimate Card Games (USA) (Rev 1)" + description "Ultimate Card Games (USA) (Rev 1)" + rom ( name "Ultimate Card Games (USA) (Rev 1).gba" size 4194304 crc 300f5d25 sha1 CD1CAA649BDFA43C838AAC8370D0E00CA746AB8A flags verified ) ) game ( name "Ultimate Muscle - The Kinnikuman Legacy - The Path of the Superhero (USA)" description "Ultimate Muscle - The Kinnikuman Legacy - The Path of the Superhero (USA)" - rom ( name "Ultimate Muscle - The Kinnikuman Legacy - The Path of the Superhero (USA).gba" size 16777216 crc BB85AD55 md5 A4E4230BAF0E3B819C84EAE58097CDB0 sha1 D502AB791843D2359726983032390CE037894C67 flags verified ) + rom ( name "Ultimate Muscle - The Kinnikuman Legacy - The Path of the Superhero (USA).gba" size 16777216 crc bb85ad55 sha1 D502AB791843D2359726983032390CE037894C67 flags verified ) ) game ( name "Ultimate Puzzle Games (USA)" description "Ultimate Puzzle Games (USA)" - rom ( name "Ultimate Puzzle Games (USA).gba" size 4194304 crc A13F76A5 md5 1EDB0B88EE507F5176900C419C52B570 sha1 EB3698C554BAC2EBA6E8CBD310E8414B7E6FBA98 ) + rom ( name "Ultimate Puzzle Games (USA).gba" size 4194304 crc a13f76a5 sha1 EB3698C554BAC2EBA6E8CBD310E8414B7E6FBA98 ) ) game ( name "Ultimate Spider-Man (USA)" description "Ultimate Spider-Man (USA)" - rom ( name "Ultimate Spider-Man (USA).gba" size 16777216 crc 931E2C18 md5 11BEB7FD8CE6C8A3D4987274835E0843 sha1 1F5959B66DAFB33C9FA01389C23214B38B0FCC79 ) + rom ( name "Ultimate Spider-Man (USA).gba" size 16777216 crc 931e2c18 sha1 1F5959B66DAFB33C9FA01389C23214B38B0FCC79 ) ) game ( name "Ultimate Spider-Man (Europe) (Fr,De,Es,It)" description "Ultimate Spider-Man (Europe) (Fr,De,Es,It)" - rom ( name "Ultimate Spider-Man (Europe) (Fr,De,Es,It).gba" size 16777216 crc 61A74634 md5 0527C2EDB2832E8D59BAAA4C4FB7B1E7 sha1 317F3D3399967D43DAA393979C94991DA8D416DF ) + rom ( name "Ultimate Spider-Man (Europe) (Fr,De,Es,It).gba" size 16777216 crc 61a74634 sha1 317F3D3399967D43DAA393979C94991DA8D416DF ) ) game ( name "Ultimate Spider-Man (Europe)" description "Ultimate Spider-Man (Europe)" - rom ( name "Ultimate Spider-Man (Europe).gba" size 16777216 crc 97E1727F md5 4959E99CBEC8FEC7E2144A14EAE386D0 sha1 5DB15933AC18877A61BF8DF4D1ACED51035A7D84 flags verified ) + rom ( name "Ultimate Spider-Man (Europe).gba" size 16777216 crc 97e1727f sha1 5DB15933AC18877A61BF8DF4D1ACED51035A7D84 flags verified ) ) game ( name "Ultimate Winter Games (USA)" description "Ultimate Winter Games (USA)" - rom ( name "Ultimate Winter Games (USA).gba" size 8388608 crc 95988EE2 md5 7D8682E1193F8C6D1B0EB9E182D3165E sha1 90368346C52EC8CDBD134D370839DE158A135EEB ) + rom ( name "Ultimate Winter Games (USA).gba" size 8388608 crc 95988ee2 sha1 90368346C52EC8CDBD134D370839DE158A135EEB ) ) game ( name "Ultra Keibitai - Monster Attack (Japan)" description "Ultra Keibitai - Monster Attack (Japan)" - rom ( name "Ultra Keibitai - Monster Attack (Japan).gba" size 8388608 crc C03785C7 md5 D4D5B7D5370BE6CD8C695EC5483F676E sha1 EB446DB23BFC128211E6CD6EFD0CD8E2B90D41AE ) + rom ( name "Ultra Keibitai - Monster Attack (Japan).gba" size 8388608 crc c03785c7 sha1 EB446DB23BFC128211E6CD6EFD0CD8E2B90D41AE ) ) game ( name "Unfabulous (USA)" description "Unfabulous (USA)" - rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547F3A1 md5 74EA809AEA3E45D9638C2997BB5D0A3D sha1 A56E96A46ED7264BDDBFC132925D291E3E8F0E38 flags verified ) + rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547f3a1 sha1 A56E96A46ED7264BDDBFC132925D291E3E8F0E38 flags verified ) ) game ( name "Unglaublichen, Die (Germany)" description "Unglaublichen, Die (Germany)" - rom ( name "Unglaublichen, Die (Germany).gba" size 8388608 crc BDC06E57 md5 43D5D773BD64E23615C0B84A40A3D443 sha1 6BC89E6AA6CD251D56FE86E520B08CADF20CA4F4 ) + rom ( name "Unglaublichen, Die (Germany).gba" size 8388608 crc bdc06e57 sha1 6BC89E6AA6CD251D56FE86E520B08CADF20CA4F4 ) ) game ( name "Uno 52 (USA)" description "Uno 52 (USA)" - rom ( name "Uno 52 (USA).gba" size 4194304 crc C659C6DB md5 DE44E3AE64659ABA9824D0047C381981 sha1 CFFF9DD74BE1D46F6787FE0403F2DEA633481617 ) + rom ( name "Uno 52 (USA).gba" size 4194304 crc c659c6db sha1 CFFF9DD74BE1D46F6787FE0403F2DEA633481617 ) ) game ( name "Uno 52 (Europe) (En,Fr,De,Es,It)" description "Uno 52 (Europe) (En,Fr,De,Es,It)" - rom ( name "Uno 52 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 315360D0 md5 DF60EA476F585692BFB05D77EA833342 sha1 F85709EC7A97C8B40504F2097497BD961531272D ) + rom ( name "Uno 52 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 315360d0 sha1 F85709EC7A97C8B40504F2097497BD961531272D ) ) game ( name "Uno Free Fall (USA)" description "Uno Free Fall (USA)" - rom ( name "Uno Free Fall (USA).gba" size 4194304 crc 19FCC78E md5 6EA2C5E69EF027C80C54A6B231706FAB sha1 2DACF03965EE248D414D385594CC919F896F032E ) + rom ( name "Uno Free Fall (USA).gba" size 4194304 crc 19fcc78e sha1 2DACF03965EE248D414D385594CC919F896F032E ) ) game ( name "Uno Free Fall (Europe) (En,Fr,De,Es,It)" description "Uno Free Fall (Europe) (En,Fr,De,Es,It)" - rom ( name "Uno Free Fall (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 414EA9F4 md5 214B56ECA30B048860579598E935C06A sha1 2AD8BDFC425F9426296C03ACD433B296E40EB72E ) + rom ( name "Uno Free Fall (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 414ea9f4 sha1 2AD8BDFC425F9426296C03ACD433B296E40EB72E ) ) game ( name "Urban Yeti! (USA, Europe)" description "Urban Yeti! (USA, Europe)" - rom ( name "Urban Yeti! (USA, Europe).gba" size 4194304 crc 4C53BA49 md5 6F4148477F8D456C00C4099E990C2FB0 sha1 79B72B0B290490019ED26A1AE6C481AC5C9F8893 flags verified ) + rom ( name "Urban Yeti! (USA, Europe).gba" size 4194304 crc 4c53ba49 sha1 79B72B0B290490019ED26A1AE6C481AC5C9F8893 flags verified ) ) game ( name "Urbz, The - Sims in the City (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Urbz, The - Sims in the City (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Urbz, The - Sims in the City (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 8B3330BB md5 0821EEA9BF87804EC1D700EC458A04E5 sha1 8EFD27375D1F92B43FE0D1C93A63C08B7A259ACC flags verified ) + rom ( name "Urbz, The - Sims in the City (USA, Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc 8b3330bb sha1 8EFD27375D1F92B43FE0D1C93A63C08B7A259ACC flags verified ) ) game ( name "Urbz, The - Sims in the City (Japan)" description "Urbz, The - Sims in the City (Japan)" - rom ( name "Urbz, The - Sims in the City (Japan).gba" size 33554432 crc BBCCC2FD md5 FF36188D91F68626D9D8B9DD9B3571E7 sha1 7AF0AB8A437616BEFAFDDD7C0EA87C8DFB80C6CD ) + rom ( name "Urbz, The - Sims in the City (Japan).gba" size 33554432 crc bbccc2fd sha1 7AF0AB8A437616BEFAFDDD7C0EA87C8DFB80C6CD flags verified ) ) game ( name "V-Master Cross (Japan)" description "V-Master Cross (Japan)" - rom ( name "V-Master Cross (Japan).gba" size 16777216 crc 251B2503 md5 287921D222D6C6CAAE129AB6418D5C7C sha1 7D4B7AA4593D7F495B5E7802BA1FE88B5D5C2CBA ) + rom ( name "V-Master Cross (Japan).gba" size 16777216 crc 251b2503 sha1 7D4B7AA4593D7F495B5E7802BA1FE88B5D5C2CBA flags verified ) ) game ( name "V-Rally 3 (Europe) (En,Fr,De,Es,It)" description "V-Rally 3 (Europe) (En,Fr,De,Es,It)" - rom ( name "V-Rally 3 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 02D20287 md5 37205E649905CC4F714FFBB0F3B41307 sha1 EDC0DCE8388B92E89BBE34CDEEFC1320F4C392A1 flags verified ) + rom ( name "V-Rally 3 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 02d20287 sha1 EDC0DCE8388B92E89BBE34CDEEFC1320F4C392A1 flags verified ) ) game ( name "V-Rally 3 (Japan)" description "V-Rally 3 (Japan)" - rom ( name "V-Rally 3 (Japan).gba" size 4194304 crc A0AA46B9 md5 70F0E0BA86C9BC154A32E9D583963825 sha1 26B1ACECF2704829438FF693EC37C227A7BDDDD4 ) + rom ( name "V-Rally 3 (Japan).gba" size 4194304 crc a0aa46b9 sha1 26B1ACECF2704829438FF693EC37C227A7BDDDD4 ) ) game ( name "V-Rally 3 (USA) (En,Fr,Es)" description "V-Rally 3 (USA) (En,Fr,Es)" - rom ( name "V-Rally 3 (USA) (En,Fr,Es).gba" size 4194304 crc D3AE3D37 md5 CF1673C920EF1D24C4F4B21EFFCC03F0 sha1 00A44C715AADD4AD3674F8D108271CDCB791CC16 ) + rom ( name "V-Rally 3 (USA) (En,Fr,Es).gba" size 4194304 crc d3ae3d37 sha1 00A44C715AADD4AD3674F8D108271CDCB791CC16 ) ) game ( name "V.I.P. (Europe) (En,Fr,De,Es,It,Nl)" description "V.I.P. (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "V.I.P. (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 718A6C3B md5 28AC2EEF3F2D0470EC88FE6551B38322 sha1 0C87F6661ACDE7B5932062681D770D3A502A5A0A ) + rom ( name "V.I.P. (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 718a6c3b sha1 0C87F6661ACDE7B5932062681D770D3A502A5A0A ) ) game ( name "Van Helsing (USA)" description "Van Helsing (USA)" - rom ( name "Van Helsing (USA).gba" size 4194304 crc 36159D63 md5 1CF89B423893A12EE0BBC1C4E2868509 sha1 1928F02A031020FAE57D42ECCC502DC04657D565 ) + rom ( name "Van Helsing (USA).gba" size 4194304 crc 36159d63 sha1 1928F02A031020FAE57D42ECCC502DC04657D565 ) ) game ( name "Van Helsing (Europe) (En,Fr,De,Es,It)" description "Van Helsing (Europe) (En,Fr,De,Es,It)" - rom ( name "Van Helsing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9E8748C9 md5 528D272AE33823D8596F6471DDC411FB sha1 3FFF7AD8D60E2CEE1C75272F62D0DEDA138B133D ) + rom ( name "Van Helsing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 9e8748c9 sha1 3FFF7AD8D60E2CEE1C75272F62D0DEDA138B133D flags verified ) ) game ( name "Vattroller X (Japan)" description "Vattroller X (Japan)" - rom ( name "Vattroller X (Japan).gba" size 8388608 crc E368A67A md5 AC4F3B73A920DDAABC9F9E003C92E02B sha1 035AE457C23D564AD97392572AB8A422ABFCE96E ) + rom ( name "Vattroller X (Japan).gba" size 8388608 crc e368a67a sha1 035AE457C23D564AD97392572AB8A422ABFCE96E ) ) game ( name "Vecinos Invasores (Spain)" description "Vecinos Invasores (Spain)" - rom ( name "Vecinos Invasores (Spain).gba" size 8388608 crc 96AF60F3 md5 CEC79164D58DEACE2122BA2E4A9CDD65 sha1 3FD93347CA0FA8FDA2A5BF88FF26DFD1D2DE1D9E ) + rom ( name "Vecinos Invasores (Spain).gba" size 8388608 crc 96af60f3 sha1 3FD93347CA0FA8FDA2A5BF88FF26DFD1D2DE1D9E ) ) game ( name "VeggieTales - LarryBoy and the Bad Apple (USA)" description "VeggieTales - LarryBoy and the Bad Apple (USA)" - rom ( name "VeggieTales - LarryBoy and the Bad Apple (USA).gba" size 4194304 crc B5213253 md5 4462BA1869564537610250D522287815 sha1 3F6F229D719A2E533ABA538763802A64C2025BD9 ) + rom ( name "VeggieTales - LarryBoy and the Bad Apple (USA).gba" size 4194304 crc b5213253 sha1 3F6F229D719A2E533ABA538763802A64C2025BD9 ) ) game ( name "Virtua Tennis (USA)" description "Virtua Tennis (USA)" - rom ( name "Virtua Tennis (USA).gba" size 8388608 crc E0BD3B75 md5 BFB5A63FDE75BECB342F5D0E9A8E0DA2 sha1 2BF5363D24C4EC6DE8AAFAE1BFFC84113EAED0A2 ) + rom ( name "Virtua Tennis (USA).gba" size 8388608 crc e0bd3b75 sha1 2BF5363D24C4EC6DE8AAFAE1BFFC84113EAED0A2 ) ) game ( name "Virtua Tennis (Europe) (En,Fr,De,Es,It)" description "Virtua Tennis (Europe) (En,Fr,De,Es,It)" - rom ( name "Virtua Tennis (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc E52A3AB8 md5 820A03DCD47B4D8AEC4B09B6D0F95D56 sha1 D200653B31C7FC150E9E84B53370CE4F40A10D43 ) + rom ( name "Virtua Tennis (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc e52a3ab8 sha1 D200653B31C7FC150E9E84B53370CE4F40A10D43 flags verified ) ) game ( name "Virtual Kasparov (Europe) (En,Fr,De,Es,It)" description "Virtual Kasparov (Europe) (En,Fr,De,Es,It)" - rom ( name "Virtual Kasparov (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 23B92CF7 md5 D4AA56B92749B7F395CA85A75616199F sha1 2BC9438EC2E8FAB515380F4020DCE14E027BF8DC ) + rom ( name "Virtual Kasparov (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 23b92cf7 sha1 2BC9438EC2E8FAB515380F4020DCE14E027BF8DC ) ) game ( name "Virtual Kasparov (USA) (En,Fr,De,Es,It)" description "Virtual Kasparov (USA) (En,Fr,De,Es,It)" - rom ( name "Virtual Kasparov (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 815B722F md5 68D45D576023082A099526D5B384DD1C sha1 F3B416A921B650CFD5C6A7F9CC6060DF0F6B82ED ) + rom ( name "Virtual Kasparov (USA) (En,Fr,De,Es,It).gba" size 4194304 crc 815b722f sha1 F3B416A921B650CFD5C6A7F9CC6060DF0F6B82ED ) ) game ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It)" description "W.i.t.c.h. (Europe) (En,Fr,De,Es,It)" - rom ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc CA4F6D5D md5 BCB8F65DB7A474622496573D752110F0 sha1 DCE3603206745F3D9288F35EAB33CC0F890C3751 flags verified ) + rom ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ca4f6d5d sha1 DCE3603206745F3D9288F35EAB33CC0F890C3751 flags verified ) ) game ( name "Wade Hixton's Counter Punch (USA, Europe)" description "Wade Hixton's Counter Punch (USA, Europe)" - rom ( name "Wade Hixton's Counter Punch (USA, Europe).gba" size 8388608 crc 47B49060 md5 05B82F996A7EBC44C62697B02833A68F sha1 11145CFE08B4BF6B51FA47C48AD5289FD322D599 flags verified ) + rom ( name "Wade Hixton's Counter Punch (USA, Europe).gba" size 8388608 crc 47b49060 sha1 11145CFE08B4BF6B51FA47C48AD5289FD322D599 flags verified ) ) game ( name "Wagamama Fairy Mirumo de Pon! - 8 Nin no Toki no Yousei (Japan)" description "Wagamama Fairy Mirumo de Pon! - 8 Nin no Toki no Yousei (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - 8 Nin no Toki no Yousei (Japan).gba" size 8388608 crc 5E5C008C md5 570A28CD1D5137E4EE061A9FC7986476 sha1 7FFA632F6CDF6E17320035930CC272FFF917D96B ) + rom ( name "Wagamama Fairy Mirumo de Pon! - 8 Nin no Toki no Yousei (Japan).gba" size 8388608 crc 5e5c008c sha1 7FFA632F6CDF6E17320035930CC272FFF917D96B flags verified ) ) game ( name "Wagamama Fairy Mirumo de Pon! - Dokidoki Memorial Panic (Japan)" description "Wagamama Fairy Mirumo de Pon! - Dokidoki Memorial Panic (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - Dokidoki Memorial Panic (Japan).gba" size 33554432 crc 5EFFDC65 md5 C42D862EDA2D7B0D49C0CBE33525A93C sha1 8DE920159F6010A6320C87946A47B6FD8A05BCDF ) + rom ( name "Wagamama Fairy Mirumo de Pon! - Dokidoki Memorial Panic (Japan).gba" size 33554432 crc 5effdc65 sha1 8DE920159F6010A6320C87946A47B6FD8A05BCDF ) ) game ( name "Wagamama Fairy Mirumo de Pon! - Nazo no Kagi to Shinjitsu no Tobira (Japan)" description "Wagamama Fairy Mirumo de Pon! - Nazo no Kagi to Shinjitsu no Tobira (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - Nazo no Kagi to Shinjitsu no Tobira (Japan).gba" size 8388608 crc AE2FB113 md5 89EDAB9880FF7A18657398E75C6D7462 sha1 8762F1031459AFE076F18FD49022D2AE19DADA72 ) + rom ( name "Wagamama Fairy Mirumo de Pon! - Nazo no Kagi to Shinjitsu no Tobira (Japan).gba" size 8388608 crc ae2fb113 sha1 8762F1031459AFE076F18FD49022D2AE19DADA72 ) ) game ( name "Wagamama Fairy Mirumo de Pon! - Ougon Maracas no Densetsu (Japan)" description "Wagamama Fairy Mirumo de Pon! - Ougon Maracas no Densetsu (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - Ougon Maracas no Densetsu (Japan).gba" size 4194304 crc 7D21F61F md5 27035B74F608FFCED0E4F78D9B3251CF sha1 951E7BC5D62DC10795806EC686B9F60116CAE8C7 ) + rom ( name "Wagamama Fairy Mirumo de Pon! - Ougon Maracas no Densetsu (Japan).gba" size 4194304 crc 7d21f61f sha1 951E7BC5D62DC10795806EC686B9F60116CAE8C7 ) ) game ( name "Wagamama Fairy Mirumo de Pon! - Taisen Mahoudama (Japan)" description "Wagamama Fairy Mirumo de Pon! - Taisen Mahoudama (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - Taisen Mahoudama (Japan).gba" size 8388608 crc F5DA0DCC md5 D0AFDDBD4F9A06AEAF9A8D7DB3A2EF82 sha1 DC226A1156744EDC55E7F261B250B933056471DA ) + rom ( name "Wagamama Fairy Mirumo de Pon! - Taisen Mahoudama (Japan).gba" size 8388608 crc f5da0dcc sha1 DC226A1156744EDC55E7F261B250B933056471DA ) ) game ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan)" description "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan)" - rom ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan).gba" size 8388608 crc A606C803 md5 335D6415DAD158195EE1290F4F955FA1 sha1 0429693DE0FF6E020B01807047DBB07B70B42529 ) + rom ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan).gba" size 8388608 crc a606c803 sha1 0429693DE0FF6E020B01807047DBB07B70B42529 flags verified ) ) game ( name "Wakeboarding Unleashed featuring Shaun Murray (Europe)" description "Wakeboarding Unleashed featuring Shaun Murray (Europe)" - rom ( name "Wakeboarding Unleashed featuring Shaun Murray (Europe).gba" size 8388608 crc A3CCF1EC md5 04D7E6CD55B91FF493E8529FBCF82266 sha1 9EB979282FB2084BD205282EA71F18409D5558E2 ) + rom ( name "Wakeboarding Unleashed featuring Shaun Murray (Europe).gba" size 8388608 crc a3ccf1ec sha1 9EB979282FB2084BD205282EA71F18409D5558E2 ) ) game ( name "Wakeboarding Unleashed featuring Shaun Murray (USA)" description "Wakeboarding Unleashed featuring Shaun Murray (USA)" - rom ( name "Wakeboarding Unleashed featuring Shaun Murray (USA).gba" size 8388608 crc CAD6376C md5 8BD140D7A98757926E62B6F6B6CDB02A sha1 AB24E4968672379EB2B22CB1B2730EADF5989130 ) + rom ( name "Wakeboarding Unleashed featuring Shaun Murray (USA).gba" size 8388608 crc cad6376c sha1 AB24E4968672379EB2B22CB1B2730EADF5989130 ) ) game ( name "Waliou Xunbao Ji (China)" description "Waliou Xunbao Ji (China)" - rom ( name "Waliou Xunbao Ji (China).gba" size 8388608 crc CF7585F1 md5 3D8FCFA27F2A659AB5F3AB0D70B9C99D sha1 229DDE72AD6B4282F2E85BEA49E3D877C473D4A9 ) + rom ( name "Waliou Xunbao Ji (China).gba" size 8388608 crc cf7585f1 sha1 229DDE72AD6B4282F2E85BEA49E3D877C473D4A9 ) ) game ( name "Waliou Zhizao (China)" description "Waliou Zhizao (China)" - rom ( name "Waliou Zhizao (China).gba" size 8388608 crc 78A4D2D4 md5 5A2E10190CA3F9CB1D3A954185A031ED sha1 4367C8E3053C56CBBD76EED7539D55A83BC52057 ) + rom ( name "Waliou Zhizao (China).gba" size 8388608 crc 78a4d2d4 sha1 4367C8E3053C56CBBD76EED7539D55A83BC52057 ) ) game ( name "Wanko de Kururin! Wancle (Japan)" description "Wanko de Kururin! Wancle (Japan)" - rom ( name "Wanko de Kururin! Wancle (Japan).gba" size 8388608 crc E93F547B md5 2B75A8546E9FAF9B404616A68F029DB0 sha1 A949EBA63C696B7C4E5EBF99EABA29EB3E06D2CE ) + rom ( name "Wanko de Kururin! Wancle (Japan).gba" size 8388608 crc e93f547b sha1 A949EBA63C696B7C4E5EBF99EABA29EB3E06D2CE ) ) game ( name "Wanko Mix Chiwanko World (Japan)" description "Wanko Mix Chiwanko World (Japan)" - rom ( name "Wanko Mix Chiwanko World (Japan).gba" size 8388608 crc 253AD05E md5 77CF6A578131F4CCB2D94532A80E12AE sha1 993A4BD4C63318A11ABD54C006ECBA57C646107C ) + rom ( name "Wanko Mix Chiwanko World (Japan).gba" size 8388608 crc 253ad05e sha1 993A4BD4C63318A11ABD54C006ECBA57C646107C ) ) game ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan)" description "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan)" - rom ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan).gba" size 4194304 crc 6DE82857 md5 96B1FE74B2D1AE2B36973ACCE0AC0BC2 sha1 36786BFEDB96E003B2A9C17376FF7277E0F9660D ) + rom ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan).gba" size 4194304 crc 6de82857 sha1 36786BFEDB96E003B2A9C17376FF7277E0F9660D ) ) game ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan) (Rev 1)" description "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan) (Rev 1)" - serial "BWDJ" - rom ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan) (Rev 1).gba" size 4194304 crc B12D2724 md5 5CE228ED956C5AD5F0BC95ECFBEFC848 sha1 D146E7D83965B8F05CD5C18C2B297A1B376AAF16 ) + rom ( name "Wannyan Doubutsu Byouin - Doubutsu no Oishasan Ikusei Game (Japan) (Rev 1).gba" size 4194304 crc b12d2724 sha1 D146E7D83965B8F05CD5C18C2B297A1B376AAF16 flags verified ) ) game ( name "Wanwan Meitantei (Japan)" description "Wanwan Meitantei (Japan)" - rom ( name "Wanwan Meitantei (Japan).gba" size 8388608 crc 5F41C9FE md5 BE5B6787B02BDA5B6283185E643A9FCF sha1 D438E3B030A814818ED7E96777AC3E46043922F9 ) + rom ( name "Wanwan Meitantei (Japan).gba" size 8388608 crc 5f41c9fe sha1 D438E3B030A814818ED7E96777AC3E46043922F9 flags verified ) ) game ( name "Wario Land 4 (USA, Europe)" description "Wario Land 4 (USA, Europe)" - rom ( name "Wario Land 4 (USA, Europe).gba" size 8388608 crc D6141609 md5 5FE47355A33E3FABEC2A1607AF88A404 sha1 B9FE05A8080E124B67BCE6A623234EE3B518A2C1 flags verified ) + rom ( name "Wario Land 4 (USA, Europe).gba" size 8388608 crc d6141609 sha1 B9FE05A8080E124B67BCE6A623234EE3B518A2C1 flags verified ) ) game ( - name "Wario Land Advance (Japan)" - description "Wario Land Advance (Japan)" - rom ( name "Wario Land Advance (Japan).gba" size 8388608 crc F56EBB7A md5 99C8AD779A16BE513A9FDFF502B6F5C2 sha1 A01DE1F2E69EC8AA9715ED0D0FBB263372B71E12 ) + name "Wario Land 4 (USA, Europe) (Wii U Virtual Console)" + description "Wario Land 4 (USA, Europe) (Wii U Virtual Console)" + rom ( name "Wario Land 4 (USA, Europe) (Wii U Virtual Console).gba" size 8388608 crc 8bb73d8a sha1 ED643151B8CC9749A490CAB6BAE26104E1652089 flags verified ) +) + +game ( + name "Wario Land Advance - Youki no Otakara (Japan)" + description "Wario Land Advance - Youki no Otakara (Japan)" + rom ( name "Wario Land Advance - Youki no Otakara (Japan).gba" size 8388608 crc f56ebb7a sha1 A01DE1F2E69EC8AA9715ED0D0FBB263372B71E12 flags verified ) +) + +game ( + name "Wario Land Advance - Youki no Otakara (Japan) (Wii U Virtual Console)" + description "Wario Land Advance - Youki no Otakara (Japan) (Wii U Virtual Console)" + rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Wii U Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2D3E6B124C84877520B482BA1016B8E3C36BAB14 flags verified ) ) game ( name "WarioWare - Twisted! (USA)" description "WarioWare - Twisted! (USA)" - rom ( name "WarioWare - Twisted! (USA).gba" size 16777216 crc CB4E844B md5 89579F4DFE1ED24A7CD16A6A61A72A17 sha1 F0102D0D6F7596FE853D5D0A94682718278E083A flags verified ) + rom ( name "WarioWare - Twisted! (USA).gba" size 16777216 crc cb4e844b sha1 F0102D0D6F7596FE853D5D0A94682718278E083A flags verified ) ) game ( name "WarioWare, Inc. - Mega Microgame$! (USA)" description "WarioWare, Inc. - Mega Microgame$! (USA)" - rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785D8B8C md5 A2D26DC774CEC9A0B47388A5DD727B03 sha1 3F556448D290FA5406D6ED367FEE16CC02387AD3 flags verified ) + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3F556448D290FA5406D6ED367FEE16CC02387AD3 flags verified ) ) game ( name "WarioWare, Inc. - Mega Microgame$! (USA) (Beta)" description "WarioWare, Inc. - Mega Microgame$! (USA) (Beta)" - rom ( name "WarioWare, Inc. - Mega Microgame$! (USA) (Beta).gba" size 8388608 crc EC0C0C58 md5 5D6028DBCF8E0CEBB7AAC36B520D94DC sha1 6A9DC96967E46C4C4FF138E73B45C031593C2A45 ) + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA) (Beta).gba" size 8388608 crc ec0c0c58 sha1 6A9DC96967E46C4C4FF138E73B45C031593C2A45 ) +) + +game ( + name "WarioWare, Inc. - Mega Microgame$! (USA) (Wii U Virtual Console)" + description "WarioWare, Inc. - Mega Microgame$! (USA) (Wii U Virtual Console)" + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA) (Wii U Virtual Console).gba" size 8388608 crc b0182907 sha1 C07AEEE46D7368A0914E9E5F0F5B108256C0D867 flags verified ) ) game ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It)" description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It)" - rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 500CA178 md5 31C33A781F3A6BD3AF3A4497E6D88C3C sha1 AAD81E722AA88F98913C0354E559F845C4689CCE flags verified ) + rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 500ca178 sha1 AAD81E722AA88F98913C0354E559F845C4689CCE flags verified ) +) + +game ( + name "WarioWare, Inc. - Trial version (USA) (Kiosk, GameCube)" + description "WarioWare, Inc. - Trial version (USA) (Kiosk, GameCube)" + rom ( name "WarioWare, Inc. - Trial version (USA) (Kiosk, GameCube).gba" size 249848 crc cc86e7c2 sha1 CA4AE225F2F758ED84CEF9A3C8490EFD4B5A0A7C flags verified ) ) game ( name "Weekend Miljonairs (Netherlands)" description "Weekend Miljonairs (Netherlands)" - rom ( name "Weekend Miljonairs (Netherlands).gba" size 4194304 crc 41AA465E md5 71DC8AEF347427313F5CFA63986337B4 sha1 93575EB15B39626E8C73BDA7C8E0AC5E1D134E92 ) + rom ( name "Weekend Miljonairs (Netherlands).gba" size 4194304 crc 41aa465e sha1 93575EB15B39626E8C73BDA7C8E0AC5E1D134E92 ) ) game ( name "Wer Wird Millionaer (Germany)" description "Wer Wird Millionaer (Germany)" - rom ( name "Wer Wird Millionaer (Germany).gba" size 4194304 crc 08D71A89 md5 105C79C9B8C04F2807A0EF1C1AAEBF6A sha1 3A3FC528645E24A2BA4E60EA3BA0F025133EB0AF ) + rom ( name "Wer Wird Millionaer (Germany).gba" size 4194304 crc 08d71a89 sha1 3A3FC528645E24A2BA4E60EA3BA0F025133EB0AF ) ) game ( name "Whac-A-Mole (USA)" description "Whac-A-Mole (USA)" - rom ( name "Whac-A-Mole (USA).gba" size 8388608 crc E58EF9A2 md5 6B611DC9657C75D06808C198C4B51AAC sha1 B5BE37328187DB934A1F7BFB158CEB59029209FB ) + rom ( name "Whac-A-Mole (USA).gba" size 8388608 crc e58ef9a2 sha1 B5BE37328187DB934A1F7BFB158CEB59029209FB ) ) game ( name "Whistle! - Dai-37-kai Tokyo-to Chuugakkou Sougou Taiiku Soccer Taikai (Japan)" description "Whistle! - Dai-37-kai Tokyo-to Chuugakkou Sougou Taiiku Soccer Taikai (Japan)" - rom ( name "Whistle! - Dai-37-kai Tokyo-to Chuugakkou Sougou Taiiku Soccer Taikai (Japan).gba" size 8388608 crc 667A0D06 md5 76471B9410D123FE28BAB047A4E4841E sha1 5438C70A8166639B80A017AA01DCFA6AF6D555B3 ) + rom ( name "Whistle! - Dai-37-kai Tokyo-to Chuugakkou Sougou Taiiku Soccer Taikai (Japan).gba" size 8388608 crc 667a0d06 sha1 5438C70A8166639B80A017AA01DCFA6AF6D555B3 flags verified ) ) game ( name "Who Wants to Be a Millionaire (Europe)" description "Who Wants to Be a Millionaire (Europe)" - rom ( name "Who Wants to Be a Millionaire (Europe).gba" size 4194304 crc B9C55B22 md5 204F81FBA1F395DB9E7966039EF48840 sha1 0A53F1BBCCB11D1E13FEC3FE539E9A891BAB8A85 ) + rom ( name "Who Wants to Be a Millionaire (Europe).gba" size 4194304 crc b9c55b22 sha1 0A53F1BBCCB11D1E13FEC3FE539E9A891BAB8A85 ) ) game ( name "Who Wants to Be a Millionaire (Australia)" description "Who Wants to Be a Millionaire (Australia)" - rom ( name "Who Wants to Be a Millionaire (Australia).gba" size 4194304 crc DA7006E0 md5 164AED5EE87071FD14E908BF65F7A6E3 sha1 B2001BFB115DD1C94DC71F96A1A569FE0248B2F2 ) + rom ( name "Who Wants to Be a Millionaire (Australia).gba" size 4194304 crc da7006e0 sha1 B2001BFB115DD1C94DC71F96A1A569FE0248B2F2 ) ) game ( name "Who Wants to Be a Millionaire - 2nd Edition (Europe)" description "Who Wants to Be a Millionaire - 2nd Edition (Europe)" - rom ( name "Who Wants to Be a Millionaire - 2nd Edition (Europe).gba" size 4194304 crc C89DEB4F md5 8E2766A5595C4916DECF99B300583D16 sha1 B9EAE6658BCB9541BE90C23493B49E1F049D84AD ) + rom ( name "Who Wants to Be a Millionaire - 2nd Edition (Europe).gba" size 4194304 crc c89deb4f sha1 B9EAE6658BCB9541BE90C23493B49E1F049D84AD ) ) game ( name "Who Wants to Be a Millionaire Junior (Europe)" description "Who Wants to Be a Millionaire Junior (Europe)" - rom ( name "Who Wants to Be a Millionaire Junior (Europe).gba" size 4194304 crc AAD93DA8 md5 94194788E55C1D3C256D816601EE7530 sha1 E3940E26BB8C2C6B0C366095407CBEAE6F85DCD9 ) -) - -game ( - name "Wild Thornberrys Movie, The (USA) (Beta)" - description "Wild Thornberrys Movie, The (USA) (Beta)" - rom ( name "Wild Thornberrys Movie, The (USA) (Beta).gba" size 3374120 crc E41720F5 md5 2AF652BD8EAAE10CAC539BF9F2491E45 sha1 A70B9D4898AE6A943ABD3602F5EE3B351CC8DCC1 ) + rom ( name "Who Wants to Be a Millionaire Junior (Europe).gba" size 4194304 crc aad93da8 sha1 E3940E26BB8C2C6B0C366095407CBEAE6F85DCD9 ) ) game ( name "Wild Thornberrys Movie, The (USA, Europe)" description "Wild Thornberrys Movie, The (USA, Europe)" - rom ( name "Wild Thornberrys Movie, The (USA, Europe).gba" size 4194304 crc 4E2C47BC md5 2C278A2282EA14997EF4202D205F91BB sha1 6BED328B3CE2C6D228E81C9FA7DC0806EE697B94 flags verified ) + rom ( name "Wild Thornberrys Movie, The (USA, Europe).gba" size 4194304 crc 4e2c47bc sha1 6BED328B3CE2C6D228E81C9FA7DC0806EE697B94 flags verified ) +) + +game ( + name "Wild Thornberrys Movie, The (USA, Europe) (Beta)" + description "Wild Thornberrys Movie, The (USA, Europe) (Beta)" + rom ( name "Wild Thornberrys Movie, The (USA, Europe) (Beta).gba" size 3374120 crc e41720f5 sha1 A70B9D4898AE6A943ABD3602F5EE3B351CC8DCC1 ) ) game ( name "Wild Thornberrys, The - Chimp Chase (USA, Europe)" description "Wild Thornberrys, The - Chimp Chase (USA, Europe)" - rom ( name "Wild Thornberrys, The - Chimp Chase (USA, Europe).gba" size 4194304 crc F0CA0689 md5 11100F0C82DE617894A90B0FA70B7E63 sha1 CC8E699DD200D4B678C6D8BA7237D44F4B1D8733 flags verified ) + rom ( name "Wild Thornberrys, The - Chimp Chase (USA, Europe).gba" size 4194304 crc f0ca0689 sha1 CC8E699DD200D4B678C6D8BA7237D44F4B1D8733 flags verified ) ) game ( name "Wild, The (USA, Europe) (En,Fr,De,Es)" description "Wild, The (USA, Europe) (En,Fr,De,Es)" - rom ( name "Wild, The (USA, Europe) (En,Fr,De,Es).gba" size 8388608 crc DE79EDC3 md5 643DADC449B6B43C78ECAD898A0E0C83 sha1 A7CF830919081655544A7BEB2C1A94BDBAB6A72E flags verified ) + rom ( name "Wild, The (USA, Europe) (En,Fr,De,Es).gba" size 8388608 crc de79edc3 sha1 A7CF830919081655544A7BEB2C1A94BDBAB6A72E flags verified ) ) game ( name "Wilden Fussball-Kerle, Die - Entscheidung im Teufelstopf (Germany)" description "Wilden Fussball-Kerle, Die - Entscheidung im Teufelstopf (Germany)" - rom ( name "Wilden Fussball-Kerle, Die - Entscheidung im Teufelstopf (Germany).gba" size 16777216 crc C8C12090 md5 D7D3E3EDD9C161BD0094A17124142EAD sha1 35DB308282C04C56BBA0833C1B5DD44A23F1BFE7 ) + rom ( name "Wilden Fussball-Kerle, Die - Entscheidung im Teufelstopf (Germany).gba" size 16777216 crc c8c12090 sha1 35DB308282C04C56BBA0833C1B5DD44A23F1BFE7 ) ) game ( name "Wilden Fussball-Kerle, Die - Gefahr im Wilde Kerle Land (Germany)" description "Wilden Fussball-Kerle, Die - Gefahr im Wilde Kerle Land (Germany)" - rom ( name "Wilden Fussball-Kerle, Die - Gefahr im Wilde Kerle Land (Germany).gba" size 16777216 crc A6281DD3 md5 0599FD3EA49510898691C1B77B42F838 sha1 12D2DF3A31CF36126113E7F481633A2DCD94F35D ) + rom ( name "Wilden Fussball-Kerle, Die - Gefahr im Wilde Kerle Land (Germany).gba" size 16777216 crc a6281dd3 sha1 12D2DF3A31CF36126113E7F481633A2DCD94F35D ) ) game ( name "Wing Commander - Prophecy (USA)" description "Wing Commander - Prophecy (USA)" - rom ( name "Wing Commander - Prophecy (USA).gba" size 4194304 crc 62D9E3D0 md5 054D89A31CA79C50638EE14E8D3185A7 sha1 6EF506892B9C2A8654E3451F952D886B11FD6C23 flags verified ) + rom ( name "Wing Commander - Prophecy (USA).gba" size 4194304 crc 62d9e3d0 sha1 6EF506892B9C2A8654E3451F952D886B11FD6C23 flags verified ) ) game ( name "Wing Commander - Prophecy (Europe) (En,Fr,De,Es,It)" description "Wing Commander - Prophecy (Europe) (En,Fr,De,Es,It)" - rom ( name "Wing Commander - Prophecy (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 09F02F6A md5 9A3589D2DD7FE1641201098EBD4BBA28 sha1 8B3D5FE031C634B7037BFAF361F83D81AC16E1EC ) -) - -game ( - name "Wings (Europe)" - description "Wings (Europe)" - rom ( name "Wings (Europe).gba" size 8388608 crc 6E0D29FC md5 AA78B66D1C1FD334587C0EBE7932D006 sha1 DEBA84AA8D5B19A2777F1D2556CB84E4BB895C77 ) + rom ( name "Wing Commander - Prophecy (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 09f02f6a sha1 8B3D5FE031C634B7037BFAF361F83D81AC16E1EC flags verified ) ) game ( name "Wings (USA)" description "Wings (USA)" - rom ( name "Wings (USA).gba" size 8388608 crc 49041BC8 md5 9003C10FD78CC0BB83C83CBBDBE03911 sha1 9D50A2150AE6EE4AACB23B826344134B63F906C2 ) + rom ( name "Wings (USA).gba" size 8388608 crc 49041bc8 sha1 9D50A2150AE6EE4AACB23B826344134B63F906C2 ) +) + +game ( + name "Wings (Europe)" + description "Wings (Europe)" + rom ( name "Wings (Europe).gba" size 8388608 crc 6e0d29fc sha1 DEBA84AA8D5B19A2777F1D2556CB84E4BB895C77 flags verified ) ) game ( name "Winnie the Pooh's Rumbly Tumbly Adventure (USA) (En,Fr,Es)" description "Winnie the Pooh's Rumbly Tumbly Adventure (USA) (En,Fr,Es)" - rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure (USA) (En,Fr,Es).gba" size 4194304 crc 5B098A68 md5 5747DF74932735205D090AA2AD1CFECE sha1 96D24D06955A13B0CE649E7536A29BE1B83F4D2B ) + rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure (USA) (En,Fr,Es).gba" size 4194304 crc 5b098a68 sha1 96D24D06955A13B0CE649E7536A29BE1B83F4D2B ) ) game ( name "Winnie the Pooh's Rumbly Tumbly Adventure (Europe) (En,Fr,De,Es,It,Nl)" description "Winnie the Pooh's Rumbly Tumbly Adventure (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc E5A97A58 md5 EE9880F52C3626749B943C91921F12AB sha1 8271EBE3929ECFACBD3FACF5008969CF62C788D7 flags verified ) + rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc e5a97a58 sha1 8271EBE3929ECFACBD3FACF5008969CF62C788D7 flags verified ) ) game ( name "Winnie the Pooh's Rumbly Tumbly Adventure & Rayman 3 (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" description "Winnie the Pooh's Rumbly Tumbly Adventure & Rayman 3 (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It,Nl,Sv,No,Da,Fi)" - rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure & Rayman 3 (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 16777216 crc C2FC12E5 md5 C4430CED04082F7CB25750B9DCC610EA sha1 AFD1F50E7C264085B749F9924F7279814CAE119C ) -) - -game ( - name "Winning Post for Game Boy Advance (Japan) (Rev 2)" - description "Winning Post for Game Boy Advance (Japan) (Rev 2)" - serial "AWPJ" - rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 2).gba" size 4194304 crc 9FB4AF0A md5 E99D7BFA10920B0E5BCA2BD235E2FA92 sha1 9151CF54475C4F773BDD9AB86A42D3E1BA462AFA ) + rom ( name "Winnie the Pooh's Rumbly Tumbly Adventure & Rayman 3 (Europe) (En,Fr,De,Es,It,Nl+En,Fr,De,Es,It,Nl,Sv,No,Da,Fi).gba" size 16777216 crc c2fc12e5 sha1 AFD1F50E7C264085B749F9924F7279814CAE119C ) ) game ( name "Winning Post for Game Boy Advance (Japan)" description "Winning Post for Game Boy Advance (Japan)" - rom ( name "Winning Post for Game Boy Advance (Japan).gba" size 4194304 crc 5ADA60F6 md5 77D05464A1AC01EF466F784C701828FE sha1 CC7E9C2A9E1DF985AED3DC4A018C93140D7A1B2C ) + rom ( name "Winning Post for Game Boy Advance (Japan).gba" size 4194304 crc 5ada60f6 sha1 CC7E9C2A9E1DF985AED3DC4A018C93140D7A1B2C ) +) + +game ( + name "Winning Post for Game Boy Advance (Japan) (Rev 2)" + description "Winning Post for Game Boy Advance (Japan) (Rev 2)" + rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 2).gba" size 4194304 crc 9fb4af0a sha1 9151CF54475C4F773BDD9AB86A42D3E1BA462AFA flags verified ) +) + +game ( + name "Winning Post for Game Boy Advance (Japan) (Rev 1)" + description "Winning Post for Game Boy Advance (Japan) (Rev 1)" + rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 1).gba" size 4194304 crc f6180af5 sha1 0F395A384B9DB2415196EDC2F911CCC67EB5E038 flags verified ) ) game ( name "Winter Sports (Europe) (En,Fr,De,Es,It)" description "Winter Sports (Europe) (En,Fr,De,Es,It)" - rom ( name "Winter Sports (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 64C802F9 md5 46D567B74F28661EE1AEED38FF453285 sha1 6E8997A0C8AF7D431703F5FBFFDFCA69BF108973 ) + rom ( name "Winter Sports (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 64c802f9 sha1 6E8997A0C8AF7D431703F5FBFFDFCA69BF108973 ) ) game ( name "WinX Club (Europe) (En,Fr,De,Es,It)" description "WinX Club (Europe) (En,Fr,De,Es,It)" - rom ( name "WinX Club (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc AFCB9CE8 md5 E43C1C1CCC83F1606ED3EE3996CC8322 sha1 3FADDB2187EC863BD181ACCD8F8B04C36005AEB6 ) + rom ( name "WinX Club (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc afcb9ce8 sha1 3FADDB2187EC863BD181ACCD8F8B04C36005AEB6 ) ) game ( name "WinX Club (USA)" description "WinX Club (USA)" - rom ( name "WinX Club (USA).gba" size 16777216 crc 1D6950A3 md5 80ACBED66F2F7A2FC88357F9A2028458 sha1 3B3F5C633F48AC218E9DA6AC78305EAB9C17AB21 ) + rom ( name "WinX Club (USA).gba" size 16777216 crc 1d6950a3 sha1 3B3F5C633F48AC218E9DA6AC78305EAB9C17AB21 ) ) game ( name "WinX Club - Quest for the Codex (USA)" description "WinX Club - Quest for the Codex (USA)" - rom ( name "WinX Club - Quest for the Codex (USA).gba" size 8388608 crc 29DFFF34 md5 6B99728FA21D6C6442BD1EBE919AFFA7 sha1 9EFDB3BD5F5AFD7E608E8A48BADF534880075A18 ) + rom ( name "WinX Club - Quest for the Codex (USA).gba" size 8388608 crc 29dfff34 sha1 9EFDB3BD5F5AFD7E608E8A48BADF534880075A18 ) ) game ( name "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It)" description "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It)" - rom ( name "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 9EB09C77 md5 978E59B7362C79193131A35C277E07C0 sha1 84951F8BAABC405EEE8A1FB94D420397623265AD ) + rom ( name "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 9eb09c77 sha1 84951F8BAABC405EEE8A1FB94D420397623265AD ) ) game ( name "Wizardry Summoner (Japan)" description "Wizardry Summoner (Japan)" - rom ( name "Wizardry Summoner (Japan).gba" size 4194304 crc 71695A71 md5 A72A1D999E9C607144FA7F3C2145EB75 sha1 C9BA4742D494D61A215F6E8068FDAEED12D19CDC ) + rom ( name "Wizardry Summoner (Japan).gba" size 4194304 crc 71695a71 sha1 C9BA4742D494D61A215F6E8068FDAEED12D19CDC flags verified ) +) + +game ( + name "Wizardry Summoner (Japan) (Rev 1)" + description "Wizardry Summoner (Japan) (Rev 1)" + rom ( name "Wizardry Summoner (Japan) (Rev 1).gba" size 4194304 crc b3c77a61 sha1 C4DDB35319B8ED0F2E3D281AD93E42A0DB757CD5 flags verified ) ) game ( name "Wolfenstein 3D (USA, Europe)" description "Wolfenstein 3D (USA, Europe)" - rom ( name "Wolfenstein 3D (USA, Europe).gba" size 8388608 crc C4AA2B7B md5 D853B5FFA5EF88605A0823D3B4B2DF08 sha1 2C077DE84348C6E09581A0A523376056A2AEBA95 flags verified ) + rom ( name "Wolfenstein 3D (USA, Europe).gba" size 8388608 crc c4aa2b7b sha1 2C077DE84348C6E09581A0A523376056A2AEBA95 flags verified ) ) game ( name "Woody Woodpecker - Crazy Castle 5 (Japan)" description "Woody Woodpecker - Crazy Castle 5 (Japan)" - rom ( name "Woody Woodpecker - Crazy Castle 5 (Japan).gba" size 4194304 crc A3E1E037 md5 DA15F288FE413A9D58432FB516F23CB0 sha1 E10B6C363F37280151E4AD00EF5F6E19BD262EC3 ) + rom ( name "Woody Woodpecker - Crazy Castle 5 (Japan).gba" size 4194304 crc a3e1e037 sha1 E10B6C363F37280151E4AD00EF5F6E19BD262EC3 ) ) game ( name "Woody Woodpecker in Crazy Castle 5 (Europe) (En,Fr,De)" description "Woody Woodpecker in Crazy Castle 5 (Europe) (En,Fr,De)" - rom ( name "Woody Woodpecker in Crazy Castle 5 (Europe) (En,Fr,De).gba" size 4194304 crc 092B3DCE md5 79A3A7D6A5546E381DE2AB17DB6ADB13 sha1 D8B7E80F2455095AF9FE05B91A3B29B0246A1588 flags verified ) + rom ( name "Woody Woodpecker in Crazy Castle 5 (Europe) (En,Fr,De).gba" size 4194304 crc 092b3dce sha1 D8B7E80F2455095AF9FE05B91A3B29B0246A1588 flags verified ) ) game ( name "Woody Woodpecker in Crazy Castle 5 (USA)" description "Woody Woodpecker in Crazy Castle 5 (USA)" - rom ( name "Woody Woodpecker in Crazy Castle 5 (USA).gba" size 4194304 crc B9A3C878 md5 B9B3BE20DACBDF7D06B7EE86E73B677A sha1 47179BAA55CC7C19B16195FF3C85396A0CC466F9 ) + rom ( name "Woody Woodpecker in Crazy Castle 5 (USA).gba" size 4194304 crc b9a3c878 sha1 47179BAA55CC7C19B16195FF3C85396A0CC466F9 ) ) game ( name "Word Safari - The Friendship Totems (USA)" description "Word Safari - The Friendship Totems (USA)" - rom ( name "Word Safari - The Friendship Totems (USA).gba" size 8388608 crc 78E5A643 md5 D64A34E34DEBB206AEB66D4ED832AC85 sha1 70994585A1173C3E71757BB0CF81E7CBE73CA196 ) + rom ( name "Word Safari - The Friendship Totems (USA).gba" size 8388608 crc 78e5a643 sha1 70994585A1173C3E71757BB0CF81E7CBE73CA196 ) ) game ( name "World Advance Soccer - Shouri e no Michi (Japan)" description "World Advance Soccer - Shouri e no Michi (Japan)" - rom ( name "World Advance Soccer - Shouri e no Michi (Japan).gba" size 8388608 crc AFE01C1F md5 868CAFBA6F72113D4473A171E9EE4D24 sha1 5D0C7EA259F44FF7F4645E2E80201C531D2F54E2 ) -) - -game ( - name "World Championship Poker (Europe) (En,Fr,De,Es,It)" - description "World Championship Poker (Europe) (En,Fr,De,Es,It)" - rom ( name "World Championship Poker (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4776F86E md5 C6394E32B564C770FE1971FDF2B1E8F2 sha1 731EF2646AD83750AFF729CB2286DE6EE60F8260 ) + rom ( name "World Advance Soccer - Shouri e no Michi (Japan).gba" size 8388608 crc afe01c1f sha1 5D0C7EA259F44FF7F4645E2E80201C531D2F54E2 ) ) game ( name "World Championship Poker (USA)" description "World Championship Poker (USA)" - rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07F15152 md5 0D8F24FA168197A151EEB95FD29AEF65 sha1 1D72864021F88F8DB2686C57CFC5176B33CE2015 flags verified ) + rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07f15152 sha1 1D72864021F88F8DB2686C57CFC5176B33CE2015 flags verified ) +) + +game ( + name "World Championship Poker (Europe) (En,Fr,De,Es,It)" + description "World Championship Poker (Europe) (En,Fr,De,Es,It)" + rom ( name "World Championship Poker (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4776f86e sha1 731EF2646AD83750AFF729CB2286DE6EE60F8260 ) ) game ( name "World Poker Tour (USA)" description "World Poker Tour (USA)" - rom ( name "World Poker Tour (USA).gba" size 4194304 crc B18784C1 md5 0C112FDA9346A9851FA7CB72D80BE501 sha1 C75851D14A96DEA46770945AAFEAF9A8F6C12271 ) + rom ( name "World Poker Tour (USA).gba" size 4194304 crc b18784c1 sha1 C75851D14A96DEA46770945AAFEAF9A8F6C12271 ) ) game ( name "World Poker Tour (Europe) (En,Fr,De)" description "World Poker Tour (Europe) (En,Fr,De)" - rom ( name "World Poker Tour (Europe) (En,Fr,De).gba" size 4194304 crc 8FA26A97 md5 18BFA442D857E038C8EF578B64DF0BA2 sha1 2F2983D33C547F09CCA512B06880BC1FAF1D4F54 ) + rom ( name "World Poker Tour (Europe) (En,Fr,De).gba" size 4194304 crc 8fa26a97 sha1 2F2983D33C547F09CCA512B06880BC1FAF1D4F54 flags verified ) ) game ( name "World Reborn (USA) (Proto)" description "World Reborn (USA) (Proto)" - rom ( name "World Reborn (USA) (Proto).gba" size 4194304 crc 4C48EBB3 md5 8ED216F4EC3342E7D27B420BFE3B4E53 sha1 91899433556C14BBE3BB043E95C3549BF3346E5A ) + rom ( name "World Reborn (USA) (Proto).gba" size 4194304 crc 4c48ebb3 sha1 91899433556C14BBE3BB043E95C3549BF3346E5A flags verified ) +) + +game ( + name "World Reborn (USA) (Unl)" + description "World Reborn (USA) (Unl)" + rom ( name "World Reborn (USA) (Unl).gba" size 4194304 crc 68301a80 sha1 A6B6409A66394DF461DC1C5B67CD7298D0328ECC ) ) game ( name "World Tennis Stars (Europe)" description "World Tennis Stars (Europe)" - rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc B5830F5F md5 092DBB8125CFBC93D55342F25277B08F sha1 2A93449943E85B7C5D75D0D7A9E1D8AD67C7A706 ) + rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2A93449943E85B7C5D75D0D7A9E1D8AD67C7A706 flags verified ) ) game ( name "World Tennis Stars (USA)" description "World Tennis Stars (USA)" - rom ( name "World Tennis Stars (USA).gba" size 4194304 crc 036E30B0 md5 B705E04F4571CC9E8801900B4E0243FD sha1 C668815A2CCF0BC6C3816D0947218661437449BC ) + rom ( name "World Tennis Stars (USA).gba" size 4194304 crc 036e30b0 sha1 C668815A2CCF0BC6C3816D0947218661437449BC ) ) game ( name "Worms Blast (Europe) (En,Fr,De,Es,It)" description "Worms Blast (Europe) (En,Fr,De,Es,It)" - rom ( name "Worms Blast (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 5223F5AA md5 CAF46477C33A49DACF2D08AED205909B sha1 0DA4FF24B61AE8B6D67EF59377770FD958517F2F ) + rom ( name "Worms Blast (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 5223f5aa sha1 0DA4FF24B61AE8B6D67EF59377770FD958517F2F ) ) game ( name "Worms World Party (Europe) (En,Fr,De,Es,It)" description "Worms World Party (Europe) (En,Fr,De,Es,It)" - rom ( name "Worms World Party (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8EE32CBE md5 78724B3F7E5DE9F1C931D5B196E7F19B sha1 5E0ABE3D94D1489FADEBE897DF1ED5A5C0212901 ) + rom ( name "Worms World Party (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8ee32cbe sha1 5E0ABE3D94D1489FADEBE897DF1ED5A5C0212901 flags verified ) ) game ( name "Worms World Party (USA) (En,Fr,De,Es,It)" description "Worms World Party (USA) (En,Fr,De,Es,It)" - rom ( name "Worms World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc E8789C18 md5 D81D39A2400A2651099A6D1AA2A461D5 sha1 7B078976D9056ABA7F81BB1FF33E5A36357F5F0B ) + rom ( name "Worms World Party (USA) (En,Fr,De,Es,It).gba" size 4194304 crc e8789c18 sha1 7B078976D9056ABA7F81BB1FF33E5A36357F5F0B ) ) game ( name "WTA Tour Tennis (USA)" description "WTA Tour Tennis (USA)" - rom ( name "WTA Tour Tennis (USA).gba" size 4194304 crc 7F8CB0AF md5 B9F78309DBCE23A4262DC32C1DEF62A2 sha1 56B1D64F9BAF83D8EC73E2857DA62CD5B0BD9851 ) + rom ( name "WTA Tour Tennis (USA).gba" size 4194304 crc 7f8cb0af sha1 56B1D64F9BAF83D8EC73E2857DA62CD5B0BD9851 ) ) game ( name "WTA Tour Tennis Pocket (Japan)" description "WTA Tour Tennis Pocket (Japan)" - rom ( name "WTA Tour Tennis Pocket (Japan).gba" size 8388608 crc 459DAF35 md5 E7E9E8948FF3A0DE232BF0D8465DA8FB sha1 2DE5495739C9D2057356E95CF84C514B55E41C31 ) + rom ( name "WTA Tour Tennis Pocket (Japan).gba" size 8388608 crc 459daf35 sha1 2DE5495739C9D2057356E95CF84C514B55E41C31 ) ) game ( name "WWE - Road to WrestleMania X8 (USA, Europe)" description "WWE - Road to WrestleMania X8 (USA, Europe)" - rom ( name "WWE - Road to WrestleMania X8 (USA, Europe).gba" size 4194304 crc F1FB4FD1 md5 0E66F9DC9C29A3A11F2A821BCC809251 sha1 4F62C900E8DD223054114AA42D50FE3306807EEF flags verified ) + rom ( name "WWE - Road to WrestleMania X8 (USA, Europe).gba" size 4194304 crc f1fb4fd1 sha1 4F62C900E8DD223054114AA42D50FE3306807EEF flags verified ) ) game ( name "WWE - Survivor Series (USA, Europe)" description "WWE - Survivor Series (USA, Europe)" - rom ( name "WWE - Survivor Series (USA, Europe).gba" size 4194304 crc 6694F94D md5 61EB8C6B8DA8E0EDC327C5EA7BD3A000 sha1 BB61E289F2A09E7CE0E193267430DBC6F5583A49 flags verified ) -) - -game ( - name "WWF - Road to WrestleMania (USA) (Beta)" - description "WWF - Road to WrestleMania (USA) (Beta)" - rom ( name "WWF - Road to WrestleMania (USA) (Beta).gba" size 4194304 crc 8314421B md5 A18EB28FA9F1ED0AFE5248FF2AFAB896 sha1 13C1965B62849873738417830E142182782430FE ) + rom ( name "WWE - Survivor Series (USA, Europe).gba" size 4194304 crc 6694f94d sha1 BB61E289F2A09E7CE0E193267430DBC6F5583A49 flags verified ) ) game ( name "WWF - Road to WrestleMania (USA, Europe)" description "WWF - Road to WrestleMania (USA, Europe)" - rom ( name "WWF - Road to WrestleMania (USA, Europe).gba" size 4194304 crc 8D3B116E md5 023327FE6C7BF7B35334B347D7F9B4D1 sha1 E9334FD4B7A8ACF2256A8E2E97F0AB3DD91D6ABB flags verified ) + rom ( name "WWF - Road to WrestleMania (USA, Europe).gba" size 4194304 crc 8d3b116e sha1 E9334FD4B7A8ACF2256A8E2E97F0AB3DD91D6ABB flags verified ) +) + +game ( + name "WWF - Road to WrestleMania (USA, Europe) (Beta)" + description "WWF - Road to WrestleMania (USA, Europe) (Beta)" + rom ( name "WWF - Road to WrestleMania (USA, Europe) (Beta).gba" size 4194304 crc 8314421b sha1 13C1965B62849873738417830E142182782430FE ) ) game ( name "X-Bladez - Inline Skater (Europe)" description "X-Bladez - Inline Skater (Europe)" - rom ( name "X-Bladez - Inline Skater (Europe).gba" size 4194304 crc C05F9907 md5 EFF13BB745908C0D38EE5F4518DA52AA sha1 8A5DC506FD6E000116BE2CA923A056BC15D5B553 ) + rom ( name "X-Bladez - Inline Skater (Europe).gba" size 4194304 crc c05f9907 sha1 8A5DC506FD6E000116BE2CA923A056BC15D5B553 ) ) game ( name "X-Bladez - Inline Skater (USA)" description "X-Bladez - Inline Skater (USA)" - rom ( name "X-Bladez - Inline Skater (USA).gba" size 4194304 crc 09FDD665 md5 DD9D7F37441572D859092E715AF804BD sha1 A8354A51738C6B28660AB74ACC7F8445A9A570A1 ) + rom ( name "X-Bladez - Inline Skater (USA).gba" size 4194304 crc 09fdd665 sha1 A8354A51738C6B28660AB74ACC7F8445A9A570A1 ) ) game ( name "X-Men - Reign of Apocalypse (USA, Europe)" description "X-Men - Reign of Apocalypse (USA, Europe)" - rom ( name "X-Men - Reign of Apocalypse (USA, Europe).gba" size 8388608 crc 25F43491 md5 9457A51730ADA0EA9CCDBAAB51D93613 sha1 2D8CB3C01031C522EFB65F2F18F2550929BE0497 ) + rom ( name "X-Men - Reign of Apocalypse (USA, Europe).gba" size 8388608 crc 25f43491 sha1 2D8CB3C01031C522EFB65F2F18F2550929BE0497 ) ) game ( name "X-Men - The Official Game (USA)" description "X-Men - The Official Game (USA)" - rom ( name "X-Men - The Official Game (USA).gba" size 8388608 crc C87F460A md5 2584C4D9C73888FFC9096A02FAFEA08C sha1 E53AEFA4E6FDAB6B9D4D29D19F9C29004E767C94 ) + rom ( name "X-Men - The Official Game (USA).gba" size 8388608 crc c87f460a sha1 E53AEFA4E6FDAB6B9D4D29D19F9C29004E767C94 ) ) game ( name "X-Men - The Official Game (Europe) (En,Fr,Es,It)" description "X-Men - The Official Game (Europe) (En,Fr,Es,It)" - rom ( name "X-Men - The Official Game (Europe) (En,Fr,Es,It).gba" size 8388608 crc 34BE6923 md5 D20A8685F12452C1699012E2CF1D9B79 sha1 2044EDC0AE4A0F02277373D99E6FF15A7127D6CC ) + rom ( name "X-Men - The Official Game (Europe) (En,Fr,Es,It).gba" size 8388608 crc 34be6923 sha1 2044EDC0AE4A0F02277373D99E6FF15A7127D6CC ) ) game ( name "X-Men 2 - La Vengeance de Wolverine (France)" description "X-Men 2 - La Vengeance de Wolverine (France)" - rom ( name "X-Men 2 - La Vengeance de Wolverine (France).gba" size 8388608 crc 82373B44 md5 01AF1ED83C07AF653EDD6F6A314F1A3A sha1 2D9F5F0D5143F92CE1585CB86684B29FBDC75594 ) + rom ( name "X-Men 2 - La Vengeance de Wolverine (France).gba" size 8388608 crc 82373b44 sha1 2D9F5F0D5143F92CE1585CB86684B29FBDC75594 ) ) game ( name "X-Terminator Advance (Japan) (Unl)" description "X-Terminator Advance (Japan) (Unl)" - rom ( name "X-Terminator Advance (Japan) (Unl).gba" size 131072 crc D48D5587 md5 51CFC7008C7C32ABD5A43EADF430A6E1 sha1 B6B5FEBC259D215892A8920A0CA0A6A8067F9CFE ) + rom ( name "X-Terminator Advance (Japan) (Unl).gba" size 131072 crc d48d5587 sha1 B6B5FEBC259D215892A8920A0CA0A6A8067F9CFE ) ) game ( name "X2 - Wolverine's Revenge (USA, Europe)" description "X2 - Wolverine's Revenge (USA, Europe)" - rom ( name "X2 - Wolverine's Revenge (USA, Europe).gba" size 8388608 crc 41A92220 md5 69662D33F665B2E00E4F95AA75B16A6A sha1 DC2E861013A9B6A65B9BCD122F070C8F55D1471B flags verified ) + rom ( name "X2 - Wolverine's Revenge (USA, Europe).gba" size 8388608 crc 41a92220 sha1 DC2E861013A9B6A65B9BCD122F070C8F55D1471B flags verified ) ) game ( name "Xploder Advance (Europe) (Alt 1) (Unl)" description "Xploder Advance (Europe) (Alt 1) (Unl)" - rom ( name "Xploder Advance (Europe) (Alt 1) (Unl).gba" size 131072 crc 4F3E7427 md5 FDBD4E62E01BA4A570188B201427D3A4 sha1 4F2252F61E80EB2A27646FD4BFB159DA8EA70CA6 ) + rom ( name "Xploder Advance (Europe) (Alt 1) (Unl).gba" size 131072 crc 4f3e7427 sha1 4F2252F61E80EB2A27646FD4BFB159DA8EA70CA6 ) ) game ( name "Xploder Advance (Europe) (Unl)" description "Xploder Advance (Europe) (Unl)" - rom ( name "Xploder Advance (Europe) (Unl).gba" size 131072 crc AD71F6FF md5 B5170BF7F64F0A75C33A17DC63D69A52 sha1 B7E7448152DF42548A6D7A8A593543D439BBFD45 ) + rom ( name "Xploder Advance (Europe) (Unl).gba" size 131072 crc ad71f6ff sha1 B7E7448152DF42548A6D7A8A593543D439BBFD45 ) ) game ( name "XS Moto (USA)" description "XS Moto (USA)" - rom ( name "XS Moto (USA).gba" size 4194304 crc 6DBBC17C md5 986FF7D285A6C161CCFD2EAEF4F8CB18 sha1 2A800D077CFB8320AC5780D840976A47D9595728 ) + rom ( name "XS Moto (USA).gba" size 4194304 crc 6dbbc17c sha1 2A800D077CFB8320AC5780D840976A47D9595728 ) ) game ( name "xXx (USA, Europe)" description "xXx (USA, Europe)" - rom ( name "xXx (USA, Europe).gba" size 8388608 crc 2B3A2AB2 md5 59118D9B87B1809A1CB50B1D42035C7A sha1 8F10C133772D8D4D0F940927D1CD303A1D8BB7BA flags verified ) + rom ( name "xXx (USA, Europe).gba" size 8388608 crc 2b3a2ab2 sha1 8F10C133772D8D4D0F940927D1CD303A1D8BB7BA flags verified ) ) game ( name "xXx (France)" description "xXx (France)" - rom ( name "xXx (France).gba" size 8388608 crc 44A77F71 md5 2395CCA1007ECD7D016860703812C2BC sha1 A47DA3B30A45035AAC333EBC62F36DA6A3D88E0A ) + rom ( name "xXx (France).gba" size 8388608 crc 44a77f71 sha1 A47DA3B30A45035AAC333EBC62F36DA6A3D88E0A ) +) + +game ( + name "Yaobai Senxigang (China) (Proto)" + description "Yaobai Senxigang (China) (Proto)" + rom ( name "Yaobai Senxigang (China) (Proto).gba" size 8388608 crc 517fb18d sha1 1113608C19806A0B7503E5F3F4F1EDD172E0FDFC flags verified ) ) game ( name "Yaoxi Dao (China)" description "Yaoxi Dao (China)" - rom ( name "Yaoxi Dao (China).gba" size 4194304 crc 9C32A829 md5 1B7E12284E562915AA7ACD260C06771D sha1 D5ED374C8D353CF27EE9160F1C4C27A7DABE5845 ) + rom ( name "Yaoxi Dao (China).gba" size 4194304 crc 9c32a829 sha1 D5ED374C8D353CF27EE9160F1C4C27A7DABE5845 ) ) game ( name "Yggdra Union (Japan)" description "Yggdra Union (Japan)" - rom ( name "Yggdra Union (Japan).gba" size 33554432 crc A86F844A md5 8DE0883BF7B60F0983F65313D3D15D9A sha1 4AC5874B98F0FA3C3AAD4C3EBE927F7FBC5B3267 ) + rom ( name "Yggdra Union (Japan).gba" size 33554432 crc a86f844a sha1 4AC5874B98F0FA3C3AAD4C3EBE927F7FBC5B3267 flags verified ) ) game ( name "Yggdra Union - We'll Never Fight Alone (USA)" description "Yggdra Union - We'll Never Fight Alone (USA)" - rom ( name "Yggdra Union - We'll Never Fight Alone (USA).gba" size 33554432 crc 3BFA68F7 md5 1EAC366817944FAECF3BCD290D3F87CC sha1 B289083B01F2F8FC726C664CF872D72B3F4986E3 ) + rom ( name "Yggdra Union - We'll Never Fight Alone (USA).gba" size 33554432 crc 3bfa68f7 sha1 B289083B01F2F8FC726C664CF872D72B3F4986E3 ) ) game ( name "Yggdra Union - We'll Never Fight Alone (Europe)" description "Yggdra Union - We'll Never Fight Alone (Europe)" - rom ( name "Yggdra Union - We'll Never Fight Alone (Europe).gba" size 33554432 crc 3E0DF130 md5 34469CBE444C6561A5A24C1159F0697E sha1 E419C835200457F67D5AB7E3C236583980B922D9 ) -) - -game ( - name "Yoshi - Topsy-Turvy (USA)" - description "Yoshi - Topsy-Turvy (USA)" - rom ( name "Yoshi - Topsy-Turvy (USA).gba" size 8388608 crc E64C265C md5 E66D2E98947A5BD1068228E4084B06DA sha1 947498CB1DB918D305500257E8223DEEADDF561D ) + rom ( name "Yggdra Union - We'll Never Fight Alone (Europe).gba" size 33554432 crc 3e0df130 sha1 E419C835200457F67D5AB7E3C236583980B922D9 ) ) game ( name "Yoshi no Banyuuinryoku (Japan)" description "Yoshi no Banyuuinryoku (Japan)" - rom ( name "Yoshi no Banyuuinryoku (Japan).gba" size 8388608 crc 31594B7A md5 91E86D6ADB495236293E75D5F0FA82B8 sha1 A3F2035CA2BDC2BC59E9E46EFBB6187705EBE3D1 ) + rom ( name "Yoshi no Banyuuinryoku (Japan).gba" size 8388608 crc 31594b7a sha1 A3F2035CA2BDC2BC59E9E46EFBB6187705EBE3D1 flags verified ) +) + +game ( + name "Yoshi Sample (Japan) (En) (Demo)" + description "Yoshi Sample (Japan) (En) (Demo)" + rom ( name "Yoshi Sample (Japan) (En) (Demo).gba" size 1717944 crc 34f2ef47 sha1 71B87B9684BABFE5751A9FB6642ACE5A927F21E0 flags verified ) +) + +game ( + name "Yoshi Sample (Japan) (En) (SDK 3.0) (Demo)" + description "Yoshi Sample (Japan) (En) (SDK 3.0) (Demo)" + rom ( name "Yoshi Sample (Japan) (En) (SDK 3.0) (Demo).gba" size 2273956 crc 954d2619 sha1 89FE5C0B5489A14F5F9BB1D4EBDE998F07C4F939 flags verified ) +) + +game ( + name "Yoshi Topsy-Turvy (USA)" + description "Yoshi Topsy-Turvy (USA)" + rom ( name "Yoshi Topsy-Turvy (USA).gba" size 8388608 crc e64c265c sha1 947498CB1DB918D305500257E8223DEEADDF561D flags verified ) ) game ( name "Yoshi's Universal Gravitation (Europe) (En,Fr,De,Es,It)" description "Yoshi's Universal Gravitation (Europe) (En,Fr,De,Es,It)" - rom ( name "Yoshi's Universal Gravitation (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 05F4D0AA md5 F9DE621B65084BCDAFF6E6B0CDC7C413 sha1 045BE1369964F141009F3701839EC0A8DCCB25C1 flags verified ) + rom ( name "Yoshi's Universal Gravitation (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 05f4d0aa sha1 045BE1369964F141009F3701839EC0A8DCCB25C1 flags verified ) ) game ( name "Youkaidou (Japan)" description "Youkaidou (Japan)" - rom ( name "Youkaidou (Japan).gba" size 8388608 crc 2A4A92B4 md5 A515E58BAF034344F78076025C3C99C9 sha1 ED6578BB6A4F201AE5B269DF5CE842158A34A421 ) + rom ( name "Youkaidou (Japan).gba" size 8388608 crc 2a4a92b4 sha1 ED6578BB6A4F201AE5B269DF5CE842158A34A421 ) ) game ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" - rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA).gba" size 8388608 crc D3784B52 md5 FFA7898EE8B3BC98E4156F3B5E7CDF63 sha1 2A9825DB34A7AEDCFD0A9FAE5C7CEE50292F03B7 ) + rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA).gba" size 8388608 crc d3784b52 sha1 2A9825DB34A7AEDCFD0A9FAE5C7CEE50292F03B7 ) ) game ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It)" description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 208D77EC md5 ADE79CC8FAC2F433648FB95CA8C51164 sha1 66DC426B71195C11761F7CE58FFEF231E8E227B1 ) + rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 208d77ec sha1 66DC426B71195C11761F7CE58FFEF231E8E227B1 flags verified ) ) game ( name "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" description "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" - rom ( name "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe).gba" size 8388608 crc AEF6B7CC md5 ACEFEBBE5FDF25AE83A386A6D1C09BCA sha1 DAB129544C5AB496DF4FD1DFBFA33E76142D2D8A ) + rom ( name "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe).gba" size 8388608 crc aef6b7cc sha1 DAB129544C5AB496DF4FD1DFBFA33E76142D2D8A ) ) game ( name "Yu-Gi-Oh! - 7 Trials to Glory - World Championship Tournament 2005 (USA) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - 7 Trials to Glory - World Championship Tournament 2005 (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - 7 Trials to Glory - World Championship Tournament 2005 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 584DB6A6 md5 27F9F0E73752CC2DF3B73BC46048E8A2 sha1 E7A2FB1901A691B3FDD0A39FB574E6DD536B165E flags verified ) + rom ( name "Yu-Gi-Oh! - 7 Trials to Glory - World Championship Tournament 2005 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 584db6a6 sha1 E7A2FB1901A691B3FDD0A39FB574E6DD536B165E flags verified ) ) game ( name "Yu-Gi-Oh! - Day of the Duelist - World Championship Tournament 2005 (Europe) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - Day of the Duelist - World Championship Tournament 2005 (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Day of the Duelist - World Championship Tournament 2005 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 17988E9B md5 DDAFCDB5A0D7F0D44B861A7700E187BC sha1 81069765961B6B1A79FDA15D45332BEF43F91118 ) + rom ( name "Yu-Gi-Oh! - Day of the Duelist - World Championship Tournament 2005 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 17988e9b sha1 81069765961B6B1A79FDA15D45332BEF43F91118 ) ) game ( name "Yu-Gi-Oh! - Destiny Board Traveler (USA)" description "Yu-Gi-Oh! - Destiny Board Traveler (USA)" - rom ( name "Yu-Gi-Oh! - Destiny Board Traveler (USA).gba" size 8388608 crc 611E7BBD md5 875524C19ADA69A0C9F3E585E6BEDAA2 sha1 DF001A60B7AB52E9735906FCD80F6C8B834ED684 ) + rom ( name "Yu-Gi-Oh! - Destiny Board Traveler (USA).gba" size 8388608 crc 611e7bbd sha1 DF001A60B7AB52E9735906FCD80F6C8B834ED684 ) ) game ( name "Yu-Gi-Oh! - Destiny Board Traveler (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! - Destiny Board Traveler (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Destiny Board Traveler (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc AE1A8E9D md5 DFB46DDC7BE8F75D7AD429B60B646AAA sha1 96FD0E583AB49258B194F578E29E9A5D55122B50 ) + rom ( name "Yu-Gi-Oh! - Destiny Board Traveler (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc ae1a8e9d sha1 96FD0E583AB49258B194F578E29E9A5D55122B50 flags verified ) ) game ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan)" description "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan)" - rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan).gba" size 8388608 crc 51B35E87 md5 72F072D0E26A9E3D12B6107598CBAF69 sha1 A0AD0CBFF3D74BB3E234ABCFF866994EA602C43A ) + rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Japan).gba" size 8388608 crc 51b35e87 sha1 A0AD0CBFF3D74BB3E234ABCFF866994EA602C43A flags verified ) ) game ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (USA) (En,Es)" description "Yu-Gi-Oh! - Dungeon Dice Monsters (USA) (En,Es)" - rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (USA) (En,Es).gba" size 8388608 crc 8B5E0A27 md5 1AC4901F9A831D6B86CA776BB61F8D8B sha1 FDD69455A072B2F74E6C5C50B96DAA0438156B27 ) + rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (USA) (En,Es).gba" size 8388608 crc 8b5e0a27 sha1 FDD69455A072B2F74E6C5C50B96DAA0438156B27 ) ) game ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc EE317F69 md5 EC2E23CC5FD7A3EA4E32AC7B8D488103 sha1 3DED1227698FBDB2BA47F03025CD1934FC184B99 flags verified ) + rom ( name "Yu-Gi-Oh! - Dungeon Dice Monsters (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ee317f69 sha1 3DED1227698FBDB2BA47F03025CD1934FC184B99 flags verified ) ) game ( name "Yu-Gi-Oh! - Reshef of Destruction (USA)" description "Yu-Gi-Oh! - Reshef of Destruction (USA)" - rom ( name "Yu-Gi-Oh! - Reshef of Destruction (USA).gba" size 16777216 crc 09E0C559 md5 C06DECDF51468503434DCB5E7BBDCCA5 sha1 DAD3AA7DD470C9B475236FED2EA867B04AB1B089 ) + rom ( name "Yu-Gi-Oh! - Reshef of Destruction (USA).gba" size 16777216 crc 09e0c559 sha1 DAD3AA7DD470C9B475236FED2EA867B04AB1B089 ) ) game ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 460E073F md5 4F71A4E021F4B9319C9D4443DD710666 sha1 1D33877DCC5EC94CC0D68460163208C7EBFB6AD3 flags verified ) + rom ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 460e073f sha1 1D33877DCC5EC94CC0D68460163208C7EBFB6AD3 flags verified ) ) game ( name "Yu-Gi-Oh! - Sugoroku no Sugoroku (Japan)" description "Yu-Gi-Oh! - Sugoroku no Sugoroku (Japan)" - rom ( name "Yu-Gi-Oh! - Sugoroku no Sugoroku (Japan).gba" size 8388608 crc 8D52B3C5 md5 C5401124A48F173F05FB10FB9E716011 sha1 6816F044C3F4CAC76E888C0EC36DC216E7C140D2 ) + rom ( name "Yu-Gi-Oh! - Sugoroku no Sugoroku (Japan).gba" size 8388608 crc 8d52b3c5 sha1 6816F044C3F4CAC76E888C0EC36DC216E7C140D2 ) ) game ( name "Yu-Gi-Oh! - The Eternal Duelist Soul (USA)" description "Yu-Gi-Oh! - The Eternal Duelist Soul (USA)" - rom ( name "Yu-Gi-Oh! - The Eternal Duelist Soul (USA).gba" size 8388608 crc DFD07A36 md5 EC3F000FFDE5754CB164A05D2D6F9053 sha1 510FBBA212ACA9BAB95EA12F8FD933E62EE34DEA flags verified ) + rom ( name "Yu-Gi-Oh! - The Eternal Duelist Soul (USA).gba" size 8388608 crc dfd07a36 sha1 510FBBA212ACA9BAB95EA12F8FD933E62EE34DEA flags verified ) ) game ( name "Yu-Gi-Oh! - The Sacred Cards (USA)" description "Yu-Gi-Oh! - The Sacred Cards (USA)" - rom ( name "Yu-Gi-Oh! - The Sacred Cards (USA).gba" size 16777216 crc 141FB1CC md5 0A7C58069D5390165482E88A22158BD2 sha1 A06735F9C3D10BE9339657026981AEF77AF34B27 ) + rom ( name "Yu-Gi-Oh! - The Sacred Cards (USA).gba" size 16777216 crc 141fb1cc sha1 A06735F9C3D10BE9339657026981AEF77AF34B27 flags verified ) ) game ( name "Yu-Gi-Oh! - The Sacred Cards (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! - The Sacred Cards (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - The Sacred Cards (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc D19DB37C md5 C43587FCA1F7E02F611BAAB02D26716D sha1 9A23AD34F67AC1F1343B7009F11AC95C77B782EF ) + rom ( name "Yu-Gi-Oh! - The Sacred Cards (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc d19db37c sha1 9A23AD34F67AC1F1343B7009F11AC95C77B782EF flags verified ) ) game ( name "Yu-Gi-Oh! - Ultimate Masters - World Championship Tournament 2006 (USA) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - Ultimate Masters - World Championship Tournament 2006 (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Ultimate Masters - World Championship Tournament 2006 (USA) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc F968A196 md5 B8A7C976B28172995FE9E465D654297A sha1 9689337D6AAC1CE9699AB60AAC73FC2CFDCCAD9B flags verified ) + rom ( name "Yu-Gi-Oh! - Ultimate Masters - World Championship Tournament 2006 (USA) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc f968a196 sha1 9689337D6AAC1CE9699AB60AAC73FC2CFDCCAD9B flags verified ) ) game ( name "Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 (Europe) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc CEDE4060 md5 020411D3B08F5639EB8CB878283F84BF sha1 0734BE2FE17D9EF5EDE88E0A14CD194656AA23D8 ) + rom ( name "Yu-Gi-Oh! - Ultimate Masters Edition - World Championship Tournament 2006 (Europe) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc cede4060 sha1 0734BE2FE17D9EF5EDE88E0A14CD194656AA23D8 flags verified ) ) game ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (USA) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - World Championship Tournament 2004 (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 69B6F229 md5 8517049CE498D84530C953D6A8B3112E sha1 3A7FCEFFA1405640FE4606E006D272D1AF542F2B ) + rom ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 69b6f229 sha1 3A7FCEFFA1405640FE4606E006D272D1AF542F2B ) ) game ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (Europe) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - World Championship Tournament 2004 (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 31EDEF1B md5 6F0F891C1D8E8DCDA39EEA116F2BD957 sha1 97A2E7CF6613538216DC807AE5ED92EAA4B9D7A8 ) + rom ( name "Yu-Gi-Oh! - World Championship Tournament 2004 (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 3c42e84c sha1 B791EE3241CAEF0566BCA56BB70C6D37AD3B8621 flags verified ) ) game ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (Europe) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (Europe) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc ACA5FFC6 md5 15DBDE22EF467C503E09F75B233DA539 sha1 96A490F9152ACFF2D0F6B2486382F1906B3BAEE8 flags verified ) + rom ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (Europe) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc aca5ffc6 sha1 96A490F9152ACFF2D0F6B2486382F1906B3BAEE8 flags verified ) ) game ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (USA) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (USA) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 39B5E771 md5 1E52D66F5F8A7C4F207D80BA4FCCF55E sha1 53D4AE06D1B605F8925C53D6C585478D73FF55C0 flags verified ) + rom ( name "Yu-Gi-Oh! - Worldwide Edition - Stairway to the Destined Duel (USA) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 39b5e771 sha1 53D4AE06D1B605F8925C53D6C585478D73FF55C0 flags verified ) ) game ( name "Yu-Gi-Oh! Double Pack (Europe) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! Double Pack (Europe) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! Double Pack (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 7EA28A99 md5 FB29D59010A0EA0FEC56CEC94241617B sha1 14A5E70E05BCA849695190833D1B107799CEB58D ) + rom ( name "Yu-Gi-Oh! Double Pack (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc 7ea28a99 sha1 14A5E70E05BCA849695190833D1B107799CEB58D flags verified ) ) game ( name "Yu-Gi-Oh! Double Pack (USA)" description "Yu-Gi-Oh! Double Pack (USA)" - rom ( name "Yu-Gi-Oh! Double Pack (USA).gba" size 33554432 crc F3DF5758 md5 B288C64EC50625B6B80BC6730EFBF190 sha1 CFA00B4F8A3F2E6400D4816DF6ED1BFEBF131120 ) + rom ( name "Yu-Gi-Oh! Double Pack (USA).gba" size 33554432 crc f3df5758 sha1 CFA00B4F8A3F2E6400D4816DF6ED1BFEBF131120 ) ) game ( name "Yu-Gi-Oh! Double Pack 2 (USA) (En,Fr,De,Es,It)" description "Yu-Gi-Oh! Double Pack 2 (USA) (En,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! Double Pack 2 (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 2CB399D0 md5 F062E6C537CFC8AAC48107915DA7E861 sha1 76BE77C5BC0B6457E40E959B1AFFF71A65DA9322 ) + rom ( name "Yu-Gi-Oh! Double Pack 2 (USA) (En,Fr,De,Es,It).gba" size 16777216 crc 2cb399d0 sha1 76BE77C5BC0B6457E40E959B1AFFF71A65DA9322 ) ) game ( name "Yu-Gi-Oh! Duel Monsters 5 Expert 1 (Japan)" description "Yu-Gi-Oh! Duel Monsters 5 Expert 1 (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 5 Expert 1 (Japan).gba" size 8388608 crc F3041E7E md5 31DD0E7EFD461E004CFA6BAD8E7B0E57 sha1 DC25F733CEE913AFDF187EC03DF30909FE28B03C ) + rom ( name "Yu-Gi-Oh! Duel Monsters 5 Expert 1 (Japan).gba" size 8388608 crc f3041e7e sha1 DC25F733CEE913AFDF187EC03DF30909FE28B03C flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 6 Expert 2 (Japan)" description "Yu-Gi-Oh! Duel Monsters 6 Expert 2 (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 6 Expert 2 (Japan).gba" size 16777216 crc A7054D60 md5 2820981C97087B1181FC44E722C64DC3 sha1 E5EE6FB7A6A4EB0E33197549FD30F8FE402B595F ) + rom ( name "Yu-Gi-Oh! Duel Monsters 6 Expert 2 (Japan).gba" size 16777216 crc a7054d60 sha1 E5EE6FB7A6A4EB0E33197549FD30F8FE402B595F flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 7 - Kettou Toshi Densetsu (Japan)" description "Yu-Gi-Oh! Duel Monsters 7 - Kettou Toshi Densetsu (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 7 - Kettou Toshi Densetsu (Japan).gba" size 16777216 crc B9BE9B91 md5 38BE3F2FF554732E3B84003ABE79E2BF sha1 C28F5C0103E3D0E5919C2023044199409375E0CD ) + rom ( name "Yu-Gi-Oh! Duel Monsters 7 - Kettou Toshi Densetsu (Japan).gba" size 16777216 crc b9be9b91 sha1 C28F5C0103E3D0E5919C2023044199409375E0CD flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 8 - Hametsu no Daijashin (Japan)" description "Yu-Gi-Oh! Duel Monsters 8 - Hametsu no Daijashin (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 8 - Hametsu no Daijashin (Japan).gba" size 16777216 crc 681DAF1F md5 1AF27A924734E9F9E30569633204269C sha1 0C1D5CC4989BC9B5BECC8C1ED962F6CAA55AF342 ) + rom ( name "Yu-Gi-Oh! Duel Monsters 8 - Hametsu no Daijashin (Japan).gba" size 16777216 crc 681daf1f sha1 0C1D5CC4989BC9B5BECC8C1ED962F6CAA55AF342 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters Expert 2006 (Japan) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! Duel Monsters Expert 2006 (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! Duel Monsters Expert 2006 (Japan) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc 7A1019E6 md5 1EA6B683E2CADC313474BADEAC929154 sha1 C1A518426745224F8549B662366933F5F8A66D49 flags verified ) + rom ( name "Yu-Gi-Oh! Duel Monsters Expert 2006 (Japan) (En,Ja,Fr,De,Es,It).gba" size 33554432 crc 7a1019e6 sha1 C1A518426745224F8549B662366933F5F8A66D49 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters Expert 3 (Japan) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! Duel Monsters Expert 3 (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! Duel Monsters Expert 3 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 7AB1EC04 md5 AC0311B3923D45B89A2DB746280C7915 sha1 1E321DF0DDF6DADE3622624BBC4A1164D5CB8ADD ) + rom ( name "Yu-Gi-Oh! Duel Monsters Expert 3 (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 7ab1ec04 sha1 1E321DF0DDF6DADE3622624BBC4A1164D5CB8ADD flags verified ) ) game ( - name "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King (Japan)" - description "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King (Japan).gba" size 33554432 crc F4295DA8 md5 A44251198E1C9087C40262C34531A5A3 sha1 ED6D8A33599EF5BFC27B54830116316ACC811018 ) -) - -game ( - name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1)" - description "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1)" - rom ( name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1).gba" size 16777216 crc 1BECF9D3 md5 9BC1EE3D43963364AD25E687EC867D26 sha1 E16DD5848BCBAFFDC60D5D5548D60F4311F4615C flags verified ) + name "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King! (Japan)" + description "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King! (Japan)" + rom ( name "Yu-Gi-Oh! Duel Monsters GX - Mezase Duel King! (Japan).gba" size 33554432 crc f4295da8 sha1 ED6D8A33599EF5BFC27B54830116316ACC811018 ) ) game ( name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It)" description "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It)" - rom ( name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 98507497 md5 9A8ABBB9E95AD1EAD235E3ADE9B7B429 sha1 A6EDDD916EFF82FA7841366BAC1932B88201E548 ) + rom ( name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It).gba" size 16777216 crc 98507497 sha1 A6EDDD916EFF82FA7841366BAC1932B88201E548 flags verified ) +) + +game ( + name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1)" + description "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1)" + rom ( name "Yu-Gi-Oh! Duel Monsters International - Worldwide Edition (Japan) (En,Ja,Fr,De,Es,It) (Rev 1).gba" size 16777216 crc 1becf9d3 sha1 E16DD5848BCBAFFDC60D5D5548D60F4311F4615C flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters International 2 (Japan) (En,Ja)" description "Yu-Gi-Oh! Duel Monsters International 2 (Japan) (En,Ja)" - rom ( name "Yu-Gi-Oh! Duel Monsters International 2 (Japan) (En,Ja).gba" size 16777216 crc 6DCFB879 md5 026FBEE1949B8508F7EF3F9F92CB1F74 sha1 4E9C134910D43F245AFD648B633A12DFFF2120B6 ) + rom ( name "Yu-Gi-Oh! Duel Monsters International 2 (Japan) (En,Ja).gba" size 16777216 crc 6dcfb879 sha1 4E9C134910D43F245AFD648B633A12DFFF2120B6 flags verified ) ) game ( name "Yu-Gi-Oh! GX - Duel Academy (USA)" description "Yu-Gi-Oh! GX - Duel Academy (USA)" - rom ( name "Yu-Gi-Oh! GX - Duel Academy (USA).gba" size 33554432 crc 3B8A00FE md5 F62C47CBE08E1E3BCFCF9F1B84841A76 sha1 57D6BB789833B62B360072902982D5F1011B3640 flags verified ) + rom ( name "Yu-Gi-Oh! GX - Duel Academy (USA).gba" size 33554432 crc 3b8a00fe sha1 57D6BB789833B62B360072902982D5F1011B3640 flags verified ) ) game ( name "Yu-Gi-Oh! GX - Duel Academy (Europe)" description "Yu-Gi-Oh! GX - Duel Academy (Europe)" - rom ( name "Yu-Gi-Oh! GX - Duel Academy (Europe).gba" size 33554432 crc 3FB2ABDA md5 E1CC21EBF4C3BE179738EBBF44F25308 sha1 DEB55081C6A567337943D1DDDEC29B1E6968BCCC ) + rom ( name "Yu-Gi-Oh! GX - Duel Academy (Europe).gba" size 33554432 crc 3fb2abda sha1 DEB55081C6A567337943D1DDDEC29B1E6968BCCC ) ) game ( name "Yumemi-chan no Naritai Series 3 - Watashi no Makesalon (Japan)" description "Yumemi-chan no Naritai Series 3 - Watashi no Makesalon (Japan)" - rom ( name "Yumemi-chan no Naritai Series 3 - Watashi no Makesalon (Japan).gba" size 4194304 crc 4D35AAB7 md5 77E321BC21CBE892780D34863354116A sha1 117D0F20AC3956AB29AE8A9F48422E8288CAF444 ) + rom ( name "Yumemi-chan no Naritai Series 3 - Watashi no Makesalon (Japan).gba" size 4194304 crc 4d35aab7 sha1 117D0F20AC3956AB29AE8A9F48422E8288CAF444 ) ) game ( name "Yuujou no Victory Goal 4v4 Arashi - Get the Goal!! (Japan)" description "Yuujou no Victory Goal 4v4 Arashi - Get the Goal!! (Japan)" - rom ( name "Yuujou no Victory Goal 4v4 Arashi - Get the Goal!! (Japan).gba" size 8388608 crc CE987F90 md5 67A1411EA622631F469733EC01C89A01 sha1 CDBEAEBDF98B3C003E8A35CFAB9B16F0C5383CD3 ) + rom ( name "Yuujou no Victory Goal 4v4 Arashi - Get the Goal!! (Japan).gba" size 8388608 crc ce987f90 sha1 CDBEAEBDF98B3C003E8A35CFAB9B16F0C5383CD3 ) ) game ( name "Yuureiyashiki no Nijuuyojikan (Japan)" description "Yuureiyashiki no Nijuuyojikan (Japan)" - rom ( name "Yuureiyashiki no Nijuuyojikan (Japan).gba" size 4194304 crc 6DA2166E md5 230BBFA7C06395868DFC17C514112C83 sha1 C1E33700E6C0E5228152E414D432C61F860C5B69 ) + rom ( name "Yuureiyashiki no Nijuuyojikan (Japan).gba" size 4194304 crc 6da2166e sha1 C1E33700E6C0E5228152E414D432C61F860C5B69 ) ) game ( name "Z.O.E. 2173 - Testament (Japan)" description "Z.O.E. 2173 - Testament (Japan)" - rom ( name "Z.O.E. 2173 - Testament (Japan).gba" size 8388608 crc 9FEEF66D md5 A1ECE5CE4FE328F0C0240FC281DE4F4B sha1 C882179863001F9F2EA15A46EC65DA0F465263C1 ) + rom ( name "Z.O.E. 2173 - Testament (Japan).gba" size 8388608 crc 9feef66d sha1 C882179863001F9F2EA15A46EC65DA0F465263C1 ) ) game ( name "Zapper (Europe) (En,Fr,De,Es,It)" description "Zapper (Europe) (En,Fr,De,Es,It)" - rom ( name "Zapper (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8753A1C5 md5 EB7BA1C777B946BD9842B6238676F799 sha1 08B1D2AA6B37D76D2B19688D01ACA778AA6E7F26 flags verified ) + rom ( name "Zapper (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8753a1c5 sha1 08B1D2AA6B37D76D2B19688D01ACA778AA6E7F26 flags verified ) ) game ( name "Zapper - One Wicked Cricket! (USA)" description "Zapper - One Wicked Cricket! (USA)" - rom ( name "Zapper - One Wicked Cricket! (USA).gba" size 4194304 crc 6751A4EF md5 9A83E6571C9543A1A4D658564F02BE4C sha1 1561C4E1F4AB945299F2DFB5BB7DF532EC4D4067 ) + rom ( name "Zapper - One Wicked Cricket! (USA).gba" size 4194304 crc 6751a4ef sha1 1561C4E1F4AB945299F2DFB5BB7DF532EC4D4067 ) ) game ( name "Zatchbell! - Electric Arena (USA)" description "Zatchbell! - Electric Arena (USA)" - rom ( name "Zatchbell! - Electric Arena (USA).gba" size 8388608 crc B4F1E785 md5 54F8B4748E5F0233BC28216A0188C968 sha1 96B67004D7592AE118936E8988C96880D9880F60 ) + rom ( name "Zatchbell! - Electric Arena (USA).gba" size 8388608 crc b4f1e785 sha1 96B67004D7592AE118936E8988C96880D9880F60 ) ) game ( name "Zelda no Densetsu - Fushigi no Boushi (Japan)" description "Zelda no Densetsu - Fushigi no Boushi (Japan)" - rom ( name "Zelda no Densetsu - Fushigi no Boushi (Japan).gba" size 16777216 crc 6CE771A5 md5 0B061059FD5E7F7B034F96932C86829C sha1 6C5404A1EFFB17F481F352181D0F1C61A2765C5D flags verified ) + rom ( name "Zelda no Densetsu - Fushigi no Boushi (Japan).gba" size 16777216 crc 6ce771a5 sha1 6C5404A1EFFB17F481F352181D0F1C61A2765C5D flags verified ) ) game ( name "Zelda no Densetsu - Kamigami no Triforce & 4tsu no Tsurugi (Japan)" description "Zelda no Densetsu - Kamigami no Triforce & 4tsu no Tsurugi (Japan)" - rom ( name "Zelda no Densetsu - Kamigami no Triforce & 4tsu no Tsurugi (Japan).gba" size 8388608 crc 81E42BEE md5 8F289129BEEFD40717718C7AB8BAA447 sha1 FB3803F6A806154DC93541D17A6D53203CB339EE flags verified ) + rom ( name "Zelda no Densetsu - Kamigami no Triforce & 4tsu no Tsurugi (Japan).gba" size 8388608 crc 81e42bee sha1 FB3803F6A806154DC93541D17A6D53203CB339EE flags verified ) ) game ( name "Zen-Nihon GT Senshuken (Japan)" description "Zen-Nihon GT Senshuken (Japan)" - rom ( name "Zen-Nihon GT Senshuken (Japan).gba" size 4194304 crc D320A965 md5 9455CEF784B0E4D3B3E706037C552892 sha1 9E837491E9F9C94B937CD1F3E9B70AC9C2A20832 ) + rom ( name "Zen-Nihon GT Senshuken (Japan).gba" size 4194304 crc d320a965 sha1 9E837491E9F9C94B937CD1F3E9B70AC9C2A20832 ) ) game ( name "Zen-Nihon Shounen Soccer Taikai 2 - Mezase Nihon-ichi! (Japan)" description "Zen-Nihon Shounen Soccer Taikai 2 - Mezase Nihon-ichi! (Japan)" - rom ( name "Zen-Nihon Shounen Soccer Taikai 2 - Mezase Nihon-ichi! (Japan).gba" size 8388608 crc 268F9C7E md5 5423D3057E1806348DD1F959F0BE94F9 sha1 E71992923C4E5B3BFE51C1A1960A584347626991 ) + rom ( name "Zen-Nihon Shounen Soccer Taikai 2 - Mezase Nihon-ichi! (Japan).gba" size 8388608 crc 268f9c7e sha1 E71992923C4E5B3BFE51C1A1960A584347626991 ) ) game ( name "Zero One (Japan)" description "Zero One (Japan)" - rom ( name "Zero One (Japan).gba" size 16777216 crc 84A4C1B4 md5 120CF0C4D430CF9DE20071A249DB62F4 sha1 42501ED8395DFCC87CC112D20183A9394D0B232F ) + rom ( name "Zero One (Japan).gba" size 16777216 crc 84a4c1b4 sha1 42501ED8395DFCC87CC112D20183A9394D0B232F ) ) game ( name "Zero One SP (Japan)" description "Zero One SP (Japan)" - rom ( name "Zero One SP (Japan).gba" size 16777216 crc FD6CE886 md5 267F45F19C0BD4CB4EEC1879C2CBD7CF sha1 7ED2B25DFF8783A924C5D6DFE2ADD95D766F32F0 ) + rom ( name "Zero One SP (Japan).gba" size 16777216 crc fd6ce886 sha1 7ED2B25DFF8783A924C5D6DFE2ADD95D766F32F0 ) ) game ( name "Zero-Tours (Japan)" description "Zero-Tours (Japan)" - rom ( name "Zero-Tours (Japan).gba" size 4194304 crc DE7C1AE8 md5 EC8FDE05B426BC7FB37FC6589018C7D9 sha1 E22EC490683E26DFF591459DA377C101638B0ED0 ) + rom ( name "Zero-Tours (Japan).gba" size 4194304 crc de7c1ae8 sha1 E22EC490683E26DFF591459DA377C101638B0ED0 flags verified ) ) game ( name "Zettaizetsumei Dangerous Jiisan - Naki no 1-kai - Zettaifukujuu Violence Kouchou - Wagahai ga 1-ban Erainjai!! (Japan)" description "Zettaizetsumei Dangerous Jiisan - Naki no 1-kai - Zettaifukujuu Violence Kouchou - Wagahai ga 1-ban Erainjai!! (Japan)" - rom ( name "Zettaizetsumei Dangerous Jiisan - Naki no 1-kai - Zettaifukujuu Violence Kouchou - Wagahai ga 1-ban Erainjai!! (Japan).gba" size 8388608 crc 00328BB3 md5 BA11D0BFD27985088AC44866D7ECE116 sha1 E582DD422F33B7F7A5AE306FE5159550F2A55444 ) + rom ( name "Zettaizetsumei Dangerous Jiisan - Naki no 1-kai - Zettaifukujuu Violence Kouchou - Wagahai ga 1-ban Erainjai!! (Japan).gba" size 8388608 crc 00328bb3 sha1 E582DD422F33B7F7A5AE306FE5159550F2A55444 ) ) game ( name "Zettaizetsumei Dangerous Jiisan - Shijou Saikyou no Dogeza (Japan)" description "Zettaizetsumei Dangerous Jiisan - Shijou Saikyou no Dogeza (Japan)" - rom ( name "Zettaizetsumei Dangerous Jiisan - Shijou Saikyou no Dogeza (Japan).gba" size 8388608 crc 7DA6CC69 md5 6CE00CD216C0B7C3D3ABE895540480A9 sha1 D246639DDD955058E45BE722F64899A2C267D02F ) + rom ( name "Zettaizetsumei Dangerous Jiisan - Shijou Saikyou no Dogeza (Japan).gba" size 8388608 crc 7da6cc69 sha1 D246639DDD955058E45BE722F64899A2C267D02F flags verified ) ) game ( name "Zettaizetsumei Dangerous Jiisan 3 - Hateshinaki Mamonogatari (Japan)" description "Zettaizetsumei Dangerous Jiisan 3 - Hateshinaki Mamonogatari (Japan)" - rom ( name "Zettaizetsumei Dangerous Jiisan 3 - Hateshinaki Mamonogatari (Japan).gba" size 8388608 crc 5BE52FB7 md5 D1B92AF267A24B56CCD00869FBC7303F sha1 8E25C26B1A55369CFEEE86708B64F41CB650B88B ) + rom ( name "Zettaizetsumei Dangerous Jiisan 3 - Hateshinaki Mamonogatari (Japan).gba" size 8388608 crc 5be52fb7 sha1 8E25C26B1A55369CFEEE86708B64F41CB650B88B ) ) game ( name "Zettaizetsumei Dangerous Jiisan Tsuu - Ikari no Oshioki Blues (Japan)" description "Zettaizetsumei Dangerous Jiisan Tsuu - Ikari no Oshioki Blues (Japan)" - rom ( name "Zettaizetsumei Dangerous Jiisan Tsuu - Ikari no Oshioki Blues (Japan).gba" size 8388608 crc 99273EE3 md5 89BEA97EC8D4F11274784AFC125DE6C8 sha1 8F294172A467FDC0114C55AC297870D918030C21 ) + rom ( name "Zettaizetsumei Dangerous Jiisan Tsuu - Ikari no Oshioki Blues (Japan).gba" size 8388608 crc 99273ee3 sha1 8F294172A467FDC0114C55AC297870D918030C21 ) ) game ( - name "Zidane Football Generation (Europe) (En,Fr,De,Es,It)" - description "Zidane Football Generation (Europe) (En,Fr,De,Es,It)" - rom ( name "Zidane Football Generation (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 59E2635F md5 2585D9385617B38836884F90997DC985 sha1 E18E9E8AABB8844DE688DDFF8843329F84E470AA ) + name "Zhuanzhuanbang (China) (Proto)" + description "Zhuanzhuanbang (China) (Proto)" + rom ( name "Zhuanzhuanbang (China) (Proto).gba" size 4194304 crc e9fed103 sha1 32E8274989C717128CD40DC2E8AFD9922C52F9EA flags verified ) +) + +game ( + name "Zhuanzhuanbang Tiantang (China) (Proto)" + description "Zhuanzhuanbang Tiantang (China) (Proto)" + rom ( name "Zhuanzhuanbang Tiantang (China) (Proto).gba" size 8388608 crc 6065e963 sha1 5CF7F27378668B4DDD28E084A7C15299ACDD6774 flags verified ) +) + +game ( + name "Zidane Football Generation 2002 (Europe) (En,Fr,De,Es,It)" + description "Zidane Football Generation 2002 (Europe) (En,Fr,De,Es,It)" + rom ( name "Zidane Football Generation 2002 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 59e2635f sha1 E18E9E8AABB8844DE688DDFF8843329F84E470AA ) ) game ( name "Zoey 101 (USA)" description "Zoey 101 (USA)" - rom ( name "Zoey 101 (USA).gba" size 4194304 crc 9CF348A8 md5 F7C0A6BF412B6F78A0F0E096AA0FD07E sha1 2953F982DFACFC7AC93BC216382F413AAD674E21 flags verified ) + rom ( name "Zoey 101 (USA).gba" size 4194304 crc 9cf348a8 sha1 2953F982DFACFC7AC93BC216382F413AAD674E21 flags verified ) ) game ( name "Zoids Legacy (USA)" description "Zoids Legacy (USA)" - rom ( name "Zoids Legacy (USA).gba" size 8388608 crc 302E75F3 md5 220A6F1B9D8D63E7638248F24DBFA709 sha1 460FA2158606097F6E6F63CE966D2D6ECDD58D70 ) + rom ( name "Zoids Legacy (USA).gba" size 8388608 crc 302e75f3 sha1 460FA2158606097F6E6F63CE966D2D6ECDD58D70 flags verified ) ) game ( name "Zoids Saga (Japan)" description "Zoids Saga (Japan)" - rom ( name "Zoids Saga (Japan).gba" size 8388608 crc 5975DDA8 md5 36545C66BF7ABDBCED2B294A7DD8D419 sha1 75D8C15AC281EA93C8AC7CC7641C490799557081 ) + rom ( name "Zoids Saga (Japan).gba" size 8388608 crc 5975dda8 sha1 75D8C15AC281EA93C8AC7CC7641C490799557081 flags verified ) ) game ( - name "Zoids Saga Fuzors (Japan)" - description "Zoids Saga Fuzors (Japan)" - rom ( name "Zoids Saga Fuzors (Japan).gba" size 8388608 crc 094E16AD md5 02FD4433F3DACBFD1C921A54909AC365 sha1 F5269ABA2E5F587AA2F851F35E96C1CBC5E1A78A ) + name "Zoids Saga (Japan) (Rev 1)" + description "Zoids Saga (Japan) (Rev 1)" + rom ( name "Zoids Saga (Japan) (Rev 1).gba" size 8388608 crc 28e8b0d9 sha1 70BB546A7D00126D452C1D2C1CCDDAFB2CB91B37 flags verified ) +) + +game ( + name "Zoids Saga - Fuzors (Japan)" + description "Zoids Saga - Fuzors (Japan)" + rom ( name "Zoids Saga - Fuzors (Japan).gba" size 8388608 crc 094e16ad sha1 F5269ABA2E5F587AA2F851F35E96C1CBC5E1A78A flags verified ) ) game ( name "Zoids Saga II (Japan)" description "Zoids Saga II (Japan)" - rom ( name "Zoids Saga II (Japan).gba" size 8388608 crc 0C039503 md5 F7BDD0EB9CD94D4C3BF924654998C514 sha1 6014CA7C7AF931D62634BE4BAA992A2FE187413F ) + rom ( name "Zoids Saga II (Japan).gba" size 8388608 crc 0c039503 sha1 6014CA7C7AF931D62634BE4BAA992A2FE187413F flags verified ) ) game ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" description "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan)" - rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan).gba" size 16777216 crc 2804E589 md5 F4E3DEAD5AF182598623CF89F9A428F4 sha1 54A4DCDECA2EE9A22559EB104B88586386639097 ) + rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan).gba" size 16777216 crc 2804e589 sha1 54A4DCDECA2EE9A22559EB104B88586386639097 ) ) game ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1)" description "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1)" - rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1).gba" size 16777216 crc 71E2CD01 md5 6449DC62CDF67C4D4D293FEBD38DCFDA sha1 1A81843C3070DECEA4CBCA20C4563541400B2437 ) + rom ( name "Zoku Bokura no Taiyou - Taiyou Shounen Django (Japan) (Rev 1).gba" size 16777216 crc 71e2cd01 sha1 1A81843C3070DECEA4CBCA20C4563541400B2437 ) ) game ( name "Zone of the Enders - The Fist of Mars (USA)" description "Zone of the Enders - The Fist of Mars (USA)" - rom ( name "Zone of the Enders - The Fist of Mars (USA).gba" size 8388608 crc 24244415 md5 B9C0646696297FB21CFAD315C434CC2A sha1 1839F900E5F2C8A52A4CE160A8C35A572C2D388F ) + rom ( name "Zone of the Enders - The Fist of Mars (USA).gba" size 8388608 crc 24244415 sha1 1839F900E5F2C8A52A4CE160A8C35A572C2D388F ) ) game ( name "Zone of the Enders - The Fist of Mars (Europe) (En,Fr,De)" description "Zone of the Enders - The Fist of Mars (Europe) (En,Fr,De)" - rom ( name "Zone of the Enders - The Fist of Mars (Europe) (En,Fr,De).gba" size 8388608 crc 973496E0 md5 55B8193F7A2E96D6AF029E2411FE22CB sha1 2441DCC18125514596C36B7EBC090F3FB3644FDB flags verified ) + rom ( name "Zone of the Enders - The Fist of Mars (Europe) (En,Fr,De).gba" size 8388608 crc 973496e0 sha1 2441DCC18125514596C36B7EBC090F3FB3644FDB flags verified ) ) game ( name "ZooCube (USA)" description "ZooCube (USA)" - rom ( name "ZooCube (USA).gba" size 4194304 crc AF20BE72 md5 01457D05D4601CEFF3F6D27A31606C18 sha1 044713BEA5245EE6E31B8EC4744C0696F79B30D0 ) + rom ( name "ZooCube (USA).gba" size 4194304 crc af20be72 sha1 044713BEA5245EE6E31B8EC4744C0696F79B30D0 ) ) game ( name "ZooCube (Europe) (En,Fr,De,Es,It)" description "ZooCube (Europe) (En,Fr,De,Es,It)" - rom ( name "ZooCube (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4A23B8D6 md5 2097AFE595661F911CFFE25050D532EC sha1 5F47FD6EBD9738C85AC93B9FAA0266C8ABB26090 ) + rom ( name "ZooCube (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 4a23b8d6 sha1 5F47FD6EBD9738C85AC93B9FAA0266C8ABB26090 ) ) game ( name "ZooCube (Japan)" description "ZooCube (Japan)" - rom ( name "ZooCube (Japan).gba" size 4194304 crc 09A2255F md5 50C6DCC5065B594199D9FE8B764420A3 sha1 A008170113AEC5B9B9C1C710C997F0F5C0511DC5 ) + rom ( name "ZooCube (Japan).gba" size 4194304 crc 09a2255f sha1 A008170113AEC5B9B9C1C710C997F0F5C0511DC5 ) ) game ( - name "Zooo (Europe) (En,Fr,De,Es,It)" - description "Zooo (Europe) (En,Fr,De,Es,It)" - rom ( name "Zooo (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 897B2893 md5 E0EC4F5CD24D2F7B93EAC7F7D7B89398 sha1 9096450C4B29AB6E317D94CA09EE82F5B74DD4B1 flags verified ) + name "Zooo - Action Puzzle Game (Europe) (En,Fr,De,Es,It)" + description "Zooo - Action Puzzle Game (Europe) (En,Fr,De,Es,It)" + rom ( name "Zooo - Action Puzzle Game (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 897b2893 sha1 9096450C4B29AB6E317D94CA09EE82F5B74DD4B1 flags verified ) ) clrmamepro ( name "Nintendo - Game Boy" description "Nintendo - Game Boy" - version 20160131-141427 - comment "no-intro | www.no-intro.org" + version 20190519-084229 + author "aci68, akubi, Bent, BigFred, BitLooter, C. V. Reynolds, darthcloud, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, jimmsu, kazumi213, leekindo, Money_114, NGEfreak, omonim2007, Powerpuff, PPLToast, relax, RetroUprising, rpg2813, Tauwasser, xNo, xuom2" + homepage No-Intro + url "http://www.no-intro.org" ) game ( - name "[BIOS] Nintendo Game Boy Boot ROM (World)" - description "[BIOS] Nintendo Game Boy Boot ROM (World)" - rom ( name "[BIOS] Nintendo Game Boy Boot ROM (World).gb" size 256 crc 59C8598E md5 32FBBD84168D3482956EB3C5051637F5 sha1 4ED31EC6B0B175BB109C0EB5FD3D193DA823339F ) + name "[BIOS] Nintendo Game Boy Boot ROM (World) (Rev 1)" + description "[BIOS] Nintendo Game Boy Boot ROM (World) (Rev 1)" + rom ( name "[BIOS] Nintendo Game Boy Boot ROM (World) (Rev 1).gb" size 256 crc 59c8598e sha1 4ED31EC6B0B175BB109C0EB5FD3D193DA823339F flags verified ) +) + +game ( + name "[BIOS] Nintendo Game Boy Boot ROM (Japan) (En)" + description "[BIOS] Nintendo Game Boy Boot ROM (Japan) (En)" + rom ( name "[BIOS] Nintendo Game Boy Boot ROM (Japan) (En).gb" size 256 crc c2f5cc97 sha1 8BD501E31921E9601788316DBD3CE9833A97BCBC flags verified ) +) + +game ( + name "[BIOS] Nintendo Game Boy Pocket Boot ROM (World)" + description "[BIOS] Nintendo Game Boy Pocket Boot ROM (World)" + rom ( name "[BIOS] Nintendo Game Boy Pocket Boot ROM (World).gb" size 256 crc e6920754 sha1 4E68F9DA03C310E84C523654B9026E51F26CE7F0 flags verified ) ) game ( name "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan)" description "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan)" - rom ( name "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan).gb" size 131072 crc B61CD120 md5 93CEA7134DB2A28B06D30729AD460DD6 sha1 0982BCC82DEB9C4DB08E602A22A2BB4F31E7E6AE ) + rom ( name "3 Choume no Tama - Tama and Friends - 3 Choume Obake Panic!! (Japan).gb" size 131072 crc b61cd120 sha1 0982BCC82DEB9C4DB08E602A22A2BB4F31E7E6AE flags verified ) ) game ( name "3-pun Yosou - Umaban Club (Japan)" description "3-pun Yosou - Umaban Club (Japan)" - rom ( name "3-pun Yosou - Umaban Club (Japan).gb" size 65536 crc CAFE0D2B md5 D4EBF9CF10DDA19DD2BAFD1C1673D762 sha1 76643F3F3481F7E515A24482779870862DD8B373 flags verified ) + rom ( name "3-pun Yosou - Umaban Club (Japan).gb" size 65536 crc cafe0d2b sha1 76643F3F3481F7E515A24482779870862DD8B373 flags verified ) ) game ( name "4 in 1 (Europe) (4B-002, Sachen) (Unl)" description "4 in 1 (Europe) (4B-002, Sachen) (Unl)" - rom ( name "4 in 1 (Europe) (4B-002, Sachen) (Unl).gb" size 65536 crc 5E438DB8 md5 53797D020821B171F9909BC300ED5AD1 sha1 D9CB1721854709BE7667F5DBCE0ADF2488C0919B flags verified ) + rom ( name "4 in 1 (Europe) (4B-002, Sachen) (Unl).gb" size 65536 crc 5e438db8 sha1 D9CB1721854709BE7667F5DBCE0ADF2488C0919B flags verified ) ) game ( name "4 in 1 (Europe) (4B-005, Sachen-Commin) (Unl)" description "4 in 1 (Europe) (4B-005, Sachen-Commin) (Unl)" - rom ( name "4 in 1 (Europe) (4B-005, Sachen-Commin) (Unl).gb" size 262144 crc F4310EB3 md5 2DFAEAF059179602D692B92EBB9A1DFE sha1 2107979104CFF88BCD635215A936BBC44354EA7C flags verified ) + rom ( name "4 in 1 (Europe) (4B-005, Sachen-Commin) (Unl).gb" size 262144 crc f4310eb3 sha1 2107979104CFF88BCD635215A936BBC44354EA7C flags verified ) ) game ( name "4 in 1 (Europe) (4B-007, Sachen) (Unl)" description "4 in 1 (Europe) (4B-007, Sachen) (Unl)" - serial "4B-007, SA-111" - rom ( name "4 in 1 (Europe) (4B-007, Sachen) (Unl).gb" size 262144 crc 62D9350E md5 04AEDABA42FDB90F6226B7F9A0B9319F sha1 0EEF7F3934508AB79E1CAD4DDF3BFDB3216B6B4F flags verified ) + rom ( name "4 in 1 (Europe) (4B-007, Sachen) (Unl).gb" size 262144 crc 62d9350e sha1 0EEF7F3934508AB79E1CAD4DDF3BFDB3216B6B4F flags verified ) ) game ( name "4 in 1 (Europe) (4B-001, Sachen-Commin) (Unl)" description "4 in 1 (Europe) (4B-001, Sachen-Commin) (Unl)" - rom ( name "4 in 1 (Europe) (4B-001, Sachen-Commin) (Unl).gb" size 262144 crc 82F06E93 md5 8CA82943C26210C92BC451015D6670A4 sha1 7506C75FDFA29935AFB1E85F5B6013516B2E9F92 flags verified ) + rom ( name "4 in 1 (Europe) (4B-001, Sachen-Commin) (Unl).gb" size 262144 crc 82f06e93 sha1 7506C75FDFA29935AFB1E85F5B6013516B2E9F92 flags verified ) ) game ( name "4 in 1 (Europe) (4B-008, Sachen) (Unl)" description "4 in 1 (Europe) (4B-008, Sachen) (Unl)" - rom ( name "4 in 1 (Europe) (4B-008, Sachen) (Unl).gb" size 262144 crc 740E9BC8 md5 95D3B0C6316A9FD3A55390FDE2B89A13 sha1 D7C11D56A42ED7C4EF2FE3C752931A63160D7429 flags verified ) + rom ( name "4 in 1 (Europe) (4B-008, Sachen) (Unl).gb" size 262144 crc 740e9bc8 sha1 D7C11D56A42ED7C4EF2FE3C752931A63160D7429 flags verified ) ) game ( name "4 in 1 (Europe) (4B-004, Sachen-Commin) (Unl)" description "4 in 1 (Europe) (4B-004, Sachen-Commin) (Unl)" - rom ( name "4 in 1 (Europe) (4B-004, Sachen-Commin) (Unl).gb" size 262144 crc C69A19F6 md5 7EB5D2C44EE56AA96FDB8E4968700953 sha1 CA7990DC03A3B3ADA1DCE37AFC4490DEAF872402 flags verified ) + rom ( name "4 in 1 (Europe) (4B-004, Sachen-Commin) (Unl).gb" size 262144 crc c69a19f6 sha1 CA7990DC03A3B3ADA1DCE37AFC4490DEAF872402 flags verified ) ) game ( name "4 in 1 (Europe) (4B-006, Sachen) (Unl)" description "4 in 1 (Europe) (4B-006, Sachen) (Unl)" - rom ( name "4 in 1 (Europe) (4B-006, Sachen) (Unl).gb" size 262144 crc 95398DA5 md5 A2A6F4AF9E87D6E34D92398A28D05149 sha1 2E856DE768C7CB442A206DE8C94A23548027BB60 flags verified ) + rom ( name "4 in 1 (Europe) (4B-006, Sachen) (Unl).gb" size 262144 crc 95398da5 sha1 2E856DE768C7CB442A206DE8C94A23548027BB60 flags verified ) ) game ( name "4 in 1 (Europe) (4B-009, Sachen) (Unl)" description "4 in 1 (Europe) (4B-009, Sachen) (Unl)" - rom ( name "4 in 1 (Europe) (4B-009, Sachen) (Unl).gb" size 262144 crc 114E1F1E md5 44DD0F3F4488C7660E432F0DA4A01A1F sha1 39743E21935A9115FCB4EE86D67D51BDB4B5F6D6 flags verified ) + rom ( name "4 in 1 (Europe) (4B-009, Sachen) (Unl).gb" size 262144 crc 114e1f1e sha1 39743E21935A9115FCB4EE86D67D51BDB4B5F6D6 flags verified ) +) + +game ( + name "4 in 1 (Taiwan) (En,Zh) (4B-003, Sachen-Commin) (Unl)" + description "4 in 1 (Taiwan) (En,Zh) (4B-003, Sachen-Commin) (Unl)" + rom ( name "4 in 1 (Taiwan) (En,Zh) (4B-003, Sachen-Commin) (Unl).gb" size 65536 crc c294aa21 sha1 B5A3EE09692476D801D873A703D508D17EE24FBD flags verified ) ) game ( name "4-in-1 Fun Pak (Japan)" description "4-in-1 Fun Pak (Japan)" - rom ( name "4-in-1 Fun Pak (Japan).gb" size 131072 crc 86F45343 md5 F1724349B22AA4F3A3E6C30D97117040 sha1 F1CF115DF0246F08D4E886CB046EBD2AA431A6C9 flags verified ) + rom ( name "4-in-1 Fun Pak (Japan).gb" size 131072 crc 86f45343 sha1 F1CF115DF0246F08D4E886CB046EBD2AA431A6C9 flags verified ) ) game ( name "4-in-1 Fun Pak (USA, Europe)" description "4-in-1 Fun Pak (USA, Europe)" - rom ( name "4-in-1 Fun Pak (USA, Europe).gb" size 131072 crc 0E0216E6 md5 B8D609B5DBAC6A2DAE6087FD9FEEC196 sha1 B1443C09EE3F2BEE5437111A635B6D84155F600E flags verified ) + rom ( name "4-in-1 Fun Pak (USA, Europe).gb" size 131072 crc 0e0216e6 sha1 B1443C09EE3F2BEE5437111A635B6D84155F600E flags verified ) ) game ( - name "4-in-1 Fun Pak Volume II (USA, Europe)" - description "4-in-1 Fun Pak Volume II (USA, Europe)" - rom ( name "4-in-1 Fun Pak Volume II (USA, Europe).gb" size 131072 crc 018B4A02 md5 71FEB6C7D5B764D5192C28EFE74D13C6 sha1 5EFEDDCE9E03AD56EE755C58FB658B045DC0FA53 flags verified ) + name "4-in-1 Funpak - Volume II (USA, Europe)" + description "4-in-1 Funpak - Volume II (USA, Europe)" + rom ( name "4-in-1 Funpak - Volume II (USA, Europe).gb" size 131072 crc 018b4a02 sha1 5EFEDDCE9E03AD56EE755C58FB658B045DC0FA53 flags verified ) ) game ( name "A-mazing Tater (USA)" description "A-mazing Tater (USA)" - rom ( name "A-mazing Tater (USA).gb" size 65536 crc D229AC62 md5 53B746BFF74C50CD3EBCF41161C66CF3 sha1 1E475CBD5FB7099DF91155A103698E4E66DA7A86 flags verified ) + rom ( name "A-mazing Tater (USA).gb" size 65536 crc d229ac62 sha1 1E475CBD5FB7099DF91155A103698E4E66DA7A86 flags verified ) ) game ( name "Aa Harimanada (Japan)" description "Aa Harimanada (Japan)" - rom ( name "Aa Harimanada (Japan).gb" size 131072 crc 5BFFCC28 md5 437FEC3B28D28314D580EC1E4D0BC9AE sha1 FF3565FCAC22B44BF542732D1B0B20BA96A6C961 ) + rom ( name "Aa Harimanada (Japan).gb" size 131072 crc 5bffcc28 sha1 FF3565FCAC22B44BF542732D1B0B20BA96A6C961 ) ) game ( name "Addams Family, The (Europe) (En,Fr,De)" description "Addams Family, The (Europe) (En,Fr,De)" - rom ( name "Addams Family, The (Europe) (En,Fr,De).gb" size 131072 crc 28FA451E md5 8814B9EC76241A6AC4DEEFA00EBEBAD8 sha1 2246DBDB6C58C77814CF034AE9224BE8E73C5084 flags verified ) + rom ( name "Addams Family, The (Europe) (En,Fr,De).gb" size 131072 crc 28fa451e sha1 2246DBDB6C58C77814CF034AE9224BE8E73C5084 flags verified ) ) game ( name "Addams Family, The (Japan)" description "Addams Family, The (Japan)" - rom ( name "Addams Family, The (Japan).gb" size 131072 crc 4C749C14 md5 DC2F4D927EDDA442DE2148AF590BEBB5 sha1 10A7D1491001657272755559ED593CC4400014EE ) + rom ( name "Addams Family, The (Japan).gb" size 131072 crc 4c749c14 sha1 10A7D1491001657272755559ED593CC4400014EE ) ) game ( name "Addams Family, The (USA)" description "Addams Family, The (USA)" - rom ( name "Addams Family, The (USA).gb" size 131072 crc C170A732 md5 F629F0B6D156BEC6ACB9E6B9DA4AD4E3 sha1 8710CEECBE3E7ADE67C0362CC3B455ACEB67A90D flags verified ) + rom ( name "Addams Family, The (USA).gb" size 131072 crc c170a732 sha1 8710CEECBE3E7ADE67C0362CC3B455ACEB67A90D flags verified ) ) game ( name "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe)" description "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe)" - rom ( name "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe).gb" size 131072 crc 7E054A88 md5 57726C28DC09949029A154F63B891DD0 sha1 F9020E3D104CB5C5347E28F45ED9E24E6C0EBDDD flags verified ) + rom ( name "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe).gb" size 131072 crc 7e054a88 sha1 F9020E3D104CB5C5347E28F45ED9E24E6C0EBDDD flags verified ) ) game ( name "Adventure Island (USA, Europe)" description "Adventure Island (USA, Europe)" - rom ( name "Adventure Island (USA, Europe).gb" size 131072 crc 64F4FA44 md5 D67E58BF5F39D5FB073FED85C3D9BEDE sha1 4A61945C1E3A37301748314777835C0E122A67E6 flags verified ) + rom ( name "Adventure Island (USA, Europe).gb" size 131072 crc 64f4fa44 sha1 4A61945C1E3A37301748314777835C0E122A67E6 flags verified ) ) game ( name "Adventure Island II - Aliens in Paradise (USA, Europe)" description "Adventure Island II - Aliens in Paradise (USA, Europe)" - rom ( name "Adventure Island II - Aliens in Paradise (USA, Europe).gb" size 262144 crc 783066CF md5 ED2444AFE317452E29C1C2258DA6963C sha1 1964FD5708150AA9F71C0A79D552466FD5BF5BF8 flags verified ) + rom ( name "Adventure Island II - Aliens in Paradise (USA, Europe).gb" size 262144 crc 783066cf sha1 1964FD5708150AA9F71C0A79D552466FD5BF5BF8 flags verified ) ) game ( name "Adventures of Lolo (Europe) (SGB Enhanced)" description "Adventures of Lolo (Europe) (SGB Enhanced)" - rom ( name "Adventures of Lolo (Europe) (SGB Enhanced).gb" size 262144 crc 176D2EEB md5 8F6B6EF366A787852F664D945C86EB72 sha1 E09277358A7FD4F3A6206464DD9D39F3ABE66A53 flags verified ) + rom ( name "Adventures of Lolo (Europe) (SGB Enhanced).gb" size 262144 crc 176d2eeb sha1 E09277358A7FD4F3A6206464DD9D39F3ABE66A53 flags verified ) ) game ( - name "Adventures of Pinocchio, The (Unknown) (Proto)" - description "Adventures of Pinocchio, The (Unknown) (Proto)" - rom ( name "Adventures of Pinocchio, The (Unknown) (Proto).gb" size 65536 crc 0B9DE1DC md5 BA78AC0638F36A89386B690D619F13B1 sha1 6808D5A5FBA9B58D67E91F22A2860E4E72F6EEC1 ) + name "Adventures of Pinocchio, The (Europe) (Proto)" + description "Adventures of Pinocchio, The (Europe) (Proto)" + rom ( name "Adventures of Pinocchio, The (Europe) (Proto).gb" size 65536 crc 0b9de1dc sha1 6808D5A5FBA9B58D67E91F22A2860E4E72F6EEC1 ) ) game ( name "Adventures of Rocky and Bullwinkle and Friends, The (USA)" description "Adventures of Rocky and Bullwinkle and Friends, The (USA)" - rom ( name "Adventures of Rocky and Bullwinkle and Friends, The (USA).gb" size 131072 crc 74C700A4 md5 9FE1A65A792825C2125D6FD47FFBB571 sha1 924A9BD18328DA81B5554E42DB873D1981EE9B20 ) + rom ( name "Adventures of Rocky and Bullwinkle and Friends, The (USA).gb" size 131072 crc 74c700a4 sha1 924A9BD18328DA81B5554E42DB873D1981EE9B20 ) ) game ( name "Adventures of Star Saver, The (USA, Europe)" description "Adventures of Star Saver, The (USA, Europe)" - rom ( name "Adventures of Star Saver, The (USA, Europe).gb" size 131072 crc 5D461374 md5 91ECEC5F8D06F18724BD1462B53C4B3D sha1 408B19A92C73DAA11B3B1A52AA6A987CC6615E97 flags verified ) + rom ( name "Adventures of Star Saver, The (USA, Europe).gb" size 131072 crc 5d461374 sha1 408B19A92C73DAA11B3B1A52AA6A987CC6615E97 flags verified ) ) game ( - name "Aero Star (Japan)" - description "Aero Star (Japan)" - rom ( name "Aero Star (Japan).gb" size 131072 crc DFA3B28A md5 4B4D6E6D4870D36A26E6FE6AD73B0EAC sha1 1088817172C10A9080AB6859DA85A074569E2CBA ) + name "Aerostar (Japan)" + description "Aerostar (Japan)" + rom ( name "Aerostar (Japan).gb" size 131072 crc dfa3b28a sha1 1088817172C10A9080AB6859DA85A074569E2CBA flags verified ) ) game ( name "Aerostar (USA, Europe)" description "Aerostar (USA, Europe)" - rom ( name "Aerostar (USA, Europe).gb" size 131072 crc F6FD275E md5 F777A4526089A83CA758EFBF01007EC1 sha1 2CB231E616008F2C809E0B2CAF40F477689E6D07 flags verified ) + rom ( name "Aerostar (USA, Europe).gb" size 131072 crc f6fd275e sha1 2CB231E616008F2C809E0B2CAF40F477689E6D07 flags verified ) ) game ( name "After Burst (Japan)" description "After Burst (Japan)" - rom ( name "After Burst (Japan).gb" size 65536 crc C0049D77 md5 B5C541C765FD3A5767B3FA1CFC821587 sha1 459CB97524669B0DE6CD7CFADA61AD67339232F1 ) + rom ( name "After Burst (Japan).gb" size 65536 crc c0049d77 sha1 459CB97524669B0DE6CD7CFADA61AD67339232F1 flags verified ) ) game ( name "Agro Soar (Australia)" description "Agro Soar (Australia)" - rom ( name "Agro Soar (Australia).gb" size 131072 crc 9B7945EA md5 C8BAB3886324F6AEC60B65D8584453A1 sha1 D635761F247301FE6BAE4D71EE67CEEF384CA53A flags verified ) + rom ( name "Agro Soar (Australia).gb" size 131072 crc 9b7945ea sha1 D635761F247301FE6BAE4D71EE67CEEF384CA53A flags verified ) ) game ( name "Akazukin Chacha (Japan) (SGB Enhanced)" description "Akazukin Chacha (Japan) (SGB Enhanced)" - rom ( name "Akazukin Chacha (Japan) (SGB Enhanced).gb" size 262144 crc 898609B4 md5 9A5215658C60A1802B11F728C292B536 sha1 D07970A7EAE51AEF8C4E8B4BCDD57AEED6360BDD flags verified ) + rom ( name "Akazukin Chacha (Japan) (SGB Enhanced).gb" size 262144 crc 898609b4 sha1 D07970A7EAE51AEF8C4E8B4BCDD57AEED6360BDD flags verified ) ) game ( name "Akumajou Dracula - Shikkoku Taru Zensoukyoku - Dark Night Prelude (Japan) (SGB Enhanced)" description "Akumajou Dracula - Shikkoku Taru Zensoukyoku - Dark Night Prelude (Japan) (SGB Enhanced)" - rom ( name "Akumajou Dracula - Shikkoku Taru Zensoukyoku - Dark Night Prelude (Japan) (SGB Enhanced).gb" size 262144 crc 4825B25F md5 6761F77E6DAA82120DD7C73ADEEC777E sha1 BAAA12BE322ADC005E51B43C73A352420D7CD034 ) + rom ( name "Akumajou Dracula - Shikkoku Taru Zensoukyoku - Dark Night Prelude (Japan) (SGB Enhanced).gb" size 262144 crc 4825b25f sha1 BAAA12BE322ADC005E51B43C73A352420D7CD034 ) ) game ( name "Akumajou Special - Boku Dracula-kun (Japan)" description "Akumajou Special - Boku Dracula-kun (Japan)" - rom ( name "Akumajou Special - Boku Dracula-kun (Japan).gb" size 262144 crc E8335398 md5 63F593E38A526A10FF3FA5AEC1C8CCB0 sha1 F2F15DA8ED94BC8652C23965428F6D767E506E38 flags verified ) + rom ( name "Akumajou Special - Boku Dracula-kun (Japan).gb" size 262144 crc e8335398 sha1 F2F15DA8ED94BC8652C23965428F6D767E506E38 flags verified ) ) game ( name "Aladdin (Europe) (SGB Enhanced)" description "Aladdin (Europe) (SGB Enhanced)" - rom ( name "Aladdin (Europe) (SGB Enhanced).gb" size 262144 crc 283C58B7 md5 781F768D5211ABA1E4CF383D4585C1BD sha1 A40694A808C5A0D3EEB386F81AD5B0C11163238F flags verified ) + rom ( name "Aladdin (Europe) (SGB Enhanced).gb" size 262144 crc 283c58b7 sha1 A40694A808C5A0D3EEB386F81AD5B0C11163238F flags verified ) ) game ( name "Aladdin (USA) (SGB Enhanced)" description "Aladdin (USA) (SGB Enhanced)" - rom ( name "Aladdin (USA) (SGB Enhanced).gb" size 262144 crc AF6BDC50 md5 ED5525A71DDA6EAF4BBF8D5601B6B3B9 sha1 81B4E56AE235FBB123D7AD4BD7C1D96C3B69EB72 ) + rom ( name "Aladdin (USA) (SGB Enhanced).gb" size 262144 crc af6bdc50 sha1 81B4E56AE235FBB123D7AD4BD7C1D96C3B69EB72 ) ) game ( name "Alfred Chicken (Europe)" description "Alfred Chicken (Europe)" - rom ( name "Alfred Chicken (Europe).gb" size 131072 crc 3CAB28D9 md5 B83F3C669D22BC74C72743821AE3AAA3 sha1 BC7327008DE518DDFAD0AD5C69896921DC2378E0 ) + rom ( name "Alfred Chicken (Europe).gb" size 131072 crc 3cab28d9 sha1 BC7327008DE518DDFAD0AD5C69896921DC2378E0 flags verified ) ) game ( name "Alfred Chicken (Japan) (SGB Enhanced)" description "Alfred Chicken (Japan) (SGB Enhanced)" - rom ( name "Alfred Chicken (Japan) (SGB Enhanced).gb" size 262144 crc 1089098F md5 A95E6579F8D6048C5E150C41D180C782 sha1 E04DDF4DF8B5EF70D85E0523D277ABFC68C61496 ) + rom ( name "Alfred Chicken (Japan) (SGB Enhanced).gb" size 262144 crc 1089098f sha1 E04DDF4DF8B5EF70D85E0523D277ABFC68C61496 ) ) game ( name "Alfred Chicken (USA)" description "Alfred Chicken (USA)" - rom ( name "Alfred Chicken (USA).gb" size 131072 crc 3B9C3BC6 md5 CAC921F8EEC70D5CCD8A2DB8F473A084 sha1 80C39D93CA58D0D6144FE7F7BDD47C3A4FCF0438 ) + rom ( name "Alfred Chicken (USA).gb" size 131072 crc 3b9c3bc6 sha1 80C39D93CA58D0D6144FE7F7BDD47C3A4FCF0438 ) ) game ( name "Alien 3 (Japan)" description "Alien 3 (Japan)" - rom ( name "Alien 3 (Japan).gb" size 131072 crc E59049B2 md5 4F5C4C439F1134177E02D72C794882BA sha1 4A3E7EB0EDAEFEC096BAA0019B3CBA28B4796689 ) + rom ( name "Alien 3 (Japan).gb" size 131072 crc e59049b2 sha1 4A3E7EB0EDAEFEC096BAA0019B3CBA28B4796689 ) ) game ( name "Alien 3 (USA, Europe)" description "Alien 3 (USA, Europe)" - rom ( name "Alien 3 (USA, Europe).gb" size 131072 crc EFFB960B md5 B3F3D35F58A0EA3AFFC0EC6D4EE1183D sha1 AB4D11EEE7FAEA42C637505469E0671C9D4A83F8 flags verified ) + rom ( name "Alien 3 (USA, Europe).gb" size 131072 crc effb960b sha1 AB4D11EEE7FAEA42C637505469E0671C9D4A83F8 flags verified ) ) game ( name "Alien Olympics (Europe)" description "Alien Olympics (Europe)" - rom ( name "Alien Olympics (Europe).gb" size 131072 crc 583C0E4E md5 D300BF9412617A95B00B80FA468A8A04 sha1 C6A69416D3F18071942D222D528B1C9D25F980B7 flags verified ) + rom ( name "Alien Olympics (Europe).gb" size 131072 crc 583c0e4e sha1 C6A69416D3F18071942D222D528B1C9D25F980B7 flags verified ) ) game ( name "Alien vs Predator (Japan)" description "Alien vs Predator (Japan)" - rom ( name "Alien vs Predator (Japan).gb" size 131072 crc E884682B md5 AB916E1DF69E7B3401CB6EBD3F1798A7 sha1 5B21DC4A7B48E75DA725657D1CCDE868759E5699 ) + rom ( name "Alien vs Predator (Japan).gb" size 131072 crc e884682b sha1 5B21DC4A7B48E75DA725657D1CCDE868759E5699 ) ) game ( name "Alien vs Predator - The Last of His Clan (USA)" description "Alien vs Predator - The Last of His Clan (USA)" - rom ( name "Alien vs Predator - The Last of His Clan (USA).gb" size 131072 crc 4BBCF652 md5 50A208BD0A223C037E01FFE07B04FA5B sha1 C0D39EE87B908CDBD68C59F73E5DC2A7A6CCBEDC ) + rom ( name "Alien vs Predator - The Last of His Clan (USA).gb" size 131072 crc 4bbcf652 sha1 C0D39EE87B908CDBD68C59F73E5DC2A7A6CCBEDC ) ) game ( name "All-Star Baseball 99 (USA)" description "All-Star Baseball 99 (USA)" - rom ( name "All-Star Baseball 99 (USA).gb" size 524288 crc D51EE6D3 md5 79492CE68C61AE8E29B96DB1D2E2BF6F sha1 49D13EEF514D26CEE37B10FF602E21A92B87B69D ) + rom ( name "All-Star Baseball 99 (USA).gb" size 524288 crc d51ee6d3 sha1 49D13EEF514D26CEE37B10FF602E21A92B87B69D ) ) game ( name "Alleyway (World)" description "Alleyway (World)" - rom ( name "Alleyway (World).gb" size 32768 crc 5CC01586 md5 91128778A332495F77699EAF3A37FE30 sha1 0CF2B8D0428F389F5361F67A0CD1ACE05A1C75CC flags verified ) + rom ( name "Alleyway (World).gb" size 32768 crc 5cc01586 sha1 0CF2B8D0428F389F5361F67A0CD1ACE05A1C75CC flags verified ) ) game ( name "Altered Space - A 3-D Alien Adventure (Europe)" description "Altered Space - A 3-D Alien Adventure (Europe)" - rom ( name "Altered Space - A 3-D Alien Adventure (Europe).gb" size 131072 crc 24D5F785 md5 B4AB37EE420C11285BE1C634C34F5726 sha1 218DA72E38A847BC5152A226C98E843B4941A8A6 ) + rom ( name "Altered Space - A 3-D Alien Adventure (Europe).gb" size 131072 crc 24d5f785 sha1 218DA72E38A847BC5152A226C98E843B4941A8A6 ) ) game ( name "Altered Space - A 3-D Alien Adventure (Japan)" description "Altered Space - A 3-D Alien Adventure (Japan)" - rom ( name "Altered Space - A 3-D Alien Adventure (Japan).gb" size 131072 crc CE36E36E md5 3208CC9EE33A163CD7CAD242DB3E1F4A sha1 6D19DFEDF2C916F13A524ACFD7C4E26DE040E655 ) + rom ( name "Altered Space - A 3-D Alien Adventure (Japan).gb" size 131072 crc ce36e36e sha1 6D19DFEDF2C916F13A524ACFD7C4E26DE040E655 ) ) game ( name "Altered Space - A 3-D Alien Adventure (USA)" description "Altered Space - A 3-D Alien Adventure (USA)" - rom ( name "Altered Space - A 3-D Alien Adventure (USA).gb" size 131072 crc 141675D3 md5 012EE0A196C03CCA91A43A9EADBECFB6 sha1 CA586C59B2473A8BEC2F0F37504CB74E3A1E4D11 flags verified ) + rom ( name "Altered Space - A 3-D Alien Adventure (USA).gb" size 131072 crc 141675d3 sha1 CA586C59B2473A8BEC2F0F37504CB74E3A1E4D11 flags verified ) ) game ( name "Amazing Penguin (USA, Europe)" description "Amazing Penguin (USA, Europe)" - rom ( name "Amazing Penguin (USA, Europe).gb" size 65536 crc 3011D5CA md5 D8326BFEE457CCB2C0AFB8DD6AC11DB2 sha1 84CC6452823EB05EE38679AEC86E3CC6E4A50E6F flags verified ) + rom ( name "Amazing Penguin (USA, Europe).gb" size 65536 crc 3011d5ca sha1 84CC6452823EB05EE38679AEC86E3CC6E4A50E6F flags verified ) ) game ( name "Amazing Spider-Man, The (USA, Europe)" description "Amazing Spider-Man, The (USA, Europe)" - rom ( name "Amazing Spider-Man, The (USA, Europe).gb" size 65536 crc 2A4EAFE4 md5 4A967A8F1DD6F627E8B72950739C26D4 sha1 0EFFB4580EFEAA323174A960BFD521FA28A18959 flags verified ) + rom ( name "Amazing Spider-Man, The (USA, Europe).gb" size 65536 crc 2a4eafe4 sha1 0EFFB4580EFEAA323174A960BFD521FA28A18959 flags verified ) ) game ( name "America Oudan Ultra Quiz (Japan)" description "America Oudan Ultra Quiz (Japan)" - rom ( name "America Oudan Ultra Quiz (Japan).gb" size 262144 crc 3BE275CD md5 C0CA6588162206B5982BA77BCF6397CE sha1 9761F22250FAF9C241FD7F9E2D00436F3FD454E7 flags verified ) + rom ( name "America Oudan Ultra Quiz (Japan).gb" size 262144 crc 3be275cd sha1 9761F22250FAF9C241FD7F9E2D00436F3FD454E7 flags verified ) ) game ( name "America Oudan Ultra Quiz Part 2 (Japan)" description "America Oudan Ultra Quiz Part 2 (Japan)" - rom ( name "America Oudan Ultra Quiz Part 2 (Japan).gb" size 262144 crc 1B3231C8 md5 9148245E7196C286506AD6B8BEF73E35 sha1 34C417F6F9DB7E8021FB1AF6C12F22C9B48BB723 flags verified ) + rom ( name "America Oudan Ultra Quiz Part 2 (Japan).gb" size 262144 crc 1b3231c8 sha1 34C417F6F9DB7E8021FB1AF6C12F22C9B48BB723 flags verified ) +) + +game ( + name "America Oudan Ultra Quiz Part 2 (Japan) (Rev 1)" + description "America Oudan Ultra Quiz Part 2 (Japan) (Rev 1)" + rom ( name "America Oudan Ultra Quiz Part 2 (Japan) (Rev 1).gb" size 262144 crc 739c26fc sha1 CB3ED70F4D095405DF2C322C528CAB2A00D56557 flags verified ) ) game ( name "America Oudan Ultra Quiz Part 3 - Champion Taikai (Japan)" description "America Oudan Ultra Quiz Part 3 - Champion Taikai (Japan)" - rom ( name "America Oudan Ultra Quiz Part 3 - Champion Taikai (Japan).gb" size 262144 crc 80CAC37C md5 EF84A328B1C87D22448ACCDB713A2329 sha1 61ACFB83A35B2D73FAD607DDD7FC1AC49E41492E flags verified ) + rom ( name "America Oudan Ultra Quiz Part 3 - Champion Taikai (Japan).gb" size 262144 crc 80cac37c sha1 61ACFB83A35B2D73FAD607DDD7FC1AC49E41492E flags verified ) ) game ( name "America Oudan Ultra Quiz Part 4 (Japan)" description "America Oudan Ultra Quiz Part 4 (Japan)" - rom ( name "America Oudan Ultra Quiz Part 4 (Japan).gb" size 262144 crc A76043C8 md5 6F32E45CC1829AB2FC3048634B68D749 sha1 30184DE60214B8D16D044433CD92F0B2A975E9D6 flags verified ) + rom ( name "America Oudan Ultra Quiz Part 4 (Japan).gb" size 262144 crc a76043c8 sha1 30184DE60214B8D16D044433CD92F0B2A975E9D6 flags verified ) ) game ( name "Amida (Japan)" description "Amida (Japan)" - rom ( name "Amida (Japan).gb" size 32768 crc 60128AA8 md5 9642B7C599B47135CBD4E45E039D608D sha1 2B502583AA73CB72557589791DEC7E28A2D29969 ) + rom ( name "Amida (Japan).gb" size 32768 crc 60128aa8 sha1 2B502583AA73CB72557589791DEC7E28A2D29969 ) ) game ( name "Animal Breeder (Japan) (SGB Enhanced)" description "Animal Breeder (Japan) (SGB Enhanced)" - rom ( name "Animal Breeder (Japan) (SGB Enhanced).gb" size 524288 crc C2EEC22F md5 54CEAD768696A61B7CD31F91C0C58021 sha1 A34B7C4ACC4454D96F93A7B04069ADBCC3BC75A0 flags verified ) + rom ( name "Animal Breeder (Japan) (SGB Enhanced).gb" size 524288 crc c2eec22f sha1 A34B7C4ACC4454D96F93A7B04069ADBCC3BC75A0 flags verified ) ) game ( name "Animal Breeder 2 (Japan) (SGB Enhanced)" description "Animal Breeder 2 (Japan) (SGB Enhanced)" - rom ( name "Animal Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 8D573F37 md5 208B978E1EE53EFA875CD6DFC42223F2 sha1 214D75221DBFB1A562740AA53E0239A73BEE9A2D flags verified ) + rom ( name "Animal Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 8d573f37 sha1 214D75221DBFB1A562740AA53E0239A73BEE9A2D flags verified ) ) game ( name "Animaniacs (Europe) (SGB Enhanced)" description "Animaniacs (Europe) (SGB Enhanced)" - rom ( name "Animaniacs (Europe) (SGB Enhanced).gb" size 262144 crc 7B23E05C md5 AE3F9A9C9A1CE63578BA68B3511C359C sha1 031421F49F98A15187012DC3F15960B260B9979F flags verified ) + rom ( name "Animaniacs (Europe) (SGB Enhanced).gb" size 262144 crc 7b23e05c sha1 031421F49F98A15187012DC3F15960B260B9979F flags verified ) ) game ( name "Animaniacs (USA) (SGB Enhanced)" description "Animaniacs (USA) (SGB Enhanced)" - rom ( name "Animaniacs (USA) (SGB Enhanced).gb" size 262144 crc 673C815D md5 84FF06249F96442626CDD75A5FA440CE sha1 A0732F81E0C4F1BBA592563BDC0EAAE9D759EF28 ) + rom ( name "Animaniacs (USA) (SGB Enhanced).gb" size 262144 crc 673c815d sha1 A0732F81E0C4F1BBA592563BDC0EAAE9D759EF28 ) ) game ( name "Another Bible (Japan) (SGB Enhanced)" description "Another Bible (Japan) (SGB Enhanced)" - rom ( name "Another Bible (Japan) (SGB Enhanced).gb" size 524288 crc 4A486435 md5 FF9196CAA266AE36D409CE7E53DDC77A sha1 6A5D0DA889247169135665DC91F153305E1C71B6 ) + rom ( name "Another Bible (Japan) (SGB Enhanced).gb" size 524288 crc 4a486435 sha1 6A5D0DA889247169135665DC91F153305E1C71B6 ) ) game ( name "Aoki Densetsu Shoot! (Japan) (SGB Enhanced)" description "Aoki Densetsu Shoot! (Japan) (SGB Enhanced)" - rom ( name "Aoki Densetsu Shoot! (Japan) (SGB Enhanced).gb" size 262144 crc 08727760 md5 6CBAAF40726A834BA7B3D7F179A140FE sha1 95574E1EEF5FBEBDE6F068091BC7298000EA2397 flags verified ) + rom ( name "Aoki Densetsu Shoot! (Japan) (SGB Enhanced).gb" size 262144 crc 08727760 sha1 95574E1EEF5FBEBDE6F068091BC7298000EA2397 flags verified ) ) game ( name "Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe) (SGB Enhanced)" description "Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe) (SGB Enhanced)" - rom ( name "Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe) (SGB Enhanced).gb" size 131072 crc 8259AC54 md5 25EC0916FF6F24A1878A9F30991D301D sha1 A4849175191C44D878AFF9EF1A86C3FE5E22E266 flags verified ) + rom ( name "Arcade Classic No. 1 - Asteroids & Missile Command (USA, Europe) (SGB Enhanced).gb" size 131072 crc 8259ac54 sha1 A4849175191C44D878AFF9EF1A86C3FE5E22E266 flags verified ) ) game ( name "Arcade Classic No. 2 - Centipede & Millipede (USA, Europe) (SGB Enhanced)" description "Arcade Classic No. 2 - Centipede & Millipede (USA, Europe) (SGB Enhanced)" - rom ( name "Arcade Classic No. 2 - Centipede & Millipede (USA, Europe) (SGB Enhanced).gb" size 131072 crc B14C3B31 md5 516085555E451966B9DD5166DFE6C728 sha1 405BC3736CFBEA3F2259AD3E53A9D64C6523DE4A flags verified ) + rom ( name "Arcade Classic No. 2 - Centipede & Millipede (USA, Europe) (SGB Enhanced).gb" size 131072 crc b14c3b31 sha1 405BC3736CFBEA3F2259AD3E53A9D64C6523DE4A flags verified ) ) game ( name "Arcade Classic No. 3 - Galaga & Galaxian (Europe) (SGB Enhanced)" description "Arcade Classic No. 3 - Galaga & Galaxian (Europe) (SGB Enhanced)" - rom ( name "Arcade Classic No. 3 - Galaga & Galaxian (Europe) (SGB Enhanced).gb" size 131072 crc D06B3F8A md5 08F46BB59E52562F08C76F4E6C0040C5 sha1 59EA594AF8520732F78C337F5C96A5BA2BDDF1CB flags verified ) + rom ( name "Arcade Classic No. 3 - Galaga & Galaxian (Europe) (SGB Enhanced).gb" size 131072 crc d06b3f8a sha1 59EA594AF8520732F78C337F5C96A5BA2BDDF1CB flags verified ) ) game ( name "Arcade Classic No. 3 - Galaga & Galaxian (USA) (SGB Enhanced)" description "Arcade Classic No. 3 - Galaga & Galaxian (USA) (SGB Enhanced)" - rom ( name "Arcade Classic No. 3 - Galaga & Galaxian (USA) (SGB Enhanced).gb" size 131072 crc 6A6ECFEC md5 19FD29EFAF7EA9E314BD613954A92169 sha1 739671D6CF151FA5527D68F78345197D278CDF19 flags verified ) + rom ( name "Arcade Classic No. 3 - Galaga & Galaxian (USA) (SGB Enhanced).gb" size 131072 crc 6a6ecfec sha1 739671D6CF151FA5527D68F78345197D278CDF19 flags verified ) ) game ( name "Arcade Classic No. 4 - Defender & Joust (USA, Europe) (SGB Enhanced)" description "Arcade Classic No. 4 - Defender & Joust (USA, Europe) (SGB Enhanced)" - rom ( name "Arcade Classic No. 4 - Defender & Joust (USA, Europe) (SGB Enhanced).gb" size 131072 crc 1C829CE3 md5 211A15218FA66E4A09BC253AE064991C sha1 6B046CA1E15E6CECB29E086A5B23EB0019419936 flags verified ) + rom ( name "Arcade Classic No. 4 - Defender & Joust (USA, Europe) (SGB Enhanced).gb" size 131072 crc 1c829ce3 sha1 6B046CA1E15E6CECB29E086A5B23EB0019419936 flags verified ) ) game ( - name "Arcade Classics - Battlezone & Super Breakout (USA, Europe) (SGB Enhanced)" - description "Arcade Classics - Battlezone & Super Breakout (USA, Europe) (SGB Enhanced)" - rom ( name "Arcade Classics - Battlezone & Super Breakout (USA, Europe) (SGB Enhanced).gb" size 262144 crc 6C292739 md5 E1B89445B1E8992D93319C52D4D7CA3B sha1 7D78B06AD896FB949E28858D141F73A37C550FE2 flags verified ) + name "Arcade Classics - Super Breakout & Battlezone (USA, Europe) (SGB Enhanced)" + description "Arcade Classics - Super Breakout & Battlezone (USA, Europe) (SGB Enhanced)" + rom ( name "Arcade Classics - Super Breakout & Battlezone (USA, Europe) (SGB Enhanced).gb" size 262144 crc 6c292739 sha1 7D78B06AD896FB949E28858D141F73A37C550FE2 flags verified ) ) game ( name "Aretha (Japan)" description "Aretha (Japan)" - rom ( name "Aretha (Japan).gb" size 131072 crc 1DB65649 md5 9C23D37D51A593E82378DAD038A52EF2 sha1 EAB8F13D110634F4EE750AC93E4F25D91A85000F flags verified ) + rom ( name "Aretha (Japan).gb" size 131072 crc 1db65649 sha1 EAB8F13D110634F4EE750AC93E4F25D91A85000F flags verified ) ) game ( name "Aretha II (Japan)" description "Aretha II (Japan)" - rom ( name "Aretha II (Japan).gb" size 262144 crc 086E4FC5 md5 A3059206EF517091A475249CE6C0DB4F sha1 5634A05EA8E93AF3DD0E41823576BF6295F8DF1F flags verified ) + rom ( name "Aretha II (Japan).gb" size 262144 crc 086e4fc5 sha1 5634A05EA8E93AF3DD0E41823576BF6295F8DF1F flags verified ) ) game ( name "Aretha III (Japan)" description "Aretha III (Japan)" - rom ( name "Aretha III (Japan).gb" size 262144 crc 430D3D6B md5 BB0CCA048A51DDBAE426221BB3D2E508 sha1 F57FF26D31283C88CC4C414B18EF6F182D07DA9D flags verified ) + rom ( name "Aretha III (Japan).gb" size 262144 crc 430d3d6b sha1 F57FF26D31283C88CC4C414B18EF6F182D07DA9D flags verified ) ) game ( name "Asmik-kun World 2 (Japan)" description "Asmik-kun World 2 (Japan)" - rom ( name "Asmik-kun World 2 (Japan).gb" size 131072 crc CAAE6B11 md5 24DB7B8D9080B1626DD949331AC40ACA sha1 4C738153A5C9F861117CC23CFEDF2C37672E1097 flags verified ) + rom ( name "Asmik-kun World 2 (Japan).gb" size 131072 crc caae6b11 sha1 4C738153A5C9F861117CC23CFEDF2C37672E1097 flags verified ) ) game ( name "Asterix (Europe) (En,Fr,De,Es,It)" description "Asterix (Europe) (En,Fr,De,Es,It)" - rom ( name "Asterix (Europe) (En,Fr,De,Es,It).gb" size 131072 crc 097FFE2C md5 812DB832566202610BB1E42E643E2B93 sha1 7D4CA6925826C0FFCA3E3004479B5E9A5B6B311B flags verified ) + rom ( name "Asterix (Europe) (En,Fr,De,Es,It).gb" size 131072 crc 097ffe2c sha1 7D4CA6925826C0FFCA3E3004479B5E9A5B6B311B flags verified ) ) game ( - name "Asterix & Obelix (Europe) (En,Es) (SGB Enhanced)" - description "Asterix & Obelix (Europe) (En,Es) (SGB Enhanced)" - rom ( name "Asterix & Obelix (Europe) (En,Es) (SGB Enhanced).gb" size 262144 crc B1FD41D0 md5 CF5BE6D9C263D02039BFAAE93C1BD32C sha1 B6CD446962357D0F560A5C9FAE4C917E039FBB77 flags verified ) + name "Asterix & Obelix (Spain) (En,Es) (SGB Enhanced)" + description "Asterix & Obelix (Spain) (En,Es) (SGB Enhanced)" + rom ( name "Asterix & Obelix (Spain) (En,Es) (SGB Enhanced).gb" size 262144 crc b1fd41d0 sha1 B6CD446962357D0F560A5C9FAE4C917E039FBB77 flags verified ) ) game ( name "Asterix & Obelix (Europe) (Fr,De) (SGB Enhanced)" description "Asterix & Obelix (Europe) (Fr,De) (SGB Enhanced)" - rom ( name "Asterix & Obelix (Europe) (Fr,De) (SGB Enhanced).gb" size 262144 crc 5143E227 md5 5354465291244E5A035807C2666D185E sha1 EBC68B180680C7037B151B9A1B511B681499BA30 flags verified ) + rom ( name "Asterix & Obelix (Europe) (Fr,De) (SGB Enhanced).gb" size 262144 crc 5143e227 sha1 EBC68B180680C7037B151B9A1B511B681499BA30 flags verified ) ) game ( name "Asteroids (USA, Europe)" description "Asteroids (USA, Europe)" - rom ( name "Asteroids (USA, Europe).gb" size 32768 crc C1F88833 md5 13749826DF12DA4574E34CCB6D9C780D sha1 435DBDAA9B9D2E0D0BC7C1C010CDC5EC9BD9F359 flags verified ) + rom ( name "Asteroids (USA, Europe).gb" size 32768 crc c1f88833 sha1 435DBDAA9B9D2E0D0BC7C1C010CDC5EC9BD9F359 flags verified ) ) game ( name "Astro Rabby (Japan)" description "Astro Rabby (Japan)" - rom ( name "Astro Rabby (Japan).gb" size 65536 crc 61E48EEF md5 5A88B67ED5475E591747BC7956642456 sha1 3E53FD25F350C78A29E0642EE6DE80208930D469 ) + rom ( name "Astro Rabby (Japan).gb" size 65536 crc 61e48eef sha1 3E53FD25F350C78A29E0642EE6DE80208930D469 flags verified ) ) game ( name "Atomic Punk (USA)" description "Atomic Punk (USA)" - rom ( name "Atomic Punk (USA).gb" size 131072 crc C4720897 md5 76010C6FF6BD0C4E8AC934DC69FB96AB sha1 4B364B4C12B83AB7ADBEC074FAC951E2EB63DEA8 ) + rom ( name "Atomic Punk (USA).gb" size 131072 crc c4720897 sha1 4B364B4C12B83AB7ADBEC074FAC951E2EB63DEA8 ) ) game ( name "Attack of the Killer Tomatoes (Japan)" description "Attack of the Killer Tomatoes (Japan)" - rom ( name "Attack of the Killer Tomatoes (Japan).gb" size 131072 crc 23068679 md5 BA556891321DBBC8DCE857CA2CF7D417 sha1 96CD454513DFB363CDA20BF0E72C6D74132A9487 ) + rom ( name "Attack of the Killer Tomatoes (Japan).gb" size 131072 crc 23068679 sha1 96CD454513DFB363CDA20BF0E72C6D74132A9487 ) ) game ( name "Attack of the Killer Tomatoes (USA, Europe)" description "Attack of the Killer Tomatoes (USA, Europe)" - rom ( name "Attack of the Killer Tomatoes (USA, Europe).gb" size 131072 crc B5B38860 md5 3910CE6B44B689A06889693771DED6DC sha1 CBBBA5D4F80F2B4AB3E882CEB4F79C293A17904F flags verified ) + rom ( name "Attack of the Killer Tomatoes (USA, Europe).gb" size 131072 crc b5b38860 sha1 CBBBA5D4F80F2B4AB3E882CEB4F79C293A17904F flags verified ) ) game ( name "Avenging Spirit (USA, Europe)" description "Avenging Spirit (USA, Europe)" - rom ( name "Avenging Spirit (USA, Europe).gb" size 262144 crc CF2BA5F7 md5 E88EAB57AB4614966748280BF3C97F52 sha1 D22CCA80A0855D7724539EF71F38E3F8F9656D6B flags verified ) + rom ( name "Avenging Spirit (USA, Europe).gb" size 262144 crc cf2ba5f7 sha1 D22CCA80A0855D7724539EF71F38E3F8F9656D6B flags verified ) ) game ( name "Ayakashi no Shiro (Japan)" description "Ayakashi no Shiro (Japan)" - rom ( name "Ayakashi no Shiro (Japan).gb" size 65536 crc DA90F5FC md5 8F3095C4D98694F19270D8C2788D5E46 sha1 DAD3EC1A054CBD092EEDFDB1D742B811C105181A ) + rom ( name "Ayakashi no Shiro (Japan).gb" size 65536 crc da90f5fc sha1 DAD3EC1A054CBD092EEDFDB1D742B811C105181A flags verified ) ) game ( name "B.C. Kid (Europe)" description "B.C. Kid (Europe)" - rom ( name "B.C. Kid (Europe).gb" size 262144 crc 373343E6 md5 D335D4D79ED002C7A67863E82CEAA472 sha1 B91F99408E4A6B69D505F304C176434321F837E7 flags verified ) + rom ( name "B.C. Kid (Europe).gb" size 262144 crc 373343e6 sha1 B91F99408E4A6B69D505F304C176434321F837E7 flags verified ) ) game ( name "B.C. Kid 2 (Europe) (SGB Enhanced)" description "B.C. Kid 2 (Europe) (SGB Enhanced)" - rom ( name "B.C. Kid 2 (Europe) (SGB Enhanced).gb" size 262144 crc C28EF062 md5 2A2AE531B2CEBD995508707B0E82B1B1 sha1 952A14298DCDE28975F2CDD61F781000AFB53125 ) + rom ( name "B.C. Kid 2 (Europe) (SGB Enhanced).gb" size 262144 crc c28ef062 sha1 952A14298DCDE28975F2CDD61F781000AFB53125 ) ) game ( name "Baby T-Rex (Europe)" description "Baby T-Rex (Europe)" - rom ( name "Baby T-Rex (Europe).gb" size 131072 crc 3F73FE7A md5 B9DF0BB1F84333A1E5AB4AF563525CDC sha1 30042C3FC60DF0DA25FA3DB3955A2E4657C1CCCF flags verified ) + rom ( name "Baby T-Rex (Europe).gb" size 131072 crc 3f73fe7a sha1 30042C3FC60DF0DA25FA3DB3955A2E4657C1CCCF flags verified ) ) game ( name "Bakenou TV '94 (Japan) (SGB Enhanced)" description "Bakenou TV '94 (Japan) (SGB Enhanced)" - rom ( name "Bakenou TV '94 (Japan) (SGB Enhanced).gb" size 131072 crc D1C3F371 md5 302F773A39FE0E45756B050EE94F0918 sha1 C567BDD1CA17750C853019F244E208FE812772FD ) + rom ( name "Bakenou TV '94 (Japan) (SGB Enhanced).gb" size 131072 crc d1c3f371 sha1 C567BDD1CA17750C853019F244E208FE812772FD ) ) game ( name "Bakenou V3 (Japan)" description "Bakenou V3 (Japan)" - rom ( name "Bakenou V3 (Japan).gb" size 131072 crc 4E2FFFE5 md5 614C8E744C8F07C6E3B29480478600D4 sha1 B1BF86F4FFB9AF9C5F1C592F0CABEDB95B405437 flags verified ) + rom ( name "Bakenou V3 (Japan).gb" size 131072 crc 4e2fffe5 sha1 B1BF86F4FFB9AF9C5F1C592F0CABEDB95B405437 flags verified ) ) game ( name "Bakuchou Retrieve Master (Japan) (SGB Enhanced)" description "Bakuchou Retrieve Master (Japan) (SGB Enhanced)" - rom ( name "Bakuchou Retrieve Master (Japan) (SGB Enhanced).gb" size 524288 crc 8A546DEC md5 7D775680308FC232D1C6547124BAB089 sha1 BFEA17B22B3AC91366156D8DB1A7DC619C7B5A28 flags verified ) + rom ( name "Bakuchou Retrieve Master (Japan) (SGB Enhanced).gb" size 524288 crc 8a546dec sha1 BFEA17B22B3AC91366156D8DB1A7DC619C7B5A28 flags verified ) ) game ( name "Bakuchou Retsuden Shou - Hyper Fishing (Japan) (SGB Enhanced)" description "Bakuchou Retsuden Shou - Hyper Fishing (Japan) (SGB Enhanced)" - rom ( name "Bakuchou Retsuden Shou - Hyper Fishing (Japan) (SGB Enhanced).gb" size 524288 crc AB3477C4 md5 7864D91F0A7CA1EEC93667BA88EC1DFC sha1 53808F56FA68AD8094D0E4FF62E06887B439BE9A flags verified ) + rom ( name "Bakuchou Retsuden Shou - Hyper Fishing (Japan) (SGB Enhanced).gb" size 524288 crc ab3477c4 sha1 53808F56FA68AD8094D0E4FF62E06887B439BE9A flags verified ) ) game ( name "Bakuretsu Senshi Warrior (Japan)" description "Bakuretsu Senshi Warrior (Japan)" - rom ( name "Bakuretsu Senshi Warrior (Japan).gb" size 65536 crc ECF1B801 md5 CBF1F4CA2288995C18DF0EF3025C9580 sha1 5F4E63796611A1ED72ACD2A5BFE2E2EA3BA5B211 flags verified ) + rom ( name "Bakuretsu Senshi Warrior (Japan).gb" size 65536 crc ecf1b801 sha1 5F4E63796611A1ED72ACD2A5BFE2E2EA3BA5B211 flags verified ) ) game ( name "Balloon Kid (USA, Europe)" description "Balloon Kid (USA, Europe)" - rom ( name "Balloon Kid (USA, Europe).gb" size 131072 crc D4B655EC md5 F70C60CA87714FA9D81BE60C9AC93DE0 sha1 0CB5ADC9BDEF5320F3F156EFED0D47A618E2299F flags verified ) + rom ( name "Balloon Kid (USA, Europe).gb" size 131072 crc d4b655ec sha1 0CB5ADC9BDEF5320F3F156EFED0D47A618E2299F flags verified ) ) game ( name "Bamse (Sweden)" description "Bamse (Sweden)" - rom ( name "Bamse (Sweden).gb" size 131072 crc 1B713DE0 md5 C7697C8DB218BCB35AA37D43E4278376 sha1 92C042A1B3B9704736B6D8B19259EFC5110C267D flags verified ) + rom ( name "Bamse (Sweden).gb" size 131072 crc 1b713de0 sha1 92C042A1B3B9704736B6D8B19259EFC5110C267D flags verified ) ) game ( name "Banishing Racer (Japan)" description "Banishing Racer (Japan)" - rom ( name "Banishing Racer (Japan).gb" size 131072 crc 3D13EC6A md5 8FDFFB08770609255EC3CD314F79F976 sha1 DF121645C367D5809ED77BFE48AA537F0D61D276 ) + rom ( name "Banishing Racer (Japan).gb" size 131072 crc 3d13ec6a sha1 DF121645C367D5809ED77BFE48AA537F0D61D276 ) ) game ( name "Barbie - Game Girl (USA, Europe)" description "Barbie - Game Girl (USA, Europe)" - rom ( name "Barbie - Game Girl (USA, Europe).gb" size 131072 crc 94C26CDF md5 159C8CA77E153B1CC5FE6D5D82A091C2 sha1 6660E4457A1DE3DE1947A90C5EA9FF012D50336E flags verified ) + rom ( name "Barbie - Game Girl (USA, Europe).gb" size 131072 crc 94c26cdf sha1 6660E4457A1DE3DE1947A90C5EA9FF012D50336E flags verified ) ) game ( name "Bart no Survival Camp (Japan)" description "Bart no Survival Camp (Japan)" - rom ( name "Bart no Survival Camp (Japan).gb" size 131072 crc 0FD66B1A md5 0434A1320607CE8E79DE69B10C7A1245 sha1 F0D855BBA656B628C7DD9ED9E586853BE75B790F ) + rom ( name "Bart no Survival Camp (Japan).gb" size 131072 crc 0fd66b1a sha1 F0D855BBA656B628C7DD9ED9E586853BE75B790F ) ) game ( name "Bart Simpson's Escape from Camp Deadly (USA, Europe)" description "Bart Simpson's Escape from Camp Deadly (USA, Europe)" - rom ( name "Bart Simpson's Escape from Camp Deadly (USA, Europe).gb" size 131072 crc 5546A382 md5 E731FA23D9CD0C3D4DEC7D5565BEEF61 sha1 89B7B2D4684D703EA5D323E3AAF4910DCDBC47D3 flags verified ) + rom ( name "Bart Simpson's Escape from Camp Deadly (USA, Europe).gb" size 131072 crc 5546a382 sha1 89B7B2D4684D703EA5D323E3AAF4910DCDBC47D3 flags verified ) ) game ( name "Baseball (World)" description "Baseball (World)" - rom ( name "Baseball (World).gb" size 65536 crc 6EEA2526 md5 E7BCB3F5534C8363F855BA92D83CB2D9 sha1 BB613ED8D492D49DB35370BEC38D9F2515DC24C9 flags verified ) + rom ( name "Baseball (World).gb" size 65536 crc 6eea2526 sha1 BB613ED8D492D49DB35370BEC38D9F2515DC24C9 flags verified ) ) game ( name "Baseball Kids (Japan)" description "Baseball Kids (Japan)" - rom ( name "Baseball Kids (Japan).gb" size 131072 crc A503CB07 md5 CB62A0DD667FF4FC2F4EBE6F0AEF955F sha1 E4A49A9ECD7A9CE8BB552981E90903F21C741428 flags verified ) + rom ( name "Baseball Kids (Japan).gb" size 131072 crc a503cb07 sha1 E4A49A9ECD7A9CE8BB552981E90903F21C741428 flags verified ) ) game ( name "Bases Loaded for Game Boy (USA)" description "Bases Loaded for Game Boy (USA)" - rom ( name "Bases Loaded for Game Boy (USA).gb" size 131072 crc D37A2FDF md5 C1C084439399DC1541EE555BCABB7700 sha1 5220DB2E87622648CAEACDFB8D4F564C9BF479FC ) + rom ( name "Bases Loaded for Game Boy (USA).gb" size 131072 crc d37a2fdf sha1 5220DB2E87622648CAEACDFB8D4F564C9BF479FC ) ) game ( name "Bass Fishing Tatsujin Techou (Japan)" description "Bass Fishing Tatsujin Techou (Japan)" - rom ( name "Bass Fishing Tatsujin Techou (Japan).gb" size 524288 crc 7625E5A5 md5 AA6CB8AA7BEE968D77AAE59ACFBDE6D8 sha1 503A4CDD6D80CE779BA293022B21F98881AF2AB6 ) + rom ( name "Bass Fishing Tatsujin Techou (Japan).gb" size 524288 crc 7625e5a5 sha1 503A4CDD6D80CE779BA293022B21F98881AF2AB6 ) ) game ( name "Bataille Navale (France) (En,Fr,De,Es)" description "Bataille Navale (France) (En,Fr,De,Es)" - rom ( name "Bataille Navale (France) (En,Fr,De,Es).gb" size 131072 crc BAB8B727 md5 B91125B6018A0A879E356A32129F5B73 sha1 5C5162743546B258CC9C6316F1437137721F5E99 ) + rom ( name "Bataille Navale (France) (En,Fr,De,Es).gb" size 131072 crc bab8b727 sha1 5C5162743546B258CC9C6316F1437137721F5E99 flags verified ) ) game ( name "Batman - Return of the Joker (Japan)" description "Batman - Return of the Joker (Japan)" - rom ( name "Batman - Return of the Joker (Japan).gb" size 131072 crc DE459A47 md5 9550FADC917DB38CACD0ECFB694F816C sha1 149586120C3AE9C9614FA6E6A5E298CCEAE16C4D ) + rom ( name "Batman - Return of the Joker (Japan).gb" size 131072 crc de459a47 sha1 149586120C3AE9C9614FA6E6A5E298CCEAE16C4D ) ) game ( name "Batman - Return of the Joker (USA, Europe)" description "Batman - Return of the Joker (USA, Europe)" - rom ( name "Batman - Return of the Joker (USA, Europe).gb" size 131072 crc 5124BBEC md5 97BC907DEBA1E7D7C9BC72FCA0310822 sha1 345A332175F58304F91111A13B770662E5EA92C3 flags verified ) + rom ( name "Batman - Return of the Joker (USA, Europe).gb" size 131072 crc 5124bbec sha1 345A332175F58304F91111A13B770662E5EA92C3 flags verified ) ) game ( name "Batman - The Animated Series (USA, Europe)" description "Batman - The Animated Series (USA, Europe)" - rom ( name "Batman - The Animated Series (USA, Europe).gb" size 131072 crc C8E578BF md5 AE073C63FF7D151DC2DD406830FBBDC2 sha1 4A8C1DD74B1279C0DC85AC2BEBB5DB2795CB67B0 flags verified ) + rom ( name "Batman - The Animated Series (USA, Europe).gb" size 131072 crc c8e578bf sha1 4A8C1DD74B1279C0DC85AC2BEBB5DB2795CB67B0 flags verified ) ) game ( name "Batman - The Video Game (World)" description "Batman - The Video Game (World)" - rom ( name "Batman - The Video Game (World).gb" size 131072 crc 6C41D3CD md5 03C6D84A951BE6703B7458478F4277B9 sha1 EF7D6684A0F737C01A1F2CC2C6609E0F3AC1310E flags verified ) + rom ( name "Batman - The Video Game (World).gb" size 131072 crc 6c41d3cd sha1 EF7D6684A0F737C01A1F2CC2C6609E0F3AC1310E flags verified ) ) game ( name "Batman Forever (Japan)" description "Batman Forever (Japan)" - rom ( name "Batman Forever (Japan).gb" size 262144 crc C2FD6244 md5 53D8596868FE081CEF40ECC02D463EA3 sha1 4FAB046D18ADDAFBC625FE4CEFEC37098747D716 ) + rom ( name "Batman Forever (Japan).gb" size 262144 crc c2fd6244 sha1 4FAB046D18ADDAFBC625FE4CEFEC37098747D716 ) ) game ( name "Batman Forever (USA, Europe)" description "Batman Forever (USA, Europe)" - rom ( name "Batman Forever (USA, Europe).gb" size 262144 crc EF3592CC md5 28737A5C760938A9746FA9E1A2FCEFC6 sha1 CB76B6D3EC9903A734F70FF11195F40F13F4D83F flags verified ) + rom ( name "Batman Forever (USA, Europe).gb" size 262144 crc ef3592cc sha1 CB76B6D3EC9903A734F70FF11195F40F13F4D83F flags verified ) ) game ( name "Battle Arena Toshinden (Europe) (SGB Enhanced)" description "Battle Arena Toshinden (Europe) (SGB Enhanced)" - rom ( name "Battle Arena Toshinden (Europe) (SGB Enhanced).gb" size 524288 crc CE34CCA4 md5 3E986CF3598E0A690FED48AA8C7D95B1 sha1 F4CC9193CA0B98C69C966CC32E37EAE444A8D53B flags verified ) + rom ( name "Battle Arena Toshinden (Europe) (SGB Enhanced).gb" size 524288 crc ce34cca4 sha1 F4CC9193CA0B98C69C966CC32E37EAE444A8D53B flags verified ) ) game ( name "Battle Arena Toshinden (USA) (SGB Enhanced)" description "Battle Arena Toshinden (USA) (SGB Enhanced)" - rom ( name "Battle Arena Toshinden (USA) (SGB Enhanced).gb" size 524288 crc 2D0C1073 md5 75B5F31FBACB972FC104B3E77D09003B sha1 9C337D3F56938AA46CFC8B85C0DB4631BCBE217C ) + rom ( name "Battle Arena Toshinden (USA) (SGB Enhanced).gb" size 524288 crc 2d0c1073 sha1 9C337D3F56938AA46CFC8B85C0DB4631BCBE217C ) ) game ( name "Battle Bull (Japan)" description "Battle Bull (Japan)" - rom ( name "Battle Bull (Japan).gb" size 131072 crc 5C69E449 md5 A58AD38354F16E3E6777E91DEDD9CE28 sha1 74ED574D2179BDF34A6E618A86BE9B3E70155370 ) + rom ( name "Battle Bull (Japan).gb" size 131072 crc 5c69e449 sha1 74ED574D2179BDF34A6E618A86BE9B3E70155370 ) ) game ( name "Battle Bull (USA)" description "Battle Bull (USA)" - rom ( name "Battle Bull (USA).gb" size 131072 crc D4D1AEA2 md5 D6D8E759C19C1BA384670F2A06B4D11B sha1 A553B2CF2A5D223B6AC8ACA4E9FD65B65087A1F4 ) + rom ( name "Battle Bull (USA).gb" size 131072 crc d4d1aea2 sha1 A553B2CF2A5D223B6AC8ACA4E9FD65B65087A1F4 flags verified ) ) game ( name "Battle Crusher (Japan) (SGB Enhanced)" description "Battle Crusher (Japan) (SGB Enhanced)" - rom ( name "Battle Crusher (Japan) (SGB Enhanced).gb" size 262144 crc EA4EB1A1 md5 C2AB034CEB1DC42C96A7A9301C382D20 sha1 AE07172C69A7BDECE4392016C6A6DD253623F5F8 ) + rom ( name "Battle Crusher (Japan) (SGB Enhanced).gb" size 262144 crc ea4eb1a1 sha1 AE07172C69A7BDECE4392016C6A6DD253623F5F8 ) ) game ( name "Battle Dodge Ball (Japan)" description "Battle Dodge Ball (Japan)" - rom ( name "Battle Dodge Ball (Japan).gb" size 131072 crc A99242C0 md5 9155B3E2A243BE1703A09934B2B80724 sha1 ED63709AF2DD22D2ABAA7E99B9DD5373B6CC91C4 ) + rom ( name "Battle Dodge Ball (Japan).gb" size 131072 crc a99242c0 sha1 ED63709AF2DD22D2ABAA7E99B9DD5373B6CC91C4 flags verified ) ) game ( name "Battle of Kingdom (Japan)" description "Battle of Kingdom (Japan)" - rom ( name "Battle of Kingdom (Japan).gb" size 131072 crc 35914DEB md5 F7AA9880DB8E7884618FF0DCAB6FBA85 sha1 5761F47A09F91A373BDA96840FE2560BFF1FFC97 ) + rom ( name "Battle of Kingdom (Japan).gb" size 131072 crc 35914deb sha1 5761F47A09F91A373BDA96840FE2560BFF1FFC97 ) ) game ( name "Battle of Olympus, The (Europe) (En,Fr,De,Es,It)" description "Battle of Olympus, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Battle of Olympus, The (Europe) (En,Fr,De,Es,It).gb" size 262144 crc CA450E93 md5 044C71562429DA60891A93A131A0304A sha1 C0CA1948C4BFCA795A29CE82AA5AB9215B9ED601 ) + rom ( name "Battle of Olympus, The (Europe) (En,Fr,De,Es,It).gb" size 262144 crc ca450e93 sha1 C0CA1948C4BFCA795A29CE82AA5AB9215B9ED601 ) ) game ( name "Battle Pingpong (Japan)" description "Battle Pingpong (Japan)" - rom ( name "Battle Pingpong (Japan).gb" size 65536 crc 7C787BC4 md5 F24CCB89C3FF60F54600D7B063D5A6C2 sha1 5008699F7A31A1A0722114F83E94591E99B22CC0 flags verified ) + rom ( name "Battle Pingpong (Japan).gb" size 65536 crc 7c787bc4 sha1 5008699F7A31A1A0722114F83E94591E99B22CC0 flags verified ) ) game ( name "Battle Space (Japan)" description "Battle Space (Japan)" - rom ( name "Battle Space (Japan).gb" size 65536 crc A828FD4F md5 C9DC09EA6D93D5114079F58C7BBF7982 sha1 76E47AD844ABDDE9EFF09EA29A014F9A1EAE5093 flags verified ) + rom ( name "Battle Space (Japan).gb" size 65536 crc a828fd4f sha1 76E47AD844ABDDE9EFF09EA29A014F9A1EAE5093 flags verified ) ) game ( name "Battle Unit Zeoth (Japan)" description "Battle Unit Zeoth (Japan)" - rom ( name "Battle Unit Zeoth (Japan).gb" size 131072 crc A1A1FE77 md5 2486AC22FF1ED53B4C8FA4F2D5226749 sha1 35413F3D4B4E68F521A90C3A48D4BD2B5BF90E09 ) + rom ( name "Battle Unit Zeoth (Japan).gb" size 131072 crc a1a1fe77 sha1 35413F3D4B4E68F521A90C3A48D4BD2B5BF90E09 ) ) game ( name "Battle Unit Zeoth (USA, Europe)" description "Battle Unit Zeoth (USA, Europe)" - rom ( name "Battle Unit Zeoth (USA, Europe).gb" size 131072 crc E67A92B3 md5 023A8FD8EACAD0656B5110DA26DCDD44 sha1 EBA09C60CD60FEBA0A7A9E82597DAD080CE78D22 flags verified ) + rom ( name "Battle Unit Zeoth (USA, Europe).gb" size 131072 crc e67a92b3 sha1 EBA09C60CD60FEBA0A7A9E82597DAD080CE78D22 flags verified ) ) game ( name "BattleCity (Japan)" description "BattleCity (Japan)" - rom ( name "BattleCity (Japan).gb" size 32768 crc A37A814A md5 E6980267D58310AF5AD57570045A95FA sha1 5C9A6077913B344C8889241EC5F9FDAAC7F24C8B ) + rom ( name "BattleCity (Japan).gb" size 32768 crc a37a814a sha1 5C9A6077913B344C8889241EC5F9FDAAC7F24C8B ) ) game ( name "Battleship (USA, Europe)" description "Battleship (USA, Europe)" - rom ( name "Battleship (USA, Europe).gb" size 65536 crc FEF62DA5 md5 D4F7ADE01AF0818A79BC809CF96118BB sha1 D3EFB4AFEBCF94B191A66797A6BAE2C90BA92C6A ) + rom ( name "Battleship (USA, Europe).gb" size 65536 crc fef62da5 sha1 D3EFB4AFEBCF94B191A66797A6BAE2C90BA92C6A ) ) game ( name "Battletoads (Japan)" description "Battletoads (Japan)" - rom ( name "Battletoads (Japan).gb" size 131072 crc 331CF7DE md5 3D57E0391C8191C105A4F015A0C103E9 sha1 666ED5D34F508C8805A67F4400FC01A1F2817E03 ) + rom ( name "Battletoads (Japan).gb" size 131072 crc 331cf7de sha1 666ED5D34F508C8805A67F4400FC01A1F2817E03 ) ) game ( name "Battletoads (USA, Europe)" description "Battletoads (USA, Europe)" - rom ( name "Battletoads (USA, Europe).gb" size 131072 crc B0C3361B md5 6D24C94D3ACD89B4B703F7BD2A504833 sha1 BA839BEA8F76BF955E3EDF7083D2CBE780244ADD flags verified ) + rom ( name "Battletoads (USA, Europe).gb" size 131072 crc b0c3361b sha1 BA839BEA8F76BF955E3EDF7083D2CBE780244ADD flags verified ) ) game ( name "Battletoads in Ragnarok's World (Europe)" description "Battletoads in Ragnarok's World (Europe)" - rom ( name "Battletoads in Ragnarok's World (Europe).gb" size 131072 crc 7FFC34EA md5 BC76C0516129C6791E4087F93F5D3C99 sha1 1852BD23644E28109B66FA937053C689A63F7729 flags verified ) + rom ( name "Battletoads in Ragnarok's World (Europe).gb" size 131072 crc 7ffc34ea sha1 1852BD23644E28109B66FA937053C689A63F7729 flags verified ) ) game ( name "Battletoads in Ragnarok's World (USA)" description "Battletoads in Ragnarok's World (USA)" - rom ( name "Battletoads in Ragnarok's World (USA).gb" size 131072 crc CE316C68 md5 4866EA7BDAA92C6986D4847209EBBD20 sha1 3DF1384E699B91689F015D7ABA65AB42410E24F5 ) + rom ( name "Battletoads in Ragnarok's World (USA).gb" size 131072 crc ce316c68 sha1 3DF1384E699B91689F015D7ABA65AB42410E24F5 ) ) game ( name "Battletoads-Double Dragon (Europe)" description "Battletoads-Double Dragon (Europe)" - rom ( name "Battletoads-Double Dragon (Europe).gb" size 262144 crc 7B217082 md5 EC8DFC2600756D4FF306EEDCD03DEFD2 sha1 5A834E0DC81703906EB441555E1AA31DE22D39D6 ) + rom ( name "Battletoads-Double Dragon (Europe).gb" size 262144 crc 7b217082 sha1 5A834E0DC81703906EB441555E1AA31DE22D39D6 ) ) game ( name "Battletoads-Double Dragon (USA)" description "Battletoads-Double Dragon (USA)" - rom ( name "Battletoads-Double Dragon (USA).gb" size 262144 crc A727F9CD md5 13EC0C660B5A963A07B39ECABF0E0AB5 sha1 CE68DF4DC2D604625164430266017B237B72303D ) + rom ( name "Battletoads-Double Dragon (USA).gb" size 262144 crc a727f9cd sha1 CE68DF4DC2D604625164430266017B237B72303D ) ) game ( name "Beavis and Butt-Head (USA, Europe)" description "Beavis and Butt-Head (USA, Europe)" - rom ( name "Beavis and Butt-Head (USA, Europe).gb" size 524288 crc AF1AE123 md5 8F160AA0B2F69A019911FD57AC8C5B31 sha1 918E9CC878A61D8174918C897182604F0C27B1D9 flags verified ) + rom ( name "Beavis and Butt-Head (USA, Europe).gb" size 524288 crc af1ae123 sha1 918E9CC878A61D8174918C897182604F0C27B1D9 flags verified ) ) game ( name "Beethoven (Europe) (SGB Enhanced)" description "Beethoven (Europe) (SGB Enhanced)" - rom ( name "Beethoven (Europe) (SGB Enhanced).gb" size 131072 crc 637E54E3 md5 5544EFA64429127007AA3779BEAA654E sha1 A175778FACA00F096F0BFDBAA844A38816BBEB0F ) + rom ( name "Beethoven (Europe) (SGB Enhanced).gb" size 131072 crc 637e54e3 sha1 A175778FACA00F096F0BFDBAA844A38816BBEB0F ) ) game ( name "Beetlejuice (USA)" description "Beetlejuice (USA)" - rom ( name "Beetlejuice (USA).gb" size 131072 crc 33574ECB md5 F6C1715B8B93356B8B8AD27F5574DC96 sha1 A8BB9681DBF0700D64A88C7D9AD0093F08087046 ) + rom ( name "Beetlejuice (USA).gb" size 131072 crc 33574ecb sha1 A8BB9681DBF0700D64A88C7D9AD0093F08087046 ) ) game ( name "Best of the Best - Championship Karate (Europe)" description "Best of the Best - Championship Karate (Europe)" - rom ( name "Best of the Best - Championship Karate (Europe).gb" size 262144 crc D5C3DA1D md5 CD2CAAB38139F54145FC5A3CE1E01925 sha1 351446B94176360C0D9AD3CEE43166FFBD9A51FA ) + rom ( name "Best of the Best - Championship Karate (Europe).gb" size 262144 crc d5c3da1d sha1 351446B94176360C0D9AD3CEE43166FFBD9A51FA flags verified ) ) game ( name "Best of the Best - Championship Karate (USA)" description "Best of the Best - Championship Karate (USA)" - rom ( name "Best of the Best - Championship Karate (USA).gb" size 262144 crc B20280E6 md5 91F7654109AFD261DF2B27BFDCD86898 sha1 BA7D64C606CC0F654217E54A0BD5B8DDA455A060 ) + rom ( name "Best of the Best - Championship Karate (USA).gb" size 262144 crc b20280e6 sha1 BA7D64C606CC0F654217E54A0BD5B8DDA455A060 ) ) game ( name "Bikkuri Nekketsu Shin Kiroku! - Dokodemo Kin Medal (Japan)" description "Bikkuri Nekketsu Shin Kiroku! - Dokodemo Kin Medal (Japan)" - rom ( name "Bikkuri Nekketsu Shin Kiroku! - Dokodemo Kin Medal (Japan).gb" size 262144 crc 86D11D10 md5 40C38735C8F225CA8DE749EFCEAB6CEB sha1 BAECEE2DFD915A41363FEF736F81853822D5DFCD ) + rom ( name "Bikkuri Nekketsu Shin Kiroku! - Dokodemo Kin Medal (Japan).gb" size 262144 crc 86d11d10 sha1 BAECEE2DFD915A41363FEF736F81853822D5DFCD flags verified ) ) game ( - name "Bill & Ted's Excellent Game Boy Adventure (USA, Europe)" - description "Bill & Ted's Excellent Game Boy Adventure (USA, Europe)" - rom ( name "Bill & Ted's Excellent Game Boy Adventure (USA, Europe).gb" size 131072 crc 5E8F656A md5 9D94D01D3133165D4469BB27D58F0F6C sha1 E19A7E5A5BD8FDE0F31773C22DBEBC9B4CF3824E flags verified ) + name "Bill & Ted's Excellent Game Boy Adventure - A Bogus Journey! (USA, Europe)" + description "Bill & Ted's Excellent Game Boy Adventure - A Bogus Journey! (USA, Europe)" + rom ( name "Bill & Ted's Excellent Game Boy Adventure - A Bogus Journey! (USA, Europe).gb" size 131072 crc 5e8f656a sha1 E19A7E5A5BD8FDE0F31773C22DBEBC9B4CF3824E flags verified ) ) game ( name "Bill Elliott's NASCAR Fast Tracks (USA)" description "Bill Elliott's NASCAR Fast Tracks (USA)" - rom ( name "Bill Elliott's NASCAR Fast Tracks (USA).gb" size 131072 crc 71CF43CE md5 915D5D1C4DDEF2C39FDB0131A34B83A4 sha1 EBC2CA8B4503F0B05E00749D693462A54F2F95EB ) + rom ( name "Bill Elliott's NASCAR Fast Tracks (USA).gb" size 131072 crc 71cf43ce sha1 EBC2CA8B4503F0B05E00749D693462A54F2F95EB ) ) game ( name "Bionic Battler (USA)" description "Bionic Battler (USA)" - rom ( name "Bionic Battler (USA).gb" size 65536 crc A1E55DC2 md5 B5A6254B1711EDFAF89830BCFFF09D38 sha1 9ECA6A5FD1E537085598E8B2903AD75FE9C0B785 ) + rom ( name "Bionic Battler (USA).gb" size 65536 crc a1e55dc2 sha1 9ECA6A5FD1E537085598E8B2903AD75FE9C0B785 flags verified ) ) game ( name "Bionic Commando (Europe)" description "Bionic Commando (Europe)" - rom ( name "Bionic Commando (Europe).gb" size 262144 crc 4C5B4547 md5 290F699F6C5B5B648AAC43751DE07EA1 sha1 A8AB419B049AEF5A04800EFD6DF58E4B3C3ABBE3 flags verified ) + rom ( name "Bionic Commando (Europe).gb" size 262144 crc 4c5b4547 sha1 A8AB419B049AEF5A04800EFD6DF58E4B3C3ABBE3 flags verified ) ) game ( name "Bionic Commando (Japan)" description "Bionic Commando (Japan)" - rom ( name "Bionic Commando (Japan).gb" size 262144 crc 3F4D5C84 md5 489F52A2761DCB6F01567EF5DE14CB8A sha1 12DC5B05751214BE3CE55DA0FECAF23A41EB1881 ) + rom ( name "Bionic Commando (Japan).gb" size 262144 crc 3f4d5c84 sha1 12DC5B05751214BE3CE55DA0FECAF23A41EB1881 ) ) game ( name "Bionic Commando (USA)" description "Bionic Commando (USA)" - rom ( name "Bionic Commando (USA).gb" size 262144 crc 41DBB5FB md5 F89A33DE3FA660A13EC29BB323EFFFA9 sha1 E0EF47568A017CCDD3DBE0DB5D7654822B4E5CE1 flags verified ) + rom ( name "Bionic Commando (USA).gb" size 262144 crc 41dbb5fb sha1 E0EF47568A017CCDD3DBE0DB5D7654822B4E5CE1 flags verified ) ) game ( name "Bishoujo Senshi Sailor Moon (Japan)" description "Bishoujo Senshi Sailor Moon (Japan)" - rom ( name "Bishoujo Senshi Sailor Moon (Japan).gb" size 131072 crc C2763E73 md5 7AFB675171D58105112DBACF2CED77CB sha1 C008913A9FBB395A7A504FE65D1D29C530755CB3 ) + rom ( name "Bishoujo Senshi Sailor Moon (Japan).gb" size 131072 crc c2763e73 sha1 C008913A9FBB395A7A504FE65D1D29C530755CB3 ) ) game ( name "Bishoujo Senshi Sailor Moon R (Japan)" description "Bishoujo Senshi Sailor Moon R (Japan)" - rom ( name "Bishoujo Senshi Sailor Moon R (Japan).gb" size 262144 crc EA759875 md5 84634FB36156BB1B9E54BC62FBAF3525 sha1 959F384998C43072CA154E531917E9AAA80A694D ) + rom ( name "Bishoujo Senshi Sailor Moon R (Japan).gb" size 262144 crc ea759875 sha1 959F384998C43072CA154E531917E9AAA80A694D ) ) game ( name "Black Bass - Lure Fishing (USA)" description "Black Bass - Lure Fishing (USA)" - rom ( name "Black Bass - Lure Fishing (USA).gb" size 262144 crc 2DB3DACE md5 88908153A898E5D91A02206DBB03713A sha1 D9524AC9F7788172A55CC8CEB6E199F8A12E033D flags verified ) + rom ( name "Black Bass - Lure Fishing (USA).gb" size 262144 crc 2db3dace sha1 D9524AC9F7788172A55CC8CEB6E199F8A12E033D flags verified ) ) game ( name "Blades of Steel (Europe)" description "Blades of Steel (Europe)" - rom ( name "Blades of Steel (Europe).gb" size 131072 crc F7BE0002 md5 6E8166C3783D1807D0A8C3B649E583C1 sha1 D030C46BC225FC92AA431276D9AE5812A30D6007 flags verified ) + rom ( name "Blades of Steel (Europe).gb" size 131072 crc f7be0002 sha1 D030C46BC225FC92AA431276D9AE5812A30D6007 flags verified ) ) game ( name "Blades of Steel (USA)" description "Blades of Steel (USA)" - rom ( name "Blades of Steel (USA).gb" size 131072 crc E81C9FB9 md5 302CAA3CEDDCCC5FBA36787B44D25DA7 sha1 82761DBF5ABE276F8E0C82F575356AED87155141 flags verified ) + rom ( name "Blades of Steel (USA).gb" size 131072 crc e81c9fb9 sha1 82761DBF5ABE276F8E0C82F575356AED87155141 flags verified ) ) game ( name "Blaster Master Boy (USA)" description "Blaster Master Boy (USA)" - rom ( name "Blaster Master Boy (USA).gb" size 131072 crc 3B2C7118 md5 C4868BF46A993B4C33A9A8AF5341282A sha1 21B1E574A6F4543651E96DE65994E7B0B7A6A0F6 ) + rom ( name "Blaster Master Boy (USA).gb" size 131072 crc 3b2c7118 sha1 21B1E574A6F4543651E96DE65994E7B0B7A6A0F6 ) ) game ( name "Blaster Master Jr. (Europe)" description "Blaster Master Jr. (Europe)" - rom ( name "Blaster Master Jr. (Europe).gb" size 131072 crc E9F9016F md5 15D9979ACE470A0ABF9C83BC1F81DABF sha1 6A6DEAE1942E7CF048CE35D18E9540363C226727 flags verified ) + rom ( name "Blaster Master Jr. (Europe).gb" size 131072 crc e9f9016f sha1 6A6DEAE1942E7CF048CE35D18E9540363C226727 flags verified ) ) game ( name "Block Kuzushi GB (Japan) (SGB Enhanced)" description "Block Kuzushi GB (Japan) (SGB Enhanced)" - rom ( name "Block Kuzushi GB (Japan) (SGB Enhanced).gb" size 131072 crc 54B67501 md5 55EF8421492242C2726E355C41AEF000 sha1 7540FE9AF69D8C7D48F50C2D5FE6D3CE07421F74 ) + rom ( name "Block Kuzushi GB (Japan) (SGB Enhanced).gb" size 131072 crc 54b67501 sha1 7540FE9AF69D8C7D48F50C2D5FE6D3CE07421F74 ) ) game ( name "Blodia (Japan)" description "Blodia (Japan)" - rom ( name "Blodia (Japan).gb" size 65536 crc 51FF6E53 md5 5E3005E18F030F58E8B919D35CB297D7 sha1 A3927543CA471F479BA7AAE7295788434672464E flags verified ) + rom ( name "Blodia (Japan).gb" size 65536 crc 51ff6e53 sha1 A3927543CA471F479BA7AAE7295788434672464E flags verified ) ) game ( name "Blues Brothers, The (USA, Europe)" description "Blues Brothers, The (USA, Europe)" - rom ( name "Blues Brothers, The (USA, Europe).gb" size 131072 crc ADB66EFF md5 CEAEDF86193A8708A8A67E0E472B57FB sha1 9DCA8B83A5D73270319CF05396FCCA8E6027E7B0 flags verified ) + rom ( name "Blues Brothers, The (USA, Europe).gb" size 131072 crc adb66eff sha1 9DCA8B83A5D73270319CF05396FCCA8E6027E7B0 flags verified ) ) game ( name "Blues Brothers, The - Jukebox Adventure (Europe)" description "Blues Brothers, The - Jukebox Adventure (Europe)" - rom ( name "Blues Brothers, The - Jukebox Adventure (Europe).gb" size 131072 crc F1C0FB1D md5 3132B823343C82DACECE721452612812 sha1 2005E94222A1F0EDD30903411343F9570A91D4F3 flags verified ) + rom ( name "Blues Brothers, The - Jukebox Adventure (Europe).gb" size 131072 crc f1c0fb1d sha1 2005E94222A1F0EDD30903411343F9570A91D4F3 flags verified ) ) game ( name "Bo Jackson - Two Games in One (USA)" description "Bo Jackson - Two Games in One (USA)" - rom ( name "Bo Jackson - Two Games in One (USA).gb" size 131072 crc 7EDB78AB md5 24B4F33417FC95FE6B092BCD30605CB2 sha1 CB360F44A398FF5CD3818B0E244FFDF7019D85C7 flags verified ) + rom ( name "Bo Jackson - Two Games in One (USA).gb" size 131072 crc 7edb78ab sha1 CB360F44A398FF5CD3818B0E244FFDF7019D85C7 flags verified ) ) game ( name "Boggle Plus (USA)" description "Boggle Plus (USA)" - rom ( name "Boggle Plus (USA).gb" size 131072 crc 70C8C799 md5 B3BE58AE099AB2A695CFEBE9881C7461 sha1 D6CF512F7301CCDC2D802F34FBBDE2D0BA2CF3CD ) + rom ( name "Boggle Plus (USA).gb" size 131072 crc 70c8c799 sha1 D6CF512F7301CCDC2D802F34FBBDE2D0BA2CF3CD ) ) game ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced)" description "Bokujou Monogatari GB (Japan) (SGB Enhanced)" - rom ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced).gb" size 524288 crc D3E2FD02 md5 6633EA57F86C4A117F0B027DA68BDA92 sha1 60ECAFDB13213B3AC2DAA3D71431EF8A89754EDB flags verified ) + rom ( name "Bokujou Monogatari GB (Japan) (SGB Enhanced).gb" size 524288 crc d3e2fd02 sha1 60ECAFDB13213B3AC2DAA3D71431EF8A89754EDB flags verified ) ) game ( - name "Bokujou Monogatari GB (Japan) (Rev AB) (SGB Enhanced)" - description "Bokujou Monogatari GB (Japan) (Rev AB) (SGB Enhanced)" - rom ( name "Bokujou Monogatari GB (Japan) (Rev AB) (SGB Enhanced).gb" size 524288 crc DA218E44 md5 275DC0712E83F34252C2FCD2EAEFB72F sha1 A1637D7BA09335631EAC1291803ADE05ADCF5FC7 flags verified ) + name "Bokujou Monogatari GB (Japan) (Rev 1) (SGB Enhanced)" + description "Bokujou Monogatari GB (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Bokujou Monogatari GB (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc da218e44 sha1 A1637D7BA09335631EAC1291803ADE05ADCF5FC7 flags verified ) +) + +game ( + name "Bokujou Monogatari GB (Japan) (GBC,SGB Enhanced) (NP)" + description "Bokujou Monogatari GB (Japan) (GBC,SGB Enhanced) (NP)" + rom ( name "Bokujou Monogatari GB (Japan) (GBC,SGB Enhanced) (NP).gb" size 524288 crc 0424df85 sha1 551DF2021D0E433E7F07CF881C7B1D534F54F6AD flags verified ) ) game ( name "Bomb Jack (Europe)" description "Bomb Jack (Europe)" - rom ( name "Bomb Jack (Europe).gb" size 32768 crc 9BD8815E md5 7615154DC9AFB1A7D7D2FE63B76C68E4 sha1 A2B2799E867777A5A19155ED1F2245630FC03560 flags verified ) + rom ( name "Bomb Jack (Europe).gb" size 32768 crc 9bd8815e sha1 A2B2799E867777A5A19155ED1F2245630FC03560 flags verified ) ) game ( name "Bomber Boy (Japan)" description "Bomber Boy (Japan)" - rom ( name "Bomber Boy (Japan).gb" size 131072 crc EF9595AC md5 FC2D9EB9479543614B6E3D0D63C359AA sha1 A9BADDFB693F20057B17C084422D7BFAC590F2BA flags verified ) + rom ( name "Bomber Boy (Japan).gb" size 131072 crc ef9595ac sha1 A9BADDFB693F20057B17C084422D7BFAC590F2BA flags verified ) ) game ( name "Bomber King - Scenario 2 (Japan)" description "Bomber King - Scenario 2 (Japan)" - rom ( name "Bomber King - Scenario 2 (Japan).gb" size 131072 crc B8FE9077 md5 2DD7CAC468422231AE2ABA980E4C4691 sha1 79F978B9E85C675F7B54229A14D04926348BB70F ) + rom ( name "Bomber King - Scenario 2 (Japan).gb" size 131072 crc b8fe9077 sha1 79F978B9E85C675F7B54229A14D04926348BB70F ) ) game ( name "Bomber Man Collection (Japan) (SGB Enhanced)" description "Bomber Man Collection (Japan) (SGB Enhanced)" - rom ( name "Bomber Man Collection (Japan) (SGB Enhanced).gb" size 1048576 crc 509A6B73 md5 9FB9C42CF52DCFDCFBAD5E61AE1B5777 sha1 385F8FAFA53A83F8F65E1E619FE124BBF7DB4A98 flags verified ) + rom ( name "Bomber Man Collection (Japan) (SGB Enhanced).gb" size 1048576 crc 509a6b73 sha1 385F8FAFA53A83F8F65E1E619FE124BBF7DB4A98 flags verified ) ) game ( name "Bomber Man GB (Japan) (SGB Enhanced)" description "Bomber Man GB (Japan) (SGB Enhanced)" - rom ( name "Bomber Man GB (Japan) (SGB Enhanced).gb" size 262144 crc 94337D56 md5 2CAD6EE6DF3402AEB8F8AB7921517779 sha1 5B989983C2F80A71DFC7CCE29395DE3E174FA848 flags verified ) + rom ( name "Bomber Man GB (Japan) (SGB Enhanced).gb" size 262144 crc 94337d56 sha1 5B989983C2F80A71DFC7CCE29395DE3E174FA848 flags verified ) ) game ( name "Bomber Man GB 2 (Japan) (SGB Enhanced)" description "Bomber Man GB 2 (Japan) (SGB Enhanced)" - rom ( name "Bomber Man GB 2 (Japan) (SGB Enhanced).gb" size 262144 crc 6157443B md5 4AB78239E79BA059D0D7AA7A629A9474 sha1 004E540E8AED59E5AEE1C88EF84975000A6EFE6C flags verified ) + rom ( name "Bomber Man GB 2 (Japan) (SGB Enhanced).gb" size 262144 crc 6157443b sha1 004E540E8AED59E5AEE1C88EF84975000A6EFE6C flags verified ) ) game ( name "Bomber Man GB 3 (Japan) (SGB Enhanced)" description "Bomber Man GB 3 (Japan) (SGB Enhanced)" - rom ( name "Bomber Man GB 3 (Japan) (SGB Enhanced).gb" size 262144 crc F658B7A7 md5 3ADDAB2611566AB072FC996F8A81B224 sha1 98A6327639833E1A6696E4ACC5CA162388D5F6E1 flags verified ) + rom ( name "Bomber Man GB 3 (Japan) (SGB Enhanced).gb" size 262144 crc f658b7a7 sha1 98A6327639833E1A6696E4ACC5CA162388D5F6E1 flags verified ) ) game ( name "Bomberman GB (USA, Europe) (SGB Enhanced)" description "Bomberman GB (USA, Europe) (SGB Enhanced)" - rom ( name "Bomberman GB (USA, Europe) (SGB Enhanced).gb" size 262144 crc F372D175 md5 7E4C9C3620BEA7B633394BEB67E9680B sha1 F7058F31DDAEC63F3B9C45EE9CAF3C8E2CAE1CA8 flags verified ) + rom ( name "Bomberman GB (USA, Europe) (SGB Enhanced).gb" size 262144 crc f372d175 sha1 F7058F31DDAEC63F3B9C45EE9CAF3C8E2CAE1CA8 flags verified ) ) game ( name "Bonk's Adventure (USA)" description "Bonk's Adventure (USA)" - rom ( name "Bonk's Adventure (USA).gb" size 262144 crc A7CDBB96 md5 79D6E6515905EC3FBCBD9E50FF469000 sha1 E27D941AF0A006C4F5FFD03914265146AA140E2C ) + rom ( name "Bonk's Adventure (USA).gb" size 262144 crc a7cdbb96 sha1 E27D941AF0A006C4F5FFD03914265146AA140E2C ) ) game ( name "Bonk's Revenge (USA) (SGB Enhanced)" description "Bonk's Revenge (USA) (SGB Enhanced)" - rom ( name "Bonk's Revenge (USA) (SGB Enhanced).gb" size 262144 crc F1344B78 md5 B73D76599E3D7F979A99BBA5F1C92ADD sha1 8D1B81E456B271AD8F49A2C6EFC9CA2504A24591 ) + rom ( name "Bonk's Revenge (USA) (SGB Enhanced).gb" size 262144 crc f1344b78 sha1 8D1B81E456B271AD8F49A2C6EFC9CA2504A24591 ) ) game ( name "Booby Boys (Japan)" description "Booby Boys (Japan)" - rom ( name "Booby Boys (Japan).gb" size 262144 crc EC83C0B6 md5 D17AA3DD0A52BC3DC03BFE20F27C8B07 sha1 61FE27A4CE83BC6D9DBA5D4D0652E83DBEC45E6E ) + rom ( name "Booby Boys (Japan).gb" size 262144 crc ec83c0b6 sha1 61FE27A4CE83BC6D9DBA5D4D0652E83DBEC45E6E ) ) game ( name "Boomer's Adventure in ASMIK World (USA)" description "Boomer's Adventure in ASMIK World (USA)" - rom ( name "Boomer's Adventure in ASMIK World (USA).gb" size 65536 crc 105BC1C0 md5 3B051DF77605172195DCFF97C2C935CC sha1 3D8A6FCC644290C9D88FE2918BFA6007EE811DE8 flags verified ) + rom ( name "Boomer's Adventure in ASMIK World (USA).gb" size 65536 crc 105bc1c0 sha1 3D8A6FCC644290C9D88FE2918BFA6007EE811DE8 flags verified ) ) game ( name "Bouken! Puzzle Road (Japan)" description "Bouken! Puzzle Road (Japan)" - rom ( name "Bouken! Puzzle Road (Japan).gb" size 32768 crc 9F0F3606 md5 0EB1920C5559F8A87B416739F192BA98 sha1 16D54DE69814E1C9AAE67A59BB0DCD2A1216395B flags verified ) + rom ( name "Bouken! Puzzle Road (Japan).gb" size 32768 crc 9f0f3606 sha1 16D54DE69814E1C9AAE67A59BB0DCD2A1216395B flags verified ) ) game ( name "Boulder Dash (Europe)" description "Boulder Dash (Europe)" - rom ( name "Boulder Dash (Europe).gb" size 65536 crc 644AEC3E md5 800C1A8F99BEA585490673352B5F11F4 sha1 01CC570A16BAD4C2C33B393620EC9E25F131D1F4 flags verified ) + rom ( name "Boulder Dash (Europe).gb" size 65536 crc 644aec3e sha1 01CC570A16BAD4C2C33B393620EC9E25F131D1F4 flags verified ) ) game ( name "Boulder Dash (Japan)" description "Boulder Dash (Japan)" - rom ( name "Boulder Dash (Japan).gb" size 65536 crc B5B3F85B md5 7068DF6F82EC8CBA4CBE36CC21B86DF0 sha1 F5A4A5CCDA4F559CE85567C4B68F758216AEE2D4 flags verified ) + rom ( name "Boulder Dash (Japan).gb" size 65536 crc b5b3f85b sha1 F5A4A5CCDA4F559CE85567C4B68F758216AEE2D4 flags verified ) ) game ( name "Boxing (Japan)" description "Boxing (Japan)" - rom ( name "Boxing (Japan).gb" size 65536 crc EF7E9FA0 md5 6A3E04A78132D5DAAB4EE4DF860CF48A sha1 5AF3A0B6E54CA67C3A4CAB8833368725CC68E99F flags verified ) + rom ( name "Boxing (Japan).gb" size 65536 crc ef7e9fa0 sha1 5AF3A0B6E54CA67C3A4CAB8833368725CC68E99F flags verified ) ) game ( - name "Boxxle (USA, Europe) (Rev A)" - description "Boxxle (USA, Europe) (Rev A)" - rom ( name "Boxxle (USA, Europe) (Rev A).gb" size 32768 crc C09CEE99 md5 239FD20F424EE53D2F11018DBD942DF4 sha1 F9D5287BC9D6EDA9EC36E9B5A8DBC38CF2CFFECF flags verified ) + name "Boxxle (USA, Europe) (Rev 1)" + description "Boxxle (USA, Europe) (Rev 1)" + rom ( name "Boxxle (USA, Europe) (Rev 1).gb" size 32768 crc c09cee99 sha1 F9D5287BC9D6EDA9EC36E9B5A8DBC38CF2CFFECF flags verified ) +) + +game ( + name "Boxxle (USA)" + description "Boxxle (USA)" + rom ( name "Boxxle (USA).gb" size 32768 crc 24843867 sha1 3E169F1DB16CC1C3FFBC8645AA7CE28194033D26 flags verified ) ) game ( name "Boxxle II (USA, Europe)" description "Boxxle II (USA, Europe) (european shaped box contains USA-cartridge)" - rom ( name "Boxxle II (USA, Europe).gb" size 32768 crc C08E9756 md5 308ABD707A48EE9D69C287D818469FD6 sha1 36315DAB12915D2D2FAD7A37FCB5CE6809118C8A ) + rom ( name "Boxxle II (USA, Europe).gb" size 32768 crc c08e9756 sha1 36315DAB12915D2D2FAD7A37FCB5CE6809118C8A ) ) game ( name "Brain Bender (Europe)" description "Brain Bender (Europe)" - rom ( name "Brain Bender (Europe).gb" size 32768 crc B651BF5D md5 77C1E3543A7F4A75A50EFBB91C2718C2 sha1 9502181C62D8343B98CEF9B881C29E4573E4FBC9 flags verified ) + rom ( name "Brain Bender (Europe).gb" size 32768 crc b651bf5d sha1 9502181C62D8343B98CEF9B881C29E4573E4FBC9 flags verified ) ) game ( name "Brain Bender (USA)" description "Brain Bender (USA)" - rom ( name "Brain Bender (USA).gb" size 32768 crc FBB1F2A1 md5 63BBFCE4FB22F4B77E68CC67F02C4B05 sha1 56FF8684284765A56918D14620AD38477AAAF0AD ) + rom ( name "Brain Bender (USA).gb" size 32768 crc fbb1f2a1 sha1 56FF8684284765A56918D14620AD38477AAAF0AD ) ) game ( name "Brain Drain (Europe) (SGB Enhanced)" description "Brain Drain (Europe) (SGB Enhanced)" - rom ( name "Brain Drain (Europe) (SGB Enhanced).gb" size 131072 crc 8A7FB0E6 md5 56F304DBD0045521271DE857FFC77FBE sha1 67E1796ED410ECC19EFC2F73EF7F5226414CC8BB ) + rom ( name "Brain Drain (Europe) (SGB Enhanced).gb" size 131072 crc 8a7fb0e6 sha1 67E1796ED410ECC19EFC2F73EF7F5226414CC8BB ) ) game ( name "Brain Drain (Japan) (SGB Enhanced)" description "Brain Drain (Japan) (SGB Enhanced)" - rom ( name "Brain Drain (Japan) (SGB Enhanced).gb" size 131072 crc E558AACD md5 DED286DC9FB5708292F01DB0839E0102 sha1 225C25D94854F509611B8C0B4B415DAF48D51310 ) + rom ( name "Brain Drain (Japan) (SGB Enhanced).gb" size 131072 crc e558aacd sha1 225C25D94854F509611B8C0B4B415DAF48D51310 ) ) game ( name "Brain Drain (USA) (SGB Enhanced)" description "Brain Drain (USA) (SGB Enhanced)" - rom ( name "Brain Drain (USA) (SGB Enhanced).gb" size 131072 crc AFF0B159 md5 0C7BEEAD4F65E97A23B718CE20A1BF55 sha1 DA11B3909BEF958ABC9B3B184771F4F8FE498456 ) + rom ( name "Brain Drain (USA) (SGB Enhanced).gb" size 131072 crc aff0b159 sha1 DA11B3909BEF958ABC9B3B184771F4F8FE498456 ) ) game ( name "Bram Stoker's Dracula (USA, Europe)" description "Bram Stoker's Dracula (USA, Europe)" - rom ( name "Bram Stoker's Dracula (USA, Europe).gb" size 131072 crc 00CD1876 md5 D8E5252704CF0681A7F737D599526591 sha1 D31CB69613A6F0504B4F3F72C18E96B5827686B9 flags verified ) + rom ( name "Bram Stoker's Dracula (USA, Europe).gb" size 131072 crc 00cd1876 sha1 D31CB69613A6F0504B4F3F72C18E96B5827686B9 flags verified ) ) game ( name "BreakThru! (USA)" description "BreakThru! (USA)" - rom ( name "BreakThru! (USA).gb" size 131072 crc 5B8F0DF2 md5 797580A91CF9DC710C37F5AF04DBBCA5 sha1 D9A49A71E6B554C2FCCCE08C446274E886225D50 ) + rom ( name "BreakThru! (USA).gb" size 131072 crc 5b8f0df2 sha1 D9A49A71E6B554C2FCCCE08C446274E886225D50 ) ) game ( name "Bubble Bobble (Japan)" description "Bubble Bobble (Japan)" - rom ( name "Bubble Bobble (Japan).gb" size 131072 crc AD9B300C md5 2EC376FB2B9565F20475D7007134B9E2 sha1 3F2E741E0DBDCC65E960F44A322E85748272F3F3 flags verified ) + rom ( name "Bubble Bobble (Japan).gb" size 131072 crc ad9b300c sha1 3F2E741E0DBDCC65E960F44A322E85748272F3F3 flags verified ) ) game ( name "Bubble Bobble (USA, Europe)" description "Bubble Bobble (USA, Europe)" - rom ( name "Bubble Bobble (USA, Europe).gb" size 131072 crc D516841D md5 11C49D405EEF2174D9C14682204BB458 sha1 569881BEA21CF5FD542FF3DFC40E1626C6748CEB flags verified ) + rom ( name "Bubble Bobble (USA, Europe).gb" size 131072 crc d516841d sha1 569881BEA21CF5FD542FF3DFC40E1626C6748CEB flags verified ) ) game ( name "Bubble Bobble Junior (Japan)" description "Bubble Bobble Junior (Japan)" - rom ( name "Bubble Bobble Junior (Japan).gb" size 131072 crc 39E261B9 md5 09DBAD535406168486B8B688CAF33A9C sha1 686C526A557065DC0005068EAFDBC6736684F925 ) + rom ( name "Bubble Bobble Junior (Japan).gb" size 131072 crc 39e261b9 sha1 686C526A557065DC0005068EAFDBC6736684F925 ) ) game ( name "Bubble Bobble Part 2 (USA, Europe)" description "Bubble Bobble Part 2 (USA, Europe)" - rom ( name "Bubble Bobble Part 2 (USA, Europe).gb" size 131072 crc 4106D781 md5 8BBB9BA0D72548706E4E5EBA1B3A9FE1 sha1 E258D852713F392454D4291032CE50AD325ABA86 flags verified ) + rom ( name "Bubble Bobble Part 2 (USA, Europe).gb" size 131072 crc 4106d781 sha1 E258D852713F392454D4291032CE50AD325ABA86 flags verified ) ) game ( name "Bubble Ghost (Japan)" description "Bubble Ghost (Japan)" - rom ( name "Bubble Ghost (Japan).gb" size 32768 crc 874D0D6F md5 E4BA52D3C6D5CD7AAD2D3C398C9B7A0E sha1 F93E37B60025C67D7FBFC035ED727C9A39D8C9F1 ) + rom ( name "Bubble Ghost (Japan).gb" size 32768 crc 874d0d6f sha1 F93E37B60025C67D7FBFC035ED727C9A39D8C9F1 ) ) game ( name "Bubble Ghost (USA, Europe)" description "Bubble Ghost (USA, Europe)" - rom ( name "Bubble Ghost (USA, Europe).gb" size 32768 crc 843068FD md5 7F970D79F06CFB4270DEA4B051277098 sha1 B08B8A9BF742F7CA4B355A866B4167741252DCF6 flags verified ) + rom ( name "Bubble Ghost (USA, Europe).gb" size 32768 crc 843068fd sha1 B08B8A9BF742F7CA4B355A866B4167741252DCF6 flags verified ) ) game ( name "Bubsy II (Europe)" description "Bubsy II (Europe)" - rom ( name "Bubsy II (Europe).gb" size 262144 crc A3164516 md5 CD1FA506EEA7590B0B24B6BDD153FFA9 sha1 F59306DA42C5D8BBF41C870828C83BBCF1E2F0AC flags verified ) + rom ( name "Bubsy II (Europe).gb" size 262144 crc a3164516 sha1 F59306DA42C5D8BBF41C870828C83BBCF1E2F0AC flags verified ) ) game ( name "Bubsy II (USA)" description "Bubsy II (USA)" - rom ( name "Bubsy II (USA).gb" size 262144 crc 600A6AD5 md5 C80413993CB4A5B79C9CDD04235010DD sha1 1AC9BF5043CAF428994BCA3E80158CA697E94C58 ) + rom ( name "Bubsy II (USA).gb" size 262144 crc 600a6ad5 sha1 1AC9BF5043CAF428994BCA3E80158CA697E94C58 ) ) game ( name "Bugs Bunny Collection (Japan) (SGB Enhanced)" description "Bugs Bunny Collection (Japan) (SGB Enhanced)" - rom ( name "Bugs Bunny Collection (Japan) (SGB Enhanced).gb" size 262144 crc D2DBEA8F md5 32628DD7B39919A3A5AB77B245CD6B63 sha1 4F1F56B06364272033372230CFE0819CB3E25B50 ) + rom ( name "Bugs Bunny Collection (Japan) (SGB Enhanced).gb" size 262144 crc d2dbea8f sha1 4F1F56B06364272033372230CFE0819CB3E25B50 ) ) game ( - name "Bugs Bunny Collection (Japan) (Rev A) (SGB Enhanced)" - description "Bugs Bunny Collection (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Bugs Bunny Collection (Japan) (Rev A) (SGB Enhanced).gb" size 262144 crc 8244220B md5 D7DA0896F856630A011AC160589912CE sha1 9D69D72B7DE0377CB0439AA301B1FB82D3CE786A ) + name "Bugs Bunny Collection (Japan) (Rev 1) (SGB Enhanced)" + description "Bugs Bunny Collection (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Bugs Bunny Collection (Japan) (Rev 1) (SGB Enhanced).gb" size 262144 crc 8244220b sha1 9D69D72B7DE0377CB0439AA301B1FB82D3CE786A ) ) game ( name "Bugs Bunny Crazy Castle 2, The (USA)" description "Bugs Bunny Crazy Castle 2, The (USA)" - rom ( name "Bugs Bunny Crazy Castle 2, The (USA).gb" size 131072 crc A973E604 md5 8963803E642DBFBE4F5F3BC5A567785D sha1 1E4C8C8FE8B6C34F76CD0DA876442F14299DA725 ) + rom ( name "Bugs Bunny Crazy Castle 2, The (USA).gb" size 131072 crc a973e604 sha1 1E4C8C8FE8B6C34F76CD0DA876442F14299DA725 flags verified ) ) game ( name "Bugs Bunny Crazy Castle, The (USA, Europe)" description "Bugs Bunny Crazy Castle, The (USA, Europe)" - rom ( name "Bugs Bunny Crazy Castle, The (USA, Europe).gb" size 65536 crc 403E1B7E md5 43189B859C0036119F233D46B1F2E9FD sha1 2A3E982E542A849F95B4497025CA5B04DB2ABE8C flags verified ) + rom ( name "Bugs Bunny Crazy Castle, The (USA, Europe).gb" size 65536 crc 403e1b7e sha1 2A3E982E542A849F95B4497025CA5B04DB2ABE8C flags verified ) ) game ( name "Burai Fighter Deluxe (USA, Europe)" description "Burai Fighter Deluxe (USA, Europe)" - rom ( name "Burai Fighter Deluxe (USA, Europe).gb" size 65536 crc 3C86F5DB md5 DD5AA6E85827A3CE6E4B7500E75A3262 sha1 178E18B7E6E65E726B4E06F80D89C55332EA868B flags verified ) + rom ( name "Burai Fighter Deluxe (USA, Europe).gb" size 65536 crc 3c86f5db sha1 178E18B7E6E65E726B4E06F80D89C55332EA868B flags verified ) ) game ( name "Burai Senshi Deluxe (Japan)" description "Burai Senshi Deluxe (Japan)" - rom ( name "Burai Senshi Deluxe (Japan).gb" size 65536 crc 5A1A20F3 md5 90A34D9897ACB1E78E00D6D5A2AF419F sha1 F8C17E07D25420B7717F4415820C09491BB6A04C flags verified ) + rom ( name "Burai Senshi Deluxe (Japan).gb" size 65536 crc 5a1a20f3 sha1 F8C17E07D25420B7717F4415820C09491BB6A04C flags verified ) ) game ( name "BurgerTime Deluxe (World)" description "BurgerTime Deluxe (World)" - rom ( name "BurgerTime Deluxe (World).gb" size 65536 crc 88219A49 md5 9627134CA3EA6E885275D30460CE3563 sha1 1AAFCEF0DD5FBB8E95188631E0B2DECDF84E9AED flags verified ) + rom ( name "BurgerTime Deluxe (World).gb" size 65536 crc 88219a49 sha1 1AAFCEF0DD5FBB8E95188631E0B2DECDF84E9AED flags verified ) ) game ( name "Burning Paper (Japan)" description "Burning Paper (Japan)" - rom ( name "Burning Paper (Japan).gb" size 131072 crc 88F8C991 md5 CB0A5D103C01D1D82D324602A45DD21B sha1 8E2BCE98CC840E52D47680F9B1E425BFC9102AC7 ) + rom ( name "Burning Paper (Japan).gb" size 131072 crc 88f8c991 sha1 8E2BCE98CC840E52D47680F9B1E425BFC9102AC7 ) ) game ( name "Bust-A-Move 2 - Arcade Edition (USA, Europe)" description "Bust-A-Move 2 - Arcade Edition (USA, Europe)" - rom ( name "Bust-A-Move 2 - Arcade Edition (USA, Europe).gb" size 131072 crc B94724E6 md5 FA91ADC7023E03F97EC36F66876A569E sha1 6B0942C231890D3E2F6C18E7804040EB4C66DCB3 flags verified ) + rom ( name "Bust-A-Move 2 - Arcade Edition (USA, Europe).gb" size 131072 crc b94724e6 sha1 6B0942C231890D3E2F6C18E7804040EB4C66DCB3 flags verified ) ) game ( name "Bust-A-Move 3 DX (Europe)" description "Bust-A-Move 3 DX (Europe)" - rom ( name "Bust-A-Move 3 DX (Europe).gb" size 131072 crc E555C612 md5 2B1221E85B545BBA7E2291FEDE03FD96 sha1 E89DC67087205C4113A4D152347EBA38204E270B ) + rom ( name "Bust-A-Move 3 DX (Europe).gb" size 131072 crc e555c612 sha1 E89DC67087205C4113A4D152347EBA38204E270B ) ) game ( name "Buster Bros. (USA)" description "Buster Bros. (USA)" - rom ( name "Buster Bros. (USA).gb" size 131072 crc B4245CA3 md5 D97F34C22A179FB4094ACBC05616F565 sha1 0D1692FF60EF1F6A97BBFD2BF8C1548F1F7439ED ) + rom ( name "Buster Bros. (USA).gb" size 131072 crc b4245ca3 sha1 0D1692FF60EF1F6A97BBFD2BF8C1548F1F7439ED flags verified ) ) game ( name "Cadillac II (Japan)" description "Cadillac II (Japan)" - rom ( name "Cadillac II (Japan).gb" size 65536 crc A6C98122 md5 679555396BCE8BEAB58D4B79ACB966BF sha1 A5D405FE7B4EA23708ACB3CB71104F63057DF6D4 ) + rom ( name "Cadillac II (Japan).gb" size 65536 crc a6c98122 sha1 A5D405FE7B4EA23708ACB3CB71104F63057DF6D4 ) ) game ( name "Caesars Palace (Europe) (En,Fr,De,Es,It)" description "Caesars Palace (Europe) (En,Fr,De,Es,It)" - rom ( name "Caesars Palace (Europe) (En,Fr,De,Es,It).gb" size 131072 crc 78BF3633 md5 8425E6AA8E841B8A6192476AC600EA81 sha1 6D77CE1B212406BA9737DD99FFD9443A3887EF79 flags verified ) + rom ( name "Caesars Palace (Europe) (En,Fr,De,Es,It).gb" size 131072 crc 78bf3633 sha1 6D77CE1B212406BA9737DD99FFD9443A3887EF79 flags verified ) ) game ( name "Caesars Palace (Japan)" description "Caesars Palace (Japan)" - rom ( name "Caesars Palace (Japan).gb" size 131072 crc 000AAA74 md5 B0EF8B9F2EA3E0898B8298A6F076064A sha1 2CF0E21F7BE55E3246D615550C8459A3659094EF ) + rom ( name "Caesars Palace (Japan).gb" size 131072 crc 000aaa74 sha1 2CF0E21F7BE55E3246D615550C8459A3659094EF ) ) game ( name "Caesars Palace (USA)" description "Caesars Palace (USA)" - rom ( name "Caesars Palace (USA).gb" size 131072 crc D9F901A9 md5 CCD1192A634C3358352172ABFEB7FB9E sha1 C1ED80F33FC3603EDABA1BDF5C317F1A205DA3DC ) + rom ( name "Caesars Palace (USA).gb" size 131072 crc d9f901a9 sha1 C1ED80F33FC3603EDABA1BDF5C317F1A205DA3DC ) ) game ( - name "Caesars Palace (USA) (Rev A)" - description "Caesars Palace (USA) (Rev A)" - rom ( name "Caesars Palace (USA) (Rev A).gb" size 131072 crc 87A9D605 md5 9C9679E4DA4DAA2EE22F1C35EEF03CAD sha1 126E9EF9E975BBBC6303D5D62A379D4DBD404CF0 ) + name "Caesars Palace (USA) (Rev 1)" + description "Caesars Palace (USA) (Rev 1)" + rom ( name "Caesars Palace (USA) (Rev 1).gb" size 131072 crc 87a9d605 sha1 126E9EF9E975BBBC6303D5D62A379D4DBD404CF0 flags verified ) ) game ( name "Capcom Quiz - Hatena no Daibouken (Japan)" description "Capcom Quiz - Hatena no Daibouken (Japan)" - rom ( name "Capcom Quiz - Hatena no Daibouken (Japan).gb" size 262144 crc 8042AFC5 md5 4ADF20CF4CED9FA2512578C133AD269F sha1 168583EA18E02647F0B35F9BD0365E37BEC076CC flags verified ) + rom ( name "Capcom Quiz - Hatena no Daibouken (Japan).gb" size 262144 crc 8042afc5 sha1 168583EA18E02647F0B35F9BD0365E37BEC076CC flags verified ) ) game ( name "Captain America and the Avengers (USA)" description "Captain America and the Avengers (USA)" - rom ( name "Captain America and the Avengers (USA).gb" size 131072 crc C762B783 md5 DD5D45D9F8722F8DED9AB85097DAA4E5 sha1 A067C4E20642A6C17F35A855E2D4815470FC6C6B ) + rom ( name "Captain America and the Avengers (USA).gb" size 131072 crc c762b783 sha1 A067C4E20642A6C17F35A855E2D4815470FC6C6B flags verified ) ) game ( name "Captain Tsubasa J - Zenkoku Seiha e no Chousen (Japan) (SGB Enhanced)" description "Captain Tsubasa J - Zenkoku Seiha e no Chousen (Japan) (SGB Enhanced)" - rom ( name "Captain Tsubasa J - Zenkoku Seiha e no Chousen (Japan) (SGB Enhanced).gb" size 524288 crc 33A1E1CF md5 D4CE04DB5F2E259967C01A8BBD9792FC sha1 D3F9C5700389F7A876A4A821DB1F99E7DA4A6F68 ) + rom ( name "Captain Tsubasa J - Zenkoku Seiha e no Chousen (Japan) (SGB Enhanced).gb" size 524288 crc 33a1e1cf sha1 D3F9C5700389F7A876A4A821DB1F99E7DA4A6F68 ) ) game ( name "Captain Tsubasa VS (Japan)" description "Captain Tsubasa VS (Japan)" - rom ( name "Captain Tsubasa VS (Japan).gb" size 262144 crc A795E851 md5 844633E79CCFE6B7D8D2DA958E708E7C sha1 1D48763A64C127B7ECFF9876F20AE0761347B4C7 flags verified ) + rom ( name "Captain Tsubasa VS (Japan).gb" size 262144 crc a795e851 sha1 1D48763A64C127B7ECFF9876F20AE0761347B4C7 flags verified ) ) game ( name "Card Game (Japan)" description "Card Game (Japan)" - rom ( name "Card Game (Japan).gb" size 65536 crc D05F4C90 md5 E46274F5C7A7E2F7816174E32DA48FDB sha1 9AC64030C1E1CA89828EA54AC1FB0D884D6D92BB flags verified ) + rom ( name "Card Game (Japan).gb" size 65536 crc d05f4c90 sha1 9AC64030C1E1CA89828EA54AC1FB0D884D6D92BB flags verified ) ) game ( name "Casino FunPak (USA, Europe)" description "Casino FunPak (USA, Europe)" - rom ( name "Casino FunPak (USA, Europe).gb" size 131072 crc 8641BA55 md5 7A60B2DCA975ECD7166FD390CB9E3238 sha1 4418A8B2029F431EFD8888817589AF6C8B0E76CC flags verified ) + rom ( name "Casino FunPak (USA, Europe).gb" size 131072 crc 8641ba55 sha1 4418A8B2029F431EFD8888817589AF6C8B0E76CC flags verified ) ) game ( name "Casper (Europe)" description "Casper (Europe)" - rom ( name "Casper (Europe).gb" size 131072 crc E4B30634 md5 A614BBD7851374A870E57F43896FFE0E sha1 1A3D272D8AFE81731862A240A77C0D3B80B1D62F ) + rom ( name "Casper (Europe).gb" size 131072 crc e4b30634 sha1 1A3D272D8AFE81731862A240A77C0D3B80B1D62F ) ) game ( name "Casper (USA)" description "Casper (USA)" - rom ( name "Casper (USA).gb" size 131072 crc E67A10E1 md5 792C706A0ADDEBED39D177077A1CAAC0 sha1 18B90172789C87819FE4D606AA7874109BCD8024 ) + rom ( name "Casper (USA).gb" size 131072 crc e67a10e1 sha1 18B90172789C87819FE4D606AA7874109BCD8024 ) ) game ( name "Castelian (Europe)" description "Castelian (Europe)" - rom ( name "Castelian (Europe).gb" size 32768 crc 2F752404 md5 3502BE0DA5D444EC144AAE9CE1409E0D sha1 6720D86D420831A0A4865D4A59C4BA6FE98FA34D flags verified ) + rom ( name "Castelian (Europe).gb" size 32768 crc 2f752404 sha1 6720D86D420831A0A4865D4A59C4BA6FE98FA34D flags verified ) ) game ( name "Castelian (USA)" description "Castelian (USA)" - rom ( name "Castelian (USA).gb" size 32768 crc F2D739E4 md5 21CC47B68FC7C9C56EF3393DBE528600 sha1 A03982E2FFA9AA368FE11BC09F024207BADA45EB ) + rom ( name "Castelian (USA).gb" size 32768 crc f2d739e4 sha1 A03982E2FFA9AA368FE11BC09F024207BADA45EB ) ) game ( name "Castle Quest (Europe)" description "Castle Quest (Europe)" - rom ( name "Castle Quest (Europe).gb" size 131072 crc 2F8AAF6F md5 03CE24437224FF296A71F402663A0EE9 sha1 45B38A334481F620BB7165FEE81391036A54A748 flags verified ) + rom ( name "Castle Quest (Europe).gb" size 131072 crc 2f8aaf6f sha1 45B38A334481F620BB7165FEE81391036A54A748 flags verified ) ) game ( name "Castlevania - The Adventure (Europe)" description "Castlevania - The Adventure (Europe)" - rom ( name "Castlevania - The Adventure (Europe).gb" size 65536 crc 6977C265 md5 7C0CBB81025DEED9E32ECDCA5F1BB482 sha1 D54888039344597FA038F2C5EEDC0726DD35CC46 flags verified ) + rom ( name "Castlevania - The Adventure (Europe).gb" size 65536 crc 6977c265 sha1 D54888039344597FA038F2C5EEDC0726DD35CC46 flags verified ) ) game ( name "Castlevania - The Adventure (USA)" description "Castlevania - The Adventure (USA)" - rom ( name "Castlevania - The Adventure (USA).gb" size 65536 crc 216E6AA1 md5 0B4410C6B94D6359DBA5609AE9A32909 sha1 FD9116EFCD8EB9698F483CC5745F83B3674D7D13 ) + rom ( name "Castlevania - The Adventure (USA).gb" size 65536 crc 216e6aa1 sha1 FD9116EFCD8EB9698F483CC5745F83B3674D7D13 ) ) game ( name "Castlevania II - Belmont's Revenge (USA, Europe)" description "Castlevania II - Belmont's Revenge (USA, Europe)" - rom ( name "Castlevania II - Belmont's Revenge (USA, Europe).gb" size 131072 crc 8875C8FE md5 7C65E9DA405D2225D079F75E56276822 sha1 696B9AD1E9CFB7112977C9A7C05CF64FE8423D8A flags verified ) + rom ( name "Castlevania II - Belmont's Revenge (USA, Europe).gb" size 131072 crc 8875c8fe sha1 696B9AD1E9CFB7112977C9A7C05CF64FE8423D8A flags verified ) ) game ( name "Castlevania Legends (USA, Europe) (SGB Enhanced)" description "Castlevania Legends (USA, Europe) (SGB Enhanced)" - rom ( name "Castlevania Legends (USA, Europe) (SGB Enhanced).gb" size 262144 crc AD9C17FB md5 1475824E7262C0D6359F43C287E034A5 sha1 91A8E49BF6EAC5FE62EC2CC5E6DECBD08CE9B515 flags verified ) + rom ( name "Castlevania Legends (USA, Europe) (SGB Enhanced).gb" size 262144 crc ad9c17fb sha1 91A8E49BF6EAC5FE62EC2CC5E6DECBD08CE9B515 flags verified ) ) game ( name "Catrap (USA)" description "Catrap (USA)" - rom ( name "Catrap (USA).gb" size 32768 crc ADB96150 md5 5A75FE8DE54E4CBD09CAE23F050F6965 sha1 171E4D54F22F8DC137D12828FCC2DA9874C56970 flags verified ) + rom ( name "Catrap (USA).gb" size 32768 crc adb96150 sha1 171E4D54F22F8DC137D12828FCC2DA9874C56970 flags verified ) ) game ( name "Cave Noire (Japan)" description "Cave Noire (Japan)" - rom ( name "Cave Noire (Japan).gb" size 131072 crc 44256A2F md5 10D92861E262069CE31559E12B927AA0 sha1 6ACDF05AAC8E3792A98A199CB6E90180E95230CD ) + rom ( name "Cave Noire (Japan).gb" size 131072 crc 44256a2f sha1 6ACDF05AAC8E3792A98A199CB6E90180E95230CD ) ) game ( name "Centipede (USA)" description "Centipede (USA)" - rom ( name "Centipede (USA).gb" size 131072 crc E957014F md5 9C3AFF83A957D13E393F99CFF8445271 sha1 A3A5755020C9CBE13FC1A815288830D2E143367F ) + rom ( name "Centipede (USA).gb" size 131072 crc e957014f sha1 A3A5755020C9CBE13FC1A815288830D2E143367F ) ) game ( name "Centipede (USA, Europe)" description "Centipede (USA, Europe)" - rom ( name "Centipede (USA, Europe).gb" size 32768 crc 245AFCDC md5 2F1F67663193E3107E028E570A7CCD86 sha1 0106C3DC8016398E9D24E2472C867487C3BD376F flags verified ) + rom ( name "Centipede (USA, Europe).gb" size 32768 crc 245afcdc sha1 0106C3DC8016398E9D24E2472C867487C3BD376F flags verified ) ) game ( name "Chachamaru Boukenki 3 - Abyss no Tou (Japan)" description "Chachamaru Boukenki 3 - Abyss no Tou (Japan)" - rom ( name "Chachamaru Boukenki 3 - Abyss no Tou (Japan).gb" size 131072 crc 9DFD4BC0 md5 A5CCB24492F40038CD5C2BB00EF6E150 sha1 9A92CCC5758506A7AD07D251BF6C401FE33AD215 flags verified ) + rom ( name "Chachamaru Boukenki 3 - Abyss no Tou (Japan).gb" size 131072 crc 9dfd4bc0 sha1 9A92CCC5758506A7AD07D251BF6C401FE33AD215 flags verified ) ) game ( name "Chachamaru Panic (Japan)" description "Chachamaru Panic (Japan)" - rom ( name "Chachamaru Panic (Japan).gb" size 65536 crc AA920298 md5 48FA05F3C1E7546A30C546C0A141C034 sha1 C6CBB08D3BB9A4DECCF1DF880465CE5D23907839 flags verified ) + rom ( name "Chachamaru Panic (Japan).gb" size 65536 crc aa920298 sha1 C6CBB08D3BB9A4DECCF1DF880465CE5D23907839 flags verified ) ) game ( name "Chalvo 55 - Super Puzzle Action (Japan)" description "Chalvo 55 - Super Puzzle Action (Japan)" - rom ( name "Chalvo 55 - Super Puzzle Action (Japan).gb" size 524288 crc 74D50B47 md5 BA50565630891680C9CF8B1827FCA429 sha1 55AAD975351670C3F632E1EBCC939C48410D29B3 flags verified ) + rom ( name "Chalvo 55 - Super Puzzle Action (Japan).gb" size 524288 crc 74d50b47 sha1 55AAD975351670C3F632E1EBCC939C48410D29B3 flags verified ) ) game ( name "Championship Pool (USA)" description "Championship Pool (USA)" - rom ( name "Championship Pool (USA).gb" size 131072 crc EF02BEB6 md5 01214C42AA62B421E7CEF6B3E4511A5F sha1 5698FA095F737A4345F02649B4B0B96AD66660D0 ) + rom ( name "Championship Pool (USA).gb" size 131072 crc ef02beb6 sha1 5698FA095F737A4345F02649B4B0B96AD66660D0 ) ) game ( name "Chase H.Q. (USA, Europe)" description "Chase H.Q. (USA, Europe)" - rom ( name "Chase H.Q. (USA, Europe).gb" size 131072 crc 67A45D19 md5 6884A31366F565CA25935E1FBA52EFBC sha1 CBCD6254B1B0227BA6AA8D95C979ABB7FE8E4D38 flags verified ) + rom ( name "Chase H.Q. (USA, Europe).gb" size 131072 crc 67a45d19 sha1 CBCD6254B1B0227BA6AA8D95C979ABB7FE8E4D38 flags verified ) ) game ( - name "Chessmaster, The (DMG-EM) (Europe)" - description "Chessmaster, The (DMG-EM) (Europe)" - rom ( name "Chessmaster, The (DMG-EM) (Europe).gb" size 65536 crc 02852E24 md5 FB62E511419FF8EA89EE1CF558E7208A sha1 26F1D9CBB392FF07EAFB8CD59526470849DE9F38 flags verified ) + name "Chessmaster, The (Europe)" + description "Chessmaster, The (Europe)" + rom ( name "Chessmaster, The (Europe).gb" size 65536 crc 02852e24 sha1 26F1D9CBB392FF07EAFB8CD59526470849DE9F38 flags verified ) ) game ( - name "Chessmaster, The (DMG-EM) (Japan)" - description "Chessmaster, The (DMG-EM) (Japan)" - rom ( name "Chessmaster, The (DMG-EM) (Japan).gb" size 65536 crc 82150E4A md5 F04F23D228F03311545B1B3BB9B3B73C sha1 092D878BB8431AC1334DFA9CB91C4B12F1A4F365 flags verified ) + name "Chessmaster, The (Japan)" + description "Chessmaster, The (Japan)" + rom ( name "Chessmaster, The (Japan).gb" size 65536 crc 82150e4a sha1 092D878BB8431AC1334DFA9CB91C4B12F1A4F365 flags verified ) ) game ( - name "Chessmaster, The (DMG-N5) (USA)" - description "Chessmaster, The (DMG-N5) (USA)" - rom ( name "Chessmaster, The (DMG-N5) (USA).gb" size 65536 crc 0C1D2B68 md5 3DB9F9F0C5913D3C9F7B5D5FBF7B5E02 sha1 0E167C8BA379103775AE8E18EC9E0B819BDD5897 ) + name "Chessmaster, The (USA)" + description "Chessmaster, The (USA)" + rom ( name "Chessmaster, The (USA).gb" size 65536 crc 0c1d2b68 sha1 0E167C8BA379103775AE8E18EC9E0B819BDD5897 ) ) game ( - name "Chessmaster, The (DMG-N5) (USA) (Rev A)" - description "Chessmaster, The (DMG-N5) (USA) (Rev A)" - rom ( name "Chessmaster, The (DMG-N5) (USA) (Rev A).gb" size 65536 crc 59ED370C md5 6B6D4A25D3C1E2890B22271C44E62DBF sha1 F0351FAAB8B912967552684D4160F5CF94540D41 ) + name "Chessmaster, The (USA) (Rev 1)" + description "Chessmaster, The (USA) (Rev 1)" + rom ( name "Chessmaster, The (USA) (Rev 1).gb" size 65536 crc 59ed370c sha1 F0351FAAB8B912967552684D4160F5CF94540D41 ) ) game ( name "Chibi Maruko-chan - Maruko Deluxe Theater (Japan) (SGB Enhanced)" description "Chibi Maruko-chan - Maruko Deluxe Theater (Japan) (SGB Enhanced)" - rom ( name "Chibi Maruko-chan - Maruko Deluxe Theater (Japan) (SGB Enhanced).gb" size 131072 crc 886049F9 md5 648770B4FE55DBCD0D834536BB8685B0 sha1 0E774A12ED2D99B5A62A5AD3F634F2C32DA5929A ) + rom ( name "Chibi Maruko-chan - Maruko Deluxe Theater (Japan) (SGB Enhanced).gb" size 131072 crc 886049f9 sha1 0E774A12ED2D99B5A62A5AD3F634F2C32DA5929A ) ) game ( name "Chibi Maruko-chan - Okozukai Daisakusen! (Japan)" description "Chibi Maruko-chan - Okozukai Daisakusen! (Japan)" - rom ( name "Chibi Maruko-chan - Okozukai Daisakusen! (Japan).gb" size 65536 crc EAB175FF md5 2843796ABF7CBA23556B0006F398C4FB sha1 1B6838B9711ECBC6C09606DA53D53309593103B2 flags verified ) + rom ( name "Chibi Maruko-chan - Okozukai Daisakusen! (Japan).gb" size 65536 crc eab175ff sha1 1B6838B9711ECBC6C09606DA53D53309593103B2 flags verified ) ) game ( name "Chibi Maruko-chan 2 - Deluxe Maruko World (Japan)" description "Chibi Maruko-chan 2 - Deluxe Maruko World (Japan)" - rom ( name "Chibi Maruko-chan 2 - Deluxe Maruko World (Japan).gb" size 131072 crc ABFF3314 md5 B8DB331900E2FF84A83EFA787A11131D sha1 4FD5EB092086ED62AA978EACC1C3904C921F9615 flags verified ) + rom ( name "Chibi Maruko-chan 2 - Deluxe Maruko World (Japan).gb" size 131072 crc abff3314 sha1 4FD5EB092086ED62AA978EACC1C3904C921F9615 flags verified ) ) game ( name "Chibi Maruko-chan 3 - Mezase! Game Taishou no Maki (Japan)" description "Chibi Maruko-chan 3 - Mezase! Game Taishou no Maki (Japan)" - rom ( name "Chibi Maruko-chan 3 - Mezase! Game Taishou no Maki (Japan).gb" size 131072 crc 44E933C8 md5 F91BD5EDF950B0D70DDFF98C1AA49F30 sha1 127FA75126FBD45EA0E3F95F862FBD4F8182780E flags verified ) + rom ( name "Chibi Maruko-chan 3 - Mezase! Game Taishou no Maki (Japan).gb" size 131072 crc 44e933c8 sha1 127FA75126FBD45EA0E3F95F862FBD4F8182780E flags verified ) ) game ( name "Chibi Maruko-chan 4 - Kore ga Nihon Da yo! Ouji-sama (Japan)" description "Chibi Maruko-chan 4 - Kore ga Nihon Da yo! Ouji-sama (Japan)" - rom ( name "Chibi Maruko-chan 4 - Kore ga Nihon Da yo! Ouji-sama (Japan).gb" size 131072 crc E55138BE md5 69D05C64157F105855171EEB027ECCB3 sha1 A4B268924E2FB500B8B13461A9CB20AEC648A52F flags verified ) + rom ( name "Chibi Maruko-chan 4 - Kore ga Nihon Da yo! Ouji-sama (Japan).gb" size 131072 crc e55138be sha1 A4B268924E2FB500B8B13461A9CB20AEC648A52F flags verified ) ) game ( name "Chiki Chiki Machine Mou Race (Japan)" description "Chiki Chiki Machine Mou Race (Japan)" - rom ( name "Chiki Chiki Machine Mou Race (Japan).gb" size 131072 crc 7E40044A md5 8E1D2E3B4F20361C496E93F8D2E08339 sha1 45963623BC09E0A132867E1A78173B2C747C3B6F flags verified ) + rom ( name "Chiki Chiki Machine Mou Race (Japan).gb" size 131072 crc 7e40044a sha1 45963623BC09E0A132867E1A78173B2C747C3B6F flags verified ) ) game ( name "Chiki Chiki Tengoku (Japan)" description "Chiki Chiki Tengoku (Japan)" - rom ( name "Chiki Chiki Tengoku (Japan).gb" size 32768 crc EB33F601 md5 C6C1CE5F473FD6A31033878D32C885D4 sha1 56012E7F9150EC8F9117B0540DCBD2BF82C948BB ) + rom ( name "Chiki Chiki Tengoku (Japan).gb" size 32768 crc eb33f601 sha1 56012E7F9150EC8F9117B0540DCBD2BF82C948BB ) ) game ( - name "Chikyuu Kaihou Gun ZAS (Japan)" - description "Chikyuu Kaihou Gun ZAS (Japan)" - rom ( name "Chikyuu Kaihou Gun ZAS (Japan).gb" size 131072 crc 7BFD1CFF md5 A74AA804A3A6439303583E6C0B413B00 sha1 2FF6D0242D845669445E3D97FFFAE5C5F7943CFD ) + name "Chikyuu Kaihou Gun ZAS (Japan) (En)" + description "Chikyuu Kaihou Gun ZAS (Japan) (En)" + rom ( name "Chikyuu Kaihou Gun ZAS (Japan) (En).gb" size 131072 crc 7bfd1cff sha1 2FF6D0242D845669445E3D97FFFAE5C5F7943CFD ) ) game ( name "Choplifter II (Japan)" description "Choplifter II (Japan)" - rom ( name "Choplifter II (Japan).gb" size 131072 crc 5109F484 md5 022F61999868AA209E0A2F66BA4EE710 sha1 9392FFC6831D5F029F5AD906AF40B607B8EB221B flags verified ) + rom ( name "Choplifter II (Japan).gb" size 131072 crc 5109f484 sha1 9392FFC6831D5F029F5AD906AF40B607B8EB221B flags verified ) ) game ( name "Choplifter II - Rescue & Survive (Europe)" description "Choplifter II - Rescue & Survive (Europe)" - rom ( name "Choplifter II - Rescue & Survive (Europe).gb" size 131072 crc 5E2E4E19 md5 24C35F0158E14746D45251B4216D8693 sha1 08F5CDBCB650BE51FE3998A28174E40997618349 flags verified ) + rom ( name "Choplifter II - Rescue & Survive (Europe).gb" size 131072 crc 5e2e4e19 sha1 08F5CDBCB650BE51FE3998A28174E40997618349 flags verified ) ) game ( name "Choplifter II - Rescue & Survive (USA)" description "Choplifter II - Rescue & Survive (USA)" - rom ( name "Choplifter II - Rescue & Survive (USA).gb" size 131072 crc 9C7D5E79 md5 D5F88D0799C85B6D59F12542DA403691 sha1 76EF770B9C75485CC29869FCA6118887AEE208DA ) + rom ( name "Choplifter II - Rescue & Survive (USA).gb" size 131072 crc 9c7d5e79 sha1 76EF770B9C75485CC29869FCA6118887AEE208DA ) ) game ( name "Choplifter III (Europe)" description "Choplifter III (Europe)" - rom ( name "Choplifter III (Europe).gb" size 131072 crc 1B3B46EF md5 04A6E77D1FABCBE325882E4BD79D6D4B sha1 FB1C83EE69FA32C26CDC7031733F17B90CDB0570 flags verified ) + rom ( name "Choplifter III (Europe).gb" size 131072 crc 1b3b46ef sha1 FB1C83EE69FA32C26CDC7031733F17B90CDB0570 flags verified ) ) game ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (SGB Enhanced)" description "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (SGB Enhanced)" - rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (SGB Enhanced).gb" size 524288 crc B3E8028D md5 C856CEE0ABFC387AAEF8C851CC2A67B8 sha1 66E8DF39AC137FE2B92581F2D88ADFA0B0C3AC14 flags verified ) + rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (SGB Enhanced).gb" size 524288 crc b3e8028d sha1 66E8DF39AC137FE2B92581F2D88ADFA0B0C3AC14 flags verified ) ) game ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (Beta) (SGB Enhanced)" description "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (Beta) (SGB Enhanced)" - rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (Beta) (SGB Enhanced).gb" size 524288 crc E6C3A473 md5 70D54771DDE507F26713FBA445F49A4F sha1 AC2360D790C855FDE91FCA26EE88A4814A1F2E9F flags verified ) + rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster (Japan) (Beta) (SGB Enhanced).gb" size 524288 crc e6c3a473 sha1 AC2360D790C855FDE91FCA26EE88A4814A1F2E9F flags verified ) ) game ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster 2 (Japan) (SGB Enhanced)" description "Chou Mashin Eiyuu Den Wataru - Mazekko Monster 2 (Japan) (SGB Enhanced)" - rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster 2 (Japan) (SGB Enhanced).gb" size 524288 crc E5520693 md5 F67D293F77A27DE481C7541D6021A659 sha1 54D2672D9720FA4322A7A45244AA898D321C1DD1 flags verified ) + rom ( name "Chou Mashin Eiyuu Den Wataru - Mazekko Monster 2 (Japan) (SGB Enhanced).gb" size 524288 crc e5520693 sha1 54D2672D9720FA4322A7A45244AA898D321C1DD1 flags verified ) ) game ( name "Chousoku Spinner (Japan) (SGB Enhanced)" description "Chousoku Spinner (Japan) (SGB Enhanced)" - rom ( name "Chousoku Spinner (Japan) (SGB Enhanced).gb" size 524288 crc B4FA9CF2 md5 7D2C84BF29EC10488C8AE3B8018EDC8A sha1 057A3251BBB7EB4E04B01F786BD2986AF5EABC58 ) + rom ( name "Chousoku Spinner (Japan) (SGB Enhanced).gb" size 524288 crc b4fa9cf2 sha1 057A3251BBB7EB4E04B01F786BD2986AF5EABC58 ) ) game ( name "Chuck Rock (USA, Europe)" description "Chuck Rock (USA, Europe)" - rom ( name "Chuck Rock (USA, Europe).gb" size 131072 crc C5951D9E md5 435B566A4B3745B0ACC5A976BEDD9245 sha1 601453F98BA7D92EBE71F3E86952A584CBEA090C flags verified ) + rom ( name "Chuck Rock (USA, Europe).gb" size 131072 crc c5951d9e sha1 601453F98BA7D92EBE71F3E86952A584CBEA090C flags verified ) ) game ( name "Cliffhanger (USA, Europe)" description "Cliffhanger (USA, Europe)" - rom ( name "Cliffhanger (USA, Europe).gb" size 131072 crc AA133439 md5 B33D6F65F4A566D715CE480BFFD004AD sha1 C74F85035842F8A2D9560066D7065FF86D9107E2 flags verified ) + rom ( name "Cliffhanger (USA, Europe).gb" size 131072 crc aa133439 sha1 C74F85035842F8A2D9560066D7065FF86D9107E2 flags verified ) ) game ( name "Collection Pocket (Japan) (SGB Enhanced)" description "Collection Pocket (Japan) (SGB Enhanced)" - rom ( name "Collection Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 34E62C8B md5 1C0FAB1D2D046BEE898372BED404C31A sha1 DAAD5EC53DA0E375CEE3962C0A9031D8A67020FD ) + rom ( name "Collection Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 34e62c8b sha1 DAAD5EC53DA0E375CEE3962C0A9031D8A67020FD ) ) game ( name "College Slam (USA)" description "College Slam (USA)" - rom ( name "College Slam (USA).gb" size 524288 crc A549A572 md5 A61B0C0E0F0D9833CBA22811CAABD3BA sha1 84DC6269FBE4EE4C157F940B0A9630412E099CC6 ) + rom ( name "College Slam (USA).gb" size 524288 crc a549a572 sha1 84DC6269FBE4EE4C157F940B0A9630412E099CC6 ) ) game ( name "Contra (Japan)" description "Contra (Japan)" - rom ( name "Contra (Japan).gb" size 131072 crc CDE6DE15 md5 2CC322A27530F6AAA09A35B2F14AEBD5 sha1 C8B34B5ABA3D448E357B59CDF106EE9B134713DB ) + rom ( name "Contra (Japan).gb" size 131072 crc cde6de15 sha1 C8B34B5ABA3D448E357B59CDF106EE9B134713DB ) ) game ( name "Contra - The Alien Wars (USA) (SGB Enhanced)" description "Contra - The Alien Wars (USA) (SGB Enhanced)" - rom ( name "Contra - The Alien Wars (USA) (SGB Enhanced).gb" size 131072 crc F1C81EB0 md5 8D885E185AD2A0CB5C9E3B152BD24583 sha1 2E23477EB8738D7FB45E13B02F054422222C9C4F ) + rom ( name "Contra - The Alien Wars (USA) (SGB Enhanced).gb" size 131072 crc f1c81eb0 sha1 2E23477EB8738D7FB45E13B02F054422222C9C4F ) ) game ( name "Contra Spirits (Japan) (SGB Enhanced)" description "Contra Spirits (Japan) (SGB Enhanced)" - rom ( name "Contra Spirits (Japan) (SGB Enhanced).gb" size 131072 crc 7FC22DF5 md5 7B1E0DD44871AA990780D93565FDB565 sha1 72213C5D8AF05CAD5F17A42566F7383066612EEE ) + rom ( name "Contra Spirits (Japan) (SGB Enhanced).gb" size 131072 crc 7fc22df5 sha1 72213C5D8AF05CAD5F17A42566F7383066612EEE ) ) game ( name "Cool Ball (USA)" description "Cool Ball (USA)" - rom ( name "Cool Ball (USA).gb" size 32768 crc E045B886 md5 57B192B42B4E1945CC7F20C98F7E1DAB sha1 F1932D4A3F063C5395E8558A63C64E5840789CE6 ) + rom ( name "Cool Ball (USA).gb" size 32768 crc e045b886 sha1 F1932D4A3F063C5395E8558A63C64E5840789CE6 ) ) game ( name "Cool Hand (Europe)" description "Cool Hand (Europe)" - rom ( name "Cool Hand (Europe).gb" size 262144 crc 0D430D1A md5 0397DD31E902A4A04F04B847AD21317D sha1 A6FE59BCC29B6D9AE6712D99822A123D2434F3B3 flags verified ) + rom ( name "Cool Hand (Europe).gb" size 262144 crc 0d430d1a sha1 A6FE59BCC29B6D9AE6712D99822A123D2434F3B3 flags verified ) ) game ( name "Cool Hand (Europe) (Fr,De)" description "Cool Hand (Europe) (Fr,De)" - rom ( name "Cool Hand (Europe) (Fr,De).gb" size 262144 crc A2F01695 md5 C2BD6566D434E175C308D99803922E3D sha1 B26441E13B9DC806B182999FF8784CEF46961010 ) + rom ( name "Cool Hand (Europe) (Fr,De).gb" size 262144 crc a2f01695 sha1 B26441E13B9DC806B182999FF8784CEF46961010 flags verified ) ) game ( name "Cool Spot (Europe)" description "Cool Spot (Europe)" - rom ( name "Cool Spot (Europe).gb" size 131072 crc 1987EACC md5 1DDFF2C150456069776F8C79671CB9F7 sha1 51EFA64A6047879B4B9E6E521E65C9D7F191556F flags verified ) + rom ( name "Cool Spot (Europe).gb" size 131072 crc 1987eacc sha1 51EFA64A6047879B4B9E6E521E65C9D7F191556F flags verified ) ) game ( name "Cool Spot (USA)" description "Cool Spot (USA)" - rom ( name "Cool Spot (USA).gb" size 131072 crc ABA1DAC9 md5 27D7C8AE7CC36C1D5DFD8BD15DF57E8D sha1 B23F3259FDEC43CE004E536D30255E1C2A642FFC ) + rom ( name "Cool Spot (USA).gb" size 131072 crc aba1dac9 sha1 B23F3259FDEC43CE004E536D30255E1C2A642FFC flags verified ) ) game ( name "Cool World (USA, Europe)" description "Cool World (USA, Europe)" - rom ( name "Cool World (USA, Europe).gb" size 131072 crc A193C0D0 md5 79BB2BA29C937253DD964142713A7869 sha1 1919495CC83C4126C90D6CFA2E14427B6364DA3A flags verified ) + rom ( name "Cool World (USA, Europe).gb" size 131072 crc a193c0d0 sha1 1919495CC83C4126C90D6CFA2E14427B6364DA3A flags verified ) ) game ( name "Cosmo Tank (Japan)" description "Cosmo Tank (Japan)" - rom ( name "Cosmo Tank (Japan).gb" size 131072 crc 80B21DF1 md5 F3580F0BFCC3B39D94EEE79820C9946D sha1 0D6A0A95F4FC9F2C61E2FCCEE0321236D3A6F5E5 flags verified ) + rom ( name "Cosmo Tank (Japan).gb" size 131072 crc 80b21df1 sha1 0D6A0A95F4FC9F2C61E2FCCEE0321236D3A6F5E5 flags verified ) ) game ( name "Cosmo Tank (USA)" description "Cosmo Tank (USA)" - rom ( name "Cosmo Tank (USA).gb" size 131072 crc 2E767D25 md5 B340BAD71C781BD1394D95241ED1ADCE sha1 48A8F5C50A237F11C8E18EFD03A5282F493312BC ) + rom ( name "Cosmo Tank (USA).gb" size 131072 crc 2e767d25 sha1 48A8F5C50A237F11C8E18EFD03A5282F493312BC ) ) game ( name "Cosmo Tank (Japan) (Beta)" description "Cosmo Tank (Japan) (Beta)" - rom ( name "Cosmo Tank (Japan) (Beta).gb" size 131072 crc 2022BBB9 md5 F4352B697190FCCADD9D07657376DA5E sha1 8963C2E8E42C452528078F10DF699FD266F01749 ) + rom ( name "Cosmo Tank (Japan) (Beta).gb" size 131072 crc 2022bbb9 sha1 8963C2E8E42C452528078F10DF699FD266F01749 flags verified ) ) game ( name "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" description "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" - rom ( name "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced).gb" size 262144 crc DC723A9E md5 82E7321AFED96C7639A817DE1F88A6F8 sha1 1DBD23B639B8A4B20ED28C3637608E03EBF59DAD ) + rom ( name "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced).gb" size 262144 crc dc723a9e sha1 1DBD23B639B8A4B20ED28C3637608E03EBF59DAD ) ) game ( name "Crayon Shin-chan - Ora to Shiro wa Otomodachi Da yo (Japan)" description "Crayon Shin-chan - Ora to Shiro wa Otomodachi Da yo (Japan)" - rom ( name "Crayon Shin-chan - Ora to Shiro wa Otomodachi Da yo (Japan).gb" size 131072 crc 2699942C md5 A5D383A5F6E9D61B505429257F2C44C1 sha1 E8DA27B1B782C154B65BA6CDC2E3915925A67566 ) + rom ( name "Crayon Shin-chan - Ora to Shiro wa Otomodachi Da yo (Japan).gb" size 131072 crc 2699942c sha1 E8DA27B1B782C154B65BA6CDC2E3915925A67566 flags verified ) ) game ( name "Crayon Shin-chan 2 - Ora to Wanpaku Gokko Dazo (Japan)" description "Crayon Shin-chan 2 - Ora to Wanpaku Gokko Dazo (Japan)" - rom ( name "Crayon Shin-chan 2 - Ora to Wanpaku Gokko Dazo (Japan).gb" size 131072 crc CA6E0BE0 md5 9116E4FA652B09B181F547AE0E782022 sha1 F034CC9C8B5962C548EBA445033C8C912E3A19E2 flags verified ) + rom ( name "Crayon Shin-chan 2 - Ora to Wanpaku Gokko Dazo (Japan).gb" size 131072 crc ca6e0be0 sha1 F034CC9C8B5962C548EBA445033C8C912E3A19E2 flags verified ) ) game ( name "Crayon Shin-chan 3 - Ora no Gokigen Athletic (Japan)" description "Crayon Shin-chan 3 - Ora no Gokigen Athletic (Japan)" - rom ( name "Crayon Shin-chan 3 - Ora no Gokigen Athletic (Japan).gb" size 131072 crc 24A12807 md5 1D69E97AFF3C67471B6030C72A8833E1 sha1 2D0119EC7B44BB89964C98024C46AFD39490B5C9 flags verified ) + rom ( name "Crayon Shin-chan 3 - Ora no Gokigen Athletic (Japan).gb" size 131072 crc 24a12807 sha1 2D0119EC7B44BB89964C98024C46AFD39490B5C9 flags verified ) ) game ( name "Crayon Shin-chan 4 - Ora no Itazura Daihenshin (Japan) (SGB Enhanced)" description "Crayon Shin-chan 4 - Ora no Itazura Daihenshin (Japan) (SGB Enhanced)" - rom ( name "Crayon Shin-chan 4 - Ora no Itazura Daihenshin (Japan) (SGB Enhanced).gb" size 131072 crc 37D4AA8C md5 BCB3D47C291FD0A26B2C7B1082C3AD88 sha1 B5BB01AD7E25E9E83C564CCF604A59F8930CD0D5 ) + rom ( name "Crayon Shin-chan 4 - Ora no Itazura Daihenshin (Japan) (SGB Enhanced).gb" size 131072 crc 37d4aa8c sha1 B5BB01AD7E25E9E83C564CCF604A59F8930CD0D5 ) ) game ( name "Crystal Quest (USA)" description "Crystal Quest (USA)" - rom ( name "Crystal Quest (USA).gb" size 32768 crc 51300CFD md5 E15A6B601C845E425F62EF2B7AED691F sha1 6C3BA1E407FF378DC004AC58D6A16180BD76A1B3 flags verified ) + rom ( name "Crystal Quest (USA).gb" size 32768 crc 51300cfd sha1 6C3BA1E407FF378DC004AC58D6A16180BD76A1B3 flags verified ) ) game ( name "Cult Jump (Japan)" description "Cult Jump (Japan)" - rom ( name "Cult Jump (Japan).gb" size 262144 crc 943059BA md5 66C924C9F21AB1FEDDC65FA923DC1F4D sha1 6A67820EF648D2E24C1212079F5CAC43E04CF0BF ) + rom ( name "Cult Jump (Japan).gb" size 262144 crc 943059ba sha1 6A67820EF648D2E24C1212079F5CAC43E04CF0BF ) ) game ( name "Cult Master - Ultraman ni Miserarete (Japan)" description "Cult Master - Ultraman ni Miserarete (Japan)" - rom ( name "Cult Master - Ultraman ni Miserarete (Japan).gb" size 262144 crc C3EB82EF md5 2E85BBFC5BC2AAA51955F0FCBCDA0842 sha1 F0E63A0A4E7B576C7460E810EB6F50D4C5B68769 ) + rom ( name "Cult Master - Ultraman ni Miserarete (Japan).gb" size 262144 crc c3eb82ef sha1 F0E63A0A4E7B576C7460E810EB6F50D4C5B68769 flags verified ) ) game ( name "CutThroat Island (USA, Europe)" description "CutThroat Island (USA, Europe)" - rom ( name "CutThroat Island (USA, Europe).gb" size 262144 crc EEBDD360 md5 C5858497D4E8FCFBB7221E327A0E79B5 sha1 5E99EA51B383CDCD53874EB027EBD59D2A3156B9 flags verified ) + rom ( name "CutThroat Island (USA, Europe).gb" size 262144 crc eebdd360 sha1 5E99EA51B383CDCD53874EB027EBD59D2A3156B9 flags verified ) ) game ( name "Cyraid (USA)" description "Cyraid (USA)" - rom ( name "Cyraid (USA).gb" size 65536 crc 9D00DA55 md5 E55ECBD33D5813FE6E9A4CA1D04E9F15 sha1 E295FCE5531BE0DF7F5A10628608E0DCF54DA71B ) + rom ( name "Cyraid (USA).gb" size 65536 crc 9d00da55 sha1 E295FCE5531BE0DF7F5A10628608E0DCF54DA71B ) ) game ( name "Daedalian Opus (USA)" description "Daedalian Opus (USA)" - rom ( name "Daedalian Opus (USA).gb" size 32768 crc B6B51FCE md5 34B3D0F0843B83E5B0E00BC3D0669793 sha1 7A9294DE582F7D3FFD8D14A786774C56AF7CE7BC flags verified ) + rom ( name "Daedalian Opus (USA).gb" size 32768 crc b6b51fce sha1 7A9294DE582F7D3FFD8D14A786774C56AF7CE7BC flags verified ) ) game ( name "Daffy Duck (USA, Europe) (SGB Enhanced)" description "Daffy Duck (USA, Europe) (SGB Enhanced)" - rom ( name "Daffy Duck (USA, Europe) (SGB Enhanced).gb" size 262144 crc C47671F3 md5 7C9CEF32DB758D3F6B8A8A23B6902E2D sha1 75B384222D07947BAED2213C288385C4B91E1911 flags verified ) + rom ( name "Daffy Duck (USA, Europe) (SGB Enhanced).gb" size 262144 crc c47671f3 sha1 75B384222D07947BAED2213C288385C4B91E1911 flags verified ) ) game ( name "Daffy Duck (Europe)" description "Daffy Duck (Europe)" - rom ( name "Daffy Duck (Europe).gb" size 131072 crc 13DD647D md5 F1DBC21B1B8F8DCBE9A15BC9EF68FB9C sha1 344C3409410FE5F88796AAFD125C522319B78012 flags verified ) + rom ( name "Daffy Duck (Europe).gb" size 131072 crc 13dd647d sha1 344C3409410FE5F88796AAFD125C522319B78012 flags verified ) ) game ( name "Dai-2-ji Super Robot Taisen G (Japan) (SGB Enhanced)" description "Dai-2-ji Super Robot Taisen G (Japan) (SGB Enhanced)" - rom ( name "Dai-2-ji Super Robot Taisen G (Japan) (SGB Enhanced).gb" size 524288 crc DF8B2B20 md5 24F96821369540F25DC3768053569029 sha1 0BAA751363C05F9830656F98E77902D543822656 flags verified ) + rom ( name "Dai-2-ji Super Robot Taisen G (Japan) (SGB Enhanced).gb" size 524288 crc df8b2b20 sha1 0BAA751363C05F9830656F98E77902D543822656 flags verified ) ) game ( name "Daikaijuu Monogatari - The Miracle of the Zone (Japan) (SGB Enhanced)" description "Daikaijuu Monogatari - The Miracle of the Zone (Japan) (SGB Enhanced)" - rom ( name "Daikaijuu Monogatari - The Miracle of the Zone (Japan) (SGB Enhanced).gb" size 524288 crc 26D2D5C2 md5 D3FCE7259E7768C7A6315B32A54CB32D sha1 44CAFCB56F470881B67E57C0649AFBC638CDA136 flags verified ) + rom ( name "Daikaijuu Monogatari - The Miracle of the Zone (Japan) (SGB Enhanced).gb" size 524288 crc 26d2d5c2 sha1 44CAFCB56F470881B67E57C0649AFBC638CDA136 flags verified ) ) game ( name "Daiku no Gen-san - Ghost Building Company (Japan)" description "Daiku no Gen-san - Ghost Building Company (Japan)" - rom ( name "Daiku no Gen-san - Ghost Building Company (Japan).gb" size 262144 crc 9E0D2B45 md5 D20D4B7E9F7299AC1F59C3130ABB6E02 sha1 90574CC899210515E83DEC714EB4D69416DCF3A3 flags verified ) + rom ( name "Daiku no Gen-san - Ghost Building Company (Japan).gb" size 262144 crc 9e0d2b45 sha1 90574CC899210515E83DEC714EB4D69416DCF3A3 flags verified ) ) game ( name "Daiku no Gen-san - Robot Teikoku no Yabou (Japan)" description "Daiku no Gen-san - Robot Teikoku no Yabou (Japan)" - rom ( name "Daiku no Gen-san - Robot Teikoku no Yabou (Japan).gb" size 262144 crc 70819E03 md5 A46DED16CDF9308ED765E857203A59E7 sha1 0C68250AADCA89027B05659122C89682FF833298 flags verified ) + rom ( name "Daiku no Gen-san - Robot Teikoku no Yabou (Japan).gb" size 262144 crc 70819e03 sha1 0C68250AADCA89027B05659122C89682FF833298 flags verified ) ) game ( name "Daisenryaku (Japan)" description "Daisenryaku (Japan)" - rom ( name "Daisenryaku (Japan).gb" size 131072 crc C8F80D90 md5 8F4262923E4A4A9C4F5074841BDCE103 sha1 79E724619D21EBB3CD5DE5438535A7EE25009DE0 flags verified ) + rom ( name "Daisenryaku (Japan).gb" size 131072 crc c8f80d90 sha1 79E724619D21EBB3CD5DE5438535A7EE25009DE0 flags verified ) ) game ( name "Darkman (USA, Europe)" description "Darkman (USA, Europe)" - rom ( name "Darkman (USA, Europe).gb" size 131072 crc FF858DA9 md5 849C5FE4002DD4240020E9EC84C8DC29 sha1 F168733DDF4F083559E52198A503E4F295FABF0D flags verified ) + rom ( name "Darkman (USA, Europe).gb" size 131072 crc ff858da9 sha1 F168733DDF4F083559E52198A503E4F295FABF0D flags verified ) ) game ( name "Darkwing Duck (Europe)" description "Darkwing Duck (Europe)" - rom ( name "Darkwing Duck (Europe).gb" size 131072 crc BE975B4F md5 5C837AEBA2AA844D4CD34653D4E332EA sha1 4E51919597AA72DD32182F9AFEE34F148036655F ) + rom ( name "Darkwing Duck (Europe).gb" size 131072 crc be975b4f sha1 4E51919597AA72DD32182F9AFEE34F148036655F flags verified ) ) game ( name "Darkwing Duck (USA)" description "Darkwing Duck (USA)" - rom ( name "Darkwing Duck (USA).gb" size 131072 crc 238B9646 md5 7D776329212FA7CC2B00C5A46F06DD92 sha1 CC1F12F3EC3852657A14D11C13D1EF91FBDDA5BB ) + rom ( name "Darkwing Duck (USA).gb" size 131072 crc 238b9646 sha1 CC1F12F3EC3852657A14D11C13D1EF91FBDDA5BB flags verified ) ) game ( name "Darkwing Duck (Germany)" description "Darkwing Duck (Germany)" - rom ( name "Darkwing Duck (Germany).gb" size 131072 crc 176C1FA2 md5 B364D2BBE0A3A09ADAFA9B6B982A9ACB sha1 5960DC01E06F19E166646504BC3097248F4A22CB flags verified ) + rom ( name "Darkwing Duck (Germany).gb" size 131072 crc 176c1fa2 sha1 5960DC01E06F19E166646504BC3097248F4A22CB flags verified ) ) game ( name "Darkwing Duck (Spain)" description "Darkwing Duck (Spain)" - rom ( name "Darkwing Duck (Spain).gb" size 131072 crc A1D4C544 md5 780BBEC4B26617B3A1A4FCDFA5A731E4 sha1 3D4B301AAB995BDF19B15ED5040DF7426A2E8057 ) + rom ( name "Darkwing Duck (Spain).gb" size 131072 crc a1d4c544 sha1 3D4B301AAB995BDF19B15ED5040DF7426A2E8057 flags verified ) ) game ( - name "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe)" - description "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe)" - rom ( name "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (Europe).gb" size 65536 crc 25F82BB1 md5 76BE24B2A33617DAD679F40A29B0B0FF sha1 4800E5D5A4230918EC751CEEAE7AC9342E0B8D83 flags verified ) + name "David Crane's The Rescue of Princess Blobette (Europe)" + description "David Crane's The Rescue of Princess Blobette (Europe)" + rom ( name "David Crane's The Rescue of Princess Blobette (Europe).gb" size 65536 crc 25f82bb1 sha1 4800E5D5A4230918EC751CEEAE7AC9342E0B8D83 flags verified ) ) game ( - name "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (USA)" - description "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (USA)" - rom ( name "David Crane's The Rescue of Princess Blobette Starring A Boy and His Blob (USA).gb" size 65536 crc 8210A03F md5 81F7DEE7546E630DE075A3397349EFB8 sha1 0A45D1B98646FD7832B5119B04BC8D6D6D0F657A flags verified ) + name "David Crane's The Rescue of Princess Blobette (USA)" + description "David Crane's The Rescue of Princess Blobette (USA)" + rom ( name "David Crane's The Rescue of Princess Blobette (USA).gb" size 65536 crc 8210a03f sha1 0A45D1B98646FD7832B5119B04BC8D6D6D0F657A flags verified ) ) game ( name "Days of Thunder (USA, Europe)" description "Days of Thunder (USA, Europe)" - rom ( name "Days of Thunder (USA, Europe).gb" size 131072 crc 35D9BE0E md5 BDCF042BC2458768522C3CCA43C89EE1 sha1 1BF54293A332FD822911218DCC4A94FCDA949CCF flags verified ) + rom ( name "Days of Thunder (USA, Europe).gb" size 131072 crc 35d9be0e sha1 1BF54293A332FD822911218DCC4A94FCDA949CCF flags verified ) ) game ( name "Dead Heat Scramble (Japan)" description "Dead Heat Scramble (Japan)" - rom ( name "Dead Heat Scramble (Japan).gb" size 65536 crc A8301BDD md5 FF76E39F9EA003242F0ADDA707C953F7 sha1 395C0C80AD5C9A24C00D6D8DFE5894E73E672639 ) + rom ( name "Dead Heat Scramble (Japan).gb" size 65536 crc a8301bdd sha1 395C0C80AD5C9A24C00D6D8DFE5894E73E672639 flags verified ) ) game ( name "Dead Heat Scramble (USA)" description "Dead Heat Scramble (USA)" - rom ( name "Dead Heat Scramble (USA).gb" size 65536 crc 9E3E3656 md5 C2212D75077638539D6AF4673B4939E6 sha1 71E560DD2B5F5C4F4DCCA0837C74BB1B843A15AA ) + rom ( name "Dead Heat Scramble (USA).gb" size 65536 crc 9e3e3656 sha1 71E560DD2B5F5C4F4DCCA0837C74BB1B843A15AA ) ) game ( name "Dennis (Europe)" description "Dennis (Europe)" - rom ( name "Dennis (Europe).gb" size 131072 crc 896A30A8 md5 2FA78F748AA9BCED4CEDD95F330C9A11 sha1 9B5C289F25829534020951F84732177036837AEA ) + rom ( name "Dennis (Europe).gb" size 131072 crc 896a30a8 sha1 9B5C289F25829534020951F84732177036837AEA ) ) game ( name "Dennis the Menace (USA)" description "Dennis the Menace (USA)" - rom ( name "Dennis the Menace (USA).gb" size 131072 crc 7EB0CD32 md5 F064BD662FDCB40A9F6926CC3BAEE116 sha1 4695B50738ADD92926DC5D4B48568B037DF7CDB9 ) + rom ( name "Dennis the Menace (USA).gb" size 131072 crc 7eb0cd32 sha1 4695B50738ADD92926DC5D4B48568B037DF7CDB9 flags verified ) ) game ( name "Desert Strike - Return to the Gulf (Europe) (SGB Enhanced)" description "Desert Strike - Return to the Gulf (Europe) (SGB Enhanced)" - rom ( name "Desert Strike - Return to the Gulf (Europe) (SGB Enhanced).gb" size 262144 crc B700F7F7 md5 6B371B815A02C5E90836F314B1625B21 sha1 B49BC8F5D292F0E2B71957C8C4AF37B20CFEAD80 flags verified ) + rom ( name "Desert Strike - Return to the Gulf (Europe) (SGB Enhanced).gb" size 262144 crc b700f7f7 sha1 B49BC8F5D292F0E2B71957C8C4AF37B20CFEAD80 flags verified ) ) game ( name "Desert Strike - Return to the Gulf (USA) (SGB Enhanced)" description "Desert Strike - Return to the Gulf (USA) (SGB Enhanced)" - rom ( name "Desert Strike - Return to the Gulf (USA) (SGB Enhanced).gb" size 262144 crc 6A702C32 md5 A926508282DA0B7889AB4F0947916068 sha1 325EE739ECF5AA403741E8DAD36ABCFA441DD26B ) + rom ( name "Desert Strike - Return to the Gulf (USA) (SGB Enhanced).gb" size 262144 crc 6a702c32 sha1 325EE739ECF5AA403741E8DAD36ABCFA441DD26B ) ) game ( name "Dexterity (USA, Europe)" description "Dexterity (USA, Europe)" - rom ( name "Dexterity (USA, Europe).gb" size 65536 crc 659E2283 md5 A58F2B1A317CFB1D60B59F3875F6A9C2 sha1 85F0A9FF87ECE93097A855D238BC6C7014893C08 flags verified ) + rom ( name "Dexterity (USA, Europe).gb" size 65536 crc 659e2283 sha1 85F0A9FF87ECE93097A855D238BC6C7014893C08 flags verified ) ) game ( name "Diablo (USA) (Proto)" description "Diablo (USA) (Proto)" - rom ( name "Diablo (USA) (Proto).gb" size 131072 crc AAAAD0B6 md5 28E1605572AEC89F7D210775E51CB8DA sha1 8982410AC627618628A8B823C0608CC8B5653F41 ) + rom ( name "Diablo (USA) (Proto).gb" size 131072 crc aaaad0b6 sha1 8982410AC627618628A8B823C0608CC8B5653F41 ) ) game ( name "Dick Tracy (USA)" description "Dick Tracy (USA)" - rom ( name "Dick Tracy (USA).gb" size 131072 crc A308B86B md5 AB5F50D0E31A07E19739453BB9A2D328 sha1 906361B2066C2B48500B9B709F7B4ED1018309C0 ) + rom ( name "Dick Tracy (USA).gb" size 131072 crc a308b86b sha1 906361B2066C2B48500B9B709F7B4ED1018309C0 ) ) game ( name "Dig Dug (Europe)" description "Dig Dug (Europe)" - rom ( name "Dig Dug (Europe).gb" size 131072 crc 0AF905C0 md5 C4801AC17A34635FDCE973354E85FAEF sha1 9E008EE24C627309B22BF42EC5A3E08AF0AF8EFE ) + rom ( name "Dig Dug (Europe).gb" size 131072 crc 0af905c0 sha1 9E008EE24C627309B22BF42EC5A3E08AF0AF8EFE flags verified ) ) game ( name "Dig Dug (USA)" description "Dig Dug (USA)" - rom ( name "Dig Dug (USA).gb" size 131072 crc 6C742478 md5 9719EAADA417782A236A9D84805A512A sha1 951753904389332412D4B0A80B48D7AC61A494FC ) + rom ( name "Dig Dug (USA).gb" size 131072 crc 6c742478 sha1 951753904389332412D4B0A80B48D7AC61A494FC ) ) game ( name "Dino Breeder (Japan) (SGB Enhanced)" description "Dino Breeder (Japan) (SGB Enhanced)" - rom ( name "Dino Breeder (Japan) (SGB Enhanced).gb" size 262144 crc 3F0AAFEC md5 BB352209D041ED1B9F09C26E0C7AB749 sha1 80CCBF87DCD4D4E76F1F6A7A94E00EC2857E530A flags verified ) + rom ( name "Dino Breeder (Japan) (SGB Enhanced).gb" size 262144 crc 3f0aafec sha1 80CCBF87DCD4D4E76F1F6A7A94E00EC2857E530A flags verified ) ) game ( - name "Dino Breeder (Japan) (Rev A) (SGB Enhanced)" - description "Dino Breeder (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Dino Breeder (Japan) (Rev A) (SGB Enhanced).gb" size 262144 crc 5B289AB4 md5 FD269FC744AC60B138F8B238E0BB5C34 sha1 A6E24E442DE0541C3F5EC4D28650256C5D25F751 ) + name "Dino Breeder (Japan) (Rev 1) (SGB Enhanced)" + description "Dino Breeder (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Dino Breeder (Japan) (Rev 1) (SGB Enhanced).gb" size 262144 crc 5b289ab4 sha1 A6E24E442DE0541C3F5EC4D28650256C5D25F751 flags verified ) ) game ( name "Dino Breeder 2 (Japan) (SGB Enhanced)" description "Dino Breeder 2 (Japan) (SGB Enhanced)" - rom ( name "Dino Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 05A3AB7A md5 0FEF748262BF93D67036A80E23CB42D1 sha1 AC4B1FE0E917298D81725D7A9BDF46C285502AC7 flags verified ) + rom ( name "Dino Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 05a3ab7a sha1 AC4B1FE0E917298D81725D7A9BDF46C285502AC7 flags verified ) ) game ( name "Dirty Racing (Japan)" description "Dirty Racing (Japan)" - rom ( name "Dirty Racing (Japan).gb" size 131072 crc 43AF45B1 md5 B2023017774D88FFE82A7D1B0AF52C12 sha1 5B58B4D02987CE3A16774BC4A6707D12AC404C1C flags verified ) + rom ( name "Dirty Racing (Japan).gb" size 131072 crc 43af45b1 sha1 5B58B4D02987CE3A16774BC4A6707D12AC404C1C flags verified ) ) game ( name "Dodge Boy (Japan)" description "Dodge Boy (Japan)" - rom ( name "Dodge Boy (Japan).gb" size 131072 crc F58DC358 md5 D9C82BF67AD459F08676A1C7CB9037F3 sha1 B48EB2BDC34588847728936491DADDA67394F9B7 ) + rom ( name "Dodge Boy (Japan).gb" size 131072 crc f58dc358 sha1 B48EB2BDC34588847728936491DADDA67394F9B7 ) ) game ( name "Donkey Kong (Japan, USA) (SGB Enhanced)" description "Donkey Kong (Japan, USA) (SGB Enhanced)" - rom ( name "Donkey Kong (Japan, USA) (SGB Enhanced).gb" size 524288 crc EDAB3378 md5 60E55697DA19BB160316EC290A7A7437 sha1 6ED661BD1D6D8CDD48E1C10F8CA4E8DCBA49128E flags verified ) + rom ( name "Donkey Kong (Japan, USA) (SGB Enhanced).gb" size 524288 crc edab3378 sha1 6ED661BD1D6D8CDD48E1C10F8CA4E8DCBA49128E flags verified ) ) game ( - name "Donkey Kong (World) (Rev A) (SGB Enhanced)" - description "Donkey Kong (World) (Rev A) (SGB Enhanced)" - rom ( name "Donkey Kong (World) (Rev A) (SGB Enhanced).gb" size 524288 crc F777A5D8 md5 4859EC2B18C4FABF489EB570C1D7D326 sha1 397AD2FF25627B83E02C71B54C72BB4DEB39E0C0 flags verified ) + name "Donkey Kong (World) (Rev 1) (SGB Enhanced)" + description "Donkey Kong (World) (Rev 1) (SGB Enhanced)" + rom ( name "Donkey Kong (World) (Rev 1) (SGB Enhanced).gb" size 524288 crc f777a5d8 sha1 397AD2FF25627B83E02C71B54C72BB4DEB39E0C0 flags verified ) ) game ( name "Donkey Kong Land (Japan) (SGB Enhanced)" description "Donkey Kong Land (Japan) (SGB Enhanced)" - rom ( name "Donkey Kong Land (Japan) (SGB Enhanced).gb" size 524288 crc 9AECA05C md5 94D72BF09AA55761CFA723882DAFC131 sha1 18FD3FCF90E60122DA92079669942B0363049D8F flags verified ) + rom ( name "Donkey Kong Land (Japan) (SGB Enhanced).gb" size 524288 crc 9aeca05c sha1 18FD3FCF90E60122DA92079669942B0363049D8F flags verified ) ) game ( name "Donkey Kong Land (USA, Europe) (SGB Enhanced)" description "Donkey Kong Land (USA, Europe) (SGB Enhanced)" - rom ( name "Donkey Kong Land (USA, Europe) (SGB Enhanced).gb" size 524288 crc 49DC0D37 md5 89BB0D67D5AF35C2EBF09D9AEF2E34AD sha1 4E6D8F085CA197479D59912C1D58E4F3B40C28AC flags verified ) + rom ( name "Donkey Kong Land (USA, Europe) (SGB Enhanced).gb" size 524288 crc 49dc0d37 sha1 4E6D8F085CA197479D59912C1D58E4F3B40C28AC flags verified ) ) game ( name "Donkey Kong Land 2 (USA, Europe) (SGB Enhanced)" description "Donkey Kong Land 2 (USA, Europe) (SGB Enhanced)" - rom ( name "Donkey Kong Land 2 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 2827E5D4 md5 6E30394FD7EF4A4DC3FE1EDD9FC69F72 sha1 89CC4F01653A6105EE5C00E10FC65AA1437FD320 flags verified ) + rom ( name "Donkey Kong Land 2 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 2827e5d4 sha1 89CC4F01653A6105EE5C00E10FC65AA1437FD320 flags verified ) ) game ( name "Donkey Kong Land III (USA, Europe) (SGB Enhanced)" description "Donkey Kong Land III (USA, Europe) (SGB Enhanced)" - rom ( name "Donkey Kong Land III (USA, Europe) (SGB Enhanced).gb" size 524288 crc B40C159C md5 2E46072CE2416FEB18F4BD1E9943546C sha1 A33F10194B5B228863C04ABD0E65C7CC5D73FC3E flags verified ) + rom ( name "Donkey Kong Land III (USA, Europe) (SGB Enhanced).gb" size 524288 crc b40c159c sha1 A33F10194B5B228863C04ABD0E65C7CC5D73FC3E flags verified ) ) game ( - name "Donkey Kong Land III (USA, Europe) (Rev A) (SGB Enhanced)" - description "Donkey Kong Land III (USA, Europe) (Rev A) (SGB Enhanced)" - rom ( name "Donkey Kong Land III (USA, Europe) (Rev A) (SGB Enhanced).gb" size 524288 crc A19ACDB6 md5 333444E90C0BFB99C4FF89FDCB920FE4 sha1 A6CE883727212E1AFB45B48431A46CFBC6F7F6EF flags verified ) + name "Donkey Kong Land III (USA, Europe) (Rev 1) (SGB Enhanced)" + description "Donkey Kong Land III (USA, Europe) (Rev 1) (SGB Enhanced)" + rom ( name "Donkey Kong Land III (USA, Europe) (Rev 1) (SGB Enhanced).gb" size 524288 crc a19acdb6 sha1 A6CE883727212E1AFB45B48431A46CFBC6F7F6EF flags verified ) ) game ( name "Donkey Kong Land III (USA, Europe) (Beta)" description "Donkey Kong Land III (USA, Europe) (Beta)" - rom ( name "Donkey Kong Land III (USA, Europe) (Beta).gb" size 524288 crc 872BBD5E md5 CB1D69526CEA3A0CBCAAE091A10707FE sha1 9D17BC07BD3C48F8BB8A3315FAF817D055417F53 ) + rom ( name "Donkey Kong Land III (USA, Europe) (Beta).gb" size 524288 crc 872bbd5e sha1 9D17BC07BD3C48F8BB8A3315FAF817D055417F53 flags verified ) ) game ( name "Doraemon - Taiketsu HimitsuDougu!! (Japan)" description "Doraemon - Taiketsu HimitsuDougu!! (Japan)" - rom ( name "Doraemon - Taiketsu HimitsuDougu!! (Japan).gb" size 131072 crc A42524A3 md5 E01F6FCB9BACCA86642744FA4003B349 sha1 5E89E34A2CEC89E0ABA4E12D18D96671151730EC flags verified ) + rom ( name "Doraemon - Taiketsu HimitsuDougu!! (Japan).gb" size 131072 crc a42524a3 sha1 5E89E34A2CEC89E0ABA4E12D18D96671151730EC flags verified ) ) game ( name "Doraemon 2 - Animal Planet Densetsu (Japan)" description "Doraemon 2 - Animal Planet Densetsu (Japan)" - rom ( name "Doraemon 2 - Animal Planet Densetsu (Japan).gb" size 131072 crc 843BD5BC md5 BBF5E9E76B28352665AFF796A13830E8 sha1 0D72E0310BBF0B23483F37688DF61543048C4B31 flags verified ) + rom ( name "Doraemon 2 - Animal Planet Densetsu (Japan).gb" size 131072 crc 843bd5bc sha1 0D72E0310BBF0B23483F37688DF61543048C4B31 flags verified ) ) game ( name "Doraemon Kart (Japan) (SGB Enhanced)" description "Doraemon Kart (Japan) (SGB Enhanced)" - rom ( name "Doraemon Kart (Japan) (SGB Enhanced).gb" size 262144 crc DD4E588F md5 20B436FC3C9621EB4EE82BC3EF3687FB sha1 F19734B2CB19DE0BE2D9E80297F567806CE4CAD5 flags verified ) + rom ( name "Doraemon Kart (Japan) (SGB Enhanced).gb" size 262144 crc dd4e588f sha1 F19734B2CB19DE0BE2D9E80297F567806CE4CAD5 flags verified ) ) game ( name "Doraemon no Game Boy de Asobouyo Deluxe 10 (Japan) (SGB Enhanced)" description "Doraemon no Game Boy de Asobouyo Deluxe 10 (Japan) (SGB Enhanced)" - rom ( name "Doraemon no Game Boy de Asobouyo Deluxe 10 (Japan) (SGB Enhanced).gb" size 262144 crc B368E717 md5 852C764440F29205099716C4500CE222 sha1 7AD70061C8AFBBE0890E3D50ACCD40B2A8CB9790 flags verified ) + rom ( name "Doraemon no Game Boy de Asobouyo Deluxe 10 (Japan) (SGB Enhanced).gb" size 262144 crc b368e717 sha1 7AD70061C8AFBBE0890E3D50ACCD40B2A8CB9790 flags verified ) ) game ( name "Doraemon no Study Boy 1 - Shou 1 Kokugo Kanji (Japan)" description "Doraemon no Study Boy 1 - Shou 1 Kokugo Kanji (Japan)" - rom ( name "Doraemon no Study Boy 1 - Shou 1 Kokugo Kanji (Japan).gb" size 524288 crc 652B3CA4 md5 C3FBE689E57E493D9E5EB8340C4EFB29 sha1 7BE5E001F60338FD605CB3CD918DF66A9EBF2AD2 flags verified ) + rom ( name "Doraemon no Study Boy 1 - Shou 1 Kokugo Kanji (Japan).gb" size 524288 crc 652b3ca4 sha1 7BE5E001F60338FD605CB3CD918DF66A9EBF2AD2 flags verified ) ) game ( name "Doraemon no Study Boy 2 - Shou 1 Sansuu Keisan (Japan)" description "Doraemon no Study Boy 2 - Shou 1 Sansuu Keisan (Japan)" - rom ( name "Doraemon no Study Boy 2 - Shou 1 Sansuu Keisan (Japan).gb" size 524288 crc 5333D083 md5 A78457AE06F670C5EC173F8D2CA605D5 sha1 38B9FAFD4604BD69A59F0445508F15BFBBA459C6 flags verified ) + rom ( name "Doraemon no Study Boy 2 - Shou 1 Sansuu Keisan (Japan).gb" size 524288 crc 5333d083 sha1 38B9FAFD4604BD69A59F0445508F15BFBBA459C6 flags verified ) ) game ( name "Doraemon no Study Boy 3 - Ku Ku Master (Japan)" description "Doraemon no Study Boy 3 - Ku Ku Master (Japan)" - rom ( name "Doraemon no Study Boy 3 - Ku Ku Master (Japan).gb" size 524288 crc 0356A509 md5 05F5F5534C0D7E8100EDF07A494F16E8 sha1 7FDD0855DCE2C5BBD229C2BA8485A3A020B873A1 flags verified ) + rom ( name "Doraemon no Study Boy 3 - Ku Ku Master (Japan).gb" size 524288 crc 0356a509 sha1 7FDD0855DCE2C5BBD229C2BA8485A3A020B873A1 flags verified ) ) game ( name "Doraemon no Study Boy 4 - Shou ni Kokugo Kanji (Japan)" description "Doraemon no Study Boy 4 - Shou ni Kokugo Kanji (Japan)" - rom ( name "Doraemon no Study Boy 4 - Shou ni Kokugo Kanji (Japan).gb" size 524288 crc 45E3E8F2 md5 79444F0A72363167FC340060EB02301C sha1 996A57958C9971070CF881F475CFA815361409C4 ) + rom ( name "Doraemon no Study Boy 4 - Shou ni Kokugo Kanji (Japan).gb" size 524288 crc 45e3e8f2 sha1 996A57958C9971070CF881F475CFA815361409C4 ) ) game ( name "Doraemon no Study Boy 5 - Shou 2 Sansuu Keisan (Japan)" description "Doraemon no Study Boy 5 - Shou 2 Sansuu Keisan (Japan)" - rom ( name "Doraemon no Study Boy 5 - Shou 2 Sansuu Keisan (Japan).gb" size 524288 crc 6B39F607 md5 4F0349ECA35C2DBB3B810E2CA9C9C94B sha1 8BC5692DE1850B68767BEE01FE4506455AAC8CC6 ) + rom ( name "Doraemon no Study Boy 5 - Shou 2 Sansuu Keisan (Japan).gb" size 524288 crc 6b39f607 sha1 8BC5692DE1850B68767BEE01FE4506455AAC8CC6 flags verified ) ) game ( name "Doraemon no Study Boy 6 - Gakushuu Kanji Master 1006 (Japan)" description "Doraemon no Study Boy 6 - Gakushuu Kanji Master 1006 (Japan)" - rom ( name "Doraemon no Study Boy 6 - Gakushuu Kanji Master 1006 (Japan).gb" size 1048576 crc 5A16C88D md5 5F2EE96647B5274D343DB91F4561C628 sha1 1BFBD1AA188CFA1A2168B5E245B87BD67090D810 ) + rom ( name "Doraemon no Study Boy 6 - Gakushuu Kanji Master 1006 (Japan).gb" size 1048576 crc 5a16c88d sha1 1BFBD1AA188CFA1A2168B5E245B87BD67090D810 flags verified ) ) game ( name "Double Dragon (Japan)" description "Double Dragon (Japan)" - rom ( name "Double Dragon (Japan).gb" size 131072 crc A0645E8A md5 0EDF8501B8C2567371AE4F8747A27D63 sha1 7DCCD7D3CA7223815E7B00A3B664F5E7D7D433B2 flags verified ) + rom ( name "Double Dragon (Japan).gb" size 131072 crc a0645e8a sha1 7DCCD7D3CA7223815E7B00A3B664F5E7D7D433B2 flags verified ) ) game ( name "Double Dragon (USA, Europe)" description "Double Dragon (USA, Europe)" - rom ( name "Double Dragon (USA, Europe).gb" size 131072 crc 40A8BF12 md5 545DE5C311259B7F7EC313A9D58CF4B4 sha1 6565A3D89827717D8E5D2E041C743266BA14B412 flags verified ) + rom ( name "Double Dragon (USA, Europe).gb" size 131072 crc 40a8bf12 sha1 6565A3D89827717D8E5D2E041C743266BA14B412 flags verified ) ) game ( name "Double Dragon 3 - The Arcade Game (USA, Europe)" description "Double Dragon 3 - The Arcade Game (USA, Europe)" - rom ( name "Double Dragon 3 - The Arcade Game (USA, Europe).gb" size 131072 crc FC970AEF md5 469605E02EB10652F8F2AFA8C7EBFFD5 sha1 C596D069D9FBD6372757E5D669A5144E2EB9D8FF flags verified ) + rom ( name "Double Dragon 3 - The Arcade Game (USA, Europe).gb" size 131072 crc fc970aef sha1 C596D069D9FBD6372757E5D669A5144E2EB9D8FF flags verified ) ) game ( name "Double Dragon II (USA, Europe)" description "Double Dragon II (USA, Europe)" - rom ( name "Double Dragon II (USA, Europe).gb" size 131072 crc 5B96E474 md5 4F3B84EB325F9162086FAC77AC577E7C sha1 3532462BE3AB1A569890261D20A1A37BFE79E1EA flags verified ) + rom ( name "Double Dragon II (USA, Europe).gb" size 131072 crc 5b96e474 sha1 3532462BE3AB1A569890261D20A1A37BFE79E1EA flags verified ) ) game ( name "Double Dribble - 5 on 5 (USA)" description "Double Dribble - 5 on 5 (USA)" - rom ( name "Double Dribble - 5 on 5 (USA).gb" size 131072 crc EE28749D md5 FF3E6D70D42987DD7F6214067DC83AFE sha1 D0F18C97B48DD8B355D195D2DDAEEE910C5FC2B1 ) + rom ( name "Double Dribble - 5 on 5 (USA).gb" size 131072 crc ee28749d sha1 D0F18C97B48DD8B355D195D2DDAEEE910C5FC2B1 ) ) game ( name "Double Yakuman (Japan)" description "Double Yakuman (Japan)" - rom ( name "Double Yakuman (Japan).gb" size 131072 crc 252C32B5 md5 D39462C174C7AE4E15680301DBAE1C35 sha1 24DD6BA6A82CA3E6ACA44AA471CF03D08371DC80 ) + rom ( name "Double Yakuman (Japan).gb" size 131072 crc 252c32b5 sha1 24DD6BA6A82CA3E6ACA44AA471CF03D08371DC80 ) ) game ( name "Double Yakuman II (Japan)" description "Double Yakuman II (Japan)" - rom ( name "Double Yakuman II (Japan).gb" size 131072 crc A3D77A55 md5 400CB2AD3D7EE30483B28F5F098A5BB7 sha1 7F6ED21BF0CCE0D524DCBCE56AF5CAB61C85D729 ) + rom ( name "Double Yakuman II (Japan).gb" size 131072 crc a3d77a55 sha1 7F6ED21BF0CCE0D524DCBCE56AF5CAB61C85D729 ) ) game ( - name "Double Yakuman Junior (Japan)" - description "Double Yakuman Junior (Japan)" - rom ( name "Double Yakuman Junior (Japan).gb" size 131072 crc 34AC7268 md5 78667E88A568B44115CB76DFE63A74A3 sha1 7D72BC65297F21605521F7320A5B49193E584CD0 ) + name "Double Yakuman Jr. (Japan)" + description "Double Yakuman Jr. (Japan)" + rom ( name "Double Yakuman Jr. (Japan).gb" size 131072 crc 34ac7268 sha1 7D72BC65297F21605521F7320A5B49193E584CD0 ) ) game ( name "Downtown - Nekketsu Koushinkyoku - Dokodemo Daiundoukai (Japan)" description "Downtown - Nekketsu Koushinkyoku - Dokodemo Daiundoukai (Japan)" - rom ( name "Downtown - Nekketsu Koushinkyoku - Dokodemo Daiundoukai (Japan).gb" size 262144 crc 82511A8F md5 04C358CBB32898D5E8FEED8BC0FE27FF sha1 1B8F59467DDCE14DB359E22567E29F6955C7C92A ) + rom ( name "Downtown - Nekketsu Koushinkyoku - Dokodemo Daiundoukai (Japan).gb" size 262144 crc 82511a8f sha1 1B8F59467DDCE14DB359E22567E29F6955C7C92A flags verified ) +) + +game ( + name "Downtown Special - Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan)" + description "Downtown Special - Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan)" + rom ( name "Downtown Special - Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan).gb" size 262144 crc 229e9113 sha1 97FF2392F126B195AC8A1700A9A91AA364549DFD ) ) game ( name "Dr. Franken (Europe) (En,Fr,De,Es,It,Nl,Sv)" description "Dr. Franken (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Dr. Franken (Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc F13A60B8 md5 2A7D9044B9BDBC133D1A9BB5C0F9B2A1 sha1 BA5AAAC92C4A2CA2D6A752C521E4D95108444A4E flags verified ) + rom ( name "Dr. Franken (Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc f13a60b8 sha1 BA5AAAC92C4A2CA2D6A752C521E4D95108444A4E flags verified ) ) game ( name "Dr. Franken (Japan)" description "Dr. Franken (Japan)" - rom ( name "Dr. Franken (Japan).gb" size 131072 crc 3D04B8E7 md5 C5397C3E9740264482995573628E3B9D sha1 6350EC30E51F388E0E290F387989CB1C7A24A91C ) + rom ( name "Dr. Franken (Japan).gb" size 131072 crc 3d04b8e7 sha1 6350EC30E51F388E0E290F387989CB1C7A24A91C ) ) game ( name "Dr. Franken (USA)" description "Dr. Franken (USA)" - rom ( name "Dr. Franken (USA).gb" size 131072 crc D409375B md5 B6DA78085D38A8BE3EF564B9989C45D0 sha1 2B136EF8E3DD082CCB4716035545FB2E03438C66 ) + rom ( name "Dr. Franken (USA).gb" size 131072 crc d409375b sha1 2B136EF8E3DD082CCB4716035545FB2E03438C66 ) ) game ( name "Dr. Franken II (USA, Europe) (En,Fr,De,Es,It,Nl,Sv)" description "Dr. Franken II (USA, Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Dr. Franken II (USA, Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc 0D62473D md5 6E2AB82A7E2348BA9753AF34F11892E4 sha1 8D578CE74907131114279854A0DC376F4426120C flags verified ) + rom ( name "Dr. Franken II (USA, Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc 0d62473d sha1 8D578CE74907131114279854A0DC376F4426120C flags verified ) ) game ( name "Dr. Mario (World)" description "Dr. Mario (World)" - rom ( name "Dr. Mario (World).gb" size 32768 crc 10C98DD1 md5 0281FD8061D82472E242954513805196 sha1 F1006D6CF77469092F3B9F266D0A65DA9C91AC42 flags verified ) + rom ( name "Dr. Mario (World).gb" size 32768 crc 10c98dd1 sha1 F1006D6CF77469092F3B9F266D0A65DA9C91AC42 flags verified ) ) game ( - name "Dr. Mario (World) (Rev A)" - description "Dr. Mario (World) (Rev A)" - rom ( name "Dr. Mario (World) (Rev A).gb" size 32768 crc F0225DD0 md5 921BDFF008475AA2C5344E1A0D110910 sha1 D31D67D0682515C7C85DEAA1752B02231150E5BF flags verified ) + name "Dr. Mario (World) (Rev 1)" + description "Dr. Mario (World) (Rev 1)" + rom ( name "Dr. Mario (World) (Rev 1).gb" size 32768 crc f0225dd0 sha1 D31D67D0682515C7C85DEAA1752B02231150E5BF flags verified ) ) game ( name "Dr. Mario (World) (Beta)" description "Dr. Mario (World) (Beta)" - serial "DMG-VUA" - rom ( name "Dr. Mario (World) (Beta).gb" size 32768 crc 2B2F4F8F md5 4599627050687063DA3F5CF804DC16F6 sha1 4B2343F40E7CA3C583108ED70A870C7BD906B108 ) + rom ( name "Dr. Mario (World) (Beta).gb" size 32768 crc 2b2f4f8f sha1 4B2343F40E7CA3C583108ED70A870C7BD906B108 flags verified ) ) game ( name "Dracula Densetsu (Japan)" description "Dracula Densetsu (Japan)" - rom ( name "Dracula Densetsu (Japan).gb" size 65536 crc A35B9EF5 md5 94135FB63D77D48D2396C60CA8823B69 sha1 BEDEB390391779400DE14196D24F07A451184ECE flags verified ) + rom ( name "Dracula Densetsu (Japan).gb" size 65536 crc a35b9ef5 sha1 BEDEB390391779400DE14196D24F07A451184ECE flags verified ) ) game ( name "Dracula Densetsu II (Japan)" description "Dracula Densetsu II (Japan)" - rom ( name "Dracula Densetsu II (Japan).gb" size 131072 crc 7582AE14 md5 2BE2472951EB4E25AB0C70FDEE298130 sha1 BCA90EDDDBF50D0D05630852C092FC5D3E0DF9D4 flags verified ) + rom ( name "Dracula Densetsu II (Japan).gb" size 131072 crc 7582ae14 sha1 BCA90EDDDBF50D0D05630852C092FC5D3E0DF9D4 flags verified ) ) game ( name "Dragon Ball Z - Gokuu Gekitouden (Japan) (SGB Enhanced)" description "Dragon Ball Z - Gokuu Gekitouden (Japan) (SGB Enhanced)" - rom ( name "Dragon Ball Z - Gokuu Gekitouden (Japan) (SGB Enhanced).gb" size 524288 crc FF3C027D md5 F29D7DC8D22C317BB7C17A7BBDC24EC6 sha1 1F7A08D2E51E90D770D9DBF4092166B2BFA5697E ) + rom ( name "Dragon Ball Z - Gokuu Gekitouden (Japan) (SGB Enhanced).gb" size 524288 crc ff3c027d sha1 1F7A08D2E51E90D770D9DBF4092166B2BFA5697E ) ) game ( name "Dragon Ball Z - Gokuu Hishouden (Japan) (SGB Enhanced)" description "Dragon Ball Z - Gokuu Hishouden (Japan) (SGB Enhanced)" - rom ( name "Dragon Ball Z - Gokuu Hishouden (Japan) (SGB Enhanced).gb" size 262144 crc 38DA46D7 md5 3D4537F6A0542F781E408BD5440D23DD sha1 6BF8F3400BF323EDECC2152C4A86F6B0CAE628FE ) + rom ( name "Dragon Ball Z - Gokuu Hishouden (Japan) (SGB Enhanced).gb" size 262144 crc 38da46d7 sha1 6BF8F3400BF323EDECC2152C4A86F6B0CAE628FE ) ) game ( - name "Dragon Slayer - Nemuri no Oukan (Japan)" - description "Dragon Slayer - Nemuri no Oukan (Japan)" - rom ( name "Dragon Slayer - Nemuri no Oukan (Japan).gb" size 131072 crc 10DCBDC3 md5 77257C9EA85A0FDF36CBA3E2A7FB5270 sha1 EF58063D896533398288A4F07245F23EFA3AEE4A flags verified ) + name "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" + description "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" + rom ( name "Dragon Slayer Gaiden - Nemuri no Oukan (Japan).gb" size 131072 crc 10dcbdc3 sha1 EF58063D896533398288A4F07245F23EFA3AEE4A flags verified ) ) game ( name "Dragon Slayer I (Japan)" description "Dragon Slayer I (Japan)" - rom ( name "Dragon Slayer I (Japan).gb" size 32768 crc 308A2465 md5 BC35DC3BF102CFA265C5C7348E674BA9 sha1 7D987446F67D8BEE42482A4932D0FA60318238E4 ) + rom ( name "Dragon Slayer I (Japan).gb" size 32768 crc 308a2465 sha1 7D987446F67D8BEE42482A4932D0FA60318238E4 ) ) game ( name "Dragon Tail (Japan)" description "Dragon Tail (Japan)" - rom ( name "Dragon Tail (Japan).gb" size 131072 crc 1D1155AF md5 92E724D9AE8E6AD79442C95FE434C998 sha1 390ADDF6BB52452DC6370EB54C702972E51968A2 ) + rom ( name "Dragon Tail (Japan).gb" size 131072 crc 1d1155af sha1 390ADDF6BB52452DC6370EB54C702972E51968A2 ) ) game ( name "Dragon's Lair (Japan)" description "Dragon's Lair (Japan)" - rom ( name "Dragon's Lair (Japan).gb" size 131072 crc 73C994A0 md5 2204AECC6784AB2E6C5F063C8584E0D2 sha1 E344B536E3EDCF1628D09773F694E14AB2864B7A ) + rom ( name "Dragon's Lair (Japan).gb" size 131072 crc 73c994a0 sha1 E344B536E3EDCF1628D09773F694E14AB2864B7A ) ) game ( name "Dragon's Lair - The Legend (Europe)" description "Dragon's Lair - The Legend (Europe)" - rom ( name "Dragon's Lair - The Legend (Europe).gb" size 131072 crc 00A14889 md5 C1AC652D62A6302D6C34814F7F703957 sha1 BABC3C70D5B73DF268CD5C9E5E841FE277B57003 flags verified ) + rom ( name "Dragon's Lair - The Legend (Europe).gb" size 131072 crc 00a14889 sha1 BABC3C70D5B73DF268CD5C9E5E841FE277B57003 flags verified ) ) game ( name "Dragon's Lair - The Legend (USA)" description "Dragon's Lair - The Legend (USA)" - rom ( name "Dragon's Lair - The Legend (USA).gb" size 131072 crc 7A38B5C3 md5 AE4FDA03378A0584D45A4735C9D6290E sha1 4E947908FDE7EF9892C59021C6EEA0607771F6D2 ) + rom ( name "Dragon's Lair - The Legend (USA).gb" size 131072 crc 7a38b5c3 sha1 4E947908FDE7EF9892C59021C6EEA0607771F6D2 ) ) game ( name "DragonHeart (France)" description "DragonHeart (France)" - rom ( name "DragonHeart (France).gb" size 524288 crc 8D089356 md5 97C000E7B02914512EE05B1159371483 sha1 6B01E78DF8A7DC3FB171D488CAE38501FCE3B660 ) + rom ( name "DragonHeart (France).gb" size 524288 crc 8d089356 sha1 6B01E78DF8A7DC3FB171D488CAE38501FCE3B660 ) ) game ( name "DragonHeart (USA, Europe)" description "DragonHeart (USA, Europe)" - rom ( name "DragonHeart (USA, Europe).gb" size 524288 crc 5129A518 md5 F9E94B9A134D900A3B971E206F4E826C sha1 1800CEEBA6ED491E5F85997C945AB52B09F6E4BA flags verified ) + rom ( name "DragonHeart (USA, Europe).gb" size 524288 crc 5129a518 sha1 1800CEEBA6ED491E5F85997C945AB52B09F6E4BA flags verified ) ) game ( name "Dropzone (Europe)" description "Dropzone (Europe)" - rom ( name "Dropzone (Europe).gb" size 32768 crc 351A7277 md5 74D96840A5C09CD88C862A5647465B81 sha1 0BF73FFA90FDBA5A4EE4E2338BB2F0D01AF6FB88 ) + rom ( name "Dropzone (Europe).gb" size 32768 crc 351a7277 sha1 0BF73FFA90FDBA5A4EE4E2338BB2F0D01AF6FB88 flags verified ) ) game ( name "Druaga no Tou (Japan)" description "Druaga no Tou (Japan)" - rom ( name "Druaga no Tou (Japan).gb" size 131072 crc F924BDB1 md5 C8611861AFE5D9B47043150EE2C94389 sha1 7701F8C535F612943D736FEF342973E9C77011DF flags verified ) + rom ( name "Druaga no Tou (Japan).gb" size 131072 crc f924bdb1 sha1 7701F8C535F612943D736FEF342973E9C77011DF flags verified ) ) game ( name "DuckTales (Europe)" description "DuckTales (Europe)" - rom ( name "DuckTales (Europe).gb" size 65536 crc AC6483DC md5 CA7A62E5E14AAFD813BC806D0CF54117 sha1 04AA9C515C2EDE8FDF37B29E69C44481F8A8630C flags verified ) + rom ( name "DuckTales (Europe).gb" size 65536 crc ac6483dc sha1 04AA9C515C2EDE8FDF37B29E69C44481F8A8630C flags verified ) ) game ( name "DuckTales (Japan)" description "DuckTales (Japan)" - rom ( name "DuckTales (Japan).gb" size 65536 crc 5B5410F5 md5 9057925ED2531251D494F76D3B8BB471 sha1 CE734CC3548F1D5A0CB26017B29B714F23D80C0F flags verified ) + rom ( name "DuckTales (Japan).gb" size 65536 crc 5b5410f5 sha1 CE734CC3548F1D5A0CB26017B29B714F23D80C0F flags verified ) ) game ( name "DuckTales (USA)" description "DuckTales (USA)" - rom ( name "DuckTales (USA).gb" size 65536 crc 2BBBB54D md5 785441D3D75913393807B10B3194DC48 sha1 93460364E33E8FB09A0659738044D0297CD4DF69 ) + rom ( name "DuckTales (USA).gb" size 65536 crc 2bbbb54d sha1 93460364E33E8FB09A0659738044D0297CD4DF69 ) ) game ( name "DuckTales 2 (Europe)" description "DuckTales 2 (Europe)" - rom ( name "DuckTales 2 (Europe).gb" size 131072 crc 169B00C1 md5 2EEE88360AA199B7ADC9D9C6647E0809 sha1 68113DCD6482A8A54E48C69223FCF2E2DEDEA844 flags verified ) + rom ( name "DuckTales 2 (Europe).gb" size 131072 crc 169b00c1 sha1 68113DCD6482A8A54E48C69223FCF2E2DEDEA844 flags verified ) ) game ( name "DuckTales 2 (Japan)" description "DuckTales 2 (Japan)" - rom ( name "DuckTales 2 (Japan).gb" size 131072 crc 2B693CDE md5 665B9EF961EE82EDB8DB54B3EB5152FD sha1 D7C33C30E9921D119C4F4C9A77BE9406207368EB ) + rom ( name "DuckTales 2 (Japan).gb" size 131072 crc 2b693cde sha1 D7C33C30E9921D119C4F4C9A77BE9406207368EB ) ) game ( name "DuckTales 2 (USA)" description "DuckTales 2 (USA)" - rom ( name "DuckTales 2 (USA).gb" size 131072 crc B151509D md5 B4E5876C5ACEDD12B62E25A12973A4AE sha1 C9D5B7A71BADCC7B198897B4888482F663F03504 flags verified ) + rom ( name "DuckTales 2 (USA).gb" size 131072 crc b151509d sha1 C9D5B7A71BADCC7B198897B4888482F663F03504 flags verified ) ) game ( name "Dungeon Land (Japan)" description "Dungeon Land (Japan)" - rom ( name "Dungeon Land (Japan).gb" size 131072 crc 11BE4B45 md5 9810EF4294BFDE29EC0BFC6C41D2F58C sha1 E354B0E78992F66BD598399998790231FF81B86F flags verified ) + rom ( name "Dungeon Land (Japan).gb" size 131072 crc 11be4b45 sha1 E354B0E78992F66BD598399998790231FF81B86F flags verified ) ) game ( name "DX Bakenou Z (Japan)" description "DX Bakenou Z (Japan)" - rom ( name "DX Bakenou Z (Japan).gb" size 131072 crc 3EF2E823 md5 F9A6AF7C1041424CBCBE79822D7DAB0C sha1 346ED92C1F56221D1FEDA2A008EAD2E3940BCBCB ) + rom ( name "DX Bakenou Z (Japan).gb" size 131072 crc 3ef2e823 sha1 346ED92C1F56221D1FEDA2A008EAD2E3940BCBCB ) ) game ( - name "DX Bakenou Z (Japan) (Rev A)" - description "DX Bakenou Z (Japan) (Rev A)" - rom ( name "DX Bakenou Z (Japan) (Rev A).gb" size 131072 crc FADFD0F6 md5 6496801345D1597B7DC1C27143E6B9D8 sha1 6E2B9B21EA7D8D482BE1F17722A579F720F2029D ) + name "DX Bakenou Z (Japan) (Rev 1)" + description "DX Bakenou Z (Japan) (Rev 1)" + rom ( name "DX Bakenou Z (Japan) (Rev 1).gb" size 131072 crc fadfd0f6 sha1 6E2B9B21EA7D8D482BE1F17722A579F720F2029D ) ) game ( name "Dynablaster (Europe)" description "Dynablaster (Europe)" - rom ( name "Dynablaster (Europe).gb" size 131072 crc 9677D157 md5 2EB9A6891FC79CD878D8BC12D04A0790 sha1 3C284831353BE165E20B56F3728B0421EAEA274A flags verified ) + rom ( name "Dynablaster (Europe).gb" size 131072 crc 9677d157 sha1 3C284831353BE165E20B56F3728B0421EAEA274A flags verified ) ) game ( name "Earthworm Jim (Europe)" description "Earthworm Jim (Europe)" - rom ( name "Earthworm Jim (Europe).gb" size 262144 crc B1A7A008 md5 8A6963239D50B262E3579359F0A24F78 sha1 4249ABE39285B02CCB0E739B5A2CF96ACE1281FF ) + rom ( name "Earthworm Jim (Europe).gb" size 262144 crc b1a7a008 sha1 4249ABE39285B02CCB0E739B5A2CF96ACE1281FF flags verified ) ) game ( name "Earthworm Jim (USA)" description "Earthworm Jim (USA)" - rom ( name "Earthworm Jim (USA).gb" size 262144 crc 259FF267 md5 0D24EEFF28040FF2A8F63DE5BC8CBEA2 sha1 F5D3085DE17A5181C07739E49BE7637FAA5FF932 ) + rom ( name "Earthworm Jim (USA).gb" size 262144 crc 259ff267 sha1 F5D3085DE17A5181C07739E49BE7637FAA5FF932 ) ) game ( name "Elevator Action (Japan)" description "Elevator Action (Japan)" - rom ( name "Elevator Action (Japan).gb" size 65536 crc BEAD8AE4 md5 DEE2448AA2314E7B3C12849A053EA079 sha1 16DBF00DF012C1216D9D4ABEC9ABCD5512D053A3 ) + rom ( name "Elevator Action (Japan).gb" size 65536 crc bead8ae4 sha1 16DBF00DF012C1216D9D4ABEC9ABCD5512D053A3 ) ) game ( name "Elevator Action (USA, Europe)" description "Elevator Action (USA, Europe)" - rom ( name "Elevator Action (USA, Europe).gb" size 65536 crc B749A927 md5 7876945A990EA94AC6B1FE5CF01BC00F sha1 C0C9DE672A31F314E98392160FC343CF46EE98B9 flags verified ) + rom ( name "Elevator Action (USA, Europe).gb" size 65536 crc b749a927 sha1 C0C9DE672A31F314E98392160FC343CF46EE98B9 flags verified ) ) game ( name "Elite Soccer (USA) (SGB Enhanced)" description "Elite Soccer (USA) (SGB Enhanced)" - rom ( name "Elite Soccer (USA) (SGB Enhanced).gb" size 131072 crc F54158A6 md5 0A3304BDADDDADC6C6B1D7CC8425D566 sha1 4576881EA25E29EBBA91C49C89F8E70E105FBC60 ) + rom ( name "Elite Soccer (USA) (SGB Enhanced).gb" size 131072 crc f54158a6 sha1 4576881EA25E29EBBA91C49C89F8E70E105FBC60 ) ) game ( name "Exodus - Journey to the Promised Land (USA) (Unl)" description "Exodus - Journey to the Promised Land (USA) (Unl)" - rom ( name "Exodus - Journey to the Promised Land (USA) (Unl).gb" size 131072 crc 2E5497EF md5 AB1FA0ED0207B1D0D5F401F0CD17BEBF sha1 685D5A47A1FC386D7B451C8B2733E654B7779B71 ) + rom ( name "Exodus - Journey to the Promised Land (USA) (Unl).gb" size 131072 crc 2e5497ef sha1 685D5A47A1FC386D7B451C8B2733E654B7779B71 flags verified ) ) game ( - name "Extra Bases! (USA)" - description "Extra Bases! (USA)" - rom ( name "Extra Bases! (USA).gb" size 131072 crc 19608641 md5 857FDAFB5ABABD641CC832CFB8FABD58 sha1 BF44F14A948E8816FB9DEEA229512D979CB42AEC ) + name "Extra Bases (USA)" + description "Extra Bases (USA)" + rom ( name "Extra Bases (USA).gb" size 131072 crc 19608641 sha1 BF44F14A948E8816FB9DEEA229512D979CB42AEC ) ) game ( name "F-1 Race (World)" description "F-1 Race (World)" - rom ( name "F-1 Race (World).gb" size 131072 crc 7E4FEBDF md5 3AD6A2E9C2872CD8F92D86E18332262C sha1 96490BE847AEEDED0B635F45B05683A6DEFDF2E8 flags verified ) + rom ( name "F-1 Race (World).gb" size 131072 crc 7e4febdf sha1 96490BE847AEEDED0B635F45B05683A6DEFDF2E8 flags verified ) ) game ( - name "F-1 Race (World) (Rev A)" - description "F-1 Race (World) (Rev A)" - rom ( name "F-1 Race (World) (Rev A).gb" size 131072 crc AB83BD70 md5 8AC5C061641B2A8B4C44B46EF693AEEF sha1 0256082F482AF57E0472F5713A432A22BFA4D2FC flags verified ) + name "F-1 Race (World) (Rev 1)" + description "F-1 Race (World) (Rev 1)" + rom ( name "F-1 Race (World) (Rev 1).gb" size 131072 crc ab83bd70 sha1 0256082F482AF57E0472F5713A432A22BFA4D2FC flags verified ) ) game ( name "F-1 Spirit (Japan)" description "F-1 Spirit (Japan)" - rom ( name "F-1 Spirit (Japan).gb" size 131072 crc F9E08783 md5 F7CAA11FCB8BE738E1FD584AC8AAD215 sha1 4F950151001C2C7E157BC407601D9A8EB9D2523C flags verified ) + rom ( name "F-1 Spirit (Japan).gb" size 131072 crc f9e08783 sha1 4F950151001C2C7E157BC407601D9A8EB9D2523C flags verified ) ) game ( name "F-15 Strike Eagle (USA, Europe)" description "F-15 Strike Eagle (USA, Europe)" - rom ( name "F-15 Strike Eagle (USA, Europe).gb" size 131072 crc 045DEE8C md5 A8B74D14E66F7A3049E79CA147141D52 sha1 237A08ABE860BCE316F1CE337AFB11EE0E566037 flags verified ) + rom ( name "F-15 Strike Eagle (USA, Europe).gb" size 131072 crc 045dee8c sha1 237A08ABE860BCE316F1CE337AFB11EE0E566037 flags verified ) ) game ( - name "F-15 Strike Eagle II (Unknown) (Proto)" - description "F-15 Strike Eagle II (Unknown) (Proto)" - rom ( name "F-15 Strike Eagle II (Unknown) (Proto).gb" size 131072 crc D80BDBBA md5 83D20A9C3F88F9FAA27C076CEFD38BC1 sha1 298C07EF596AB3A3C4A320B2F2D7E2C0DBAF764D ) + name "F-15 Strike Eagle II (USA, Europe) (Beta) (July, 1992)" + description "F-15 Strike Eagle II (USA, Europe) (Beta) (July, 1992)" + rom ( name "F-15 Strike Eagle II (USA, Europe) (Beta) (July, 1992).gb" size 131072 crc d80bdbba sha1 298C07EF596AB3A3C4A320B2F2D7E2C0DBAF764D flags verified ) ) game ( name "F1 Boy (Japan)" description "F1 Boy (Japan)" - rom ( name "F1 Boy (Japan).gb" size 65536 crc FAC1F53B md5 1EE7E23AF0663DD66AF62276917974B6 sha1 632F0CCC2BCB1C33AD46724D7B1BC66B256303A2 flags verified ) + rom ( name "F1 Boy (Japan).gb" size 65536 crc fac1f53b sha1 632F0CCC2BCB1C33AD46724D7B1BC66B256303A2 flags verified ) ) game ( name "F1 Pole Position (USA, Europe)" description "F1 Pole Position (USA, Europe)" - rom ( name "F1 Pole Position (USA, Europe).gb" size 262144 crc AABE61BB md5 2F367A3FFD68A90D45909F89ED835E2C sha1 A0087BD7421D73E1F8F339A266E62C2D03D081D6 ) + rom ( name "F1 Pole Position (USA, Europe).gb" size 262144 crc aabe61bb sha1 A0087BD7421D73E1F8F339A266E62C2D03D081D6 flags verified ) ) game ( name "Faceball 2000 (USA)" description "Faceball 2000 (USA)" - rom ( name "Faceball 2000 (USA).gb" size 131072 crc 7D890CD0 md5 05BA7F165DAB1FFD49B63B4F5C704C02 sha1 B0BD15BACE04E0A3EB89773F231AC3A532181A0A ) + rom ( name "Faceball 2000 (USA).gb" size 131072 crc 7d890cd0 sha1 B0BD15BACE04E0A3EB89773F231AC3A532181A0A ) ) game ( name "Family Jockey (Japan)" description "Family Jockey (Japan)" - rom ( name "Family Jockey (Japan).gb" size 131072 crc D6EF1450 md5 1BCACE7D7315F384CD853DF51E8BBEF7 sha1 E463999D178489E050504298F4A3FFE30B48494A flags verified ) + rom ( name "Family Jockey (Japan).gb" size 131072 crc d6ef1450 sha1 E463999D178489E050504298F4A3FFE30B48494A flags verified ) ) game ( name "Family Jockey 2 - Meiba no Kettou (Japan)" description "Family Jockey 2 - Meiba no Kettou (Japan)" - rom ( name "Family Jockey 2 - Meiba no Kettou (Japan).gb" size 131072 crc 0325E729 md5 B172D8B9954D1DCF374EF99FC7CC2716 sha1 D858FCDFCE099435FA632859A9F8E8C82823BBCB flags verified ) + rom ( name "Family Jockey 2 - Meiba no Kettou (Japan).gb" size 131072 crc 0325e729 sha1 D858FCDFCE099435FA632859A9F8E8C82823BBCB flags verified ) ) game ( name "Famista (Japan)" description "Famista (Japan)" - rom ( name "Famista (Japan).gb" size 131072 crc 3D3C059E md5 7D99006D00431AC246817D4F61E49B59 sha1 5CB8E63906D32C5408B7F959A75C41578A444C3B flags verified ) + rom ( name "Famista (Japan).gb" size 131072 crc 3d3c059e sha1 5CB8E63906D32C5408B7F959A75C41578A444C3B flags verified ) ) game ( name "Famista 2 (Japan)" description "Famista 2 (Japan)" - rom ( name "Famista 2 (Japan).gb" size 131072 crc 241A6E4C md5 6F94AD4F3761BF5C6F85F28FE4FF0ED6 sha1 E6F4CA432C36EC421935E6D4ECFC65C46764BC9C flags verified ) + rom ( name "Famista 2 (Japan).gb" size 131072 crc 241a6e4c sha1 E6F4CA432C36EC421935E6D4ECFC65C46764BC9C flags verified ) ) game ( name "Famista 3 (Japan)" description "Famista 3 (Japan)" - rom ( name "Famista 3 (Japan).gb" size 262144 crc BDC4CCC3 md5 C24FAB661012D1CF62E030BC31CD1F69 sha1 AC4B03E11E2BA135D0427C8B1DA7DE57C006B4A6 ) + rom ( name "Famista 3 (Japan).gb" size 262144 crc bdc4ccc3 sha1 AC4B03E11E2BA135D0427C8B1DA7DE57C006B4A6 flags verified ) ) game ( name "Fastest Lap (Japan, USA)" description "Fastest Lap (Japan, USA)" - rom ( name "Fastest Lap (Japan, USA).gb" size 131072 crc 59285F0A md5 E8DB5B611F9BB6DA2FFFD9FC5A880472 sha1 F1ABE89A52E4F06E0479277D8681FEAA09FCFF2F ) + rom ( name "Fastest Lap (Japan, USA).gb" size 131072 crc 59285f0a sha1 F1ABE89A52E4F06E0479277D8681FEAA09FCFF2F ) ) game ( name "Felix the Cat (USA, Europe)" description "Felix the Cat (USA, Europe)" - rom ( name "Felix the Cat (USA, Europe).gb" size 131072 crc F53F7F00 md5 4D606AB4FFD5C3D3ECF914A6AF1C1F90 sha1 C4A0D02D5964335A18839C7C30AC05B6F40C33B3 flags verified ) + rom ( name "Felix the Cat (USA, Europe).gb" size 131072 crc f53f7f00 sha1 C4A0D02D5964335A18839C7C30AC05B6F40C33B3 flags verified ) ) game ( name "Ferrari (Japan)" description "Ferrari (Japan)" - rom ( name "Ferrari (Japan).gb" size 131072 crc A7BDFEC8 md5 A1B98DAD8650552A7133E786D319C95D sha1 F9883AF35E5F49736F9DC073CE00F3779E93CF3F flags verified ) + rom ( name "Ferrari (Japan).gb" size 131072 crc a7bdfec8 sha1 F9883AF35E5F49736F9DC073CE00F3779E93CF3F flags verified ) ) game ( name "Ferrari Grand Prix Challenge (USA, Europe)" description "Ferrari Grand Prix Challenge (USA, Europe)" - rom ( name "Ferrari Grand Prix Challenge (USA, Europe).gb" size 131072 crc ED6771DB md5 D5596FA64E5B0FF193FEEAC749B8BE88 sha1 ECDBE43DB8714367BD606127E3276D8A3431841C flags verified ) + rom ( name "Ferrari Grand Prix Challenge (USA, Europe).gb" size 131072 crc ed6771db sha1 ECDBE43DB8714367BD606127E3276D8A3431841C flags verified ) ) game ( name "Fidgetts, The (Japan)" description "Fidgetts, The (Japan)" - rom ( name "Fidgetts, The (Japan).gb" size 262144 crc FFD4A9E3 md5 A3EE0AE53BDBDDD093304CB566A48EDA sha1 C701CE4C62C414AADA502F8C17AA9261DD635685 ) + rom ( name "Fidgetts, The (Japan).gb" size 262144 crc ffd4a9e3 sha1 C701CE4C62C414AADA502F8C17AA9261DD635685 ) ) game ( name "Fidgetts, The (USA, Europe) (En,Fr,De,Es,It,Nl,Sv)" description "Fidgetts, The (USA, Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Fidgetts, The (USA, Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc B3FD3E36 md5 AC2CD2A4227B38765F23FB5B72DE6229 sha1 1100F259FE30857D1103BEB116B888497F6FBDAA flags verified ) + rom ( name "Fidgetts, The (USA, Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc b3fd3e36 sha1 1100F259FE30857D1103BEB116B888497F6FBDAA flags verified ) +) + +game ( + name "FIFA - Road to World Cup 98 (Europe) (SGB Enhanced)" + description "FIFA - Road to World Cup 98 (Europe) (SGB Enhanced)" + rom ( name "FIFA - Road to World Cup 98 (Europe) (SGB Enhanced).gb" size 524288 crc cdf6a5ac sha1 5EF615A919EA967E749FEBB046F9D097D91FAB0D flags verified ) +) + +game ( + name "FIFA - Road to World Cup 98 (Europe) (Rev 1) (SGB Enhanced)" + description "FIFA - Road to World Cup 98 (Europe) (Rev 1) (SGB Enhanced)" + rom ( name "FIFA - Road to World Cup 98 (Europe) (Rev 1) (SGB Enhanced).gb" size 524288 crc 8dc0d46c sha1 8DC3AB8F020E4377AF1E1F636396CC3881268A1F flags verified ) ) game ( name "FIFA International Soccer (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" description "FIFA International Soccer (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" - rom ( name "FIFA International Soccer (USA, Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 524288 crc E5989908 md5 49CCE431C6AA61F97E650CFD83724F6E sha1 6F0AFFDEC339D7BEB9C565DC51ABE59EE0398B7B flags verified ) + rom ( name "FIFA International Soccer (USA, Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 524288 crc e5989908 sha1 6F0AFFDEC339D7BEB9C565DC51ABE59EE0398B7B flags verified ) ) game ( - name "FIFA Road to World Cup '98 (Europe) (SGB Enhanced)" - description "FIFA Road to World Cup '98 (Europe) (SGB Enhanced)" - rom ( name "FIFA Road to World Cup '98 (Europe) (SGB Enhanced).gb" size 524288 crc CDF6A5AC md5 3552EADA6EA2DB722FAB1048E3EC654F sha1 5EF615A919EA967E749FEBB046F9D097D91FAB0D flags verified ) + name "FIFA Soccer 96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" + description "FIFA Soccer 96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" + rom ( name "FIFA Soccer 96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 524288 crc af4a5de1 sha1 A434F0F96D1AA3EC50D35F82EB5EF876BCD22115 flags verified ) ) game ( - name "FIFA Road to World Cup '98 (Europe) (Rev A) (SGB Enhanced)" - description "FIFA Road to World Cup '98 (Europe) (Rev A) (SGB Enhanced)" - rom ( name "FIFA Road to World Cup '98 (Europe) (Rev A) (SGB Enhanced).gb" size 524288 crc 8DC0D46C md5 0980A1650AD5E23A27202A58FC792EC8 sha1 8DC3AB8F020E4377AF1E1F636396CC3881268A1F ) + name "FIFA Soccer 97 (USA, Europe) (SGB Enhanced)" + description "FIFA Soccer 97 (USA, Europe) (SGB Enhanced)" + rom ( name "FIFA Soccer 97 (USA, Europe) (SGB Enhanced).gb" size 524288 crc dcab906c sha1 DD9B9B99BD663CDF55187FF5867ECCD52615F025 flags verified ) ) game ( - name "FIFA Soccer '96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" - description "FIFA Soccer '96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced)" - rom ( name "FIFA Soccer '96 (USA, Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 524288 crc AF4A5DE1 md5 FAACAF378B59452D81C4EF020F87DB6D sha1 A434F0F96D1AA3EC50D35F82EB5EF876BCD22115 flags verified ) -) - -game ( - name "FIFA Soccer '97 (USA, Europe) (SGB Enhanced)" - description "FIFA Soccer '97 (USA, Europe) (SGB Enhanced)" - rom ( name "FIFA Soccer '97 (USA, Europe) (SGB Enhanced).gb" size 524288 crc DCAB906C md5 77F89E919DACE1F5B989E0DBEDC1AB8B sha1 DD9B9B99BD663CDF55187FF5867ECCD52615F025 flags verified ) -) - -game ( - name "Fighting Simulator 2 in 1 (USA, Europe)" - description "Fighting Simulator 2 in 1 (USA, Europe)" - rom ( name "Fighting Simulator 2 in 1 (USA, Europe).gb" size 131072 crc 52678AE8 md5 42B8CE5B0D54F4565BA99E02F09FE115 sha1 9073276D8ADF1E59829AE48073B42AE19C9770CE flags verified ) + name "Fighting Simulator 2 in 1 - Flying Warriors (USA, Europe)" + description "Fighting Simulator 2 in 1 - Flying Warriors (USA, Europe)" + rom ( name "Fighting Simulator 2 in 1 - Flying Warriors (USA, Europe).gb" size 131072 crc 52678ae8 sha1 9073276D8ADF1E59829AE48073B42AE19C9770CE flags verified ) ) game ( name "Final Fantasy Adventure (USA)" description "Final Fantasy Adventure (USA)" - rom ( name "Final Fantasy Adventure (USA).gb" size 262144 crc 18C78B3A md5 24CD3BDF490EF2E1AA6A8AF380ECCD78 sha1 8B93C55EE2660C60CF86DD70058F96ACE98782C8 flags verified ) + rom ( name "Final Fantasy Adventure (USA).gb" size 262144 crc 18c78b3a sha1 8B93C55EE2660C60CF86DD70058F96ACE98782C8 flags verified ) ) game ( name "Final Fantasy Legend II (USA)" description "Final Fantasy Legend II (USA)" - rom ( name "Final Fantasy Legend II (USA).gb" size 262144 crc 58314182 md5 2BB0DF1B672253AAA5F9CAF9AAB78224 sha1 6AB6890E8F688BCD87E97886A1748A4D9D341909 flags verified ) + rom ( name "Final Fantasy Legend II (USA).gb" size 262144 crc 58314182 sha1 6AB6890E8F688BCD87E97886A1748A4D9D341909 flags verified ) ) game ( name "Final Fantasy Legend III (USA)" description "Final Fantasy Legend III (USA)" - rom ( name "Final Fantasy Legend III (USA).gb" size 262144 crc 3E454710 md5 DB156BC96B528996CE1BF771195171AF sha1 3864AFA48A97DB826FFDA1D31A7FF9C6C315D5C9 flags verified ) + rom ( name "Final Fantasy Legend III (USA).gb" size 262144 crc 3e454710 sha1 3864AFA48A97DB826FFDA1D31A7FF9C6C315D5C9 flags verified ) ) game ( name "Final Fantasy Legend, The (USA)" description "Final Fantasy Legend, The (USA)" - rom ( name "Final Fantasy Legend, The (USA).gb" size 131072 crc 8046148F md5 D5C27FF8CB1B69CB56DF4FF170E2BAF0 sha1 901DFC83C72E172D35A376835807FC788444A9BB flags verified ) + rom ( name "Final Fantasy Legend, The (USA).gb" size 131072 crc 8046148f sha1 901DFC83C72E172D35A376835807FC788444A9BB flags verified ) ) game ( name "Final Reverse (Japan)" description "Final Reverse (Japan)" - rom ( name "Final Reverse (Japan).gb" size 65536 crc E94A6942 md5 C836B4B44EDCBE8A811FB10541919FE8 sha1 E4B08E702F3B6C575B31DBD62615619126E03AF5 ) + rom ( name "Final Reverse (Japan).gb" size 65536 crc e94a6942 sha1 E4B08E702F3B6C575B31DBD62615619126E03AF5 ) ) game ( name "Fire Fighter (Europe)" description "Fire Fighter (Europe)" - rom ( name "Fire Fighter (Europe).gb" size 131072 crc C46BBD49 md5 CFC7EDBC95E8DF5305D117C6993D5F20 sha1 A26A4F0A51FB3AAD3F138EEDFE326A04AF9A1B56 ) + rom ( name "Fire Fighter (Europe).gb" size 131072 crc c46bbd49 sha1 A26A4F0A51FB3AAD3F138EEDFE326A04AF9A1B56 ) ) game ( name "Fish Dude (USA)" description "Fish Dude (USA)" - rom ( name "Fish Dude (USA).gb" size 65536 crc 4B929719 md5 0BEB67DE765EF358D50C28836A39BFB0 sha1 72D11AE07B6701EFE109D20DAD6107FF6F603EA5 ) + rom ( name "Fish Dude (USA).gb" size 65536 crc 4b929719 sha1 72D11AE07B6701EFE109D20DAD6107FF6F603EA5 flags verified ) ) game ( name "Fist of the North Star (USA)" description "Fist of the North Star (USA)" - rom ( name "Fist of the North Star (USA).gb" size 131072 crc 9A84B6CF md5 C88D94A984AFDE869426694A3B992894 sha1 0BF60583DA14CD32947F8E8E6B995C2B176D95C5 ) + rom ( name "Fist of the North Star (USA).gb" size 131072 crc 9a84b6cf sha1 0BF60583DA14CD32947F8E8E6B995C2B176D95C5 ) ) game ( name "Flappy Special (Japan)" description "Flappy Special (Japan)" - rom ( name "Flappy Special (Japan).gb" size 32768 crc 3B6CDDA4 md5 C27EBEBEE5A53FE6EB857747C0556111 sha1 6517AEE7CAA2FA60750005EF1DACAEAECEE7C2F6 flags verified ) + rom ( name "Flappy Special (Japan).gb" size 32768 crc 3b6cdda4 sha1 6517AEE7CAA2FA60750005EF1DACAEAECEE7C2F6 flags verified ) ) game ( name "Flash, The (USA, Europe)" description "Flash, The (USA, Europe)" - rom ( name "Flash, The (USA, Europe).gb" size 131072 crc 6DEB1F06 md5 300C72AA607AAC5126DD791884233691 sha1 F7E5701E6FA8FE4440988D1207517668C35088C6 flags verified ) + rom ( name "Flash, The (USA, Europe).gb" size 131072 crc 6deb1f06 sha1 F7E5701E6FA8FE4440988D1207517668C35088C6 flags verified ) ) game ( name "Fleet Commander VS. (Japan)" description "Fleet Commander VS. (Japan)" - rom ( name "Fleet Commander VS. (Japan).gb" size 262144 crc 71BF3256 md5 6D301BBECADB7D4CD064A97751D642C5 sha1 B858D597E5EEA575C5BAA953785C96459D9BE593 ) + rom ( name "Fleet Commander VS. (Japan).gb" size 262144 crc 71bf3256 sha1 B858D597E5EEA575C5BAA953785C96459D9BE593 ) ) game ( name "Flintstones, The (USA, Europe)" description "Flintstones, The (USA, Europe)" - rom ( name "Flintstones, The (USA, Europe).gb" size 262144 crc 503D3613 md5 F07ED24E96F84CE78787709F248263C8 sha1 506A647137BCAAD81589F1B3592884B3BBED8AA3 flags verified ) + rom ( name "Flintstones, The (USA, Europe).gb" size 262144 crc 503d3613 sha1 506A647137BCAAD81589F1B3592884B3BBED8AA3 flags verified ) ) game ( name "Flintstones, The - King Rock Treasure Island (USA, Europe)" description "Flintstones, The - King Rock Treasure Island (USA, Europe)" - rom ( name "Flintstones, The - King Rock Treasure Island (USA, Europe).gb" size 131072 crc 508282D0 md5 25DFACA5120462AF05532AAF4756776A sha1 4EA1609DC273623C677AAA0ACCD0CD8D4A03EFCA flags verified ) -) - -game ( - name "Flipull (Japan)" - description "Flipull (Japan)" - rom ( name "Flipull (Japan).gb" size 32768 crc 198F147D md5 F9B37FD741EE5EED62355F11AFB52BCB sha1 090C88AE19892C35608F4FA844A6E9EFCBE23893 flags verified ) + rom ( name "Flintstones, The - King Rock Treasure Island (USA, Europe).gb" size 131072 crc 508282d0 sha1 4EA1609DC273623C677AAA0ACCD0CD8D4A03EFCA flags verified ) ) game ( name "Flipull (USA)" description "Flipull (USA)" - rom ( name "Flipull (USA).gb" size 32768 crc A2F30B4B md5 4FCC13DB8144687E6B28200387AED25C sha1 54CF45A997D390729DD23B9ED46A967B77CB7664 ) + rom ( name "Flipull (USA).gb" size 32768 crc a2f30b4b sha1 54CF45A997D390729DD23B9ED46A967B77CB7664 ) +) + +game ( + name "Flipull - An Exciting Cube Game (Japan)" + description "Flipull - An Exciting Cube Game (Japan)" + rom ( name "Flipull - An Exciting Cube Game (Japan).gb" size 32768 crc 198f147d sha1 090C88AE19892C35608F4FA844A6E9EFCBE23893 flags verified ) ) game ( name "Football International (Europe)" description "Football International (Europe)" - rom ( name "Football International (Europe).gb" size 131072 crc 6E659690 md5 E84971B95D5DBB25EFAF4EA89564A1A9 sha1 30BE5422B15E1960D22DC77D646642D7365B243C ) + rom ( name "Football International (Europe).gb" size 131072 crc 6e659690 sha1 30BE5422B15E1960D22DC77D646642D7365B243C ) ) game ( name "Foreman for Real (Japan)" description "Foreman for Real (Japan)" - rom ( name "Foreman for Real (Japan).gb" size 262144 crc 860EA816 md5 E273C01531ADF757CE6B3BC6D17AFEC2 sha1 835B3208458E8CA1956E27A693FAB036D4B25974 ) + rom ( name "Foreman for Real (Japan).gb" size 262144 crc 860ea816 sha1 835B3208458E8CA1956E27A693FAB036D4B25974 ) ) game ( name "Foreman for Real (USA, Europe)" description "Foreman for Real (USA, Europe)" - rom ( name "Foreman for Real (USA, Europe).gb" size 262144 crc 77083AE0 md5 F6C52E1DC73CFFCBCBD9958008F6DB06 sha1 7B088C7B3A0AD275D340CA27F64A99C1BD6C34E6 flags verified ) + rom ( name "Foreman for Real (USA, Europe).gb" size 262144 crc 77083ae0 sha1 7B088C7B3A0AD275D340CA27F64A99C1BD6C34E6 flags verified ) ) game ( name "Fortified Zone (USA, Europe)" description "Fortified Zone (USA, Europe)" - rom ( name "Fortified Zone (USA, Europe).gb" size 131072 crc E3B59B7E md5 A981378DA19C08597DB03F3EE02CD6D7 sha1 232D2F57AB4BEF748EB832DFB4085CC3DF1FD532 flags verified ) + rom ( name "Fortified Zone (USA, Europe).gb" size 131072 crc e3b59b7e sha1 232D2F57AB4BEF748EB832DFB4085CC3DF1FD532 flags verified ) ) game ( name "Frank Thomas Big Hurt Baseball (USA, Europe)" description "Frank Thomas Big Hurt Baseball (USA, Europe)" - rom ( name "Frank Thomas Big Hurt Baseball (USA, Europe).gb" size 524288 crc 9A494AE6 md5 C5B36DE3DD613B23E2AEF7FC4427E5F8 sha1 CCEA5B85ED334A2BF7BD4449F07BBF3A86841DFD flags verified ) + rom ( name "Frank Thomas Big Hurt Baseball (USA, Europe).gb" size 524288 crc 9a494ae6 sha1 CCEA5B85ED334A2BF7BD4449F07BBF3A86841DFD flags verified ) ) game ( - name "Franky, Joe & Dirk... On the Tiles (Europe) (En,Fr,De,Es,It,Nl)" - description "Franky, Joe & Dirk... On the Tiles (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Franky, Joe & Dirk... On the Tiles (Europe) (En,Fr,De,Es,It,Nl).gb" size 131072 crc CAF5B372 md5 EA8D9E89565FF9E931118B9EA4712C29 sha1 B7E292CFD34D64546F158E548AFA92EFAF8C2ACD flags verified ) + name "Franky, Joe & Dirk - On the Tiles (Europe) (En,Fr,De,Es,It,Nl)" + description "Franky, Joe & Dirk - On the Tiles (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Franky, Joe & Dirk - On the Tiles (Europe) (En,Fr,De,Es,It,Nl).gb" size 131072 crc caf5b372 sha1 B7E292CFD34D64546F158E548AFA92EFAF8C2ACD flags verified ) ) game ( name "Frisky Tom (Japan) (SGB Enhanced)" description "Frisky Tom (Japan) (SGB Enhanced)" - rom ( name "Frisky Tom (Japan) (SGB Enhanced).gb" size 131072 crc 0BEF84A1 md5 F49FEF0C5CC023462D7F84286DC19976 sha1 4162CA88C94C40E3FA6E09067B956CF4953CCF89 ) + rom ( name "Frisky Tom (Japan) (SGB Enhanced).gb" size 131072 crc 0bef84a1 sha1 4162CA88C94C40E3FA6E09067B956CF4953CCF89 ) ) game ( name "Frogger (USA)" description "Frogger (USA)" - rom ( name "Frogger (USA).gb" size 131072 crc 4D933C08 md5 1ED313C4FD78B81A8CA3613E6234DA7E sha1 1DBB26DD94C9710B029F2F88473AED0267DB491C ) + rom ( name "Frogger (USA).gb" size 131072 crc 4d933c08 sha1 1DBB26DD94C9710B029F2F88473AED0267DB491C flags verified ) ) game ( name "From TV Animation Slam Dunk - Gakeppuchi no Kesshou League (Japan) (SGB Enhanced)" description "From TV Animation Slam Dunk - Gakeppuchi no Kesshou League (Japan) (SGB Enhanced)" - rom ( name "From TV Animation Slam Dunk - Gakeppuchi no Kesshou League (Japan) (SGB Enhanced).gb" size 262144 crc AE478A6F md5 E96273C4D399F1A9DE58702AED110B4A sha1 0FAF2C66A916C979450810EC16029C2258F90F83 flags verified ) + rom ( name "From TV Animation Slam Dunk - Gakeppuchi no Kesshou League (Japan) (SGB Enhanced).gb" size 262144 crc ae478a6f sha1 0FAF2C66A916C979450810EC16029C2258F90F83 flags verified ) ) game ( name "From TV Animation Slam Dunk 2 - Zenkoku e no Tip Off (Japan) (SGB Enhanced)" description "From TV Animation Slam Dunk 2 - Zenkoku e no Tip Off (Japan) (SGB Enhanced)" - rom ( name "From TV Animation Slam Dunk 2 - Zenkoku e no Tip Off (Japan) (SGB Enhanced).gb" size 524288 crc CB35900A md5 4C76F3947EC093275C65EB3932678712 sha1 B8223CE166121AE7224D4431FDF27750C737B3F2 ) + rom ( name "From TV Animation Slam Dunk 2 - Zenkoku e no Tip Off (Japan) (SGB Enhanced).gb" size 524288 crc cb35900a sha1 B8223CE166121AE7224D4431FDF27750C737B3F2 ) ) game ( name "Funny Field (Japan)" description "Funny Field (Japan)" - rom ( name "Funny Field (Japan).gb" size 65536 crc BFD87AA4 md5 87F730D486BDC4685BCC6E91A7124C35 sha1 0B74E84CE50454057F78E4178BE2599E57C91855 flags verified ) + rom ( name "Funny Field (Japan).gb" size 65536 crc bfd87aa4 sha1 0B74E84CE50454057F78E4178BE2599E57C91855 flags verified ) ) game ( name "Fushigi na Blobby - Princess Blob o Sukue! (Japan)" description "Fushigi na Blobby - Princess Blob o Sukue! (Japan)" - rom ( name "Fushigi na Blobby - Princess Blob o Sukue! (Japan).gb" size 65536 crc 3D0BAC10 md5 8A7AAF3AFCD00348730C86DDC926E30A sha1 FCD6AC8A0AD6EB1F5D9E00C877747521541204DE ) + rom ( name "Fushigi na Blobby - Princess Blob o Sukue! (Japan).gb" size 65536 crc 3d0bac10 sha1 FCD6AC8A0AD6EB1F5D9E00C877747521541204DE ) ) game ( name "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced)" description "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced)" - rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced).gb" size 524288 crc 2962AFB4 md5 754398219A3AB38394CDAC543D8DEB47 sha1 920EF94C05AC741047A266CB1668C881EAB2937C flags verified ) + rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB - Tsukikage Mura no Kaibutsu (Japan) (SGB Enhanced).gb" size 524288 crc 2962afb4 sha1 920EF94C05AC741047A266CB1668C881EAB2937C flags verified ) +) + +game ( + name "G Arms - Operation Gundam (Japan)" + description "G Arms - Operation Gundam (Japan)" + rom ( name "G Arms - Operation Gundam (Japan).gb" size 131072 crc 39058153 sha1 7D8011636FE36266B5F716E78E3E29006F024992 flags verified ) ) game ( name "Galaga & Galaxian (Japan) (SGB Enhanced)" description "Galaga & Galaxian (Japan) (SGB Enhanced)" - rom ( name "Galaga & Galaxian (Japan) (SGB Enhanced).gb" size 131072 crc 532036D5 md5 49F8BA40E521BB0451AC5C6C1D00AF77 sha1 2D67A97B4737B24EA0EFF7A7C798B7D77E6A0724 ) + rom ( name "Galaga & Galaxian (Japan) (SGB Enhanced).gb" size 131072 crc 532036d5 sha1 2D67A97B4737B24EA0EFF7A7C798B7D77E6A0724 ) ) game ( name "Game & Watch Gallery (Europe) (SGB Enhanced)" description "Game & Watch Gallery (Europe) (SGB Enhanced)" - rom ( name "Game & Watch Gallery (Europe) (SGB Enhanced).gb" size 262144 crc 96ECC1E0 md5 E5511E9A5F0C709BA25DF570EB5BE41C sha1 31186CFF6BB548ECD0C91C07F16DC98DE9C19EA2 flags verified ) + rom ( name "Game & Watch Gallery (Europe) (SGB Enhanced).gb" size 262144 crc 96ecc1e0 sha1 31186CFF6BB548ECD0C91C07F16DC98DE9C19EA2 flags verified ) ) game ( name "Game & Watch Gallery (USA) (SGB Enhanced)" description "Game & Watch Gallery (USA) (SGB Enhanced)" - rom ( name "Game & Watch Gallery (USA) (SGB Enhanced).gb" size 262144 crc 99B2FE79 md5 D5081250257E0DAFCB8FE8720FCB9F28 sha1 F8C5AD6D6BF1A5A90DFFEBADA1DBD69A93720C83 ) + rom ( name "Game & Watch Gallery (USA) (SGB Enhanced).gb" size 262144 crc 99b2fe79 sha1 F8C5AD6D6BF1A5A90DFFEBADA1DBD69A93720C83 ) ) game ( - name "Game & Watch Gallery (USA) (Rev A) (SGB Enhanced)" - description "Game & Watch Gallery (USA) (Rev A) (SGB Enhanced)" - rom ( name "Game & Watch Gallery (USA) (Rev A) (SGB Enhanced).gb" size 262144 crc 9E6CDC96 md5 7727F43D66A77FE0284BF1B8FFEDE7DD sha1 4E4DA0ED89C2BAAED64600F7EACA90AEEADC084E flags verified ) + name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced)" + description "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced)" + rom ( name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced).gb" size 262144 crc 9e6cdc96 sha1 4E4DA0ED89C2BAAED64600F7EACA90AEEADC084E flags verified ) ) game ( name "Game Boy Camera (USA, Europe) (SGB Enhanced)" description "Game Boy Camera (USA, Europe) (SGB Enhanced)" - rom ( name "Game Boy Camera (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 4640909F md5 42D2F65E2549BE9D1D126A6828B5D1C1 sha1 461C3C37ED270681E3E94053EFB21504B600AEF5 flags verified ) + rom ( name "Game Boy Camera (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 4640909f sha1 461C3C37ED270681E3E94053EFB21504B600AEF5 flags verified ) ) game ( name "Game Boy Camera Gold (USA) (SGB Enhanced)" description "Game Boy Camera Gold (USA) (SGB Enhanced)" - rom ( name "Game Boy Camera Gold (USA) (SGB Enhanced).gb" size 1048576 crc A1A3F786 md5 B2999CFB6DACB439F501A71F30F91762 sha1 53A0DD6DE3EBD0D3495F8BDC377AB08E5074C0EF ) + rom ( name "Game Boy Camera Gold (USA) (SGB Enhanced).gb" size 1048576 crc a1a3f786 sha1 53A0DD6DE3EBD0D3495F8BDC377AB08E5074C0EF ) ) game ( name "Game Boy Controller Kensa Cartridge (Japan)" description "Game Boy Controller Kensa Cartridge (Japan)" - rom ( name "Game Boy Controller Kensa Cartridge (Japan).gb" size 32768 crc F5657FCE md5 9FCF969D7D4554997CA902BBF9033287 sha1 1BED2A9AC25AC2F88B4FC45E729122ABCAD962F3 ) + rom ( name "Game Boy Controller Kensa Cartridge (Japan).gb" size 32768 crc f5657fce sha1 1BED2A9AC25AC2F88B4FC45E729122ABCAD962F3 flags verified ) ) game ( name "Game Boy Datenlogger 1 (Germany) (v1.0) (GBD1) (Unl)" description "Game Boy Datenlogger 1 (Germany) (v1.0) (GBD1) (Unl)" - serial "0412421A BS" - rom ( name "Game Boy Datenlogger 1 (Germany) (v1.0) (GBD1) (Unl).gb" size 32768 crc 9AB28AF0 md5 137D38365425885D5D86B16DC380D5C5 sha1 BFEBA84926A72498EA65FCAE767DF8BA13F28D49 ) + rom ( name "Game Boy Datenlogger 1 (Germany) (v1.0) (GBD1) (Unl).gb" size 32768 crc 9ab28af0 sha1 BFEBA84926A72498EA65FCAE767DF8BA13F28D49 flags verified ) ) game ( name "Game Boy Digital Sampling Oscilloscope (Europe) (v3.6) (GBDSO) (Unl)" description "Game Boy Digital Sampling Oscilloscope (Europe) (v3.6) (GBDSO) (Unl)" - rom ( name "Game Boy Digital Sampling Oscilloscope (Europe) (v3.6) (GBDSO) (Unl).gb" size 32768 crc 572EA59C md5 ACC04AEBB20CB829DCA77BB554F60653 sha1 68128BD8B01970054590A88B785D553456B68EC1 ) + rom ( name "Game Boy Digital Sampling Oscilloscope (Europe) (v3.6) (GBDSO) (Unl).gb" size 32768 crc 572ea59c sha1 68128BD8B01970054590A88B785D553456B68EC1 flags verified ) ) game ( name "Game Boy Gallery (Japan) (SGB Enhanced)" description "Game Boy Gallery (Japan) (SGB Enhanced)" - rom ( name "Game Boy Gallery (Japan) (SGB Enhanced).gb" size 262144 crc A93E125B md5 C25B8EBA16BB9A24DCF6339FEBC05DBE sha1 9D9465486610AB470203236C614692BC7B86C328 flags verified ) + rom ( name "Game Boy Gallery (Japan) (SGB Enhanced).gb" size 262144 crc a93e125b sha1 9D9465486610AB470203236C614692BC7B86C328 flags verified ) ) game ( - name "Game Boy Gallery - 5 Games in One (Europe) (SGB Enhanced)" - description "Game Boy Gallery - 5 Games in One (Europe) (SGB Enhanced)" - rom ( name "Game Boy Gallery - 5 Games in One (Europe) (SGB Enhanced).gb" size 131072 crc 263FD152 md5 B6D1139FB8D57CD47F173FAEF592C813 sha1 07B6174A413858F84BFC480169945C7FD1A372B9 flags verified ) + name "Game Boy Gallery - 5 Games in 1 (Europe) (SGB Enhanced)" + description "Game Boy Gallery - 5 Games in 1 (Europe) (SGB Enhanced)" + rom ( name "Game Boy Gallery - 5 Games in 1 (Europe) (SGB Enhanced).gb" size 131072 crc 263fd152 sha1 07B6174A413858F84BFC480169945C7FD1A372B9 flags verified ) ) game ( name "Game Boy Gallery 2 (Australia) (SGB Enhanced)" description "Game Boy Gallery 2 (Australia) (SGB Enhanced)" - rom ( name "Game Boy Gallery 2 (Australia) (SGB Enhanced).gb" size 262144 crc 6B09508F md5 5C63962225AE9F8738305DC281EBBFB0 sha1 F002564F9CD9EDB704B9C64F889AEA3E7836A712 flags verified ) + rom ( name "Game Boy Gallery 2 (Australia) (SGB Enhanced).gb" size 262144 crc 6b09508f sha1 F002564F9CD9EDB704B9C64F889AEA3E7836A712 flags verified ) ) game ( name "Game Boy Gallery 2 (Japan) (SGB Enhanced)" description "Game Boy Gallery 2 (Japan) (SGB Enhanced)" - rom ( name "Game Boy Gallery 2 (Japan) (SGB Enhanced).gb" size 524288 crc 9359A183 md5 3E35ECE810EAA26BB027A18F58CF6DBA sha1 021C47F89FA975E4DC5CC32C61BF87B120A25C09 flags verified ) + rom ( name "Game Boy Gallery 2 (Japan) (SGB Enhanced).gb" size 524288 crc 9359a183 sha1 021C47F89FA975E4DC5CC32C61BF87B120A25C09 flags verified ) +) + +game ( + name "Game Boy Test Cartridge (USA, Europe)" + description "Game Boy Test Cartridge (USA, Europe)" + rom ( name "Game Boy Test Cartridge (USA, Europe).gb" size 32768 crc ae13a5c3 sha1 CE9C211852B4357B1356BB015DB6F675DEF69C9F flags verified ) ) game ( name "Game Boy Wars (Japan)" description "Game Boy Wars (Japan)" - rom ( name "Game Boy Wars (Japan).gb" size 262144 crc F5D364DB md5 1EC4506AEF73C1BE2412B39D2BA3681C sha1 9F725D3CBBEB5E27B7EE36304F077F78D9AD074E flags verified ) + rom ( name "Game Boy Wars (Japan).gb" size 262144 crc f5d364db sha1 9F725D3CBBEB5E27B7EE36304F077F78D9AD074E flags verified ) ) game ( name "Game Boy Wars Turbo (Japan) (SGB Enhanced)" description "Game Boy Wars Turbo (Japan) (SGB Enhanced)" - rom ( name "Game Boy Wars Turbo (Japan) (SGB Enhanced).gb" size 524288 crc 94563424 md5 C10A76A601EA375593F1CB944C3365E7 sha1 27121450BEE04790E7A0D8A08086AD42302F17E9 ) + rom ( name "Game Boy Wars Turbo (Japan) (SGB Enhanced).gb" size 524288 crc 94563424 sha1 27121450BEE04790E7A0D8A08086AD42302F17E9 ) ) game ( name "Game Boy Wars Turbo - Famitsu Version (Japan) (SGB Enhanced)" description "Game Boy Wars Turbo - Famitsu Version (Japan) (SGB Enhanced)" - rom ( name "Game Boy Wars Turbo - Famitsu Version (Japan) (SGB Enhanced).gb" size 262144 crc 86D04BFB md5 9CCC41FE3FB0AC407440CB8EA9FB3D0A sha1 A0106F20AAF857A7BA033537821E31C6EC074DD6 ) + rom ( name "Game Boy Wars Turbo - Famitsu Version (Japan) (SGB Enhanced).gb" size 262144 crc 86d04bfb sha1 A0106F20AAF857A7BA033537821E31C6EC074DD6 ) ) game ( name "Game de Hakken!! Tamagotchi (Japan) (SGB Enhanced)" description "Game de Hakken!! Tamagotchi (Japan) (SGB Enhanced)" - rom ( name "Game de Hakken!! Tamagotchi (Japan) (SGB Enhanced).gb" size 524288 crc EFC0F266 md5 FDD228F59EE0EB8B162054A330039B0A sha1 5AEA023FD373643E55C7276B79A2D042302C3329 flags verified ) + rom ( name "Game de Hakken!! Tamagotchi (Japan) (SGB Enhanced).gb" size 524288 crc efc0f266 sha1 5AEA023FD373643E55C7276B79A2D042302C3329 flags verified ) ) game ( name "Game de Hakken!! Tamagotchi - Osutchi to Mesutchi (Japan) (SGB Enhanced)" description "Game de Hakken!! Tamagotchi - Osutchi to Mesutchi (Japan) (SGB Enhanced)" - rom ( name "Game de Hakken!! Tamagotchi - Osutchi to Mesutchi (Japan) (SGB Enhanced).gb" size 524288 crc 9694D69D md5 3488999B749038EFA076EA7B2FCC99BC sha1 E61F7FAAD888E5A1C56FFE66FA3C0330B5EE459B flags verified ) + rom ( name "Game de Hakken!! Tamagotchi - Osutchi to Mesutchi (Japan) (SGB Enhanced).gb" size 524288 crc 9694d69d sha1 E61F7FAAD888E5A1C56FFE66FA3C0330B5EE459B flags verified ) ) game ( name "Game de Hakken!! Tamagotchi 2 (Japan) (SGB Enhanced)" description "Game de Hakken!! Tamagotchi 2 (Japan) (SGB Enhanced)" - rom ( name "Game de Hakken!! Tamagotchi 2 (Japan) (SGB Enhanced).gb" size 524288 crc 19889C43 md5 D57EEED4D5DEDE4B9AEFD15C4C703113 sha1 ADE11F43F6957C75CDE8575E7CBA11DE9E53E0EA flags verified ) + rom ( name "Game de Hakken!! Tamagotchi 2 (Japan) (SGB Enhanced).gb" size 524288 crc 19889c43 sha1 ADE11F43F6957C75CDE8575E7CBA11DE9E53E0EA flags verified ) ) game ( name "Game Genie (USA) (v2.1) (Unl)" description "Game Genie (USA) (v2.1) (Unl)" - rom ( name "Game Genie (USA) (v2.1) (Unl).gb" size 8192 crc BC491C4B md5 49E512BB8B0DCC6A8D26D873623D0590 sha1 50E2CEB9B83F953D304D5BC6A25065BAFAD89490 flags verified ) + rom ( name "Game Genie (USA) (v2.1) (Unl).gb" size 8192 crc bc491c4b sha1 50E2CEB9B83F953D304D5BC6A25065BAFAD89490 flags verified ) ) game ( name "Game of Harmony, The (USA)" description "Game of Harmony, The (USA)" - rom ( name "Game of Harmony, The (USA).gb" size 32768 crc B0074ACB md5 8AA55E4347527C8780243BC6AE3D7E02 sha1 B0BC752E3AD25FCB83D8CA04A82A0F5E35381DB2 flags verified ) + rom ( name "Game of Harmony, The (USA).gb" size 32768 crc b0074acb sha1 B0BC752E3AD25FCB83D8CA04A82A0F5E35381DB2 flags verified ) ) game ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" description "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" - rom ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced).gb" size 262144 crc 62769EC1 md5 88C33C0FC3DBDC848B9BE604CDDA5744 sha1 C6EC7AA3AD2B28CA43551CDA3C0CFDBCB4377B45 ) + rom ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced).gb" size 262144 crc 62769ec1 sha1 C6EC7AA3AD2B28CA43551CDA3C0CFDBCB4377B45 ) ) game ( name "GameShark (USA) (Unl)" description "GameShark (USA) (Unl)" - rom ( name "GameShark (USA) (Unl).gb" size 131072 crc D6909596 md5 6AE8105F21BF0B80A6F64FABC4094C4B sha1 09A6DAE5E5FAAE1C4B5CF20E1B913B1C5E72297E ) + rom ( name "GameShark (USA) (Unl).gb" size 131072 crc d6909596 sha1 09A6DAE5E5FAAE1C4B5CF20E1B913B1C5E72297E ) ) game ( name "Ganbare Goemon - Kurofunetou no Nazo (Japan) (SGB Enhanced)" description "Ganbare Goemon - Kurofunetou no Nazo (Japan) (SGB Enhanced)" - rom ( name "Ganbare Goemon - Kurofunetou no Nazo (Japan) (SGB Enhanced).gb" size 262144 crc 910AFE24 md5 853B7EF83C8DC9DEA361303766FEA360 sha1 BD336346982E33270128B74A7B356E9E6824E4A6 ) + rom ( name "Ganbare Goemon - Kurofunetou no Nazo (Japan) (SGB Enhanced).gb" size 262144 crc 910afe24 sha1 BD336346982E33270128B74A7B356E9E6824E4A6 flags verified ) ) game ( name "Ganbare Goemon - Sarawareta Ebisumaru (Japan)" description "Ganbare Goemon - Sarawareta Ebisumaru (Japan)" - rom ( name "Ganbare Goemon - Sarawareta Ebisumaru (Japan).gb" size 262144 crc 33261C11 md5 63C858BE7CC05E2CB7A8D3CCDDCE5DFF sha1 DD38C2B305160B6BC7E1767A0E7DE9850260779C flags verified ) + rom ( name "Ganbare Goemon - Sarawareta Ebisumaru (Japan).gb" size 262144 crc 33261c11 sha1 DD38C2B305160B6BC7E1767A0E7DE9850260779C flags verified ) ) game ( name "Ganso!! Yancha Maru (Japan)" description "Ganso!! Yancha Maru (Japan)" - rom ( name "Ganso!! Yancha Maru (Japan).gb" size 65536 crc 004443E6 md5 A60DF6AEB6820683805BE1717097FCA8 sha1 76BE351EAC00749553C942B6F8002E65D8A35986 flags verified ) + rom ( name "Ganso!! Yancha Maru (Japan).gb" size 65536 crc 004443e6 sha1 76BE351EAC00749553C942B6F8002E65D8A35986 flags verified ) ) game ( name "Garfield Labyrinth (Europe)" description "Garfield Labyrinth (Europe)" - rom ( name "Garfield Labyrinth (Europe).gb" size 131072 crc 51B8626D md5 49BCB33470DF757847EEF5E170C9B6BD sha1 87913E557DFB98C5F2A0F42EA074C36ECA57A4F7 ) + rom ( name "Garfield Labyrinth (Europe).gb" size 131072 crc 51b8626d sha1 87913E557DFB98C5F2A0F42EA074C36ECA57A4F7 flags verified ) ) game ( name "Gargoyle's Quest (USA, Europe)" description "Gargoyle's Quest (USA, Europe)" - rom ( name "Gargoyle's Quest (USA, Europe).gb" size 131072 crc 0030E61F md5 63E3F5F4B90F17BDF6D2F2AED515E248 sha1 1DA5834CD7CEA711195CD8581614C5022DA768B7 flags verified ) + rom ( name "Gargoyle's Quest (USA, Europe).gb" size 131072 crc 0030e61f sha1 1DA5834CD7CEA711195CD8581614C5022DA768B7 flags verified ) +) + +game ( + name "Gargoyle's Quest (Europe) (Rev 1)" + description "Gargoyle's Quest (Europe) (Rev 1)" + rom ( name "Gargoyle's Quest (Europe) (Rev 1).gb" size 131072 crc b86ef7a5 sha1 21FBE39014FFED80D0DE2092517522D3CB9B03F9 flags verified ) ) game ( name "Gauntlet II (USA, Europe)" description "Gauntlet II (USA, Europe)" - rom ( name "Gauntlet II (USA, Europe).gb" size 262144 crc 1907DAC5 md5 CDCA15CFD1645C02FE1CC327B772264E sha1 DC37DF322B54A5DF5D04BC637E26B011B84598BF flags verified ) + rom ( name "Gauntlet II (USA, Europe).gb" size 262144 crc 1907dac5 sha1 DC37DF322B54A5DF5D04BC637E26B011B84598BF flags verified ) ) game ( name "GB Basketball (Japan)" description "GB Basketball (Japan)" - rom ( name "GB Basketball (Japan).gb" size 131072 crc D9B24D21 md5 F97902058640F3700B5ACFF422969BA3 sha1 65F73DB2942D400A4C555FBCFD6313F07303D4E4 flags verified ) + rom ( name "GB Basketball (Japan).gb" size 131072 crc d9b24d21 sha1 65F73DB2942D400A4C555FBCFD6313F07303D4E4 flags verified ) ) game ( name "GB Genjin (Japan)" description "GB Genjin (Japan)" - rom ( name "GB Genjin (Japan).gb" size 262144 crc 690227F6 md5 CCB0D2A704C3EC24A0BBD78FCDFAD4DD sha1 C2E98C76E49155E7B9815E0C33AE6CF71DAAEE2C flags verified ) + rom ( name "GB Genjin (Japan).gb" size 262144 crc 690227f6 sha1 C2E98C76E49155E7B9815E0C33AE6CF71DAAEE2C flags verified ) ) game ( name "GB Genjin 2 (Japan) (SGB Enhanced)" description "GB Genjin 2 (Japan) (SGB Enhanced)" - rom ( name "GB Genjin 2 (Japan) (SGB Enhanced).gb" size 262144 crc 6F7AD5D9 md5 B6D07D6830C8517AA96B000D9F3B2BF6 sha1 82C1E3DD8B425FB49A1D1C25813002B23963A84A flags verified ) + rom ( name "GB Genjin 2 (Japan) (SGB Enhanced).gb" size 262144 crc 6f7ad5d9 sha1 82C1E3DD8B425FB49A1D1C25813002B23963A84A flags verified ) ) game ( name "GB Genjin Land - Viva! Chikkun Oukoku (Japan)" description "GB Genjin Land - Viva! Chikkun Oukoku (Japan)" - rom ( name "GB Genjin Land - Viva! Chikkun Oukoku (Japan).gb" size 262144 crc B08BB116 md5 E6E405968FACE6A00ABF3ABF8514E9DE sha1 6C7B6268E28281AE06FB621BF3CBBCBADC8E30E8 ) + rom ( name "GB Genjin Land - Viva! Chikkun Oukoku (Japan).gb" size 262144 crc b08bb116 sha1 6C7B6268E28281AE06FB621BF3CBBCBADC8E30E8 ) ) game ( - name "GB Pachi-Slot Hisshouhou! Jr (Japan)" - description "GB Pachi-Slot Hisshouhou! Jr (Japan)" - rom ( name "GB Pachi-Slot Hisshouhou! Jr (Japan).gb" size 131072 crc A2E210E9 md5 7FED5D5E548D9A4C1F61A47F1A6692A9 sha1 7636799F5A57D22CF579BB687BE5BB9FEDDDD0CA flags verified ) + name "GB Pachi-Slot Hisshouhou! Jr. (Japan)" + description "GB Pachi-Slot Hisshouhou! Jr. (Japan)" + rom ( name "GB Pachi-Slot Hisshouhou! Jr. (Japan).gb" size 131072 crc a2e210e9 sha1 7636799F5A57D22CF579BB687BE5BB9FEDDDD0CA flags verified ) ) game ( name "GBKiss Mini Games (Japan)" description "GBKiss Mini Games (Japan)" - rom ( name "GBKiss Mini Games (Japan).gb" size 262144 crc 92A03FC3 md5 5EB0CC0785ADBC6AD8C1DFA09FE4A692 sha1 3C6C78F0A936DBC3F366A82C1ECA8BE0597D4D5B ) + rom ( name "GBKiss Mini Games (Japan).gb" size 262144 crc 92a03fc3 sha1 3C6C78F0A936DBC3F366A82C1ECA8BE0597D4D5B flags verified ) ) game ( name "Gear Works (USA, Europe)" description "Gear Works (USA, Europe)" - rom ( name "Gear Works (USA, Europe).gb" size 131072 crc B2B72056 md5 16AF858484041D572299B501EAD2B788 sha1 F064C897DA11945287ED793FE041D75C1B536709 flags verified ) + rom ( name "Gear Works (USA, Europe).gb" size 131072 crc b2b72056 sha1 F064C897DA11945287ED793FE041D75C1B536709 flags verified ) ) game ( name "Gegege no Kitarou - Youkai Souzoushu Arawaru! (Japan) (SGB Enhanced)" description "Gegege no Kitarou - Youkai Souzoushu Arawaru! (Japan) (SGB Enhanced)" - rom ( name "Gegege no Kitarou - Youkai Souzoushu Arawaru! (Japan) (SGB Enhanced).gb" size 262144 crc 28E507B0 md5 D76CA0B687C813464743967C26B03278 sha1 FA52C8F0BB31E25BE829C7D4F52A7F4DB1D5EF5B ) + rom ( name "Gegege no Kitarou - Youkai Souzoushu Arawaru! (Japan) (SGB Enhanced).gb" size 262144 crc 28e507b0 sha1 FA52C8F0BB31E25BE829C7D4F52A7F4DB1D5EF5B flags verified ) ) game ( name "Gekitou Power Modeller (Japan) (SGB Enhanced)" description "Gekitou Power Modeller (Japan) (SGB Enhanced)" - rom ( name "Gekitou Power Modeller (Japan) (SGB Enhanced).gb" size 524288 crc 48C1EE22 md5 255BCA32093336CCBACDD185951C8727 sha1 22D6BF37EB3A29AEB1F9969EC51537ECA8036A4C flags verified ) + rom ( name "Gekitou Power Modeller (Japan) (SGB Enhanced).gb" size 524288 crc 48c1ee22 sha1 22D6BF37EB3A29AEB1F9969EC51537ECA8036A4C flags verified ) ) game ( name "Gem Gem (Japan)" description "Gem Gem (Japan)" - rom ( name "Gem Gem (Japan).gb" size 65536 crc A64A8710 md5 75963DD8E91147452BFA88F0D608D554 sha1 90A29D7A56F64B596CDA1C64C8998B63D12C321E ) + rom ( name "Gem Gem (Japan).gb" size 65536 crc a64a8710 sha1 90A29D7A56F64B596CDA1C64C8998B63D12C321E ) ) game ( name "Genjin Collection (Japan) (SGB Enhanced)" description "Genjin Collection (Japan) (SGB Enhanced)" - rom ( name "Genjin Collection (Japan) (SGB Enhanced).gb" size 1048576 crc B2EEDD36 md5 E6E0B97C6A3B80AB2E0A323E3D21A137 sha1 A9F953E2A3680078E51CB42FAC44EDF81991737B flags verified ) + rom ( name "Genjin Collection (Japan) (SGB Enhanced).gb" size 1048576 crc b2eedd36 sha1 A9F953E2A3680078E51CB42FAC44EDF81991737B flags verified ) ) game ( name "Genjin Cottsu (Japan) (SGB Enhanced)" description "Genjin Cottsu (Japan) (SGB Enhanced)" - rom ( name "Genjin Cottsu (Japan) (SGB Enhanced).gb" size 262144 crc 95E8FCB1 md5 B90369597FE5E986AF4C1C31AD655F86 sha1 70E3CD1DF16FBFF644C32F588BF80A116B043BB2 ) + rom ( name "Genjin Cottsu (Japan) (SGB Enhanced).gb" size 262144 crc 95e8fcb1 sha1 70E3CD1DF16FBFF644C32F588BF80A116B043BB2 ) ) game ( name "Genki Bakuhatsu Gambaruger (Japan)" description "Genki Bakuhatsu Gambaruger (Japan)" - rom ( name "Genki Bakuhatsu Gambaruger (Japan).gb" size 131072 crc 6226D280 md5 837F3B25D5864B631DFF52E0F2B8CBD3 sha1 4CA8A77C95530879B175A2EC9A792485AE18E83C ) + rom ( name "Genki Bakuhatsu Gambaruger (Japan).gb" size 131072 crc 6226d280 sha1 4CA8A77C95530879B175A2EC9A792485AE18E83C ) ) game ( name "George Foreman's KO Boxing (USA, Europe)" description "George Foreman's KO Boxing (USA, Europe)" - rom ( name "George Foreman's KO Boxing (USA, Europe).gb" size 131072 crc 7F62456B md5 8A4245CBEB1D6400B4CB586790400B60 sha1 01E923706486C75B2D0A438D968C5D571B2FDF1C flags verified ) + rom ( name "George Foreman's KO Boxing (USA, Europe).gb" size 131072 crc 7f62456b sha1 01E923706486C75B2D0A438D968C5D571B2FDF1C flags verified ) ) game ( - name "Getaway, The (USA)" - description "Getaway, The (USA)" - rom ( name "Getaway, The (USA).gb" size 262144 crc 8F2BF517 md5 033C219483EC7766517C94635B3A43F8 sha1 A0CA7187B55135150F348D44544D3A6E6D51394E ) + name "Gerry Anderson's Thunderbirds (Japan)" + description "Gerry Anderson's Thunderbirds (Japan)" + rom ( name "Gerry Anderson's Thunderbirds (Japan).gb" size 131072 crc 149e9393 sha1 440169376982AA89CEDDE08EDBC9EFDFAFC6C7F1 ) +) + +game ( + name "Getaway, The - High Speed II (USA)" + description "Getaway, The - High Speed II (USA)" + rom ( name "Getaway, The - High Speed II (USA).gb" size 262144 crc 8f2bf517 sha1 A0CA7187B55135150F348D44544D3A6E6D51394E ) ) game ( name "Ghostbusters II (Japan)" description "Ghostbusters II (Japan)" - rom ( name "Ghostbusters II (Japan).gb" size 131072 crc 69B161BC md5 4067F70F9DEF39CEB49A258540CE3D66 sha1 0CA645C40CA8DC6102B4F3CF56F0E9AE5D1FFC03 flags verified ) + rom ( name "Ghostbusters II (Japan).gb" size 131072 crc 69b161bc sha1 0CA645C40CA8DC6102B4F3CF56F0E9AE5D1FFC03 flags verified ) ) game ( name "Ghostbusters II (USA, Europe)" description "Ghostbusters II (USA, Europe)" - rom ( name "Ghostbusters II (USA, Europe).gb" size 131072 crc 5821ECD4 md5 0841A527B116A52AD26DE023B20B1A42 sha1 1E2AA42B7E0F974F45FBCA35160CDA6D5964F0AD flags verified ) + rom ( name "Ghostbusters II (USA, Europe).gb" size 131072 crc 5821ecd4 sha1 1E2AA42B7E0F974F45FBCA35160CDA6D5964F0AD flags verified ) ) game ( name "GI King! - Sanbiki no Yosouya (Japan)" description "GI King! - Sanbiki no Yosouya (Japan)" - rom ( name "GI King! - Sanbiki no Yosouya (Japan).gb" size 65536 crc 150BC291 md5 894DC0498B1527DEDDF7C6FCC75A6B25 sha1 DE6109B643A97E7A96E55A6BECFD7E61DFDC915E flags verified ) + rom ( name "GI King! - Sanbiki no Yosouya (Japan).gb" size 65536 crc 150bc291 sha1 DE6109B643A97E7A96E55A6BECFD7E61DFDC915E flags verified ) ) game ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja)" description "Ginga - Card & Puzzle Collection (Japan) (En,Ja)" - rom ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja).gb" size 65536 crc 87D0637B md5 49EFF735E839F8A57F75AFCBF2C11AE4 sha1 14F4F14CAEE081DCEADB9D31AE26FD8968C432EA flags verified ) + rom ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja).gb" size 65536 crc 87d0637b sha1 14F4F14CAEE081DCEADB9D31AE26FD8968C432EA flags verified ) ) game ( name "Gluecksrad (Germany)" description "Gluecksrad (Germany)" - rom ( name "Gluecksrad (Germany).gb" size 131072 crc E8B26577 md5 060CAA70249D12DA3CF53D6D48323B08 sha1 638CD5087B53B7FE7C6ECE99FD973F98C0C09EBE flags verified ) + rom ( name "Gluecksrad (Germany).gb" size 131072 crc e8b26577 sha1 638CD5087B53B7FE7C6ECE99FD973F98C0C09EBE flags verified ) ) game ( name "Go Go Ackman (Japan) (SGB Enhanced)" description "Go Go Ackman (Japan) (SGB Enhanced)" - rom ( name "Go Go Ackman (Japan) (SGB Enhanced).gb" size 262144 crc 61D80946 md5 D6665854FDFE6D6D34C03B56D641D193 sha1 28CE08F67B4FB26E7A5A46F853B053D20EC9D7CD flags verified ) + rom ( name "Go Go Ackman (Japan) (SGB Enhanced).gb" size 262144 crc 61d80946 sha1 28CE08F67B4FB26E7A5A46F853B053D20EC9D7CD flags verified ) ) game ( name "Go! Go! Hitchhike (Japan) (SGB Enhanced)" description "Go! Go! Hitchhike (Japan) (SGB Enhanced)" - rom ( name "Go! Go! Hitchhike (Japan) (SGB Enhanced).gb" size 524288 crc 845735DE md5 25693D62F14011ED543A273E34E92CE5 sha1 6A35BC2967F25FDA0626B7A00A2CACFEC9C53278 flags verified ) + rom ( name "Go! Go! Hitchhike (Japan) (SGB Enhanced).gb" size 524288 crc 845735de sha1 6A35BC2967F25FDA0626B7A00A2CACFEC9C53278 flags verified ) ) game ( name "Go! Go! Tank (Japan)" description "Go! Go! Tank (Japan)" - rom ( name "Go! Go! Tank (Japan).gb" size 65536 crc 30AE39B6 md5 D7BC88E01B7722082B3A5AE729DE170E sha1 6A60D5B550355E634BA54D8BD83B51CA55D6874B flags verified ) + rom ( name "Go! Go! Tank (Japan).gb" size 65536 crc 30ae39b6 sha1 6A60D5B550355E634BA54D8BD83B51CA55D6874B flags verified ) ) game ( name "Go! Go! Tank (USA)" description "Go! Go! Tank (USA)" - rom ( name "Go! Go! Tank (USA).gb" size 65536 crc 65DFABCB md5 23824D72928A05E9FCF052D42F3C91C6 sha1 7F3408C951A161F93394812D34F6D2534658B7D3 flags verified ) + rom ( name "Go! Go! Tank (USA).gb" size 65536 crc 65dfabcb sha1 7F3408C951A161F93394812D34F6D2534658B7D3 flags verified ) +) + +game ( + name "Go! Go! Tank (Japan) (Beta)" + description "Go! Go! Tank (Japan) (Beta)" + rom ( name "Go! Go! Tank (Japan) (Beta).gb" size 65536 crc 6dcf5e7f sha1 18BBEE226858AF45A81F7DA1186938F53511EF73 flags verified ) ) game ( name "Goal! (Europe)" description "Goal! (Europe)" - rom ( name "Goal! (Europe).gb" size 131072 crc 533FA979 md5 613C2336E19EA8F958F66C3E7DFEF3C5 sha1 24FFFA3DB4153895546A346A38971B6946011679 ) + rom ( name "Goal! (Europe).gb" size 131072 crc 533fa979 sha1 24FFFA3DB4153895546A346A38971B6946011679 ) ) game ( name "Goal! (USA)" description "Goal! (USA)" - rom ( name "Goal! (USA).gb" size 131072 crc 00D4CAF2 md5 009AEA0AC7F214FF6F3C8C070D4A6421 sha1 9BB15769B2674D41075B45256DBFFFC18483FD84 ) + rom ( name "Goal! (USA).gb" size 131072 crc 00d4caf2 sha1 9BB15769B2674D41075B45256DBFFFC18483FD84 ) ) game ( name "God Medicine - Fantasy Sekai no Tanjou (Japan)" description "God Medicine - Fantasy Sekai no Tanjou (Japan)" - rom ( name "God Medicine - Fantasy Sekai no Tanjou (Japan).gb" size 262144 crc A1B29AB8 md5 52E110882A9F42C8B5C97489A29005F5 sha1 B365CD58D133C2B441BBF53C2E5FF9486BBF0BDE ) + rom ( name "God Medicine - Fantasy Sekai no Tanjou (Japan).gb" size 262144 crc a1b29ab8 sha1 B365CD58D133C2B441BBF53C2E5FF9486BBF0BDE ) ) game ( name "God Medicine - Fukkokuban (Japan) (SGB Enhanced)" description "God Medicine - Fukkokuban (Japan) (SGB Enhanced)" - rom ( name "God Medicine - Fukkokuban (Japan) (SGB Enhanced).gb" size 524288 crc 847E0772 md5 4057131CB9CEDFB2FCDBC36904E7896D sha1 61D3579293BF07166402D11D891E14BFD6FEF6B4 flags verified ) + rom ( name "God Medicine - Fukkokuban (Japan) (SGB Enhanced).gb" size 524288 crc 847e0772 sha1 61D3579293BF07166402D11D891E14BFD6FEF6B4 flags verified ) ) game ( name "Godzilla (USA, Europe)" description "Godzilla (USA, Europe)" - rom ( name "Godzilla (USA, Europe).gb" size 131072 crc FE4F80B7 md5 E83411ADCCF5266F2DEB263E67B68BC1 sha1 C0FA19386AA1E325AF42E8DD2CAF8E66112B9578 flags verified ) + rom ( name "Godzilla (USA, Europe).gb" size 131072 crc fe4f80b7 sha1 C0FA19386AA1E325AF42E8DD2CAF8E66112B9578 flags verified ) ) game ( - name "Gojira-kun (Japan)" - description "Gojira-kun (Japan)" - rom ( name "Gojira-kun (Japan).gb" size 131072 crc ED204600 md5 259AA674AC5634E47A642D024CFBDC66 sha1 4C03DA759E5FB2EC06D286D5F0B52D64621FEA41 ) + name "Gojira-kun - Kaijuu Daikoushin (Japan)" + description "Gojira-kun - Kaijuu Daikoushin (Japan)" + rom ( name "Gojira-kun - Kaijuu Daikoushin (Japan).gb" size 131072 crc ed204600 sha1 4C03DA759E5FB2EC06D286D5F0B52D64621FEA41 ) ) game ( name "Golf (World)" description "Golf (World)" - rom ( name "Golf (World).gb" size 131072 crc 6ED10383 md5 6175A5EF55A1998944267E75D8EBF79D sha1 2ACEE1A14BA611E73B0B7D6BCE170107213FCC0C flags verified ) + rom ( name "Golf (World).gb" size 131072 crc 6ed10383 sha1 2ACEE1A14BA611E73B0B7D6BCE170107213FCC0C flags verified ) ) game ( name "Golf Classic (Europe) (SGB Enhanced)" description "Golf Classic (Europe) (SGB Enhanced)" - rom ( name "Golf Classic (Europe) (SGB Enhanced).gb" size 262144 crc A6DADB1E md5 4B49017D182635C587EF2E3001769785 sha1 B7FFB77A5061C33B0BBE5B074C1526E46C5EB7C3 flags verified ) + rom ( name "Golf Classic (Europe) (SGB Enhanced).gb" size 262144 crc a6dadb1e sha1 B7FFB77A5061C33B0BBE5B074C1526E46C5EB7C3 flags verified ) ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Special Edition)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Special Edition)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Special Edition).gb" size 1048576 crc 5D43A385 md5 D4088D3239A9291E4E7BDB2119AD7708 sha1 D367F2DAB5EACB10E785A13A2550CA7CC3E54177 ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (Imagineer).gb" size 1048576 crc 5d43a385 sha1 D367F2DAB5EACB10E785A13A2550CA7CC3E54177 flags verified ) ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan).gb" size 1048576 crc 26772E04 md5 FA54481D628D2FC1F5DA2FB3C3368C0B sha1 A6AB7420A2D69D62338BC03DC4E0E46B0DC8429B flags verified ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (IE Institute)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (IE Institute)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Joushiki no Sho (Japan) (IE Institute).gb" size 1048576 crc 26772e04 sha1 A6AB7420A2D69D62338BC03DC4E0E46B0DC8429B flags verified ) ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Special Edition)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Special Edition)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Special Edition).gb" size 1048576 crc 62B00F69 md5 E0B9DD8E504EC8E44D15B2BD0D8901A6 sha1 1D3E5AD888B8339E35C46455D84017D8A0D69C6D flags verified ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Imagineer)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Imagineer)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (Imagineer).gb" size 1048576 crc 62b00f69 sha1 1D3E5AD888B8339E35C46455D84017D8A0D69C6D flags verified ) ) game ( - name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan)" - description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan).gb" size 1048576 crc 71ACBB67 md5 1905FF1A339E777237EDC66B59969F4C sha1 E2AC91493248869ABA6B7D26A36E5FF6BD6D6F5A flags verified ) + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Kanji no Tatsujin (Japan) (IE Institute).gb" size 1048576 crc 180d54a7 sha1 7DCE0ADCBAC61F0CAAE33646847FD06CED8C8B67 flags verified ) +) + +game ( + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (Imagineer).gb" size 1048576 crc 71acbb67 sha1 E2AC91493248869ABA6B7D26A36E5FF6BD6D6F5A flags verified ) +) + +game ( + name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (IE Institute)" + description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (IE Institute)" + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Keisan no Tatsujin (Japan) (IE Institute).gb" size 1048576 crc 04214f92 sha1 6B8726C69A31E674A4C5AB02631DE073D42E7D52 flags verified ) ) game ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan)" description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan).gb" size 1048576 crc 3C907F2C md5 5AA4ECE6D3FD99E7CE0682B92C55D25B sha1 FA7A40ACD835676FBCAE9507A8AAAF1191F9B1CD flags verified ) + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Nanmon no Sho (Japan).gb" size 1048576 crc 3c907f2c sha1 FA7A40ACD835676FBCAE9507A8AAAF1191F9B1CD flags verified ) ) game ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan)" description "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan)" - rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan).gb" size 1048576 crc 479E2C18 md5 0482EFB6AFA8EF213F7FE92510CA3ADE sha1 630A331A3C89823647FBDA13235B6299D91A1B25 ) + rom ( name "Goukaku Boy GOLD - Shikakui Atama o Maruku Suru - Zukei no Tatsujin (Japan).gb" size 1048576 crc 479e2c18 sha1 630A331A3C89823647FBDA13235B6299D91A1B25 flags verified ) ) game ( name "Goukaku Boy Series - 99 Nendo Ban Eitango Center 1500 (Japan)" description "Goukaku Boy Series - 99 Nendo Ban Eitango Center 1500 (Japan)" - rom ( name "Goukaku Boy Series - 99 Nendo Ban Eitango Center 1500 (Japan).gb" size 262144 crc 9C0D14C3 md5 6A10EB4A1D02D21C0B2A865D464246C3 sha1 B9E79E032F4D65442DAA37767BE5238A84C103DB ) + rom ( name "Goukaku Boy Series - 99 Nendo Ban Eitango Center 1500 (Japan).gb" size 262144 crc 9c0d14c3 sha1 B9E79E032F4D65442DAA37767BE5238A84C103DB ) ) game ( name "Goukaku Boy Series - Eijukugo Target 1000 (Japan)" description "Goukaku Boy Series - Eijukugo Target 1000 (Japan)" - rom ( name "Goukaku Boy Series - Eijukugo Target 1000 (Japan).gb" size 262144 crc CA20C594 md5 CC6419598044961237496D3AF7F18D58 sha1 535FBF6988AF70C4283D8101C72ACB67D249BB96 flags verified ) + rom ( name "Goukaku Boy Series - Eijukugo Target 1000 (Japan).gb" size 262144 crc ca20c594 sha1 535FBF6988AF70C4283D8101C72ACB67D249BB96 flags verified ) ) game ( name "Goukaku Boy Series - Eiken 2kyuu Level no Kaiwa Hyougen 333 (Japan)" description "Goukaku Boy Series - Eiken 2kyuu Level no Kaiwa Hyougen 333 (Japan)" - rom ( name "Goukaku Boy Series - Eiken 2kyuu Level no Kaiwa Hyougen 333 (Japan).gb" size 262144 crc 46AF90DA md5 1BFC3E94193D95C4E1145FD6CBF8FD1B sha1 E58D4DC3E8B5F0407F156C5D252D34B40E7DFEC0 ) + rom ( name "Goukaku Boy Series - Eiken 2kyuu Level no Kaiwa Hyougen 333 (Japan).gb" size 262144 crc 46af90da sha1 E58D4DC3E8B5F0407F156C5D252D34B40E7DFEC0 ) ) game ( name "Goukaku Boy Series - Eitango Target 1900 (Japan)" description "Goukaku Boy Series - Eitango Target 1900 (Japan)" - rom ( name "Goukaku Boy Series - Eitango Target 1900 (Japan).gb" size 262144 crc F8406560 md5 75143DC6628B92B1EAAF72B39891506C sha1 C5F885C9C6B7AB89646B4C17B6FF83B2DFE67A04 flags verified ) + rom ( name "Goukaku Boy Series - Eitango Target 1900 (Japan).gb" size 262144 crc f8406560 sha1 C5F885C9C6B7AB89646B4C17B6FF83B2DFE67A04 flags verified ) ) game ( name "Goukaku Boy Series - Gakken - Kanyouku Kotowaza 210 (Japan)" description "Goukaku Boy Series - Gakken - Kanyouku Kotowaza 210 (Japan)" - rom ( name "Goukaku Boy Series - Gakken - Kanyouku Kotowaza 210 (Japan).gb" size 262144 crc 44F5A443 md5 290BE7FD63076E4373F322900542C1B1 sha1 19A6F8C7A98B84B9B0BF53C25DBBA02C438C1822 ) + rom ( name "Goukaku Boy Series - Gakken - Kanyouku Kotowaza 210 (Japan).gb" size 262144 crc 44f5a443 sha1 19A6F8C7A98B84B9B0BF53C25DBBA02C438C1822 ) ) game ( name "Goukaku Boy Series - Gakken - Rekishi 512 (Japan)" description "Goukaku Boy Series - Gakken - Rekishi 512 (Japan)" - rom ( name "Goukaku Boy Series - Gakken - Rekishi 512 (Japan).gb" size 262144 crc 10BD83BA md5 3701CF0841B45C7B2C546FC4E303AAF1 sha1 AB7733C04BC7975312B0CBE75D8D9B2519AC35AE flags verified ) + rom ( name "Goukaku Boy Series - Gakken - Rekishi 512 (Japan).gb" size 262144 crc 10bd83ba sha1 AB7733C04BC7975312B0CBE75D8D9B2519AC35AE flags verified ) ) game ( name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan)" description "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan)" - rom ( name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan).gb" size 262144 crc 631A752E md5 B2C2367B5A3E6A483C147DEBEC006508 sha1 DF253AFB9C01615AD8219730573321A40FB5E230 ) + rom ( name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan).gb" size 262144 crc 631a752e sha1 DF253AFB9C01615AD8219730573321A40FB5E230 flags verified ) ) game ( - name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev A)" - description "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev A)" - rom ( name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev A).gb" size 262144 crc C8E01C7C md5 7D3BFF19F269A9B0C52338CCD0E654AE sha1 7DF1D7B389814C6DE2A1B201A00C71316B0AC856 flags verified ) + name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev 1)" + description "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev 1)" + rom ( name "Goukaku Boy Series - Gakken - Yojijukugo 288 (Japan) (Rev 1).gb" size 262144 crc c8e01c7c sha1 7DF1D7B389814C6DE2A1B201A00C71316B0AC856 flags verified ) ) game ( name "Goukaku Boy Series - Kirihara Shoten Hinshutsu Eibunpou Gohou Mondai 1000 (Japan)" description "Goukaku Boy Series - Kirihara Shoten Hinshutsu Eibunpou Gohou Mondai 1000 (Japan)" - rom ( name "Goukaku Boy Series - Kirihara Shoten Hinshutsu Eibunpou Gohou Mondai 1000 (Japan).gb" size 262144 crc 41C17421 md5 D8F049E77238C17C5A91AEF2BF300180 sha1 134A9D7A276B8EF2ED698075E0990D0553FFBF73 ) + rom ( name "Goukaku Boy Series - Kirihara Shoten Hinshutsu Eibunpou Gohou Mondai 1000 (Japan).gb" size 262144 crc 41c17421 sha1 134A9D7A276B8EF2ED698075E0990D0553FFBF73 ) ) game ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eijukugo 350 (Japan)" description "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eijukugo 350 (Japan)" - rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eijukugo 350 (Japan).gb" size 262144 crc E4271F4B md5 B4981DDAB0CB1574701E7F1DAE333861 sha1 02BAAF987249F2DAF9DAA6D6000E61ADC05B0EF6 flags verified ) + rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eijukugo 350 (Japan).gb" size 262144 crc e4271f4b sha1 02BAAF987249F2DAF9DAA6D6000E61ADC05B0EF6 flags verified ) ) game ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eitango 1700 (Japan)" description "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eitango 1700 (Japan)" - rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eitango 1700 (Japan).gb" size 262144 crc D3168ECA md5 996F21D850FA8D9B8B15205493976650 sha1 2E30D41E3783DA4D3F6BB928C54C0E243F63E4CA flags verified ) + rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Chuugaku Eitango 1700 (Japan).gb" size 262144 crc d3168eca sha1 2E30D41E3783DA4D3F6BB928C54C0E243F63E4CA flags verified ) ) game ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Kanji Mondai no Seifuku (Japan)" description "Goukaku Boy Series - Koukou Nyuushi Derujun - Kanji Mondai no Seifuku (Japan)" - rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Kanji Mondai no Seifuku (Japan).gb" size 262144 crc 84E30E6C md5 230B96E98D05CF0385CFAA5B75F1735C sha1 2185BBB4868058577FBE696B9A88FA7238CE7098 ) + rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Kanji Mondai no Seifuku (Japan).gb" size 262144 crc 84e30e6c sha1 2185BBB4868058577FBE696B9A88FA7238CE7098 ) ) game ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rekishi Nendai Anki Point 240 (Japan)" description "Goukaku Boy Series - Koukou Nyuushi Derujun - Rekishi Nendai Anki Point 240 (Japan)" - rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rekishi Nendai Anki Point 240 (Japan).gb" size 262144 crc 7E262A4D md5 F98A6CE8E8065E351693098E906BD32E sha1 D969DBC0CF3E5D427726BF749D082B89E171354B ) + rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rekishi Nendai Anki Point 240 (Japan).gb" size 262144 crc 7e262a4d sha1 D969DBC0CF3E5D427726BF749D082B89E171354B ) ) game ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rika Anki Point 250 (Japan)" description "Goukaku Boy Series - Koukou Nyuushi Derujun - Rika Anki Point 250 (Japan)" - rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rika Anki Point 250 (Japan).gb" size 262144 crc 70468755 md5 DE64A15FB90FAE1C179A0D32A5EB1390 sha1 B96ACB6454BA916AD5DF2256F9A0A8022CDBFF3B flags verified ) + rom ( name "Goukaku Boy Series - Koukou Nyuushi Derujun - Rika Anki Point 250 (Japan).gb" size 262144 crc 70468755 sha1 B96ACB6454BA916AD5DF2256F9A0A8022CDBFF3B flags verified ) ) game ( name "Goukaku Boy Series - Nihonshi Target 201 (Japan)" description "Goukaku Boy Series - Nihonshi Target 201 (Japan)" - rom ( name "Goukaku Boy Series - Nihonshi Target 201 (Japan).gb" size 262144 crc CF133379 md5 E22A670567858F46060C047DEFA01818 sha1 D6178851D778BF794A0FCE14A831F6E2CD991F22 ) + rom ( name "Goukaku Boy Series - Nihonshi Target 201 (Japan).gb" size 262144 crc cf133379 sha1 D6178851D778BF794A0FCE14A831F6E2CD991F22 flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan).gb" size 262144 crc 8BD567D1 md5 DDCE618F0A986B96960BC5F6F69E3415 sha1 75009AC4A2114B4CEAC3E4BC7E6C3F3173292BF0 flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Imagineer)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Imagineer)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Imagineer).gb" size 262144 crc 8bd567d1 sha1 75009AC4A2114B4CEAC3E4BC7E6C3F3173292BF0 flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Special Edition)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Special Edition)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (Special Edition).gb" size 262144 crc 7E6E16D5 md5 2232EE0598C7B953B38B1BF4F7BF8ECF sha1 3FC9C1BC1D3B8E7EE90C14D4AE4938726F61A2DB flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (IE Institute)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (IE Institute)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Kokugo Battle Hen (Japan) (IE Institute).gb" size 262144 crc 7e6e16d5 sha1 3FC9C1BC1D3B8E7EE90C14D4AE4938726F61A2DB flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Special Edition)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Special Edition)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Special Edition).gb" size 262144 crc 62AA54A4 md5 DDD4C08B975E78D77B00B56B85A7862D sha1 4569F5CC0F528FDF46CFD1B3A8EF8A6FD3953D7E flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Imagineer)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Imagineer)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (Imagineer).gb" size 262144 crc c34ae38f sha1 FA92AD7099A6C698088433D7721FD1E87B2B925D flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan).gb" size 262144 crc C34AE38F md5 B8AD678F5F1E8A7F498B04A6257B3108 sha1 FA92AD7099A6C698088433D7721FD1E87B2B925D flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (IE Institute)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (IE Institute)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Rika Battle Hen (Japan) (IE Institute).gb" size 262144 crc 62aa54a4 sha1 4569F5CC0F528FDF46CFD1B3A8EF8A6FD3953D7E flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan).gb" size 262144 crc 0DADB829 md5 833C2C1990EAB0F9F09A6471FFEB24DE sha1 A10E78F3FE2C46E167D39ED713106937365A6D55 flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Imagineer)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Imagineer)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Imagineer).gb" size 262144 crc 0dadb829 sha1 A10E78F3FE2C46E167D39ED713106937365A6D55 flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Special Edition)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Special Edition)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (Special Edition).gb" size 262144 crc DE74FD69 md5 53CAA3D63F1DB9059CABE555E18CF2FF sha1 1E0FE5A54B4EB03A1F108D8650AD5EF8814D7444 flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (IE Institute)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (IE Institute)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Sansuu Battle Hen (Japan) (IE Institute).gb" size 262144 crc de74fd69 sha1 1E0FE5A54B4EB03A1F108D8650AD5EF8814D7444 flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Special Edition)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Special Edition)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Special Edition).gb" size 262144 crc 8BA62B3D md5 45CB9CD406F53033E0FBFC5413797192 sha1 DFDCABDC06B74F896B9EF47DB2A9CC49DDB104C4 flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Imagineer)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Imagineer)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (Imagineer).gb" size 262144 crc 87f0cfad sha1 EDFC194F9F58EF97DFE87092EEBD4C73359925E1 flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan).gb" size 262144 crc 87F0CFAD md5 1C04158B8C2408523620E73D88B0D8D5 sha1 EDFC194F9F58EF97DFE87092EEBD4C73359925E1 flags verified ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (IE Institute)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (IE Institute)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Shakai Battle Hen (Japan) (IE Institute).gb" size 262144 crc 8ba62b3d sha1 DFDCABDC06B74F896B9EF47DB2A9CC49DDB104C4 flags verified ) ) game ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan)" description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan).gb" size 262144 crc F141B2DC md5 2E5943F9E984FA4AED26542EACF2D9F4 sha1 02DDCAEF0008871786797FC76C649D74F010718D flags verified ) + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan).gb" size 262144 crc f141b2dc sha1 02DDCAEF0008871786797FC76C649D74F010718D flags verified ) ) game ( - name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev A)" - description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev A)" - rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev A).gb" size 262144 crc 74821248 md5 20477830FCDBE53EBAE93A2AE90C72C9 sha1 B1626C1FE162A7B0292D292E8BA60A1C6823FC8D ) + name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev 1)" + description "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev 1)" + rom ( name "Goukaku Boy Series - Shikakui Atama o Maruku Suru - Suuji de Asobou Sansuu Hen (Japan) (Rev 1).gb" size 262144 crc 74821248 sha1 B1626C1FE162A7B0292D292E8BA60A1C6823FC8D ) ) game ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Nihonshi B Yougo Mondaishuu (Japan)" description "Goukaku Boy Series - Yamakawa Ichimonittou - Nihonshi B Yougo Mondaishuu (Japan)" - rom ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Nihonshi B Yougo Mondaishuu (Japan).gb" size 524288 crc A09C1790 md5 4CFA25F0CC297FD5F98FAA1DDAE083F0 sha1 6611ADC52FAA628BBC36CDC759D7C18B00316BA4 flags verified ) + rom ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Nihonshi B Yougo Mondaishuu (Japan).gb" size 524288 crc a09c1790 sha1 6611ADC52FAA628BBC36CDC759D7C18B00316BA4 flags verified ) ) game ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Sekaishi B Yougo Mondaishuu (Japan)" description "Goukaku Boy Series - Yamakawa Ichimonittou - Sekaishi B Yougo Mondaishuu (Japan)" - rom ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Sekaishi B Yougo Mondaishuu (Japan).gb" size 524288 crc D185B939 md5 51DE6F0697D2BBC53CCB5727DCDC884B sha1 33E651BBCCDA46AB395B6609810EE175B5CFACEA ) + rom ( name "Goukaku Boy Series - Yamakawa Ichimonittou - Sekaishi B Yougo Mondaishuu (Japan).gb" size 524288 crc d185b939 sha1 33E651BBCCDA46AB395B6609810EE175B5CFACEA ) ) game ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Chuugaku Eitango 1132 (Japan)" description "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Chuugaku Eitango 1132 (Japan)" - rom ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Chuugaku Eitango 1132 (Japan).gb" size 262144 crc DC010F04 md5 7E05D529985B34741BF1C8B909C96D8A sha1 A5F3E531B8BECF0FA218D73D21C3775265DF607E flags verified ) + rom ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Chuugaku Eitango 1132 (Japan).gb" size 262144 crc dc010f04 sha1 A5F3E531B8BECF0FA218D73D21C3775265DF607E flags verified ) ) game ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Kyuukyoku no Kobun Tango (Japan)" description "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Kyuukyoku no Kobun Tango (Japan)" - rom ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Kyuukyoku no Kobun Tango (Japan).gb" size 262144 crc 99062C13 md5 B55A747B3674C0C330C143EE715B1A6A sha1 E105F4D680FBF0621997AA2F9CE05CB0651A9EE9 flags verified ) + rom ( name "Goukaku Boy Series - Z Kai (Reibun de Oboeru) Kyuukyoku no Kobun Tango (Japan).gb" size 262144 crc 99062c13 sha1 E105F4D680FBF0621997AA2F9CE05CB0651A9EE9 flags verified ) ) game ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eigo Koubun 285 (Japan)" description "Goukaku Boy Series - Z Kai Kyuukyoku no Eigo Koubun 285 (Japan)" - rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eigo Koubun 285 (Japan).gb" size 262144 crc D792F747 md5 704C6F2D6EABF59ADA905613C06CCA5B sha1 4D0D8BF6CBAEF902C5855513531203B756DEB93F ) + rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eigo Koubun 285 (Japan).gb" size 262144 crc d792f747 sha1 4D0D8BF6CBAEF902C5855513531203B756DEB93F ) ) game ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eijukugo 1017 (Japan)" description "Goukaku Boy Series - Z Kai Kyuukyoku no Eijukugo 1017 (Japan)" - rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eijukugo 1017 (Japan).gb" size 262144 crc 12E738EA md5 B1871E07C180925C0D196CF3A5FEA020 sha1 BA02B31919422226D22F89E59DF90AB060B046C9 ) + rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eijukugo 1017 (Japan).gb" size 262144 crc 12e738ea sha1 BA02B31919422226D22F89E59DF90AB060B046C9 ) ) game ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eitango 1500 (Japan)" description "Goukaku Boy Series - Z Kai Kyuukyoku no Eitango 1500 (Japan)" - rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eitango 1500 (Japan).gb" size 262144 crc 3FAC5C42 md5 B251D6A81102315A0965281653B1AE36 sha1 F439497B513262D2C98B622AF1A00F4EFD8650A6 flags verified ) + rom ( name "Goukaku Boy Series - Z Kai Kyuukyoku no Eitango 1500 (Japan).gb" size 262144 crc 3fac5c42 sha1 F439497B513262D2C98B622AF1A00F4EFD8650A6 flags verified ) ) game ( name "Gradius - The Interstellar Assault (USA)" description "Gradius - The Interstellar Assault (USA)" - rom ( name "Gradius - The Interstellar Assault (USA).gb" size 262144 crc 90F87D57 md5 E10F788DA29E18934C3E9161B25B96C7 sha1 7A50FDF0B8AD15556C933DF0657FAE0A2CD8BC92 ) + rom ( name "Gradius - The Interstellar Assault (USA).gb" size 262144 crc 90f87d57 sha1 7A50FDF0B8AD15556C933DF0657FAE0A2CD8BC92 flags verified ) ) game ( name "Grander Musashi RV (Japan) (SGB Enhanced)" description "Grander Musashi RV (Japan) (SGB Enhanced)" - rom ( name "Grander Musashi RV (Japan) (SGB Enhanced).gb" size 524288 crc E97F2E9A md5 B80FC4C1AA83F4F57CD8E0378287FFD4 sha1 D6FC45FD02E3D7C885C0E0244DC3C8073FB64FF4 flags verified ) + rom ( name "Grander Musashi RV (Japan) (SGB Enhanced).gb" size 524288 crc e97f2e9a sha1 D6FC45FD02E3D7C885C0E0244DC3C8073FB64FF4 flags verified ) ) game ( name "Great Greed (USA)" description "Great Greed (USA)" - rom ( name "Great Greed (USA).gb" size 262144 crc C4CBF6B1 md5 B83F33F33AB52E0B7EE80715DBB8D415 sha1 9D7DE25431F3E31F244925E317E3D0933F5EFA2E flags verified ) + rom ( name "Great Greed (USA).gb" size 262144 crc c4cbf6b1 sha1 9D7DE25431F3E31F244925E317E3D0933F5EFA2E flags verified ) ) game ( name "Gremlins 2 - The New Batch (World)" description "Gremlins 2 - The New Batch (World)" - rom ( name "Gremlins 2 - The New Batch (World).gb" size 131072 crc 3579E297 md5 F59DBCE4CF5B51A5241806E1B35301FB sha1 0CB722D9D4E349BEA1B1AFA85D8D3B93F2DC2AAD flags verified ) + rom ( name "Gremlins 2 - The New Batch (World).gb" size 131072 crc 3579e297 sha1 0CB722D9D4E349BEA1B1AFA85D8D3B93F2DC2AAD flags verified ) ) game ( name "HAL Wrestling (USA)" description "HAL Wrestling (USA)" - rom ( name "HAL Wrestling (USA).gb" size 131072 crc 5E4A61D3 md5 7AC8443EEFC33432B989F00CB984B9A1 sha1 861F1CD6EA513A003AB8364B37FA73C63B555E38 flags verified ) + rom ( name "HAL Wrestling (USA).gb" size 131072 crc 5e4a61d3 sha1 861F1CD6EA513A003AB8364B37FA73C63B555E38 flags verified ) ) game ( name "HAL Wrestling (USA) (Beta)" description "HAL Wrestling (USA) (Beta)" - rom ( name "HAL Wrestling (USA) (Beta).gb" size 131072 crc B02FAA0B md5 9AF91C7E344A9048F0F4037A8ABCBE54 sha1 6AC35A017FD1F61C19086765107E3940426A2A66 ) + rom ( name "HAL Wrestling (USA) (Beta).gb" size 131072 crc b02faa0b sha1 6AC35A017FD1F61C19086765107E3940426A2A66 ) ) game ( name "Hammerin' Harry - Ghost Building Company (Europe)" description "Hammerin' Harry - Ghost Building Company (Europe)" - rom ( name "Hammerin' Harry - Ghost Building Company (Europe).gb" size 262144 crc 9F09AFE8 md5 131993B986F3BA1F682D8D74F050487B sha1 05490AB94AE5E01DD02B4A578BFCCC5647816408 ) + rom ( name "Hammerin' Harry - Ghost Building Company (Europe).gb" size 262144 crc 9f09afe8 sha1 05490AB94AE5E01DD02B4A578BFCCC5647816408 ) ) game ( name "Harvest Moon GB (USA) (SGB Enhanced)" description "Harvest Moon GB (USA) (SGB Enhanced)" - rom ( name "Harvest Moon GB (USA) (SGB Enhanced).gb" size 524288 crc 1EAE0E10 md5 7EF69878C3B5BC5532C69A51A2DD42F3 sha1 5B85D2ACCD3877E80D73A7AD19D9F55C288F43CC ) + rom ( name "Harvest Moon GB (USA) (SGB Enhanced).gb" size 524288 crc 1eae0e10 sha1 5B85D2ACCD3877E80D73A7AD19D9F55C288F43CC ) ) game ( name "Hatris (Japan, USA)" description "Hatris (Japan, USA)" - rom ( name "Hatris (Japan, USA).gb" size 65536 crc 7635F28B md5 B9D3D91D8389CC510AA8FE9063228644 sha1 E8002F226E90ED52E1675C003D3C8CE804B56B0E ) + rom ( name "Hatris (Japan, USA).gb" size 65536 crc 7635f28b sha1 E8002F226E90ED52E1675C003D3C8CE804B56B0E ) ) game ( name "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced)" description "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced)" - rom ( name "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced).gb" size 524288 crc 60727BF9 md5 DA7F9623E0D544196747CFD2B79B5E78 sha1 7F0010677E3052C6B9CAF41714E87D285AD45A91 flags verified ) + rom ( name "Hayaoshi Quiz - Ouza Ketteisen (Japan) (SGB Enhanced).gb" size 524288 crc 60727bf9 sha1 7F0010677E3052C6B9CAF41714E87D285AD45A91 flags verified ) ) game ( name "Head On (Japan)" description "Head On (Japan)" - rom ( name "Head On (Japan).gb" size 65536 crc 78830DAF md5 3353653E75B9110AFDD37452B27CD312 sha1 76261091ADB7DEF20A4F76AA6C062C60C6D9761C flags verified ) + rom ( name "Head On (Japan).gb" size 65536 crc 78830daf sha1 76261091ADB7DEF20A4F76AA6C062C60C6D9761C flags verified ) ) game ( name "Heavyweight Championship Boxing (USA)" description "Heavyweight Championship Boxing (USA)" - rom ( name "Heavyweight Championship Boxing (USA).gb" size 65536 crc 1526A96B md5 1F8089CA53D6E9AFF6D1907710D28BC8 sha1 1D6F1AFED7CE7A90A07219449D4D3B679AFEDA6B flags verified ) + rom ( name "Heavyweight Championship Boxing (USA).gb" size 65536 crc 1526a96b sha1 1D6F1AFED7CE7A90A07219449D4D3B679AFEDA6B flags verified ) ) game ( name "Heiankyo Alien (USA)" description "Heiankyo Alien (USA)" - rom ( name "Heiankyo Alien (USA).gb" size 32768 crc 1495BBE5 md5 B236E81E9F5C19148C24C4984D8EF90F sha1 7372E49DBE5CBB25B8201F52CA544737D06E0FB6 flags verified ) + rom ( name "Heiankyo Alien (USA).gb" size 32768 crc 1495bbe5 sha1 7372E49DBE5CBB25B8201F52CA544737D06E0FB6 flags verified ) ) game ( name "Heiankyou Alien (Japan)" description "Heiankyou Alien (Japan)" - rom ( name "Heiankyou Alien (Japan).gb" size 32768 crc 08BF29C9 md5 3D02CB66BDEEA139AAA1F9D91D092A21 sha1 602561D82CEC7484E9509B5739BE021F8A3F3449 flags verified ) + rom ( name "Heiankyou Alien (Japan).gb" size 32768 crc 08bf29c9 sha1 602561D82CEC7484E9509B5739BE021F8A3F3449 flags verified ) ) game ( name "Heisei Tensai Bakabon (Japan)" description "Heisei Tensai Bakabon (Japan)" - rom ( name "Heisei Tensai Bakabon (Japan).gb" size 131072 crc AC044E9A md5 E6AECB5959F3435DF9B4500DC54404F6 sha1 AACCD5B75894916EF655082A4AB4E05CB3F6FEE8 flags verified ) + rom ( name "Heisei Tensai Bakabon (Japan).gb" size 131072 crc ac044e9a sha1 AACCD5B75894916EF655082A4AB4E05CB3F6FEE8 flags verified ) ) game ( name "Heracles no Eikou - Ugokidashita Kamigami (Japan)" description "Heracles no Eikou - Ugokidashita Kamigami (Japan)" - rom ( name "Heracles no Eikou - Ugokidashita Kamigami (Japan).gb" size 262144 crc 4F8A61BF md5 CCBD8D97A61883E05EAB21A5546188B2 sha1 C12C60B0C0A2EE1AADED61020FA72B5B467459E1 ) + rom ( name "Heracles no Eikou - Ugokidashita Kamigami (Japan).gb" size 262144 crc 4f8a61bf sha1 C12C60B0C0A2EE1AADED61020FA72B5B467459E1 flags verified ) ) game ( name "Hercules (USA, Europe) (SGB Enhanced)" description "Hercules (USA, Europe) (SGB Enhanced)" - rom ( name "Hercules (USA, Europe) (SGB Enhanced).gb" size 524288 crc 00A9001E md5 ABD4BAA57F0B90B402C2E56090394F9E sha1 215CCEACCD4A33A2DA6205F33A2803FF4004E2B1 flags verified ) + rom ( name "Hercules (USA, Europe) (SGB Enhanced).gb" size 524288 crc 00a9001e sha1 215CCEACCD4A33A2DA6205F33A2803FF4004E2B1 flags verified ) ) game ( name "Hero Shuugou!! Pinball Party (Japan)" description "Hero Shuugou!! Pinball Party (Japan)" - rom ( name "Hero Shuugou!! Pinball Party (Japan).gb" size 65536 crc 740552ED md5 CD6CA2A01E2310193C46AFCBFA382AB5 sha1 C4F0428455C6A4772C2DB7BAB0132DCA169E22C7 flags verified ) + rom ( name "Hero Shuugou!! Pinball Party (Japan).gb" size 65536 crc 740552ed sha1 C4F0428455C6A4772C2DB7BAB0132DCA169E22C7 flags verified ) ) game ( name "Hiden Inyou Kikouhou - Ca Da (Japan)" description "Hiden Inyou Kikouhou - Ca Da (Japan)" - rom ( name "Hiden Inyou Kikouhou - Ca Da (Japan).gb" size 65536 crc 9234EEAB md5 7E6C999C8B4BD0E7030977C7FA73C75C sha1 0BA32A4383F1FF89C8838D155CB672FF799F0687 ) + rom ( name "Hiden Inyou Kikouhou - Ca Da (Japan).gb" size 65536 crc 9234eeab sha1 0BA32A4383F1FF89C8838D155CB672FF799F0687 ) ) game ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '91 (Japan)" description "Higashio Osamu Kanshuu Pro Yakyuu Stadium '91 (Japan)" - rom ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '91 (Japan).gb" size 131072 crc 420881AE md5 D1D01441DBC0BAA83B23010CB60C687B sha1 CC6CBBCAABCE4A63106DA3C9B5E4A761511CAE38 flags verified ) + rom ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '91 (Japan).gb" size 131072 crc 420881ae sha1 CC6CBBCAABCE4A63106DA3C9B5E4A761511CAE38 flags verified ) ) game ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '92 (Japan)" description "Higashio Osamu Kanshuu Pro Yakyuu Stadium '92 (Japan)" - rom ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '92 (Japan).gb" size 262144 crc 71559BA0 md5 74B8D0C410C9579AB69B3550B2134DF6 sha1 7C89B508B71569776C50256DA350652657027CF2 ) + rom ( name "Higashio Osamu Kanshuu Pro Yakyuu Stadium '92 (Japan).gb" size 262144 crc 71559ba0 sha1 7C89B508B71569776C50256DA350652657027CF2 ) ) game ( - name "High Stakes (USA)" - description "High Stakes (USA)" - rom ( name "High Stakes (USA).gb" size 131072 crc 6B17ABE5 md5 EB41C29D9526E5F24F590D16F7BD33B8 sha1 4235ECC5416A3FB0A455BEC19BF26ECC9A12197B ) + name "High Stakes Gambling (USA)" + description "High Stakes Gambling (USA)" + rom ( name "High Stakes Gambling (USA).gb" size 131072 crc 6b17abe5 sha1 4235ECC5416A3FB0A455BEC19BF26ECC9A12197B ) ) game ( name "Hiryuu no Ken Gaiden (Japan)" description "Hiryuu no Ken Gaiden (Japan)" - rom ( name "Hiryuu no Ken Gaiden (Japan).gb" size 131072 crc 8EE95E0B md5 FA2A6CFAD08C5023543DA193ADE69A0F sha1 FB4133F25FA0B9EEA75F2EC69B786FE2D20D537E flags verified ) + rom ( name "Hiryuu no Ken Gaiden (Japan).gb" size 131072 crc 8ee95e0b sha1 FB4133F25FA0B9EEA75F2EC69B786FE2D20D537E flags verified ) ) game ( name "Hit the Ice - VHL - The Official Video Hockey League (USA, Europe)" description "Hit the Ice - VHL - The Official Video Hockey League (USA, Europe)" - rom ( name "Hit the Ice - VHL - The Official Video Hockey League (USA, Europe).gb" size 131072 crc 2C77F399 md5 66FC892B9682E8E2981FA83FA681CCAD sha1 F1631E0A97FD60A285FEBA1B2FC9082BCA3BE829 flags verified ) + rom ( name "Hit the Ice - VHL - The Official Video Hockey League (USA, Europe).gb" size 131072 crc 2c77f399 sha1 F1631E0A97FD60A285FEBA1B2FC9082BCA3BE829 flags verified ) ) game ( name "Hitori de Dekirumon! - Cooking Densetsu (Japan)" description "Hitori de Dekirumon! - Cooking Densetsu (Japan)" - rom ( name "Hitori de Dekirumon! - Cooking Densetsu (Japan).gb" size 131072 crc 59DB5E75 md5 6B9CCDC2B6611C87DD5425EBCF95185C sha1 D7B744B84DE2097FE77E55C76676256A14B20D74 ) + rom ( name "Hitori de Dekirumon! - Cooking Densetsu (Japan).gb" size 131072 crc 59db5e75 sha1 D7B744B84DE2097FE77E55C76676256A14B20D74 ) ) game ( name "Hoi Hoi - Game Boy Ban (Japan)" description "Hoi Hoi - Game Boy Ban (Japan)" - rom ( name "Hoi Hoi - Game Boy Ban (Japan).gb" size 131072 crc C2C2AD19 md5 A09CA996D31AC59D76A7C156D38C02ED sha1 D8962CC3A8C4D11AF236B2612DB7AB3F29615435 ) + rom ( name "Hoi Hoi - Game Boy Ban (Japan).gb" size 131072 crc c2c2ad19 sha1 D8962CC3A8C4D11AF236B2612DB7AB3F29615435 ) ) game ( name "Hokuto no Ken - Seizetsu Juuban Shoubu (Japan)" description "Hokuto no Ken - Seizetsu Juuban Shoubu (Japan)" - rom ( name "Hokuto no Ken - Seizetsu Juuban Shoubu (Japan).gb" size 131072 crc E4B4FEBC md5 C9EDC6CB63E3C2A91889653AF8929FF7 sha1 4F8E8D2D079A0E3B76A67411D919297808F3849B flags verified ) + rom ( name "Hokuto no Ken - Seizetsu Juuban Shoubu (Japan).gb" size 131072 crc e4b4febc sha1 4F8E8D2D079A0E3B76A67411D919297808F3849B flags verified ) ) game ( name "Home Alone (Japan)" description "Home Alone (Japan)" - rom ( name "Home Alone (Japan).gb" size 131072 crc 7C3F3107 md5 D4792ED1687D50CF4C77AFCAB05A24BC sha1 24C58E7B4BCCE704AB0976C18919066582E6DAF2 ) + rom ( name "Home Alone (Japan).gb" size 131072 crc 7c3f3107 sha1 24C58E7B4BCCE704AB0976C18919066582E6DAF2 ) ) game ( name "Home Alone (USA, Europe)" description "Home Alone (USA, Europe)" - rom ( name "Home Alone (USA, Europe).gb" size 131072 crc 8EFC8434 md5 6993211741EEA010F51B1C20B05D4C43 sha1 A3142C83F391EDA6F445226F2D49BD8A384BE411 flags verified ) + rom ( name "Home Alone (USA, Europe).gb" size 131072 crc 8efc8434 sha1 A3142C83F391EDA6F445226F2D49BD8A384BE411 flags verified ) ) game ( - name "Home Alone 2 - Lost In New York (USA, Europe)" - description "Home Alone 2 - Lost In New York (USA, Europe)" - rom ( name "Home Alone 2 - Lost In New York (USA, Europe).gb" size 131072 crc E8E430F1 md5 0611B365116B22C1AAA7E3CE4FAED5ED sha1 853E6F96BCBA40BC4CFA72898B02AEBC3F9D9498 flags verified ) + name "Home Alone 2 - Lost in New York (USA, Europe)" + description "Home Alone 2 - Lost in New York (USA, Europe)" + rom ( name "Home Alone 2 - Lost in New York (USA, Europe).gb" size 131072 crc e8e430f1 sha1 853E6F96BCBA40BC4CFA72898B02AEBC3F9D9498 flags verified ) ) game ( name "Hon Shougi (Japan) (SGB Enhanced)" description "Hon Shougi (Japan) (SGB Enhanced)" - rom ( name "Hon Shougi (Japan) (SGB Enhanced).gb" size 65536 crc 6C407EED md5 5AC712759DE3B6D6F7760272D62E2F53 sha1 3F49109296B4DC0006B4E8E68133992F5CA2B843 ) + rom ( name "Hon Shougi (Japan) (SGB Enhanced).gb" size 65536 crc 6c407eed sha1 3F49109296B4DC0006B4E8E68133992F5CA2B843 ) ) game ( name "Hong Kong (Japan)" description "Hong Kong (Japan)" - rom ( name "Hong Kong (Japan).gb" size 32768 crc 5AD83D68 md5 2CD8171D2C0D6695F6C4159476D459E7 sha1 D8DD3E1BAA95D8BB0A4E6B4E97EA64B8EC34331A flags verified ) + rom ( name "Hong Kong (Japan).gb" size 32768 crc 5ad83d68 sha1 D8DD3E1BAA95D8BB0A4E6B4E97EA64B8EC34331A flags verified ) ) game ( name "Honmei Boy (Japan)" description "Honmei Boy (Japan)" - rom ( name "Honmei Boy (Japan).gb" size 262144 crc 0D255D59 md5 7AE0D384AD38A528BED9C76E07671126 sha1 2D6C460123886502E1590268EC5D8422C5375F7B ) + rom ( name "Honmei Boy (Japan).gb" size 262144 crc 0d255d59 sha1 2D6C460123886502E1590268EC5D8422C5375F7B ) ) game ( name "Honoo no Toukyuuji - Dodge Danpei (Japan)" description "Honoo no Toukyuuji - Dodge Danpei (Japan)" - rom ( name "Honoo no Toukyuuji - Dodge Danpei (Japan).gb" size 262144 crc BA595897 md5 588B4E9EE2CBF179734C6E71379CD144 sha1 417C22BFD8DBA5DA00C207DA7866D8D8E8B292D1 flags verified ) + rom ( name "Honoo no Toukyuuji - Dodge Danpei (Japan).gb" size 262144 crc ba595897 sha1 417C22BFD8DBA5DA00C207DA7866D8D8E8B292D1 flags verified ) ) game ( name "Hook (Europe)" description "Hook (Europe)" - rom ( name "Hook (Europe).gb" size 131072 crc 370A2C2F md5 B3E011CDE1FA6B5BEBCAC15AC970C4A9 sha1 0E0784C238B8A16666157E1AC99CEE17FEB52C63 flags verified ) + rom ( name "Hook (Europe).gb" size 131072 crc 370a2c2f sha1 0E0784C238B8A16666157E1AC99CEE17FEB52C63 flags verified ) ) game ( name "Hook (Japan)" description "Hook (Japan)" - rom ( name "Hook (Japan).gb" size 131072 crc 62D8173C md5 42926474038E4D82E2B7A5E60FBD46C6 sha1 90EEE3E0434BDF63D00B0E9C5CF6F62626974CA4 ) + rom ( name "Hook (Japan).gb" size 131072 crc 62d8173c sha1 90EEE3E0434BDF63D00B0E9C5CF6F62626974CA4 ) ) game ( name "Hook (USA)" description "Hook (USA)" - rom ( name "Hook (USA).gb" size 131072 crc 6765B61B md5 C4E2DE3BE0BB5608AB903A885AFC065D sha1 570D7CC03E80E199E856160912431C21A6CA0F6C ) + rom ( name "Hook (USA).gb" size 131072 crc 6765b61b sha1 570D7CC03E80E199E856160912431C21A6CA0F6C ) ) game ( name "Hoshi no Kirby (Japan)" description "Hoshi no Kirby (Japan)" - rom ( name "Hoshi no Kirby (Japan).gb" size 262144 crc 21035F95 md5 B7963A68F95D644F8ADEDB269D29666C sha1 1E34B7BEEE30E350087771B3A3E05A40E4A1EA84 ) + rom ( name "Hoshi no Kirby (Japan).gb" size 262144 crc 21035f95 sha1 1E34B7BEEE30E350087771B3A3E05A40E4A1EA84 ) ) game ( - name "Hoshi no Kirby (Japan) (Rev A)" - description "Hoshi no Kirby (Japan) (Rev A)" - rom ( name "Hoshi no Kirby (Japan) (Rev A).gb" size 262144 crc 04342C83 md5 995CE81FE91162CFF295BADD94E366F3 sha1 5FE35FAB25299B6C53B40DECFE2B1827B4A64D2A flags verified ) + name "Hoshi no Kirby (Japan) (Rev 1)" + description "Hoshi no Kirby (Japan) (Rev 1)" + rom ( name "Hoshi no Kirby (Japan) (Rev 1).gb" size 262144 crc 04342c83 sha1 5FE35FAB25299B6C53B40DECFE2B1827B4A64D2A flags verified ) ) game ( name "Hoshi no Kirby 2 (Japan) (SGB Enhanced)" description "Hoshi no Kirby 2 (Japan) (SGB Enhanced)" - rom ( name "Hoshi no Kirby 2 (Japan) (SGB Enhanced).gb" size 524288 crc 4BEDF22C md5 28A8263BB19B7EF3DDCAC5EE83F62AEE sha1 8487FCC3F9005F6C6819C3D5810F54E78B510D47 flags verified ) + rom ( name "Hoshi no Kirby 2 (Japan) (SGB Enhanced).gb" size 524288 crc 4bedf22c sha1 8487FCC3F9005F6C6819C3D5810F54E78B510D47 flags verified ) ) game ( name "Hudson Hawk (Japan)" description "Hudson Hawk (Japan)" - rom ( name "Hudson Hawk (Japan).gb" size 131072 crc 1CB6158C md5 2F53A8739ACAC44FE6400DFDAED01A81 sha1 6DFC4F8269DCCEC1653854B98FA5C8627CD50CE0 ) + rom ( name "Hudson Hawk (Japan).gb" size 131072 crc 1cb6158c sha1 6DFC4F8269DCCEC1653854B98FA5C8627CD50CE0 ) ) game ( name "Hudson Hawk (USA)" description "Hudson Hawk (USA)" - rom ( name "Hudson Hawk (USA).gb" size 131072 crc ADFF7BBD md5 9C1EFB1BD07FD91765F680E7E9BC44F1 sha1 EFDBB5F86D6FF3B3F248B0360AB548AC1CEB1E0E flags verified ) + rom ( name "Hudson Hawk (USA).gb" size 131072 crc adff7bbd sha1 EFDBB5F86D6FF3B3F248B0360AB548AC1CEB1E0E flags verified ) ) game ( name "Hugo (Europe) (SGB Enhanced)" description "Hugo (Europe) (SGB Enhanced)" - rom ( name "Hugo (Europe) (SGB Enhanced).gb" size 131072 crc 74AA5E0F md5 6C960F0E87A857A7B49EF08484F79CE0 sha1 D314DFFCF5FB441D5D6D6419E01DC825E90CF0FC ) + rom ( name "Hugo (Europe) (SGB Enhanced).gb" size 131072 crc 74aa5e0f sha1 D314DFFCF5FB441D5D6D6419E01DC825E90CF0FC flags verified ) ) game ( name "Hugo 2 (Germany)" description "Hugo 2 (Germany)" - rom ( name "Hugo 2 (Germany).gb" size 131072 crc 67998FA4 md5 BF9334B9C902510CD9FE39AF82B4B465 sha1 66324A9B4D6F8782B706E0D3942D7EFDB2B1F141 flags verified ) + rom ( name "Hugo 2 (Germany).gb" size 131072 crc 67998fa4 sha1 66324A9B4D6F8782B706E0D3942D7EFDB2B1F141 flags verified ) ) game ( name "Humans, The (Europe) (En,Fr,De,Es,It)" description "Humans, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Humans, The (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 999C67D6 md5 A818623C008517F677C1C1EB17962E8D sha1 DAA810CF09EAE39867339B7615C6FFCF4BFD701A ) + rom ( name "Humans, The (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 999c67d6 sha1 DAA810CF09EAE39867339B7615C6FFCF4BFD701A flags verified ) ) game ( name "Humans, The (USA)" description "Humans, The (USA)" - rom ( name "Humans, The (USA).gb" size 262144 crc 1DF2E81D md5 4A1ECC8CCC706ED5FDCE2FDAB2AAF03E sha1 39B7F8F6ABB213BB5727379B864106CA2947FE6F ) + rom ( name "Humans, The (USA).gb" size 262144 crc 1df2e81d sha1 39B7F8F6ABB213BB5727379B864106CA2947FE6F ) ) game ( name "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced)" description "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced)" - rom ( name "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced).gb" size 524288 crc 3A4636FF md5 3F55FDE8E05A4D372F7F30A1F7398FB5 sha1 DE0310602E675924F393140B3FA66284870661DD flags verified ) + rom ( name "Hunchback of Notre Dame, The - 5 Foolishly Fun Topsy Turvy Games (USA, Europe) (SGB Enhanced).gb" size 524288 crc 3a4636ff sha1 DE0310602E675924F393140B3FA66284870661DD flags verified ) ) game ( name "Hunt for Red October, The (USA, Europe)" description "Hunt for Red October, The (USA, Europe)" - rom ( name "Hunt for Red October, The (USA, Europe).gb" size 131072 crc 5A61EE00 md5 CCA5288A7A9E0270592BF75C0431BBB5 sha1 7C9CCFD9E98B30C33FF71B3AB3098C2AFEB9037C flags verified ) + rom ( name "Hunt for Red October, The (USA, Europe).gb" size 131072 crc 5a61ee00 sha1 7C9CCFD9E98B30C33FF71B3AB3098C2AFEB9037C flags verified ) ) game ( name "Hyper Black Bass (Japan) (En,Ja)" description "Hyper Black Bass (Japan) (En,Ja)" - rom ( name "Hyper Black Bass (Japan) (En,Ja).gb" size 262144 crc C364D55F md5 3B710442B0A0E792E43DD98CB079DC5E sha1 FC8AD749979702C3D52954ED5808065CDE77FE38 flags verified ) + rom ( name "Hyper Black Bass (Japan) (En,Ja).gb" size 262144 crc c364d55f sha1 FC8AD749979702C3D52954ED5808065CDE77FE38 flags verified ) ) game ( name "Hyper Black Bass '95 (Japan) (En,Ja)" description "Hyper Black Bass '95 (Japan) (En,Ja)" - rom ( name "Hyper Black Bass '95 (Japan) (En,Ja).gb" size 262144 crc 32A81A49 md5 D9DA15A5481FDC184D75C6D190D45FD3 sha1 BEA9133CDBE8D96EE753A4F55CF5FA7BB80FF490 ) + rom ( name "Hyper Black Bass '95 (Japan) (En,Ja).gb" size 262144 crc 32a81a49 sha1 BEA9133CDBE8D96EE753A4F55CF5FA7BB80FF490 ) ) game ( name "Hyper Dunk (Europe)" description "Hyper Dunk (Europe)" - rom ( name "Hyper Dunk (Europe).gb" size 131072 crc 02D09CE3 md5 9ADD23B6CF3A5B76305192DA693DFD21 sha1 6ACA47DD2D9C57999A566903292AF2601C832C9C flags verified ) + rom ( name "Hyper Dunk (Europe).gb" size 131072 crc 02d09ce3 sha1 6ACA47DD2D9C57999A566903292AF2601C832C9C flags verified ) ) game ( - name "Hyper Lode Runner (World) (Rev A)" - description "Hyper Lode Runner (World) (Rev A)" - rom ( name "Hyper Lode Runner (World) (Rev A).gb" size 32768 crc B3A86164 md5 DC79B733997E469E961E2D850448DB23 sha1 261DA795C7B4155F1B8083ACC55DA78699C8A0DE flags verified ) + name "Hyper Lode Runner (World) (Rev 1)" + description "Hyper Lode Runner (World) (Rev 1)" + rom ( name "Hyper Lode Runner (World) (Rev 1).gb" size 32768 crc b3a86164 sha1 261DA795C7B4155F1B8083ACC55DA78699C8A0DE flags verified ) ) game ( name "Ikari no Yousai (Japan)" description "Ikari no Yousai (Japan)" - rom ( name "Ikari no Yousai (Japan).gb" size 131072 crc 1C2BA2A1 md5 AC04D143DE6734E181A223D05178BDE8 sha1 039DA1616E1A179AEDA7186D6CC1955149F49581 ) + rom ( name "Ikari no Yousai (Japan).gb" size 131072 crc 1c2ba2a1 sha1 039DA1616E1A179AEDA7186D6CC1955149F49581 ) ) game ( name "Ikari no Yousai 2 (Japan)" description "Ikari no Yousai 2 (Japan)" - rom ( name "Ikari no Yousai 2 (Japan).gb" size 131072 crc 6D4FD9AA md5 1EFEA4210026A8D733A5B2ADE2B005F1 sha1 AE437D4FB39D7438FC9EB98C91820AA2B5161B4F flags verified ) + rom ( name "Ikari no Yousai 2 (Japan).gb" size 131072 crc 6d4fd9aa sha1 AE437D4FB39D7438FC9EB98C91820AA2B5161B4F flags verified ) ) game ( name "In Your Face (USA)" description "In Your Face (USA)" - rom ( name "In Your Face (USA).gb" size 131072 crc 80AC487E md5 A4FC8158D1F2B6359DDAC6C66D747A95 sha1 0BE0F2A952497B321655DBEE5C89678F40BF0B5A ) + rom ( name "In Your Face (USA).gb" size 131072 crc 80ac487e sha1 0BE0F2A952497B321655DBEE5C89678F40BF0B5A ) ) game ( name "Incredible Crash Dummies, The (USA, Europe)" description "Incredible Crash Dummies, The (USA, Europe)" - rom ( name "Incredible Crash Dummies, The (USA, Europe).gb" size 131072 crc D81C08FA md5 C21058AF21EFC29413797F0A2C532E16 sha1 F62D369B576CFD2882F8E03A5A32238EB1599477 flags verified ) + rom ( name "Incredible Crash Dummies, The (USA, Europe).gb" size 131072 crc d81c08fa sha1 F62D369B576CFD2882F8E03A5A32238EB1599477 flags verified ) ) game ( name "Indiana Jones - Saigo no Seisen (Japan)" description "Indiana Jones - Saigo no Seisen (Japan)" - rom ( name "Indiana Jones - Saigo no Seisen (Japan).gb" size 131072 crc 8F234F49 md5 DA11BF0E3D40D317A0D27A665B739BAE sha1 238499F9FC98183E57222E8F1271B9BBAD2AF3EC ) + rom ( name "Indiana Jones - Saigo no Seisen (Japan).gb" size 131072 crc 8f234f49 sha1 238499F9FC98183E57222E8F1271B9BBAD2AF3EC ) ) game ( name "Indiana Jones and the Last Crusade (USA, Europe)" description "Indiana Jones and the Last Crusade (USA, Europe)" - rom ( name "Indiana Jones and the Last Crusade (USA, Europe).gb" size 131072 crc 9189921A md5 A27E15CDE0A8FBFC4489E0F599A53A9A sha1 B656BA6C03D0CB5C81C2ED8C5C64EA8E36660AAA flags verified ) + rom ( name "Indiana Jones and the Last Crusade (USA, Europe).gb" size 131072 crc 9189921a sha1 B656BA6C03D0CB5C81C2ED8C5C64EA8E36660AAA flags verified ) ) game ( name "Indien dans la Ville, Un (France) (SGB Enhanced)" description "Indien dans la Ville, Un (France) (SGB Enhanced)" - rom ( name "Indien dans la Ville, Un (France) (SGB Enhanced).gb" size 131072 crc E37E1832 md5 1D2FED99F9F478F404F161940E53CEA6 sha1 168337CDD8E4D919CE3B62EA4802EC6B959C6893 ) + rom ( name "Indien dans la Ville, Un (France) (SGB Enhanced).gb" size 131072 crc e37e1832 sha1 168337CDD8E4D919CE3B62EA4802EC6B959C6893 ) ) game ( name "InfoGenius Productivity Pak - Berlitz French Translator (USA, Europe)" description "InfoGenius Productivity Pak - Berlitz French Translator (USA, Europe)" - rom ( name "InfoGenius Productivity Pak - Berlitz French Translator (USA, Europe).gb" size 131072 crc 80485FDA md5 7EC2171517A50BBE35B319E0BCFA625C sha1 EA77A00E9982FFA710CE9E179D4614419F9E1A35 flags verified ) + rom ( name "InfoGenius Productivity Pak - Berlitz French Translator (USA, Europe).gb" size 131072 crc 80485fda sha1 EA77A00E9982FFA710CE9E179D4614419F9E1A35 flags verified ) ) game ( name "InfoGenius Productivity Pak - Berlitz Spanish Translator (USA, Europe)" description "InfoGenius Productivity Pak - Berlitz Spanish Translator (USA, Europe)" - rom ( name "InfoGenius Productivity Pak - Berlitz Spanish Translator (USA, Europe).gb" size 131072 crc 058EEEDB md5 82FFEC2FA00B08E001AA73BDC8FFA60A sha1 FF229BC70EF30154EF4B4D4F9A4F0EB86015682E flags verified ) + rom ( name "InfoGenius Productivity Pak - Berlitz Spanish Translator (USA, Europe).gb" size 131072 crc 058eeedb sha1 FF229BC70EF30154EF4B4D4F9A4F0EB86015682E flags verified ) ) game ( name "InfoGenius Productivity Pak - Frommer's Travel Guide (USA)" description "InfoGenius Productivity Pak - Frommer's Travel Guide (USA)" - rom ( name "InfoGenius Productivity Pak - Frommer's Travel Guide (USA).gb" size 262144 crc 40242E35 md5 5C4ED53347A60E467DF77024F05E23BA sha1 E4155270A59B0998B3EEFFEA779C33713EDDF2E6 flags verified ) + rom ( name "InfoGenius Productivity Pak - Frommer's Travel Guide (USA).gb" size 262144 crc 40242e35 sha1 E4155270A59B0998B3EEFFEA779C33713EDDF2E6 flags verified ) ) game ( name "InfoGenius Productivity Pak - Personal Organizer and Phone Book (USA)" description "InfoGenius Productivity Pak - Personal Organizer and Phone Book (USA)" - rom ( name "InfoGenius Productivity Pak - Personal Organizer and Phone Book (USA).gb" size 65536 crc CA436939 md5 976A32B5043C440B9ECA90B085BA747B sha1 9F65E16785E82FBDDC27D811F051F60F4812FCB4 flags verified ) + rom ( name "InfoGenius Productivity Pak - Personal Organizer and Phone Book (USA).gb" size 65536 crc ca436939 sha1 9F65E16785E82FBDDC27D811F051F60F4812FCB4 flags verified ) ) game ( name "InfoGenius Productivity Pak - Spell Checker and Calculator (USA)" description "InfoGenius Productivity Pak - Spell Checker and Calculator (USA)" - rom ( name "InfoGenius Productivity Pak - Spell Checker and Calculator (USA).gb" size 131072 crc 754496BB md5 70CF0BBC9F4A2BBC4C89649406B09E59 sha1 654E6F36C1260AFBA14640CF25C05C31A4075EB6 flags verified ) + rom ( name "InfoGenius Productivity Pak - Spell Checker and Calculator (USA).gb" size 131072 crc 754496bb sha1 654E6F36C1260AFBA14640CF25C05C31A4075EB6 flags verified ) ) game ( name "InfoGenius Systems - Personal Organizer with Phone Book (Europe)" description "InfoGenius Systems - Personal Organizer with Phone Book (Europe)" - rom ( name "InfoGenius Systems - Personal Organizer with Phone Book (Europe).gb" size 65536 crc BFD65534 md5 872E582831A17FAEE1DF663C39A73E99 sha1 434D2ACB7C2C23AE58222254F2E2CA2F4CEDDC61 flags verified ) + rom ( name "InfoGenius Systems - Personal Organizer with Phone Book (Europe).gb" size 65536 crc bfd65534 sha1 434D2ACB7C2C23AE58222254F2E2CA2F4CEDDC61 flags verified ) ) game ( name "Initial D Gaiden (Japan) (SGB Enhanced)" description "Initial D Gaiden (Japan) (SGB Enhanced)" - rom ( name "Initial D Gaiden (Japan) (SGB Enhanced).gb" size 262144 crc 6CC56612 md5 83EF6DC979EE752513A3B2C794D4CBFF sha1 1B3C4C1C4DFCA46A009EB2E5CD45B343D7EE6681 ) + rom ( name "Initial D Gaiden (Japan) (SGB Enhanced).gb" size 262144 crc 6cc56612 sha1 1B3C4C1C4DFCA46A009EB2E5CD45B343D7EE6681 ) ) game ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced)" description "International Superstar Soccer (USA, Europe) (SGB Enhanced)" - rom ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced).gb" size 262144 crc 94757BE8 md5 BF4E4002FFA88B9BE2C8B8A5B4CD9A48 sha1 13F2FC0945FB7A90F4D87D8C4E310DEC9AF6B792 flags verified ) + rom ( name "International Superstar Soccer (USA, Europe) (SGB Enhanced).gb" size 262144 crc 94757be8 sha1 13F2FC0945FB7A90F4D87D8C4E310DEC9AF6B792 flags verified ) ) game ( name "Ippatsu Gyakuten! DX Bakenou (Japan)" description "Ippatsu Gyakuten! DX Bakenou (Japan)" - rom ( name "Ippatsu Gyakuten! DX Bakenou (Japan).gb" size 65536 crc 8F3E7F95 md5 B8DAF4591CD9DD9DA702D3544A3D07F5 sha1 991EFD117DCB30DDF111BB4F6E46BDDA1C811417 flags verified ) + rom ( name "Ippatsu Gyakuten! DX Bakenou (Japan).gb" size 65536 crc 8f3e7f95 sha1 991EFD117DCB30DDF111BB4F6E46BDDA1C811417 flags verified ) ) game ( name "Iron Man X-O Manowar in Heavy Metal (USA, Europe) (SGB Enhanced)" description "Iron Man X-O Manowar in Heavy Metal (USA, Europe) (SGB Enhanced)" - rom ( name "Iron Man X-O Manowar in Heavy Metal (USA, Europe) (SGB Enhanced).gb" size 524288 crc 173232E5 md5 C31E99CB81E95C56AF7596CDCFE5A48C sha1 4EE9BA152E2339497D6AD49ACA6F2C78A8431480 flags verified ) + rom ( name "Iron Man X-O Manowar in Heavy Metal (USA, Europe) (SGB Enhanced).gb" size 524288 crc 173232e5 sha1 4EE9BA152E2339497D6AD49ACA6F2C78A8431480 flags verified ) ) game ( name "Ishida Yoshio Tsumego Paradise (Japan)" description "Ishida Yoshio Tsumego Paradise (Japan)" - rom ( name "Ishida Yoshio Tsumego Paradise (Japan).gb" size 65536 crc C97DAACA md5 DE12E7C222CA5BE9A1B1EA76DDC6C568 sha1 DD9FD57DFA72E8818C553DB553D9E598EDB9D956 ) + rom ( name "Ishida Yoshio Tsumego Paradise (Japan).gb" size 65536 crc c97daaca sha1 DD9FD57DFA72E8818C553DB553D9E598EDB9D956 ) ) game ( name "Ishido - The Way of Stones (Japan)" description "Ishido - The Way of Stones (Japan)" - rom ( name "Ishido - The Way of Stones (Japan).gb" size 32768 crc AB367915 md5 E90254B52FBB54F563697134EFE57C15 sha1 75768FA6C719B96E6642BCA5439A78CD3696761F ) + rom ( name "Ishido - The Way of Stones (Japan).gb" size 32768 crc ab367915 sha1 75768FA6C719B96E6642BCA5439A78CD3696761F flags verified ) ) game ( name "Ishido - The Way of Stones (USA)" description "Ishido - The Way of Stones (USA)" - rom ( name "Ishido - The Way of Stones (USA).gb" size 65536 crc 85B98A77 md5 E904AD95019FAD36DECD3B8BAE8B3F09 sha1 41A00B379864CC0BE08DE75AE0DE5BB2C6FBB045 flags verified ) + rom ( name "Ishido - The Way of Stones (USA).gb" size 65536 crc 85b98a77 sha1 41A00B379864CC0BE08DE75AE0DE5BB2C6FBB045 flags verified ) ) game ( name "Itsudemo! Nyan to Wonderful (Japan) (SGB Enhanced)" description "Itsudemo! Nyan to Wonderful (Japan) (SGB Enhanced)" - rom ( name "Itsudemo! Nyan to Wonderful (Japan) (SGB Enhanced).gb" size 262144 crc 1C4D3665 md5 6A268131029986557C75E559622A3C87 sha1 A48D6B68D82B98E775C00366DA544402D7C7AC0E ) + rom ( name "Itsudemo! Nyan to Wonderful (Japan) (SGB Enhanced).gb" size 262144 crc 1c4d3665 sha1 A48D6B68D82B98E775C00366DA544402D7C7AC0E flags verified ) ) game ( name "J.League Big Wave Soccer (Japan) (SGB Enhanced)" description "J.League Big Wave Soccer (Japan) (SGB Enhanced)" - rom ( name "J.League Big Wave Soccer (Japan) (SGB Enhanced).gb" size 262144 crc CDD02F22 md5 A6FD94FF8F5293AEE192B89253B7BE80 sha1 00369C42D2C4BE0506901B64F7D5424538574CE0 ) + rom ( name "J.League Big Wave Soccer (Japan) (SGB Enhanced).gb" size 262144 crc cdd02f22 sha1 00369C42D2C4BE0506901B64F7D5424538574CE0 ) ) game ( name "J.League Fighting Soccer - The King of Ace Strikers (Japan)" description "J.League Fighting Soccer - The King of Ace Strikers (Japan)" - rom ( name "J.League Fighting Soccer - The King of Ace Strikers (Japan).gb" size 131072 crc 17608642 md5 523E5C08731617A2826A3772126045CB sha1 FBE94C42A9BD7D5EBDDB28382CAF03AB2F9902D6 ) + rom ( name "J.League Fighting Soccer - The King of Ace Strikers (Japan).gb" size 131072 crc 17608642 sha1 FBE94C42A9BD7D5EBDDB28382CAF03AB2F9902D6 flags verified ) ) game ( - name "J.League Live '95 (Japan) (SGB Enhanced)" - description "J.League Live '95 (Japan) (SGB Enhanced)" - rom ( name "J.League Live '95 (Japan) (SGB Enhanced).gb" size 262144 crc F0321342 md5 F4C4FCA9E816C1FEE2E0D09026A2EA29 sha1 3B4922F8034877D1A5ACA380F846A7CB6841F6EE ) + name "J.League Live 95 (Japan) (SGB Enhanced)" + description "J.League Live 95 (Japan) (SGB Enhanced)" + rom ( name "J.League Live 95 (Japan) (SGB Enhanced).gb" size 262144 crc f0321342 sha1 3B4922F8034877D1A5ACA380F846A7CB6841F6EE ) ) game ( name "J.League Winning Goal (Japan)" description "J.League Winning Goal (Japan)" - rom ( name "J.League Winning Goal (Japan).gb" size 131072 crc ADB46F9C md5 B9C444465748AF0C5A7532C91D8C6D64 sha1 B8630F06E8B9682E667B7B1F2139162E2F022561 flags verified ) + rom ( name "J.League Winning Goal (Japan).gb" size 131072 crc adb46f9c sha1 B8630F06E8B9682E667B7B1F2139162E2F022561 flags verified ) ) game ( name "Jack Nicklaus Golf (France)" description "Jack Nicklaus Golf (France)" - rom ( name "Jack Nicklaus Golf (France).gb" size 131072 crc 374893D7 md5 5ADD36377363B6E8B38D5F69A33B4ED2 sha1 2BC2C3A95A49498347C49D5DD7182A1387AB531E ) + rom ( name "Jack Nicklaus Golf (France).gb" size 131072 crc 374893d7 sha1 2BC2C3A95A49498347C49D5DD7182A1387AB531E flags verified ) ) game ( name "Jack Nicklaus Golf (USA, Europe)" description "Jack Nicklaus Golf (USA, Europe)" - rom ( name "Jack Nicklaus Golf (USA, Europe).gb" size 131072 crc 654988B2 md5 A126F0EE58E0B47C405C15DD314D279B sha1 BAC74527DBD276F395D5C89F14450BB5BC2BAAB1 flags verified ) + rom ( name "Jack Nicklaus Golf (USA, Europe).gb" size 131072 crc 654988b2 sha1 BAC74527DBD276F395D5C89F14450BB5BC2BAAB1 flags verified ) ) game ( name "Jaleco J.Cup Soccer (Japan)" description "Jaleco J.Cup Soccer (Japan)" - rom ( name "Jaleco J.Cup Soccer (Japan).gb" size 131072 crc 98259257 md5 7F7DF6B53D2C01C2C2FE9CE20A8EEBE5 sha1 984F4FD0127325311CAD9FBCEB5C71F305CB2B23 flags verified ) + rom ( name "Jaleco J.Cup Soccer (Japan).gb" size 131072 crc 98259257 sha1 984F4FD0127325311CAD9FBCEB5C71F305CB2B23 flags verified ) ) game ( name "James Bond 007 (USA, Europe) (SGB Enhanced)" description "James Bond 007 (USA, Europe) (SGB Enhanced)" - rom ( name "James Bond 007 (USA, Europe) (SGB Enhanced).gb" size 524288 crc CA3BC3CE md5 669A4ECF89794505591B36D617E51F8A sha1 E03754173A5D62CB9DA7D2306BC41B0E23E3D519 flags verified ) + rom ( name "James Bond 007 (USA, Europe) (SGB Enhanced).gb" size 524288 crc ca3bc3ce sha1 E03754173A5D62CB9DA7D2306BC41B0E23E3D519 flags verified ) ) game ( name "Jankenman (Japan)" description "Jankenman (Japan)" - rom ( name "Jankenman (Japan).gb" size 65536 crc 37B3D081 md5 3EFC6C34D89A19A434DCF2E8F45E67B9 sha1 723F34875166B73C95610A6C146EEAC34DD90868 ) + rom ( name "Jankenman (Japan).gb" size 65536 crc 37b3d081 sha1 723F34875166B73C95610A6C146EEAC34DD90868 ) ) game ( name "Janshirou (Japan)" description "Janshirou (Japan)" - rom ( name "Janshirou (Japan).gb" size 65536 crc 0530E1CC md5 5E0703F8FC08728544F4F2594EE93E81 sha1 658120FF41A0FD4C2198F5618DD43A799958AA55 ) + rom ( name "Janshirou (Japan).gb" size 65536 crc 0530e1cc sha1 658120FF41A0FD4C2198F5618DD43A799958AA55 flags verified ) ) game ( name "Janshirou II - Sekai Saikyou no Janshi (Japan)" description "Janshirou II - Sekai Saikyou no Janshi (Japan)" - rom ( name "Janshirou II - Sekai Saikyou no Janshi (Japan).gb" size 131072 crc 2812036B md5 6847A0AF37237BBADCF582ED59FCABCE sha1 F85022F21549349F95B58DB57AB71998AB24C012 ) + rom ( name "Janshirou II - Sekai Saikyou no Janshi (Japan).gb" size 131072 crc 2812036b sha1 F85022F21549349F95B58DB57AB71998AB24C012 ) ) game ( name "Jantaku Boy (Japan)" description "Jantaku Boy (Japan)" - rom ( name "Jantaku Boy (Japan).gb" size 131072 crc 04DAA03B md5 9FC7D7525963A0029FCD15AA05E4CEBF sha1 34F0A33F329915800BA681728C43D7451FF1F162 ) + rom ( name "Jantaku Boy (Japan).gb" size 131072 crc 04daa03b sha1 34F0A33F329915800BA681728C43D7451FF1F162 flags verified ) ) game ( - name "Jeep Jamboree (USA)" - description "Jeep Jamboree (USA)" - rom ( name "Jeep Jamboree (USA).gb" size 131072 crc A1E76A33 md5 47B2627E14592A8C5B53C84C5F06400B sha1 988A40823F7DB661BC91FFFF8FC1BCD80E64F18D ) + name "Jeep Jamboree - Off-Road Adventure (USA)" + description "Jeep Jamboree - Off-Road Adventure (USA)" + rom ( name "Jeep Jamboree - Off-Road Adventure (USA).gb" size 131072 crc a1e76a33 sha1 988A40823F7DB661BC91FFFF8FC1BCD80E64F18D ) ) game ( name "Jelly Boy (Europe)" description "Jelly Boy (Europe)" - rom ( name "Jelly Boy (Europe).gb" size 262144 crc 7E6598BB md5 0ACEFB175380637BF0D49AD96DA23D52 sha1 579579D660CDC84AF2428CCD1B30B40A2FB592FA ) + rom ( name "Jelly Boy (Europe).gb" size 262144 crc 7e6598bb sha1 579579D660CDC84AF2428CCD1B30B40A2FB592FA ) ) game ( name "Jeopardy! (USA)" description "Jeopardy! (USA)" - rom ( name "Jeopardy! (USA).gb" size 131072 crc 08725C79 md5 60EF5FFC3AF0AC5110C2B31E83570494 sha1 D0BF6E71DDAE1FAFF179309EAAB554C2AE994DE0 ) + rom ( name "Jeopardy! (USA).gb" size 131072 crc 08725c79 sha1 D0BF6E71DDAE1FAFF179309EAAB554C2AE994DE0 ) ) game ( name "Jeopardy! - Platinum Edition (USA) (SGB Enhanced)" description "Jeopardy! - Platinum Edition (USA) (SGB Enhanced)" - rom ( name "Jeopardy! - Platinum Edition (USA) (SGB Enhanced).gb" size 131072 crc 5206FD09 md5 60F66390BEF3EC6E5A84E299D2261F73 sha1 35934633A9B301D734A6FCED7C56D55EBA0385AA ) + rom ( name "Jeopardy! - Platinum Edition (USA) (SGB Enhanced).gb" size 131072 crc 5206fd09 sha1 35934633A9B301D734A6FCED7C56D55EBA0385AA flags verified ) ) game ( name "Jeopardy! - Sports Edition (USA)" description "Jeopardy! - Sports Edition (USA)" - rom ( name "Jeopardy! - Sports Edition (USA).gb" size 131072 crc 3B523216 md5 5DCC16E0C5CAF4C5C610C02B6A5746BF sha1 AE534DCDEAA7138E1A0C775E0574C423A8C76DFB ) + rom ( name "Jeopardy! - Sports Edition (USA).gb" size 131072 crc 3b523216 sha1 AE534DCDEAA7138E1A0C775E0574C423A8C76DFB ) ) game ( name "Jeopardy! - Teen Tournament (USA) (SGB Enhanced)" description "Jeopardy! - Teen Tournament (USA) (SGB Enhanced)" - rom ( name "Jeopardy! - Teen Tournament (USA) (SGB Enhanced).gb" size 131072 crc CD3DF0C1 md5 D8AD8389C9EC44D4E3BACC88D7B7B1A9 sha1 20C71F434EF093FAC9361FA1DB9C2282C938DD71 ) + rom ( name "Jeopardy! - Teen Tournament (USA) (SGB Enhanced).gb" size 131072 crc cd3df0c1 sha1 20C71F434EF093FAC9361FA1DB9C2282C938DD71 ) ) game ( name "Jet Pack (USA, Europe) (Beta)" description "Jet Pack (USA, Europe) (Beta)" - rom ( name "Jet Pack (USA, Europe) (Beta).gb" size 131072 crc 1C223204 md5 CD40BDA7A113C2279D5FFD1CFA0CFDC7 sha1 DF7ABBCAACCD5CFF4C55BB331FA5D3049FB92896 ) + rom ( name "Jet Pack (USA, Europe) (Beta).gb" size 131072 crc 1c223204 sha1 DF7ABBCAACCD5CFF4C55BB331FA5D3049FB92896 flags verified ) ) game ( name "Jetsons, The - Robot Panic (USA, Europe)" description "Jetsons, The - Robot Panic (USA, Europe)" - rom ( name "Jetsons, The - Robot Panic (USA, Europe).gb" size 131072 crc 6386C870 md5 70CD582D3B1F15CB251620203D8B00C9 sha1 1790C7462907F803E9641A330DF6F06AA5E4E985 flags verified ) + rom ( name "Jetsons, The - Robot Panic (USA, Europe).gb" size 131072 crc 6386c870 sha1 1790C7462907F803E9641A330DF6F06AA5E4E985 flags verified ) ) game ( name "Jikuu Senki Mu (Japan)" description "Jikuu Senki Mu (Japan)" - rom ( name "Jikuu Senki Mu (Japan).gb" size 262144 crc 435C4697 md5 70A552E27767205B4D9BE337B419C05F sha1 799790FDF14C6202A44E5C9A18023FA4245243B8 ) + rom ( name "Jikuu Senki Mu (Japan).gb" size 262144 crc 435c4697 sha1 799790FDF14C6202A44E5C9A18023FA4245243B8 ) ) game ( name "Jimmy Connors no Pro Tennis Tour (Japan)" description "Jimmy Connors no Pro Tennis Tour (Japan)" - rom ( name "Jimmy Connors no Pro Tennis Tour (Japan).gb" size 65536 crc 18671602 md5 E35D24F2A2B72255E0CAADCFD131CE08 sha1 43AE08919DCCB5129E17A3FDAC553901FB6E3918 flags verified ) + rom ( name "Jimmy Connors no Pro Tennis Tour (Japan).gb" size 65536 crc 18671602 sha1 43AE08919DCCB5129E17A3FDAC553901FB6E3918 flags verified ) ) game ( name "Jimmy Connors Tennis (USA, Europe)" description "Jimmy Connors Tennis (USA, Europe)" - rom ( name "Jimmy Connors Tennis (USA, Europe).gb" size 65536 crc 9B7EBF91 md5 BF01B798DE6B41D301827A4C943A9E45 sha1 D1F93DB9A95C9023241E72FE0D7F9848322B53AA flags verified ) + rom ( name "Jimmy Connors Tennis (USA, Europe).gb" size 65536 crc 9b7ebf91 sha1 D1F93DB9A95C9023241E72FE0D7F9848322B53AA flags verified ) ) game ( name "Jinsei Game (Japan) (SGB Enhanced)" description "Jinsei Game (Japan) (SGB Enhanced)" - rom ( name "Jinsei Game (Japan) (SGB Enhanced).gb" size 262144 crc 09F53D55 md5 B67196DB786A67CDFE50D6D2E902AA11 sha1 11F883C0F5F4B62D614FD8662AE56E62AB00450B flags verified ) + rom ( name "Jinsei Game (Japan) (SGB Enhanced).gb" size 262144 crc 09f53d55 sha1 11F883C0F5F4B62D614FD8662AE56E62AB00450B flags verified ) ) game ( name "Jinsei Game Densetsu (Japan)" description "Jinsei Game Densetsu (Japan)" - rom ( name "Jinsei Game Densetsu (Japan).gb" size 131072 crc 590F4AFC md5 C7BF23774F3FEC0BBE79504A558FBBB6 sha1 106F9671E52D15DD06D614D87B4D690AB95D4131 flags verified ) + rom ( name "Jinsei Game Densetsu (Japan).gb" size 131072 crc 590f4afc sha1 106F9671E52D15DD06D614D87B4D690AB95D4131 flags verified ) ) game ( name "Joe & Mac (USA)" description "Joe & Mac (USA)" - rom ( name "Joe & Mac (USA).gb" size 262144 crc 5DA86ED4 md5 A4627FB86C2B91FC0ACE4F628AA607E4 sha1 DC4DC933C3138A05AB1D11BF77B4C7405CDD524B ) + rom ( name "Joe & Mac (USA).gb" size 262144 crc 5da86ed4 sha1 DC4DC933C3138A05AB1D11BF77B4C7405CDD524B ) ) game ( name "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv)" description "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc 9BD7F196 md5 341B155413D2253886D8F188625CC1C3 sha1 88AE07382560825B7CF9307D224938D3A0A89F8D ) + rom ( name "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv).gb" size 262144 crc 9bd7f196 sha1 88AE07382560825B7CF9307D224938D3A0A89F8D flags verified ) ) game ( name "Jordan vs Bird - One on One (Japan)" description "Jordan vs Bird - One on One (Japan)" - rom ( name "Jordan vs Bird - One on One (Japan).gb" size 65536 crc 3FCB174D md5 E27F25F72E2C4BEA5D8CD51592852B08 sha1 E498C76C6367DAED183CC3B185557078832AA5D9 flags verified ) + rom ( name "Jordan vs Bird - One on One (Japan).gb" size 65536 crc 3fcb174d sha1 E498C76C6367DAED183CC3B185557078832AA5D9 flags verified ) ) game ( name "Jordan vs Bird - One on One (USA, Europe)" description "Jordan vs Bird - One on One (USA, Europe)" - rom ( name "Jordan vs Bird - One on One (USA, Europe).gb" size 65536 crc C90C5456 md5 99314AEE7DEA4221CB38C03216239A51 sha1 C07FAC4E1F29C4216ED94A2CDC7659DC3121B76E flags verified ) + rom ( name "Jordan vs Bird - One on One (USA, Europe).gb" size 65536 crc c90c5456 sha1 C07FAC4E1F29C4216ED94A2CDC7659DC3121B76E flags verified ) ) game ( name "Joshua & the Battle of Jericho (USA) (Unl)" description "Joshua & the Battle of Jericho (USA) (Unl)" - rom ( name "Joshua & the Battle of Jericho (USA) (Unl).gb" size 131072 crc E0CF879B md5 2C07CAEE51A1F0C91C72C7C6F380B0F6 sha1 019B4B0E76336E2613AE6E8B415B5C65F6D465A5 ) + rom ( name "Joshua & the Battle of Jericho (USA) (Unl).gb" size 131072 crc e0cf879b sha1 019B4B0E76336E2613AE6E8B415B5C65F6D465A5 flags verified ) ) game ( name "Judge Dredd (Japan)" description "Judge Dredd (Japan)" - rom ( name "Judge Dredd (Japan).gb" size 262144 crc 951B9907 md5 C7F41E40A9E5A9141CA80BE614E0907B sha1 CB5D6F34F5289C16782EDEE0257649BFCB82C096 ) + rom ( name "Judge Dredd (Japan).gb" size 262144 crc 951b9907 sha1 CB5D6F34F5289C16782EDEE0257649BFCB82C096 ) ) game ( name "Judge Dredd (USA, Europe)" description "Judge Dredd (USA, Europe)" - rom ( name "Judge Dredd (USA, Europe).gb" size 262144 crc B9D11656 md5 7E9D69EACD6B4C82527065BCF63E474B sha1 36266C67C4FB095566401C25B11981785AC20A7D flags verified ) + rom ( name "Judge Dredd (USA, Europe).gb" size 262144 crc b9d11656 sha1 36266C67C4FB095566401C25B11981785AC20A7D flags verified ) ) game ( name "Jungle Book, The (USA, Europe)" description "Jungle Book, The (USA, Europe)" - rom ( name "Jungle Book, The (USA, Europe).gb" size 131072 crc B64D27EE md5 E5876720BF10345FB2150DB6D68C1CFB sha1 CA69DDE7B176D4BEC9C51F92C37A5D68402AF616 flags verified ) + rom ( name "Jungle Book, The (USA, Europe).gb" size 131072 crc b64d27ee sha1 CA69DDE7B176D4BEC9C51F92C37A5D68402AF616 flags verified ) ) game ( name "Jungle no Ouja Tar-chan (Japan) (SGB Enhanced)" description "Jungle no Ouja Tar-chan (Japan) (SGB Enhanced)" - rom ( name "Jungle no Ouja Tar-chan (Japan) (SGB Enhanced).gb" size 262144 crc 96555E9A md5 17792B7924AA9275A5A4655E8B9BBC27 sha1 5312E1804848603C41AC804243E5B2B758C75D0D flags verified ) + rom ( name "Jungle no Ouja Tar-chan (Japan) (SGB Enhanced).gb" size 262144 crc 96555e9a sha1 5312E1804848603C41AC804243E5B2B758C75D0D flags verified ) ) game ( name "Jungle Strike (USA, Europe)" description "Jungle Strike (USA, Europe)" - rom ( name "Jungle Strike (USA, Europe).gb" size 262144 crc 763ABABB md5 2B42DBC0934FDD90BCA3A4965520BF37 sha1 B4C53804F6D7ED230C092232148E69B53F9EB597 flags verified ) + rom ( name "Jungle Strike (USA, Europe).gb" size 262144 crc 763ababb sha1 B4C53804F6D7ED230C092232148E69B53F9EB597 flags verified ) ) game ( name "Jungle Wars (Japan)" description "Jungle Wars (Japan)" - rom ( name "Jungle Wars (Japan).gb" size 262144 crc 2AD46AC7 md5 0068D12E8A75CF18B9D0B34FFCBD119B sha1 3835A7821C11197FCA87564B8D51A82C81FA7286 flags verified ) + rom ( name "Jungle Wars (Japan).gb" size 262144 crc 2ad46ac7 sha1 3835A7821C11197FCA87564B8D51A82C81FA7286 flags verified ) ) game ( name "Jurassic Park (Europe) (En,Fr,De,Es,It)" description "Jurassic Park (Europe) (En,Fr,De,Es,It)" - rom ( name "Jurassic Park (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2C8AD255 md5 7173CECC94BCDB7AEB7240AE87491044 sha1 EFBC825BAE50C0498E56B53E9D02F00C400FF6D9 flags verified ) + rom ( name "Jurassic Park (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2c8ad255 sha1 EFBC825BAE50C0498E56B53E9D02F00C400FF6D9 flags verified ) ) game ( name "Jurassic Park (USA)" description "Jurassic Park (USA)" - rom ( name "Jurassic Park (USA).gb" size 262144 crc B350BEDF md5 D11D2DC76C6D743C3CC791104A2BDAE2 sha1 66273F0B52F9FF2BE875B1428ADD267A5F01ADB0 ) + rom ( name "Jurassic Park (USA).gb" size 262144 crc b350bedf sha1 66273F0B52F9FF2BE875B1428ADD267A5F01ADB0 ) ) game ( name "Jurassic Park Part 2 - The Chaos Continues (USA, Europe) (En,Fr,De,It)" description "Jurassic Park Part 2 - The Chaos Continues (USA, Europe) (En,Fr,De,It)" - rom ( name "Jurassic Park Part 2 - The Chaos Continues (USA, Europe) (En,Fr,De,It).gb" size 262144 crc AF3D2E95 md5 B94EB524347BB0A8A5C151B59AD63CFA sha1 B3DF5F3BF73B42696261247C4C9C425A81322BB0 flags verified ) + rom ( name "Jurassic Park Part 2 - The Chaos Continues (USA, Europe) (En,Fr,De,It).gb" size 262144 crc af3d2e95 sha1 B3DF5F3BF73B42696261247C4C9C425A81322BB0 flags verified ) ) game ( name "Kachiuma Yosou Keiba Kizoku (Japan)" description "Kachiuma Yosou Keiba Kizoku (Japan)" - rom ( name "Kachiuma Yosou Keiba Kizoku (Japan).gb" size 131072 crc A57E1AC1 md5 3DCBD16D3F9DA153DCA926F200CA1725 sha1 DE965FAE7D1E744302E6A12656EBB8867BA9CFFF flags verified ) + rom ( name "Kachiuma Yosou Keiba Kizoku (Japan).gb" size 131072 crc a57e1ac1 sha1 DE965FAE7D1E744302E6A12656EBB8867BA9CFFF flags verified ) ) game ( name "Kachiuma Yosou Keiba Kizoku EX '94 (Japan)" description "Kachiuma Yosou Keiba Kizoku EX '94 (Japan)" - rom ( name "Kachiuma Yosou Keiba Kizoku EX '94 (Japan).gb" size 131072 crc D4319169 md5 3DE5424CBDC270C965487A614A360828 sha1 30AAB6EFED1CC00295D7A35EA8E9F3D809F96334 flags verified ) + rom ( name "Kachiuma Yosou Keiba Kizoku EX '94 (Japan).gb" size 131072 crc d4319169 sha1 30AAB6EFED1CC00295D7A35EA8E9F3D809F96334 flags verified ) ) game ( name "Kachiuma Yosou Keiba Kizoku EX '95 (Japan)" description "Kachiuma Yosou Keiba Kizoku EX '95 (Japan)" - rom ( name "Kachiuma Yosou Keiba Kizoku EX '95 (Japan).gb" size 131072 crc 9C6A4918 md5 1FB76BB7F55CA19340FE8C7D1007E7FF sha1 A368D20E2EDCB8BC2745AE2C875505F45E40F4FB flags verified ) + rom ( name "Kachiuma Yosou Keiba Kizoku EX '95 (Japan).gb" size 131072 crc 9c6a4918 sha1 A368D20E2EDCB8BC2745AE2C875505F45E40F4FB flags verified ) ) game ( name "Kaeru no Tame ni Kane wa Naru (Japan)" description "Kaeru no Tame ni Kane wa Naru (Japan)" - rom ( name "Kaeru no Tame ni Kane wa Naru (Japan).gb" size 524288 crc C18CD57A md5 4EBE14C4C51555908C0E4CABB66DC813 sha1 CE1E4A788327F3099877C88CC848E48C1FD055AB flags verified ) + rom ( name "Kaeru no Tame ni Kane wa Naru (Japan).gb" size 524288 crc c18cd57a sha1 CE1E4A788327F3099877C88CC848E48C1FD055AB flags verified ) ) game ( name "Kaijuu Ou Gojira (Japan)" description "Kaijuu Ou Gojira (Japan)" - rom ( name "Kaijuu Ou Gojira (Japan).gb" size 262144 crc C529A96A md5 DEB601B4FADEFB13F5E6251C945D10F4 sha1 56271383F34A7709668A982DF95EBD083831E30F ) + rom ( name "Kaijuu Ou Gojira (Japan).gb" size 262144 crc c529a96a sha1 56271383F34A7709668A982DF95EBD083831E30F ) ) game ( - name "Kaisen Game - Navy Blue (Japan)" - description "Kaisen Game - Navy Blue (Japan)" - rom ( name "Kaisen Game - Navy Blue (Japan).gb" size 65536 crc AFD8C47C md5 27BCEF0893A0848B25FC69BE177DB1E3 sha1 7FBF13DD0B5A4E7798724270A81006BE9950F81A flags verified ) + name "Kaisen Game - Navyblue (Japan)" + description "Kaisen Game - Navyblue (Japan)" + rom ( name "Kaisen Game - Navyblue (Japan).gb" size 65536 crc afd8c47c sha1 7FBF13DD0B5A4E7798724270A81006BE9950F81A flags verified ) +) + +game ( + name "Kaisen Game - Navyblue 90 (Japan)" + description "Kaisen Game - Navyblue 90 (Japan)" + rom ( name "Kaisen Game - Navyblue 90 (Japan).gb" size 131072 crc 8cfeb2e2 sha1 60FA3FB83910F548047BBAC02627C914A9057372 ) +) + +game ( + name "Kaisen Game - Radarmission (Japan)" + description "Kaisen Game - Radarmission (Japan)" + rom ( name "Kaisen Game - Radarmission (Japan).gb" size 131072 crc 892fc0af sha1 64A808F582AFCBED6A3CE0263F1DAE6FDE57F30B flags verified ) ) game ( name "Kakomunja (Japan)" description "Kakomunja (Japan)" - rom ( name "Kakomunja (Japan).gb" size 32768 crc BEF1FE2B md5 73377222A76829E02C9A32B569862BDE sha1 560D174D34B32A35E302297D1667CF67C3D4E8B8 flags verified ) + rom ( name "Kakomunja (Japan).gb" size 32768 crc bef1fe2b sha1 560D174D34B32A35E302297D1667CF67C3D4E8B8 flags verified ) ) game ( name "Kamen Rider SD - Hashire! Mighty Riders (Japan)" description "Kamen Rider SD - Hashire! Mighty Riders (Japan)" - rom ( name "Kamen Rider SD - Hashire! Mighty Riders (Japan).gb" size 131072 crc 71C804B3 md5 D3B0F2FD8305D44173634FF52A5F7B37 sha1 03269715C9398659FA685830A6359CAA3FFA3BBF flags verified ) + rom ( name "Kamen Rider SD - Hashire! Mighty Riders (Japan).gb" size 131072 crc 71c804b3 sha1 03269715C9398659FA685830A6359CAA3FFA3BBF flags verified ) ) game ( name "Kandume Monsters (Japan) (SGB Enhanced)" description "Kandume Monsters (Japan) (SGB Enhanced)" - rom ( name "Kandume Monsters (Japan) (SGB Enhanced).gb" size 524288 crc 82E03E10 md5 0937C8FC7C7B5470ACB80F2462F49D48 sha1 9444196C413A13CF326C18C5AA457BCAC92114A5 flags verified ) + rom ( name "Kandume Monsters (Japan) (SGB Enhanced).gb" size 524288 crc 82e03e10 sha1 9444196C413A13CF326C18C5AA457BCAC92114A5 flags verified ) ) game ( - name "Karakuri Kengou Den - Musashi Lord (Japan)" - description "Karakuri Kengou Den - Musashi Lord (Japan)" - rom ( name "Karakuri Kengou Den - Musashi Lord (Japan).gb" size 131072 crc 01AEE24B md5 A74A2A87BB4B2637C5243A37523FA7AE sha1 ABEF454BA28D9A89CDEEF53DC32549D7BD7D95BB flags verified ) + name "Karakuri Kengou Den Musashi Lord (Japan)" + description "Karakuri Kengou Den Musashi Lord (Japan)" + rom ( name "Karakuri Kengou Den Musashi Lord (Japan).gb" size 131072 crc 01aee24b sha1 ABEF454BA28D9A89CDEEF53DC32549D7BD7D95BB flags verified ) ) game ( name "Karamuchou no Daijiken (Japan) (SGB Enhanced)" description "Karamuchou no Daijiken (Japan) (SGB Enhanced)" - rom ( name "Karamuchou no Daijiken (Japan) (SGB Enhanced).gb" size 262144 crc FA7EA8A0 md5 A8F87A97F8B5B84282C68D0CE989DD65 sha1 D831320BCEC612C283AFC2B6F194062CF98243DC flags verified ) + rom ( name "Karamuchou no Daijiken (Japan) (SGB Enhanced).gb" size 262144 crc fa7ea8a0 sha1 D831320BCEC612C283AFC2B6F194062CF98243DC flags verified ) ) game ( name "Kaseki Sousei Reborn (Japan) (SGB Enhanced)" description "Kaseki Sousei Reborn (Japan) (SGB Enhanced)" - rom ( name "Kaseki Sousei Reborn (Japan) (SGB Enhanced).gb" size 524288 crc 42E8BA89 md5 64B18855B9F342AB623BCECBF2865CB8 sha1 C61050451F8731E35B1B983C610041CB59509ED2 ) + rom ( name "Kaseki Sousei Reborn (Japan) (SGB Enhanced).gb" size 524288 crc 42e8ba89 sha1 C61050451F8731E35B1B983C610041CB59509ED2 flags verified ) ) game ( name "Kattobi Road (Japan)" description "Kattobi Road (Japan)" - rom ( name "Kattobi Road (Japan).gb" size 131072 crc EFBC23FC md5 DB93FEDEEE04D4A18FD4251CDC93620D sha1 7AC064A877ECC8247DFB7213722DBD0F4BE665F0 flags verified ) + rom ( name "Kattobi Road (Japan).gb" size 131072 crc efbc23fc sha1 7AC064A877ECC8247DFB7213722DBD0F4BE665F0 flags verified ) ) game ( name "Kawa no Nushi Tsuri 3 (Japan) (SGB Enhanced)" description "Kawa no Nushi Tsuri 3 (Japan) (SGB Enhanced)" - rom ( name "Kawa no Nushi Tsuri 3 (Japan) (SGB Enhanced).gb" size 524288 crc 147E82AE md5 8E012973051E41BB2C14FB33CAE38DDC sha1 5DC0C9B3FBAF75B44F368B8074C92A294E7382C4 flags verified ) + rom ( name "Kawa no Nushi Tsuri 3 (Japan) (SGB Enhanced).gb" size 524288 crc 147e82ae sha1 5DC0C9B3FBAF75B44F368B8074C92A294E7382C4 flags verified ) ) game ( name "Keitai Keiba Eight Special (Japan)" description "Keitai Keiba Eight Special (Japan)" - rom ( name "Keitai Keiba Eight Special (Japan).gb" size 131072 crc 326273B7 md5 844B2475D463154CAF57FE10AD8FAB15 sha1 1BBC35DDF540F2AD9937F57184ADD528C2811A5D ) + rom ( name "Keitai Keiba Eight Special (Japan).gb" size 131072 crc 326273b7 sha1 1BBC35DDF540F2AD9937F57184ADD528C2811A5D ) ) game ( name "Ken Griffey Jr. Presents Major League Baseball (USA, Europe) (SGB Enhanced)" description "Ken Griffey Jr. Presents Major League Baseball (USA, Europe) (SGB Enhanced)" - rom ( name "Ken Griffey Jr. Presents Major League Baseball (USA, Europe) (SGB Enhanced).gb" size 524288 crc 0A9859C1 md5 2D07BA7A88C2DAFF07DA53831166500A sha1 7092AFA1C1EA592BCD3AFD185AE17A7B1CDF6800 flags verified ) + rom ( name "Ken Griffey Jr. Presents Major League Baseball (USA, Europe) (SGB Enhanced).gb" size 524288 crc 0a9859c1 sha1 7092AFA1C1EA592BCD3AFD185AE17A7B1CDF6800 flags verified ) ) game ( name "Kenyuu Densetsu Yaiba (Japan)" description "Kenyuu Densetsu Yaiba (Japan)" - rom ( name "Kenyuu Densetsu Yaiba (Japan).gb" size 262144 crc CC19768E md5 7D76D2A9EAADA93DC846EFE1B2A815CC sha1 C2B71CEEE21F66F462DF18233F7622D8EC95FCCA ) + rom ( name "Kenyuu Densetsu Yaiba (Japan).gb" size 262144 crc cc19768e sha1 C2B71CEEE21F66F462DF18233F7622D8EC95FCCA ) ) game ( name "Kick Boxing, The (Japan)" description "Kick Boxing, The (Japan)" - rom ( name "Kick Boxing, The (Japan).gb" size 262144 crc 8056344C md5 B00C32FC442B523CEC2F2A26FFE9A1A4 sha1 6FB48835E5401D7B559B7E97C020BC8C356DFA1F ) + rom ( name "Kick Boxing, The (Japan).gb" size 262144 crc 8056344c sha1 6FB48835E5401D7B559B7E97C020BC8C356DFA1F ) ) game ( name "Kid Dracula (USA, Europe)" description "Kid Dracula (USA, Europe)" - rom ( name "Kid Dracula (USA, Europe).gb" size 262144 crc F27294B7 md5 24A6B4457A511CC667E9AC25417401AB sha1 F186833A2CCEC808210EB4BA669F08401F950E23 flags verified ) + rom ( name "Kid Dracula (USA, Europe).gb" size 262144 crc f27294b7 sha1 F186833A2CCEC808210EB4BA669F08401F950E23 flags verified ) ) game ( name "Kid Icarus - Of Myths and Monsters (USA, Europe)" description "Kid Icarus - Of Myths and Monsters (USA, Europe)" - rom ( name "Kid Icarus - Of Myths and Monsters (USA, Europe).gb" size 131072 crc 0C042862 md5 23C7BE98AC9A4D3B046AD1BE3F0965E4 sha1 465614BB236C507A5709ECAB95827A8BE4E2E6B8 flags verified ) + rom ( name "Kid Icarus - Of Myths and Monsters (USA, Europe).gb" size 131072 crc 0c042862 sha1 465614BB236C507A5709ECAB95827A8BE4E2E6B8 flags verified ) ) game ( name "Kidou Keisatsu Patlabor - Nerawareta Machi 1990 (Japan)" description "Kidou Keisatsu Patlabor - Nerawareta Machi 1990 (Japan)" - rom ( name "Kidou Keisatsu Patlabor - Nerawareta Machi 1990 (Japan).gb" size 131072 crc C7F7F0AC md5 8BCA6330273282546D0E74AD5C699590 sha1 63508A4CC76BF1DE2125B1055C631D9EDFC6E11B ) + rom ( name "Kidou Keisatsu Patlabor - Nerawareta Machi 1990 (Japan).gb" size 131072 crc c7f7f0ac sha1 63508A4CC76BF1DE2125B1055C631D9EDFC6E11B ) ) game ( name "Kikou Keisatsu Metal Jack (Japan)" description "Kikou Keisatsu Metal Jack (Japan)" - rom ( name "Kikou Keisatsu Metal Jack (Japan).gb" size 131072 crc F3CC5E62 md5 29D9BA6B3724A8DE14F1F66DBE2E4AEC sha1 8245F9F91126FAAD1F30502E1FC8012CC26C43C1 ) + rom ( name "Kikou Keisatsu Metal Jack (Japan).gb" size 131072 crc f3cc5e62 sha1 8245F9F91126FAAD1F30502E1FC8012CC26C43C1 ) ) game ( name "Killer Instinct (USA, Europe) (SGB Enhanced)" description "Killer Instinct (USA, Europe) (SGB Enhanced)" - rom ( name "Killer Instinct (USA, Europe) (SGB Enhanced).gb" size 524288 crc AC793B54 md5 BA8628A70339843C2EE8A294B840E8D6 sha1 65AE38588ABC0E699B244B0854F698DDF72C7B46 flags verified ) + rom ( name "Killer Instinct (USA, Europe) (SGB Enhanced).gb" size 524288 crc ac793b54 sha1 65AE38588ABC0E699B244B0854F698DDF72C7B46 flags verified ) ) game ( name "King James Bible (USA) (Unl)" description "King James Bible (USA) (Unl)" - rom ( name "King James Bible (USA) (Unl).gb" size 1048576 crc 23679231 md5 BA2AC3587B3E1B36DE52E740274071B0 sha1 6362FDE9DCB08242A64F2FBEA33DE93D1776A6E0 ) + rom ( name "King James Bible (USA) (Unl).gb" size 1048576 crc 23679231 sha1 6362FDE9DCB08242A64F2FBEA33DE93D1776A6E0 flags verified ) ) game ( name "King of Fighters '95, The (Europe) (SGB Enhanced)" description "King of Fighters '95, The (Europe) (SGB Enhanced)" - rom ( name "King of Fighters '95, The (Europe) (SGB Enhanced).gb" size 524288 crc A3E9B148 md5 AA9D61A428C592030A88828AE80C8FB2 sha1 27EEB37F7BE07381B6E4E01B5AE0D32F2EC209C0 flags verified ) + rom ( name "King of Fighters '95, The (Europe) (SGB Enhanced).gb" size 524288 crc a3e9b148 sha1 27EEB37F7BE07381B6E4E01B5AE0D32F2EC209C0 flags verified ) ) game ( name "King of Fighters '95, The (USA) (SGB Enhanced)" description "King of Fighters '95, The (USA) (SGB Enhanced)" - rom ( name "King of Fighters '95, The (USA) (SGB Enhanced).gb" size 524288 crc 1FF84E8C md5 B68C4141B4C4F778BD13100B9A3DB82C sha1 59C11DD527D47B24323F84FB8A1BB3D06A531F32 ) + rom ( name "King of Fighters '95, The (USA) (SGB Enhanced).gb" size 524288 crc 1ff84e8c sha1 59C11DD527D47B24323F84FB8A1BB3D06A531F32 ) ) game ( name "King of Fighters, The - Heat of Battle (Europe) (SGB Enhanced)" description "King of Fighters, The - Heat of Battle (Europe) (SGB Enhanced)" - rom ( name "King of Fighters, The - Heat of Battle (Europe) (SGB Enhanced).gb" size 524288 crc 4D2D8BC3 md5 CF6EC3C13CD20240EF0C0C63EC06558F sha1 1B5AC034B1333B3340FBDC5C128BC12ABD310043 ) + rom ( name "King of Fighters, The - Heat of Battle (Europe) (SGB Enhanced).gb" size 524288 crc 4d2d8bc3 sha1 1B5AC034B1333B3340FBDC5C128BC12ABD310043 flags verified ) ) game ( name "King of the Zoo (Europe)" description "King of the Zoo (Europe)" - rom ( name "King of the Zoo (Europe).gb" size 65536 crc D2D648C4 md5 61E363E80AC331A3D5F71C59044862F9 sha1 683FCB45CF98F8D84C221FFB180B06BF81C1CF74 flags verified ) + rom ( name "King of the Zoo (Europe).gb" size 65536 crc d2d648c4 sha1 683FCB45CF98F8D84C221FFB180B06BF81C1CF74 flags verified ) ) game ( name "Kingdom Crusade (USA)" description "Kingdom Crusade (USA)" - rom ( name "Kingdom Crusade (USA).gb" size 131072 crc 920202DC md5 79603FD837ABD36B72D73F959E0AE749 sha1 CECA61F9EE1E549CA5B70BF620159CF2C2290423 ) + rom ( name "Kingdom Crusade (USA).gb" size 131072 crc 920202dc sha1 CECA61F9EE1E549CA5B70BF620159CF2C2290423 ) ) game ( name "Kingyo Chuuihou! - Wapiko no Wakuwaku Stamp Rally! (Japan)" description "Kingyo Chuuihou! - Wapiko no Wakuwaku Stamp Rally! (Japan)" - rom ( name "Kingyo Chuuihou! - Wapiko no Wakuwaku Stamp Rally! (Japan).gb" size 131072 crc E69A6F0A md5 341D925720680E94FDAADFC10458D07F sha1 BAF5C1019C9A3752543036DCA0925D370AA20D45 flags verified ) + rom ( name "Kingyo Chuuihou! - Wapiko no Wakuwaku Stamp Rally! (Japan).gb" size 131072 crc e69a6f0a sha1 BAF5C1019C9A3752543036DCA0925D370AA20D45 flags verified ) ) game ( name "Kingyo Chuuihou! 2 - Gyopi-chan o Sagase! (Japan)" description "Kingyo Chuuihou! 2 - Gyopi-chan o Sagase! (Japan)" - rom ( name "Kingyo Chuuihou! 2 - Gyopi-chan o Sagase! (Japan).gb" size 131072 crc F3CCADC3 md5 DE6058A29141DD5B327070C7C7BA4196 sha1 0674ABAFB9DE841D658D249D06A499C14484F72C flags verified ) + rom ( name "Kingyo Chuuihou! 2 - Gyopi-chan o Sagase! (Japan).gb" size 131072 crc f3ccadc3 sha1 0674ABAFB9DE841D658D249D06A499C14484F72C flags verified ) ) game ( name "Kinin Koumaroku Oni (Japan)" description "Kinin Koumaroku Oni (Japan)" - rom ( name "Kinin Koumaroku Oni (Japan).gb" size 131072 crc B7F48649 md5 A7594D0B4362A7E4325DD8EA913C4BF1 sha1 7C6C71B52C62B814945EE102054A7A3210B1ECF3 flags verified ) + rom ( name "Kinin Koumaroku Oni (Japan).gb" size 131072 crc b7f48649 sha1 7C6C71B52C62B814945EE102054A7A3210B1ECF3 flags verified ) +) + +game ( + name "Kinin Koumaroku Oni (Japan) (Rev 1)" + description "Kinin Koumaroku Oni (Japan) (Rev 1)" + rom ( name "Kinin Koumaroku Oni (Japan) (Rev 1).gb" size 131072 crc aaf6366c sha1 298965BC2B99E49339618914114ABFD0962560C1 flags verified ) ) game ( name "Kinnikuman - The Dream Match (Japan)" description "Kinnikuman - The Dream Match (Japan)" - rom ( name "Kinnikuman - The Dream Match (Japan).gb" size 131072 crc 48C2CD38 md5 16A03DA1364C683B73742DC3E6C0E788 sha1 CC55E811024F60C0097EFDFF5962D85830626AB0 flags verified ) + rom ( name "Kinnikuman - The Dream Match (Japan).gb" size 131072 crc 48c2cd38 sha1 CC55E811024F60C0097EFDFF5962D85830626AB0 flags verified ) ) game ( name "Kirby no Block Ball (Japan) (SGB Enhanced)" description "Kirby no Block Ball (Japan) (SGB Enhanced)" - rom ( name "Kirby no Block Ball (Japan) (SGB Enhanced).gb" size 524288 crc DF3BBCD7 md5 6B09CC03750B853BB67845B667D0185E sha1 3FECC964D2C13AD98ABAC1DF49F05C488833EF5A flags verified ) + rom ( name "Kirby no Block Ball (Japan) (SGB Enhanced).gb" size 524288 crc df3bbcd7 sha1 3FECC964D2C13AD98ABAC1DF49F05C488833EF5A flags verified ) ) game ( name "Kirby no Kirakira Kids (Japan) (SGB Enhanced)" description "Kirby no Kirakira Kids (Japan) (SGB Enhanced)" - rom ( name "Kirby no Kirakira Kids (Japan) (SGB Enhanced).gb" size 262144 crc 47F42F42 md5 8C0F8CFBC339C2A2DEA15B6F50793AE2 sha1 2C46C42BE76ECA134E188814345AFA390E298811 flags verified ) + rom ( name "Kirby no Kirakira Kids (Japan) (SGB Enhanced).gb" size 262144 crc 47f42f42 sha1 2C46C42BE76ECA134E188814345AFA390E298811 flags verified ) ) game ( name "Kirby no Pinball (Japan)" description "Kirby no Pinball (Japan)" - rom ( name "Kirby no Pinball (Japan).gb" size 262144 crc 8B44FB7D md5 C2DE4B0C726B579012FEF2BE578B1920 sha1 678CA586F5A2E2FC894FB8E9F7B9EFA54FABBA44 flags verified ) + rom ( name "Kirby no Pinball (Japan).gb" size 262144 crc 8b44fb7d sha1 678CA586F5A2E2FC894FB8E9F7B9EFA54FABBA44 flags verified ) ) game ( name "Kirby's Block Ball (USA, Europe) (SGB Enhanced)" description "Kirby's Block Ball (USA, Europe) (SGB Enhanced)" - rom ( name "Kirby's Block Ball (USA, Europe) (SGB Enhanced).gb" size 524288 crc 7AD90B4B md5 203DB7DDC72359E4DB5E9AB42A6F0BA8 sha1 A790D96526972D7CEB026CA27AE41FF475CCB2C5 flags verified ) + rom ( name "Kirby's Block Ball (USA, Europe) (SGB Enhanced).gb" size 524288 crc 7ad90b4b sha1 A790D96526972D7CEB026CA27AE41FF475CCB2C5 flags verified ) ) game ( name "Kirby's Dream Land (USA, Europe)" description "Kirby's Dream Land (USA, Europe)" - rom ( name "Kirby's Dream Land (USA, Europe).gb" size 262144 crc 40F25740 md5 A66E4918EDCD042EC171A57FE3CE36C3 sha1 90979BAA1D0E24B41B5C304C5DDAF77450692D5A flags verified ) + rom ( name "Kirby's Dream Land (USA, Europe).gb" size 262144 crc 40f25740 sha1 90979BAA1D0E24B41B5C304C5DDAF77450692D5A flags verified ) ) game ( name "Kirby's Dream Land 2 (USA, Europe) (SGB Enhanced)" description "Kirby's Dream Land 2 (USA, Europe) (SGB Enhanced)" - rom ( name "Kirby's Dream Land 2 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 8DC07C35 md5 DDB5BFAE32B0CA39CF8AB6C46880126C sha1 8A2898FFA17E25F43793F40C88421D840D372D3C flags verified ) + rom ( name "Kirby's Dream Land 2 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 8dc07c35 sha1 8A2898FFA17E25F43793F40C88421D840D372D3C flags verified ) ) game ( name "Kirby's Pinball Land (USA, Europe)" description "Kirby's Pinball Land (USA, Europe)" - rom ( name "Kirby's Pinball Land (USA, Europe).gb" size 262144 crc 31CB6526 md5 F711ED10307D4EA27223FE965595B123 sha1 06EFDB138FF56CD9522DECE44ADADD3FAE169C76 flags verified ) + rom ( name "Kirby's Pinball Land (USA, Europe).gb" size 262144 crc 31cb6526 sha1 06EFDB138FF56CD9522DECE44ADADD3FAE169C76 flags verified ) ) game ( name "Kirby's Star Stacker (USA, Europe) (SGB Enhanced)" description "Kirby's Star Stacker (USA, Europe) (SGB Enhanced)" - rom ( name "Kirby's Star Stacker (USA, Europe) (SGB Enhanced).gb" size 262144 crc 91300898 md5 F4C0BF35939BE6786C099E9EB4635919 sha1 3999993D31E457BB279EFAC3E4A65FE4967BA861 flags verified ) + rom ( name "Kirby's Star Stacker (USA, Europe) (SGB Enhanced).gb" size 262144 crc 91300898 sha1 3999993D31E457BB279EFAC3E4A65FE4967BA861 flags verified ) ) game ( name "Kitchen Panic (Japan)" description "Kitchen Panic (Japan)" - rom ( name "Kitchen Panic (Japan).gb" size 131072 crc 909937CB md5 517373DFEC43EBAEDCCB2FA62307FF87 sha1 0E1B2F25C29EBABB1BC67737F3E47B263579423B ) + rom ( name "Kitchen Panic (Japan).gb" size 131072 crc 909937cb sha1 0E1B2F25C29EBABB1BC67737F3E47B263579423B ) ) game ( name "Kiteretsu Daihyakka - Bouken Ooedo Juraki (Japan)" description "Kiteretsu Daihyakka - Bouken Ooedo Juraki (Japan)" - rom ( name "Kiteretsu Daihyakka - Bouken Ooedo Juraki (Japan).gb" size 262144 crc D53548B0 md5 E386E74A32C38938607DD9034E52BA6B sha1 58D54CDC21C73661CCC0BE22E8A40CEF84861680 flags verified ) + rom ( name "Kiteretsu Daihyakka - Bouken Ooedo Juraki (Japan).gb" size 262144 crc d53548b0 sha1 58D54CDC21C73661CCC0BE22E8A40CEF84861680 flags verified ) ) game ( name "Kizuchi da Quiz da Gen-san da! (Japan)" description "Kizuchi da Quiz da Gen-san da! (Japan)" - rom ( name "Kizuchi da Quiz da Gen-san da! (Japan).gb" size 262144 crc 74A52399 md5 BEC4B32510F72AF2811045A87261AEA9 sha1 0729DA81A62A1C30E34F5C3157DE16FC014C52FE flags verified ) + rom ( name "Kizuchi da Quiz da Gen-san da! (Japan).gb" size 262144 crc 74a52399 sha1 0729DA81A62A1C30E34F5C3157DE16FC014C52FE flags verified ) ) game ( - name "Klax (Japan)" - description "Klax (Japan)" - rom ( name "Klax (Japan).gb" size 32768 crc B4955889 md5 BD456F73BA9CF33058D5A32F9F149E89 sha1 0BC9AF06D21B01BBECBE616C57E9A22F51DA3EFF flags verified ) + name "Klax (Japan) (Hudson Soft)" + description "Klax (Japan) (Hudson Soft)" + rom ( name "Klax (Japan) (Hudson Soft).gb" size 32768 crc b4955889 sha1 0BC9AF06D21B01BBECBE616C57E9A22F51DA3EFF flags verified ) ) game ( - name "Klax (USA)" - description "Klax (USA)" - rom ( name "Klax (USA).gb" size 65536 crc 72660774 md5 7D4F3BF92BBFF701583EB74F36951BB9 sha1 85F6B02815E7131FDD96F3802EB0A17D93277E75 ) + name "Klax (USA) (Mindscape)" + description "Klax (USA) (Mindscape)" + rom ( name "Klax (USA) (Mindscape).gb" size 65536 crc 72660774 sha1 85F6B02815E7131FDD96F3802EB0A17D93277E75 ) ) game ( name "Knight Quest (Japan)" description "Knight Quest (Japan)" - rom ( name "Knight Quest (Japan).gb" size 131072 crc C6F24D2F md5 F05959D91B9CB0CCFD8493351DB3ECCC sha1 717C65392A5ED9F19FCE995BE08685DF5FA0978B ) + rom ( name "Knight Quest (Japan).gb" size 131072 crc c6f24d2f sha1 717C65392A5ED9F19FCE995BE08685DF5FA0978B ) ) game ( name "Knight Quest (USA)" description "Knight Quest (USA)" - rom ( name "Knight Quest (USA).gb" size 131072 crc DF50F477 md5 3418B37CC4AB9BBD8B416BA27BE2F8F7 sha1 99EB275DF25BAA6D1B53F5518E93C5F5913A2B6A ) + rom ( name "Knight Quest (USA).gb" size 131072 crc df50f477 sha1 99EB275DF25BAA6D1B53F5518E93C5F5913A2B6A flags verified ) ) game ( name "Koi wa Kakehiki (Japan)" description "Koi wa Kakehiki (Japan)" - rom ( name "Koi wa Kakehiki (Japan).gb" size 32768 crc F3E1E652 md5 CF71CA9D27BB91C32CDCAD09024B2457 sha1 D6A59FC334F93BA0D17FAA66542EB74DCC3E536B ) + rom ( name "Koi wa Kakehiki (Japan).gb" size 32768 crc f3e1e652 sha1 D6A59FC334F93BA0D17FAA66542EB74DCC3E536B ) ) game ( name "Konami GB Collection Vol.1 (Japan) (SGB Enhanced)" description "Konami GB Collection Vol.1 (Japan) (SGB Enhanced)" - rom ( name "Konami GB Collection Vol.1 (Japan) (SGB Enhanced).gb" size 524288 crc 992CD78F md5 74EC77E1CFBDC05BBA5381B3F78D5DD9 sha1 DFB86B1B2DB29A7086D60DC143374EF27B130580 ) + rom ( name "Konami GB Collection Vol.1 (Japan) (SGB Enhanced).gb" size 524288 crc 992cd78f sha1 DFB86B1B2DB29A7086D60DC143374EF27B130580 ) ) game ( name "Konami GB Collection Vol.2 (Japan) (SGB Enhanced)" description "Konami GB Collection Vol.2 (Japan) (SGB Enhanced)" - rom ( name "Konami GB Collection Vol.2 (Japan) (SGB Enhanced).gb" size 524288 crc C3B318CD md5 E107E33EC2CE9A3F8E6E107F65ABB070 sha1 5753310CB9FBE44EFC2B27CE488CD069EF243199 ) + rom ( name "Konami GB Collection Vol.2 (Japan) (SGB Enhanced).gb" size 524288 crc c3b318cd sha1 5753310CB9FBE44EFC2B27CE488CD069EF243199 flags verified ) ) game ( name "Konami GB Collection Vol.3 (Japan) (SGB Enhanced)" description "Konami GB Collection Vol.3 (Japan) (SGB Enhanced)" - rom ( name "Konami GB Collection Vol.3 (Japan) (SGB Enhanced).gb" size 524288 crc 1DE9CAF9 md5 09ACB679F68373C9853A4E215D627527 sha1 DB9F1192DF7E186EA498C4F576FC016FDC339539 ) + rom ( name "Konami GB Collection Vol.3 (Japan) (SGB Enhanced).gb" size 524288 crc 1de9caf9 sha1 DB9F1192DF7E186EA498C4F576FC016FDC339539 ) ) game ( name "Konami GB Collection Vol.4 (Japan) (SGB Enhanced)" description "Konami GB Collection Vol.4 (Japan) (SGB Enhanced)" - rom ( name "Konami GB Collection Vol.4 (Japan) (SGB Enhanced).gb" size 524288 crc 3A43EA33 md5 933FEECC92BF118BBE99BF6FF7FFB97A sha1 C33BA418386B34B466B5DD28159EA76CA2DB12F8 ) + rom ( name "Konami GB Collection Vol.4 (Japan) (SGB Enhanced).gb" size 524288 crc 3a43ea33 sha1 C33BA418386B34B466B5DD28159EA76CA2DB12F8 ) ) game ( name "Konami Golf (Europe)" description "Konami Golf (Europe)" - rom ( name "Konami Golf (Europe).gb" size 131072 crc 0FDC9FB1 md5 E83A80A058FA5CFEC4A16C1C2F3E0DD3 sha1 59D13714F8477DB50CF164254480DD25959ECD23 flags verified ) + rom ( name "Konami Golf (Europe).gb" size 131072 crc 0fdc9fb1 sha1 59D13714F8477DB50CF164254480DD25959ECD23 flags verified ) ) game ( name "Konamic Basket (Japan)" description "Konamic Basket (Japan)" - rom ( name "Konamic Basket (Japan).gb" size 131072 crc 8E367457 md5 C0A038C66FB8252108EE888F8A0BA2BF sha1 10372339DB6D65210F7D04591D92C1889CEF5133 ) + rom ( name "Konamic Basket (Japan).gb" size 131072 crc 8e367457 sha1 10372339DB6D65210F7D04591D92C1889CEF5133 flags verified ) ) game ( name "Konamic Golf (Japan)" description "Konamic Golf (Japan)" - rom ( name "Konamic Golf (Japan).gb" size 131072 crc C16D4DB2 md5 F214EBEDB198F539230C4738CC644109 sha1 78D014F8FEB88CC8B509172C1A6FA48AA5EED67C ) + rom ( name "Konamic Golf (Japan).gb" size 131072 crc c16d4db2 sha1 78D014F8FEB88CC8B509172C1A6FA48AA5EED67C ) ) game ( name "Konamic Ice Hockey (Japan)" description "Konamic Ice Hockey (Japan)" - rom ( name "Konamic Ice Hockey (Japan).gb" size 131072 crc D14DEE07 md5 127FD88142D69AC75368E9B59BE70E05 sha1 E7FECCC615F71EBD7C3D61C3406ED63A894758F0 ) + rom ( name "Konamic Ice Hockey (Japan).gb" size 131072 crc d14dee07 sha1 E7FECCC615F71EBD7C3D61C3406ED63A894758F0 flags verified ) ) game ( name "Konamic Sports in Barcelona (Japan)" description "Konamic Sports in Barcelona (Japan)" - rom ( name "Konamic Sports in Barcelona (Japan).gb" size 131072 crc 5721E7D6 md5 A0F5378A7C89B4C423DB56204CBFCC31 sha1 4D3B7D1A615C6783E741812A1B1DE4467ED14EEF ) + rom ( name "Konamic Sports in Barcelona (Japan).gb" size 131072 crc 5721e7d6 sha1 4D3B7D1A615C6783E741812A1B1DE4467ED14EEF ) ) game ( name "Konchuu Hakase (Japan) (SGB Enhanced)" description "Konchuu Hakase (Japan) (SGB Enhanced)" - rom ( name "Konchuu Hakase (Japan) (SGB Enhanced).gb" size 524288 crc F6B3E291 md5 0DED2A31627C29A285637AAE52B51427 sha1 AC792793B43CC8FAE098DF23E6AEB845F98199CD flags verified ) + rom ( name "Konchuu Hakase (Japan) (SGB Enhanced).gb" size 524288 crc f6b3e291 sha1 AC792793B43CC8FAE098DF23E6AEB845F98199CD flags verified ) ) game ( - name "Konchuu Hakase (Japan) (Rev A) (SGB Enhanced)" - description "Konchuu Hakase (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Konchuu Hakase (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc 05753790 md5 F60FD654E4998E42B1AA53845A584220 sha1 3E8E47B36A2171AD93D0E21FE5C22FEFF17C6D88 ) + name "Konchuu Hakase (Japan) (Rev 1) (SGB Enhanced)" + description "Konchuu Hakase (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Konchuu Hakase (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc 05753790 sha1 3E8E47B36A2171AD93D0E21FE5C22FEFF17C6D88 ) ) game ( name "Koro Dice (Japan)" description "Koro Dice (Japan)" - rom ( name "Koro Dice (Japan).gb" size 32768 crc 39608C31 md5 DD846C4E076DD2F02FC3A4E2ECB6C940 sha1 17D51F459B854D1911C48418FF1592B11981CC84 ) + rom ( name "Koro Dice (Japan).gb" size 32768 crc 39608c31 sha1 17D51F459B854D1911C48418FF1592B11981CC84 ) ) game ( name "Koukiatsu Boy (Japan) (SGB Enhanced)" description "Koukiatsu Boy (Japan) (SGB Enhanced)" - rom ( name "Koukiatsu Boy (Japan) (SGB Enhanced).gb" size 524288 crc 53FF8041 md5 F88A0DF4F77F415235BF6C83EB39709C sha1 F7F5B71A8D3B393B0507EEE75FBDAEA7006F945F ) + rom ( name "Koukiatsu Boy (Japan) (SGB Enhanced).gb" size 524288 crc 53ff8041 sha1 F7F5B71A8D3B393B0507EEE75FBDAEA7006F945F ) ) game ( name "Krusty World (Japan)" description "Krusty World (Japan)" - rom ( name "Krusty World (Japan).gb" size 131072 crc 01FBC9F6 md5 91E47C8966A0DA555E211BE583987A1F sha1 BA64940BCE70DE459FFF84A16222481344749558 ) + rom ( name "Krusty World (Japan).gb" size 131072 crc 01fbc9f6 sha1 BA64940BCE70DE459FFF84A16222481344749558 ) ) game ( name "Krusty's Fun House (USA, Europe)" description "Krusty's Fun House (USA, Europe)" - rom ( name "Krusty's Fun House (USA, Europe).gb" size 131072 crc 1CEDB141 md5 38B05E5167A24089CB18CC95E3911019 sha1 E61039C52C053A8AE1BDFFFA3F694934569BB570 flags verified ) + rom ( name "Krusty's Fun House (USA, Europe).gb" size 131072 crc 1cedb141 sha1 E61039C52C053A8AE1BDFFFA3F694934569BB570 flags verified ) ) game ( name "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" description "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced)" - rom ( name "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced).gb" size 262144 crc F01D0B87 md5 6CDBF3CDDE7DEFC8D81D5BF2AFB9FDDD sha1 B986CE8E1A6A4A1B22E0DB5BF03B8B028CCE9057 flags verified ) + rom ( name "Kuma no Puutarou - Takara Sagashi da Ooiri Game Battle! (Japan) (SGB Enhanced).gb" size 262144 crc f01d0b87 sha1 B986CE8E1A6A4A1B22E0DB5BF03B8B028CCE9057 flags verified ) ) game ( name "Kung-Fu Master (USA, Europe)" description "Kung-Fu Master (USA, Europe)" - rom ( name "Kung-Fu Master (USA, Europe).gb" size 65536 crc 3340E600 md5 18FE3526F170F47A277E0FAC17D90170 sha1 B0BB485E2B57793DA9F153DB074C13A060A1E0D4 flags verified ) -) - -game ( - name "Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan)" - description "Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan)" - rom ( name "Kunio-kun no Jidaigeki Da yo Zenin Shuugou! (Japan).gb" size 262144 crc 229E9113 md5 4ED480F8974E938C01BE3B410EBEC3DF sha1 97FF2392F126B195AC8A1700A9A91AA364549DFD ) + rom ( name "Kung-Fu Master (USA, Europe).gb" size 65536 crc 3340e600 sha1 B0BB485E2B57793DA9F153DB074C13A060A1E0D4 flags verified ) ) game ( name "Kuusou Kagaku Sekai Gulliver Boy - Kuusou Kagaku Puzzle Purittopon!! (Japan) (SGB Enhanced)" description "Kuusou Kagaku Sekai Gulliver Boy - Kuusou Kagaku Puzzle Purittopon!! (Japan) (SGB Enhanced)" - rom ( name "Kuusou Kagaku Sekai Gulliver Boy - Kuusou Kagaku Puzzle Purittopon!! (Japan) (SGB Enhanced).gb" size 262144 crc FB291E78 md5 026D4AE446271173CE797E93E8CFF4B5 sha1 1BA1ABC4DB088CFC57BC733634C5B02308D132F4 ) + rom ( name "Kuusou Kagaku Sekai Gulliver Boy - Kuusou Kagaku Puzzle Purittopon!! (Japan) (SGB Enhanced).gb" size 262144 crc fb291e78 sha1 1BA1ABC4DB088CFC57BC733634C5B02308D132F4 ) ) game ( name "Kwirk - He's A-maze-ing! (USA, Europe)" description "Kwirk - He's A-maze-ing! (USA, Europe)" - rom ( name "Kwirk - He's A-maze-ing! (USA, Europe).gb" size 32768 crc 21C98AF2 md5 3A4BB57E9FBD4EF563C0C7B59A1C82A5 sha1 6EF48E912A47C774048456AA870C7E810FD45685 flags verified ) + rom ( name "Kwirk - He's A-maze-ing! (USA, Europe).gb" size 32768 crc 21c98af2 sha1 6EF48E912A47C774048456AA870C7E810FD45685 flags verified ) ) game ( name "Kyoro-chan Land (Japan)" description "Kyoro-chan Land (Japan)" - rom ( name "Kyoro-chan Land (Japan).gb" size 32768 crc E158D4DB md5 FB8540A7262842083991F4AA2A6330D5 sha1 67B9B01FBB58C69AAD716BCC0409A9DBA3BD92B5 ) + rom ( name "Kyoro-chan Land (Japan).gb" size 32768 crc e158d4db sha1 67B9B01FBB58C69AAD716BCC0409A9DBA3BD92B5 ) ) game ( name "Lamborghini American Challenge (USA, Europe)" description "Lamborghini American Challenge (USA, Europe)" - rom ( name "Lamborghini American Challenge (USA, Europe).gb" size 131072 crc 675E1309 md5 967D5FC3AB464C465C04D55BC1747768 sha1 82A6808F0C4CB1E05A4C2A38A39B0C37874B4211 flags verified ) + rom ( name "Lamborghini American Challenge (USA, Europe).gb" size 131072 crc 675e1309 sha1 82A6808F0C4CB1E05A4C2A38A39B0C37874B4211 flags verified ) ) game ( name "Last Action Hero (USA, Europe)" description "Last Action Hero (USA, Europe)" - rom ( name "Last Action Hero (USA, Europe).gb" size 131072 crc 10499AF6 md5 36CE150459099B9A7FCCBC2EE46AC22C sha1 010EB2CBAB987EC242CD0792C789A07C00106F48 flags verified ) + rom ( name "Last Action Hero (USA, Europe).gb" size 131072 crc 10499af6 sha1 010EB2CBAB987EC242CD0792C789A07C00106F48 flags verified ) ) game ( name "Lawnmower Man, The (Europe)" description "Lawnmower Man, The (Europe)" - rom ( name "Lawnmower Man, The (Europe).gb" size 131072 crc 134F91D7 md5 0BD1CF9C439B7095A64B4F76A5D16021 sha1 6E63A725FC802966986E6ED6917A7B976794F403 flags verified ) + rom ( name "Lawnmower Man, The (Europe).gb" size 131072 crc 134f91d7 sha1 6E63A725FC802966986E6ED6917A7B976794F403 flags verified ) ) game ( name "Lazlos' Leap (USA)" description "Lazlos' Leap (USA)" - rom ( name "Lazlos' Leap (USA).gb" size 65536 crc 31FB404B md5 68A06792AE4401F9FC09D460120EC2A1 sha1 C111470FCDADF191CF843E50C8F3D3DBB995A5C5 ) + rom ( name "Lazlos' Leap (USA).gb" size 65536 crc 31fb404b sha1 C111470FCDADF191CF843E50C8F3D3DBB995A5C5 ) ) game ( - name "Legend (Japan)" - description "Legend (Japan)" - rom ( name "Legend (Japan).gb" size 131072 crc FC20EBF0 md5 FEBEAD9C066474CCF390C92D84D7208F sha1 7447B3FAA1D15E80815CDACE3C6C0691BC28AA90 ) + name "Legend - Ashita e no Tsubasa (Japan)" + description "Legend - Ashita e no Tsubasa (Japan)" + rom ( name "Legend - Ashita e no Tsubasa (Japan).gb" size 131072 crc fc20ebf0 sha1 7447B3FAA1D15E80815CDACE3C6C0691BC28AA90 flags verified ) ) game ( name "Legend of Prince Valiant, The (Europe) (En,Fr,De)" description "Legend of Prince Valiant, The (Europe) (En,Fr,De)" - rom ( name "Legend of Prince Valiant, The (Europe) (En,Fr,De).gb" size 131072 crc 179C494E md5 017ACE47F4970576043075F7BA86073C sha1 D56B59AD9E483F6912E8E5869C43E1771CF167C2 flags verified ) + rom ( name "Legend of Prince Valiant, The (Europe) (En,Fr,De).gb" size 131072 crc 179c494e sha1 D56B59AD9E483F6912E8E5869C43E1771CF167C2 flags verified ) ) game ( name "Legend of the River King GB (USA) (SGB Enhanced)" description "Legend of the River King GB (USA) (SGB Enhanced)" - rom ( name "Legend of the River King GB (USA) (SGB Enhanced).gb" size 524288 crc A6E685DC md5 E54042D63D3671719B95D311731C02E4 sha1 D2E8A9ACEEC8639B528F712532A38FE0C2B0EDEF ) + rom ( name "Legend of the River King GB (USA) (SGB Enhanced).gb" size 524288 crc a6e685dc sha1 D2E8A9ACEEC8639B528F712532A38FE0C2B0EDEF ) ) game ( name "Legend of the River King GB (Australia) (SGB Enhanced)" description "Legend of the River King GB (Australia) (SGB Enhanced)" - rom ( name "Legend of the River King GB (Australia) (SGB Enhanced).gb" size 524288 crc 51627213 md5 55AD8DD2A99A840F3726600380B44315 sha1 87274E8C0D2DAAAC2E0DDA94651C35D6A0617C0F ) -) - -game ( - name "Legend of Zelda, The - Link's Awakening (Canada)" - description "Legend of Zelda, The - Link's Awakening (Canada)" - rom ( name "Legend of Zelda, The - Link's Awakening (Canada).gb" size 524288 crc 4407C759 md5 DD0752E29D7754AE3249F32BF0352811 sha1 4BBD38A4548E0C7922D0A6719AC5D16791E9535B flags verified ) + rom ( name "Legend of the River King GB (Australia) (SGB Enhanced).gb" size 524288 crc 51627213 sha1 87274E8C0D2DAAAC2E0DDA94651C35D6A0617C0F flags verified ) ) game ( name "Legend of Zelda, The - Link's Awakening (France)" description "Legend of Zelda, The - Link's Awakening (France)" - rom ( name "Legend of Zelda, The - Link's Awakening (France).gb" size 524288 crc BF2AB18B md5 5BC0913D533000522C7C9CAC1EF6F97F sha1 AF93E1B3140F61FCD614F1EF9266D6892224767F flags verified ) + rom ( name "Legend of Zelda, The - Link's Awakening (France).gb" size 524288 crc bf2ab18b sha1 AF93E1B3140F61FCD614F1EF9266D6892224767F flags verified ) ) game ( name "Legend of Zelda, The - Link's Awakening (Germany)" description "Legend of Zelda, The - Link's Awakening (Germany)" - rom ( name "Legend of Zelda, The - Link's Awakening (Germany).gb" size 524288 crc 760AB4E7 md5 8B7AF1A8CA96C74301D633E0CE83BA0B sha1 CC468442508A8BA6C4661238AA1925A3132F1630 flags verified ) + rom ( name "Legend of Zelda, The - Link's Awakening (Germany).gb" size 524288 crc 760ab4e7 sha1 CC468442508A8BA6C4661238AA1925A3132F1630 flags verified ) ) game ( name "Legend of Zelda, The - Link's Awakening (USA, Europe)" description "Legend of Zelda, The - Link's Awakening (USA, Europe)" - rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe).gb" size 524288 crc 8CF27C90 md5 C4360F89E2B09A21307FE864258ECAB7 sha1 602167F897B4F56FE8CEE837933DA3BED5882BBD flags verified ) + rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe).gb" size 524288 crc 8cf27c90 sha1 602167F897B4F56FE8CEE837933DA3BED5882BBD flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A)" - description "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A)" - rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev A).gb" size 524288 crc 7D1B6CD6 md5 E202EE96A60CE347E39FE3F5D9FD65E7 sha1 5259E68522225A7A830E29EA17DFDDC33263CED5 flags verified ) + name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 1)" + description "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 1)" + rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 1).gb" size 524288 crc 7d1b6cd6 sha1 5259E68522225A7A830E29EA17DFDDC33263CED5 flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B)" - description "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B)" - rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev B).gb" size 524288 crc 34D08E7B md5 69D643BF4E37B3C133518517338B6A1C sha1 5AB63DEF958728933571C3B4F6AF54DB14F3F8B2 flags verified ) + name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)" + description "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2)" + rom ( name "Legend of Zelda, The - Link's Awakening (USA, Europe) (Rev 2).gb" size 524288 crc 34d08e7b sha1 5AB63DEF958728933571C3B4F6AF54DB14F3F8B2 flags verified ) +) + +game ( + name "Legend of Zelda, The - Link's Awakening (Canada)" + description "Legend of Zelda, The - Link's Awakening (Canada)" + rom ( name "Legend of Zelda, The - Link's Awakening (Canada).gb" size 524288 crc 4407c759 sha1 4BBD38A4548E0C7922D0A6719AC5D16791E9535B flags verified ) ) game ( name "Lemmings (Europe)" description "Lemmings (Europe)" - rom ( name "Lemmings (Europe).gb" size 131072 crc 23467A35 md5 6F72B0B3DD1D0939B1CCF7E9A8B05A04 sha1 8EDB7E1A1A7289D4C393FBA6D27776AB6AF441FF flags verified ) + rom ( name "Lemmings (Europe).gb" size 131072 crc 23467a35 sha1 8EDB7E1A1A7289D4C393FBA6D27776AB6AF441FF flags verified ) ) game ( name "Lemmings (Japan)" description "Lemmings (Japan)" - rom ( name "Lemmings (Japan).gb" size 131072 crc 7D5CC03A md5 6CDEA29ACCD2C7C1B2AF1822F142BE4D sha1 0A4FEF2A6A09BB66B1B34B5294FF737530CFF4E1 ) + rom ( name "Lemmings (Japan).gb" size 131072 crc 7d5cc03a sha1 0A4FEF2A6A09BB66B1B34B5294FF737530CFF4E1 ) ) game ( name "Lemmings (USA)" description "Lemmings (USA)" - rom ( name "Lemmings (USA).gb" size 131072 crc F2D1C19D md5 25BC75255FDC90BA6AD00636D968DD2A sha1 1754FDE0B1C40752A5716A291E842E38401BAF08 ) + rom ( name "Lemmings (USA).gb" size 131072 crc f2d1c19d sha1 1754FDE0B1C40752A5716A291E842E38401BAF08 ) ) game ( - name "Lemmings (Europe) (Rev A)" - description "Lemmings (Europe) (Rev A)" - rom ( name "Lemmings (Europe) (Rev A).gb" size 131072 crc 560D71EB md5 33D428BD17848C4CFA7DC1B7F16644EC sha1 C156D7EE57860A23754E87D42F952B17077994AD ) + name "Lemmings (Europe) (Rev 1)" + description "Lemmings (Europe) (Rev 1)" + rom ( name "Lemmings (Europe) (Rev 1).gb" size 131072 crc 560d71eb sha1 C156D7EE57860A23754E87D42F952B17077994AD flags verified ) +) + +game ( + name "Lemmings (Europe) (Beta) (1993-05-19)" + description "Lemmings (Europe) (Beta) (1993-05-19)" + rom ( name "Lemmings (Europe) (Beta) (1993-05-19).gb" size 131072 crc e2a65174 sha1 4F23D9DCC315F5DBD5EF2350F6623B6CD077B393 flags verified ) ) game ( name "Lemmings 2 - The Tribes (Europe)" description "Lemmings 2 - The Tribes (Europe)" - rom ( name "Lemmings 2 - The Tribes (Europe).gb" size 524288 crc 9800BD49 md5 7B96ADFD6D3576CB2BAB2AFD06D8BD6E sha1 76CCF9AC82FAEBC7F9C4A4C8B5CD47DDEA46C486 flags verified ) + rom ( name "Lemmings 2 - The Tribes (Europe).gb" size 524288 crc 9800bd49 sha1 76CCF9AC82FAEBC7F9C4A4C8B5CD47DDEA46C486 flags verified ) ) game ( name "Lethal Weapon (USA, Europe)" description "Lethal Weapon (USA, Europe)" - rom ( name "Lethal Weapon (USA, Europe).gb" size 131072 crc 1F8D207C md5 D345B97E4B43F20A01FA2E4EA4A63A2B sha1 8B4621471B376A6262FBED70C1191416AB3BE915 flags verified ) + rom ( name "Lethal Weapon (USA, Europe).gb" size 131072 crc 1f8d207c sha1 8B4621471B376A6262FBED70C1191416AB3BE915 flags verified ) ) game ( name "Lingo (Europe) (En,Fr,De,Nl)" description "Lingo (Europe) (En,Fr,De,Nl)" - rom ( name "Lingo (Europe) (En,Fr,De,Nl).gb" size 131072 crc 0EF4637D md5 CB66B804AEA0DB325D5F2DD795C71A6A sha1 4838C0BAAE82A9DE62E70F2004D674B87CAA2043 ) + rom ( name "Lingo (Europe) (En,Fr,De,Nl).gb" size 131072 crc 0ef4637d sha1 4838C0BAAE82A9DE62E70F2004D674B87CAA2043 flags verified ) ) game ( name "Lion King, The (USA)" description "Lion King, The (USA)" - rom ( name "Lion King, The (USA).gb" size 524288 crc 3430D261 md5 FDAB70DF67C8941ED7B39A0405161545 sha1 FBBDB1D2073BAFA45943CB5F4D4AAE5648120089 ) + rom ( name "Lion King, The (USA).gb" size 524288 crc 3430d261 sha1 FBBDB1D2073BAFA45943CB5F4D4AAE5648120089 ) ) game ( name "Lion King, The (Europe)" description "Lion King, The (Europe)" - rom ( name "Lion King, The (Europe).gb" size 524288 crc 8FC3CA73 md5 BAF5068C926C2EABEA4AFE559F2E3CB0 sha1 043D29EDE2AF013C000FF650231C10B3F62D7ACA flags verified ) + rom ( name "Lion King, The (Europe).gb" size 524288 crc 8fc3ca73 sha1 043D29EDE2AF013C000FF650231C10B3F62D7ACA flags verified ) ) game ( name "Litti's Summer Sports (Germany)" description "Litti's Summer Sports (Germany)" - rom ( name "Litti's Summer Sports (Germany).gb" size 131072 crc E681395B md5 B834825661C10226C42EF6BE87224B83 sha1 D958C99EBE387B1BA489F4FFDA943C00345D2F4E flags verified ) + rom ( name "Litti's Summer Sports (Germany).gb" size 131072 crc e681395b sha1 D958C99EBE387B1BA489F4FFDA943C00345D2F4E flags verified ) ) game ( name "Little Master - Raikuban no Densetsu (Japan)" description "Little Master - Raikuban no Densetsu (Japan)" - rom ( name "Little Master - Raikuban no Densetsu (Japan).gb" size 131072 crc 31CD9670 md5 DE95D425F6A2836960F4EE2A9AA2F6F7 sha1 7C83B3C6CD9571C422E66E64E522A0416FA477B2 ) + rom ( name "Little Master - Raikuban no Densetsu (Japan).gb" size 131072 crc 31cd9670 sha1 7C83B3C6CD9571C422E66E64E522A0416FA477B2 ) ) game ( name "Little Master 2 - Raikou no Kishi (Japan)" description "Little Master 2 - Raikou no Kishi (Japan)" - rom ( name "Little Master 2 - Raikou no Kishi (Japan).gb" size 262144 crc 187DE7F8 md5 422652C9F3474CB89F8EEE38808EBFB4 sha1 9CC2D0F5EC33CA5EBF382E68DD55503C75A889B5 flags verified ) + rom ( name "Little Master 2 - Raikou no Kishi (Japan).gb" size 262144 crc 187de7f8 sha1 9CC2D0F5EC33CA5EBF382E68DD55503C75A889B5 flags verified ) ) game ( name "Little Mermaid, The (Europe)" description "Little Mermaid, The (Europe)" - rom ( name "Little Mermaid, The (Europe).gb" size 131072 crc 00DEF37A md5 8CFCE7B63AA070B5BCDC2E1BCB56E18E sha1 62A5BEEA93D48445A0F16F5582FC4FC61BA9FC1B flags verified ) + rom ( name "Little Mermaid, The (Europe).gb" size 131072 crc 00def37a sha1 62A5BEEA93D48445A0F16F5582FC4FC61BA9FC1B flags verified ) ) game ( name "Little Mermaid, The (USA)" description "Little Mermaid, The (USA)" - rom ( name "Little Mermaid, The (USA).gb" size 131072 crc D7C517E5 md5 A4DEE5DE1B4C3D9083F307D910FA0C3F sha1 9C7D7A82D0EEB4D7B4F4B7AE35E5EBD80C93D780 ) + rom ( name "Little Mermaid, The (USA).gb" size 131072 crc d7c517e5 sha1 9C7D7A82D0EEB4D7B4F4B7AE35E5EBD80C93D780 ) ) game ( name "Lock n' Chase ~ Lock 'n' Chase (World)" description "Lock n' Chase ~ Lock 'n' Chase (World)" - rom ( name "Lock n' Chase ~ Lock 'n' Chase (World).gb" size 65536 crc DAB91C7A md5 8BB31F539E8999D5C4E9449FE1BEFAD6 sha1 643CBD566D35CE8DBE0F24627E4862C09805A04C flags verified ) + rom ( name "Lock n' Chase ~ Lock 'n' Chase (World).gb" size 65536 crc dab91c7a sha1 643CBD566D35CE8DBE0F24627E4862C09805A04C flags verified ) ) game ( name "Lolo no Daibouken (Japan)" description "Lolo no Daibouken (Japan)" - rom ( name "Lolo no Daibouken (Japan).gb" size 131072 crc D6185941 md5 5070AAF41D5AE9EE08F988B9AAD26AF5 sha1 2F4A4215E3C95F7F3646AD678C5CD191FCE02515 flags verified ) + rom ( name "Lolo no Daibouken (Japan).gb" size 131072 crc d6185941 sha1 2F4A4215E3C95F7F3646AD678C5CD191FCE02515 flags verified ) ) game ( name "Looney Tunes (USA, Europe)" description "Looney Tunes (USA, Europe)" - rom ( name "Looney Tunes (USA, Europe).gb" size 131072 crc A662A8EF md5 6E9DD3C1FB169DA79292A1962E95A884 sha1 97D96F8EC66ACBA996C7BEC0A713C84075F22680 flags verified ) + rom ( name "Looney Tunes (USA, Europe).gb" size 131072 crc a662a8ef sha1 97D96F8EC66ACBA996C7BEC0A713C84075F22680 flags verified ) ) game ( name "Looney Tunes - Bugs Bunny to Yukai na Nakama-tachi (Japan)" description "Looney Tunes - Bugs Bunny to Yukai na Nakama-tachi (Japan)" - rom ( name "Looney Tunes - Bugs Bunny to Yukai na Nakama-tachi (Japan).gb" size 131072 crc 40E47DA3 md5 BEEB3092AEC6DA08F5A86630207AE87C sha1 ED26FD9D4011C286E2E6109967CAD2564C17900B ) + rom ( name "Looney Tunes - Bugs Bunny to Yukai na Nakama-tachi (Japan).gb" size 131072 crc 40e47da3 sha1 ED26FD9D4011C286E2E6109967CAD2564C17900B ) +) + +game ( + name "Looney Tunes 2 - Tasmanian Devil in Island Chase ~ Taz-Mania (USA, Europe)" + description "Looney Tunes 2 - Tasmanian Devil in Island Chase ~ Taz-Mania (USA, Europe)" + rom ( name "Looney Tunes 2 - Tasmanian Devil in Island Chase ~ Taz-Mania (USA, Europe).gb" size 262144 crc 22d07cf6 sha1 D36D731BD2644EE84C7CF77A2C1D319851E4D6BB flags verified ) ) game ( name "Looney Tunes Series - Daffy Duck (Japan) (SGB Enhanced)" description "Looney Tunes Series - Daffy Duck (Japan) (SGB Enhanced)" - rom ( name "Looney Tunes Series - Daffy Duck (Japan) (SGB Enhanced).gb" size 262144 crc 798D9489 md5 EB4C1F70056AAC7A767E6EB790B2FA30 sha1 65F063906680E65D8786E698BD51674268D7AE68 ) + rom ( name "Looney Tunes Series - Daffy Duck (Japan) (SGB Enhanced).gb" size 262144 crc 798d9489 sha1 65F063906680E65D8786E698BD51674268D7AE68 ) ) game ( name "Loopz (World)" description "Loopz (World)" - rom ( name "Loopz (World).gb" size 32768 crc 531A3E16 md5 7E68C061D77A2E8925442A9B6FA0A0ED sha1 DD2DDAC2310409287299C287F1959196E0B4D14E flags verified ) + rom ( name "Loopz (World).gb" size 32768 crc 531a3e16 sha1 DD2DDAC2310409287299C287F1959196E0B4D14E flags verified ) ) game ( name "Lost World, The - Jurassic Park (USA, Europe) (SGB Enhanced)" description "Lost World, The - Jurassic Park (USA, Europe) (SGB Enhanced)" - rom ( name "Lost World, The - Jurassic Park (USA, Europe) (SGB Enhanced).gb" size 524288 crc 391F532A md5 81AD77F41587AAB8E452F42CC0252E26 sha1 68BF63BA6A6C9F3A71A933D6F00E5212C66DCD03 flags verified ) + rom ( name "Lost World, The - Jurassic Park (USA, Europe) (SGB Enhanced).gb" size 524288 crc 391f532a sha1 68BF63BA6A6C9F3A71A933D6F00E5212C66DCD03 flags verified ) ) game ( name "Lucky Luke (Europe) (En,Fr,De,Es)" description "Lucky Luke (Europe) (En,Fr,De,Es)" - rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gb" size 262144 crc 538E0591 md5 307889B908A3954B224493486E4C4294 sha1 7D67AA8B17D7208D8ED234BD70B4DEF9582B362D flags verified ) + rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gb" size 262144 crc 538e0591 sha1 7D67AA8B17D7208D8ED234BD70B4DEF9582B362D flags verified ) ) game ( name "Lucky Monkey (Japan)" description "Lucky Monkey (Japan)" - rom ( name "Lucky Monkey (Japan).gb" size 65536 crc A2234EB1 md5 CC111BC1EE3E0AD566B8BC058372B6CD sha1 AB8654013DC574538B815D8B15AA3CAE66AFC809 ) + rom ( name "Lucky Monkey (Japan).gb" size 65536 crc a2234eb1 sha1 AB8654013DC574538B815D8B15AA3CAE66AFC809 ) ) game ( name "Lucle (Japan, Europe)" description "Lucle (Japan, Europe)" - rom ( name "Lucle (Japan, Europe).gb" size 524288 crc A3D5C8D7 md5 E1D28CE25A61B4F623C3C8013CE55B89 sha1 2FEF16FAC95EC4FFD252E9974ECCFCE538E5F797 flags verified ) + rom ( name "Lucle (Japan, Europe).gb" size 524288 crc a3d5c8d7 sha1 2FEF16FAC95EC4FFD252E9974ECCFCE538E5F797 flags verified ) +) + +game ( + name "Lunar Chase (USA) (Proto)" + description "Lunar Chase (USA) (Proto)" + rom ( name "Lunar Chase (USA) (Proto).gb" size 245760 crc cd555712 sha1 B1C5B60B82AAA0B824F7BF67FC8F111377CCFB6A flags verified ) ) game ( name "Lunar Lander (Japan)" description "Lunar Lander (Japan)" - rom ( name "Lunar Lander (Japan).gb" size 131072 crc 030D2054 md5 1FFA46F368917656A1590ABAE6112E79 sha1 05266F727879963A23DBBCD8C87C68597607F3B8 flags verified ) + rom ( name "Lunar Lander (Japan).gb" size 131072 crc 030d2054 sha1 05266F727879963A23DBBCD8C87C68597607F3B8 flags verified ) ) game ( name "Mach Go Go Go (Japan) (SGB Enhanced)" description "Mach Go Go Go (Japan) (SGB Enhanced)" - rom ( name "Mach Go Go Go (Japan) (SGB Enhanced).gb" size 262144 crc 016D230B md5 D87FDB7009DECE416655EDF24EE19EDE sha1 BAEA8B49CE2402C5C094DDAE0320A382C0D95D86 ) + rom ( name "Mach Go Go Go (Japan) (SGB Enhanced).gb" size 262144 crc 016d230b sha1 BAEA8B49CE2402C5C094DDAE0320A382C0D95D86 ) ) game ( - name "Madden '95 (USA, Europe) (SGB Enhanced)" - description "Madden '95 (USA, Europe) (SGB Enhanced)" - rom ( name "Madden '95 (USA, Europe) (SGB Enhanced).gb" size 524288 crc D2585BBB md5 EB57688DA8812DEE7C813954DEE175CE sha1 B41A14394BBD890E341BF5D27F297CB5E906FD60 flags verified ) + name "Madden 95 (USA, Europe) (SGB Enhanced)" + description "Madden 95 (USA, Europe) (SGB Enhanced)" + rom ( name "Madden 95 (USA, Europe) (SGB Enhanced).gb" size 524288 crc d2585bbb sha1 B41A14394BBD890E341BF5D27F297CB5E906FD60 flags verified ) ) game ( - name "Madden '96 (USA, Europe) (SGB Enhanced)" - description "Madden '96 (USA, Europe) (SGB Enhanced)" - rom ( name "Madden '96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc FD9DC1AD md5 27FF412B4909F2B20E28A629CA91FEEE sha1 DD67D34B7801F31063DF522C45349823713FE99B flags verified ) + name "Madden 96 (USA, Europe) (SGB Enhanced)" + description "Madden 96 (USA, Europe) (SGB Enhanced)" + rom ( name "Madden 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc fd9dc1ad sha1 DD67D34B7801F31063DF522C45349823713FE99B flags verified ) ) game ( - name "Madden '97 (USA) (SGB Enhanced)" - description "Madden '97 (USA) (SGB Enhanced)" - rom ( name "Madden '97 (USA) (SGB Enhanced).gb" size 524288 crc 88A837A2 md5 A5EEF9D26684AF4EE340F3B49A454283 sha1 E1D92B6AFDD7DC2254C895AD8A9A066262FB214B ) + name "Madden 97 (USA) (SGB Enhanced)" + description "Madden 97 (USA) (SGB Enhanced)" + rom ( name "Madden 97 (USA) (SGB Enhanced).gb" size 524288 crc 88a837a2 sha1 E1D92B6AFDD7DC2254C895AD8A9A066262FB214B ) ) game ( name "Maerchen Club (Japan)" description "Maerchen Club (Japan)" - rom ( name "Maerchen Club (Japan).gb" size 131072 crc CDFD660A md5 29962EF94473A677EE26EEE90B16DC6D sha1 DCB42287FFDBC352CD954B28A797FCD3547730DE ) + rom ( name "Maerchen Club (Japan).gb" size 131072 crc cdfd660a sha1 DCB42287FFDBC352CD954B28A797FCD3547730DE ) ) game ( name "Magic Knight Rayearth (Japan) (SGB Enhanced)" description "Magic Knight Rayearth (Japan) (SGB Enhanced)" - rom ( name "Magic Knight Rayearth (Japan) (SGB Enhanced).gb" size 262144 crc 94838A81 md5 06B75E657DEBD1568F18D369CC2422DD sha1 4F77031946E62772A241A9B5B046D7FCF6A28EA8 flags verified ) + rom ( name "Magic Knight Rayearth (Japan) (SGB Enhanced).gb" size 262144 crc 94838a81 sha1 4F77031946E62772A241A9B5B046D7FCF6A28EA8 flags verified ) ) game ( name "Magic Knight Rayearth 2nd. - The Missing Colors (Japan) (SGB Enhanced)" description "Magic Knight Rayearth 2nd. - The Missing Colors (Japan) (SGB Enhanced)" - rom ( name "Magic Knight Rayearth 2nd. - The Missing Colors (Japan) (SGB Enhanced).gb" size 262144 crc 00202DFA md5 522C139D757A5F5AEF530C60EF3C5502 sha1 AFE76C2D6F796813F1803E8C542107BF0827F966 flags verified ) + rom ( name "Magic Knight Rayearth 2nd. - The Missing Colors (Japan) (SGB Enhanced).gb" size 262144 crc 00202dfa sha1 AFE76C2D6F796813F1803E8C542107BF0827F966 flags verified ) ) game ( name "Magical Taruruuto-kun (Japan)" description "Magical Taruruuto-kun (Japan)" - rom ( name "Magical Taruruuto-kun (Japan).gb" size 131072 crc 9C4F54F1 md5 46031CAC5D2280D74DDA7471AB23C06E sha1 0B7723D1761A61DCF42FC93F134B59F2232D4C37 flags verified ) + rom ( name "Magical Taruruuto-kun (Japan).gb" size 131072 crc 9c4f54f1 sha1 0B7723D1761A61DCF42FC93F134B59F2232D4C37 flags verified ) ) game ( name "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan)" description "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan)" - rom ( name "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan).gb" size 131072 crc 0AAD5217 md5 E928D1F7DFAFF38ABC7937A6E092CEC4 sha1 3BE6C6B8CEC80A0FE0F6EDBBE40496F4D077C750 flags verified ) + rom ( name "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan).gb" size 131072 crc 0aad5217 sha1 3BE6C6B8CEC80A0FE0F6EDBBE40496F4D077C750 flags verified ) ) game ( name "Magnetic Soccer (Europe)" description "Magnetic Soccer (Europe)" - rom ( name "Magnetic Soccer (Europe).gb" size 131072 crc 9C318C64 md5 27334D7717D8E3DC953BA733EF1853C4 sha1 DA24BA642FC6EA91D0FB395481840CD9060A6DE4 flags verified ) + rom ( name "Magnetic Soccer (Europe).gb" size 131072 crc 9c318c64 sha1 DA24BA642FC6EA91D0FB395481840CD9060A6DE4 flags verified ) ) game ( - name "Mahoujin Guruguru (Japan) (SGB Enhanced)" - description "Mahoujin Guruguru (Japan) (SGB Enhanced)" - rom ( name "Mahoujin Guruguru (Japan) (SGB Enhanced).gb" size 262144 crc 2D439D0D md5 81EFA6BE1EE143FBE8634AFF615EA1AD sha1 10A55C546C68CB117CC47D49304F807A7BB63687 flags verified ) -) - -game ( - name "Makai Mura Gaiden - The Demon Darkness (Japan)" - description "Makai Mura Gaiden - The Demon Darkness (Japan)" - rom ( name "Makai Mura Gaiden - The Demon Darkness (Japan).gb" size 262144 crc CFA358DE md5 DE731A5F2F4E7D16BCDC4B5953DDCC12 sha1 961D05E91288D7AD1F2E6A1C996059D7AB96FE98 ) + name "Mahoujin GuruGuru - Yuusha to Kukuri no Daibouken (Japan) (SGB Enhanced)" + description "Mahoujin GuruGuru - Yuusha to Kukuri no Daibouken (Japan) (SGB Enhanced)" + rom ( name "Mahoujin GuruGuru - Yuusha to Kukuri no Daibouken (Japan) (SGB Enhanced).gb" size 262144 crc 2d439d0d sha1 10A55C546C68CB117CC47D49304F807A7BB63687 flags verified ) ) game ( name "Makai Toushi Sa-Ga (Japan)" description "Makai Toushi Sa-Ga (Japan)" - rom ( name "Makai Toushi Sa-Ga (Japan).gb" size 131072 crc 131B09F2 md5 6EF878EBC023775F09437A2588AC5E7D sha1 7A8F770A34207FEE324431C47836F1AB317863F9 ) + rom ( name "Makai Toushi Sa-Ga (Japan).gb" size 131072 crc 131b09f2 sha1 7A8F770A34207FEE324431C47836F1AB317863F9 flags verified ) ) game ( - name "Makai Toushi Sa-Ga (Japan) (Rev A)" - description "Makai Toushi Sa-Ga (Japan) (Rev A)" - rom ( name "Makai Toushi Sa-Ga (Japan) (Rev A).gb" size 131072 crc 1953820F md5 8831343566E891E0176B6781594A1C15 sha1 CBF480BC92BD98BAE4FB79294B604D341FE58CBE flags verified ) + name "Makai Toushi Sa-Ga (Japan) (Rev 1)" + description "Makai Toushi Sa-Ga (Japan) (Rev 1)" + rom ( name "Makai Toushi Sa-Ga (Japan) (Rev 1).gb" size 131072 crc 1953820f sha1 CBF480BC92BD98BAE4FB79294B604D341FE58CBE flags verified ) +) + +game ( + name "Makaimura Gaiden - The Demon Darkness (Japan)" + description "Makaimura Gaiden - The Demon Darkness (Japan)" + rom ( name "Makaimura Gaiden - The Demon Darkness (Japan).gb" size 262144 crc cfa358de sha1 961D05E91288D7AD1F2E6A1C996059D7AB96FE98 ) ) game ( name "Malibu Beach Volleyball (USA)" description "Malibu Beach Volleyball (USA)" - rom ( name "Malibu Beach Volleyball (USA).gb" size 65536 crc DFA5DA12 md5 5E411C0F57B2D867F16084251E677D1C sha1 F7FED41B98FC8BCDC8F72C470E20B8BAB150CA33 ) + rom ( name "Malibu Beach Volleyball (USA).gb" size 65536 crc dfa5da12 sha1 F7FED41B98FC8BCDC8F72C470E20B8BAB150CA33 ) ) game ( - name "Mani 4 in 1 (China) (DMG-602 CHN)" - description "Mani 4 in 1 (China) (DMG-602 CHN)" - rom ( name "Mani 4 in 1 (China) (DMG-602 CHN).gb" size 524288 crc 5BFC3EF5 md5 D57F73C47ACA3E22F4EA2143469AB20E sha1 C0639D6C993690022200F2FA4B3094249B9335C0 flags verified ) + name "Mani 4 in 1 (China) (DMG-602)" + description "Mani 4 in 1 (China) (DMG-602)" + rom ( name "Mani 4 in 1 (China) (DMG-602).gb" size 524288 crc 5bfc3ef5 sha1 C0639D6C993690022200F2FA4B3094249B9335C0 flags verified ) ) game ( - name "Mani 4 in 1 (China) (DMG-603 CHN)" - description "Mani 4 in 1 (China) (DMG-603 CHN)" - rom ( name "Mani 4 in 1 (China) (DMG-603 CHN).gb" size 524288 crc C373AC09 md5 D9293475642991E942AC11262D8E5927 sha1 0030295574E4C518FF5CDF20FEBF6B6737426468 flags verified ) + name "Mani 4 in 1 (China) (DMG-603)" + description "Mani 4 in 1 (China) (DMG-603)" + rom ( name "Mani 4 in 1 (China) (DMG-603).gb" size 524288 crc c373ac09 sha1 0030295574E4C518FF5CDF20FEBF6B6737426468 flags verified ) ) game ( - name "Mani 4 in 1 (China) (DMG-605 CHN)" - description "Mani 4 in 1 (China) (DMG-605 CHN)" - serial "DMG-605 CHN, DMG-MMM-BEAN-M13" - rom ( name "Mani 4 in 1 (China) (DMG-605 CHN).gb" size 1048576 crc 950773EE md5 3EB5EBDA098635B2DA0021F46A959DE4 sha1 AF4706DA224D794668F3B2C68AEA7B3C16452D83 ) + name "Mani 4 in 1 (China) (DMG-605)" + description "Mani 4 in 1 (China) (DMG-605)" + rom ( name "Mani 4 in 1 (China) (DMG-605).gb" size 1048576 crc 950773ee sha1 AF4706DA224D794668F3B2C68AEA7B3C16452D83 flags verified ) ) game ( - name "Mani 4 in 1 (China) (DMG-601 CHN)" - description "Mani 4 in 1 (China) (DMG-601 CHN)" - serial "DMG-601 CHN, DMG-M161-M12" - rom ( name "Mani 4 in 1 (China) (DMG-601 CHN).gb" size 262144 crc 0C38A775 md5 60AFF2B753DF13E3702895300687DADA sha1 DFE46E066C599C17E684DDDA3FD74C5357910630 flags verified ) + name "Mani 4 in 1 (China) (DMG-601)" + description "Mani 4 in 1 (China) (DMG-601)" + rom ( name "Mani 4 in 1 (China) (DMG-601).gb" size 262144 crc 0c38a775 sha1 DFE46E066C599C17E684DDDA3FD74C5357910630 flags verified ) ) game ( - name "Mani 4 in 1 (China) (DMG-604 CHN)" - description "Mani 4 in 1 (China) (DMG-604 CHN)" - serial "DMG-604 CHN" - rom ( name "Mani 4 in 1 (China) (DMG-604 CHN).gb" size 524288 crc CB48B6D0 md5 203FD4178EE332D1B2CF24504716C885 sha1 1C79EB31A6754B4E96D33A182D36833208DC7177 ) + name "Mani 4 in 1 (China) (DMG-604)" + description "Mani 4 in 1 (China) (DMG-604)" + rom ( name "Mani 4 in 1 (China) (DMG-604).gb" size 524288 crc cb48b6d0 sha1 1C79EB31A6754B4E96D33A182D36833208DC7177 flags verified ) ) game ( name "Marble Madness (USA, Europe)" description "Marble Madness (USA, Europe)" - rom ( name "Marble Madness (USA, Europe).gb" size 262144 crc B9725E66 md5 F489B8EB7DC88A39842F20A7F7165E5B sha1 BF2A73F7ADF200410038350C2C754A943D841681 flags verified ) + rom ( name "Marble Madness (USA, Europe).gb" size 262144 crc b9725e66 sha1 BF2A73F7ADF200410038350C2C754A943D841681 flags verified ) ) game ( name "Mario & Yoshi (Europe)" description "Mario & Yoshi (Europe)" - rom ( name "Mario & Yoshi (Europe).gb" size 65536 crc 4627D88B md5 5CFF00DB388D27727A1C9FB4C303F40B sha1 9BF642EABDB51625D1EF1AC470666EC8F5F10F77 flags verified ) + rom ( name "Mario & Yoshi (Europe).gb" size 65536 crc 4627d88b sha1 9BF642EABDB51625D1EF1AC470666EC8F5F10F77 flags verified ) ) game ( name "Mario no Picross (Japan) (SGB Enhanced)" description "Mario no Picross (Japan) (SGB Enhanced)" - rom ( name "Mario no Picross (Japan) (SGB Enhanced).gb" size 262144 crc 17533700 md5 DEFE3559EF5E8D69CA95289EDB6F9F6E sha1 6B72CBFF3E224299EFF6F79E0110A477B8F840C2 flags verified ) + rom ( name "Mario no Picross (Japan) (SGB Enhanced).gb" size 262144 crc 17533700 sha1 6B72CBFF3E224299EFF6F79E0110A477B8F840C2 flags verified ) ) game ( name "Mario's Picross (USA, Europe) (SGB Enhanced)" description "Mario's Picross (USA, Europe) (SGB Enhanced)" - rom ( name "Mario's Picross (USA, Europe) (SGB Enhanced).gb" size 262144 crc F2D652AD md5 CCAF9331318D4DFE3D1EE681928A74FD sha1 9712F37171B8A0CDC99A60170EA7B2AED161195E flags verified ) + rom ( name "Mario's Picross (USA, Europe) (SGB Enhanced).gb" size 262144 crc f2d652ad sha1 9712F37171B8A0CDC99A60170EA7B2AED161195E flags verified ) ) game ( name "Marmalade Boy (Japan) (SGB Enhanced)" description "Marmalade Boy (Japan) (SGB Enhanced)" - rom ( name "Marmalade Boy (Japan) (SGB Enhanced).gb" size 262144 crc 0F3FF7DA md5 F5155252FF84EA0F708154CFE46A31D7 sha1 60125690B7A354FF8E72F497C8A88ECD691E7E4B ) + rom ( name "Marmalade Boy (Japan) (SGB Enhanced).gb" size 262144 crc 0f3ff7da sha1 60125690B7A354FF8E72F497C8A88ECD691E7E4B flags verified ) ) game ( name "Maru's Mission (USA)" description "Maru's Mission (USA)" - rom ( name "Maru's Mission (USA).gb" size 131072 crc 6E4F1EB3 md5 7F26DD90F8E80B52EAD8FC0E3609D4F2 sha1 91446B1CC6DBF3B98B81F13E35FFE7BFAAA027AA flags verified ) + rom ( name "Maru's Mission (USA).gb" size 131072 crc 6e4f1eb3 sha1 91446B1CC6DBF3B98B81F13E35FFE7BFAAA027AA flags verified ) ) game ( name "Masakari Densetsu - Kintarou Action Hen (Japan)" description "Masakari Densetsu - Kintarou Action Hen (Japan)" - rom ( name "Masakari Densetsu - Kintarou Action Hen (Japan).gb" size 262144 crc 7CB70D3D md5 33349AD9019762B79C467CD241D79344 sha1 EC23AF3D5590B75B2A3B33708A4FE5CFFE495A1F flags verified ) + rom ( name "Masakari Densetsu - Kintarou Action Hen (Japan).gb" size 262144 crc 7cb70d3d sha1 EC23AF3D5590B75B2A3B33708A4FE5CFFE495A1F flags verified ) ) game ( name "Masakari Densetsu - Kintarou RPG Hen (Japan) (SGB Enhanced)" description "Masakari Densetsu - Kintarou RPG Hen (Japan) (SGB Enhanced)" - rom ( name "Masakari Densetsu - Kintarou RPG Hen (Japan) (SGB Enhanced).gb" size 524288 crc D8BAB8E0 md5 35B1621D14B27CACE027BD710ED6040B sha1 A9BCB90DF5B19A372CEED81C614BB7EB295EC74C flags verified ) + rom ( name "Masakari Densetsu - Kintarou RPG Hen (Japan) (SGB Enhanced).gb" size 524288 crc d8bab8e0 sha1 A9BCB90DF5B19A372CEED81C614BB7EB295EC74C flags verified ) ) game ( name "Master Karateka (Japan)" description "Master Karateka (Japan)" - rom ( name "Master Karateka (Japan).gb" size 32768 crc 4C0FB33E md5 8076DB86C921743AEDD82B12D139C3C3 sha1 1FFEA01D8D91F026CE6677631BCB10991092FF13 flags verified ) + rom ( name "Master Karateka (Japan).gb" size 32768 crc 4c0fb33e sha1 1FFEA01D8D91F026CE6677631BCB10991092FF13 flags verified ) ) game ( name "Matthias Sammer Soccer (Germany) (SGB Enhanced)" description "Matthias Sammer Soccer (Germany) (SGB Enhanced)" - rom ( name "Matthias Sammer Soccer (Germany) (SGB Enhanced).gb" size 262144 crc 631E656F md5 4097F89B7F66168FD977F2DF42DB15EC sha1 EADC06E71EA4F04700E2ED1EF232B6E57CB48725 flags verified ) + rom ( name "Matthias Sammer Soccer (Germany) (SGB Enhanced).gb" size 262144 crc 631e656f sha1 EADC06E71EA4F04700E2ED1EF232B6E57CB48725 flags verified ) ) game ( - name "Maui Mallard (USA)" - description "Maui Mallard (USA)" - rom ( name "Maui Mallard (USA).gb" size 262144 crc 6F30A43A md5 6DFCAEBFFC8E2645BB2B1E5BE69E1514 sha1 EB401C5DDFF1488013FF032918ED365E82104AE0 ) + name "Maui Mallard in Cold Shadow (USA)" + description "Maui Mallard in Cold Shadow (USA)" + rom ( name "Maui Mallard in Cold Shadow (USA).gb" size 262144 crc 6f30a43a sha1 EB401C5DDFF1488013FF032918ED365E82104AE0 ) ) game ( name "Maus, Die (Europe) (En,Fr,De,Es)" description "Maus, Die (Europe) (En,Fr,De,Es)" - rom ( name "Maus, Die (Europe) (En,Fr,De,Es).gb" size 262144 crc 478F573C md5 FF3B9E42AA323EF0045A6000F6010764 sha1 BF2B9D7A54FF0B80C2710F747F5457578CAA0CD0 flags verified ) + rom ( name "Maus, Die (Europe) (En,Fr,De,Es).gb" size 262144 crc 478f573c sha1 BF2B9D7A54FF0B80C2710F747F5457578CAA0CD0 flags verified ) ) game ( name "Max (Europe)" description "Max (Europe)" - rom ( name "Max (Europe).gb" size 65536 crc 1B167F00 md5 660A98B774E7D136E302DFE6557405E9 sha1 1F995332AE8A8832C178B22505D05080BF978AA8 flags verified ) + rom ( name "Max (Europe).gb" size 65536 crc 1b167f00 sha1 1F995332AE8A8832C178B22505D05080BF978AA8 flags verified ) ) game ( name "McDonaldland (Europe)" description "McDonaldland (Europe)" - rom ( name "McDonaldland (Europe).gb" size 131072 crc 81DE6C13 md5 DCF79D785D5CE187F727F7DC2E00DC8C sha1 FD11D61F961A7E3C69E272EF19EB243B7DF89833 flags verified ) + rom ( name "McDonaldland (Europe).gb" size 131072 crc 81de6c13 sha1 FD11D61F961A7E3C69E272EF19EB243B7DF89833 flags verified ) ) game ( name "Medarot - Kabuto Version (Japan) (SGB Enhanced)" description "Medarot - Kabuto Version (Japan) (SGB Enhanced)" - rom ( name "Medarot - Kabuto Version (Japan) (SGB Enhanced).gb" size 524288 crc 1BAB9900 md5 A849BC6810AE27DE442AB9AA354EA594 sha1 AE26B9310AB41D94A73B807EF5F30E2D0E34D667 flags verified ) + rom ( name "Medarot - Kabuto Version (Japan) (SGB Enhanced).gb" size 524288 crc 1bab9900 sha1 AE26B9310AB41D94A73B807EF5F30E2D0E34D667 flags verified ) ) game ( - name "Medarot - Kabuto Version (Japan) (Rev A) (SGB Enhanced)" - description "Medarot - Kabuto Version (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Medarot - Kabuto Version (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc 12A3982D md5 78C568CBFFF6314B1416880D9EFAECA6 sha1 1CBC7AB5941DC27BC50699A00EF2B1BEB930449D flags verified ) + name "Medarot - Kabuto Version (Japan) (Rev 1) (SGB Enhanced)" + description "Medarot - Kabuto Version (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Medarot - Kabuto Version (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc 12a3982d sha1 1CBC7AB5941DC27BC50699A00EF2B1BEB930449D flags verified ) ) game ( name "Medarot - Kuwagata Version (Japan) (SGB Enhanced)" description "Medarot - Kuwagata Version (Japan) (SGB Enhanced)" - rom ( name "Medarot - Kuwagata Version (Japan) (SGB Enhanced).gb" size 524288 crc BC0588C4 md5 D6CF6D5B5A86292D88116B9C4EBEE091 sha1 F657F822ED15E459C4ABCD171C9620CDDBDFD022 ) + rom ( name "Medarot - Kuwagata Version (Japan) (SGB Enhanced).gb" size 524288 crc bc0588c4 sha1 F657F822ED15E459C4ABCD171C9620CDDBDFD022 ) ) game ( - name "Medarot - Kuwagata Version (Japan) (Rev A) (SGB Enhanced)" - description "Medarot - Kuwagata Version (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Medarot - Kuwagata Version (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc 5E77E82E md5 A9C9D6B6759C28F2B3986717F4DF2F98 sha1 2262F69A89ABE0F66DC1554C1EE470FD536130A3 flags verified ) + name "Medarot - Kuwagata Version (Japan) (Rev 1) (SGB Enhanced)" + description "Medarot - Kuwagata Version (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Medarot - Kuwagata Version (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc 5e77e82e sha1 2262F69A89ABE0F66DC1554C1EE470FD536130A3 flags verified ) ) game ( name "Medarot - Parts Collection (Japan) (SGB Enhanced)" description "Medarot - Parts Collection (Japan) (SGB Enhanced)" - rom ( name "Medarot - Parts Collection (Japan) (SGB Enhanced).gb" size 524288 crc F4CAB596 md5 A83D745AE8806A04D4A9E3C241F8C8CB sha1 EEC1245ABB1D97CD2DF976FDF179C924A4EFA720 ) + rom ( name "Medarot - Parts Collection (Japan) (SGB Enhanced).gb" size 524288 crc f4cab596 sha1 EEC1245ABB1D97CD2DF976FDF179C924A4EFA720 flags verified ) ) game ( name "Medarot - Parts Collection 2 (Japan) (SGB Enhanced)" description "Medarot - Parts Collection 2 (Japan) (SGB Enhanced)" - rom ( name "Medarot - Parts Collection 2 (Japan) (SGB Enhanced).gb" size 524288 crc 89F94482 md5 E1C096F4953421F7FEDB767ADB675EC7 sha1 EDD74AFBFCA5E3D3366FB231C4BEDD80FCF8A81E ) + rom ( name "Medarot - Parts Collection 2 (Japan) (SGB Enhanced).gb" size 524288 crc 89f94482 sha1 EDD74AFBFCA5E3D3366FB231C4BEDD80FCF8A81E flags verified ) ) game ( name "Mega Man - Dr. Wily's Revenge (Europe)" description "Mega Man - Dr. Wily's Revenge (Europe)" - rom ( name "Mega Man - Dr. Wily's Revenge (Europe).gb" size 262144 crc 2EA4B976 md5 2C1358474573C9DD38D6A128F4714A86 sha1 11255A24344E9FED53B8F1F6F894D21E161A0D5E flags verified ) + rom ( name "Mega Man - Dr. Wily's Revenge (Europe).gb" size 262144 crc 2ea4b976 sha1 11255A24344E9FED53B8F1F6F894D21E161A0D5E flags verified ) ) game ( name "Mega Man - Dr. Wily's Revenge (USA)" description "Mega Man - Dr. Wily's Revenge (USA)" - rom ( name "Mega Man - Dr. Wily's Revenge (USA).gb" size 262144 crc 47E70E08 md5 4BA4398181D98958FA7434BA7716F11A sha1 277EDB3C844E812BA4B3EB9A96C9C30414541858 flags verified ) + rom ( name "Mega Man - Dr. Wily's Revenge (USA).gb" size 262144 crc 47e70e08 sha1 277EDB3C844E812BA4B3EB9A96C9C30414541858 flags verified ) ) game ( name "Mega Man II (Europe)" description "Mega Man II (Europe)" - rom ( name "Mega Man II (Europe).gb" size 262144 crc 5E90CB48 md5 B9CFEE05797BEB8FF7E259EE77EAF2FB sha1 D19993A4630E7F9450FF6469115F4095F6F29667 flags verified ) + rom ( name "Mega Man II (Europe).gb" size 262144 crc 5e90cb48 sha1 D19993A4630E7F9450FF6469115F4095F6F29667 flags verified ) ) game ( name "Mega Man II (USA)" description "Mega Man II (USA)" - rom ( name "Mega Man II (USA).gb" size 262144 crc E496F686 md5 7FE07271D04ED9E0BC0663DDE55A2AE4 sha1 334F1A93346D55E1BE2967F0AF952E37AA52FCA7 flags verified ) + rom ( name "Mega Man II (USA).gb" size 262144 crc e496f686 sha1 334F1A93346D55E1BE2967F0AF952E37AA52FCA7 flags verified ) ) game ( name "Mega Man III (Europe)" description "Mega Man III (Europe)" - rom ( name "Mega Man III (Europe).gb" size 262144 crc 03B0D4EC md5 F155C9C04EF01A99B26478C1121C8069 sha1 ECADBC9E273E4D99CCD87F98BBBD912AEC43C077 flags verified ) + rom ( name "Mega Man III (Europe).gb" size 262144 crc 03b0d4ec sha1 ECADBC9E273E4D99CCD87F98BBBD912AEC43C077 flags verified ) ) game ( name "Mega Man III (USA)" description "Mega Man III (USA)" - rom ( name "Mega Man III (USA).gb" size 262144 crc 5175D761 md5 4C614F884A07872F12056AD1A421E1F9 sha1 57347305AB297DAA4332564623C4A098E6DBB1A3 flags verified ) + rom ( name "Mega Man III (USA).gb" size 262144 crc 5175d761 sha1 57347305AB297DAA4332564623C4A098E6DBB1A3 flags verified ) ) game ( name "Mega Man IV (Europe)" description "Mega Man IV (Europe)" - serial "DMG-R4-EUR, DMG-BEAN-10" - rom ( name "Mega Man IV (Europe).gb" size 524288 crc 060B89E6 md5 B1A4DA0FC96BE115B3D5303C9CA1447F sha1 A15A05593BF9BDDDB5826B148E25182E7B90F268 ) + rom ( name "Mega Man IV (Europe).gb" size 524288 crc 060b89e6 sha1 A15A05593BF9BDDDB5826B148E25182E7B90F268 flags verified ) ) game ( name "Mega Man IV (USA)" description "Mega Man IV (USA)" - rom ( name "Mega Man IV (USA).gb" size 524288 crc ABCEA00D md5 8A00F627B8902C92327435901C249E19 sha1 6F0901DB2B5DCAACE0215C0ABDC21A914FA21B65 flags verified ) + rom ( name "Mega Man IV (USA).gb" size 524288 crc abcea00d sha1 6F0901DB2B5DCAACE0215C0ABDC21A914FA21B65 flags verified ) ) game ( name "Mega Man V (Europe) (SGB Enhanced)" description "Mega Man V (Europe) (SGB Enhanced)" - rom ( name "Mega Man V (Europe) (SGB Enhanced).gb" size 524288 crc D12AC4FE md5 B53FE06DB30AB689153135990354DD5A sha1 1A377BB0571BBE48A58B5006CCB02046EC64B076 flags verified ) + rom ( name "Mega Man V (Europe) (SGB Enhanced).gb" size 524288 crc d12ac4fe sha1 1A377BB0571BBE48A58B5006CCB02046EC64B076 flags verified ) ) game ( name "Mega Man V (USA) (SGB Enhanced)" description "Mega Man V (USA) (SGB Enhanced)" - rom ( name "Mega Man V (USA) (SGB Enhanced).gb" size 524288 crc 72E6D21D md5 CEB17D831B410D91AA41BF2819CBED82 sha1 9A7DA0E4D3F49E4A0B94E85CD64E28A687D81260 ) + rom ( name "Mega Man V (USA) (SGB Enhanced).gb" size 524288 crc 72e6d21d sha1 9A7DA0E4D3F49E4A0B94E85CD64E28A687D81260 ) ) game ( name "Megalit (Japan)" description "Megalit (Japan)" - rom ( name "Megalit (Japan).gb" size 131072 crc C764B1F2 md5 24C5CEC170F19493C6013B4CCAEE1E35 sha1 C40E35CF3C7AF6CFF9E079543650F51CF9777018 ) + rom ( name "Megalit (Japan).gb" size 131072 crc c764b1f2 sha1 C40E35CF3C7AF6CFF9E079543650F51CF9777018 ) ) game ( name "Megalit (USA, Europe)" description "Megalit (USA, Europe)" - rom ( name "Megalit (USA, Europe).gb" size 65536 crc F315B842 md5 45B5142059907DBD92AAF3F8D003721B sha1 7F3F6B1CC543228BCDD336DFCD1865A3C8D7D177 flags verified ) + rom ( name "Megalit (USA, Europe).gb" size 65536 crc f315b842 sha1 7F3F6B1CC543228BCDD336DFCD1865A3C8D7D177 flags verified ) ) game ( name "Megami Tensei Gaiden - Last Bible (Japan)" description "Megami Tensei Gaiden - Last Bible (Japan)" - rom ( name "Megami Tensei Gaiden - Last Bible (Japan).gb" size 262144 crc FE9DD4C0 md5 2215684318211E85135C4CD8E55F91A4 sha1 537B38234DA5164335E98F6AEE3B792048624626 ) + rom ( name "Megami Tensei Gaiden - Last Bible (Japan).gb" size 262144 crc fe9dd4c0 sha1 537B38234DA5164335E98F6AEE3B792048624626 flags verified ) ) game ( name "Megami Tensei Gaiden - Last Bible II (Japan)" description "Megami Tensei Gaiden - Last Bible II (Japan)" - rom ( name "Megami Tensei Gaiden - Last Bible II (Japan).gb" size 262144 crc F8E519D9 md5 BD08880684132809013B413CFC1051DC sha1 D7575F7F60C75DD71A7B5BE071DB57BE13237D30 flags verified ) + rom ( name "Megami Tensei Gaiden - Last Bible II (Japan).gb" size 262144 crc f8e519d9 sha1 D7575F7F60C75DD71A7B5BE071DB57BE13237D30 flags verified ) ) game ( name "Meitantei Conan - Chika Yuuenchi Satsujin Jiken (Japan) (SGB Enhanced)" description "Meitantei Conan - Chika Yuuenchi Satsujin Jiken (Japan) (SGB Enhanced)" - rom ( name "Meitantei Conan - Chika Yuuenchi Satsujin Jiken (Japan) (SGB Enhanced).gb" size 262144 crc 3945BC0D md5 7AB8EB19C5356F62BCC3FA2A8F1ABA1F sha1 2AB6749D2ABAF3FC3CB9317F64CEC78E0184FF6B flags verified ) + rom ( name "Meitantei Conan - Chika Yuuenchi Satsujin Jiken (Japan) (SGB Enhanced).gb" size 262144 crc 3945bc0d sha1 2AB6749D2ABAF3FC3CB9317F64CEC78E0184FF6B flags verified ) ) game ( name "Meitantei Conan - Giwaku no Gouka Ressha (Japan) (SGB Enhanced)" description "Meitantei Conan - Giwaku no Gouka Ressha (Japan) (SGB Enhanced)" - rom ( name "Meitantei Conan - Giwaku no Gouka Ressha (Japan) (SGB Enhanced).gb" size 262144 crc 1DC5C31A md5 F75FDE95C0C8E957C9FE76D546E5180A sha1 125DB863BAD5D48033D0BF94ED808B2B8D34CA2F flags verified ) + rom ( name "Meitantei Conan - Giwaku no Gouka Ressha (Japan) (SGB Enhanced).gb" size 262144 crc 1dc5c31a sha1 125DB863BAD5D48033D0BF94ED808B2B8D34CA2F flags verified ) ) game ( name "Mercenary Force (USA, Europe)" description "Mercenary Force (USA, Europe)" - rom ( name "Mercenary Force (USA, Europe).gb" size 131072 crc 9BB5BA03 md5 BF3D90FF1C8D4827B5657D7B15D84FDE sha1 35BBDE8934792588620D1C242DEDEF1DA9097A2E flags verified ) + rom ( name "Mercenary Force (USA, Europe).gb" size 131072 crc 9bb5ba03 sha1 35BBDE8934792588620D1C242DEDEF1DA9097A2E flags verified ) ) game ( name "Metal Masters (USA)" description "Metal Masters (USA)" - rom ( name "Metal Masters (USA).gb" size 131072 crc BF6866DC md5 680C8FBB0BC15C850121EF2C929DF177 sha1 CAAE5811B2D2B884B691EA7D940ECB86647CD250 flags verified ) + rom ( name "Metal Masters (USA).gb" size 131072 crc bf6866dc sha1 CAAE5811B2D2B884B691EA7D940ECB86647CD250 flags verified ) ) game ( name "Metroid II - Return of Samus (World)" description "Metroid II - Return of Samus (World)" - rom ( name "Metroid II - Return of Samus (World).gb" size 262144 crc DEE05370 md5 9639948AD274FA15281F549E5F9C4D87 sha1 74A2FAD86B9A4C013149B1E214BC4600EFB1066D flags verified ) + rom ( name "Metroid II - Return of Samus (World).gb" size 262144 crc dee05370 sha1 74A2FAD86B9A4C013149B1E214BC4600EFB1066D flags verified ) +) + +game ( + name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-07-20)" + description "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-07-20)" + rom ( name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-07-20).gb" size 131072 crc 1e8a59c2 sha1 81456302F06DD7B026854ABBF8BB34804A14DFA1 flags verified ) +) + +game ( + name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-09-27)" + description "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-09-27)" + rom ( name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-09-27).gb" size 131072 crc 016ae810 sha1 0108D3B03232FDC57DD087F823B6F0C2C1669629 flags verified ) +) + +game ( + name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-10-04)" + description "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-10-04)" + rom ( name "Mick & Mack as the Global Gladiators (USA) (Proto) (1993-10-04).gb" size 131072 crc 2646f927 sha1 9EB948563E05D6F242FB5BB4759856E8EDF17DA5 flags verified ) +) + +game ( + name "Mick & Mack as the Global Gladiators (USA) (Proto) (1994-01-18)" + description "Mick & Mack as the Global Gladiators (USA) (Proto) (1994-01-18)" + rom ( name "Mick & Mack as the Global Gladiators (USA) (Proto) (1994-01-18).gb" size 131072 crc cf486f7b sha1 A00346E49EF4D067865AF8C2638CF7418F896B2E flags verified ) ) game ( name "Mickey Mouse (Europe)" description "Mickey Mouse (Europe)" - rom ( name "Mickey Mouse (Europe).gb" size 131072 crc FC50DEE7 md5 FECC3F5A95CCAEC78F83892933D8159F sha1 B8E708DFE7496C712BD3EF171429D81CB6619252 flags verified ) + rom ( name "Mickey Mouse (Europe).gb" size 131072 crc fc50dee7 sha1 B8E708DFE7496C712BD3EF171429D81CB6619252 flags verified ) ) game ( name "Mickey Mouse (Japan)" description "Mickey Mouse (Japan)" - rom ( name "Mickey Mouse (Japan).gb" size 65536 crc 4CA75D4D md5 C58EDFFDB628EA2FC904D4B8C93B6CBC sha1 A5E526B47E9295C7CBEA21A84BEF2C1658E6F87E flags verified ) + rom ( name "Mickey Mouse (Japan).gb" size 65536 crc 4ca75d4d sha1 A5E526B47E9295C7CBEA21A84BEF2C1658E6F87E flags verified ) ) game ( - name "Mickey Mouse - Magic Wands (USA, Europe) (SGB Enhanced)" - description "Mickey Mouse - Magic Wands (USA, Europe) (SGB Enhanced)" - rom ( name "Mickey Mouse - Magic Wands (USA, Europe) (SGB Enhanced).gb" size 131072 crc F0482567 md5 38B65D28AC0BD619F5DEE5A45D5FC542 sha1 90A181EE7D42941BCE3B425077D6570DA0E2FB2C flags verified ) + name "Mickey Mouse - Magic Wands! (USA, Europe) (SGB Enhanced)" + description "Mickey Mouse - Magic Wands! (USA, Europe) (SGB Enhanced)" + rom ( name "Mickey Mouse - Magic Wands! (USA, Europe) (SGB Enhanced).gb" size 131072 crc f0482567 sha1 90A181EE7D42941BCE3B425077D6570DA0E2FB2C flags verified ) ) game ( name "Mickey Mouse II (Japan)" description "Mickey Mouse II (Japan)" - rom ( name "Mickey Mouse II (Japan).gb" size 131072 crc DFEE8BCC md5 9F5DDC6EE110A6843B1D9D9A08514C71 sha1 2D44566D2D74F573D2FAF23988A3070ABB47555D ) + rom ( name "Mickey Mouse II (Japan).gb" size 131072 crc dfee8bcc sha1 2D44566D2D74F573D2FAF23988A3070ABB47555D flags verified ) ) game ( - name "Mickey Mouse IV (Japan)" - description "Mickey Mouse IV (Japan)" - rom ( name "Mickey Mouse IV (Japan).gb" size 131072 crc 0D30B3A1 md5 744DC7E4B03D16B8B6DD35A697C77892 sha1 D091D67890103CA97CAF2C46D6BF4E2A85C92383 ) + name "Mickey Mouse IV - Mahou no Labyrinth (Japan)" + description "Mickey Mouse IV - Mahou no Labyrinth (Japan)" + rom ( name "Mickey Mouse IV - Mahou no Labyrinth (Japan).gb" size 131072 crc 0d30b3a1 sha1 D091D67890103CA97CAF2C46D6BF4E2A85C92383 flags verified ) ) game ( name "Mickey Mouse V (Japan)" description "Mickey Mouse V (Japan)" - rom ( name "Mickey Mouse V (Japan).gb" size 131072 crc 44CD01DD md5 B1864AB2FA592AA7E8337C308DF08047 sha1 B8537BEF22696FEADF51343B6E1697370C4A8D5A ) + rom ( name "Mickey Mouse V (Japan).gb" size 131072 crc 44cd01dd sha1 B8537BEF22696FEADF51343B6E1697370C4A8D5A ) +) + +game ( + name "Mickey Mouse V (Japan) (Rev 1)" + description "Mickey Mouse V (Japan) (Rev 1)" + rom ( name "Mickey Mouse V (Japan) (Rev 1).gb" size 131072 crc 464eaa5d sha1 095285EC078124E3A4CBBFA3AC0D7680EE491E2B flags verified ) ) game ( name "Mickey's Chase (Japan)" description "Mickey's Chase (Japan)" - rom ( name "Mickey's Chase (Japan).gb" size 131072 crc 0AB490C8 md5 9CD7F210AE2680349078ACA844BE5354 sha1 BD890E13F7518513178F324D6FC5D28BC22E5BFB flags verified ) + rom ( name "Mickey's Chase (Japan).gb" size 131072 crc 0ab490c8 sha1 BD890E13F7518513178F324D6FC5D28BC22E5BFB flags verified ) ) game ( name "Mickey's Dangerous Chase (Europe)" description "Mickey's Dangerous Chase (Europe)" - rom ( name "Mickey's Dangerous Chase (Europe).gb" size 131072 crc E72DB762 md5 B0195767BF5D839E4CC4C837A4709B54 sha1 1F749B9A805B28EE2F130DA9E0E941A0427683D4 flags verified ) + rom ( name "Mickey's Dangerous Chase (Europe).gb" size 131072 crc e72db762 sha1 1F749B9A805B28EE2F130DA9E0E941A0427683D4 flags verified ) ) game ( name "Mickey's Dangerous Chase (USA)" description "Mickey's Dangerous Chase (USA)" - rom ( name "Mickey's Dangerous Chase (USA).gb" size 131072 crc 7B822D8F md5 16BC18EF00088094E9FAD502E613BE5E sha1 37D0737BE3773AD62664645D34505A136F0BE99B flags verified ) + rom ( name "Mickey's Dangerous Chase (USA).gb" size 131072 crc 7b822d8f sha1 37D0737BE3773AD62664645D34505A136F0BE99B flags verified ) ) game ( name "Mickey's Ultimate Challenge (USA, Europe)" description "Mickey's Ultimate Challenge (USA, Europe)" - rom ( name "Mickey's Ultimate Challenge (USA, Europe).gb" size 262144 crc 23E9D625 md5 F7D266BC81C150796AE373BDDD0A9A84 sha1 CEBDC7B9F5764AEBAB116BA0A5D06C67CD4BEA84 flags verified ) + rom ( name "Mickey's Ultimate Challenge (USA, Europe).gb" size 262144 crc 23e9d625 sha1 CEBDC7B9F5764AEBAB116BA0A5D06C67CD4BEA84 flags verified ) ) game ( name "Micro Machines (USA, Europe)" description "Micro Machines (USA, Europe)" - rom ( name "Micro Machines (USA, Europe).gb" size 262144 crc 2088F85F md5 0631158EAD23BFED84CD3A5010EB9295 sha1 62C07BAA3ED0CCAF704399F05FE90569D90C6EFF flags verified ) + rom ( name "Micro Machines (USA, Europe).gb" size 262144 crc 2088f85f sha1 62C07BAA3ED0CCAF704399F05FE90569D90C6EFF flags verified ) ) game ( name "Micro Machines 2 - Turbo Tournament (Europe)" description "Micro Machines 2 - Turbo Tournament (Europe)" - rom ( name "Micro Machines 2 - Turbo Tournament (Europe).gb" size 524288 crc 24666C4D md5 750D2AF7347FB539698655AE946A880A sha1 50FEA244C7B8C982421FCCD67BC8177CF510A306 flags verified ) + rom ( name "Micro Machines 2 - Turbo Tournament (Europe).gb" size 524288 crc 24666c4d sha1 50FEA244C7B8C982421FCCD67BC8177CF510A306 flags verified ) ) game ( name "Midori no Makibaou (Japan) (SGB Enhanced)" description "Midori no Makibaou (Japan) (SGB Enhanced)" - rom ( name "Midori no Makibaou (Japan) (SGB Enhanced).gb" size 262144 crc 1DD93D95 md5 C29DF42EF1237C4392049196D2205FFE sha1 4DE380B202E375761F9FE7FB13349F5B02E2DAC2 flags verified ) + rom ( name "Midori no Makibaou (Japan) (SGB Enhanced).gb" size 262144 crc 1dd93d95 sha1 4DE380B202E375761F9FE7FB13349F5B02E2DAC2 flags verified ) ) game ( name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" description "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced)" - rom ( name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced).gb" size 262144 crc C60D032A md5 5B83DB9958EEFBD72A82C4893E79D9E1 sha1 EF88476D9A1A26B67F3535AE7AFCF5156578E38C flags verified ) + rom ( name "Mighty Morphin Power Rangers (USA, Europe) (SGB Enhanced).gb" size 262144 crc c60d032a sha1 EF88476D9A1A26B67F3535AE7AFCF5156578E38C flags verified ) ) game ( name "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced)" description "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced)" - rom ( name "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced).gb" size 262144 crc 86A1C549 md5 967473063A55634223F15E4C0A79DC44 sha1 0646BFF26350059224A5DCA807218FF02A4704AF flags verified ) + rom ( name "Mighty Morphin Power Rangers - The Movie (USA, Europe) (SGB Enhanced).gb" size 262144 crc 86a1c549 sha1 0646BFF26350059224A5DCA807218FF02A4704AF flags verified ) ) game ( name "Migrain (Japan)" description "Migrain (Japan)" - rom ( name "Migrain (Japan).gb" size 32768 crc CED936F8 md5 78FB0BD56717488E313AEB3E47F936C8 sha1 98EA7EAB4048CBD0E4AA5F88E9A831E522C493D5 ) + rom ( name "Migrain (Japan).gb" size 32768 crc ced936f8 sha1 98EA7EAB4048CBD0E4AA5F88E9A831E522C493D5 ) ) game ( name "Mikeneko Holmes no Kishidou (Japan)" description "Mikeneko Holmes no Kishidou (Japan)" - rom ( name "Mikeneko Holmes no Kishidou (Japan).gb" size 131072 crc 73B80B16 md5 01DEDF212717562BBC2730A4F5947CD4 sha1 0FA85AF4827F141CF3E6788B3BFDBC134D1A80C5 ) + rom ( name "Mikeneko Holmes no Kishidou (Japan).gb" size 131072 crc 73b80b16 sha1 0FA85AF4827F141CF3E6788B3BFDBC134D1A80C5 ) ) game ( name "Milon no Meikyuu Kumikyoku (Japan)" description "Milon no Meikyuu Kumikyoku (Japan)" - rom ( name "Milon no Meikyuu Kumikyoku (Japan).gb" size 131072 crc F188C94C md5 3F2335F849FD02769099AC3BD6D81337 sha1 95E6473824B7671140C738E0D3BFDBE2B1F39480 flags verified ) + rom ( name "Milon no Meikyuu Kumikyoku (Japan).gb" size 131072 crc f188c94c sha1 95E6473824B7671140C738E0D3BFDBE2B1F39480 flags verified ) ) game ( name "Milon's Secret Castle (USA, Europe)" description "Milon's Secret Castle (USA, Europe)" - rom ( name "Milon's Secret Castle (USA, Europe).gb" size 131072 crc 62B4CC8C md5 1F93249C298F3ECDC4099602D9DEDBB5 sha1 40FF7865B543C9B6A3C2DDE542819018E7F06FA8 flags verified ) + rom ( name "Milon's Secret Castle (USA, Europe).gb" size 131072 crc 62b4cc8c sha1 40FF7865B543C9B6A3C2DDE542819018E7F06FA8 flags verified ) ) game ( name "Miner 2049er Starring Bounty Bob (USA)" description "Miner 2049er Starring Bounty Bob (USA)" - rom ( name "Miner 2049er Starring Bounty Bob (USA).gb" size 65536 crc 1A6BD577 md5 E5EBA5278BBC6E5F040649AFE98A0AF4 sha1 6F62BF7F88263470DFA61D6752B345573F10CD8F ) + rom ( name "Miner 2049er Starring Bounty Bob (USA).gb" size 65536 crc 1a6bd577 sha1 6F62BF7F88263470DFA61D6752B345573F10CD8F ) ) game ( name "Minesweeper - Soukaitei (Japan)" description "Minesweeper - Soukaitei (Japan)" - rom ( name "Minesweeper - Soukaitei (Japan).gb" size 32768 crc 5532B3D1 md5 A36B4C6C13D1DC9A98AF66F963858BA9 sha1 8538358957B2F6D6C58E2CEB2C83CF82149985FD ) + rom ( name "Minesweeper - Soukaitei (Japan).gb" size 32768 crc 5532b3d1 sha1 8538358957B2F6D6C58E2CEB2C83CF82149985FD ) ) game ( name "Mini 4 Boy (Japan) (SGB Enhanced)" description "Mini 4 Boy (Japan) (SGB Enhanced)" - rom ( name "Mini 4 Boy (Japan) (SGB Enhanced).gb" size 524288 crc 0618E4B0 md5 04EC032CD1F6DAB8F7737D422D129C70 sha1 CB6022EF5729CBF370CCDC9C1958D0B4BCBD5E90 flags verified ) + rom ( name "Mini 4 Boy (Japan) (SGB Enhanced).gb" size 524288 crc 0618e4b0 sha1 CB6022EF5729CBF370CCDC9C1958D0B4BCBD5E90 flags verified ) ) game ( - name "Mini 4 Boy II - Final Evolution (Japan) (SGB Enhanced)" - description "Mini 4 Boy II - Final Evolution (Japan) (SGB Enhanced)" - rom ( name "Mini 4 Boy II - Final Evolution (Japan) (SGB Enhanced).gb" size 524288 crc D6962241 md5 A58397C62D44A60FA08D3F51CD8385C6 sha1 EEBCF67AB1455501F1B758AB71A8DC22808B34F1 ) -) - -game ( - name "Mini Putt (Japan)" - description "Mini Putt (Japan)" - rom ( name "Mini Putt (Japan).gb" size 65536 crc 33CD7550 md5 872B8EB18385ED6B1937B42436AF56FD sha1 E2A75FC09D8F9E56325449CA91CDA9A68D058C1F ) + name "Mini 4 Boy II (Japan) (SGB Enhanced)" + description "Mini 4 Boy II (Japan) (SGB Enhanced)" + rom ( name "Mini 4 Boy II (Japan) (SGB Enhanced).gb" size 524288 crc d6962241 sha1 EEBCF67AB1455501F1B758AB71A8DC22808B34F1 flags verified ) ) game ( name "Mini Yonku GB Let's & Go!! (Japan) (SGB Enhanced)" description "Mini Yonku GB Let's & Go!! (Japan) (SGB Enhanced)" - rom ( name "Mini Yonku GB Let's & Go!! (Japan) (SGB Enhanced).gb" size 524288 crc FC0C180B md5 9835DFEDDB332A9C9E1C2269E7863AF9 sha1 A51DC3EA1961297A3056E0326C8A153F496DAE8A flags verified ) + rom ( name "Mini Yonku GB Let's & Go!! (Japan) (SGB Enhanced).gb" size 524288 crc fc0c180b sha1 A51DC3EA1961297A3056E0326C8A153F496DAE8A flags verified ) ) game ( name "Mini Yonku GB Let's & Go!! - All-Star Battle Max (Japan) (SGB Enhanced)" description "Mini Yonku GB Let's & Go!! - All-Star Battle Max (Japan) (SGB Enhanced)" - rom ( name "Mini Yonku GB Let's & Go!! - All-Star Battle Max (Japan) (SGB Enhanced).gb" size 1048576 crc 97EBD21D md5 7E17B120B34823D2E6BD61CDD08ECC2A sha1 CA662CB506B553F1730C29C088E597BACE1E0052 flags verified ) + rom ( name "Mini Yonku GB Let's & Go!! - All-Star Battle Max (Japan) (SGB Enhanced).gb" size 1048576 crc 97ebd21d sha1 CA662CB506B553F1730C29C088E597BACE1E0052 flags verified ) +) + +game ( + name "Mini-Putt (Japan)" + description "Mini-Putt (Japan)" + rom ( name "Mini-Putt (Japan).gb" size 65536 crc 33cd7550 sha1 E2A75FC09D8F9E56325449CA91CDA9A68D058C1F flags verified ) +) + +game ( + name "Minolta Camera Test Cart 2420 (USA)" + description "Minolta Camera Test Cart 2420 (USA)" + rom ( name "Minolta Camera Test Cart 2420 (USA).gb" size 32768 crc 97561d80 sha1 A55A5FD97CA1BE3FA129F744F81FC972E29418AC flags verified ) +) + +game ( + name "Minolta Camera Test Cart 2440 (USA)" + description "Minolta Camera Test Cart 2440 (USA)" + rom ( name "Minolta Camera Test Cart 2440 (USA).gb" size 32768 crc 7a9359ea sha1 C15325E2E0AD2C8BD4323EF2390DF28E578DCDB8 flags verified ) ) game ( name "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan)" description "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan)" - rom ( name "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan).gb" size 131072 crc B3AD9B76 md5 64080619789F154EE057F2946A98C61C sha1 27B272AFF632F7E8CA72E87627CE37336666C952 flags verified ) + rom ( name "Miracle Adventure of Esparks - Ushinawareta Seiseki Perivron (Japan).gb" size 131072 crc b3ad9b76 sha1 27B272AFF632F7E8CA72E87627CE37336666C952 flags verified ) ) game ( name "Missile Command (USA, Europe)" description "Missile Command (USA, Europe)" - rom ( name "Missile Command (USA, Europe).gb" size 32768 crc 3A6CD4D8 md5 FF0033CEECD7562360C5D5D3CAE76575 sha1 ED529062AE3D1FEB4DEFBF54C2CC759211E3AEAA flags verified ) + rom ( name "Missile Command (USA, Europe).gb" size 32768 crc 3a6cd4d8 sha1 ED529062AE3D1FEB4DEFBF54C2CC759211E3AEAA flags verified ) ) game ( - name "Mogu Mogu Gombo (Japan) (SGB Enhanced)" - description "Mogu Mogu Gombo (Japan) (SGB Enhanced)" - rom ( name "Mogu Mogu Gombo (Japan) (SGB Enhanced).gb" size 262144 crc 85C984F2 md5 3E0790735FCBFA6F2CD2C5C850EEED1E sha1 A4524D11F2A86E28BC319335B5C05EA6550B26E1 ) + name "Mogu Mogu Gombo - Harukanaru Chou Ryouri Densetsu (Japan) (SGB Enhanced)" + description "Mogu Mogu Gombo - Harukanaru Chou Ryouri Densetsu (Japan) (SGB Enhanced)" + rom ( name "Mogu Mogu Gombo - Harukanaru Chou Ryouri Densetsu (Japan) (SGB Enhanced).gb" size 262144 crc 85c984f2 sha1 A4524D11F2A86E28BC319335B5C05EA6550B26E1 ) ) game ( name "Mogura de Pon! (Japan)" description "Mogura de Pon! (Japan)" - rom ( name "Mogura de Pon! (Japan).gb" size 32768 crc E1E3629F md5 6EE9C4E484B70BBECAAFFAFB963F004B sha1 3C6586F3D591CEE7415ED76D92355A27AD42E1E3 flags verified ) + rom ( name "Mogura de Pon! (Japan).gb" size 32768 crc e1e3629f sha1 3C6586F3D591CEE7415ED76D92355A27AD42E1E3 flags verified ) ) game ( name "Moguranya (Japan) (SGB Enhanced)" description "Moguranya (Japan) (SGB Enhanced)" - rom ( name "Moguranya (Japan) (SGB Enhanced).gb" size 524288 crc 82FCA204 md5 4FF223851BC7E3D19ACDBF8034E4829F sha1 16B6355019E4E0EB8871D6CB16AABB971AB1B62A flags verified ) + rom ( name "Moguranya (Japan) (SGB Enhanced).gb" size 524288 crc 82fca204 sha1 16B6355019E4E0EB8871D6CB16AABB971AB1B62A flags verified ) ) game ( name "Mole Mania (USA, Europe) (SGB Enhanced)" description "Mole Mania (USA, Europe) (SGB Enhanced)" - rom ( name "Mole Mania (USA, Europe) (SGB Enhanced).gb" size 524288 crc 2C36C74C md5 F28ADE3926852A8AD2E449C274683956 sha1 37085973519D61E17797693B23016493DA56A462 flags verified ) + rom ( name "Mole Mania (USA, Europe) (SGB Enhanced).gb" size 524288 crc 2c36c74c sha1 37085973519D61E17797693B23016493DA56A462 flags verified ) ) game ( name "Momotarou Collection (Japan) (SGB Enhanced)" description "Momotarou Collection (Japan) (SGB Enhanced)" - rom ( name "Momotarou Collection (Japan) (SGB Enhanced).gb" size 1048576 crc AD376905 md5 6832C643107D2966E17B3A52CF80A485 sha1 CD7088D13F5B80F32C0FAE95A57969F6F33A9A02 flags verified ) + rom ( name "Momotarou Collection (Japan) (SGB Enhanced).gb" size 1048576 crc ad376905 sha1 CD7088D13F5B80F32C0FAE95A57969F6F33A9A02 flags verified ) ) game ( name "Momotarou Collection 2 (Japan) (SGB Enhanced)" description "Momotarou Collection 2 (Japan) (SGB Enhanced)" - rom ( name "Momotarou Collection 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 562C8F7F md5 2B589E58D8821C59B7AF702723361DB5 sha1 0D6BD573AE696B337D107EFF2AEE502BB240A40C flags verified ) + rom ( name "Momotarou Collection 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 562c8f7f sha1 0D6BD573AE696B337D107EFF2AEE502BB240A40C flags verified ) ) game ( name "Momotarou Dengeki (Japan)" description "Momotarou Dengeki (Japan)" - rom ( name "Momotarou Dengeki (Japan).gb" size 262144 crc F09B34AB md5 F31C556186B91CF161ECF60644FBECBA sha1 8450758A8338700468F862C73F344C63B921812F ) + rom ( name "Momotarou Dengeki (Japan).gb" size 262144 crc f09b34ab sha1 8450758A8338700468F862C73F344C63B921812F ) ) game ( name "Momotarou Dengeki 2 (Japan) (SGB Enhanced)" description "Momotarou Dengeki 2 (Japan) (SGB Enhanced)" - rom ( name "Momotarou Dengeki 2 (Japan) (SGB Enhanced).gb" size 524288 crc 3C1C5EB4 md5 872B72113281DC0A906B033B8F8E4E76 sha1 F050CC860E610A07A27C51FF873DD71ACA9E23E6 ) + rom ( name "Momotarou Dengeki 2 (Japan) (SGB Enhanced).gb" size 524288 crc 3c1c5eb4 sha1 F050CC860E610A07A27C51FF873DD71ACA9E23E6 flags verified ) ) game ( name "Momotarou Densetsu Gaiden (Japan)" description "Momotarou Densetsu Gaiden (Japan)" - rom ( name "Momotarou Densetsu Gaiden (Japan).gb" size 262144 crc BA5611EF md5 5526C1396E574E92EC8F467C0DE80377 sha1 1A819534E7E29A17D5644EF190998CEA781A69A6 flags verified ) + rom ( name "Momotarou Densetsu Gaiden (Japan).gb" size 262144 crc ba5611ef sha1 1A819534E7E29A17D5644EF190998CEA781A69A6 flags verified ) ) game ( name "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced)" description "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced)" - rom ( name "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced).gb" size 524288 crc 218265B3 md5 2A5FC7ED564D290E04FBB5968480DB52 sha1 30EDF17FC9DDD9DB7613C8F78B0EBC340CC89EB0 flags verified ) + rom ( name "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced).gb" size 524288 crc 218265b3 sha1 30EDF17FC9DDD9DB7613C8F78B0EBC340CC89EB0 flags verified ) ) game ( name "Monde Perdu, Le - Jurassic Park (France) (SGB Enhanced)" description "Monde Perdu, Le - Jurassic Park (France) (SGB Enhanced)" - rom ( name "Monde Perdu, Le - Jurassic Park (France) (SGB Enhanced).gb" size 524288 crc FB22D72E md5 0EA0896DB6476D0D07CF3D35E0993849 sha1 589EFA9EF5A6CE38200A137083F856F75D75A8C6 ) + rom ( name "Monde Perdu, Le - Jurassic Park (France) (SGB Enhanced).gb" size 524288 crc fb22d72e sha1 589EFA9EF5A6CE38200A137083F856F75D75A8C6 flags verified ) ) game ( name "Money Idol Exchanger (Japan) (SGB Enhanced)" description "Money Idol Exchanger (Japan) (SGB Enhanced)" - rom ( name "Money Idol Exchanger (Japan) (SGB Enhanced).gb" size 262144 crc 800226A9 md5 05ABF83F5E7C30675801EC0D7648E03F sha1 A52CC4167316683C7DDC0B6FB5370A05AB49DBBE flags verified ) + rom ( name "Money Idol Exchanger (Japan) (SGB Enhanced).gb" size 262144 crc 800226a9 sha1 A52CC4167316683C7DDC0B6FB5370A05AB49DBBE flags verified ) ) game ( name "Monopoly (Europe) (En,Fr,De)" description "Monopoly (Europe) (En,Fr,De)" - rom ( name "Monopoly (Europe) (En,Fr,De).gb" size 262144 crc 987B621E md5 3BA194E36DDEFBD8585D9E567E9F494D sha1 D7BB71F20396B6E65E6396CA75A6D1F992A05B08 flags verified ) + rom ( name "Monopoly (Europe) (En,Fr,De).gb" size 262144 crc 987b621e sha1 D7BB71F20396B6E65E6396CA75A6D1F992A05B08 flags verified ) ) game ( name "Monopoly (Japan)" description "Monopoly (Japan)" - rom ( name "Monopoly (Japan).gb" size 262144 crc D8AC08B5 md5 1D5C3627F001D863E42DFA67C6C02EBC sha1 F6E72820E7D397528A1B225081DE96F297E12093 flags verified ) + rom ( name "Monopoly (Japan).gb" size 262144 crc d8ac08b5 sha1 F6E72820E7D397528A1B225081DE96F297E12093 flags verified ) ) game ( name "Monopoly (USA)" description "Monopoly (USA)" - rom ( name "Monopoly (USA).gb" size 131072 crc FD90F0D6 md5 F7A896711997EA35D4F79F37AC0890BB sha1 FF54EF03CB4DDA14890AE0394DD7BA5E00130D08 ) + rom ( name "Monopoly (USA).gb" size 131072 crc fd90f0d6 sha1 FF54EF03CB4DDA14890AE0394DD7BA5E00130D08 flags verified ) ) game ( name "Monster Maker (Japan)" description "Monster Maker (Japan)" - rom ( name "Monster Maker (Japan).gb" size 131072 crc 725EE86C md5 51DFF0233C9D348AB59341D8AFBB6275 sha1 70D99059EF780033CD0844AB724CB0C1B4B3C839 flags verified ) + rom ( name "Monster Maker (Japan).gb" size 131072 crc 725ee86c sha1 70D99059EF780033CD0844AB724CB0C1B4B3C839 flags verified ) ) game ( name "Monster Maker - Barcode Saga (Japan)" description "Monster Maker - Barcode Saga (Japan)" - rom ( name "Monster Maker - Barcode Saga (Japan).gb" size 131072 crc 56BA6A71 md5 F0C0599F8D8A18B1ADCBE6E79D8D936A sha1 F7A101338C4EEBCDCC1E5D9082A30CAA2D706969 flags verified ) + rom ( name "Monster Maker - Barcode Saga (Japan).gb" size 131072 crc 56ba6a71 sha1 F7A101338C4EEBCDCC1E5D9082A30CAA2D706969 flags verified ) ) game ( name "Monster Maker 2 - Uru no Hiken (Japan)" description "Monster Maker 2 - Uru no Hiken (Japan)" - rom ( name "Monster Maker 2 - Uru no Hiken (Japan).gb" size 262144 crc 66E708FC md5 214F461D32073E12F0F8BE8F25D0F4ED sha1 FFAC4E116CFE1C2D545C746640CC55E7DF59101B ) + rom ( name "Monster Maker 2 - Uru no Hiken (Japan).gb" size 262144 crc 66e708fc sha1 FFAC4E116CFE1C2D545C746640CC55E7DF59101B flags verified ) ) game ( name "Monster Max (Europe) (En,Fr,De,Es,It,Nl)" description "Monster Max (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Monster Max (Europe) (En,Fr,De,Es,It,Nl).gb" size 262144 crc 300B1D2D md5 261EC744FCF7A4EB5A6025C48C0538A3 sha1 4C3647C79C97114BB7DAF74B1A30F33FD989CF04 flags verified ) + rom ( name "Monster Max (Europe) (En,Fr,De,Es,It,Nl).gb" size 262144 crc 300b1d2d sha1 4C3647C79C97114BB7DAF74B1A30F33FD989CF04 flags verified ) ) game ( name "Monster Race (Japan) (SGB Enhanced)" description "Monster Race (Japan) (SGB Enhanced)" - rom ( name "Monster Race (Japan) (SGB Enhanced).gb" size 524288 crc C191BD66 md5 3029C962C483DF174FC6F5C9202326E3 sha1 BB305EC61EC272A7A2FADA1C03BA6784C5168F86 flags verified ) + rom ( name "Monster Race (Japan) (SGB Enhanced).gb" size 524288 crc c191bd66 sha1 BB305EC61EC272A7A2FADA1C03BA6784C5168F86 flags verified ) ) game ( name "Monster Race Okawari (Japan) (SGB Enhanced)" description "Monster Race Okawari (Japan) (SGB Enhanced)" - rom ( name "Monster Race Okawari (Japan) (SGB Enhanced).gb" size 524288 crc BD3039E5 md5 E2C928A942CD827B52499AA9FB148F9A sha1 A566012977DBCEDE8066C06E445B6A346D158E53 flags verified ) + rom ( name "Monster Race Okawari (Japan) (SGB Enhanced).gb" size 524288 crc bd3039e5 sha1 A566012977DBCEDE8066C06E445B6A346D158E53 flags verified ) ) game ( name "Monster Truck (Japan)" description "Monster Truck (Japan)" - rom ( name "Monster Truck (Japan).gb" size 65536 crc ABF9B517 md5 5062DA78CDF359A8E0CF0F6A6239698A sha1 3DB1E6333AF2DA6CD86BFFD1AFAFC7CE96BF4B95 flags verified ) + rom ( name "Monster Truck (Japan).gb" size 65536 crc abf9b517 sha1 3DB1E6333AF2DA6CD86BFFD1AFAFC7CE96BF4B95 flags verified ) ) game ( name "Monster Truck Wars (USA, Europe)" description "Monster Truck Wars (USA, Europe)" - rom ( name "Monster Truck Wars (USA, Europe).gb" size 131072 crc 186C109B md5 CEE6D41002411E7D8B8344EEA2A3DED9 sha1 8EFE65D5DEB4D0705BF6E11C6C6B97901AC1278A flags verified ) + rom ( name "Monster Truck Wars (USA, Europe).gb" size 131072 crc 186c109b sha1 8EFE65D5DEB4D0705BF6E11C6C6B97901AC1278A flags verified ) ) game ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It)" description "Montezuma's Return! (Europe) (En,Fr,De,Es,It)" - rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It).gb" size 262144 crc E7AC155B md5 47900027FCBC2F749B3C0B1CE7FA3372 sha1 A6B90CC58AEB5B44EF674C503A55A58278B1B6FA flags verified ) -) - -game ( - name "Mortal Kombat (Japan)" - description "Mortal Kombat (Japan)" - rom ( name "Mortal Kombat (Japan).gb" size 262144 crc 160FA9EF md5 B17C839D444F98A4BD7FEC2E49CACF12 sha1 5C24D595401CE3D1BB4027D0BC12312DCA275470 ) + rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It).gb" size 262144 crc e7ac155b sha1 A6B90CC58AEB5B44EF674C503A55A58278B1B6FA flags verified ) ) game ( name "Mortal Kombat (USA, Europe)" description "Mortal Kombat (USA, Europe)" - rom ( name "Mortal Kombat (USA, Europe).gb" size 262144 crc 90EB0929 md5 B3474BAB3EDA25BDB1508ED53765FB30 sha1 59752879EFAF2F271CE4B8A9D4A455056A2985D0 flags verified ) + rom ( name "Mortal Kombat (USA, Europe).gb" size 262144 crc 90eb0929 sha1 59752879EFAF2F271CE4B8A9D4A455056A2985D0 flags verified ) ) game ( name "Mortal Kombat & Mortal Kombat II (Japan)" description "Mortal Kombat & Mortal Kombat II (Japan)" - rom ( name "Mortal Kombat & Mortal Kombat II (Japan).gb" size 1048576 crc B1A8DFD0 md5 EB8A2EE6284C53C81329479FEAA28A7F sha1 CF6CA53E1DF526C73BAB62743085257119865107 ) + rom ( name "Mortal Kombat & Mortal Kombat II (Japan).gb" size 1048576 crc b1a8dfd0 sha1 CF6CA53E1DF526C73BAB62743085257119865107 ) ) game ( name "Mortal Kombat & Mortal Kombat II (USA, Europe)" description "Mortal Kombat & Mortal Kombat II (USA, Europe)" - rom ( name "Mortal Kombat & Mortal Kombat II (USA, Europe).gb" size 1048576 crc 55300D0A md5 CF1F58AB72112716D3C615A553B2F481 sha1 E337489255B33367CE26194FC4038346D3388BD9 flags verified ) + rom ( name "Mortal Kombat & Mortal Kombat II (USA, Europe).gb" size 1048576 crc 55300d0a sha1 E337489255B33367CE26194FC4038346D3388BD9 flags verified ) +) + +game ( + name "Mortal Kombat - Shinken Kourin Densetsu (Japan)" + description "Mortal Kombat - Shinken Kourin Densetsu (Japan)" + rom ( name "Mortal Kombat - Shinken Kourin Densetsu (Japan).gb" size 262144 crc 160fa9ef sha1 5C24D595401CE3D1BB4027D0BC12312DCA275470 ) ) game ( name "Mortal Kombat 3 (Europe)" description "Mortal Kombat 3 (Europe)" - rom ( name "Mortal Kombat 3 (Europe).gb" size 524288 crc 40C9D0F2 md5 2AFF6AD314AA6833E558F2B8B8CDAC91 sha1 73D10C377EAB9BF73B1824AC1FE4A1855DEE7303 flags verified ) + rom ( name "Mortal Kombat 3 (Europe).gb" size 524288 crc 40c9d0f2 sha1 73D10C377EAB9BF73B1824AC1FE4A1855DEE7303 flags verified ) ) game ( name "Mortal Kombat 3 (USA)" description "Mortal Kombat 3 (USA)" - rom ( name "Mortal Kombat 3 (USA).gb" size 524288 crc BF9C65FB md5 C19D61E31D6AEBC12ABF80D628A7BD09 sha1 B43626E2F20FA865783892AB8A012AA86E1DCEE2 ) + rom ( name "Mortal Kombat 3 (USA).gb" size 524288 crc bf9c65fb sha1 B43626E2F20FA865783892AB8A012AA86E1DCEE2 flags verified ) ) game ( name "Mortal Kombat II (USA, Europe)" description "Mortal Kombat II (USA, Europe)" - rom ( name "Mortal Kombat II (USA, Europe).gb" size 262144 crc BFAEADD0 md5 CE2927987765182B9C69F26F758656E9 sha1 B8D400EE3D78A38F721F97E5222108D3586D2E63 flags verified ) + rom ( name "Mortal Kombat II (USA, Europe).gb" size 262144 crc bfaeadd0 sha1 B8D400EE3D78A38F721F97E5222108D3586D2E63 flags verified ) ) game ( name "Mortal Kombat II - Kyuukyoku Shinken (Japan)" description "Mortal Kombat II - Kyuukyoku Shinken (Japan)" - rom ( name "Mortal Kombat II - Kyuukyoku Shinken (Japan).gb" size 262144 crc 57BA5D56 md5 31223019B126DBCC85F14905588D053B sha1 0661CE04696AD0C1B70345C9E880A8B26CC1218A ) + rom ( name "Mortal Kombat II - Kyuukyoku Shinken (Japan).gb" size 262144 crc 57ba5d56 sha1 0661CE04696AD0C1B70345C9E880A8B26CC1218A ) ) game ( name "Motocross Maniacs (Europe)" description "Motocross Maniacs (Europe)" - rom ( name "Motocross Maniacs (Europe).gb" size 32768 crc E2697678 md5 DCA464649EA6A3969AC8EE834D431D44 sha1 956A12A65A1C39948C312303719895BD6F141A61 flags verified ) + rom ( name "Motocross Maniacs (Europe).gb" size 32768 crc e2697678 sha1 956A12A65A1C39948C312303719895BD6F141A61 flags verified ) ) game ( name "Motocross Maniacs (Japan)" description "Motocross Maniacs (Japan)" - rom ( name "Motocross Maniacs (Japan).gb" size 32768 crc DA6053C3 md5 57D60F97E42D24835B6723D9B7A3C0DB sha1 DE3FBB541ACAC5E4FCD828E9CF4EEF7541E95645 flags verified ) + rom ( name "Motocross Maniacs (Japan).gb" size 32768 crc da6053c3 sha1 DE3FBB541ACAC5E4FCD828E9CF4EEF7541E95645 flags verified ) ) game ( name "Motocross Maniacs (USA)" description "Motocross Maniacs (USA)" - rom ( name "Motocross Maniacs (USA).gb" size 32768 crc 318DBDE1 md5 DE1572D4D181B265E2CB7D517C0BA04A sha1 80575304CCEDBD26C0366D8F6F0F0FAAE09A4F13 ) + rom ( name "Motocross Maniacs (USA).gb" size 32768 crc 318dbde1 sha1 80575304CCEDBD26C0366D8F6F0F0FAAE09A4F13 ) ) game ( - name "Motocross Maniacs (Europe) (Rev A)" - description "Motocross Maniacs (Europe) (Rev A)" - rom ( name "Motocross Maniacs (Europe) (Rev A).gb" size 32768 crc F867EE3B md5 5B47F714DC337DB2DD9972383E6D0805 sha1 D21F2A4DDB69C408A370B6768F83914C11012C71 ) + name "Motocross Maniacs (Europe) (Rev 1)" + description "Motocross Maniacs (Europe) (Rev 1)" + rom ( name "Motocross Maniacs (Europe) (Rev 1).gb" size 32768 crc f867ee3b sha1 D21F2A4DDB69C408A370B6768F83914C11012C71 flags verified ) ) game ( name "Mouse Trap Hotel (USA)" description "Mouse Trap Hotel (USA)" - rom ( name "Mouse Trap Hotel (USA).gb" size 65536 crc 6EDF07E5 md5 CD8EB18DEC915D8E2EA73F097D33BA04 sha1 301658FD29B1A9277690A3C6E43DC68C8A277C1D ) + rom ( name "Mouse Trap Hotel (USA).gb" size 65536 crc 6edf07e5 sha1 301658FD29B1A9277690A3C6E43DC68C8A277C1D ) ) game ( name "Mr. Chin's Gourmet Paradise (USA)" description "Mr. Chin's Gourmet Paradise (USA)" - rom ( name "Mr. Chin's Gourmet Paradise (USA).gb" size 65536 crc D03E59AA md5 1EFBB42C4DB24E5E42E778D969BA1F5D sha1 1B510734463A5095FA94786FC233B57587EE402D ) + rom ( name "Mr. Chin's Gourmet Paradise (USA).gb" size 65536 crc d03e59aa sha1 1B510734463A5095FA94786FC233B57587EE402D ) ) game ( name "Mr. Do! (Europe)" description "Mr. Do! (Europe)" - rom ( name "Mr. Do! (Europe).gb" size 65536 crc CF84AC77 md5 D8FAFE7E8BF3D169D03B48EA23262FD5 sha1 83663A2D49CFE41E6D9A6AAD6157D7D8F024E969 ) + rom ( name "Mr. Do! (Europe).gb" size 65536 crc cf84ac77 sha1 83663A2D49CFE41E6D9A6AAD6157D7D8F024E969 flags verified ) ) game ( name "Mr. Do! (USA)" description "Mr. Do! (USA)" - rom ( name "Mr. Do! (USA).gb" size 65536 crc A1122FC0 md5 65E455737DF458E59CC7B0892B95E6CD sha1 1262A3119E7D7CB724863AFA0AC467756F2FE611 ) + rom ( name "Mr. Do! (USA).gb" size 65536 crc a1122fc0 sha1 1262A3119E7D7CB724863AFA0AC467756F2FE611 ) ) game ( name "Mr. Go no Baken Tekichuu Jutsu (Japan)" description "Mr. Go no Baken Tekichuu Jutsu (Japan)" - rom ( name "Mr. Go no Baken Tekichuu Jutsu (Japan).gb" size 131072 crc EADAF1E7 md5 709D59A30863336C26A48001C23AF729 sha1 DDF49BDC73C9B50045396915767C7610EEB296B5 flags verified ) + rom ( name "Mr. Go no Baken Tekichuu Jutsu (Japan).gb" size 131072 crc eadaf1e7 sha1 DDF49BDC73C9B50045396915767C7610EEB296B5 flags verified ) ) game ( name "Mr. Nutz (Europe)" description "Mr. Nutz (Europe)" - rom ( name "Mr. Nutz (Europe).gb" size 262144 crc 03B64A35 md5 7DB13139BC32E2AADB732D610F4C1604 sha1 C3DC8FA1AEBC92B07EACD6C78AECE7C6DD33429D flags verified ) + rom ( name "Mr. Nutz (Europe).gb" size 262144 crc 03b64a35 sha1 C3DC8FA1AEBC92B07EACD6C78AECE7C6DD33429D flags verified ) ) game ( name "Ms. Pac-Man (Europe)" description "Ms. Pac-Man (Europe)" - rom ( name "Ms. Pac-Man (Europe).gb" size 65536 crc E19F67D7 md5 5CFA323AD8D8E4A6D50022D5C64B46FD sha1 C3388250F3FD3E18289EDBAF0063AC563E2DFEC0 flags verified ) + rom ( name "Ms. Pac-Man (Europe).gb" size 65536 crc e19f67d7 sha1 C3388250F3FD3E18289EDBAF0063AC563E2DFEC0 flags verified ) ) game ( name "Ms. Pac-Man (USA)" description "Ms. Pac-Man (USA)" - rom ( name "Ms. Pac-Man (USA).gb" size 65536 crc 0E5BB1C4 md5 FFA8642A18781FBE79DF436A761A9775 sha1 FCC05F0625D52ACE28D21FD8270E71246229CBAD ) + rom ( name "Ms. Pac-Man (USA).gb" size 65536 crc 0e5bb1c4 sha1 FCC05F0625D52ACE28D21FD8270E71246229CBAD ) ) game ( name "Muhammad Ali Heavyweight Boxing (USA, Europe)" description "Muhammad Ali Heavyweight Boxing (USA, Europe)" - rom ( name "Muhammad Ali Heavyweight Boxing (USA, Europe).gb" size 131072 crc 97BD3E8F md5 2DD28F8F43DF06327C04A51959AC526E sha1 9E7002575177A5AF87500C53AFD6187DA3923510 flags verified ) + rom ( name "Muhammad Ali Heavyweight Boxing (USA, Europe).gb" size 131072 crc 97bd3e8f sha1 9E7002575177A5AF87500C53AFD6187DA3923510 flags verified ) ) game ( name "Mulan (USA, Europe) (SGB Enhanced)" description "Mulan (USA, Europe) (SGB Enhanced)" - rom ( name "Mulan (USA, Europe) (SGB Enhanced).gb" size 524288 crc E285CF30 md5 314CA1610E00861BC97611C8F874503A sha1 B039F13D7A4EAC290AB2D0BF4A4A740CFC517959 flags verified ) + rom ( name "Mulan (USA, Europe) (SGB Enhanced).gb" size 524288 crc e285cf30 sha1 B039F13D7A4EAC290AB2D0BF4A4A740CFC517959 flags verified ) ) game ( name "MVP Baseball (Japan)" description "MVP Baseball (Japan)" - rom ( name "MVP Baseball (Japan).gb" size 262144 crc 38C126AA md5 7B040899FA8B62F4C27115C21A4EA881 sha1 F0D921D13689D2AFE7838EEE127BF670439C8D8D ) + rom ( name "MVP Baseball (Japan).gb" size 262144 crc 38c126aa sha1 F0D921D13689D2AFE7838EEE127BF670439C8D8D ) ) game ( name "Mysterium (Japan)" description "Mysterium (Japan)" - rom ( name "Mysterium (Japan).gb" size 131072 crc 3420EDEA md5 F0551F45075CA99A762C292F13E42422 sha1 775E1CEAC81306F0198153920223FCEBEDFC6616 ) + rom ( name "Mysterium (Japan).gb" size 131072 crc 3420edea sha1 775E1CEAC81306F0198153920223FCEBEDFC6616 ) ) game ( name "Mysterium (USA)" description "Mysterium (USA)" - rom ( name "Mysterium (USA).gb" size 131072 crc EB225E96 md5 12E9E43481D38003A4F1E2C2CE596AEE sha1 382C346AF83E3CB9F95192378843D4E15EF93716 ) + rom ( name "Mysterium (USA).gb" size 131072 crc eb225e96 sha1 382C346AF83E3CB9F95192378843D4E15EF93716 flags verified ) ) game ( name "Mystic Quest (Europe)" description "Mystic Quest (Europe)" - rom ( name "Mystic Quest (Europe).gb" size 262144 crc 57D95C92 md5 5F41A4DE9F480C72CBC6EAAD6BCC3753 sha1 3513310426C6AE88F9BEB588F71C666E003273BE flags verified ) + rom ( name "Mystic Quest (Europe).gb" size 262144 crc 57d95c92 sha1 3513310426C6AE88F9BEB588F71C666E003273BE flags verified ) ) game ( name "Mystic Quest (France)" description "Mystic Quest (France)" - rom ( name "Mystic Quest (France).gb" size 262144 crc B6E134AF md5 2EFE1569E3BE81E7E19B13EAFC60CD24 sha1 B52D82248849F1EAD9BF22954B3CBF7BF8E02907 ) + rom ( name "Mystic Quest (France).gb" size 262144 crc b6e134af sha1 B52D82248849F1EAD9BF22954B3CBF7BF8E02907 ) ) game ( name "Mystic Quest (Germany)" description "Mystic Quest (Germany)" - rom ( name "Mystic Quest (Germany).gb" size 262144 crc 0351B9A6 md5 B6A08C7E3AF4EC8C9559CD268115D97C sha1 7CB65CB314E3F26B92549DDC7F4FC275186C6170 flags verified ) + rom ( name "Mystic Quest (Germany).gb" size 262144 crc 0351b9a6 sha1 7CB65CB314E3F26B92549DDC7F4FC275186C6170 flags verified ) ) game ( name "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced)" description "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced)" - rom ( name "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced).gb" size 262144 crc A1813CD5 md5 85AC741A34B971DFC107C15C8A902F07 sha1 6A47EC0C2A81741D93687B85F966C6BFCA039770 flags verified ) + rom ( name "Mystical Ninja Starring Goemon (Europe) (SGB Enhanced).gb" size 262144 crc a1813cd5 sha1 6A47EC0C2A81741D93687B85F966C6BFCA039770 flags verified ) ) game ( name "Mystical Ninja Starring Goemon (USA) (SGB Enhanced)" description "Mystical Ninja Starring Goemon (USA) (SGB Enhanced)" - rom ( name "Mystical Ninja Starring Goemon (USA) (SGB Enhanced).gb" size 262144 crc FAFB343C md5 FEAA1BBB7E532872CF1D37D80AF6FDB4 sha1 6674BAAAE85A8EB6E950F1EA30527321C942A9BC flags verified ) + rom ( name "Mystical Ninja Starring Goemon (USA) (SGB Enhanced).gb" size 262144 crc fafb343c sha1 6674BAAAE85A8EB6E950F1EA30527321C942A9BC flags verified ) ) game ( name "Nada Asatarou & Kojima Takeo no Jissen Mahjong Kyoushitsu (Japan) (SGB Enhanced)" description "Nada Asatarou & Kojima Takeo no Jissen Mahjong Kyoushitsu (Japan) (SGB Enhanced)" - rom ( name "Nada Asatarou & Kojima Takeo no Jissen Mahjong Kyoushitsu (Japan) (SGB Enhanced).gb" size 131072 crc 9D335162 md5 B6CC27346353A8F02DDA978A4E8AE2D3 sha1 20BA98670EB3BF18756F15E50B5FC65F58A15918 ) + rom ( name "Nada Asatarou & Kojima Takeo no Jissen Mahjong Kyoushitsu (Japan) (SGB Enhanced).gb" size 131072 crc 9d335162 sha1 20BA98670EB3BF18756F15E50B5FC65F58A15918 ) ) game ( name "Nada Asatarou no Powerful Mahjong - Tsugi no Itte 100 Dai (Japan)" description "Nada Asatarou no Powerful Mahjong - Tsugi no Itte 100 Dai (Japan)" - rom ( name "Nada Asatarou no Powerful Mahjong - Tsugi no Itte 100 Dai (Japan).gb" size 131072 crc B4DD8E6A md5 B68CE95D923F40FE9166FF635031147C sha1 CC51CCC05897EC05B31270EF9F30BD8475D1CCA0 ) + rom ( name "Nada Asatarou no Powerful Mahjong - Tsugi no Itte 100 Dai (Japan).gb" size 131072 crc b4dd8e6a sha1 CC51CCC05897EC05B31270EF9F30BD8475D1CCA0 ) ) game ( - name "Nail'n Scale (USA, Europe)" - description "Nail'n Scale (USA, Europe)" - rom ( name "Nail'n Scale (USA, Europe).gb" size 131072 crc 44BADBB7 md5 521D2AA473F4E740A6938861F70511CC sha1 96D25741F02EA4744BB9AD81B32F04226847649C flags verified ) + name "Nail 'n Scale (USA, Europe)" + description "Nail 'n Scale (USA, Europe)" + rom ( name "Nail 'n Scale (USA, Europe).gb" size 131072 crc 44badbb7 sha1 96D25741F02EA4744BB9AD81B32F04226847649C flags verified ) ) game ( name "Nakajima Satoru - F-1 Hero GB - World Championship '91 (Japan)" description "Nakajima Satoru - F-1 Hero GB - World Championship '91 (Japan)" - rom ( name "Nakajima Satoru - F-1 Hero GB - World Championship '91 (Japan).gb" size 131072 crc E00EBC44 md5 70D0944BF4B877734D059CCF022D83FB sha1 E07448143B82704FC142E7CCE5DDB73866EF1D78 ) + rom ( name "Nakajima Satoru - F-1 Hero GB - World Championship '91 (Japan).gb" size 131072 crc e00ebc44 sha1 E07448143B82704FC142E7CCE5DDB73866EF1D78 flags verified ) ) game ( name "Nakajima Satoru Kanshuu - F-1 Hero GB '92 - The Graded Driver (Japan)" description "Nakajima Satoru Kanshuu - F-1 Hero GB '92 - The Graded Driver (Japan)" - rom ( name "Nakajima Satoru Kanshuu - F-1 Hero GB '92 - The Graded Driver (Japan).gb" size 262144 crc B6EF042E md5 C7DD61D11B33E88FC09ACD045D4AB339 sha1 6FE738C80ECAC86DB44A032CB636ABEB2B00C4CB flags verified ) + rom ( name "Nakajima Satoru Kanshuu - F-1 Hero GB '92 - The Graded Driver (Japan).gb" size 262144 crc b6ef042e sha1 6FE738C80ECAC86DB44A032CB636ABEB2B00C4CB flags verified ) ) game ( name "Namco Classic (Japan)" description "Namco Classic (Japan)" - rom ( name "Namco Classic (Japan).gb" size 131072 crc EC3257B3 md5 D38D79715B8EC31DE8905F5D1312079E sha1 65B91CC77B1971F8229D4CAAF4FEB89C64856C8B flags verified ) + rom ( name "Namco Classic (Japan).gb" size 131072 crc ec3257b3 sha1 65B91CC77B1971F8229D4CAAF4FEB89C64856C8B flags verified ) ) game ( name "Namco Gallery Vol.1 (Japan) (SGB Enhanced)" description "Namco Gallery Vol.1 (Japan) (SGB Enhanced)" - rom ( name "Namco Gallery Vol.1 (Japan) (SGB Enhanced).gb" size 524288 crc 1902C6BD md5 C9A8D61D6D4707D28FCB267F93FA59EC sha1 D6B3C5FDB4B710CB104D461FAF3B57F6EEC066C4 ) + rom ( name "Namco Gallery Vol.1 (Japan) (SGB Enhanced).gb" size 524288 crc 1902c6bd sha1 D6B3C5FDB4B710CB104D461FAF3B57F6EEC066C4 ) ) game ( name "Namco Gallery Vol.2 (Japan) (SGB Enhanced)" description "Namco Gallery Vol.2 (Japan) (SGB Enhanced)" - rom ( name "Namco Gallery Vol.2 (Japan) (SGB Enhanced).gb" size 524288 crc A69B9260 md5 FBCA46F59BD36388B116DF8D1FECE132 sha1 02B1D728A8C722BD2299C44B54BEB4DE6EB70E4F ) + rom ( name "Namco Gallery Vol.2 (Japan) (SGB Enhanced).gb" size 524288 crc a69b9260 sha1 02B1D728A8C722BD2299C44B54BEB4DE6EB70E4F ) ) game ( name "Namco Gallery Vol.3 (Japan) (SGB Enhanced)" description "Namco Gallery Vol.3 (Japan) (SGB Enhanced)" - rom ( name "Namco Gallery Vol.3 (Japan) (SGB Enhanced).gb" size 524288 crc 7740341E md5 401E3778FB24A2AF4BCE7A3189FCFDD3 sha1 A8902E4AF858B28C1C934879718E8C971A2000BB ) + rom ( name "Namco Gallery Vol.3 (Japan) (SGB Enhanced).gb" size 524288 crc 7740341e sha1 A8902E4AF858B28C1C934879718E8C971A2000BB ) ) game ( name "Nangoku Shounen Papuwa-kun - Ganmadan no Yabou (Japan)" description "Nangoku Shounen Papuwa-kun - Ganmadan no Yabou (Japan)" - rom ( name "Nangoku Shounen Papuwa-kun - Ganmadan no Yabou (Japan).gb" size 131072 crc 798F324A md5 C5256354A6FCD57240C97A399773822E sha1 BAFEA45AEDF20D2162941FCB3B5E315595E9F481 flags verified ) + rom ( name "Nangoku Shounen Papuwa-kun - Ganmadan no Yabou (Japan).gb" size 131072 crc 798f324a sha1 BAFEA45AEDF20D2162941FCB3B5E315595E9F481 flags verified ) ) game ( name "Nanonote (Japan)" description "Nanonote (Japan)" - rom ( name "Nanonote (Japan).gb" size 131072 crc 3E30B63D md5 DCAC90D51F56F90E26D41E7731DE08EC sha1 8D280E610A827E56864E6B99A637103A2D14F7BF flags verified ) -) - -game ( - name "Navy Blue 90 (Japan)" - description "Navy Blue 90 (Japan)" - rom ( name "Navy Blue 90 (Japan).gb" size 131072 crc 8CFEB2E2 md5 008EA3BE93C0E1D808431DC8728E01F6 sha1 60FA3FB83910F548047BBAC02627C914A9057372 ) -) - -game ( - name "Navy Blue 98 (Japan)" - description "Navy Blue 98 (Japan)" - rom ( name "Navy Blue 98 (Japan).gb" size 262144 crc 2CBE5381 md5 8C464AAEB8920878E1B7EC2F0D6BBE4E sha1 FBDF3744335297E64A1578E19D987B9DADB0E2F7 flags verified ) + rom ( name "Nanonote (Japan).gb" size 131072 crc 3e30b63d sha1 8D280E610A827E56864E6B99A637103A2D14F7BF flags verified ) ) game ( name "Navy SEALs (USA, Europe)" description "Navy SEALs (USA, Europe)" - rom ( name "Navy SEALs (USA, Europe).gb" size 131072 crc 296CEACB md5 FC2B347600EDFFC8E997A7FC75382873 sha1 F6930EA45B012EBD16C1D637AE763DFB94198623 flags verified ) + rom ( name "Navy SEALs (USA, Europe).gb" size 131072 crc 296ceacb sha1 F6930EA45B012EBD16C1D637AE763DFB94198623 flags verified ) ) game ( - name "NBA All Star Challenge (USA, Europe)" - description "NBA All Star Challenge (USA, Europe)" - rom ( name "NBA All Star Challenge (USA, Europe).gb" size 65536 crc F25BA8BF md5 709726EB6DE8D45E63A88063529605BC sha1 FF2EDDBB7FC60EFDCAB60BAD53D404768AFC9F40 flags verified ) + name "Navyblue 98 (Japan)" + description "Navyblue 98 (Japan)" + rom ( name "Navyblue 98 (Japan).gb" size 262144 crc 2cbe5381 sha1 FBDF3744335297E64A1578E19D987B9DADB0E2F7 flags verified ) ) game ( - name "NBA All Star Challenge 2 (Japan)" - description "NBA All Star Challenge 2 (Japan)" - rom ( name "NBA All Star Challenge 2 (Japan).gb" size 131072 crc DF9DB013 md5 6AFAC3034F2A07A58C1D08B69ED43B9B sha1 A19B5FCFF89E5E58EFB19449ACE3D8F83A18EA78 flags verified ) + name "NBA All-Star Challenge (USA, Europe)" + description "NBA All-Star Challenge (USA, Europe)" + rom ( name "NBA All-Star Challenge (USA, Europe).gb" size 65536 crc f25ba8bf sha1 FF2EDDBB7FC60EFDCAB60BAD53D404768AFC9F40 flags verified ) ) game ( - name "NBA All Star Challenge 2 (USA, Europe)" - description "NBA All Star Challenge 2 (USA, Europe)" - rom ( name "NBA All Star Challenge 2 (USA, Europe).gb" size 131072 crc C27C0289 md5 0A1EA6552EB8DAF756824ADB1F498559 sha1 A07672471909CACE9E9765BCE6A05A8AB74D55D4 flags verified ) + name "NBA All-Star Challenge 2 (Japan)" + description "NBA All-Star Challenge 2 (Japan)" + rom ( name "NBA All-Star Challenge 2 (Japan).gb" size 131072 crc df9db013 sha1 A19B5FCFF89E5E58EFB19449ACE3D8F83A18EA78 flags verified ) +) + +game ( + name "NBA All-Star Challenge 2 (USA, Europe)" + description "NBA All-Star Challenge 2 (USA, Europe)" + rom ( name "NBA All-Star Challenge 2 (USA, Europe).gb" size 131072 crc c27c0289 sha1 A07672471909CACE9E9765BCE6A05A8AB74D55D4 flags verified ) ) game ( name "NBA Jam (USA, Europe)" description "NBA Jam (USA, Europe)" - rom ( name "NBA Jam (USA, Europe).gb" size 262144 crc 0CA07CDA md5 1A4AAF4AF4B3610CA74EF3B307B6B2A9 sha1 CECA1552909ACAAD74241CB3CEF360EBB845AC3B flags verified ) + rom ( name "NBA Jam (USA, Europe).gb" size 262144 crc 0ca07cda sha1 CECA1552909ACAAD74241CB3CEF360EBB845AC3B flags verified ) ) game ( name "NBA Jam - Tournament Edition (Japan)" description "NBA Jam - Tournament Edition (Japan)" - rom ( name "NBA Jam - Tournament Edition (Japan).gb" size 524288 crc 32909F62 md5 4668B13913DFB14E43C263A7015EB9AB sha1 ED3DE869011CCF636A7BE0949CA08D029C7873E2 ) + rom ( name "NBA Jam - Tournament Edition (Japan).gb" size 524288 crc 32909f62 sha1 ED3DE869011CCF636A7BE0949CA08D029C7873E2 ) ) game ( name "NBA Jam - Tournament Edition (USA, Europe)" description "NBA Jam - Tournament Edition (USA, Europe)" - rom ( name "NBA Jam - Tournament Edition (USA, Europe).gb" size 524288 crc 27D74C50 md5 802CFBC386BB79B0889D7DD2B6ABDC13 sha1 981DE2C70A2DFB5AE829D39CC5F302815780E771 flags verified ) + rom ( name "NBA Jam - Tournament Edition (USA, Europe).gb" size 524288 crc 27d74c50 sha1 981DE2C70A2DFB5AE829D39CC5F302815780E771 flags verified ) ) game ( name "NBA Live 96 (USA, Europe) (SGB Enhanced)" description "NBA Live 96 (USA, Europe) (SGB Enhanced)" - rom ( name "NBA Live 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 8885C7CD md5 9E71577A809BBEF83ABD02596CB00913 sha1 F4D13F947F7F8F074F7979A5889CC2C91C56F4EA flags verified ) + rom ( name "NBA Live 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 8885c7cd sha1 F4D13F947F7F8F074F7979A5889CC2C91C56F4EA flags verified ) ) game ( name "Nectaris GB (Japan) (SGB Enhanced)" description "Nectaris GB (Japan) (SGB Enhanced)" - rom ( name "Nectaris GB (Japan) (SGB Enhanced).gb" size 524288 crc 20BFD7EF md5 1080141C1B99B5B92D187990BDC85C6A sha1 BA251BFEF8162EF032DA8D5C28FE693EDE28F030 ) + rom ( name "Nectaris GB (Japan) (SGB Enhanced).gb" size 524288 crc 20bfd7ef sha1 BA251BFEF8162EF032DA8D5C28FE693EDE28F030 flags verified ) ) game ( name "Nekketsu Kouha Kunio-kun - Bangai Rantou Hen (Japan)" description "Nekketsu Kouha Kunio-kun - Bangai Rantou Hen (Japan)" - rom ( name "Nekketsu Kouha Kunio-kun - Bangai Rantou Hen (Japan).gb" size 131072 crc 25B21ACC md5 EB771FB255FA207A830DF06338AF6D87 sha1 28E6EDFF470613A2ABF015C9795581E8E2822029 flags verified ) + rom ( name "Nekketsu Kouha Kunio-kun - Bangai Rantou Hen (Japan).gb" size 131072 crc 25b21acc sha1 28E6EDFF470613A2ABF015C9795581E8E2822029 flags verified ) ) game ( - name "Nekketsu Koukou Dodgeball-bu - Kyouteki! Toukyuu Senshi no Maki (Japan)" - description "Nekketsu Koukou Dodgeball-bu - Kyouteki! Toukyuu Senshi no Maki (Japan)" - rom ( name "Nekketsu Koukou Dodgeball-bu - Kyouteki! Toukyuu Senshi no Maki (Japan).gb" size 131072 crc 7EAF671A md5 1D94024621B825E9FBE7E46ED4E0A567 sha1 4AD83D6EDC948CAE10221B7AAF8FD8B999D4B489 ) + name "Nekketsu Koukou Dodgeball-bu - Kyouteki! Dodge Soldier no Maki (Japan)" + description "Nekketsu Koukou Dodgeball-bu - Kyouteki! Dodge Soldier no Maki (Japan)" + rom ( name "Nekketsu Koukou Dodgeball-bu - Kyouteki! Dodge Soldier no Maki (Japan).gb" size 131072 crc 7eaf671a sha1 4AD83D6EDC948CAE10221B7AAF8FD8B999D4B489 ) ) game ( name "Nekketsu Koukou Soccer-bu - World Cup Hen (Japan)" description "Nekketsu Koukou Soccer-bu - World Cup Hen (Japan)" - rom ( name "Nekketsu Koukou Soccer-bu - World Cup Hen (Japan).gb" size 131072 crc 50C2ADA1 md5 3593F45C94D5B612C7864E5181C7AEFF sha1 3763313B9F371E5428A67B7461E4F6F2C1AB8422 flags verified ) + rom ( name "Nekketsu Koukou Soccer-bu - World Cup Hen (Japan).gb" size 131072 crc 50c2ada1 sha1 3763313B9F371E5428A67B7461E4F6F2C1AB8422 flags verified ) ) game ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced)" description "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced)" - rom ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced).gb" size 262144 crc ABFB84DF md5 C3F48A71DA12919004C88B6F37EEBD0D sha1 D3AD43C40C21D9825B4879DBF28CA58835DA658A ) + rom ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced).gb" size 262144 crc abfb84df sha1 D3AD43C40C21D9825B4879DBF28CA58835DA658A ) ) game ( name "Nekojara Monogatari (Japan)" description "Nekojara Monogatari (Japan)" - rom ( name "Nekojara Monogatari (Japan).gb" size 131072 crc 3D6D309B md5 ACA9ABFBAB8345733456394B516F03E1 sha1 F0F320B9170501C762E724E9B22D37CB4D15D0A9 ) + rom ( name "Nekojara Monogatari (Japan).gb" size 131072 crc 3d6d309b sha1 F0F320B9170501C762E724E9B22D37CB4D15D0A9 ) ) game ( name "Nemesis (Europe)" description "Nemesis (Europe)" - rom ( name "Nemesis (Europe).gb" size 131072 crc 19930EA5 md5 4D4EAE6560062B9A12D9770653F1A53F sha1 E95E7A476A160BC0A685112D80239A5D669FD192 flags verified ) + rom ( name "Nemesis (Europe).gb" size 131072 crc 19930ea5 sha1 E95E7A476A160BC0A685112D80239A5D669FD192 flags verified ) ) game ( name "Nemesis (Japan)" description "Nemesis (Japan)" - rom ( name "Nemesis (Japan).gb" size 131072 crc B338DAE7 md5 F5D9206E1A5F8B42485E4DD431A5A2D4 sha1 DA54433D91970421A87C6595E0F77EEFED750AC1 flags verified ) + rom ( name "Nemesis (Japan).gb" size 131072 crc b338dae7 sha1 DA54433D91970421A87C6595E0F77EEFED750AC1 flags verified ) ) game ( name "Nemesis (USA)" description "Nemesis (USA)" - rom ( name "Nemesis (USA).gb" size 131072 crc 5110E971 md5 1EB7FF636E532321A18885EEA660604A sha1 0AD4A8F156BC6899E2337417CEDF9E279F8ABC08 flags verified ) + rom ( name "Nemesis (USA).gb" size 131072 crc 5110e971 sha1 0AD4A8F156BC6899E2337417CEDF9E279F8ABC08 flags verified ) ) game ( name "Nemesis II (Japan)" description "Nemesis II (Japan)" - rom ( name "Nemesis II (Japan).gb" size 262144 crc AC5B062D md5 C4DC3987A841A428F837DB26BDDC586E sha1 F2797D5FA272CECC8CE89F6326A29CAD332F72D1 flags verified ) + rom ( name "Nemesis II (Japan).gb" size 262144 crc ac5b062d sha1 F2797D5FA272CECC8CE89F6326A29CAD332F72D1 flags verified ) ) game ( name "Nemesis II - The Return of the Hero (Europe)" description "Nemesis II - The Return of the Hero (Europe)" - rom ( name "Nemesis II - The Return of the Hero (Europe).gb" size 262144 crc C3E62A35 md5 BA760B6D4B96BAF0FA2E7AD6E4498A95 sha1 EE59DA08C23102AB99A28C5DA9CEAF222E7FB461 flags verified ) + rom ( name "Nemesis II - The Return of the Hero (Europe).gb" size 262144 crc c3e62a35 sha1 EE59DA08C23102AB99A28C5DA9CEAF222E7FB461 flags verified ) ) game ( name "Nettou Garou Densetsu 2 - Aratanaru Tatakai (Japan) (SGB Enhanced)" description "Nettou Garou Densetsu 2 - Aratanaru Tatakai (Japan) (SGB Enhanced)" - rom ( name "Nettou Garou Densetsu 2 - Aratanaru Tatakai (Japan) (SGB Enhanced).gb" size 524288 crc AA98687F md5 4E493ADA5353CF6EB1C0F009D6A5AC13 sha1 74B1E1B53235EB356AE1EF4BCE940873A96BD076 flags verified ) + rom ( name "Nettou Garou Densetsu 2 - Aratanaru Tatakai (Japan) (SGB Enhanced).gb" size 524288 crc aa98687f sha1 74B1E1B53235EB356AE1EF4BCE940873A96BD076 flags verified ) ) game ( name "Nettou Real Bout Garou Densetsu Special (Japan) (SGB Enhanced)" description "Nettou Real Bout Garou Densetsu Special (Japan) (SGB Enhanced)" - rom ( name "Nettou Real Bout Garou Densetsu Special (Japan) (SGB Enhanced).gb" size 524288 crc F4031D4C md5 4C24F644E70F0786D20D8CA9FFCEA51C sha1 D67A26AF79BECDF957CCA82BC472B188F5754CD2 ) + rom ( name "Nettou Real Bout Garou Densetsu Special (Japan) (SGB Enhanced).gb" size 524288 crc f4031d4c sha1 D67A26AF79BECDF957CCA82BC472B188F5754CD2 flags verified ) ) game ( name "Nettou Samurai Spirits (Japan) (SGB Enhanced)" description "Nettou Samurai Spirits (Japan) (SGB Enhanced)" - rom ( name "Nettou Samurai Spirits (Japan) (SGB Enhanced).gb" size 524288 crc 4A306276 md5 BD816C99EF46497C67ACA61D1CB306BE sha1 6303A5FB1D99BA8BAD36437AF5E2592FDECF0F72 flags verified ) + rom ( name "Nettou Samurai Spirits (Japan) (SGB Enhanced).gb" size 524288 crc 4a306276 sha1 6303A5FB1D99BA8BAD36437AF5E2592FDECF0F72 flags verified ) ) game ( - name "Nettou Samurai Spirits (Japan) (Rev A) (SGB Enhanced)" - description "Nettou Samurai Spirits (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Nettou Samurai Spirits (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc C94850CC md5 369BC7CDE60AC3F97F72FF605502797F sha1 05BFA0C00E29FB8D69EF683EDDEC52E1DE57A9FF flags verified ) + name "Nettou Samurai Spirits (Japan) (Rev 1) (SGB Enhanced)" + description "Nettou Samurai Spirits (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Nettou Samurai Spirits (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc c94850cc sha1 05BFA0C00E29FB8D69EF683EDDEC52E1DE57A9FF flags verified ) ) game ( name "Nettou Samurai Spirits - Zankurou Musouken (Japan) (SGB Enhanced)" description "Nettou Samurai Spirits - Zankurou Musouken (Japan) (SGB Enhanced)" - rom ( name "Nettou Samurai Spirits - Zankurou Musouken (Japan) (SGB Enhanced).gb" size 1048576 crc 995D0838 md5 4426B35EF04094F9C5518D6FB6414D55 sha1 0BA93965808F7A96C92A85289678E16B41CB09EC ) + rom ( name "Nettou Samurai Spirits - Zankurou Musouken (Japan) (SGB Enhanced).gb" size 1048576 crc 995d0838 sha1 0BA93965808F7A96C92A85289678E16B41CB09EC flags verified ) ) game ( name "Nettou The King of Fighters '95 (Japan) (SGB Enhanced)" description "Nettou The King of Fighters '95 (Japan) (SGB Enhanced)" - rom ( name "Nettou The King of Fighters '95 (Japan) (SGB Enhanced).gb" size 524288 crc 8712F17B md5 3EADE561A44103622A0AFF7B176D3207 sha1 AF48F83D5DC319AA1E373B8E91EDE45606BD867C ) + rom ( name "Nettou The King of Fighters '95 (Japan) (SGB Enhanced).gb" size 524288 crc 8712f17b sha1 AF48F83D5DC319AA1E373B8E91EDE45606BD867C ) ) game ( name "Nettou The King of Fighters '96 (Japan) (SGB Enhanced)" description "Nettou The King of Fighters '96 (Japan) (SGB Enhanced)" - rom ( name "Nettou The King of Fighters '96 (Japan) (SGB Enhanced).gb" size 524288 crc FECDAE42 md5 16EE9B10C27C136D2959AE87105A8A2E sha1 63F25BFF422A591907B83AB9F14709E938172839 flags verified ) + rom ( name "Nettou The King of Fighters '96 (Japan) (SGB Enhanced).gb" size 524288 crc fecdae42 sha1 63F25BFF422A591907B83AB9F14709E938172839 flags verified ) ) game ( name "Nettou Toushinden (Japan) (SGB Enhanced)" description "Nettou Toushinden (Japan) (SGB Enhanced)" - rom ( name "Nettou Toushinden (Japan) (SGB Enhanced).gb" size 524288 crc DDE161A5 md5 D14502BCDCF71E9E16476B5077C03945 sha1 61B99FBC4D56DAD2E6002C7A8C6B5A1660A23137 ) + rom ( name "Nettou Toushinden (Japan) (SGB Enhanced).gb" size 524288 crc dde161a5 sha1 61B99FBC4D56DAD2E6002C7A8C6B5A1660A23137 ) ) game ( - name "Nettou Toushinden (Japan) (Rev A) (SGB Enhanced)" - description "Nettou Toushinden (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Nettou Toushinden (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc D5A6B132 md5 A093E160D18423BDAA2D6BF22F5F32A0 sha1 5FD55A5D01817C770B251DBB9A0DC73A02D8C566 ) + name "Nettou Toushinden (Japan) (Rev 1) (SGB Enhanced)" + description "Nettou Toushinden (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Nettou Toushinden (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc d5a6b132 sha1 5FD55A5D01817C770B251DBB9A0DC73A02D8C566 flags verified ) ) game ( name "Nettou World Heroes 2 Jet (Japan) (SGB Enhanced)" description "Nettou World Heroes 2 Jet (Japan) (SGB Enhanced)" - rom ( name "Nettou World Heroes 2 Jet (Japan) (SGB Enhanced).gb" size 524288 crc 0A12F53C md5 DEE3E9698D8087AA884D95978D5EFAA7 sha1 0DD04CA0AC61B449D3040587918B63D649FBBCC2 ) + rom ( name "Nettou World Heroes 2 Jet (Japan) (SGB Enhanced).gb" size 524288 crc 0a12f53c sha1 0DD04CA0AC61B449D3040587918B63D649FBBCC2 flags verified ) +) + +game ( + name "Nettou World Heroes 2 Jet (Japan) (Rev 1) (SGB Enhanced)" + description "Nettou World Heroes 2 Jet (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Nettou World Heroes 2 Jet (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc 7c5ffe52 sha1 14BC507F479E814B0131FEBFAB19F2EF30EB23A5 flags verified ) ) game ( name "New Chessmaster, The (Japan) (En,Ja)" description "New Chessmaster, The (Japan) (En,Ja)" - rom ( name "New Chessmaster, The (Japan) (En,Ja).gb" size 65536 crc 5E1C3E8D md5 25B34EBECE0E2C54BAF9DEE4F5845292 sha1 5D0A22B99FFA528003997C59C54AC9D1C8920D6F ) + rom ( name "New Chessmaster, The (Japan) (En,Ja).gb" size 65536 crc 5e1c3e8d sha1 5D0A22B99FFA528003997C59C54AC9D1C8920D6F ) ) game ( name "New Chessmaster, The (USA, Europe)" description "New Chessmaster, The (USA, Europe)" - rom ( name "New Chessmaster, The (USA, Europe).gb" size 65536 crc C7FFC203 md5 F395F7B8CE24E6DA365B843ADF7D763E sha1 23458FE9E811F2F9ADE1ACC527024BAB0B892BAC flags verified ) + rom ( name "New Chessmaster, The (USA, Europe).gb" size 65536 crc c7ffc203 sha1 23458FE9E811F2F9ADE1ACC527024BAB0B892BAC flags verified ) ) game ( name "NFL Football (USA)" description "NFL Football (USA)" - rom ( name "NFL Football (USA).gb" size 32768 crc 4C3D1508 md5 20E16379B6667AB17C512780BD9AE757 sha1 5A74FC3B137986A3569158F3B0E99551A277069C ) -) - -game ( - name "NFL Quarterback Club (Japan)" - description "NFL Quarterback Club (Japan)" - rom ( name "NFL Quarterback Club (Japan).gb" size 262144 crc EECB703C md5 F35A1D453FA4287FFC6FC070FD11DC2E sha1 454726DE3BF724B1CCE8D99721BBAA48B5C2B2C6 ) + rom ( name "NFL Football (USA).gb" size 32768 crc 4c3d1508 sha1 5A74FC3B137986A3569158F3B0E99551A277069C ) ) game ( name "NFL Quarterback Club (USA, Europe)" description "NFL Quarterback Club (USA, Europe)" - rom ( name "NFL Quarterback Club (USA, Europe).gb" size 131072 crc C7838830 md5 3B16CCB118F4959886AB5CBC14041002 sha1 CB5B7B05549E0EEDDB820FA92CD46C3E3E28B760 flags verified ) + rom ( name "NFL Quarterback Club (USA, Europe).gb" size 131072 crc c7838830 sha1 CB5B7B05549E0EEDDB820FA92CD46C3E3E28B760 flags verified ) ) game ( - name "NFL Quarterback Club '96 (USA, Europe)" - description "NFL Quarterback Club '96 (USA, Europe)" - rom ( name "NFL Quarterback Club '96 (USA, Europe).gb" size 262144 crc D583BC4E md5 0E6D310F979C83BF1DFA01DA803038D4 sha1 39ABB312F304F9ABF88F8E16283B5180C8F2720A flags verified ) + name "NFL Quarterback Club '95 (Japan)" + description "NFL Quarterback Club '95 (Japan)" + rom ( name "NFL Quarterback Club '95 (Japan).gb" size 262144 crc eecb703c sha1 454726DE3BF724B1CCE8D99721BBAA48B5C2B2C6 ) +) + +game ( + name "NFL Quarterback Club 96 (USA, Europe)" + description "NFL Quarterback Club 96 (USA, Europe)" + rom ( name "NFL Quarterback Club 96 (USA, Europe).gb" size 262144 crc d583bc4e sha1 39ABB312F304F9ABF88F8E16283B5180C8F2720A flags verified ) ) game ( name "NFL Quarterback Club II (USA, Europe)" description "NFL Quarterback Club II (USA, Europe)" - rom ( name "NFL Quarterback Club II (USA, Europe).gb" size 262144 crc 06F04370 md5 6F898C606275DBE71EDE0179574AD9F2 sha1 248313851266FBE5F21B16F0E27C3FB19B796D28 flags verified ) + rom ( name "NFL Quarterback Club II (USA, Europe).gb" size 262144 crc 06f04370 sha1 248313851266FBE5F21B16F0E27C3FB19B796D28 flags verified ) ) game ( - name "NHL '96 (USA, Europe) (SGB Enhanced)" - description "NHL '96 (USA, Europe) (SGB Enhanced)" - rom ( name "NHL '96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 15CD2B63 md5 89CBBDA4899D5FEA755026D671ED08D7 sha1 FB0389A7F4E99A7974DC11B4602AF441016FD57C flags verified ) + name "NHL 96 (USA, Europe) (SGB Enhanced)" + description "NHL 96 (USA, Europe) (SGB Enhanced)" + rom ( name "NHL 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 15cd2b63 sha1 FB0389A7F4E99A7974DC11B4602AF441016FD57C flags verified ) ) game ( - name "NHL Hockey '95 (USA, Europe) (SGB Enhanced)" - description "NHL Hockey '95 (USA, Europe) (SGB Enhanced)" - rom ( name "NHL Hockey '95 (USA, Europe) (SGB Enhanced).gb" size 524288 crc BCABD2D2 md5 46B681A7873D130BE35E2115263BAA6E sha1 BAEA6987F69B4C8792FF4E453EA88006803A3EF9 flags verified ) + name "NHL Hockey 95 (USA, Europe) (SGB Enhanced)" + description "NHL Hockey 95 (USA, Europe) (SGB Enhanced)" + rom ( name "NHL Hockey 95 (USA, Europe) (SGB Enhanced).gb" size 524288 crc bcabd2d2 sha1 BAEA6987F69B4C8792FF4E453EA88006803A3EF9 flags verified ) ) game ( name "Nichibutsu Mahjong - Yoshimoto Gekijou (Japan)" description "Nichibutsu Mahjong - Yoshimoto Gekijou (Japan)" - rom ( name "Nichibutsu Mahjong - Yoshimoto Gekijou (Japan).gb" size 262144 crc D983FF48 md5 E31C6235113ED686705BF664219E87D9 sha1 1CCEC61DD26B163D921043893B1D2405E05AE3A2 ) + rom ( name "Nichibutsu Mahjong - Yoshimoto Gekijou (Japan).gb" size 262144 crc d983ff48 sha1 1CCEC61DD26B163D921043893B1D2405E05AE3A2 ) ) game ( name "Nigel Mansell's World Championship (Europe)" description "Nigel Mansell's World Championship (Europe)" - rom ( name "Nigel Mansell's World Championship (Europe).gb" size 131072 crc E1B202DB md5 9EFFA81D3BA96812459BD6E76726371A sha1 DB7919CD2E31084AE569821D5ACB18140B3CFEF4 flags verified ) + rom ( name "Nigel Mansell's World Championship (Europe).gb" size 131072 crc e1b202db sha1 DB7919CD2E31084AE569821D5ACB18140B3CFEF4 flags verified ) ) game ( name "Nigel Mansell's World Championship (USA)" description "Nigel Mansell's World Championship (USA)" - rom ( name "Nigel Mansell's World Championship (USA).gb" size 131072 crc 03E84D7D md5 303CA5FA5DCF4ABBF2E18429D7241ECB sha1 BEEBC29EF505916A525FB9A5AB0D6D11BCBBFB47 ) + rom ( name "Nigel Mansell's World Championship (USA).gb" size 131072 crc 03e84d7d sha1 BEEBC29EF505916A525FB9A5AB0D6D11BCBBFB47 flags verified ) ) game ( name "Nigel Mansell's World Championship Racing (Europe)" description "Nigel Mansell's World Championship Racing (Europe)" - rom ( name "Nigel Mansell's World Championship Racing (Europe).gb" size 131072 crc 0D0958A3 md5 C18510AF46A7E2649221FDC2E03599E6 sha1 7B91447B2162154BC5882C86F2FAD5FC414DF506 flags verified ) + rom ( name "Nigel Mansell's World Championship Racing (Europe).gb" size 131072 crc 0d0958a3 sha1 7B91447B2162154BC5882C86F2FAD5FC414DF506 flags verified ) ) game ( name "Nihon Daihyou Team - Eikou no Eleven (Japan) (SGB Enhanced)" description "Nihon Daihyou Team - Eikou no Eleven (Japan) (SGB Enhanced)" - rom ( name "Nihon Daihyou Team - Eikou no Eleven (Japan) (SGB Enhanced).gb" size 262144 crc E497842E md5 256F34DF36549FB877101D28A7B92688 sha1 344613295D4B246B8873DDE2951B323197D18DB7 flags verified ) + rom ( name "Nihon Daihyou Team - Eikou no Eleven (Japan) (SGB Enhanced).gb" size 262144 crc e497842e sha1 344613295D4B246B8873DDE2951B323197D18DB7 flags verified ) ) game ( name "Nihon Daihyou Team France de Ganbare! - J.League Supporter Soccer (Japan) (SGB Enhanced)" description "Nihon Daihyou Team France de Ganbare! - J.League Supporter Soccer (Japan) (SGB Enhanced)" - rom ( name "Nihon Daihyou Team France de Ganbare! - J.League Supporter Soccer (Japan) (SGB Enhanced).gb" size 524288 crc 91E6BF74 md5 E102078685B4ECC91B4E844A922C33BD sha1 1F038DF0B742A2D76D49EAEFE7B753ED0DEA3767 flags verified ) + rom ( name "Nihon Daihyou Team France de Ganbare! - J.League Supporter Soccer (Japan) (SGB Enhanced).gb" size 524288 crc 91e6bf74 sha1 1F038DF0B742A2D76D49EAEFE7B753ED0DEA3767 flags verified ) ) game ( name "Nikkan Berutomo Club (Japan) (SGB Enhanced)" description "Nikkan Berutomo Club (Japan) (SGB Enhanced)" - rom ( name "Nikkan Berutomo Club (Japan) (SGB Enhanced).gb" size 524288 crc AD3F851D md5 D4BF4C5EBEC2A496BB6EC062058158C6 sha1 4403DDBC2FAA6B540893814A7ECAAFB218849EE9 ) + rom ( name "Nikkan Berutomo Club (Japan) (SGB Enhanced).gb" size 524288 crc ad3f851d sha1 4403DDBC2FAA6B540893814A7ECAAFB218849EE9 flags verified ) ) game ( name "Ninja Boy (USA, Europe)" description "Ninja Boy (USA, Europe)" - rom ( name "Ninja Boy (USA, Europe).gb" size 65536 crc 59D3E2AD md5 28C1EF075F37BCF4951AC11385A1104F sha1 ACD93F152574A47E2BEF3BA739F722BEC90BADEF flags verified ) + rom ( name "Ninja Boy (USA, Europe).gb" size 65536 crc 59d3e2ad sha1 ACD93F152574A47E2BEF3BA739F722BEC90BADEF flags verified ) ) game ( name "Ninja Boy 2 (USA, Europe)" description "Ninja Boy 2 (USA, Europe)" - rom ( name "Ninja Boy 2 (USA, Europe).gb" size 262144 crc 64C06D94 md5 504E1A39167C467B15D5AD56B744AD48 sha1 833B20931F29B3BB16736D7D1A1BC98E9A540261 flags verified ) + rom ( name "Ninja Boy 2 (USA, Europe).gb" size 262144 crc 64c06d94 sha1 833B20931F29B3BB16736D7D1A1BC98E9A540261 flags verified ) ) game ( name "Ninja Gaiden Shadow (USA)" description "Ninja Gaiden Shadow (USA)" - rom ( name "Ninja Gaiden Shadow (USA).gb" size 131072 crc D3741A3A md5 E12C5C2897ED095F8D26C7578AFDDFDA sha1 8AADD7DFB4ADD75D5AC5351658762E5F56E78C66 flags verified ) + rom ( name "Ninja Gaiden Shadow (USA).gb" size 131072 crc d3741a3a sha1 8AADD7DFB4ADD75D5AC5351658762E5F56E78C66 flags verified ) ) game ( name "Ninja Ryuuken Den - Matenrou Kessen (Japan)" description "Ninja Ryuuken Den - Matenrou Kessen (Japan)" - rom ( name "Ninja Ryuuken Den - Matenrou Kessen (Japan).gb" size 131072 crc D2BE3397 md5 7F896B5E5E27EDA1B08251EBE581C885 sha1 7200AC959877B4E4E423997D699A0E5C144F5B0B flags verified ) + rom ( name "Ninja Ryuuken Den - Matenrou Kessen (Japan).gb" size 131072 crc d2be3397 sha1 7200AC959877B4E4E423997D699A0E5C144F5B0B flags verified ) ) game ( name "Ninja Taro (USA)" description "Ninja Taro (USA)" - rom ( name "Ninja Taro (USA).gb" size 131072 crc C53EBFBD md5 1A52FB8F767E24DC75C3BB2D08679F6C sha1 BD472ED88042E032A57041EB0A889DA6AA3D1598 flags verified ) + rom ( name "Ninja Taro (USA).gb" size 131072 crc c53ebfbd sha1 BD472ED88042E032A57041EB0A889DA6AA3D1598 flags verified ) ) game ( name "Ninja Taro (USA) (Beta)" description "Ninja Taro (USA) (Beta)" - rom ( name "Ninja Taro (USA) (Beta).gb" size 131072 crc 61598B3D md5 A83273EDB8B89C84145D619D72EE19FE sha1 D93B6718E9C8A2505F4DA73B99F57866111948AF ) + rom ( name "Ninja Taro (USA) (Beta).gb" size 131072 crc 61598b3d sha1 D93B6718E9C8A2505F4DA73B99F57866111948AF flags verified ) ) game ( name "Ninku (Japan) (SGB Enhanced)" description "Ninku (Japan) (SGB Enhanced)" - rom ( name "Ninku (Japan) (SGB Enhanced).gb" size 524288 crc B50119EB md5 CEA0E2A46CCBF9B9A77B14379E49228E sha1 44B35AE3AA21D42D67B04A8581A0C83DC96521CE flags verified ) + rom ( name "Ninku (Japan) (SGB Enhanced).gb" size 524288 crc b50119eb sha1 44B35AE3AA21D42D67B04A8581A0C83DC96521CE flags verified ) ) game ( name "Ninku Dai-2-dan - Ninku Sensou Hen (Japan) (SGB Enhanced)" description "Ninku Dai-2-dan - Ninku Sensou Hen (Japan) (SGB Enhanced)" - rom ( name "Ninku Dai-2-dan - Ninku Sensou Hen (Japan) (SGB Enhanced).gb" size 524288 crc 7F818772 md5 C83CFED9C0CC9043EED5F761550DE64C sha1 52D3AB8B84E3E825280C6B5DB80933ACE1AA5909 flags verified ) + rom ( name "Ninku Dai-2-dan - Ninku Sensou Hen (Japan) (SGB Enhanced).gb" size 524288 crc 7f818772 sha1 52D3AB8B84E3E825280C6B5DB80933ACE1AA5909 flags verified ) ) game ( name "Nintama Rantarou GB (Japan) (SGB Enhanced)" description "Nintama Rantarou GB (Japan) (SGB Enhanced)" - rom ( name "Nintama Rantarou GB (Japan) (SGB Enhanced).gb" size 262144 crc BD223184 md5 A7032C0BBFE917790135ACD338EC3D2F sha1 4110BD38BDE1D9A9A20C2A0C73A3E9F799A72847 ) + rom ( name "Nintama Rantarou GB (Japan) (SGB Enhanced).gb" size 262144 crc bd223184 sha1 4110BD38BDE1D9A9A20C2A0C73A3E9F799A72847 flags verified ) ) game ( name "Nintama Rantarou GB - Eawase Challenge Puzzle (Japan) (SGB Enhanced)" description "Nintama Rantarou GB - Eawase Challenge Puzzle (Japan) (SGB Enhanced)" - rom ( name "Nintama Rantarou GB - Eawase Challenge Puzzle (Japan) (SGB Enhanced).gb" size 524288 crc 0E37E462 md5 1FF86F10D1104200BF316CDC6612B63C sha1 5642C866711BD5057A2C7DE2662D23A4A74D8BE9 flags verified ) + rom ( name "Nintama Rantarou GB - Eawase Challenge Puzzle (Japan) (SGB Enhanced).gb" size 524288 crc 0e37e462 sha1 5642C866711BD5057A2C7DE2662D23A4A74D8BE9 flags verified ) ) game ( name "Nintendo World Cup (USA, Europe)" description "Nintendo World Cup (USA, Europe)" - rom ( name "Nintendo World Cup (USA, Europe).gb" size 131072 crc 96C24E13 md5 C9200B1BE878F079CEE6CBEBBEAA27EA sha1 9308DADFEB1BECB81FE35015397DF6E8E8EAD06E flags verified ) + rom ( name "Nintendo World Cup (USA, Europe).gb" size 131072 crc 96c24e13 sha1 9308DADFEB1BECB81FE35015397DF6E8E8EAD06E flags verified ) ) game ( name "NIV Bible & the 20 Lost Levels of Joshua (USA) (Unl)" description "NIV Bible & the 20 Lost Levels of Joshua (USA) (Unl)" - rom ( name "NIV Bible & the 20 Lost Levels of Joshua (USA) (Unl).gb" size 2097152 crc E7A26B31 md5 8CDDB8B2DCD3EC1A3FDD770DF8BDA07C sha1 136CF97A8C3560EC9DB3D8F354D91B7DE27E0743 ) + rom ( name "NIV Bible & the 20 Lost Levels of Joshua (USA) (Unl).gb" size 2097152 crc e7a26b31 sha1 136CF97A8C3560EC9DB3D8F354D91B7DE27E0743 flags verified ) ) game ( name "Nobunaga no Yabou - Game Boy Ban (Japan)" description "Nobunaga no Yabou - Game Boy Ban (Japan)" - rom ( name "Nobunaga no Yabou - Game Boy Ban (Japan).gb" size 131072 crc 8803186A md5 E821EC4FE25C679EFEB9676A129C2130 sha1 B86474BE139BE4C7BD7AA8AD01C50D2C49F4B78B flags verified ) + rom ( name "Nobunaga no Yabou - Game Boy Ban (Japan).gb" size 131072 crc 8803186a sha1 B86474BE139BE4C7BD7AA8AD01C50D2C49F4B78B flags verified ) ) game ( name "Nobunaga's Ambition (USA)" description "Nobunaga's Ambition (USA)" - rom ( name "Nobunaga's Ambition (USA).gb" size 131072 crc 5A843008 md5 7CC78EA5DBC099E8F89849A11A08C38E sha1 D4DD65535D2A15F177289B53A49F1BC9E9B739F3 ) + rom ( name "Nobunaga's Ambition (USA).gb" size 131072 crc 5a843008 sha1 D4DD65535D2A15F177289B53A49F1BC9E9B739F3 ) ) game ( name "Nontan to Issho - Kurukuru Puzzle (Japan)" description "Nontan to Issho - Kurukuru Puzzle (Japan)" - rom ( name "Nontan to Issho - Kurukuru Puzzle (Japan).gb" size 131072 crc 6CD63B0B md5 3322CE4E576A33DF834BBFF80E627047 sha1 D9B2D7A30B68C8BBD4F91203A475B64B410A25AE ) + rom ( name "Nontan to Issho - Kurukuru Puzzle (Japan).gb" size 131072 crc 6cd63b0b sha1 D9B2D7A30B68C8BBD4F91203A475B64B410A25AE ) ) game ( name "Noobow (Japan)" description "Noobow (Japan)" - rom ( name "Noobow (Japan).gb" size 262144 crc 8BBCC8BB md5 CCD0CF7CC240714A9694E1FE296AFB7C sha1 B571D9051E3A9F1A55533B4F43941CAE907AEDFF flags verified ) + rom ( name "Noobow (Japan).gb" size 262144 crc 8bbcc8bb sha1 B571D9051E3A9F1A55533B4F43941CAE907AEDFF flags verified ) ) game ( name "Oddworld Adventures (USA, Europe)" description "Oddworld Adventures (USA, Europe)" - rom ( name "Oddworld Adventures (USA, Europe).gb" size 524288 crc 6510C0E2 md5 5CA71CD4CEACE3CB6650FF05D679D149 sha1 BE3F69371B6959DAB34014CB1D3672F4F3377C3A flags verified ) + rom ( name "Oddworld Adventures (USA, Europe).gb" size 524288 crc 6510c0e2 sha1 BE3F69371B6959DAB34014CB1D3672F4F3377C3A flags verified ) ) game ( name "Oira Jajamaru! Sekai Daibouken (Japan)" description "Oira Jajamaru! Sekai Daibouken (Japan)" - rom ( name "Oira Jajamaru! Sekai Daibouken (Japan).gb" size 131072 crc 2D08D27F md5 512B5B0CE0933A8C3217D810B23BEA0A sha1 5E13EEB635B41589689FC1B495EE077125B7E8C1 ) + rom ( name "Oira Jajamaru! Sekai Daibouken (Japan).gb" size 131072 crc 2d08d27f sha1 5E13EEB635B41589689FC1B495EE077125B7E8C1 ) ) game ( name "Olympic Summer Games (USA, Europe) (SGB Enhanced)" description "Olympic Summer Games (USA, Europe) (SGB Enhanced)" - rom ( name "Olympic Summer Games (USA, Europe) (SGB Enhanced).gb" size 524288 crc BE81BD61 md5 2BDA57560F54FE854EA5D53B60BD22A8 sha1 070D594FCD3637920234BF28206015287B97937E flags verified ) + rom ( name "Olympic Summer Games (USA, Europe) (SGB Enhanced).gb" size 524288 crc be81bd61 sha1 070D594FCD3637920234BF28206015287B97937E flags verified ) ) game ( - name "Oni II - Innin Densetsu (Japan)" - description "Oni II - Innin Densetsu (Japan)" - rom ( name "Oni II - Innin Densetsu (Japan).gb" size 262144 crc 2F895DF5 md5 D63C397E5F6C81E4ACCC9114F75EE574 sha1 7B40A873249F8306FF6C0277492ED28250D87FCC ) + name "Olympic Winter Games - Lillehammer '94 (USA)" + description "Olympic Winter Games - Lillehammer '94 (USA)" + rom ( name "Olympic Winter Games - Lillehammer '94 (USA).gb" size 131072 crc 1a98f0a4 sha1 95D664A8A0B74D6993501847D4CE065913BD1E08 ) +) + +game ( + name "Oni II - Oni Densetsu (Japan)" + description "Oni II - Oni Densetsu (Japan)" + rom ( name "Oni II - Oni Densetsu (Japan).gb" size 262144 crc 2f895df5 sha1 7B40A873249F8306FF6C0277492ED28250D87FCC flags verified ) ) game ( name "Oni III - Kuro no Hakaishin (Japan)" description "Oni III - Kuro no Hakaishin (Japan)" - rom ( name "Oni III - Kuro no Hakaishin (Japan).gb" size 262144 crc 6CD62FDB md5 906E42E643B65DDF4497CEA6B0EFB0A0 sha1 2813CF81A13D5A07A221320BA80DA0D3E271D87C ) + rom ( name "Oni III - Kuro no Hakaishin (Japan).gb" size 262144 crc 6cd62fdb sha1 2813CF81A13D5A07A221320BA80DA0D3E271D87C ) ) game ( name "Oni IV - Kijin no Ketsuzoku (Japan)" description "Oni IV - Kijin no Ketsuzoku (Japan)" - rom ( name "Oni IV - Kijin no Ketsuzoku (Japan).gb" size 262144 crc BEFF4F57 md5 399FA899194542C7BD5BA92969795AC5 sha1 5AF71863E48AFE1FB5F16AEE6FBE7F4E97EF54CE ) + rom ( name "Oni IV - Kijin no Ketsuzoku (Japan).gb" size 262144 crc beff4f57 sha1 5AF71863E48AFE1FB5F16AEE6FBE7F4E97EF54CE ) ) game ( - name "Oni V - Innin o Tsugumono (Japan) (SGB Enhanced)" - description "Oni V - Innin o Tsugumono (Japan) (SGB Enhanced)" - rom ( name "Oni V - Innin o Tsugumono (Japan) (SGB Enhanced).gb" size 262144 crc AF030940 md5 14A8E0BDB9F2B16D354CA0209E35AEDB sha1 197E2D2980053104ECF1C0EDBFF9F4D235518320 flags verified ) + name "Oni V - Oni wo Tsugumono (Japan) (SGB Enhanced)" + description "Oni V - Oni wo Tsugumono (Japan) (SGB Enhanced)" + rom ( name "Oni V - Oni wo Tsugumono (Japan) (SGB Enhanced).gb" size 262144 crc af030940 sha1 197E2D2980053104ECF1C0EDBFF9F4D235518320 flags verified ) ) game ( name "Onigashima Pachinkoten (Japan)" description "Onigashima Pachinkoten (Japan)" - rom ( name "Onigashima Pachinkoten (Japan).gb" size 131072 crc F54EC8EB md5 4150508F6882F691DC6DD3F28BC4D48F sha1 FF12ED91AA5CB3216860E7C18FF523B9BCB6A76A ) + rom ( name "Onigashima Pachinkoten (Japan).gb" size 131072 crc f54ec8eb sha1 FF12ED91AA5CB3216860E7C18FF523B9BCB6A76A ) ) game ( name "Operation C (USA)" description "Operation C (USA)" - rom ( name "Operation C (USA).gb" size 131072 crc 2EBBC1AE md5 C6EFFB3A51B36056411760D1FFE048F7 sha1 1DC3E1C62E62F77AC633408B544AC1D02B3761EB flags verified ) + rom ( name "Operation C (USA).gb" size 131072 crc 2ebbc1ae sha1 1DC3E1C62E62F77AC633408B544AC1D02B3761EB flags verified ) ) game ( name "Osawagase! Penguin Boy (Japan)" description "Osawagase! Penguin Boy (Japan)" - rom ( name "Osawagase! Penguin Boy (Japan).gb" size 65536 crc 54913227 md5 D939E5C1CE9436A548FCDD3938348BA1 sha1 1CDCF9810E98BA04378B2D6B555654722CB0ACF6 ) + rom ( name "Osawagase! Penguin Boy (Japan).gb" size 65536 crc 54913227 sha1 1CDCF9810E98BA04378B2D6B555654722CB0ACF6 ) ) game ( name "Othello (Europe)" description "Othello (Europe)" - rom ( name "Othello (Europe).gb" size 32768 crc E6607E29 md5 F57101BF26E140991A4E2F50A968CE7C sha1 03848A74502F4571BEC20B42ADAB86DED357AF81 flags verified ) + rom ( name "Othello (Europe).gb" size 32768 crc e6607e29 sha1 03848A74502F4571BEC20B42ADAB86DED357AF81 flags verified ) ) game ( name "Othello (Japan)" description "Othello (Japan)" - rom ( name "Othello (Japan).gb" size 32768 crc C17A002E md5 1123060CB5177D576C191D774EBE403A sha1 60A427C5DC6DAD226C80B120AA2E52725D719D16 flags verified ) + rom ( name "Othello (Japan).gb" size 32768 crc c17a002e sha1 60A427C5DC6DAD226C80B120AA2E52725D719D16 flags verified ) ) game ( name "Othello World (Japan) (SGB Enhanced)" description "Othello World (Japan) (SGB Enhanced)" - rom ( name "Othello World (Japan) (SGB Enhanced).gb" size 65536 crc 64D13A6D md5 BBEE4BC313CF03C016129E1E00B50008 sha1 089013EB2DAC79C5525C442BFC9CDA74E8660597 flags verified ) + rom ( name "Othello World (Japan) (SGB Enhanced).gb" size 65536 crc 64d13a6d sha1 089013EB2DAC79C5525C442BFC9CDA74E8660597 flags verified ) ) game ( name "Otogibanashi Taisen (Japan) (SGB Enhanced)" description "Otogibanashi Taisen (Japan) (SGB Enhanced)" - rom ( name "Otogibanashi Taisen (Japan) (SGB Enhanced).gb" size 262144 crc 98500521 md5 2A0465C954847A7DC00DBCF5D363CD16 sha1 49176CED7152D6D411DB1AA77D7A131F46E7A081 ) + rom ( name "Otogibanashi Taisen (Japan) (SGB Enhanced).gb" size 262144 crc 98500521 sha1 49176CED7152D6D411DB1AA77D7A131F46E7A081 ) ) game ( - name "Otto's Ottifanten - Baby Bruno's Nightmare (Europe) (En,Fr,De,Es)" - description "Otto's Ottifanten - Baby Bruno's Nightmare (Europe) (En,Fr,De,Es)" - rom ( name "Otto's Ottifanten - Baby Bruno's Nightmare (Europe) (En,Fr,De,Es).gb" size 262144 crc 0C228A78 md5 A9E795191670FE5994700C9CD8B7FBFD sha1 93EDD0772A3A65DF17EC5877E2BCFAFDA3020169 flags verified ) + name "Otto's Ottifanten - Baby Bruno's Alptraum (Europe) (En,Fr,De,Es)" + description "Otto's Ottifanten - Baby Bruno's Alptraum (Europe) (En,Fr,De,Es)" + rom ( name "Otto's Ottifanten - Baby Bruno's Alptraum (Europe) (En,Fr,De,Es).gb" size 262144 crc 0c228a78 sha1 93EDD0772A3A65DF17EC5877E2BCFAFDA3020169 flags verified ) ) game ( name "Out of Gas (USA)" description "Out of Gas (USA)" - rom ( name "Out of Gas (USA).gb" size 131072 crc 1B67E8B1 md5 0B7CBE56D1CF6370E60699E553D091A1 sha1 770AC35C0780CF432235593BD5674E72EDD6CF7D ) + rom ( name "Out of Gas (USA).gb" size 131072 crc 1b67e8b1 sha1 770AC35C0780CF432235593BD5674E72EDD6CF7D ) ) game ( name "Outburst (Japan)" description "Outburst (Japan)" - rom ( name "Outburst (Japan).gb" size 262144 crc 8AFCC4B0 md5 9DA5066FED7D826101A92688AA03059A sha1 2D5A27B675A1F3C0BE43E6F662F0159A3B3BF92B flags verified ) + rom ( name "Outburst (Japan).gb" size 262144 crc 8afcc4b0 sha1 2D5A27B675A1F3C0BE43E6F662F0159A3B3BF92B flags verified ) ) game ( name "Oyatsu Quiz Mogu Mogu Q (Japan) (SGB Enhanced)" description "Oyatsu Quiz Mogu Mogu Q (Japan) (SGB Enhanced)" - rom ( name "Oyatsu Quiz Mogu Mogu Q (Japan) (SGB Enhanced).gb" size 262144 crc 79E05789 md5 279022F2B918CBE8148B6F2C1A5F9ACF sha1 9B026834756201CCC58988F1718C2380BD8F6326 ) + rom ( name "Oyatsu Quiz Mogu Mogu Q (Japan) (SGB Enhanced).gb" size 262144 crc 79e05789 sha1 9B026834756201CCC58988F1718C2380BD8F6326 ) ) game ( name "P-Man GB (Japan)" description "P-Man GB (Japan)" - rom ( name "P-Man GB (Japan).gb" size 131072 crc 727D5509 md5 943A21195AFC5ABEFB3F925B84A9F19F sha1 D8704A68E1F3037C43E8987CA99F557AD6DBC0DE ) + rom ( name "P-Man GB (Japan).gb" size 131072 crc 727d5509 sha1 D8704A68E1F3037C43E8987CA99F557AD6DBC0DE ) ) game ( name "Pac-Attack (USA) (SGB Enhanced)" description "Pac-Attack (USA) (SGB Enhanced)" - rom ( name "Pac-Attack (USA) (SGB Enhanced).gb" size 131072 crc 94E0AF9C md5 8A0430CF49ABDA1FC055C16D2BBEA387 sha1 3FB6907D2352B34E0E60E3AE7B1D32F3E0C84FC9 ) + rom ( name "Pac-Attack (USA) (SGB Enhanced).gb" size 131072 crc 94e0af9c sha1 3FB6907D2352B34E0E60E3AE7B1D32F3E0C84FC9 flags verified ) ) game ( name "Pac-In-Time (USA) (SGB Enhanced)" description "Pac-In-Time (USA) (SGB Enhanced)" - rom ( name "Pac-In-Time (USA) (SGB Enhanced).gb" size 262144 crc 50A15DC8 md5 54EF4BB8C3D272AF5BB78B4306F37248 sha1 282F9BBABD5A57D5E7755E5D00F4D65094F816D5 ) + rom ( name "Pac-In-Time (USA) (SGB Enhanced).gb" size 262144 crc 50a15dc8 sha1 282F9BBABD5A57D5E7755E5D00F4D65094F816D5 flags verified ) ) game ( name "Pac-In-Time (Japan) (SGB Enhanced)" description "Pac-In-Time (Japan) (SGB Enhanced)" - rom ( name "Pac-In-Time (Japan) (SGB Enhanced).gb" size 262144 crc 1A5A38DA md5 F898DDF750D2C10675A1C3BB1B306E1B sha1 A804E8FC2614C55154B1A904639244BCA6553997 ) + rom ( name "Pac-In-Time (Japan) (SGB Enhanced).gb" size 262144 crc 1a5a38da sha1 A804E8FC2614C55154B1A904639244BCA6553997 ) ) game ( name "Pac-In-Time (Europe) (SGB Enhanced)" description "Pac-In-Time (Europe) (SGB Enhanced)" - rom ( name "Pac-In-Time (Europe) (SGB Enhanced).gb" size 262144 crc 8690B691 md5 E3B7B3649E52EE6AA6FD98BAF88D50DE sha1 63419FD7AF5FE2BA2F26A6CDAAD5ED9C399FE44A flags verified ) + rom ( name "Pac-In-Time (Europe) (SGB Enhanced).gb" size 262144 crc 8690b691 sha1 63419FD7AF5FE2BA2F26A6CDAAD5ED9C399FE44A flags verified ) ) game ( name "Pac-Man (Europe)" description "Pac-Man (Europe)" - rom ( name "Pac-Man (Europe).gb" size 65536 crc 0509069C md5 CD9027E147F4605F26EE261C537441B3 sha1 8D9FDA32419CA7030BA15F67FF8F857C1A119916 flags verified ) + rom ( name "Pac-Man (Europe).gb" size 65536 crc 0509069c sha1 8D9FDA32419CA7030BA15F67FF8F857C1A119916 flags verified ) ) game ( name "Pac-Man (Japan)" description "Pac-Man (Japan)" - rom ( name "Pac-Man (Japan).gb" size 65536 crc 65998F48 md5 1A76705A7617C4F2C54ECF60D89BD0AE sha1 AE088BBA7147780AFAF5CFF9E5B296F893DB823B ) + rom ( name "Pac-Man (Japan).gb" size 65536 crc 65998f48 sha1 AE088BBA7147780AFAF5CFF9E5B296F893DB823B ) ) game ( name "Pac-Man (USA)" description "Pac-Man (USA)" - rom ( name "Pac-Man (USA).gb" size 65536 crc B681E243 md5 F6B898BFAA367AC1B0782A363CD098C7 sha1 A05F50D3571C0572EB0433474A99C966A67A2D1B flags verified ) + rom ( name "Pac-Man (USA).gb" size 65536 crc b681e243 sha1 A05F50D3571C0572EB0433474A99C966A67A2D1B flags verified ) ) game ( name "Pac-Panic (Europe) (SGB Enhanced)" description "Pac-Panic (Europe) (SGB Enhanced)" - rom ( name "Pac-Panic (Europe) (SGB Enhanced).gb" size 131072 crc E4AF8F75 md5 E2E76C7E50D4463F9E628DF2933BB79A sha1 963222935BECB2139FB0133FBD9B02A1E239BBF2 ) + rom ( name "Pac-Panic (Europe) (SGB Enhanced).gb" size 131072 crc e4af8f75 sha1 963222935BECB2139FB0133FBD9B02A1E239BBF2 flags verified ) ) game ( name "Pac-Panic (Japan) (SGB Enhanced)" description "Pac-Panic (Japan) (SGB Enhanced)" - rom ( name "Pac-Panic (Japan) (SGB Enhanced).gb" size 131072 crc AAEBD509 md5 F683F5E516C1F267D4D16DC0E697F746 sha1 64573CD6C4A26087485AF540818C972CD256A881 ) + rom ( name "Pac-Panic (Japan) (SGB Enhanced).gb" size 131072 crc aaebd509 sha1 64573CD6C4A26087485AF540818C972CD256A881 ) ) game ( name "Pachi-Slot Hisshou Guide GB (Japan) (SGB Enhanced)" description "Pachi-Slot Hisshou Guide GB (Japan) (SGB Enhanced)" - rom ( name "Pachi-Slot Hisshou Guide GB (Japan) (SGB Enhanced).gb" size 131072 crc 6EE0F7B9 md5 835D8F147210C87FD0B0CB8416ADADE0 sha1 48564D29DD997878EB3165D7B40AC3FA8F287143 ) + rom ( name "Pachi-Slot Hisshou Guide GB (Japan) (SGB Enhanced).gb" size 131072 crc 6ee0f7b9 sha1 48564D29DD997878EB3165D7B40AC3FA8F287143 ) ) game ( name "Pachi-Slot Kids (Japan)" description "Pachi-Slot Kids (Japan)" - rom ( name "Pachi-Slot Kids (Japan).gb" size 131072 crc 8C21A77D md5 DD3B8A8023D8EB0C9766D42F78BE4FB1 sha1 5A510844BCD6ADFE73694A4781E446BF87FDF674 flags verified ) + rom ( name "Pachi-Slot Kids (Japan).gb" size 131072 crc 8c21a77d sha1 5A510844BCD6ADFE73694A4781E446BF87FDF674 flags verified ) ) game ( name "Pachi-Slot Kids 2 (Japan)" description "Pachi-Slot Kids 2 (Japan)" - rom ( name "Pachi-Slot Kids 2 (Japan).gb" size 131072 crc DEACE430 md5 629275BBCB97EF74B0A9138F70BD6CD7 sha1 DA6EBC9AD58B427A580F72233CB0364D039342A9 ) + rom ( name "Pachi-Slot Kids 2 (Japan).gb" size 131072 crc deace430 sha1 DA6EBC9AD58B427A580F72233CB0364D039342A9 ) ) game ( name "Pachi-Slot Kids 3 (Japan)" description "Pachi-Slot Kids 3 (Japan)" - rom ( name "Pachi-Slot Kids 3 (Japan).gb" size 262144 crc 40FC1186 md5 3164121570D96F879A1426DF2826269D sha1 73FD8B3CAF2C9A50FD5A5FA4BE56C50557095A60 ) + rom ( name "Pachi-Slot Kids 3 (Japan).gb" size 262144 crc 40fc1186 sha1 73FD8B3CAF2C9A50FD5A5FA4BE56C50557095A60 ) ) game ( name "Pachi-Slot World Cup '94 (Japan)" description "Pachi-Slot World Cup '94 (Japan)" - rom ( name "Pachi-Slot World Cup '94 (Japan).gb" size 131072 crc 92C9141F md5 C197D6AFC51B6BCF616781A5C32708A4 sha1 FAC33654DC37C120674A8F9E20019DFCCA72EBCD ) + rom ( name "Pachi-Slot World Cup '94 (Japan).gb" size 131072 crc 92c9141f sha1 FAC33654DC37C120674A8F9E20019DFCCA72EBCD ) ) game ( name "Pachinko CR Daiku no Gen-san GB (Japan) (SGB Enhanced)" description "Pachinko CR Daiku no Gen-san GB (Japan) (SGB Enhanced)" - rom ( name "Pachinko CR Daiku no Gen-san GB (Japan) (SGB Enhanced).gb" size 262144 crc 69A5E681 md5 DD807BCE8CE4A54A6BF40FF653BEEAF8 sha1 2FC86C0DA3601E7B614290B30197AAAE50AB510E ) + rom ( name "Pachinko CR Daiku no Gen-san GB (Japan) (SGB Enhanced).gb" size 262144 crc 69a5e681 sha1 2FC86C0DA3601E7B614290B30197AAAE50AB510E ) ) game ( name "Pachinko Data Card - Chou Ataru-kun (Japan) (SGB Enhanced)" description "Pachinko Data Card - Chou Ataru-kun (Japan) (SGB Enhanced)" - rom ( name "Pachinko Data Card - Chou Ataru-kun (Japan) (SGB Enhanced).gb" size 1048576 crc 955B25BA md5 808058B66A16E497AAB979BA53BBE37E sha1 B8799E2A7D6DF8A41F0E8F8857885F7CCC3397B8 ) + rom ( name "Pachinko Data Card - Chou Ataru-kun (Japan) (SGB Enhanced).gb" size 1048576 crc 955b25ba sha1 B8799E2A7D6DF8A41F0E8F8857885F7CCC3397B8 ) ) game ( name "Pachinko Kaguya Hime (Japan)" description "Pachinko Kaguya Hime (Japan)" - rom ( name "Pachinko Kaguya Hime (Japan).gb" size 131072 crc B6D9D6C4 md5 BBFBC7F8BF4BC6BC5F4B829B2E52D593 sha1 260E8BDCE496CE59ECCC48431009839011C1F5BC flags verified ) + rom ( name "Pachinko Kaguya Hime (Japan).gb" size 131072 crc b6d9d6c4 sha1 260E8BDCE496CE59ECCC48431009839011C1F5BC flags verified ) ) game ( name "Pachinko Monogatari Gaiden (Japan) (SGB Enhanced)" description "Pachinko Monogatari Gaiden (Japan) (SGB Enhanced)" - rom ( name "Pachinko Monogatari Gaiden (Japan) (SGB Enhanced).gb" size 524288 crc 52ADB7F9 md5 508F13C91C125DFC8EA0334D3BD9B2FD sha1 B5229F7263ED761FBF30E98D88192787E79BCC56 ) + rom ( name "Pachinko Monogatari Gaiden (Japan) (SGB Enhanced).gb" size 524288 crc 52adb7f9 sha1 B5229F7263ED761FBF30E98D88192787E79BCC56 ) ) game ( name "Pachinko Saiyuuki (Japan)" description "Pachinko Saiyuuki (Japan)" - rom ( name "Pachinko Saiyuuki (Japan).gb" size 131072 crc E05843D3 md5 59582082C1ACCA301B5E5E2A684BB66B sha1 9AAE7F3C969C835E697E0CB703FA76994FFBE137 flags verified ) + rom ( name "Pachinko Saiyuuki (Japan).gb" size 131072 crc 8f931831 sha1 8BBC798EB5B531F513FFA56F105983F19F9CAA1E flags verified ) ) game ( name "Pachinko Time (Japan)" description "Pachinko Time (Japan)" - rom ( name "Pachinko Time (Japan).gb" size 65536 crc 47658ADE md5 BE99CA18C5B9DBB90B4E08F164855BE5 sha1 EF0E7C6B39744342397523E31E861EC09246613D flags verified ) + rom ( name "Pachinko Time (Japan).gb" size 65536 crc 47658ade sha1 EF0E7C6B39744342397523E31E861EC09246613D flags verified ) ) game ( name "Pachio-kun (Japan)" description "Pachio-kun (Japan)" - rom ( name "Pachio-kun (Japan).gb" size 131072 crc 9A3E2DC2 md5 DE3860796170EE4CA80D302A5F024474 sha1 A7D82002B2A263B2CE4C09417FC639713601AEC1 ) -) - -game ( - name "Pachio-kun - Game Gallery (Japan)" - description "Pachio-kun - Game Gallery (Japan)" - rom ( name "Pachio-kun - Game Gallery (Japan).gb" size 524288 crc BE4718E8 md5 4781664E85368B224ABFA7C01A421F18 sha1 010F512C53A84EDBC38C817E7F556EB308834E29 ) + rom ( name "Pachio-kun (Japan).gb" size 131072 crc 9a3e2dc2 sha1 A7D82002B2A263B2CE4C09417FC639713601AEC1 ) ) game ( name "Pachio-kun - Puzzle Castle (Japan)" description "Pachio-kun - Puzzle Castle (Japan)" - rom ( name "Pachio-kun - Puzzle Castle (Japan).gb" size 131072 crc 3690C99C md5 4625FCE9752DF3666F19EFD2A6F03748 sha1 946D25B62C6F4BEA3214551260EB52BA68E23C8E ) + rom ( name "Pachio-kun - Puzzle Castle (Japan).gb" size 131072 crc 3690c99c sha1 946D25B62C6F4BEA3214551260EB52BA68E23C8E ) ) game ( name "Pachio-kun 2 (Japan)" description "Pachio-kun 2 (Japan)" - rom ( name "Pachio-kun 2 (Japan).gb" size 131072 crc 3E8D0AE9 md5 FFED7CC94E45730F0ACD41DA998C6820 sha1 AA7F33113CABB0395848A237F819300B0F2E13DB flags verified ) + rom ( name "Pachio-kun 2 (Japan).gb" size 131072 crc 3e8d0ae9 sha1 AA7F33113CABB0395848A237F819300B0F2E13DB flags verified ) ) game ( name "Pachio-kun 3 (Japan)" description "Pachio-kun 3 (Japan)" - rom ( name "Pachio-kun 3 (Japan).gb" size 131072 crc C6DD7D92 md5 55CEE72182F73704AC2240A971887210 sha1 A57E7919D962DF82D77D39BF81DFCAB124506ACA ) + rom ( name "Pachio-kun 3 (Japan).gb" size 131072 crc c6dd7d92 sha1 A57E7919D962DF82D77D39BF81DFCAB124506ACA ) +) + +game ( + name "Pachio-kun Game Gallery (Japan)" + description "Pachio-kun Game Gallery (Japan)" + rom ( name "Pachio-kun Game Gallery (Japan).gb" size 524288 crc be4718e8 sha1 010F512C53A84EDBC38C817E7F556EB308834E29 ) ) game ( name "Pagemaster, The (Europe) (SGB Enhanced)" description "Pagemaster, The (Europe) (SGB Enhanced)" - rom ( name "Pagemaster, The (Europe) (SGB Enhanced).gb" size 262144 crc C9BE96D3 md5 2B3C9EE51F0E89DF14C3698B293BA531 sha1 9B3063350581CEC9CF595A78FAA8D415B75BE399 flags verified ) + rom ( name "Pagemaster, The (Europe) (SGB Enhanced).gb" size 262144 crc c9be96d3 sha1 9B3063350581CEC9CF595A78FAA8D415B75BE399 flags verified ) ) game ( name "Pagemaster, The (USA) (SGB Enhanced)" description "Pagemaster, The (USA) (SGB Enhanced)" - rom ( name "Pagemaster, The (USA) (SGB Enhanced).gb" size 262144 crc CDFA71E5 md5 0040B5BD11A936063A0DC9A30B9A8727 sha1 1D1DFDAB693FDB1A3A1388CAE34AF017F79C41AB ) + rom ( name "Pagemaster, The (USA) (SGB Enhanced).gb" size 262144 crc cdfa71e5 sha1 1D1DFDAB693FDB1A3A1388CAE34AF017F79C41AB ) ) game ( name "Painter Momopie (Japan)" description "Painter Momopie (Japan)" - rom ( name "Painter Momopie (Japan).gb" size 65536 crc FB79EF58 md5 7A1DB9950B7FB12499DF822B32EF1ED9 sha1 193901223FFC89CF4F42A19E57447249AFFCC843 ) + rom ( name "Painter Momopie (Japan).gb" size 65536 crc fb79ef58 sha1 193901223FFC89CF4F42A19E57447249AFFCC843 ) ) game ( name "Palamedes (Europe)" description "Palamedes (Europe)" - rom ( name "Palamedes (Europe).gb" size 32768 crc 526942E1 md5 F4E5B89F72CF88C203D8F66C627ACD91 sha1 F93F5B939985935B9CCE1364119344B9DC236F57 flags verified ) + rom ( name "Palamedes (Europe).gb" size 32768 crc 526942e1 sha1 F93F5B939985935B9CCE1364119344B9DC236F57 flags verified ) ) game ( name "Palamedes (Japan)" description "Palamedes (Japan)" - rom ( name "Palamedes (Japan).gb" size 32768 crc 4B993D0D md5 27E8623A411F04FDF53B43508A0D2A7B sha1 789694FCE114BF076F77DDA4858C1AB53B35E6A4 flags verified ) + rom ( name "Palamedes (Japan).gb" size 32768 crc 4b993d0d sha1 789694FCE114BF076F77DDA4858C1AB53B35E6A4 flags verified ) ) game ( name "Panel Action Bingo (USA)" description "Panel Action Bingo (USA)" - rom ( name "Panel Action Bingo (USA).gb" size 65536 crc D000A116 md5 E0B6FF29D6F0FC5B7509B70CB7C0ACA5 sha1 527AEAAA52722605C98314CB7E522BB3A95A3B29 ) + rom ( name "Panel Action Bingo (USA).gb" size 65536 crc d000a116 sha1 527AEAAA52722605C98314CB7E522BB3A95A3B29 ) ) game ( name "Panel no Ninja Kesamaru (Japan)" description "Panel no Ninja Kesamaru (Japan)" - rom ( name "Panel no Ninja Kesamaru (Japan).gb" size 65536 crc 12CAA1CA md5 4EAD57F6FB441FB86A78922F1288EE40 sha1 67F8DEA045BC2D01C00936A66CD4B56B10FA0F39 ) + rom ( name "Panel no Ninja Kesamaru (Japan).gb" size 65536 crc 12caa1ca sha1 67F8DEA045BC2D01C00936A66CD4B56B10FA0F39 ) ) game ( name "Pang (Europe)" description "Pang (Europe)" - rom ( name "Pang (Europe).gb" size 131072 crc 9AE199DF md5 031E78C5067B88ABE2870841D1125A29 sha1 AE97143E51B6F031EFB83B245B1B2558E6CB9026 ) + rom ( name "Pang (Europe).gb" size 131072 crc 9ae199df sha1 AE97143E51B6F031EFB83B245B1B2558E6CB9026 ) ) game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" - rom ( name "Paperboy (USA, Europe).gb" size 65536 crc 46DE32BA md5 DCABC0879C258E54048237D280FFA7DA sha1 4103B51BBD75572181D407821890F167462A996B flags verified ) + rom ( name "Paperboy (USA, Europe).gb" size 65536 crc 46de32ba sha1 4103B51BBD75572181D407821890F167462A996B flags verified ) ) game ( name "Paperboy 2 (USA, Europe)" description "Paperboy 2 (USA, Europe)" - rom ( name "Paperboy 2 (USA, Europe).gb" size 262144 crc 8EE404CA md5 86E22A57CF0055F858ACC9A4062EBC30 sha1 473D84E2BFDB2DC2615B2EA416188C62FEDB4ECF flags verified ) + rom ( name "Paperboy 2 (USA, Europe).gb" size 262144 crc 8ee404ca sha1 473D84E2BFDB2DC2615B2EA416188C62FEDB4ECF flags verified ) ) game ( name "Parasol Henbee (Japan)" description "Parasol Henbee (Japan)" - rom ( name "Parasol Henbee (Japan).gb" size 65536 crc AE97EC53 md5 E0AADD04CF2C955FF60D9446B2B18931 sha1 8F319D3D1929D953934E32CE900249ECF6B55FBD flags verified ) + rom ( name "Parasol Henbee (Japan).gb" size 65536 crc ae97ec53 sha1 8F319D3D1929D953934E32CE900249ECF6B55FBD flags verified ) ) game ( name "Parasol Stars - Rainbow Islands II (Europe)" description "Parasol Stars - Rainbow Islands II (Europe)" - rom ( name "Parasol Stars - Rainbow Islands II (Europe).gb" size 131072 crc C35AD128 md5 AB5E4C728A5B62F7985C22C61551469C sha1 4970BBF5456305F2BFDB27E3A0DC14BE4A0E10B7 flags verified ) + rom ( name "Parasol Stars - Rainbow Islands II (Europe).gb" size 131072 crc c35ad128 sha1 4970BBF5456305F2BFDB27E3A0DC14BE4A0E10B7 flags verified ) ) game ( name "Parodius (Europe)" description "Parodius (Europe)" - rom ( name "Parodius (Europe).gb" size 262144 crc 85748525 md5 C94AFB46CADA0118AA8FF08CC07749A4 sha1 A00A1ADC326D368E9198C006D43C0FD1AB290219 flags verified ) + rom ( name "Parodius (Europe).gb" size 262144 crc 85748525 sha1 A00A1ADC326D368E9198C006D43C0FD1AB290219 flags verified ) ) game ( name "Parodius Da! (Japan)" description "Parodius Da! (Japan)" - rom ( name "Parodius Da! (Japan).gb" size 262144 crc 1791E952 md5 2E3A0305F79B058CC4618565BC2DB745 sha1 CFE0C6619A28DDD535214C8F8C446081C0ED8194 flags verified ) + rom ( name "Parodius Da! (Japan).gb" size 262144 crc 1791e952 sha1 CFE0C6619A28DDD535214C8F8C446081C0ED8194 flags verified ) ) game ( name "Peetan (Japan)" description "Peetan (Japan)" - rom ( name "Peetan (Japan).gb" size 131072 crc D0040F49 md5 1A9C3966C0C2D17C1D67A0A49409DB29 sha1 D3059A96DCBCE249DE69A969003E3164A6896C5E ) + rom ( name "Peetan (Japan).gb" size 131072 crc d0040f49 sha1 D3059A96DCBCE249DE69A969003E3164A6896C5E ) ) game ( name "Peke to Poko no Daruman Busters (Japan)" description "Peke to Poko no Daruman Busters (Japan)" - rom ( name "Peke to Poko no Daruman Busters (Japan).gb" size 65536 crc A66F5C02 md5 B86BE9C65C1BA0DB48D6EB8E0770926D sha1 A782F490AE8F7EB7140D9D23FD8BD181B1A916F4 flags verified ) + rom ( name "Peke to Poko no Daruman Busters (Japan).gb" size 65536 crc a66f5c02 sha1 A782F490AE8F7EB7140D9D23FD8BD181B1A916F4 flags verified ) ) game ( name "Penguin Land (Japan)" description "Penguin Land (Japan)" - rom ( name "Penguin Land (Japan).gb" size 32768 crc A9E62E88 md5 62F6B0C1C7EED0AF0CB7D9F15D14E7C8 sha1 C9CB05557006B0F99790D19E3972258AB92DA6CF ) + rom ( name "Penguin Land (Japan).gb" size 32768 crc a9e62e88 sha1 C9CB05557006B0F99790D19E3972258AB92DA6CF ) ) game ( name "Penguin Wars (USA)" description "Penguin Wars (USA)" - rom ( name "Penguin Wars (USA).gb" size 65536 crc EECFF7F3 md5 9C17A77F10F8C8024ADDC299CFD74B8B sha1 2C00F5678D55DCB865B596FCB1DBECD2C9213988 ) + rom ( name "Penguin Wars (USA).gb" size 65536 crc eecff7f3 sha1 2C00F5678D55DCB865B596FCB1DBECD2C9213988 ) ) game ( name "Penguin-kun Wars VS. (Japan)" description "Penguin-kun Wars VS. (Japan)" - rom ( name "Penguin-kun Wars VS. (Japan).gb" size 65536 crc C169606D md5 6EDAB4CBBFEB6F5A04AF669A31559F1C sha1 F19E870E95C03288B019EF6BAC3966BF74DD48FB flags verified ) + rom ( name "Penguin-kun Wars VS. (Japan).gb" size 65536 crc c169606d sha1 F19E870E95C03288B019EF6BAC3966BF74DD48FB flags verified ) ) game ( name "Penta Dragon (Japan)" description "Penta Dragon (Japan)" - rom ( name "Penta Dragon (Japan).gb" size 262144 crc 1E2EFAEE md5 DF43E0ADFDC74B2829C7E95E91C71A28 sha1 FD75D43258E79F14D104FB4756E219141882C837 ) + rom ( name "Penta Dragon (Japan).gb" size 262144 crc 1e2efaee sha1 FD75D43258E79F14D104FB4756E219141882C837 flags verified ) ) game ( name "PGA European Tour (USA, Europe) (SGB Enhanced)" description "PGA European Tour (USA, Europe) (SGB Enhanced)" - rom ( name "PGA European Tour (USA, Europe) (SGB Enhanced).gb" size 524288 crc 7D7DEF64 md5 248DAC256CCD86A224E7B28D86FA8BDE sha1 FF0FDF447E91AF93FDA6C1B6A1675986D798798A flags verified ) + rom ( name "PGA European Tour (USA, Europe) (SGB Enhanced).gb" size 524288 crc 7d7def64 sha1 FF0FDF447E91AF93FDA6C1B6A1675986D798798A flags verified ) ) game ( name "PGA Tour 96 (USA, Europe) (SGB Enhanced)" description "PGA Tour 96 (USA, Europe) (SGB Enhanced)" - rom ( name "PGA Tour 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6FF72043 md5 0D1406D83D25D417B8DE92BE3F302EBA sha1 8566F5C09CCB682BBC74CADCBC9FFCC8FC349968 flags verified ) + rom ( name "PGA Tour 96 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6ff72043 sha1 8566F5C09CCB682BBC74CADCBC9FFCC8FC349968 flags verified ) ) game ( name "Phantasm (Japan)" description "Phantasm (Japan)" - rom ( name "Phantasm (Japan).gb" size 262144 crc E742561E md5 2A457900607B2BF87D1377F066D7AA44 sha1 64B55F6FCE16E80BDB9825B5246E7C05D76AF7AE ) + rom ( name "Phantasm (Japan).gb" size 262144 crc e742561e sha1 64B55F6FCE16E80BDB9825B5246E7C05D76AF7AE ) ) game ( name "Phantom Air Mission (Europe)" description "Phantom Air Mission (Europe)" - rom ( name "Phantom Air Mission (Europe).gb" size 131072 crc 8ACED4A6 md5 6560B1BA5589509EFF4D1EDF318FBE58 sha1 2A270597D7B814A1C8819A5698AB922200569206 flags verified ) + rom ( name "Phantom Air Mission (Europe).gb" size 131072 crc 8aced4a6 sha1 2A270597D7B814A1C8819A5698AB922200569206 flags verified ) ) game ( name "Picross 2 (Japan) (SGB Enhanced)" description "Picross 2 (Japan) (SGB Enhanced)" - rom ( name "Picross 2 (Japan) (SGB Enhanced).gb" size 524288 crc F5AA5902 md5 142D1F9F4B868780824CCA20010AD4D8 sha1 57788519111CBE9E20B43D1935E9F52AE165E858 ) + rom ( name "Picross 2 (Japan) (SGB Enhanced).gb" size 524288 crc f5aa5902 sha1 57788519111CBE9E20B43D1935E9F52AE165E858 flags verified ) ) game ( - name "Pierre le Chef Is... Out to Lunch (Europe)" - description "Pierre le Chef Is... Out to Lunch (Europe)" - rom ( name "Pierre le Chef Is... Out to Lunch (Europe).gb" size 131072 crc 0145BB6C md5 E41AAC285898754055EB3F0C3F280EA3 sha1 5A2E27C74DF619ADF2C80964F9EDCEBD0D82C581 flags verified ) + name "Pierre le Chef is... Out to Lunch (Europe)" + description "Pierre le Chef is... Out to Lunch (Europe)" + rom ( name "Pierre le Chef is... Out to Lunch (Europe).gb" size 131072 crc 0145bb6c sha1 5A2E27C74DF619ADF2C80964F9EDCEBD0D82C581 flags verified ) ) game ( name "Pinball - 66hiki no Wani Daikoushin! (Japan)" description "Pinball - 66hiki no Wani Daikoushin! (Japan)" - rom ( name "Pinball - 66hiki no Wani Daikoushin! (Japan).gb" size 65536 crc 1B3A89C6 md5 C03ABC409B442AA42864CB2AC2BA89B9 sha1 3671335514B388EE08322416ABD873F11A5E0B66 flags verified ) + rom ( name "Pinball - 66hiki no Wani Daikoushin! (Japan).gb" size 65536 crc 1b3a89c6 sha1 3671335514B388EE08322416ABD873F11A5E0B66 flags verified ) ) game ( name "Pinball - Revenge of the 'Gator (USA, Europe)" description "Pinball - Revenge of the 'Gator (USA, Europe)" - rom ( name "Pinball - Revenge of the 'Gator (USA, Europe).gb" size 65536 crc 79804305 md5 113D8F894DF6B8C3641B2BA1FE60C250 sha1 493834DB1C3C7859086A1C570A4BF5E5F6DD332B flags verified ) + rom ( name "Pinball - Revenge of the 'Gator (USA, Europe).gb" size 65536 crc 79804305 sha1 493834DB1C3C7859086A1C570A4BF5E5F6DD332B flags verified ) ) game ( name "Pinball Deluxe (Europe)" description "Pinball Deluxe (Europe)" - rom ( name "Pinball Deluxe (Europe).gb" size 262144 crc 02864C32 md5 FA4AF656B09274E5B8139BE0A3A39A2C sha1 A99D8A9880ED79B40766B3A532F8A165171CA450 flags verified ) + rom ( name "Pinball Deluxe (Europe).gb" size 262144 crc 02864c32 sha1 A99D8A9880ED79B40766B3A532F8A165171CA450 flags verified ) ) game ( name "Pinball Dreams (USA, Europe)" description "Pinball Dreams (USA, Europe)" - rom ( name "Pinball Dreams (USA, Europe).gb" size 131072 crc 6DA713E3 md5 49C8EAA9801C56B432BEB6CF51D7FDE0 sha1 A84E46E6A102B9DD65C3156582C0B22B3D9D6832 flags verified ) + rom ( name "Pinball Dreams (USA, Europe).gb" size 131072 crc 6da713e3 sha1 A84E46E6A102B9DD65C3156582C0B22B3D9D6832 flags verified ) ) game ( name "Pinball Fantasies (USA, Europe)" description "Pinball Fantasies (USA, Europe)" - rom ( name "Pinball Fantasies (USA, Europe).gb" size 262144 crc F056A911 md5 3496B0CAB86AE1981142C0DDB9AE6183 sha1 58243F69598F2119F42DC4B35E89F04F92BB6D72 flags verified ) + rom ( name "Pinball Fantasies (USA, Europe).gb" size 262144 crc f056a911 sha1 58243F69598F2119F42DC4B35E89F04F92BB6D72 flags verified ) ) game ( name "Pinball Mania (Europe)" description "Pinball Mania (Europe)" - rom ( name "Pinball Mania (Europe).gb" size 262144 crc EDC8D122 md5 1D44F2B3C1E0A1CB65BCD4D5D0486776 sha1 0541161B4B93FFFC3C75708ACA86EA0873747CED flags verified ) + rom ( name "Pinball Mania (Europe).gb" size 262144 crc edc8d122 sha1 0541161B4B93FFFC3C75708ACA86EA0873747CED flags verified ) ) game ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan)" description "Pingu - Sekai de 1ban Genki na Penguin (Japan)" - rom ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan).gb" size 262144 crc A8DD80C6 md5 4202E3486B95AB9A5718830B2AA9B7F6 sha1 3EE536AD6CEE67DB12DE648B60E4E71E50A072AC ) + rom ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan).gb" size 262144 crc a8dd80c6 sha1 3EE536AD6CEE67DB12DE648B60E4E71E50A072AC ) ) game ( name "Pinocchio (Europe)" description "Pinocchio (Europe)" - rom ( name "Pinocchio (Europe).gb" size 262144 crc 085C4A02 md5 37F2E18C9C015C6578EF3DD404DAFE26 sha1 7716809645E00BE2FDBBBFD05823A14856F01183 flags verified ) + rom ( name "Pinocchio (Europe).gb" size 262144 crc 085c4a02 sha1 7716809645E00BE2FDBBBFD05823A14856F01183 flags verified ) ) game ( name "Pinocchio (USA)" description "Pinocchio (USA)" - rom ( name "Pinocchio (USA).gb" size 262144 crc 2D924E46 md5 97FECF5AB824825B781771A40E1C60BF sha1 E17C15325A1EAF5BB365AE4923C660E8C98A1D6B ) + rom ( name "Pinocchio (USA).gb" size 262144 crc 2d924e46 sha1 E17C15325A1EAF5BB365AE4923C660E8C98A1D6B ) ) game ( name "Pipe Dream (Japan)" description "Pipe Dream (Japan)" - rom ( name "Pipe Dream (Japan).gb" size 32768 crc D8B4AEA4 md5 D9BACB4B392A0CE4E8F9D29BAA916B0B sha1 64A58AAFECB0ACEED2DDE843A19A28B2BB000B2F flags verified ) + rom ( name "Pipe Dream (Japan).gb" size 32768 crc d8b4aea4 sha1 64A58AAFECB0ACEED2DDE843A19A28B2BB000B2F flags verified ) ) game ( name "Pipe Dream (USA)" description "Pipe Dream (USA)" - rom ( name "Pipe Dream (USA).gb" size 32768 crc F59CEDEA md5 0F021462180B18436C21299E923CCA91 sha1 12A2C76EC96CC94A4C7EEAD6536EDDD5F3F9998F flags verified ) + rom ( name "Pipe Dream (USA).gb" size 32768 crc f59cedea sha1 12A2C76EC96CC94A4C7EEAD6536EDDD5F3F9998F flags verified ) ) game ( - name "Pit Fighter (USA, Europe)" - description "Pit Fighter (USA, Europe)" - rom ( name "Pit Fighter (USA, Europe).gb" size 262144 crc 0680BFC3 md5 09066099D74C7398F6F99EA8CCEFA479 sha1 2A399B0524E9983FD361A98EC4B99D562361223B flags verified ) + name "Pit-Fighter (USA, Europe)" + description "Pit-Fighter (USA, Europe)" + rom ( name "Pit-Fighter (USA, Europe).gb" size 262144 crc 0680bfc3 sha1 2A399B0524E9983FD361A98EC4B99D562361223B flags verified ) ) game ( name "Pitman (Japan)" description "Pitman (Japan)" - rom ( name "Pitman (Japan).gb" size 32768 crc A0B68136 md5 45F764BF05ABE6102A641642C71CEDE3 sha1 A698D4BCCD69D2CA51CB48877BDE5D1F83D4317F flags verified ) + rom ( name "Pitman (Japan).gb" size 32768 crc a0b68136 sha1 A698D4BCCD69D2CA51CB48877BDE5D1F83D4317F flags verified ) ) game ( name "Play Action Football (USA)" description "Play Action Football (USA)" - rom ( name "Play Action Football (USA).gb" size 131072 crc 983CAF46 md5 4CEE4E93651D9468E7EF47975B71ACA2 sha1 DC2981BAF1BB4D0A65EC45FB22D44A5CA4C06254 ) + rom ( name "Play Action Football (USA).gb" size 131072 crc 983caf46 sha1 DC2981BAF1BB4D0A65EC45FB22D44A5CA4C06254 ) ) game ( name "Pocahontas (USA, Europe) (SGB Enhanced)" description "Pocahontas (USA, Europe) (SGB Enhanced)" - rom ( name "Pocahontas (USA, Europe) (SGB Enhanced).gb" size 524288 crc CE58C63D md5 966CC6DF20D8C5D42F690F28BBCC8CAA sha1 2A974981CFAAE8096F09B76D060EC06C696963AC flags verified ) + rom ( name "Pocahontas (USA, Europe) (SGB Enhanced).gb" size 524288 crc ce58c63d sha1 2A974981CFAAE8096F09B76D060EC06C696963AC flags verified ) ) game ( name "Pocket Bass Fishing (Japan)" description "Pocket Bass Fishing (Japan)" - rom ( name "Pocket Bass Fishing (Japan).gb" size 131072 crc 2C88F996 md5 E32F759CA399650F8A35535D0D815C23 sha1 C59402EAF86FB8D52DDF81E3054AB78A06A07EB3 flags verified ) + rom ( name "Pocket Bass Fishing (Japan).gb" size 131072 crc 2c88f996 sha1 C59402EAF86FB8D52DDF81E3054AB78A06A07EB3 flags verified ) ) game ( name "Pocket Battle (Japan)" description "Pocket Battle (Japan)" - rom ( name "Pocket Battle (Japan).gb" size 131072 crc 17114316 md5 FF22733A091E9D32596FBFF8331153C6 sha1 9993242A8C9412A88B207A941531C0A5D0E4B8EC flags verified ) + rom ( name "Pocket Battle (Japan).gb" size 131072 crc 17114316 sha1 9993242A8C9412A88B207A941531C0A5D0E4B8EC flags verified ) ) game ( name "Pocket Bomber Man (Japan) (SGB Enhanced)" description "Pocket Bomber Man (Japan) (SGB Enhanced)" - rom ( name "Pocket Bomber Man (Japan) (SGB Enhanced).gb" size 524288 crc 212B47A5 md5 50971F6CBB3E4395CB66213D7F096B46 sha1 83D1C2420AE69D2A7CA9880C9B84F0BA948E39EB flags verified ) + rom ( name "Pocket Bomber Man (Japan) (SGB Enhanced).gb" size 524288 crc 212b47a5 sha1 83D1C2420AE69D2A7CA9880C9B84F0BA948E39EB flags verified ) ) game ( name "Pocket Bomberman (Europe) (SGB Enhanced)" description "Pocket Bomberman (Europe) (SGB Enhanced)" - rom ( name "Pocket Bomberman (Europe) (SGB Enhanced).gb" size 524288 crc 0FD1AE54 md5 3050CDF055B1D036F85C9C629B03FBF2 sha1 34F377A6DE2961FE16BFB854E0CEBC7FDBA7CF4B ) + rom ( name "Pocket Bomberman (Europe) (SGB Enhanced).gb" size 524288 crc 0fd1ae54 sha1 34F377A6DE2961FE16BFB854E0CEBC7FDBA7CF4B ) ) game ( - name "Pocket Camera (Japan) (Rev A) (SGB Enhanced)" - description "Pocket Camera (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Pocket Camera (Japan) (Rev A) (SGB Enhanced).gb" size 1048576 crc 73E8EF96 md5 FDCFE686CF4DF461E870B6E53B2B5A8B sha1 912205EA22E1DD735ED4F41D247039EEBF39DDDC ) + name "Pocket Camera (Japan) (Rev 1) (SGB Enhanced)" + description "Pocket Camera (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Pocket Camera (Japan) (Rev 1) (SGB Enhanced).gb" size 1048576 crc 73e8ef96 sha1 912205EA22E1DD735ED4F41D247039EEBF39DDDC ) ) game ( name "Pocket Densha (Japan) (SGB Enhanced)" description "Pocket Densha (Japan) (SGB Enhanced)" - rom ( name "Pocket Densha (Japan) (SGB Enhanced).gb" size 524288 crc 845BB677 md5 E764267D68869AE2E7D6FDB37BB76F45 sha1 702981654640FE59C2F6B47C7191A58BE0804A4D flags verified ) + rom ( name "Pocket Densha (Japan) (SGB Enhanced).gb" size 524288 crc 845bb677 sha1 702981654640FE59C2F6B47C7191A58BE0804A4D flags verified ) ) game ( - name "Pocket Family (Japan) (SGB Enhanced)" - description "Pocket Family (Japan) (SGB Enhanced)" - rom ( name "Pocket Family (Japan) (SGB Enhanced).gb" size 524288 crc 48993D4F md5 80644B75F16DC41B5B474807FA2FA765 sha1 162B0AB1FCFCF9B7AC888F137FEDC41264219CF9 flags verified ) + name "Pocket Family GB (Japan) (SGB Enhanced)" + description "Pocket Family GB (Japan) (SGB Enhanced)" + rom ( name "Pocket Family GB (Japan) (SGB Enhanced).gb" size 524288 crc 48993d4f sha1 162B0AB1FCFCF9B7AC888F137FEDC41264219CF9 flags verified ) ) game ( name "Pocket Golf (Japan)" description "Pocket Golf (Japan)" - rom ( name "Pocket Golf (Japan).gb" size 131072 crc 755152BB md5 0EFE8E1F415CA008202BE92566EFDF75 sha1 7747DC7E6BEAF824C79DD4308735E259445D5E19 flags verified ) + rom ( name "Pocket Golf (Japan).gb" size 131072 crc 755152bb sha1 7747DC7E6BEAF824C79DD4308735E259445D5E19 flags verified ) ) game ( name "Pocket Kanjirou (Japan) (SGB Enhanced)" description "Pocket Kanjirou (Japan) (SGB Enhanced)" - rom ( name "Pocket Kanjirou (Japan) (SGB Enhanced).gb" size 524288 crc E18AEDAF md5 B8AE13EDC37731756974A2B520763F20 sha1 EF150C97CB4E9A46F90D826B1AAD208CBAA4410F ) + rom ( name "Pocket Kanjirou (Japan) (SGB Enhanced).gb" size 524288 crc e18aedaf sha1 EF150C97CB4E9A46F90D826B1AAD208CBAA4410F ) ) game ( name "Pocket Kyoro-chan (Japan) (SGB Enhanced)" description "Pocket Kyoro-chan (Japan) (SGB Enhanced)" - rom ( name "Pocket Kyoro-chan (Japan) (SGB Enhanced).gb" size 262144 crc C034ECE1 md5 9C189413F62B92172B0BB95E81731465 sha1 0506DEFFDF9FEE21DDA394E272C84FE8DF2FBEC0 ) + rom ( name "Pocket Kyoro-chan (Japan) (SGB Enhanced).gb" size 262144 crc c034ece1 sha1 0506DEFFDF9FEE21DDA394E272C84FE8DF2FBEC0 flags verified ) ) game ( name "Pocket Love (Japan) (SGB Enhanced)" description "Pocket Love (Japan) (SGB Enhanced)" - rom ( name "Pocket Love (Japan) (SGB Enhanced).gb" size 524288 crc D570A9DF md5 DED0B53FCFCB2FC647982727CC8FA072 sha1 69F08AA97B5B72E99C826C810FDAEBD766C2B416 flags verified ) + rom ( name "Pocket Love (Japan) (SGB Enhanced).gb" size 524288 crc d570a9df sha1 69F08AA97B5B72E99C826C810FDAEBD766C2B416 flags verified ) ) game ( name "Pocket Love 2 (Japan) (SGB Enhanced)" description "Pocket Love 2 (Japan) (SGB Enhanced)" - rom ( name "Pocket Love 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 9F8440B5 md5 712B4B22DC5674E33C68BF0001AF8B34 sha1 B35C25AE2A621748ABB68A7C2FC7A3C7927467E8 ) + rom ( name "Pocket Love 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 9f8440b5 sha1 B35C25AE2A621748ABB68A7C2FC7A3C7927467E8 flags verified ) ) game ( name "Pocket Mahjong (Japan)" description "Pocket Mahjong (Japan)" - rom ( name "Pocket Mahjong (Japan).gb" size 131072 crc 90F026D4 md5 9B7768644978E51E316841B57DA510F0 sha1 F559E999A9957D5804EAB7A250CDCFEF1708E7F7 ) + rom ( name "Pocket Mahjong (Japan).gb" size 131072 crc 90f026d4 sha1 F559E999A9957D5804EAB7A250CDCFEF1708E7F7 flags verified ) ) game ( name "Pocket Monsters - Aka (Japan) (SGB Enhanced)" description "Pocket Monsters - Aka (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters - Aka (Japan) (SGB Enhanced).gb" size 524288 crc 13652705 md5 912D4F77D118390A2E2C42B2016A19D4 sha1 0623AD12F48C259447980D68BD85DDBF8204B2CD ) + rom ( name "Pocket Monsters - Aka (Japan) (SGB Enhanced).gb" size 524288 crc 13652705 sha1 0623AD12F48C259447980D68BD85DDBF8204B2CD flags verified ) ) game ( - name "Pocket Monsters - Aka (Japan) (Rev A) (SGB Enhanced)" - description "Pocket Monsters - Aka (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Pocket Monsters - Aka (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc B77BE1E0 md5 4C44844F8D5AA3305A0CF2C95CF96333 sha1 EF74C79CDED14204AC79E77F4964D9CB25003120 flags verified ) + name "Pocket Monsters - Aka (Japan) (Rev 1) (SGB Enhanced)" + description "Pocket Monsters - Aka (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Pocket Monsters - Aka (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc b77be1e0 sha1 EF74C79CDED14204AC79E77F4964D9CB25003120 flags verified ) ) game ( name "Pocket Monsters - Ao (Japan) (SGB Enhanced)" description "Pocket Monsters - Ao (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters - Ao (Japan) (SGB Enhanced).gb" size 524288 crc E4468D14 md5 C1ADF0A77809AC91D905A4828888A2F0 sha1 0DA501E3E5C51AB8FEF55B092DCDD7E6B050E424 flags verified ) + rom ( name "Pocket Monsters - Ao (Japan) (SGB Enhanced).gb" size 524288 crc e4468d14 sha1 0DA501E3E5C51AB8FEF55B092DCDD7E6B050E424 flags verified ) ) game ( name "Pocket Monsters - Midori (Japan) (SGB Enhanced)" description "Pocket Monsters - Midori (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters - Midori (Japan) (SGB Enhanced).gb" size 524288 crc BAEACD2B md5 E30FFBAB1F239F09B226477D84DB1368 sha1 82C0EEF40A5E2423699D9FD8BA15DFAA8B51D196 flags verified ) + rom ( name "Pocket Monsters - Midori (Japan) (SGB Enhanced).gb" size 524288 crc baeacd2b sha1 82C0EEF40A5E2423699D9FD8BA15DFAA8B51D196 flags verified ) ) game ( - name "Pocket Monsters - Midori (Japan) (Rev A) (SGB Enhanced)" - description "Pocket Monsters - Midori (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Pocket Monsters - Midori (Japan) (Rev A) (SGB Enhanced).gb" size 524288 crc 37AE8DC4 md5 16DDD8897092936FBC0E286C6A6B23A2 sha1 4B97CD44AA3F0DD290BFE7B3AC17B7BD8270897B flags verified ) -) - -game ( - name "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced)" - description "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced)" - rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced).gb" size 1048576 crc FD3DA7FF md5 5D9C071CF6EB5F3A697BBCD9311B4D04 sha1 91864ECDF26D1C593BDE4D9ED615520EB57D5E41 flags verified ) -) - -game ( - name "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced)" - description "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced)" - rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced).gb" size 1048576 crc E9E6483A md5 90AE2EA218F8E21AFA678C6A4E7B6013 sha1 A40298A8123613EE60CD7AAB204D788B8425976E flags verified ) + name "Pocket Monsters - Midori (Japan) (Rev 1) (SGB Enhanced)" + description "Pocket Monsters - Midori (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Pocket Monsters - Midori (Japan) (Rev 1) (SGB Enhanced).gb" size 524288 crc 37ae8dc4 sha1 4B97CD44AA3F0DD290BFE7B3AC17B7BD8270897B flags verified ) ) game ( name "Pocket Monsters - Pikachu (Japan) (SGB Enhanced)" description "Pocket Monsters - Pikachu (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters - Pikachu (Japan) (SGB Enhanced).gb" size 1048576 crc 4EC85504 md5 AA13E886A47FD473DA63B7D5DDF2828D sha1 1FB6C264E950D97CE3FD99B347E485B2150DF4FF flags verified ) + rom ( name "Pocket Monsters - Pikachu (Japan) (SGB Enhanced).gb" size 1048576 crc 4ec85504 sha1 1FB6C264E950D97CE3FD99B347E485B2150DF4FF flags verified ) ) game ( name "Pocket Monsters - Pikachu (Japan) (Rev 1) (SGB Enhanced)" description "Pocket Monsters - Pikachu (Japan) (Rev 1) (SGB Enhanced)" - rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 1) (SGB Enhanced).gb" size 1048576 crc A2545D33 md5 96C1F411671B6E1761CF31884DDE0DBB sha1 28E4B8531EA4EA1DE5A396FCCB0CFBA51B06B149 flags verified ) + rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 1) (SGB Enhanced).gb" size 1048576 crc a2545d33 sha1 28E4B8531EA4EA1DE5A396FCCB0CFBA51B06B149 flags verified ) +) + +game ( + name "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced)" + description "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced)" + rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 2) (SGB Enhanced).gb" size 1048576 crc fd3da7ff sha1 91864ECDF26D1C593BDE4D9ED615520EB57D5E41 flags verified ) +) + +game ( + name "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced)" + description "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced)" + rom ( name "Pocket Monsters - Pikachu (Japan) (Rev 3) (SGB Enhanced).gb" size 1048576 crc e9e6483a sha1 A40298A8123613EE60CD7AAB204D788B8425976E flags verified ) +) + +game ( + name "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Non-Debug)" + description "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Non-Debug)" + rom ( name "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Non-Debug).gb" size 1048576 crc 7246170a sha1 F338DAFD76619BE268B4987BD2C94ADB15AA9386 ) +) + +game ( + name "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Debug)" + description "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Debug)" + rom ( name "Pocket Monsters Gin (Japan) (Demo) (Kiosk, Space World, Debug).gb" size 1048576 crc 2c5732db sha1 4C576DD4671BB1FE36C5E6D76C8909F98D739667 ) +) + +game ( + name "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Non-Debug) (SGB Enhanced)" + description "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Non-Debug) (SGB Enhanced)" + rom ( name "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Non-Debug) (SGB Enhanced).gb" size 1048576 crc abedd2bf sha1 6A5DF1B84698168B44CA53B0DF15128E4BFAAD6A ) +) + +game ( + name "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Debug) (SGB Enhanced)" + description "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Debug) (SGB Enhanced)" + rom ( name "Pocket Monsters Kin (Japan) (Demo) (Kiosk, Space World, Debug) (SGB Enhanced).gb" size 1048576 crc c2ca5626 sha1 B1D7539A87DEA81B2CFF6146AFAAD64470D08D84 ) ) game ( name "Pocket Puyo Puyo Tsuu (Japan) (SGB Enhanced)" description "Pocket Puyo Puyo Tsuu (Japan) (SGB Enhanced)" - rom ( name "Pocket Puyo Puyo Tsuu (Japan) (SGB Enhanced).gb" size 262144 crc 43E47A81 md5 296CB17655E184BB65C1CD2A3BC68D8A sha1 2FFBFF6706047988468A7952DE09C2720C3019ED ) + rom ( name "Pocket Puyo Puyo Tsuu (Japan) (SGB Enhanced).gb" size 262144 crc 43e47a81 sha1 2FFBFF6706047988468A7952DE09C2720C3019ED flags verified ) +) + +game ( + name "Pocket Puyo Puyo Tsuu (Japan) (Rev 1) (SGB Enhanced) (NP)" + description "Pocket Puyo Puyo Tsuu (Japan) (Rev 1) (SGB Enhanced) (NP)" + rom ( name "Pocket Puyo Puyo Tsuu (Japan) (Rev 1) (SGB Enhanced) (NP).gb" size 262144 crc cae8a317 sha1 36B677B76AF12287CDBDEC9AE06CA3F9DBFC1E67 flags verified ) ) game ( name "Pocket Shougi (Japan) (SGB Enhanced)" description "Pocket Shougi (Japan) (SGB Enhanced)" - rom ( name "Pocket Shougi (Japan) (SGB Enhanced).gb" size 262144 crc 2FA1BDE6 md5 F3C6246DB6DD47701435E0EDE493B975 sha1 5BC0AEA0BEB7C80F3D2BC650499A6C0E30006544 ) + rom ( name "Pocket Shougi (Japan) (SGB Enhanced).gb" size 262144 crc 2fa1bde6 sha1 5BC0AEA0BEB7C80F3D2BC650499A6C0E30006544 ) ) game ( name "Pocket Sonar (Japan)" description "Pocket Sonar (Japan)" - rom ( name "Pocket Sonar (Japan).gb" size 524288 crc D68C9F79 md5 E7E0943CB9B8D6DD29C18E6A41E8D346 sha1 788CDF148431B82B5308C68B3E45B133A7074196 ) + rom ( name "Pocket Sonar (Japan).gb" size 524288 crc d68c9f79 sha1 788CDF148431B82B5308C68B3E45B133A7074196 ) ) game ( name "Pocket Stadium (Japan)" description "Pocket Stadium (Japan)" - rom ( name "Pocket Stadium (Japan).gb" size 65536 crc C7BD9228 md5 A7B0E283170B28C4C77016A95210B714 sha1 7BA422F2B48FF09673F7F1A258BE6ECC1FF6A8D7 ) + rom ( name "Pocket Stadium (Japan).gb" size 65536 crc c7bd9228 sha1 7BA422F2B48FF09673F7F1A258BE6ECC1FF6A8D7 flags verified ) ) game ( name "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" description "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" - rom ( name "Pokemon - Blaue Edition (Germany) (SGB Enhanced).gb" size 1048576 crc 9C336307 md5 A1EC7F07C7B4251D5FAFC50622D546F8 sha1 20E72DC6F41493EEE1FDD0CEF54214E6C3389688 flags verified ) + rom ( name "Pokemon - Blaue Edition (Germany) (SGB Enhanced).gb" size 1048576 crc 9c336307 sha1 20E72DC6F41493EEE1FDD0CEF54214E6C3389688 flags verified ) ) game ( name "Pokemon - Blue Version (USA, Europe) (SGB Enhanced)" description "Pokemon - Blue Version (USA, Europe) (SGB Enhanced)" - rom ( name "Pokemon - Blue Version (USA, Europe) (SGB Enhanced).gb" size 1048576 crc D6DA8A1A md5 50927E843568814F7ED45EC4F944BD8B sha1 D7037C83E1AE5B39BDE3C30787637BA1D4C48CE2 flags verified ) + rom ( name "Pokemon - Blue Version (USA, Europe) (SGB Enhanced).gb" size 1048576 crc d6da8a1a sha1 D7037C83E1AE5B39BDE3C30787637BA1D4C48CE2 flags verified ) ) game ( name "Pokemon - Edicion Amarilla - Edicion Especial Pikachu (Spain) (GBC,SGB Enhanced)" description "Pokemon - Edicion Amarilla - Edicion Especial Pikachu (Spain) (GBC,SGB Enhanced)" - serial "APSS" - rom ( name "Pokemon - Edicion Amarilla - Edicion Especial Pikachu (Spain) (GBC,SGB Enhanced).gb" size 1048576 crc 964B7A10 md5 F0DA8B1CFF3AAB898ECDE9DCBDA6D817 sha1 1DC242039218FBA50928D1AFB66B70565B6B9DAF flags verified ) + rom ( name "Pokemon - Edicion Amarilla - Edicion Especial Pikachu (Spain) (GBC,SGB Enhanced).gb" size 1048576 crc 964b7a10 sha1 1DC242039218FBA50928D1AFB66B70565B6B9DAF flags verified ) ) game ( name "Pokemon - Edicion Azul (Spain) (SGB Enhanced)" description "Pokemon - Edicion Azul (Spain) (SGB Enhanced)" - rom ( name "Pokemon - Edicion Azul (Spain) (SGB Enhanced).gb" size 1048576 crc D95416F9 md5 6E7663F908334724548A66FC9C386002 sha1 7715E7B133E8634DF48918B9138374110212A108 flags verified ) + rom ( name "Pokemon - Edicion Azul (Spain) (SGB Enhanced).gb" size 1048576 crc d95416f9 sha1 7715E7B133E8634DF48918B9138374110212A108 flags verified ) ) game ( name "Pokemon - Edicion Roja (Spain) (SGB Enhanced)" description "Pokemon - Edicion Roja (Spain) (SGB Enhanced)" - rom ( name "Pokemon - Edicion Roja (Spain) (SGB Enhanced).gb" size 1048576 crc D8507D8A md5 463C241C8721AB1D1DA17C91DE9F8A32 sha1 FC17C5B904D551B1B908054CCD1C493F755F832A flags verified ) + rom ( name "Pokemon - Edicion Roja (Spain) (SGB Enhanced).gb" size 1048576 crc d8507d8a sha1 FC17C5B904D551B1B908054CCD1C493F755F832A flags verified ) ) game ( name "Pokemon - Gelbe Edition - Special Pikachu Edition (Germany) (GBC,SGB Enhanced)" description "Pokemon - Gelbe Edition - Special Pikachu Edition (Germany) (GBC,SGB Enhanced)" - serial "APSD" - rom ( name "Pokemon - Gelbe Edition - Special Pikachu Edition (Germany) (GBC,SGB Enhanced).gb" size 1048576 crc 7A01E45A md5 E93F10168E3C9B9D18E3AD4A1415E1D0 sha1 42F3714EEC6ECA25200D42461FF08D57C98F6D1D flags verified ) + rom ( name "Pokemon - Gelbe Edition - Special Pikachu Edition (Germany) (GBC,SGB Enhanced).gb" size 1048576 crc 7a01e45a sha1 42F3714EEC6ECA25200D42461FF08D57C98F6D1D flags verified ) ) game ( name "Pokemon - Red Version (USA, Europe) (SGB Enhanced)" description "Pokemon - Red Version (USA, Europe) (SGB Enhanced)" - rom ( name "Pokemon - Red Version (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 9F7FDD53 md5 3D45C1EE9ABD5738DF46D2BDDA8B57DC sha1 EA9BCAE617FDF159B045185467AE58B2E4A48B9A flags verified ) + rom ( name "Pokemon - Red Version (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 9f7fdd53 sha1 EA9BCAE617FDF159B045185467AE58B2E4A48B9A flags verified ) ) game ( name "Pokemon - Rote Edition (Germany) (SGB Enhanced)" description "Pokemon - Rote Edition (Germany) (SGB Enhanced)" - rom ( name "Pokemon - Rote Edition (Germany) (SGB Enhanced).gb" size 1048576 crc 89197825 md5 8ED0E8D45A81CA34DE625D930148A512 sha1 87D523FE1A0C548DB7C5477B451DDEC1EB083C06 flags verified ) + rom ( name "Pokemon - Rote Edition (Germany) (SGB Enhanced).gb" size 1048576 crc 89197825 sha1 87D523FE1A0C548DB7C5477B451DDEC1EB083C06 flags verified ) ) game ( name "Pokemon - Version Bleue (France) (SGB Enhanced)" description "Pokemon - Version Bleue (France) (SGB Enhanced)" - rom ( name "Pokemon - Version Bleue (France) (SGB Enhanced).gb" size 1048576 crc 50E2FC1D md5 35C8154C81ABB2AB850689FD28A03515 sha1 47FAA910D0E073C600665BF9C83B6BD17BABDF8A ) + rom ( name "Pokemon - Version Bleue (France) (SGB Enhanced).gb" size 1048576 crc 50e2fc1d sha1 47FAA910D0E073C600665BF9C83B6BD17BABDF8A ) ) game ( name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (GBC,SGB Enhanced)" description "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (GBC,SGB Enhanced)" - serial "APSF" - rom ( name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (GBC,SGB Enhanced).gb" size 1048576 crc D03426E9 md5 2DF6B439A35E0D511D52FA75C6A7849A sha1 0ACEEC0EF7AA2CA5AA831554598D91F61A925591 flags verified ) + rom ( name "Pokemon - Version Jaune - Edition Speciale Pikachu (France) (GBC,SGB Enhanced).gb" size 1048576 crc d03426e9 sha1 0ACEEC0EF7AA2CA5AA831554598D91F61A925591 flags verified ) ) game ( name "Pokemon - Version Rouge (France) (SGB Enhanced)" description "Pokemon - Version Rouge (France) (SGB Enhanced)" - rom ( name "Pokemon - Version Rouge (France) (SGB Enhanced).gb" size 1048576 crc 337FCE11 md5 669700657CB06ED09371CDBDEF69E8A3 sha1 47A7622FA30E6402A3891FE65B3A930BF9BD7AEC ) + rom ( name "Pokemon - Version Rouge (France) (SGB Enhanced).gb" size 1048576 crc 337fce11 sha1 47A7622FA30E6402A3891FE65B3A930BF9BD7AEC ) ) game ( name "Pokemon - Versione Blu (Italy) (SGB Enhanced)" description "Pokemon - Versione Blu (Italy) (SGB Enhanced)" - rom ( name "Pokemon - Versione Blu (Italy) (SGB Enhanced).gb" size 1048576 crc 4D0984A9 md5 EBE0742B472B3E80A9C6749F06181073 sha1 F69ED1A1332F04C24C7DB899A09019BB045FA8B3 flags verified ) + rom ( name "Pokemon - Versione Blu (Italy) (SGB Enhanced).gb" size 1048576 crc 4d0984a9 sha1 F69ED1A1332F04C24C7DB899A09019BB045FA8B3 flags verified ) ) game ( name "Pokemon - Versione Gialla - Speciale Edizione Pikachu (Italy) (GBC,SGB Enhanced)" description "Pokemon - Versione Gialla - Speciale Edizione Pikachu (Italy) (GBC,SGB Enhanced)" - serial "APSI" - rom ( name "Pokemon - Versione Gialla - Speciale Edizione Pikachu (Italy) (GBC,SGB Enhanced).gb" size 1048576 crc 8B56FE33 md5 3343CECA5DD6586E4774609526167D55 sha1 05BB8E99F24D498613930949730AFA8024E77D08 flags verified ) + rom ( name "Pokemon - Versione Gialla - Speciale Edizione Pikachu (Italy) (GBC,SGB Enhanced).gb" size 1048576 crc 8b56fe33 sha1 05BB8E99F24D498613930949730AFA8024E77D08 flags verified ) ) game ( name "Pokemon - Versione Rossa (Italy) (SGB Enhanced)" description "Pokemon - Versione Rossa (Italy) (SGB Enhanced)" - rom ( name "Pokemon - Versione Rossa (Italy) (SGB Enhanced).gb" size 1048576 crc 2945ACEB md5 6468FB0652DDE30EB968A44F17C686F1 sha1 65B97CF8F2F1CFF711A6D08C6C894C8CE65CE522 flags verified ) + rom ( name "Pokemon - Versione Rossa (Italy) (SGB Enhanced).gb" size 1048576 crc 2945aceb sha1 65B97CF8F2F1CFF711A6D08C6C894C8CE65CE522 flags verified ) ) game ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (GBC,SGB Enhanced)" description "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (GBC,SGB Enhanced)" - serial "APSU" - rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (GBC,SGB Enhanced).gb" size 1048576 crc 7D527D62 md5 D9290DB87B1F0A23B89F99EE4469E34B sha1 CC7D03262EBFAF2F06772C1A480C7D9D5F4A38E1 flags verified ) + rom ( name "Pokemon - Yellow Version - Special Pikachu Edition (USA, Europe) (GBC,SGB Enhanced).gb" size 1048576 crc 7d527d62 sha1 CC7D03262EBFAF2F06772C1A480C7D9D5F4A38E1 flags verified ) ) game ( name "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced)" description "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced)" - rom ( name "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced).gb" size 262144 crc 61C34232 md5 16D86EC93F9AAD85EDCEC7E6DB18B435 sha1 C5706E26F1CC591CD1FE762ACE097DF868703480 ) + rom ( name "Pokonyan! - Yume no Daibouken (Japan) (SGB Enhanced).gb" size 262144 crc 61c34232 sha1 C5706E26F1CC591CD1FE762ACE097DF868703480 ) ) game ( name "Ponta to Hinako no Chindouchuu - Yuujou Hen (Japan)" description "Ponta to Hinako no Chindouchuu - Yuujou Hen (Japan)" - rom ( name "Ponta to Hinako no Chindouchuu - Yuujou Hen (Japan).gb" size 65536 crc 058B3DAB md5 2A76AB00F041EC61EA08899021A4C07E sha1 83110CE7B82117069C9F147219FC2EFBD1CDD103 ) + rom ( name "Ponta to Hinako no Chindouchuu - Yuujou Hen (Japan).gb" size 65536 crc 058b3dab sha1 83110CE7B82117069C9F147219FC2EFBD1CDD103 ) ) game ( name "Pop Up (Europe)" description "Pop Up (Europe)" - rom ( name "Pop Up (Europe).gb" size 32768 crc 7F545B40 md5 B85A4BDEA69168870D5BE639B8A1AA4B sha1 80094C524C8C9DD01D1402692837B4BC9701350F flags verified ) + rom ( name "Pop Up (Europe).gb" size 32768 crc 7f545b40 sha1 80094C524C8C9DD01D1402692837B4BC9701350F flags verified ) ) game ( name "Pop'n TwinBee (Europe)" description "Pop'n TwinBee (Europe)" - rom ( name "Pop'n TwinBee (Europe).gb" size 131072 crc D07DB274 md5 05D5CF3404868EFC22AC06E22AB5BA89 sha1 0206230B55C15A8C18FBB85F852967E44B33A0A4 flags verified ) + rom ( name "Pop'n TwinBee (Europe).gb" size 131072 crc d07db274 sha1 0206230B55C15A8C18FBB85F852967E44B33A0A4 flags verified ) ) game ( name "Popeye (Japan)" description "Popeye (Japan)" - rom ( name "Popeye (Japan).gb" size 131072 crc 2FB4DA21 md5 55A2CA284B3B42F6C55D59F9E11C196C sha1 D7C4CFA460E65368477F9394164B67E03310FC69 ) + rom ( name "Popeye (Japan).gb" size 131072 crc 2fb4da21 sha1 D7C4CFA460E65368477F9394164B67E03310FC69 flags verified ) ) game ( name "Popeye 2 (Europe)" description "Popeye 2 (Europe)" - rom ( name "Popeye 2 (Europe).gb" size 131072 crc C07ED722 md5 0CC70045DA0C0CAE54892684AF4C0202 sha1 D3078FCEADF469AB976422707A24B396530AAE05 ) + rom ( name "Popeye 2 (Europe).gb" size 131072 crc c07ed722 sha1 D3078FCEADF469AB976422707A24B396530AAE05 ) ) game ( name "Popeye 2 (Japan)" description "Popeye 2 (Japan)" - rom ( name "Popeye 2 (Japan).gb" size 131072 crc 4372ED68 md5 5CBD186AF88B167C2A972DDAC81AE756 sha1 D59986195BD74DDE865245FAE9C4081A8A24EFB0 ) + rom ( name "Popeye 2 (Japan).gb" size 131072 crc 4372ed68 sha1 D59986195BD74DDE865245FAE9C4081A8A24EFB0 ) ) game ( name "Popeye 2 (USA)" description "Popeye 2 (USA)" - rom ( name "Popeye 2 (USA).gb" size 131072 crc 729C2E40 md5 30B579D82AE755BD37C1D4157A96129C sha1 DD673EE4DD847A3A217F5F5B6E76FF4D418F2D41 ) + rom ( name "Popeye 2 (USA).gb" size 131072 crc 729c2e40 sha1 DD673EE4DD847A3A217F5F5B6E76FF4D418F2D41 ) +) + +game ( + name "Popeye 2 (Japan) (Rev 1)" + description "Popeye 2 (Japan) (Rev 1)" + rom ( name "Popeye 2 (Japan) (Rev 1).gb" size 131072 crc 8cd93719 sha1 7C4AC88E7A9F034DA08EE84F299D9093E40213FD flags verified ) ) game ( name "Populous (Europe)" description "Populous (Europe)" - rom ( name "Populous (Europe).gb" size 131072 crc 453057AC md5 AB5FAC354726B7B0710CFDBA22D7142F sha1 4E3976FE32F4DB8F2E56EAE539D7CAE04D1B64CB flags verified ) + rom ( name "Populous (Europe).gb" size 131072 crc 453057ac sha1 4E3976FE32F4DB8F2E56EAE539D7CAE04D1B64CB flags verified ) ) game ( - name "Populous (Japan)" - description "Populous (Japan)" - rom ( name "Populous (Japan).gb" size 131072 crc F327167E md5 A98F3B3B87D4B8AE3672F518295A8FDE sha1 FDE1789EB253309CAE80FAF4FE7241C6F9D72F29 ) + name "Populous Gaiden (Japan)" + description "Populous Gaiden (Japan)" + rom ( name "Populous Gaiden (Japan).gb" size 131072 crc f327167e sha1 FDE1789EB253309CAE80FAF4FE7241C6F9D72F29 ) ) game ( name "Power Mission (Japan)" description "Power Mission (Japan)" - rom ( name "Power Mission (Japan).gb" size 131072 crc 0E2A1414 md5 CFEE195BFD47E8E061ED67B9545242A4 sha1 EF28356E7A3B82F64E62CB9A7B4C121AA626FF7C ) + rom ( name "Power Mission (Japan).gb" size 131072 crc 0e2a1414 sha1 EF28356E7A3B82F64E62CB9A7B4C121AA626FF7C ) ) game ( - name "Power Mission (Japan) (Rev A)" - description "Power Mission (Japan) (Rev A)" - rom ( name "Power Mission (Japan) (Rev A).gb" size 131072 crc E30EF8AB md5 5D516B5DE2BF54FB6C687F1838B628CC sha1 89B2306AD9C9E296884354EC3BE039B944D52D13 ) + name "Power Mission (Japan) (Rev 1)" + description "Power Mission (Japan) (Rev 1)" + rom ( name "Power Mission (Japan) (Rev 1).gb" size 131072 crc e30ef8ab sha1 89B2306AD9C9E296884354EC3BE039B944D52D13 ) ) game ( name "Power Mission (USA)" description "Power Mission (USA)" - rom ( name "Power Mission (USA).gb" size 131072 crc 46CB2F33 md5 3C8DFC25FD8D2691CFE1CB2C375E097C sha1 7EB044E49C370C8E85619CFE42A5B4FB41CBCF17 flags verified ) + rom ( name "Power Mission (USA).gb" size 131072 crc 46cb2f33 sha1 7EB044E49C370C8E85619CFE42A5B4FB41CBCF17 flags verified ) ) game ( name "Power Pro GB (Japan) (SGB Enhanced)" description "Power Pro GB (Japan) (SGB Enhanced)" - rom ( name "Power Pro GB (Japan) (SGB Enhanced).gb" size 262144 crc 2E123F5B md5 F213C0040E067CFAE27C3FE90143B7C3 sha1 135D04CBAAB6AFD03997BCEB6B1A2A8AA1DBC7E8 ) + rom ( name "Power Pro GB (Japan) (SGB Enhanced).gb" size 262144 crc 2e123f5b sha1 135D04CBAAB6AFD03997BCEB6B1A2A8AA1DBC7E8 ) ) game ( - name "Power Pro GB (Japan) (Rev A) (SGB Enhanced)" - description "Power Pro GB (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Power Pro GB (Japan) (Rev A) (SGB Enhanced).gb" size 262144 crc 71BEA855 md5 7BD22F707C9264FA6C94C0248576167D sha1 EBCA3BCE624D19A0FA3A92D30A5C543C12541EA4 flags verified ) + name "Power Pro GB (Japan) (Rev 1) (SGB Enhanced)" + description "Power Pro GB (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Power Pro GB (Japan) (Rev 1) (SGB Enhanced).gb" size 262144 crc 71bea855 sha1 EBCA3BCE624D19A0FA3A92D30A5C543C12541EA4 flags verified ) ) game ( name "Power Racer (Europe)" description "Power Racer (Europe)" - rom ( name "Power Racer (Europe).gb" size 65536 crc CF8AEEE8 md5 8E76D1CE4B251E3A31056FEDDDA92E9B sha1 6E10F59BB4090C0D0E79B57A2E39D9577CE0282E flags verified ) + rom ( name "Power Racer (Europe).gb" size 65536 crc cf8aeee8 sha1 6E10F59BB4090C0D0E79B57A2E39D9577CE0282E flags verified ) ) game ( name "Power Racer (USA)" description "Power Racer (USA)" - rom ( name "Power Racer (USA).gb" size 65536 crc AFC6A949 md5 6073CB28E651B48F0BF19E654AAB8C7D sha1 C0C8F28A9B66B6C08A0ED4D31A186C3382160C3D ) + rom ( name "Power Racer (USA).gb" size 65536 crc afc6a949 sha1 C0C8F28A9B66B6C08A0ED4D31A186C3382160C3D flags verified ) ) game ( name "Prehistorik Man (USA, Europe)" description "Prehistorik Man (USA, Europe)" - rom ( name "Prehistorik Man (USA, Europe).gb" size 131072 crc C5204156 md5 64F43161EB16EB1BE99262C36867BC79 sha1 1139D6B799B8585BBB7868BD3BCA5BA9DEA4EEF5 flags verified ) + rom ( name "Prehistorik Man (USA, Europe).gb" size 131072 crc c5204156 sha1 1139D6B799B8585BBB7868BD3BCA5BA9DEA4EEF5 flags verified ) ) game ( name "Pri Pri - Primitive Princess! (Japan)" description "Pri Pri - Primitive Princess! (Japan)" - rom ( name "Pri Pri - Primitive Princess! (Japan).gb" size 65536 crc 55DA3515 md5 24186CB8EF3210C00B9C227C71B9DB73 sha1 FEA367A2FC321DAEAE59746EE2CB7FFAFD51479A flags verified ) + rom ( name "Pri Pri - Primitive Princess! (Japan).gb" size 65536 crc 55da3515 sha1 FEA367A2FC321DAEAE59746EE2CB7FFAFD51479A flags verified ) ) game ( name "Primal Rage (USA, Europe)" description "Primal Rage (USA, Europe)" - rom ( name "Primal Rage (USA, Europe).gb" size 262144 crc C95D927B md5 C1CFF8487B25700A509CE89CC3C7BCAC sha1 8561D62CD7DF59082D6B3C048CA3B85A30D769B7 flags verified ) + rom ( name "Primal Rage (USA, Europe).gb" size 262144 crc c95d927b sha1 8561D62CD7DF59082D6B3C048CA3B85A30D769B7 flags verified ) ) game ( name "Prince of Persia (Europe) (En,Fr,De,Es,It)" description "Prince of Persia (Europe) (En,Fr,De,Es,It)" - rom ( name "Prince of Persia (Europe) (En,Fr,De,Es,It).gb" size 131072 crc B2CBF20F md5 710EE7DA860FB18A29A929DB1198C1BB sha1 FD4DA10C0A7AF510B026007FB66A22672634E2D4 ) + rom ( name "Prince of Persia (Europe) (En,Fr,De,Es,It).gb" size 131072 crc b2cbf20f sha1 FD4DA10C0A7AF510B026007FB66A22672634E2D4 flags verified ) ) game ( name "Prince of Persia (Japan)" description "Prince of Persia (Japan)" - rom ( name "Prince of Persia (Japan).gb" size 131072 crc 1D16D689 md5 7A1ED5C273362A56EAEC07A1DDD6B195 sha1 9D6DEAAFED4328E485D7A9368E0BB4859760EDF7 ) + rom ( name "Prince of Persia (Japan).gb" size 131072 crc 1d16d689 sha1 9D6DEAAFED4328E485D7A9368E0BB4859760EDF7 ) ) game ( name "Prince of Persia (USA)" description "Prince of Persia (USA)" - rom ( name "Prince of Persia (USA).gb" size 131072 crc 2BD995F1 md5 80034DA43F35307291714AE2553D9DDF sha1 EF3EF15B791CEFF34D7D9BB5B3AF2E05842C8323 ) + rom ( name "Prince of Persia (USA).gb" size 131072 crc 2bd995f1 sha1 EF3EF15B791CEFF34D7D9BB5B3AF2E05842C8323 ) ) game ( name "Pro Action Replay (Europe) (Unl)" description "Pro Action Replay (Europe) (Unl)" - rom ( name "Pro Action Replay (Europe) (Unl).gb" size 32768 crc A2A6A863 md5 B7477B7050CC569B4C02A5AE60E5F24E sha1 CC691EEEF80423BB55B442CC1D9E5ABD8BB80148 ) + rom ( name "Pro Action Replay (Europe) (Unl).gb" size 32768 crc a2a6a863 sha1 CC691EEEF80423BB55B442CC1D9E5ABD8BB80148 ) ) game ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced)" description "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced)" - rom ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced).gb" size 131072 crc 6F5B6748 md5 052BD7A432452C0E811D1EA8BB6D9B21 sha1 DC6B304AC4E9B679272F843411BA964B438A69B6 flags verified ) + rom ( name "Pro Mahjong Kiwame GB (Japan) (SGB Enhanced).gb" size 131072 crc 6f5b6748 sha1 DC6B304AC4E9B679272F843411BA964B438A69B6 flags verified ) ) game ( name "Pro Soccer (Japan)" description "Pro Soccer (Japan)" - rom ( name "Pro Soccer (Japan).gb" size 131072 crc A6F3BEE2 md5 741890CBDEEFE98175A56A87B9E9EF8E sha1 CCF50AE867633F608BA38302C8561654223DC14B ) + rom ( name "Pro Soccer (Japan).gb" size 131072 crc a6f3bee2 sha1 CCF50AE867633F608BA38302C8561654223DC14B ) ) game ( name "Pro Wrestling (Japan)" description "Pro Wrestling (Japan)" - rom ( name "Pro Wrestling (Japan).gb" size 131072 crc F27C06DA md5 93660017F0AF0589E3CE0869EBBE9BDC sha1 C368831C5468C3F03F3F38E4C2FA2BAB9478FC4E flags verified ) + rom ( name "Pro Wrestling (Japan).gb" size 131072 crc f27c06da sha1 C368831C5468C3F03F3F38E4C2FA2BAB9478FC4E flags verified ) ) game ( name "Probotector (Europe)" description "Probotector (Europe)" - rom ( name "Probotector (Europe).gb" size 131072 crc C9ACC4F4 md5 298C80FE568BB2FF8BB7E4DFE5862A9D sha1 45482A44CE0CDFA33FC58A8A8AFE2D7284DFA498 flags verified ) + rom ( name "Probotector (Europe).gb" size 131072 crc c9acc4f4 sha1 45482A44CE0CDFA33FC58A8A8AFE2D7284DFA498 flags verified ) ) game ( name "Probotector 2 (Europe) (SGB Enhanced)" description "Probotector 2 (Europe) (SGB Enhanced)" - rom ( name "Probotector 2 (Europe) (SGB Enhanced).gb" size 131072 crc B5090E43 md5 E1EA97584E0CF0D0F4187E1C6322DA93 sha1 D3EAFED6727AFD14BD30FFC31E2D3E4EE6CFC52E flags verified ) + rom ( name "Probotector 2 (Europe) (SGB Enhanced).gb" size 131072 crc b5090e43 sha1 D3EAFED6727AFD14BD30FFC31E2D3E4EE6CFC52E flags verified ) ) game ( name "Probotector 2 (Europe) (Beta)" description "Probotector 2 (Europe) (Beta)" - rom ( name "Probotector 2 (Europe) (Beta).gb" size 131072 crc 7D60C005 md5 6E47B388DFFAE893FF1FC33CA552CF9A sha1 8F060253EA228C43D2992458DBF904A0B0D7B01E ) + rom ( name "Probotector 2 (Europe) (Beta).gb" size 131072 crc 7d60c005 sha1 8F060253EA228C43D2992458DBF904A0B0D7B01E flags verified ) ) game ( name "Prophecy - The Viking Child (Europe) (En,Fr,De,Es,It)" description "Prophecy - The Viking Child (Europe) (En,Fr,De,Es,It)" - rom ( name "Prophecy - The Viking Child (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 590F5FB1 md5 D7569C3FAAA4A657385C119E6B4A48C6 sha1 DDED3DB8437BA2342599E9DBDE3AA20CE83E15CA ) + rom ( name "Prophecy - The Viking Child (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 590f5fb1 sha1 DDED3DB8437BA2342599E9DBDE3AA20CE83E15CA flags verified ) ) game ( name "Prophecy - The Viking Child (USA)" description "Prophecy - The Viking Child (USA)" - rom ( name "Prophecy - The Viking Child (USA).gb" size 262144 crc 80F62F9A md5 AFA16D0822254CF68DF1E29556E6CBCC sha1 A6FCA2FD143C605DD166E7462729599AD0143457 ) + rom ( name "Prophecy - The Viking Child (USA).gb" size 262144 crc 80f62f9a sha1 A6FCA2FD143C605DD166E7462729599AD0143457 flags verified ) ) game ( name "Punisher, The - The Ultimate Payback (USA)" description "Punisher, The - The Ultimate Payback (USA)" - rom ( name "Punisher, The - The Ultimate Payback (USA).gb" size 131072 crc 5916713E md5 84133AF3324FC1AAF00C0769E15708C0 sha1 C7B01CE2F83E00F6F3E0CA65DDEDFB2435119BA2 flags verified ) + rom ( name "Punisher, The - The Ultimate Payback (USA).gb" size 131072 crc 5916713e sha1 C7B01CE2F83E00F6F3E0CA65DDEDFB2435119BA2 flags verified ) ) game ( name "Purikura Pocket - Fukanzen Joshikousei Manual (Japan) (SGB Enhanced)" description "Purikura Pocket - Fukanzen Joshikousei Manual (Japan) (SGB Enhanced)" - rom ( name "Purikura Pocket - Fukanzen Joshikousei Manual (Japan) (SGB Enhanced).gb" size 524288 crc ACC589FC md5 2CF73AE0EF2B62E9D20B5432B2F6C5DE sha1 2F2D519E0C9ACAD3CF96546AEBB04B8FF309AB1F ) + rom ( name "Purikura Pocket - Fukanzen Joshikousei Manual (Japan) (SGB Enhanced).gb" size 524288 crc acc589fc sha1 2F2D519E0C9ACAD3CF96546AEBB04B8FF309AB1F ) ) game ( name "Purikura Pocket 2 - Kareshi Kaizou Daisakusen (Japan) (SGB Enhanced)" description "Purikura Pocket 2 - Kareshi Kaizou Daisakusen (Japan) (SGB Enhanced)" - rom ( name "Purikura Pocket 2 - Kareshi Kaizou Daisakusen (Japan) (SGB Enhanced).gb" size 524288 crc D145EA23 md5 B5E99DCB3296AFB933796E552CAC1E31 sha1 6B7AB5728973865F970CD676A4837E7F4C4128BB ) + rom ( name "Purikura Pocket 2 - Kareshi Kaizou Daisakusen (Japan) (SGB Enhanced).gb" size 524288 crc d145ea23 sha1 6B7AB5728973865F970CD676A4837E7F4C4128BB ) ) game ( name "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (SGB Enhanced)" description "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (SGB Enhanced)" - rom ( name "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (SGB Enhanced).gb" size 1048576 crc CEB62411 md5 D112981290430C09B82D7FD7EDFCE0BB sha1 B8DF59D63A2F836EF497F503B67A3401EAE497A7 ) + rom ( name "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (SGB Enhanced).gb" size 1048576 crc ceb62411 sha1 B8DF59D63A2F836EF497F503B67A3401EAE497A7 flags verified ) ) game ( name "Puyo Puyo (Japan) (SGB Enhanced)" description "Puyo Puyo (Japan) (SGB Enhanced)" - rom ( name "Puyo Puyo (Japan) (SGB Enhanced).gb" size 262144 crc 9E372D13 md5 1A181F068D715C4CA350FB168FB9DD8A sha1 65C80185C8948E1963509E13C40FB670AD6B64C5 flags verified ) + rom ( name "Puyo Puyo (Japan) (SGB Enhanced).gb" size 262144 crc 9e372d13 sha1 65C80185C8948E1963509E13C40FB670AD6B64C5 flags verified ) ) game ( - name "Puyo Puyo (Japan) (Rev A) (SGB Enhanced)" - description "Puyo Puyo (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Puyo Puyo (Japan) (Rev A) (SGB Enhanced).gb" size 262144 crc 20E48285 md5 300EA2593B2C29C3950FED23D672E11E sha1 EF05AB17131030554E0D820DD0E602AF82E1FE54 flags verified ) + name "Puyo Puyo (Japan) (Rev 1) (SGB Enhanced)" + description "Puyo Puyo (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Puyo Puyo (Japan) (Rev 1) (SGB Enhanced).gb" size 262144 crc 20e48285 sha1 EF05AB17131030554E0D820DD0E602AF82E1FE54 flags verified ) ) game ( name "Puzzle Bobble GB (Japan)" description "Puzzle Bobble GB (Japan)" - rom ( name "Puzzle Bobble GB (Japan).gb" size 131072 crc 10235E38 md5 37C69C73C81E221189A672938B5F30AB sha1 203A39B937E1900FA272F93830D3C6F825E67821 flags verified ) + rom ( name "Puzzle Bobble GB (Japan).gb" size 131072 crc 10235e38 sha1 203A39B937E1900FA272F93830D3C6F825E67821 flags verified ) ) game ( name "Puzzle Boy (Japan)" description "Puzzle Boy (Japan)" - rom ( name "Puzzle Boy (Japan).gb" size 32768 crc 2AE2D71C md5 AEE13A4AA95C9B3A4B4CF607A3E17A91 sha1 67CBF1EFB8DB55091D87EAEE9942BC0D9D5291D4 flags verified ) + rom ( name "Puzzle Boy (Japan).gb" size 32768 crc 2ae2d71c sha1 67CBF1EFB8DB55091D87EAEE9942BC0D9D5291D4 flags verified ) ) game ( name "Puzzle Boy II (Japan)" description "Puzzle Boy II (Japan)" - rom ( name "Puzzle Boy II (Japan).gb" size 65536 crc E5463A1D md5 1CDEA2BEB1F8F1F4A3FB0C939112267E sha1 15E325BE6272281D74448936FEE5179448AE480E flags verified ) + rom ( name "Puzzle Boy II (Japan).gb" size 65536 crc e5463a1d sha1 15E325BE6272281D74448936FEE5179448AE480E flags verified ) ) game ( - name "Puzzle Nintama Rantarou (Japan) (SGB Enhanced)" - description "Puzzle Nintama Rantarou (Japan) (SGB Enhanced)" - rom ( name "Puzzle Nintama Rantarou (Japan) (SGB Enhanced).gb" size 262144 crc 952920BA md5 073E6A0F2FDAE655760AAF6DB81DA3B2 sha1 5239823F04DA93FC6B8FCAC48F0D0425F90972BC ) + name "Puzzle Nintama Rantarou GB (Japan) (SGB Enhanced)" + description "Puzzle Nintama Rantarou GB (Japan) (SGB Enhanced)" + rom ( name "Puzzle Nintama Rantarou GB (Japan) (SGB Enhanced).gb" size 262144 crc 952920ba sha1 5239823F04DA93FC6B8FCAC48F0D0425F90972BC flags verified ) ) game ( name "Puzznic (Japan)" description "Puzznic (Japan)" - rom ( name "Puzznic (Japan).gb" size 65536 crc 916E638D md5 9A777D82CD7A8913BA1AED2CC854FA50 sha1 74B26B502C5C728BC7B99F387F1AAF817D22B55A ) + rom ( name "Puzznic (Japan).gb" size 65536 crc 916e638d sha1 74B26B502C5C728BC7B99F387F1AAF817D22B55A flags verified ) ) game ( name "Pyramids of Ra (USA)" description "Pyramids of Ra (USA)" - rom ( name "Pyramids of Ra (USA).gb" size 65536 crc ABEF175B md5 1C1619F1CAEF49132E87160AA20A0A4D sha1 8B75BC3127862C8B38B7992D2560966982BBE2E0 ) + rom ( name "Pyramids of Ra (USA).gb" size 65536 crc abef175b sha1 8B75BC3127862C8B38B7992D2560966982BBE2E0 ) ) game ( name "Q Billion (Japan)" description "Q Billion (Japan)" - rom ( name "Q Billion (Japan).gb" size 32768 crc 979ED154 md5 D310864869DCA081FD30002548830051 sha1 6344D6F2EEFA56655C39C65C0595425799826498 ) + rom ( name "Q Billion (Japan).gb" size 32768 crc 979ed154 sha1 6344D6F2EEFA56655C39C65C0595425799826498 ) ) game ( name "Q Billion (USA)" description "Q Billion (USA)" - rom ( name "Q Billion (USA).gb" size 32768 crc 7202E973 md5 AB7A5F3D9E818A434CC64915C3DBD31F sha1 CFC54888F1BA368463009983F3CB3F6DA66F3AEC ) + rom ( name "Q Billion (USA).gb" size 32768 crc 7202e973 sha1 CFC54888F1BA368463009983F3CB3F6DA66F3AEC ) ) game ( name "Q-bert for Game Boy (Japan)" description "Q-bert for Game Boy (Japan)" - rom ( name "Q-bert for Game Boy (Japan).gb" size 65536 crc E9BA4BAD md5 1C1911E4A8D299FCC5DF4180F33B69E6 sha1 44665169FDB96C685646613A82719276E7F07763 ) + rom ( name "Q-bert for Game Boy (Japan).gb" size 65536 crc e9ba4bad sha1 44665169FDB96C685646613A82719276E7F07763 ) ) game ( name "Q-bert for Game Boy (USA, Europe)" description "Q-bert for Game Boy (USA, Europe)" - rom ( name "Q-bert for Game Boy (USA, Europe).gb" size 65536 crc B0109545 md5 514688DF17C1F7BCF978A13C83D0C22C sha1 BD56A1E96C3D310B522E25D7B72CEEF26AF87F2E flags verified ) + rom ( name "Q-bert for Game Boy (USA, Europe).gb" size 65536 crc b0109545 sha1 BD56A1E96C3D310B522E25D7B72CEEF26AF87F2E flags verified ) ) game ( name "QIX (World)" description "QIX (World)" - rom ( name "QIX (World).gb" size 65536 crc 9185E89E md5 1C94DCCDFAAA0C3E1D6BDA5969704885 sha1 FB9935CA821562966EAFA8F60EC2F489AD33940A flags verified ) + rom ( name "QIX (World).gb" size 65536 crc 9185e89e sha1 FB9935CA821562966EAFA8F60EC2F489AD33940A flags verified ) ) game ( name "Quarth (Japan)" description "Quarth (Japan)" - rom ( name "Quarth (Japan).gb" size 65536 crc 40E5ADC9 md5 530220B702B6E1CC4D0CA9FEC3749646 sha1 DE0F86FDF63461BA0B01DF3839416F834133F2C9 flags verified ) + rom ( name "Quarth (Japan).gb" size 65536 crc 40e5adc9 sha1 DE0F86FDF63461BA0B01DF3839416F834133F2C9 flags verified ) ) game ( name "Quarth (USA, Europe)" description "Quarth (USA, Europe)" - rom ( name "Quarth (USA, Europe).gb" size 65536 crc BFB112AD md5 DE2236723C8D218E04C93849EBCDA72D sha1 89448B17700A6016A3F81DE09A15E097C060D103 flags verified ) + rom ( name "Quarth (USA, Europe).gb" size 65536 crc bfb112ad sha1 89448B17700A6016A3F81DE09A15E097C060D103 flags verified ) ) game ( name "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" description "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" - rom ( name "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan).gb" size 262144 crc 471C237B md5 65EF3652202749D5D281C9C9641E0E19 sha1 C91507AA0E17580E8CF8F1901F328432C12CE2DD ) + rom ( name "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan).gb" size 262144 crc 471c237b sha1 C91507AA0E17580E8CF8F1901F328432C12CE2DD ) ) game ( name "Quiz Sekai wa Show by Shoubai!! (Japan)" description "Quiz Sekai wa Show by Shoubai!! (Japan)" - rom ( name "Quiz Sekai wa Show by Shoubai!! (Japan).gb" size 262144 crc D8C33DCD md5 6064C32BCF58C67966231E0ECBC76BFD sha1 5E0004D7C87E49B3ED9E72CB292A967FAAD6EA6C flags verified ) + rom ( name "Quiz Sekai wa Show by Shoubai!! (Japan).gb" size 262144 crc d8c33dcd sha1 5E0004D7C87E49B3ED9E72CB292A967FAAD6EA6C flags verified ) ) game ( name "R-Type (Japan)" description "R-Type (Japan)" - rom ( name "R-Type (Japan).gb" size 131072 crc E4988910 md5 89BDC38FD17A6C969306F756EDEF8A70 sha1 440573CE4EA3BAB679E25315CD3F05C5530F6BD1 flags verified ) + rom ( name "R-Type (Japan).gb" size 131072 crc e4988910 sha1 440573CE4EA3BAB679E25315CD3F05C5530F6BD1 flags verified ) ) game ( name "R-Type (USA, Europe)" description "R-Type (USA, Europe)" - rom ( name "R-Type (USA, Europe).gb" size 131072 crc E0F23FC0 md5 972DC35B3B2BD0762999B1AE48DA94F6 sha1 28531A4EB668477DF98CAF0E87CEDC0E5FDFE53B flags verified ) + rom ( name "R-Type (USA, Europe).gb" size 131072 crc e0f23fc0 sha1 28531A4EB668477DF98CAF0E87CEDC0E5FDFE53B flags verified ) ) game ( name "R-Type II (Europe)" description "R-Type II (Europe)" - rom ( name "R-Type II (Europe).gb" size 131072 crc 2FE2A72D md5 967030223FA85F7BA4AC71F26837F831 sha1 F19436DFED41B9C2E94E070A76C5BDBCC7F993C3 ) + rom ( name "R-Type II (Europe).gb" size 131072 crc 2fe2a72d sha1 F19436DFED41B9C2E94E070A76C5BDBCC7F993C3 ) ) game ( name "R-Type II (Japan)" description "R-Type II (Japan)" - rom ( name "R-Type II (Japan).gb" size 131072 crc 6002E291 md5 ACAC255E33082DDE52EEE7AF941D8681 sha1 28E13DB505CBB5C178002ACF02E5C0BFCFC6B08F flags verified ) -) - -game ( - name "Race Days (Europe)" - description "Race Days (Europe)" - rom ( name "Race Days (Europe).gb" size 262144 crc 442420B3 md5 4E4D51039CCE43B11F51191DC7A6BCD9 sha1 750143B2057B604123972A978A51A14A7E8621BF ) + rom ( name "R-Type II (Japan).gb" size 131072 crc 6002e291 sha1 28E13DB505CBB5C178002ACF02E5C0BFCFC6B08F flags verified ) ) game ( name "Race Days (USA)" description "Race Days (USA)" - rom ( name "Race Days (USA).gb" size 262144 crc B9AB5319 md5 B65938F85944BDA47E59C123537ABEA0 sha1 EEE5FEB39AF996804177F4A269D2A41F692120F9 ) + rom ( name "Race Days (USA).gb" size 262144 crc 442420b3 sha1 750143B2057B604123972A978A51A14A7E8621BF ) +) + +game ( + name "Race Days (Europe)" + description "Race Days (Europe)" + rom ( name "Race Days (Europe).gb" size 262144 crc b9ab5319 sha1 EEE5FEB39AF996804177F4A269D2A41F692120F9 flags verified ) ) game ( name "Race Drivin' (USA, Europe)" description "Race Drivin' (USA, Europe)" - rom ( name "Race Drivin' (USA, Europe).gb" size 131072 crc 6775CCD6 md5 74D409740CE00448D42B25EBB31E7BCD sha1 67111295FE2095861256B46E7417E4C1D115A6FE flags verified ) + rom ( name "Race Drivin' (USA, Europe).gb" size 131072 crc 6775ccd6 sha1 67111295FE2095861256B46E7417E4C1D115A6FE flags verified ) ) game ( name "Racing Damashii (Japan)" description "Racing Damashii (Japan)" - rom ( name "Racing Damashii (Japan).gb" size 65536 crc 796FBB66 md5 CF4E3F4EE5DF2D68E978826AE564E1DA sha1 4466B36294176B3E1FC1558CD00ABDFA4247A75D flags verified ) -) - -game ( - name "Radar Mission (Japan)" - description "Radar Mission (Japan)" - rom ( name "Radar Mission (Japan).gb" size 131072 crc 892FC0AF md5 8CA4B92850C06465FA7BACAD00314CF0 sha1 64A808F582AFCBED6A3CE0263F1DAE6FDE57F30B flags verified ) + rom ( name "Racing Damashii (Japan).gb" size 65536 crc 796fbb66 sha1 4466B36294176B3E1FC1558CD00ABDFA4247A75D flags verified ) ) game ( name "Radar Mission (USA, Europe)" description "Radar Mission (USA, Europe)" - rom ( name "Radar Mission (USA, Europe).gb" size 131072 crc 581DA9C9 md5 82D650A781EF372126A863D519C01AAE sha1 5AB5998A84EEBC769F75C482CB0A5586ED97E888 flags verified ) + rom ( name "Radar Mission (USA, Europe).gb" size 131072 crc 581da9c9 sha1 5AB5998A84EEBC769F75C482CB0A5586ED97E888 flags verified ) ) game ( name "Raging Fighter (USA, Europe)" description "Raging Fighter (USA, Europe)" - rom ( name "Raging Fighter (USA, Europe).gb" size 262144 crc 1EF3BEDB md5 1752014C81020E4DBCE44C47C301DAF9 sha1 3E9AE5693208B8C377792C0FB67D682C6158B14D flags verified ) + rom ( name "Raging Fighter (USA, Europe).gb" size 262144 crc 1ef3bedb sha1 3E9AE5693208B8C377792C0FB67D682C6158B14D flags verified ) ) game ( name "Rampart (Japan)" description "Rampart (Japan)" - rom ( name "Rampart (Japan).gb" size 131072 crc 96A4C720 md5 7172C397CB5D45E28B615C26E518A107 sha1 0E196236A21FC4558F3EAB92BA38A574A1FDE918 ) + rom ( name "Rampart (Japan).gb" size 131072 crc 96a4c720 sha1 0E196236A21FC4558F3EAB92BA38A574A1FDE918 ) ) game ( name "Rampart (USA, Europe)" description "Rampart (USA, Europe)" - rom ( name "Rampart (USA, Europe).gb" size 131072 crc 6D347812 md5 ABA4C0670730F413D4946D88AAB28629 sha1 51E5408E5E8243C762F4218FD4138C849EE7D625 flags verified ) + rom ( name "Rampart (USA, Europe).gb" size 131072 crc 6d347812 sha1 51E5408E5E8243C762F4218FD4138C849EE7D625 flags verified ) ) game ( name "Ranma 1-2 (Japan)" description "Ranma 1-2 (Japan)" - rom ( name "Ranma 1-2 (Japan).gb" size 65536 crc 4E05537E md5 12D88FA2C0E6707F05BEB556B661702D sha1 C869D7FC1FCE8EA7CA534E29E8DA826017F4CA4F flags verified ) + rom ( name "Ranma 1-2 (Japan).gb" size 65536 crc 4e05537e sha1 C869D7FC1FCE8EA7CA534E29E8DA826017F4CA4F flags verified ) ) game ( name "Ranma 1-2 - Kakugeki Mondou!! (Japan)" description "Ranma 1-2 - Kakugeki Mondou!! (Japan)" - rom ( name "Ranma 1-2 - Kakugeki Mondou!! (Japan).gb" size 262144 crc 613E657A md5 F8B0F3889FC7B9936F7E556A3F73825F sha1 57FD028FD44D6096967A3C80AFD9E17C38C2513E ) + rom ( name "Ranma 1-2 - Kakugeki Mondou!! (Japan).gb" size 262144 crc 613e657a sha1 57FD028FD44D6096967A3C80AFD9E17C38C2513E flags verified ) ) game ( name "Ranma 1-2 - Netsuretsu Kakutou Hen (Japan)" description "Ranma 1-2 - Netsuretsu Kakutou Hen (Japan)" - rom ( name "Ranma 1-2 - Netsuretsu Kakutou Hen (Japan).gb" size 262144 crc D9D57151 md5 CD5B7AB41C9C5B1F0F70F4A736628DC0 sha1 62BFBB19B825C3305C819DA06332F731437C51F0 ) + rom ( name "Ranma 1-2 - Netsuretsu Kakutou Hen (Japan).gb" size 262144 crc d9d57151 sha1 62BFBB19B825C3305C819DA06332F731437C51F0 ) ) game ( name "Ray-Thunder (Japan)" description "Ray-Thunder (Japan)" - rom ( name "Ray-Thunder (Japan).gb" size 131072 crc A00A9468 md5 3DEFA1C909AF45963F3AD867EC5F3414 sha1 E250E681B26835FF60B5EF0D9CE4513D8CAF59E5 ) + rom ( name "Ray-Thunder (Japan).gb" size 131072 crc a00a9468 sha1 E250E681B26835FF60B5EF0D9CE4513D8CAF59E5 ) ) game ( name "Real Ghostbusters, The (USA)" description "Real Ghostbusters, The (USA)" - rom ( name "Real Ghostbusters, The (USA).gb" size 131072 crc E1592B83 md5 BBCA91D6BC19CDA45C706046B6E854E6 sha1 F470BF48B02E95B7F2C0D82B5C676BD298AB6D52 ) + rom ( name "Real Ghostbusters, The (USA).gb" size 131072 crc e1592b83 sha1 F470BF48B02E95B7F2C0D82B5C676BD298AB6D52 ) ) game ( - name "Red Arremer - Makai Mura Gaiden (Japan)" - description "Red Arremer - Makai Mura Gaiden (Japan)" - rom ( name "Red Arremer - Makai Mura Gaiden (Japan).gb" size 131072 crc AE0122AA md5 DAEE829005D9C4BD5F636004BFFFDFE3 sha1 DD49A66372411DA76023E993B3476190F76EECA8 flags verified ) + name "Red Arremer - Makaimura Gaiden (Japan)" + description "Red Arremer - Makaimura Gaiden (Japan)" + rom ( name "Red Arremer - Makaimura Gaiden (Japan).gb" size 131072 crc ae0122aa sha1 DD49A66372411DA76023E993B3476190F76EECA8 flags verified ) ) game ( name "Red October o Oe! (Japan)" description "Red October o Oe! (Japan)" - rom ( name "Red October o Oe! (Japan).gb" size 131072 crc C2E7BE35 md5 22EF15C88A371718D81B36F957F4F664 sha1 48D5F02A126C32423569065F31D2C5695E39FD2F flags verified ) + rom ( name "Red October o Oe! (Japan).gb" size 131072 crc c2e7be35 sha1 48D5F02A126C32423569065F31D2C5695E39FD2F flags verified ) ) game ( name "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" description "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" - rom ( name "Ren & Stimpy Show, The - Space Cadet Adventures (USA).gb" size 262144 crc 2085AAD9 md5 3B3EE80272479464698200AD712D4152 sha1 DA7634AA8E34BE43D7DC89A572BE2126795989AF ) + rom ( name "Ren & Stimpy Show, The - Space Cadet Adventures (USA).gb" size 262144 crc 2085aad9 sha1 DA7634AA8E34BE43D7DC89A572BE2126795989AF flags verified ) ) game ( name "Ren & Stimpy Show, The - Veediots! (USA, Europe)" description "Ren & Stimpy Show, The - Veediots! (USA, Europe)" - rom ( name "Ren & Stimpy Show, The - Veediots! (USA, Europe).gb" size 262144 crc 504CBD1D md5 99D9043A801704007D7AD227676FA6F1 sha1 40E278161A0268F00DCAE5B7F16AE390D0400937 flags verified ) + rom ( name "Ren & Stimpy Show, The - Veediots! (USA, Europe).gb" size 262144 crc 504cbd1d sha1 40E278161A0268F00DCAE5B7F16AE390D0400937 flags verified ) ) game ( - name "Renju Club (Japan) (SGB Enhanced)" - description "Renju Club (Japan) (SGB Enhanced)" - rom ( name "Renju Club (Japan) (SGB Enhanced).gb" size 32768 crc 52F5E960 md5 CF189F7F8A35BD5838C102CD2126DE46 sha1 D5D2A3F194AF308A2E7FBBF0F893537BD9E44A68 ) + name "Renju Club - Gomoku Narabe (Japan) (SGB Enhanced)" + description "Renju Club - Gomoku Narabe (Japan) (SGB Enhanced)" + rom ( name "Renju Club - Gomoku Narabe (Japan) (SGB Enhanced).gb" size 32768 crc 52f5e960 sha1 D5D2A3F194AF308A2E7FBBF0F893537BD9E44A68 ) ) game ( name "Rentaiou (Japan)" description "Rentaiou (Japan)" - rom ( name "Rentaiou (Japan).gb" size 65536 crc 2350922B md5 A580EE4E1FC4DDE0D3B8C11B62A4D77B sha1 5B2FA3DA4DCD8AFCD88C00134A2BBC8942135897 ) + rom ( name "Rentaiou (Japan).gb" size 65536 crc 2350922b sha1 5B2FA3DA4DCD8AFCD88C00134A2BBC8942135897 ) ) game ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It)" description "Reservoir Rat (Europe) (En,Fr,De,Es,It)" - rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2D33E175 md5 FEE2CFB63E4491E395B6F3438C48ACA2 sha1 08DAD9AC1F045D1C9E403C4EA1368AEE991E0094 ) + rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2d33e175 sha1 08DAD9AC1F045D1C9E403C4EA1368AEE991E0094 flags verified ) ) game ( name "Riddick Bowe Boxing (Europe)" description "Riddick Bowe Boxing (Europe)" - rom ( name "Riddick Bowe Boxing (Europe).gb" size 131072 crc 8DE1AE9C md5 7FC2DADD7AE98064FEBAA30A0D35112F sha1 261A6272560E04BEF0819FD38E70607D7E23EEA5 ) + rom ( name "Riddick Bowe Boxing (Europe).gb" size 131072 crc 8de1ae9c sha1 261A6272560E04BEF0819FD38E70607D7E23EEA5 flags verified ) ) game ( name "Riddick Bowe Boxing (USA)" description "Riddick Bowe Boxing (USA)" - rom ( name "Riddick Bowe Boxing (USA).gb" size 131072 crc FB5D24E0 md5 F72BA137F679BDE064E2E4E644C69B22 sha1 93A8A28244461B564E828CCA876821FB7A60FC89 ) + rom ( name "Riddick Bowe Boxing (USA).gb" size 131072 crc fb5d24e0 sha1 93A8A28244461B564E828CCA876821FB7A60FC89 ) ) game ( name "Ring Rage (Japan)" description "Ring Rage (Japan)" - rom ( name "Ring Rage (Japan).gb" size 131072 crc FD3D5BA7 md5 813FC943982D8A24085097D395994CCF sha1 C6689E9DF7312DDFF14F3E7B483FB02107C7B84B ) + rom ( name "Ring Rage (Japan).gb" size 131072 crc fd3d5ba7 sha1 C6689E9DF7312DDFF14F3E7B483FB02107C7B84B ) ) game ( name "Ring Rage (USA)" description "Ring Rage (USA)" - rom ( name "Ring Rage (USA).gb" size 131072 crc BCE5DFB7 md5 6C4D2F2A4AA7029759441D2C16D8C931 sha1 EB9509415D08792A29712814A7887824F11624C0 ) + rom ( name "Ring Rage (USA).gb" size 131072 crc bce5dfb7 sha1 EB9509415D08792A29712814A7887824F11624C0 ) ) game ( name "Road Rash (USA, Europe)" description "Road Rash (USA, Europe)" - rom ( name "Road Rash (USA, Europe).gb" size 131072 crc 88EDC83D md5 71AF355CBF7B8C7FE30F509803BBCED6 sha1 488E699490598234E762ECF864C75EDCB1BC6066 flags verified ) + rom ( name "Road Rash (USA, Europe).gb" size 131072 crc 88edc83d sha1 488E699490598234E762ECF864C75EDCB1BC6066 flags verified ) ) game ( name "Road Rash (USA, Europe) (Beta)" description "Road Rash (USA, Europe) (Beta)" - rom ( name "Road Rash (USA, Europe) (Beta).gb" size 131072 crc 4F09238A md5 68571BDA998E8C3B3753ADEC24AF7EDC sha1 5CC1416EEDEABC32D8D0A7A42D170B70C6117B19 ) + rom ( name "Road Rash (USA, Europe) (Beta).gb" size 131072 crc 4f09238a sha1 5CC1416EEDEABC32D8D0A7A42D170B70C6117B19 ) ) game ( name "Roadster (Japan)" description "Roadster (Japan)" - rom ( name "Roadster (Japan).gb" size 131072 crc 04453E78 md5 E6EDABD28A9D6600F8B8E9707BAA930E sha1 685C31496DE738C27160D1F75408DA6B95DAAAE8 ) + rom ( name "Roadster (Japan).gb" size 131072 crc 04453e78 sha1 685C31496DE738C27160D1F75408DA6B95DAAAE8 ) ) game ( name "Robin Hood - Prince of Thieves (Europe)" description "Robin Hood - Prince of Thieves (Europe)" - rom ( name "Robin Hood - Prince of Thieves (Europe).gb" size 262144 crc 55BBA483 md5 1294651EE0BCDAF1A0724E7FA9FFE557 sha1 7E7B7508F810D0CAB2D0873B7CB8DCB61F4B493A ) + rom ( name "Robin Hood - Prince of Thieves (Europe).gb" size 262144 crc 55bba483 sha1 7E7B7508F810D0CAB2D0873B7CB8DCB61F4B493A flags verified ) ) game ( name "Robin Hood - Prince of Thieves (France)" description "Robin Hood - Prince of Thieves (France)" - rom ( name "Robin Hood - Prince of Thieves (France).gb" size 262144 crc EF1A493A md5 4A3309BE521DF2CA7645363A88D1F2B4 sha1 0C74624F8D2F6F7F1A969C4FA9B621734877FBBD ) + rom ( name "Robin Hood - Prince of Thieves (France).gb" size 262144 crc ef1a493a sha1 0C74624F8D2F6F7F1A969C4FA9B621734877FBBD flags verified ) ) game ( name "Robin Hood - Prince of Thieves (Germany)" description "Robin Hood - Prince of Thieves (Germany)" - rom ( name "Robin Hood - Prince of Thieves (Germany).gb" size 262144 crc 0B2071A3 md5 1636D766639525DE9FE1EF335808CDFB sha1 98FBE26F7C05121DD3A2C8F3CDC4ADD3E2F81BC1 flags verified ) + rom ( name "Robin Hood - Prince of Thieves (Germany).gb" size 262144 crc 0b2071a3 sha1 98FBE26F7C05121DD3A2C8F3CDC4ADD3E2F81BC1 flags verified ) ) game ( name "Robin Hood - Prince of Thieves (Spain)" description "Robin Hood - Prince of Thieves (Spain)" - rom ( name "Robin Hood - Prince of Thieves (Spain).gb" size 262144 crc 7846DF7D md5 D0444ABF63571F46CD080063F82A4452 sha1 C9AFA1AFAFB05289B5E26B2C3E3D9744067384E7 ) + rom ( name "Robin Hood - Prince of Thieves (Spain).gb" size 262144 crc 7846df7d sha1 C9AFA1AFAFB05289B5E26B2C3E3D9744067384E7 flags verified ) ) game ( name "Robin Hood - Prince of Thieves (USA)" description "Robin Hood - Prince of Thieves (USA)" - rom ( name "Robin Hood - Prince of Thieves (USA).gb" size 262144 crc E5C8C2B1 md5 2815FF13131712BCD00C3852D461B414 sha1 999BB7878472B657375E04B75ED86EFA90933A55 ) + rom ( name "Robin Hood - Prince of Thieves (USA).gb" size 262144 crc e5c8c2b1 sha1 999BB7878472B657375E04B75ED86EFA90933A55 ) ) game ( name "RoboCop (Japan)" description "RoboCop (Japan)" - rom ( name "RoboCop (Japan).gb" size 131072 crc 06D6980B md5 4B248813C7F2317E55690B5C95F163B2 sha1 11B22799A4FE7A605C54C7D5FB9B9F61ECEFFD08 flags verified ) + rom ( name "RoboCop (Japan).gb" size 131072 crc 06d6980b sha1 11B22799A4FE7A605C54C7D5FB9B9F61ECEFFD08 flags verified ) ) game ( name "RoboCop (USA)" description "RoboCop (USA)" - rom ( name "RoboCop (USA).gb" size 131072 crc 6088B426 md5 421A923BA483F65A967B8455500B8880 sha1 39B92E019134DFD4480B957509C3EB64920CECB3 ) + rom ( name "RoboCop (USA).gb" size 131072 crc 6088b426 sha1 39B92E019134DFD4480B957509C3EB64920CECB3 ) ) game ( - name "RoboCop (USA, Europe) (Rev A)" - description "RoboCop (USA, Europe) (Rev A)" - rom ( name "RoboCop (USA, Europe) (Rev A).gb" size 65536 crc 62D56C31 md5 A477AC86BE35D1FA70B708AD08DC88B8 sha1 B858E5A7B5B87578FB14A60A2D9A330A6C8A10EB flags verified ) + name "RoboCop (USA, Europe) (Rev 1)" + description "RoboCop (USA, Europe) (Rev 1)" + rom ( name "RoboCop (USA, Europe) (Rev 1).gb" size 65536 crc 62d56c31 sha1 B858E5A7B5B87578FB14A60A2D9A330A6C8A10EB flags verified ) ) game ( name "RoboCop 2 (Japan)" description "RoboCop 2 (Japan)" - rom ( name "RoboCop 2 (Japan).gb" size 131072 crc 157CE6E5 md5 CD84CC505331F6A1D0702BB4A9667CEC sha1 AA5FA94C51CE454D76FAA8BF5B3729557D064904 flags verified ) + rom ( name "RoboCop 2 (Japan).gb" size 131072 crc 157ce6e5 sha1 AA5FA94C51CE454D76FAA8BF5B3729557D064904 flags verified ) ) game ( name "RoboCop 2 (USA, Europe)" description "RoboCop 2 (USA, Europe)" - rom ( name "RoboCop 2 (USA, Europe).gb" size 131072 crc 4365A789 md5 3EB476D0C6347CE9034246F826866A58 sha1 B4B78CB9B606D64E8EBB80E047B3B4B4767C019C flags verified ) + rom ( name "RoboCop 2 (USA, Europe).gb" size 131072 crc 4365a789 sha1 B4B78CB9B606D64E8EBB80E047B3B4B4767C019C flags verified ) ) game ( - name "RoboCop vs. The Terminator (Europe)" - description "RoboCop vs. The Terminator (Europe)" - rom ( name "RoboCop vs. The Terminator (Europe).gb" size 131072 crc 9E3B05C4 md5 C515CC92427EA1148C1D6274F803B07A sha1 A5ABFFF1026FC65C8DA95B40423C4D136F4BCFBA ) + name "RoboCop versus The Terminator (Europe)" + description "RoboCop versus The Terminator (Europe)" + rom ( name "RoboCop versus The Terminator (Europe).gb" size 131072 crc 9e3b05c4 sha1 A5ABFFF1026FC65C8DA95B40423C4D136F4BCFBA flags verified ) ) game ( - name "RoboCop vs. The Terminator (USA)" - description "RoboCop vs. The Terminator (USA)" - rom ( name "RoboCop vs. The Terminator (USA).gb" size 131072 crc F82D7223 md5 0E82B5210966E9EB53D5B7EF906A0F40 sha1 CA0484363D1D427474DE028F037C7D566E9C1FEA ) + name "RoboCop versus The Terminator (USA)" + description "RoboCop versus The Terminator (USA)" + rom ( name "RoboCop versus The Terminator (USA).gb" size 131072 crc f82d7223 sha1 CA0484363D1D427474DE028F037C7D566E9C1FEA ) ) game ( name "Rock'n! Monster!! (Japan) (SGB Enhanced)" description "Rock'n! Monster!! (Japan) (SGB Enhanced)" - rom ( name "Rock'n! Monster!! (Japan) (SGB Enhanced).gb" size 524288 crc 630299C1 md5 FC89AE96C911BA84A5539BCC180F8F79 sha1 338070ED1CED15EACA02198AB32B9E82A92F77EE ) + rom ( name "Rock'n! Monster!! (Japan) (SGB Enhanced).gb" size 524288 crc 630299c1 sha1 338070ED1CED15EACA02198AB32B9E82A92F77EE ) ) game ( name "Rockman World (Japan)" description "Rockman World (Japan)" - rom ( name "Rockman World (Japan).gb" size 262144 crc 3BE6AC04 md5 D0B1C550250C859F4563165EB29033D6 sha1 91318509322FBCD1E1E05B98243227377D8F31D5 flags verified ) + rom ( name "Rockman World (Japan).gb" size 262144 crc 3be6ac04 sha1 91318509322FBCD1E1E05B98243227377D8F31D5 flags verified ) ) game ( name "Rockman World (Japan) (En) (Beta)" description "Rockman World (Japan) (En) (Beta)" - rom ( name "Rockman World (Japan) (En) (Beta).gb" size 262144 crc D7356A4F md5 2B04DBC9B7DBDDD456F56282F36F58CE sha1 60C5C997B4B2C47D852520817228D2B8EFC2A33F ) + rom ( name "Rockman World (Japan) (En) (Beta).gb" size 262144 crc d7356a4f sha1 60C5C997B4B2C47D852520817228D2B8EFC2A33F flags verified ) ) game ( name "Rockman World 2 (Japan)" description "Rockman World 2 (Japan)" - rom ( name "Rockman World 2 (Japan).gb" size 262144 crc C34D265E md5 C05B47DF8BDFE770BE228E51BC42DA84 sha1 5D35BAA2FADD07796ED8B441F82ED5B136A999C7 ) + rom ( name "Rockman World 2 (Japan).gb" size 262144 crc c34d265e sha1 5D35BAA2FADD07796ED8B441F82ED5B136A999C7 ) ) game ( name "Rockman World 3 (Japan)" description "Rockman World 3 (Japan)" - rom ( name "Rockman World 3 (Japan).gb" size 262144 crc E904484F md5 C22F3EFE9048652EF6F798650FCE2D2A sha1 201ABC73CF669F71A477A431D387518F4B488C1F flags verified ) + rom ( name "Rockman World 3 (Japan).gb" size 262144 crc e904484f sha1 201ABC73CF669F71A477A431D387518F4B488C1F flags verified ) ) game ( name "Rockman World 4 (Japan)" description "Rockman World 4 (Japan)" - rom ( name "Rockman World 4 (Japan).gb" size 524288 crc 16AEC559 md5 401647AD59208D67507245AC13E3894C sha1 D0835A9C5DC7FCA4DA4D62A9BC244525ECD76EE7 flags verified ) + rom ( name "Rockman World 4 (Japan).gb" size 524288 crc 16aec559 sha1 D0835A9C5DC7FCA4DA4D62A9BC244525ECD76EE7 flags verified ) ) game ( name "Rockman World 5 (Japan) (SGB Enhanced)" description "Rockman World 5 (Japan) (SGB Enhanced)" - rom ( name "Rockman World 5 (Japan) (SGB Enhanced).gb" size 524288 crc EEABD3C6 md5 309FC69D5AB1D2B17D0BBC127FAF04C1 sha1 F3904D2069A888E45CA44878461324E4C2A8B03D flags verified ) + rom ( name "Rockman World 5 (Japan) (SGB Enhanced).gb" size 524288 crc eeabd3c6 sha1 F3904D2069A888E45CA44878461324E4C2A8B03D flags verified ) ) game ( name "Rodland (Europe)" description "Rodland (Europe)" - rom ( name "Rodland (Europe).gb" size 65536 crc 6093F4EC md5 E4FCC98CF30AB2DB7D3C08F322667BE1 sha1 7865263ED508BFF8298444ECABEC55EFBB64190F ) + rom ( name "Rodland (Europe).gb" size 65536 crc 6093f4ec sha1 7865263ED508BFF8298444ECABEC55EFBB64190F flags verified ) ) game ( name "Roger Clemens' MVP Baseball (USA)" description "Roger Clemens' MVP Baseball (USA)" - rom ( name "Roger Clemens' MVP Baseball (USA).gb" size 262144 crc 9DA8595B md5 89DAE4A6F82D2E603AF41A4499A3360B sha1 2B37B40AB05BEE2B23B30B898AF6197A35278C10 ) + rom ( name "Roger Clemens' MVP Baseball (USA).gb" size 262144 crc 9da8595b sha1 2B37B40AB05BEE2B23B30B898AF6197A35278C10 ) +) + +game ( + name "Roger Clemens' MVP Baseball (USA) (Rev 1)" + description "Roger Clemens' MVP Baseball (USA) (Rev 1)" + rom ( name "Roger Clemens' MVP Baseball (USA) (Rev 1).gb" size 262144 crc fa955b39 sha1 678EA6EC765C467862BE861D2C61FBB3A582C1F2 flags verified ) ) game ( name "Rolan's Curse (USA)" description "Rolan's Curse (USA)" - rom ( name "Rolan's Curse (USA).gb" size 65536 crc 1A602590 md5 EBD1866DC6C13CA48F45538ED33EA46F sha1 D5EEB34B24691EB6895D3349A05E2A75D910CF16 flags verified ) + rom ( name "Rolan's Curse (USA).gb" size 65536 crc 1a602590 sha1 D5EEB34B24691EB6895D3349A05E2A75D910CF16 flags verified ) ) game ( name "Rolan's Curse II (USA)" description "Rolan's Curse II (USA)" - rom ( name "Rolan's Curse II (USA).gb" size 131072 crc 2754F360 md5 27F2C99B13CBDB5A5BE4AFCE87B9039B sha1 7632E23853DD2579012489F75BD370473F0F2C46 flags verified ) + rom ( name "Rolan's Curse II (USA).gb" size 131072 crc 2754f360 sha1 7632E23853DD2579012489F75BD370473F0F2C46 flags verified ) ) game ( name "Rubble Saver (Japan)" description "Rubble Saver (Japan)" - rom ( name "Rubble Saver (Japan).gb" size 131072 crc E8AEA452 md5 10C581E4D5B612831C79724434F93E9F sha1 B535B2B78611BA1EB59E530456545FCED0FDDB76 ) + rom ( name "Rubble Saver (Japan).gb" size 131072 crc e8aea452 sha1 B535B2B78611BA1EB59E530456545FCED0FDDB76 ) ) game ( name "Rubble Saver II (Japan)" description "Rubble Saver II (Japan)" - rom ( name "Rubble Saver II (Japan).gb" size 65536 crc 92C95F2D md5 019DB3E93FA9583A04366A4E4597C618 sha1 49A07665695018B29DEF2CF3F843E10B88889775 ) + rom ( name "Rubble Saver II (Japan).gb" size 65536 crc 92c95f2d sha1 49A07665695018B29DEF2CF3F843E10B88889775 ) ) game ( name "Rugrats Movie, The (USA) (SGB Enhanced)" description "Rugrats Movie, The (USA) (SGB Enhanced)" - rom ( name "Rugrats Movie, The (USA) (SGB Enhanced).gb" size 524288 crc 124A0D06 md5 D29CC1B6FE7709A6D16F00C779499DE2 sha1 70384EB3474637B81BEC3018EBF0C2D6FA1D8A9D ) + rom ( name "Rugrats Movie, The (USA) (SGB Enhanced).gb" size 524288 crc 124a0d06 sha1 70384EB3474637B81BEC3018EBF0C2D6FA1D8A9D ) ) game ( name "Sa-Ga 2 - Hihou Densetsu (Japan)" description "Sa-Ga 2 - Hihou Densetsu (Japan)" - rom ( name "Sa-Ga 2 - Hihou Densetsu (Japan).gb" size 262144 crc 18055BB9 md5 10C1170D5B5416A217EB66821060421D sha1 F1DB92D8076237489AA1528141FE240843111A54 ) + rom ( name "Sa-Ga 2 - Hihou Densetsu (Japan).gb" size 262144 crc 18055bb9 sha1 F1DB92D8076237489AA1528141FE240843111A54 flags verified ) ) game ( - name "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev A)" - description "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev A)" - rom ( name "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev A).gb" size 262144 crc F6CFCFB1 md5 1F66F1DE0DC183D58E47CAFDC414EC2B sha1 96EF7D31AD098A620BA7AC57AFEF416972707EA3 flags verified ) + name "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev 1)" + description "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev 1)" + rom ( name "Sa-Ga 2 - Hihou Densetsu (Japan) (Rev 1).gb" size 262144 crc f6cfcfb1 sha1 96EF7D31AD098A620BA7AC57AFEF416972707EA3 flags verified ) ) game ( name "Sa-Ga 3 - Jikuu no Hasha (Japan)" description "Sa-Ga 3 - Jikuu no Hasha (Japan)" - rom ( name "Sa-Ga 3 - Jikuu no Hasha (Japan).gb" size 262144 crc 575D6D9D md5 FCFA7B01F96B5546DEFB6B3C739F4008 sha1 C8DCBEFC0352B0590FD85A683D983B5510A63519 flags verified ) + rom ( name "Sa-Ga 3 - Jikuu no Hasha (Japan).gb" size 262144 crc 575d6d9d sha1 C8DCBEFC0352B0590FD85A683D983B5510A63519 flags verified ) ) game ( name "Sagaia (Japan)" description "Sagaia (Japan)" - rom ( name "Sagaia (Japan).gb" size 131072 crc E43DA090 md5 70A9EF90AD443881CA90CDD8D910AE66 sha1 79600F8602CA33F2B39A9B8D9824DFF55DFC1EF0 flags verified ) + rom ( name "Sagaia (Japan).gb" size 131072 crc e43da090 sha1 79600F8602CA33F2B39A9B8D9824DFF55DFC1EF0 flags verified ) ) game ( name "Saigo no Nindou (Japan)" description "Saigo no Nindou (Japan)" - rom ( name "Saigo no Nindou (Japan).gb" size 131072 crc B864A3B6 md5 322965849B9103A3D6906C9697A19C09 sha1 F983BD9B58EE07204E50C9FDD8A76BA57F2FB40C flags verified ) + rom ( name "Saigo no Nindou (Japan).gb" size 131072 crc b864a3b6 sha1 F983BD9B58EE07204E50C9FDD8A76BA57F2FB40C flags verified ) ) game ( name "Saint Paradise - Saikyou no Senshi-tachi (Japan)" description "Saint Paradise - Saikyou no Senshi-tachi (Japan)" - rom ( name "Saint Paradise - Saikyou no Senshi-tachi (Japan).gb" size 262144 crc D6FE3C56 md5 4D2EC4DA71D11F95367D9163C89B70F9 sha1 E7CF9EABEAD0E5C0D3228871BB8219643E5BD7E0 flags verified ) + rom ( name "Saint Paradise - Saikyou no Senshi-tachi (Japan).gb" size 262144 crc d6fe3c56 sha1 E7CF9EABEAD0E5C0D3228871BB8219643E5BD7E0 flags verified ) ) game ( name "Sakigake!! Otoko Juku - Meioutou Kessen (Japan)" description "Sakigake!! Otoko Juku - Meioutou Kessen (Japan)" - rom ( name "Sakigake!! Otoko Juku - Meioutou Kessen (Japan).gb" size 131072 crc 2F0F7F63 md5 7DBD16112EBEF871062660808B5A0CD4 sha1 C731F8BE269D74748AE54FE5CE5FAEA89A825E0F flags verified ) + rom ( name "Sakigake!! Otoko Juku - Meioutou Kessen (Japan).gb" size 131072 crc 2f0f7f63 sha1 C731F8BE269D74748AE54FE5CE5FAEA89A825E0F flags verified ) ) game ( name "Same Game (Japan) (SGB Enhanced)" description "Same Game (Japan) (SGB Enhanced)" - rom ( name "Same Game (Japan) (SGB Enhanced).gb" size 262144 crc 70393C0F md5 BDD6F3F98390202800751A4EA2A48C36 sha1 9DCB5A95E808423E6BD1149319CA8EDA069363C8 ) + rom ( name "Same Game (Japan) (SGB Enhanced).gb" size 262144 crc 70393c0f sha1 9DCB5A95E808423E6BD1149319CA8EDA069363C8 ) ) game ( name "Samurai Shodown (USA, Europe) (SGB Enhanced)" description "Samurai Shodown (USA, Europe) (SGB Enhanced)" - rom ( name "Samurai Shodown (USA, Europe) (SGB Enhanced).gb" size 524288 crc 69292EE6 md5 CB5FE1C733F610AD6151216B6887285A sha1 D696BA3562BED549A144FFE0B97FBF4C528F325F flags verified ) + rom ( name "Samurai Shodown (USA, Europe) (SGB Enhanced).gb" size 524288 crc 69292ee6 sha1 D696BA3562BED549A144FFE0B97FBF4C528F325F flags verified ) ) game ( name "Samurai Shodown (USA, Europe) (Beta) (SGB Enhanced)" description "Samurai Shodown (USA, Europe) (Beta) (SGB Enhanced)" - rom ( name "Samurai Shodown (USA, Europe) (Beta) (SGB Enhanced).gb" size 524288 crc 90D51289 md5 CDD340A5F4E02C5D84D094FA0A06DB1A sha1 1DDB05F7237E792DDA9924AC0C525D8D1950CB44 ) + rom ( name "Samurai Shodown (USA, Europe) (Beta) (SGB Enhanced).gb" size 524288 crc 90d51289 sha1 1DDB05F7237E792DDA9924AC0C525D8D1950CB44 flags verified ) ) game ( name "Sangokushi - Game Boy Ban (Japan)" description "Sangokushi - Game Boy Ban (Japan)" - rom ( name "Sangokushi - Game Boy Ban (Japan).gb" size 262144 crc 83706E92 md5 85082BCBDA4FEBF4E9E05FA0679940B4 sha1 E94128D58341CAAEE595ED75292908A9AC5A466D flags verified ) + rom ( name "Sangokushi - Game Boy Ban (Japan).gb" size 262144 crc 83706e92 sha1 E94128D58341CAAEE595ED75292908A9AC5A466D flags verified ) ) game ( name "Sanrio Carnival (Japan)" description "Sanrio Carnival (Japan)" - rom ( name "Sanrio Carnival (Japan).gb" size 65536 crc 48D8AB7A md5 D82114F0AADFC632CDC9D4C553B3CC7A sha1 E17FA516E0F85C6DD80F29573363E42528D88266 flags verified ) + rom ( name "Sanrio Carnival (Japan).gb" size 65536 crc 48d8ab7a sha1 E17FA516E0F85C6DD80F29573363E42528D88266 flags verified ) ) game ( name "Sanrio Carnival 2 (Japan)" description "Sanrio Carnival 2 (Japan)" - rom ( name "Sanrio Carnival 2 (Japan).gb" size 65536 crc 758C7B2A md5 FE9C96C1D212D9CBC7C6F25946A87059 sha1 7FF76205C59CD090FDC91B2D8C57CB44FD4B009B ) + rom ( name "Sanrio Carnival 2 (Japan).gb" size 65536 crc 758c7b2a sha1 7FF76205C59CD090FDC91B2D8C57CB44FD4B009B ) ) game ( name "Sanrio Uranai Party (Japan)" description "Sanrio Uranai Party (Japan)" - rom ( name "Sanrio Uranai Party (Japan).gb" size 262144 crc 0D4C02A7 md5 9FA5CE9C87D949DFBD5D8FF46ECE63EB sha1 0D12280E689EB320DF06CEB469C629D93860DC2E ) + rom ( name "Sanrio Uranai Party (Japan).gb" size 262144 crc 0d4c02a7 sha1 0D12280E689EB320DF06CEB469C629D93860DC2E flags verified ) ) game ( - name "Sanrio Uranai Party (Japan) (Rev A)" - description "Sanrio Uranai Party (Japan) (Rev A)" - rom ( name "Sanrio Uranai Party (Japan) (Rev A).gb" size 262144 crc D0687D9F md5 442C13B1747376782D1DAE3F8877F94D sha1 72DFCC83DBD78AD2B5B43014FC9ADF05431E230C flags verified ) + name "Sanrio Uranai Party (Japan) (Rev 1)" + description "Sanrio Uranai Party (Japan) (Rev 1)" + rom ( name "Sanrio Uranai Party (Japan) (Rev 1).gb" size 262144 crc d0687d9f sha1 72DFCC83DBD78AD2B5B43014FC9ADF05431E230C flags verified ) ) game ( name "Schiffe Versenken (Germany) (En,Fr,De,Es)" description "Schiffe Versenken (Germany) (En,Fr,De,Es)" - rom ( name "Schiffe Versenken (Germany) (En,Fr,De,Es).gb" size 131072 crc 1CB8BFC2 md5 C62460C4FB6430CB4D2C6A3902B5442D sha1 00745F75877423494679BBC3912E58238AC399C3 flags verified ) + rom ( name "Schiffe Versenken (Germany) (En,Fr,De,Es).gb" size 131072 crc 1cb8bfc2 sha1 00745F75877423494679BBC3912E58238AC399C3 flags verified ) ) game ( name "Scotland Yard (Japan)" description "Scotland Yard (Japan)" - rom ( name "Scotland Yard (Japan).gb" size 131072 crc 4A0F5972 md5 3D9099F5C9822D771F461C20A153A59B sha1 8B6D7DB97DA4664353241D67EA225E74DBA6A170 ) -) - -game ( - name "SD Command Gundam - G-Arms (Japan)" - description "SD Command Gundam - G-Arms (Japan)" - rom ( name "SD Command Gundam - G-Arms (Japan).gb" size 131072 crc 39058153 md5 7D8E0DC0CC90B414488FE7DF3D9151E5 sha1 7D8011636FE36266B5F716E78E3E29006F024992 flags verified ) + rom ( name "Scotland Yard (Japan).gb" size 131072 crc 4a0f5972 sha1 8B6D7DB97DA4664353241D67EA225E74DBA6A170 ) ) game ( name "SD Gundam - SD Sengokuden - Kunitori Monogatari (Japan)" description "SD Gundam - SD Sengokuden - Kunitori Monogatari (Japan)" - rom ( name "SD Gundam - SD Sengokuden - Kunitori Monogatari (Japan).gb" size 131072 crc 016A0552 md5 E5B64D0F6D48D325A3235109FC12FB12 sha1 86A57796557698DEF6EE760BFA03C8E3BEFCC4EF flags verified ) + rom ( name "SD Gundam - SD Sengokuden - Kunitori Monogatari (Japan).gb" size 131072 crc 016a0552 sha1 86A57796557698DEF6EE760BFA03C8E3BEFCC4EF flags verified ) ) game ( name "SD Gundam Gaiden - Lacroan' Heroes (Japan)" description "SD Gundam Gaiden - Lacroan' Heroes (Japan)" - rom ( name "SD Gundam Gaiden - Lacroan' Heroes (Japan).gb" size 131072 crc C9DBBA10 md5 5C815764DF1D3C04D99A9BC5B298AA2C sha1 BC598168A70BBBC1B89B3DE13086EC89E8CE9DED flags verified ) + rom ( name "SD Gundam Gaiden - Lacroan' Heroes (Japan).gb" size 131072 crc c9dbba10 sha1 BC598168A70BBBC1B89B3DE13086EC89E8CE9DED flags verified ) ) game ( name "SD Hiryuu no Ken Gaiden (Japan) (SGB Enhanced)" description "SD Hiryuu no Ken Gaiden (Japan) (SGB Enhanced)" - rom ( name "SD Hiryuu no Ken Gaiden (Japan) (SGB Enhanced).gb" size 524288 crc C4D09768 md5 EB23450A50F1EEFF27B33C988F2D779E sha1 E62B70188B146B82196F09720E99C7DD6F03036F flags verified ) + rom ( name "SD Hiryuu no Ken Gaiden (Japan) (SGB Enhanced).gb" size 524288 crc c4d09768 sha1 E62B70188B146B82196F09720E99C7DD6F03036F flags verified ) ) game ( name "SD Hiryuu no Ken Gaiden 2 (Japan) (SGB Enhanced)" description "SD Hiryuu no Ken Gaiden 2 (Japan) (SGB Enhanced)" - rom ( name "SD Hiryuu no Ken Gaiden 2 (Japan) (SGB Enhanced).gb" size 1048576 crc ADB511CA md5 6B22D2D8AA10B0A0F1479D159A3A4C84 sha1 C4D7A4D22406619C0A05E1B738C0330ED75A69BF ) + rom ( name "SD Hiryuu no Ken Gaiden 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 10034d19 sha1 D3E747B341D76DC3582257FE53111ECE385EB399 flags verified ) ) game ( name "SD Lupin Sansei - Kinko Yaburi Daisakusen (Japan)" description "SD Lupin Sansei - Kinko Yaburi Daisakusen (Japan)" - rom ( name "SD Lupin Sansei - Kinko Yaburi Daisakusen (Japan).gb" size 65536 crc F0B73DB4 md5 4EA04AB8FCEA4C41F26E44BB4F50D73E sha1 758FF1BF4FE54FEBA8750238CD062A1AD37843E7 flags verified ) + rom ( name "SD Lupin Sansei - Kinko Yaburi Daisakusen (Japan).gb" size 65536 crc f0b73db4 sha1 758FF1BF4FE54FEBA8750238CD062A1AD37843E7 flags verified ) ) game ( name "SD Sengokuden 2 - Tenka Touitsu Hen (Japan)" description "SD Sengokuden 2 - Tenka Touitsu Hen (Japan)" - rom ( name "SD Sengokuden 2 - Tenka Touitsu Hen (Japan).gb" size 262144 crc 5B7C6FAA md5 27B8724D17AABA0FFB4D3B8D79CDE2AC sha1 4494A8A9F960C55B056B12D2D2760CC976E36E17 ) + rom ( name "SD Sengokuden 2 - Tenka Touitsu Hen (Japan).gb" size 262144 crc 5b7c6faa sha1 4494A8A9F960C55B056B12D2D2760CC976E36E17 flags verified ) ) game ( name "SD Sengokuden 3 - Chijou Saikyou Hen (Japan)" description "SD Sengokuden 3 - Chijou Saikyou Hen (Japan)" - rom ( name "SD Sengokuden 3 - Chijou Saikyou Hen (Japan).gb" size 262144 crc 7C61426C md5 9832AB77352FD51D2C38FB6C75D1C4A4 sha1 2CB0368452033029EF8B8D92698D95ED41114A73 flags verified ) + rom ( name "SD Sengokuden 3 - Chijou Saikyou Hen (Japan).gb" size 262144 crc 7c61426c sha1 2CB0368452033029EF8B8D92698D95ED41114A73 flags verified ) ) game ( name "Sea Battle (Europe) (En,Fr,De,Es)" description "Sea Battle (Europe) (En,Fr,De,Es)" - rom ( name "Sea Battle (Europe) (En,Fr,De,Es).gb" size 131072 crc BA091B91 md5 EFE060EA92C1815417D7FC12005D6AFD sha1 560D62B96A1B9820E3FD953F76E33B4F5FDC9E2F ) + rom ( name "Sea Battle (Europe) (En,Fr,De,Es).gb" size 131072 crc ba091b91 sha1 560D62B96A1B9820E3FD953F76E33B4F5FDC9E2F ) ) game ( - name "SeaQuest DSV (USA, Europe) (SGB Enhanced)" - description "SeaQuest DSV (USA, Europe) (SGB Enhanced)" - rom ( name "SeaQuest DSV (USA, Europe) (SGB Enhanced).gb" size 262144 crc 31A3BD99 md5 AF8022DAA8B774C666FCC65961C8BD4A sha1 E9572941B35F119746B995F7FE578C31EF778026 flags verified ) + name "seaQuest DSV (USA, Europe) (SGB Enhanced)" + description "seaQuest DSV (USA, Europe) (SGB Enhanced)" + rom ( name "seaQuest DSV (USA, Europe) (SGB Enhanced).gb" size 262144 crc 31a3bd99 sha1 E9572941B35F119746B995F7FE578C31EF778026 flags verified ) ) game ( name "Seaside Volley (Japan)" description "Seaside Volley (Japan)" - rom ( name "Seaside Volley (Japan).gb" size 65536 crc 79AFE59E md5 5D07F39B93C83683C2C77ED31EC66048 sha1 42EC788B74B03000164533C87CAB0292B0D37995 flags verified ) + rom ( name "Seaside Volley (Japan).gb" size 65536 crc 79afe59e sha1 42EC788B74B03000164533C87CAB0292B0D37995 flags verified ) ) game ( name "Seiken Densetsu - Final Fantasy Gaiden (Japan)" description "Seiken Densetsu - Final Fantasy Gaiden (Japan)" - rom ( name "Seiken Densetsu - Final Fantasy Gaiden (Japan).gb" size 262144 crc D771C1B6 md5 3B359E9FEC183BFF5F964E25B599B246 sha1 998A5E6DF52DFF24AE686E287EED06F125940194 flags verified ) + rom ( name "Seiken Densetsu - Final Fantasy Gaiden (Japan).gb" size 262144 crc d771c1b6 sha1 998A5E6DF52DFF24AE686E287EED06F125940194 flags verified ) ) game ( name "Selection - Erabareshi Mono (Japan)" description "Selection - Erabareshi Mono (Japan)" - rom ( name "Selection - Erabareshi Mono (Japan).gb" size 131072 crc 799C5CDB md5 9F2B62D971705E147745DC2BFFB99CC1 sha1 A52A8DCD93C4FA4F020719C83780092B514D2B03 flags verified ) + rom ( name "Selection - Erabareshi Mono (Japan).gb" size 131072 crc 799c5cdb sha1 A52A8DCD93C4FA4F020719C83780092B514D2B03 flags verified ) ) game ( - name "Selection I & II (Japan) (SGB Enhanced)" - description "Selection I & II (Japan) (SGB Enhanced)" - rom ( name "Selection I & II (Japan) (SGB Enhanced).gb" size 524288 crc A6027919 md5 A7DF57DCB5F80AC0BBE39C4DC6339A4E sha1 58C0C524B07018BEB2D9178DE53FE2F6CBB6670F ) + name "Selection I & II - Erabareshi Mono & Ankoku no Fuuin (Japan) (SGB Enhanced)" + description "Selection I & II - Erabareshi Mono & Ankoku no Fuuin (Japan) (SGB Enhanced)" + rom ( name "Selection I & II - Erabareshi Mono & Ankoku no Fuuin (Japan) (SGB Enhanced).gb" size 524288 crc a6027919 sha1 58C0C524B07018BEB2D9178DE53FE2F6CBB6670F ) ) game ( name "Selection II - Ankoku no Fuuin (Japan)" description "Selection II - Ankoku no Fuuin (Japan)" - rom ( name "Selection II - Ankoku no Fuuin (Japan).gb" size 262144 crc D09073F6 md5 EA0BE44BB573550D7EA0EE91232EBDC8 sha1 6E524D0894DE0DB1B3EB4CA0C1075F6EA1A2FFC1 flags verified ) + rom ( name "Selection II - Ankoku no Fuuin (Japan).gb" size 262144 crc d09073f6 sha1 6E524D0894DE0DB1B3EB4CA0C1075F6EA1A2FFC1 flags verified ) ) game ( name "Sengoku Ninja-kun (Japan)" description "Sengoku Ninja-kun (Japan)" - rom ( name "Sengoku Ninja-kun (Japan).gb" size 131072 crc 6BAE3A41 md5 E3B96773C7D55B3EE4C2615D1B9DACA7 sha1 A60F4F815467298BD3928FE4AEE0EDD763EBE85D ) + rom ( name "Sengoku Ninja-kun (Japan).gb" size 131072 crc 6bae3a41 sha1 A60F4F815467298BD3928FE4AEE0EDD763EBE85D ) ) game ( name "Sensible Soccer - European Champions (Europe)" description "Sensible Soccer - European Champions (Europe)" - rom ( name "Sensible Soccer - European Champions (Europe).gb" size 131072 crc BD022658 md5 3AE8ECEB23913AEB1A655DA481541A6B sha1 EB9F0C6D3C137BE7991E9D28FE48D5026BEB2F35 flags verified ) + rom ( name "Sensible Soccer - European Champions (Europe).gb" size 131072 crc bd022658 sha1 EB9F0C6D3C137BE7991E9D28FE48D5026BEB2F35 flags verified ) ) game ( name "Serpent (USA)" description "Serpent (USA)" - rom ( name "Serpent (USA).gb" size 32768 crc 74D466D7 md5 ED999967209A4CBCAA844B8A84E09EA9 sha1 3122B3C12C2580C3A81D70C5648F767BF3590AAF flags verified ) + rom ( name "Serpent (USA).gb" size 32768 crc 74d466d7 sha1 3122B3C12C2580C3A81D70C5648F767BF3590AAF flags verified ) ) game ( name "Shadow Warriors (Europe)" description "Shadow Warriors (Europe)" - rom ( name "Shadow Warriors (Europe).gb" size 131072 crc BCC18E24 md5 13DD6801246DA226B0C2DB339DF4A246 sha1 F19075AA787CCE771077152F0D6C83527B9D7104 ) + rom ( name "Shadow Warriors (Europe).gb" size 131072 crc bcc18e24 sha1 F19075AA787CCE771077152F0D6C83527B9D7104 ) ) game ( - name "Shanghai (Japan)" - description "Shanghai (Japan)" - rom ( name "Shanghai (Japan).gb" size 32768 crc 7C29672B md5 FEF106AA1596FE49144B02A837D7D9EB sha1 7756E8C955E3BD4FE9B007C9EA4C83F914A100AE flags verified ) + name "Shanghai (Japan) (HAL Laboratory)" + description "Shanghai (Japan) (HAL Laboratory)" + rom ( name "Shanghai (Japan) (HAL Laboratory).gb" size 32768 crc 7c29672b sha1 7756E8C955E3BD4FE9B007C9EA4C83F914A100AE flags verified ) ) game ( name "Shanghai (Japan) (Activision)" description "Shanghai (Japan) (Activision)" - rom ( name "Shanghai (Japan) (Activision).gb" size 32768 crc 6AA684EB md5 72C0A7EB38FFC2EF65C0E2FFB1729AA5 sha1 2569352EA796864FCD769CC9B25C6497516134C6 flags verified ) + rom ( name "Shanghai (Japan) (Activision).gb" size 32768 crc 6aa684eb sha1 2569352EA796864FCD769CC9B25C6497516134C6 flags verified ) ) game ( name "Shanghai (USA)" description "Shanghai (USA)" - rom ( name "Shanghai (USA).gb" size 32768 crc 580FCB18 md5 D11777331E12F55AE4BAB2F6E0BDA918 sha1 D5CC81D0379982FE69E8FE30868FDCC621DD1BAE ) + rom ( name "Shanghai (USA).gb" size 32768 crc 580fcb18 sha1 D5CC81D0379982FE69E8FE30868FDCC621DD1BAE ) ) game ( name "Shanghai Pocket (Japan) (SGB Enhanced)" description "Shanghai Pocket (Japan) (SGB Enhanced)" - rom ( name "Shanghai Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 6B8EFF2C md5 C042681ADBBE175B354D0ABEE3413219 sha1 82FE97442AA625FD36CF865D82F78B07108EDE7F ) + rom ( name "Shanghai Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 6b8eff2c sha1 82FE97442AA625FD36CF865D82F78B07108EDE7F ) ) game ( name "Shaq Fu (USA) (SGB Enhanced)" description "Shaq Fu (USA) (SGB Enhanced)" - rom ( name "Shaq Fu (USA) (SGB Enhanced).gb" size 524288 crc 7ED43FE6 md5 9D4D9A346158FCDA7221C853B13BD19D sha1 5E9E68D9235CF8149232B85FD6080BA8796CB85E ) + rom ( name "Shaq Fu (USA) (SGB Enhanced).gb" size 524288 crc 7ed43fe6 sha1 5E9E68D9235CF8149232B85FD6080BA8796CB85E ) ) game ( name "Shikinjou (Japan)" description "Shikinjou (Japan)" - rom ( name "Shikinjou (Japan).gb" size 65536 crc F8EC3A41 md5 6CEB30C99E4642B62533F6F9101D59E5 sha1 84CB709A3E66B8B5F8B9415BC3CD34BF8F7E7B12 ) + rom ( name "Shikinjou (Japan).gb" size 65536 crc f8ec3a41 sha1 84CB709A3E66B8B5F8B9415BC3CD34BF8F7E7B12 ) ) game ( name "Shin Keiba Kizoku Pocket Jockey (Japan) (SGB Enhanced)" description "Shin Keiba Kizoku Pocket Jockey (Japan) (SGB Enhanced)" - rom ( name "Shin Keiba Kizoku Pocket Jockey (Japan) (SGB Enhanced).gb" size 524288 crc 490F8C46 md5 254554A4412D0FBA81C2ECE8E094D30F sha1 8D65A4F9F7B903D145FA863D09C8894DB4FD742A flags verified ) + rom ( name "Shin Keiba Kizoku Pocket Jockey (Japan) (SGB Enhanced).gb" size 524288 crc 490f8c46 sha1 8D65A4F9F7B903D145FA863D09C8894DB4FD742A flags verified ) ) game ( name "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan)" description "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan)" - rom ( name "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan).gb" size 131072 crc A8A43013 md5 037FCC5F7D7750B9DFD1C8946B64CF4F sha1 B8B7F4177D87124A5CD6C931FBC2EE3C6D97B3D4 flags verified ) + rom ( name "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan).gb" size 131072 crc a8a43013 sha1 B8B7F4177D87124A5CD6C931FBC2EE3C6D97B3D4 flags verified ) ) game ( - name "Shin SD Gundam Gaiden - Knight Gundam Story (Japan) (SGB Enhanced)" - description "Shin SD Gundam Gaiden - Knight Gundam Story (Japan) (SGB Enhanced)" - rom ( name "Shin SD Gundam Gaiden - Knight Gundam Story (Japan) (SGB Enhanced).gb" size 262144 crc E5A78B9B md5 70436283AC6D8B8AB84F256134159AB9 sha1 62E1D4DC9F6FAE94E981BDCF2FA4B65BB3949644 ) + name "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan) (Sample)" + description "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan) (Sample)" + rom ( name "Shin Nihon Pro Wrestling - Toukon Sanjuushi (Japan) (Sample).gb" size 131072 crc 12d978bf sha1 0F46531204B6D4A5294734CC5F14B9F9D2179D03 flags verified ) +) + +game ( + name "Shin SD Gundam Gaiden - Knight Gundam Monogatari (Japan) (SGB Enhanced)" + description "Shin SD Gundam Gaiden - Knight Gundam Monogatari (Japan) (SGB Enhanced)" + rom ( name "Shin SD Gundam Gaiden - Knight Gundam Monogatari (Japan) (SGB Enhanced).gb" size 262144 crc e5a78b9b sha1 62E1D4DC9F6FAE94E981BDCF2FA4B65BB3949644 ) ) game ( name "Shinri Game 2, The - Oosaka Hen (Japan)" description "Shinri Game 2, The - Oosaka Hen (Japan)" - rom ( name "Shinri Game 2, The - Oosaka Hen (Japan).gb" size 262144 crc 47095204 md5 B050DEF2AA2280EE666D23C3A688F438 sha1 1899A1EE1A6D7B69E2697395CE23FC3CE1E88624 ) + rom ( name "Shinri Game 2, The - Oosaka Hen (Japan).gb" size 262144 crc 47095204 sha1 1899A1EE1A6D7B69E2697395CE23FC3CE1E88624 ) ) game ( name "Shinri Game, The (Japan)" description "Shinri Game, The (Japan)" - rom ( name "Shinri Game, The (Japan).gb" size 262144 crc FB2FE362 md5 46853483281D6B04CF94EB541480F8E3 sha1 F47114A20DB53B8B789790DDCFF1CD3105B35482 ) + rom ( name "Shinri Game, The (Japan).gb" size 262144 crc fb2fe362 sha1 F47114A20DB53B8B789790DDCFF1CD3105B35482 ) ) game ( name "Shinseiki GPX Cyber Formula (Japan)" description "Shinseiki GPX Cyber Formula (Japan)" - rom ( name "Shinseiki GPX Cyber Formula (Japan).gb" size 131072 crc 72B42EA7 md5 0A7C71CE47CDC63550934037541019A6 sha1 5716F20E0726450A4FF7C9C6FD3FDC8004D38A77 ) + rom ( name "Shinseiki GPX Cyber Formula (Japan).gb" size 131072 crc 72b42ea7 sha1 5716F20E0726450A4FF7C9C6FD3FDC8004D38A77 ) ) game ( name "Shippo de Bun (Japan)" description "Shippo de Bun (Japan)" - rom ( name "Shippo de Bun (Japan).gb" size 65536 crc 56410442 md5 BB5544584F2988490565198C56D81C06 sha1 71E605D62C80BD2905A5ED3CE6CC1590638F2F2F flags verified ) + rom ( name "Shippo de Bun (Japan).gb" size 65536 crc 56410442 sha1 71E605D62C80BD2905A5ED3CE6CC1590638F2F2F flags verified ) ) game ( name "Shippuu! Iron Leaguer (Japan)" description "Shippuu! Iron Leaguer (Japan)" - rom ( name "Shippuu! Iron Leaguer (Japan).gb" size 131072 crc 8E3C7E15 md5 1107C6EC10EBA471045548919E7C114E sha1 2555E4B9426FF90EFD431D46BE5371D3E0A6DABF ) + rom ( name "Shippuu! Iron Leaguer (Japan).gb" size 131072 crc 8e3c7e15 sha1 2555E4B9426FF90EFD431D46BE5371D3E0A6DABF ) ) game ( name "Shisenshou - Match-Mania (Japan)" description "Shisenshou - Match-Mania (Japan)" - rom ( name "Shisenshou - Match-Mania (Japan).gb" size 32768 crc 0CDD8B04 md5 E60B4E21A7357819B7602954EA517EA3 sha1 6E84A906F9E1CE43272DB84C63F1B037096AC34F flags verified ) + rom ( name "Shisenshou - Match-Mania (Japan).gb" size 32768 crc 0cdd8b04 sha1 6E84A906F9E1CE43272DB84C63F1B037096AC34F flags verified ) ) game ( name "Shougi (Japan)" description "Shougi (Japan)" - rom ( name "Shougi (Japan).gb" size 131072 crc 4FB44CB4 md5 09AB7A431E216C65A0CFD9AE2F558A2E sha1 76D5D8C622F62563E0AB1E242B924B24C8DC42F0 flags verified ) + rom ( name "Shougi (Japan).gb" size 131072 crc 4fb44cb4 sha1 76D5D8C622F62563E0AB1E242B924B24C8DC42F0 flags verified ) ) game ( name "Shougi Saikyou (Japan) (SGB Enhanced)" description "Shougi Saikyou (Japan) (SGB Enhanced)" - rom ( name "Shougi Saikyou (Japan) (SGB Enhanced).gb" size 262144 crc 2F0F7C6E md5 F07094CB4398C3670D1DA2F704895B95 sha1 0638C6C66B94E70BA658240BE457DA5CE913BC8B ) + rom ( name "Shougi Saikyou (Japan) (SGB Enhanced).gb" size 262144 crc 2f0f7c6e sha1 0638C6C66B94E70BA658240BE457DA5CE913BC8B flags verified ) ) game ( - name "Shougi Saikyou (Japan) (Rev A) (SGB Enhanced)" - description "Shougi Saikyou (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Shougi Saikyou (Japan) (Rev A) (SGB Enhanced).gb" size 262144 crc A074BF7E md5 DF91ED711FB8553D034D4952C666B3C6 sha1 1C5A97AA3A09362C94FDD630456E5E59AE3AF5FA flags verified ) + name "Shougi Saikyou (Japan) (Rev 1) (SGB Enhanced)" + description "Shougi Saikyou (Japan) (Rev 1) (SGB Enhanced)" + rom ( name "Shougi Saikyou (Japan) (Rev 1) (SGB Enhanced).gb" size 262144 crc a074bf7e sha1 1C5A97AA3A09362C94FDD630456E5E59AE3AF5FA flags verified ) ) game ( name "Shounen Ashibe - Yuuenchi Panic (Japan)" description "Shounen Ashibe - Yuuenchi Panic (Japan)" - rom ( name "Shounen Ashibe - Yuuenchi Panic (Japan).gb" size 131072 crc B3063DB5 md5 4E6788188FD7E6BAB9B6974B308A38EB sha1 0BA051E85F793DB4466F10AB7452C778C55337DF flags verified ) + rom ( name "Shounen Ashibe - Yuuenchi Panic (Japan).gb" size 131072 crc b3063db5 sha1 0BA051E85F793DB4466F10AB7452C778C55337DF flags verified ) ) game ( name "Shuyaku Sentai Irem Fighter (Japan)" description "Shuyaku Sentai Irem Fighter (Japan)" - rom ( name "Shuyaku Sentai Irem Fighter (Japan).gb" size 262144 crc ECD61F03 md5 EFC276516B3CEEA0D291B49271B95BCD sha1 714134877092DDB688DED5D3516D7DB4B22E329E ) + rom ( name "Shuyaku Sentai Irem Fighter (Japan).gb" size 262144 crc ecd61f03 sha1 714134877092DDB688DED5D3516D7DB4B22E329E ) ) game ( name "Side Pocket (World)" description "Side Pocket (World)" - rom ( name "Side Pocket (World).gb" size 65536 crc 9A1E30B4 md5 3DBE9BE772CA50DA3A76D8860C7B08E2 sha1 0E9D907E9EBF8D69FB94133362590C8AC6AA6392 flags verified ) + rom ( name "Side Pocket (World).gb" size 65536 crc 9a1e30b4 sha1 0E9D907E9EBF8D69FB94133362590C8AC6AA6392 flags verified ) ) game ( name "Simpsons Itchy & Scratchy, The - Miniature Golf Madness (USA, Europe)" description "Simpsons Itchy & Scratchy, The - Miniature Golf Madness (USA, Europe)" - rom ( name "Simpsons Itchy & Scratchy, The - Miniature Golf Madness (USA, Europe).gb" size 131072 crc DDB147E5 md5 ED0A8885341EE6A201873B2038C87582 sha1 1DBB3EB39E0A2D695136880E6DD0557EB48EBF21 flags verified ) + rom ( name "Simpsons Itchy & Scratchy, The - Miniature Golf Madness (USA, Europe).gb" size 131072 crc ddb147e5 sha1 1DBB3EB39E0A2D695136880E6DD0557EB48EBF21 flags verified ) ) game ( name "Simpsons, The - Bart & the Beanstalk (USA, Europe)" description "Simpsons, The - Bart & the Beanstalk (USA, Europe)" - rom ( name "Simpsons, The - Bart & the Beanstalk (USA, Europe).gb" size 131072 crc 517A614C md5 19058077B12AC22580AAE17B3DD1233F sha1 98A2D90717D8C9F7FEB2D7653AAAB6FAA0F3EE64 flags verified ) + rom ( name "Simpsons, The - Bart & the Beanstalk (USA, Europe).gb" size 131072 crc 517a614c sha1 98A2D90717D8C9F7FEB2D7653AAAB6FAA0F3EE64 flags verified ) ) game ( name "Simpsons, The - Bart no Jack to Mame no Ki (Japan)" description "Simpsons, The - Bart no Jack to Mame no Ki (Japan)" - rom ( name "Simpsons, The - Bart no Jack to Mame no Ki (Japan).gb" size 131072 crc 7AA4E0BB md5 1D5E05159B0AC6A5119BD6F743C7EB9E sha1 F73E5FDA698E102D8CAD610BD601C73F6EC6E51A ) + rom ( name "Simpsons, The - Bart no Jack to Mame no Ki (Japan).gb" size 131072 crc 7aa4e0bb sha1 F73E5FDA698E102D8CAD610BD601C73F6EC6E51A ) ) game ( name "Simpsons, The - Bart vs. the Juggernauts (USA, Europe)" description "Simpsons, The - Bart vs. the Juggernauts (USA, Europe)" - rom ( name "Simpsons, The - Bart vs. the Juggernauts (USA, Europe).gb" size 131072 crc 6819CF0D md5 BC36D55377D7961A49A48A70A2827E5E sha1 95D60B87862FCCD914446E0581146142D19C76BD flags verified ) + rom ( name "Simpsons, The - Bart vs. the Juggernauts (USA, Europe).gb" size 131072 crc 6819cf0d sha1 95D60B87862FCCD914446E0581146142D19C76BD flags verified ) ) game ( name "Skate or Die - Bad 'N Rad (Europe)" description "Skate or Die - Bad 'N Rad (Europe)" - rom ( name "Skate or Die - Bad 'N Rad (Europe).gb" size 131072 crc AC1FB27A md5 FD6BD52147792817CBDDF37C454E8563 sha1 11508D5834EEA7352493D193A097C95E38EC4A55 flags verified ) + rom ( name "Skate or Die - Bad 'N Rad (Europe).gb" size 131072 crc ac1fb27a sha1 11508D5834EEA7352493D193A097C95E38EC4A55 flags verified ) ) game ( name "Skate or Die - Bad 'N Rad (USA)" description "Skate or Die - Bad 'N Rad (USA)" - rom ( name "Skate or Die - Bad 'N Rad (USA).gb" size 131072 crc 4DB7C817 md5 ED7318B615B0A827F3EDCFF0C817CAEA sha1 6A128648584AE17AC6DEE5A2BDBA10B0BB220434 ) + rom ( name "Skate or Die - Bad 'N Rad (USA).gb" size 131072 crc 4db7c817 sha1 6A128648584AE17AC6DEE5A2BDBA10B0BB220434 ) ) game ( name "Skate or Die - Tour de Thrash (USA)" description "Skate or Die - Tour de Thrash (USA)" - rom ( name "Skate or Die - Tour de Thrash (USA).gb" size 131072 crc 02B77C09 md5 F8D92A05C7BE07964824830E9CE3FF30 sha1 6E1610450DA0C836983A1C310524639FEFCC304F ) + rom ( name "Skate or Die - Tour de Thrash (USA).gb" size 131072 crc 02b77c09 sha1 6E1610450DA0C836983A1C310524639FEFCC304F ) ) game ( name "Small Soldiers (USA, Europe) (SGB Enhanced)" description "Small Soldiers (USA, Europe) (SGB Enhanced)" - rom ( name "Small Soldiers (USA, Europe) (SGB Enhanced).gb" size 524288 crc DBF106D1 md5 46B6AE39B3140F81D66BE8338A8BCEA3 sha1 FCE53AED026E3171AC5C26D21D5DBCBBB2C14968 flags verified ) + rom ( name "Small Soldiers (USA, Europe) (SGB Enhanced).gb" size 524288 crc dbf106d1 sha1 FCE53AED026E3171AC5C26D21D5DBCBBB2C14968 flags verified ) ) game ( name "SMARTCOM (Europe) (Unl)" description "SMARTCOM (Europe) (Unl)" - rom ( name "SMARTCOM (Europe) (Unl).gb" size 262144 crc 1EF0ABF1 md5 31ADC9A8F9F1619E736BFC533E4ED2DD sha1 A04BBF813BCD9B7E3AF97D388AD77D25C1403831 ) + rom ( name "SMARTCOM (Europe) (Unl).gb" size 262144 crc 1ef0abf1 sha1 A04BBF813BCD9B7E3AF97D388AD77D25C1403831 ) ) game ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" description "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" - rom ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es).gb" size 262144 crc 8EF938C4 md5 AF46F94B7A05CAF538B7C07B8BB75238 sha1 EFBC4BC9714393D5F493AD653FC1FA2180B40892 flags verified ) + rom ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es).gb" size 262144 crc 8ef938c4 sha1 EFBC4BC9714393D5F493AD653FC1FA2180B40892 flags verified ) ) game ( name "Smurfs Travel the World, The (Europe) (En,Fr,De,Es)" description "Smurfs Travel the World, The (Europe) (En,Fr,De,Es)" - rom ( name "Smurfs Travel the World, The (Europe) (En,Fr,De,Es).gb" size 131072 crc CB2C7198 md5 072E25973DC896758749C55D2698BE88 sha1 E138C3AC1BC2E23091E71CC1AA90788770622458 flags verified ) + rom ( name "Smurfs Travel the World, The (Europe) (En,Fr,De,Es).gb" size 131072 crc cb2c7198 sha1 E138C3AC1BC2E23091E71CC1AA90788770622458 flags verified ) ) game ( name "Smurfs, The (Europe) (En,Fr,De,Es)" description "Smurfs, The (Europe) (En,Fr,De,Es)" - rom ( name "Smurfs, The (Europe) (En,Fr,De,Es).gb" size 131072 crc CDFF161F md5 4528D42EAE39A3FA756EEFA29D52EF55 sha1 9FC50648C18F7F8F0E567BA8791B1D9A43C9F044 flags verified ) + rom ( name "Smurfs, The (Europe) (En,Fr,De,Es).gb" size 131072 crc cdff161f sha1 9FC50648C18F7F8F0E567BA8791B1D9A43C9F044 flags verified ) ) game ( - name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev A) (SGB Enhanced)" - description "Smurfs, The (USA, Europe) (En,Fr,De) (Rev A) (SGB Enhanced)" - rom ( name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev A) (SGB Enhanced).gb" size 131072 crc 8B5BCDE7 md5 A574E5F7119B31E5112221C3A0ADA813 sha1 A0D6A85331FB034F68F05629A5FF85E13ADAB205 flags verified ) + name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced)" + description "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced)" + rom ( name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced).gb" size 131072 crc 8b5bcde7 sha1 A0D6A85331FB034F68F05629A5FF85E13ADAB205 flags verified ) ) game ( name "Sneaky Snakes (USA, Europe)" description "Sneaky Snakes (USA, Europe)" - rom ( name "Sneaky Snakes (USA, Europe).gb" size 131072 crc 7BF40D7D md5 0B5127A54CC8581ACFABE0413378CA3D sha1 9087B44139EA56D85C8ECADB2603A2D599C2A00B flags verified ) + rom ( name "Sneaky Snakes (USA, Europe).gb" size 131072 crc 7bf40d7d sha1 9087B44139EA56D85C8ECADB2603A2D599C2A00B flags verified ) ) game ( name "Snoopy - Magic Show (Japan)" description "Snoopy - Magic Show (Japan)" - rom ( name "Snoopy - Magic Show (Japan).gb" size 65536 crc 4892984D md5 3D8F6ECCC13F3344C8D971B7E141F064 sha1 07BF2DD8C1BEBD40A63FB571C587F0E77286C6A0 flags verified ) -) - -game ( - name "Snoopy - Magic Show (USA, Europe)" - description "Snoopy - Magic Show (USA, Europe)" - rom ( name "Snoopy - Magic Show (USA, Europe).gb" size 65536 crc 2B7A5034 md5 8A06994B2E265244147A4D6D0E80623F sha1 BC21FB3AA1A58E2AEF30FABE103B2E5BEC02B535 flags verified ) + rom ( name "Snoopy - Magic Show (Japan).gb" size 65536 crc 4892984d sha1 07BF2DD8C1BEBD40A63FB571C587F0E77286C6A0 flags verified ) ) game ( name "Snoopy no Hajimete no Otsukai (Japan) (SGB Enhanced)" description "Snoopy no Hajimete no Otsukai (Japan) (SGB Enhanced)" - rom ( name "Snoopy no Hajimete no Otsukai (Japan) (SGB Enhanced).gb" size 131072 crc 8900A7C0 md5 4F597338777CC0B67465BD0DDE285645 sha1 535A85E3955EC58754395A8BF7C4F5B7D319E57F ) + rom ( name "Snoopy no Hajimete no Otsukai (Japan) (SGB Enhanced).gb" size 131072 crc 8900a7c0 sha1 535A85E3955EC58754395A8BF7C4F5B7D319E57F ) ) game ( - name "Snow Bros. Jr. (Europe)" - description "Snow Bros. Jr. (Europe)" - rom ( name "Snow Bros. Jr. (Europe).gb" size 131072 crc 9014B3D8 md5 A94E7294260B4266AF7D0283C95F0018 sha1 FE6754976F6758A91D2594D7CB9781CA0A340A90 ) + name "Snoopy's Magic Show (USA, Europe)" + description "Snoopy's Magic Show (USA, Europe)" + rom ( name "Snoopy's Magic Show (USA, Europe).gb" size 65536 crc 2b7a5034 sha1 BC21FB3AA1A58E2AEF30FABE103B2E5BEC02B535 flags verified ) ) game ( name "Snow Bros. Jr. (Japan)" description "Snow Bros. Jr. (Japan)" - rom ( name "Snow Bros. Jr. (Japan).gb" size 131072 crc E5A22F5A md5 099D768C3541F4CBB6362C914E97F667 sha1 D46E6BB01129F0725E73B6B9ACA35A1ACEB7E415 ) + rom ( name "Snow Bros. Jr. (Japan).gb" size 131072 crc e5a22f5a sha1 D46E6BB01129F0725E73B6B9ACA35A1ACEB7E415 flags verified ) ) game ( - name "Snow Bros. Jr. (USA)" - description "Snow Bros. Jr. (USA)" - rom ( name "Snow Bros. Jr. (USA).gb" size 131072 crc D45A1DAA md5 B4CEE49981C3124DF8BBD40A60426F9E sha1 3798924873D76952810B28925662F9CF805A17CC flags verified ) + name "Snow Brothers (Europe)" + description "Snow Brothers (Europe)" + rom ( name "Snow Brothers (Europe).gb" size 131072 crc 9014b3d8 sha1 FE6754976F6758A91D2594D7CB9781CA0A340A90 flags verified ) ) game ( - name "Soccer (Europe) (En,Fr,De) (SGB Enhanced)" - description "Soccer (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Soccer (Europe) (En,Fr,De) (SGB Enhanced).gb" size 131072 crc C36B199B md5 EFFBAF8C4B83EDFEBBE6451DF0D44FD1 sha1 355FB7F220A0BA470011220282A59E707F168E1A flags verified ) + name "Snow Brothers (USA)" + description "Snow Brothers (USA)" + rom ( name "Snow Brothers (USA).gb" size 131072 crc d45a1daa sha1 3798924873D76952810B28925662F9CF805A17CC flags verified ) +) + +game ( + name "Soccer (Europe, Australia) (En,Fr,De) (SGB Enhanced)" + description "Soccer (Europe, Australia) (En,Fr,De) (SGB Enhanced)" + rom ( name "Soccer (Europe, Australia) (En,Fr,De) (SGB Enhanced).gb" size 131072 crc c36b199b sha1 355FB7F220A0BA470011220282A59E707F168E1A flags verified ) ) game ( name "Soccer (Japan)" description "Soccer (Japan)" - rom ( name "Soccer (Japan).gb" size 131072 crc BE51A876 md5 1F406D44B61098883BBAAFC076E994E9 sha1 F9FD41616185EAD719774ACB2B826C5C7359CDB2 flags verified ) + rom ( name "Soccer (Japan).gb" size 131072 crc be51a876 sha1 F9FD41616185EAD719774ACB2B826C5C7359CDB2 flags verified ) ) game ( name "Soccer Boy (Japan)" description "Soccer Boy (Japan)" - rom ( name "Soccer Boy (Japan).gb" size 65536 crc 23F64E82 md5 8C34E1879B4F81A22515D82AA9D0BB68 sha1 7554B42D1C38508FD615828C96AB58EA8F41DE4D flags verified ) + rom ( name "Soccer Boy (Japan).gb" size 65536 crc 23f64e82 sha1 7554B42D1C38508FD615828C96AB58EA8F41DE4D flags verified ) ) game ( name "Soccer Mania (USA)" description "Soccer Mania (USA)" - rom ( name "Soccer Mania (USA).gb" size 65536 crc 6F87B543 md5 12454FBCB38432E26F280282E7196E73 sha1 6E641FEE2628E98890E579E3AB6574B1757B8D08 ) + rom ( name "Soccer Mania (USA).gb" size 65536 crc 6f87b543 sha1 6E641FEE2628E98890E579E3AB6574B1757B8D08 ) ) game ( name "SolarStriker (World)" description "SolarStriker (World)" - rom ( name "SolarStriker (World).gb" size 65536 crc 11817103 md5 83BED4EBEFEECE45748258FD2EF105B3 sha1 A8D6ACB026B0D0A8A2BCAEA094951E915A3DEB80 flags verified ) + rom ( name "SolarStriker (World).gb" size 65536 crc 11817103 sha1 A8D6ACB026B0D0A8A2BCAEA094951E915A3DEB80 flags verified ) ) game ( name "Soldam (Japan)" description "Soldam (Japan)" - rom ( name "Soldam (Japan).gb" size 131072 crc 7C5AEC86 md5 E64C49A5280DA30ECEABDC3ED3852A88 sha1 B50A35A605BAEFBA743819C2F0F3A494EAEC4E11 ) + rom ( name "Soldam (Japan).gb" size 131072 crc 7c5aec86 sha1 B50A35A605BAEFBA743819C2F0F3A494EAEC4E11 flags verified ) ) game ( name "Solitaire (Japan)" description "Solitaire (Japan)" - rom ( name "Solitaire (Japan).gb" size 65536 crc 1119484A md5 7D908BA84A5FF43A3622A917B07D8B3A sha1 220F5B230559AE0C5742A31C59A90615C7FB8613 flags verified ) + rom ( name "Solitaire (Japan).gb" size 65536 crc 1119484a sha1 220F5B230559AE0C5742A31C59A90615C7FB8613 flags verified ) ) game ( name "Solitaire FunPak (USA, Europe)" description "Solitaire FunPak (USA, Europe)" - rom ( name "Solitaire FunPak (USA, Europe).gb" size 131072 crc 35A5234A md5 78DA1015CA2B5B4E83F7AEA41214E779 sha1 185B95313D437B9E4BED2D10A346D16C4640325C flags verified ) + rom ( name "Solitaire FunPak (USA, Europe).gb" size 131072 crc 35a5234a sha1 185B95313D437B9E4BED2D10A346D16C4640325C flags verified ) ) game ( name "Solomon's Club (Europe)" description "Solomon's Club (Europe)" - rom ( name "Solomon's Club (Europe).gb" size 65536 crc 701CCDB3 md5 45AE101994D2DFB0CEC87E8A97E2B5A8 sha1 9E4A1C2608DA3E245FE3C35C8A9F626C1BD6152E flags verified ) + rom ( name "Solomon's Club (Europe).gb" size 65536 crc 701ccdb3 sha1 9E4A1C2608DA3E245FE3C35C8A9F626C1BD6152E flags verified ) ) game ( name "Solomon's Club (Japan)" description "Solomon's Club (Japan)" - rom ( name "Solomon's Club (Japan).gb" size 65536 crc 901BFF2E md5 CC5FE746D5E216B4A1048453B2068A5D sha1 DC60824A69856A162AEE6F7FA86BD2D283FADD32 flags verified ) + rom ( name "Solomon's Club (Japan).gb" size 65536 crc 901bff2e sha1 DC60824A69856A162AEE6F7FA86BD2D283FADD32 flags verified ) ) game ( name "Solomon's Club (USA)" description "Solomon's Club (USA)" - rom ( name "Solomon's Club (USA).gb" size 65536 crc CEA9622A md5 8A5CCF172F31A0DBFA0600D40B388FDC sha1 36ABF2BE4A16DF8E9FE30307CBD8CB949A9B9BDB ) + rom ( name "Solomon's Club (USA).gb" size 65536 crc cea9622a sha1 36ABF2BE4A16DF8E9FE30307CBD8CB949A9B9BDB ) ) game ( name "Soreyuke! Speedy Gonzales (Japan)" description "Soreyuke! Speedy Gonzales (Japan)" - rom ( name "Soreyuke! Speedy Gonzales (Japan).gb" size 262144 crc B2E6A1C5 md5 F8ADC92B72483F92A40EBE0DF7117907 sha1 306B85BEC28FA6E4A47F9CCAA5384AFD8547C7EA ) + rom ( name "Soreyuke! Speedy Gonzales (Japan).gb" size 262144 crc b2e6a1c5 sha1 306B85BEC28FA6E4A47F9CCAA5384AFD8547C7EA ) ) game ( name "Soreyuke!! Kid (Japan)" description "Soreyuke!! Kid (Japan)" - rom ( name "Soreyuke!! Kid (Japan).gb" size 131072 crc 2A4A2D2B md5 C07063729944FFC4459E006E862DF061 sha1 B3B46D61C49A22145CE57B881D355B86D5C5ECC1 ) + rom ( name "Soreyuke!! Kid (Japan).gb" size 131072 crc 2a4a2d2b sha1 B3B46D61C49A22145CE57B881D355B86D5C5ECC1 ) ) game ( name "Soukoban (Japan)" description "Soukoban (Japan)" - rom ( name "Soukoban (Japan).gb" size 32768 crc D50D6D0A md5 2FC9BE5FA50CFA9C660A2CEAA55344AE sha1 AA0CFCB8E049533BC4AE9AFE4E97F5336425D5A7 flags verified ) + rom ( name "Soukoban (Japan).gb" size 32768 crc d50d6d0a sha1 AA0CFCB8E049533BC4AE9AFE4E97F5336425D5A7 flags verified ) ) game ( name "Soukoban 2 (Japan)" description "Soukoban 2 (Japan)" - rom ( name "Soukoban 2 (Japan).gb" size 32768 crc D9DA6741 md5 7F1E1CE56ACA694B46DA2BA407B60CB3 sha1 211221BD34B3AE86CE5D647A81CAAB8BB91BFA71 flags verified ) + rom ( name "Soukoban 2 (Japan).gb" size 32768 crc d9da6741 sha1 211221BD34B3AE86CE5D647A81CAAB8BB91BFA71 flags verified ) ) game ( name "Space Invaders (Europe) (SGB Enhanced)" description "Space Invaders (Europe) (SGB Enhanced)" - rom ( name "Space Invaders (Europe) (SGB Enhanced).gb" size 524288 crc 891B8F04 md5 704CEFB5C77DC74631B9ACBAA2B19435 sha1 6395CA055DE6B6538B915D0CB69BD829D7AA2E2A flags verified ) + rom ( name "Space Invaders (Europe) (SGB Enhanced).gb" size 524288 crc 891b8f04 sha1 6395CA055DE6B6538B915D0CB69BD829D7AA2E2A flags verified ) ) game ( name "Space Invaders (Japan)" description "Space Invaders (Japan)" - rom ( name "Space Invaders (Japan).gb" size 32768 crc 868B57B2 md5 7C1AB6FE16BCF564C7F8E13E40F2B87D sha1 9E94553ECB76E95EB85A5F8FBBB201B96271710A flags verified ) + rom ( name "Space Invaders (Japan).gb" size 32768 crc 868b57b2 sha1 9E94553ECB76E95EB85A5F8FBBB201B96271710A flags verified ) ) game ( name "Space Invaders (USA) (SGB Enhanced)" description "Space Invaders (USA) (SGB Enhanced)" - rom ( name "Space Invaders (USA) (SGB Enhanced).gb" size 524288 crc 7F0F5762 md5 D32B9DA8028D357E20C791B07DED4F86 sha1 DA48687F3A5EE547510A0EA9EB05859B4EA9531D ) + rom ( name "Space Invaders (USA) (SGB Enhanced).gb" size 524288 crc 7f0f5762 sha1 DA48687F3A5EE547510A0EA9EB05859B4EA9531D ) ) game ( name "Spanky's Quest (Europe)" description "Spanky's Quest (Europe)" - rom ( name "Spanky's Quest (Europe).gb" size 65536 crc E9EF8136 md5 9B66B6CFA9BDB791709B3A30722C7DFF sha1 7708270675979F25453E680BC8A6D45B5929AFA8 flags verified ) + rom ( name "Spanky's Quest (Europe).gb" size 65536 crc e9ef8136 sha1 7708270675979F25453E680BC8A6D45B5929AFA8 flags verified ) ) game ( name "Spanky's Quest (USA)" description "Spanky's Quest (USA)" - rom ( name "Spanky's Quest (USA).gb" size 65536 crc 6EE7CA79 md5 3C268409BF6869A8707839A7DD1EE1C7 sha1 8F448EAB7E6A05266D62F3564A00813F79314736 ) + rom ( name "Spanky's Quest (USA).gb" size 65536 crc 6ee7ca79 sha1 8F448EAB7E6A05266D62F3564A00813F79314736 ) ) game ( name "Spartan X (Japan)" description "Spartan X (Japan)" - rom ( name "Spartan X (Japan).gb" size 65536 crc CA7B4229 md5 83F05D3FF8DA7E340A75D8E1234D8834 sha1 E2319966EA5EBB99DB6F6178BB927DC1C7F734B2 flags verified ) + rom ( name "Spartan X (Japan).gb" size 65536 crc ca7b4229 sha1 E2319966EA5EBB99DB6F6178BB927DC1C7F734B2 flags verified ) ) game ( name "Speedball 2 - Brutal Deluxe (USA, Europe)" description "Speedball 2 - Brutal Deluxe (USA, Europe)" - rom ( name "Speedball 2 - Brutal Deluxe (USA, Europe).gb" size 131072 crc FD06E22D md5 D7FB01DEC29A52DE74E5B335B8619E0A sha1 9EC7EF7F362CDA3C28A727D2D8A8458FFD80CDA0 flags verified ) + rom ( name "Speedball 2 - Brutal Deluxe (USA, Europe).gb" size 131072 crc fd06e22d sha1 9EC7EF7F362CDA3C28A727D2D8A8458FFD80CDA0 flags verified ) ) game ( name "Speedy Gonzales (USA, Europe)" description "Speedy Gonzales (USA, Europe)" - rom ( name "Speedy Gonzales (USA, Europe).gb" size 262144 crc 27CDE8D6 md5 7E1BEDF88581EE7370C8EB86C6863E2C sha1 805BE36B4701DDA53B967C0153B9BFCC2C059F75 flags verified ) + rom ( name "Speedy Gonzales (USA, Europe).gb" size 262144 crc 27cde8d6 sha1 805BE36B4701DDA53B967C0153B9BFCC2C059F75 flags verified ) ) game ( - name "Spider-Man - X-Men (USA, Europe)" - description "Spider-Man - X-Men (USA, Europe)" - rom ( name "Spider-Man - X-Men (USA, Europe).gb" size 131072 crc 1009C6C0 md5 634532DE88AA7C35BD9231EE5356AE8A sha1 FB3770E2DA5C668D23E5F96A4806A6D3DB24EAEB flags verified ) + name "Spider-Man - X-Men - Arcade's Revenge (USA, Europe)" + description "Spider-Man - X-Men - Arcade's Revenge (USA, Europe)" + rom ( name "Spider-Man - X-Men - Arcade's Revenge (USA, Europe).gb" size 131072 crc 1009c6c0 sha1 FB3770E2DA5C668D23E5F96A4806A6D3DB24EAEB flags verified ) ) game ( name "Spider-Man 2 (USA, Europe)" description "Spider-Man 2 (USA, Europe)" - rom ( name "Spider-Man 2 (USA, Europe).gb" size 131072 crc 13DD233F md5 506CCD75DB221ACBF26F1681F3C97EFD sha1 9D85634232053A52B8D3BBCA0F613337FCAB32A8 flags verified ) + rom ( name "Spider-Man 2 (USA, Europe).gb" size 131072 crc 13dd233f sha1 9D85634232053A52B8D3BBCA0F613337FCAB32A8 flags verified ) ) game ( name "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe)" description "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe)" - rom ( name "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe).gb" size 131072 crc CBB2F22C md5 8833AE0FD3B4C47B8249A12708C98A98 sha1 D9687896481316D873046DACA43CC0E259C32929 flags verified ) + rom ( name "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe).gb" size 131072 crc cbb2f22c sha1 D9687896481316D873046DACA43CC0E259C32929 flags verified ) ) game ( name "Spirit of F-1, The (Europe)" description "Spirit of F-1, The (Europe)" - rom ( name "Spirit of F-1, The (Europe).gb" size 131072 crc 2B795480 md5 B5A41149D31B00FAE3460C5B89C6755B sha1 A777C399BB4B8D3E55EE0E8B29890E20B859D5E4 ) + rom ( name "Spirit of F-1, The (Europe).gb" size 131072 crc 2b795480 sha1 A777C399BB4B8D3E55EE0E8B29890E20B859D5E4 flags verified ) ) game ( name "Spiritual Warfare (USA) (Unl)" description "Spiritual Warfare (USA) (Unl)" - rom ( name "Spiritual Warfare (USA) (Unl).gb" size 262144 crc F7A961BA md5 37E017C8D1A45BAB609FB5B43FB64337 sha1 6E6AE5DBD8FF8B8F41B8411EF119E96E4ECF763F ) + rom ( name "Spiritual Warfare (USA) (Unl).gb" size 262144 crc f7a961ba sha1 6E6AE5DBD8FF8B8F41B8411EF119E96E4ECF763F flags verified ) ) game ( name "Spirou (Europe) (En,Fr,De,Es) (SGB Enhanced)" description "Spirou (Europe) (En,Fr,De,Es) (SGB Enhanced)" - rom ( name "Spirou (Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 262144 crc 735B29E2 md5 5AA012CF540A5267D6ADEA6659764441 sha1 5EEF57753B7FAAE2B9710E38BE30662B0B77383A flags verified ) + rom ( name "Spirou (Europe) (En,Fr,De,Es) (SGB Enhanced).gb" size 262144 crc 735b29e2 sha1 5EEF57753B7FAAE2B9710E38BE30662B0B77383A flags verified ) ) game ( name "Spirou (Europe) (En,Fr,De,Es) (Beta) (SGB Enhanced)" description "Spirou (Europe) (En,Fr,De,Es) (Beta) (SGB Enhanced)" - rom ( name "Spirou (Europe) (En,Fr,De,Es) (Beta) (SGB Enhanced).gb" size 262144 crc 35415A00 md5 378236DF6A7C686DFAA6743B63D1F757 sha1 556641FC79700C5CCB4F8FEAEC1D7FAFE99C31C4 ) + rom ( name "Spirou (Europe) (En,Fr,De,Es) (Beta) (SGB Enhanced).gb" size 262144 crc 35415a00 sha1 556641FC79700C5CCB4F8FEAEC1D7FAFE99C31C4 ) ) game ( name "Splitz (Europe)" description "Splitz (Europe)" - rom ( name "Splitz (Europe).gb" size 65536 crc 112487C9 md5 9ECB13A68C8C58D90DD15157440D5B10 sha1 27A8C04BF7126D2B9F564B5F8F709C08817D9692 flags verified ) + rom ( name "Splitz (Europe).gb" size 65536 crc 112487c9 sha1 27A8C04BF7126D2B9F564B5F8F709C08817D9692 flags verified ) ) game ( name "Splitz - Nigaoe 15 Game (Japan)" description "Splitz - Nigaoe 15 Game (Japan)" - rom ( name "Splitz - Nigaoe 15 Game (Japan).gb" size 65536 crc B07A2745 md5 59E6F8F432D4C0B99A3FB6432A2CDAD7 sha1 C71D031DA8206798A56BEAE6A90F143174A76947 ) + rom ( name "Splitz - Nigaoe 15 Game (Japan).gb" size 65536 crc b07a2745 sha1 C71D031DA8206798A56BEAE6A90F143174A76947 flags verified ) ) game ( name "Sports Collection (Japan)" description "Sports Collection (Japan)" - rom ( name "Sports Collection (Japan).gb" size 524288 crc 24DD09E0 md5 FE0AC40641BC533A4A011898C0C15139 sha1 23C51363B64BD7CE2F2581E1FE9C5368FD8D8AFB ) + rom ( name "Sports Collection (Japan).gb" size 524288 crc 24dd09e0 sha1 23C51363B64BD7CE2F2581E1FE9C5368FD8D8AFB ) ) game ( - name "Sports Illustrated - Football & Baseball (USA)" - description "Sports Illustrated - Football & Baseball (USA)" - rom ( name "Sports Illustrated - Football & Baseball (USA).gb" size 524288 crc 235171C4 md5 56C494CD7737F51EE2C3AEB50406E51A sha1 AB8272544D97B97D48420649070A927E6A0D2AC7 ) + name "Sports Illustrated - Championship Football & Baseball (USA)" + description "Sports Illustrated - Championship Football & Baseball (USA)" + rom ( name "Sports Illustrated - Championship Football & Baseball (USA).gb" size 524288 crc 235171c4 sha1 AB8272544D97B97D48420649070A927E6A0D2AC7 ) ) game ( name "Sports Illustrated - Golf Classic (USA) (SGB Enhanced)" description "Sports Illustrated - Golf Classic (USA) (SGB Enhanced)" - rom ( name "Sports Illustrated - Golf Classic (USA) (SGB Enhanced).gb" size 262144 crc 87B306B4 md5 531A63F17EBD140ED15B382C0C13EEBB sha1 39761CFEDCFE4E5CF161F58A91F5FD364FC3DDB9 flags verified ) + rom ( name "Sports Illustrated - Golf Classic (USA) (SGB Enhanced).gb" size 262144 crc 87b306b4 sha1 39761CFEDCFE4E5CF161F58A91F5FD364FC3DDB9 flags verified ) ) game ( name "Sports Illustrated for Kids - The Ultimate Triple Dare! (USA)" description "Sports Illustrated for Kids - The Ultimate Triple Dare! (USA)" - rom ( name "Sports Illustrated for Kids - The Ultimate Triple Dare! (USA).gb" size 262144 crc F0D76D49 md5 6E20CFAC9F66AB55BFB5E7524EF4C144 sha1 170A9B400E7DB3270883DBB58704FC141053FAA9 ) -) - -game ( - name "Spot (Europe)" - description "Spot (Europe)" - rom ( name "Spot (Europe).gb" size 32768 crc 04E241E4 md5 41E5A302C648373565F7FDE4CA7E4FF9 sha1 10577304FAE59B9C5D8B72BBF710BA97EF85AC90 ) + rom ( name "Sports Illustrated for Kids - The Ultimate Triple Dare! (USA).gb" size 262144 crc f0d76d49 sha1 170A9B400E7DB3270883DBB58704FC141053FAA9 ) ) game ( name "Spot (Japan)" description "Spot (Japan)" - rom ( name "Spot (Japan).gb" size 32768 crc 2CA58280 md5 43F73771D3141A522C5C6C8617042D6F sha1 A14CF8C28E8BCC573B7ED6543CB40D6B1467FA6B ) + rom ( name "Spot (Japan).gb" size 32768 crc 2ca58280 sha1 A14CF8C28E8BCC573B7ED6543CB40D6B1467FA6B ) ) game ( - name "Spot (USA)" - description "Spot (USA)" - rom ( name "Spot (USA).gb" size 32768 crc FCD61B98 md5 2524230D0300F46EBF423AE1B37747EB sha1 1A1AE34A3EC668D9A69C9C851C0291752DC63238 flags verified ) -) - -game ( - name "Spot - The Cool Adventure (Japan)" - description "Spot - The Cool Adventure (Japan)" - rom ( name "Spot - The Cool Adventure (Japan).gb" size 131072 crc 552A53B9 md5 5D1D8FEF74CA8A35E1B09705AB3DF3D8 sha1 075512A3AF4BC7C2DA2D51D84DF2D04C81B2A8AD ) + name "Spot - Cool Adventure (Japan)" + description "Spot - Cool Adventure (Japan)" + rom ( name "Spot - Cool Adventure (Japan).gb" size 131072 crc 552a53b9 sha1 075512A3AF4BC7C2DA2D51D84DF2D04C81B2A8AD ) ) game ( name "Spot - The Cool Adventure (USA)" description "Spot - The Cool Adventure (USA)" - rom ( name "Spot - The Cool Adventure (USA).gb" size 131072 crc 76F67428 md5 58E1CD396548B0E57B0514D8BEC066D9 sha1 BCC923E6E73EFE7E865625BB6ECF2EF08E380826 ) + rom ( name "Spot - The Cool Adventure (USA).gb" size 131072 crc 76f67428 sha1 BCC923E6E73EFE7E865625BB6ECF2EF08E380826 flags verified ) +) + +game ( + name "Spot - The Video Game (Europe)" + description "Spot - The Video Game (Europe)" + rom ( name "Spot - The Video Game (Europe).gb" size 32768 crc 04e241e4 sha1 10577304FAE59B9C5D8B72BBF710BA97EF85AC90 flags verified ) +) + +game ( + name "Spot - The Video Game (USA)" + description "Spot - The Video Game (USA)" + rom ( name "Spot - The Video Game (USA).gb" size 32768 crc fcd61b98 sha1 1A1AE34A3EC668D9A69C9C851C0291752DC63238 flags verified ) ) game ( name "Spud's Adventure (USA)" description "Spud's Adventure (USA)" - rom ( name "Spud's Adventure (USA).gb" size 65536 crc 70E5ED99 md5 C9E8C196D57AAB17C4C171816FCD6492 sha1 556F6BF41D671A80B0B71D5897C4D8A6FFC7B5B1 ) + rom ( name "Spud's Adventure (USA).gb" size 65536 crc 70e5ed99 sha1 556F6BF41D671A80B0B71D5897C4D8A6FFC7B5B1 ) ) game ( name "Spy vs Spy - Operation Boobytrap (Europe)" description "Spy vs Spy - Operation Boobytrap (Europe)" - rom ( name "Spy vs Spy - Operation Boobytrap (Europe).gb" size 131072 crc 36645203 md5 4F1B689127635CEBE5145926E0E24FBB sha1 F3405AB4E07570DB790850C928A2D338478B93FF flags verified ) + rom ( name "Spy vs Spy - Operation Boobytrap (Europe).gb" size 131072 crc 36645203 sha1 F3405AB4E07570DB790850C928A2D338478B93FF flags verified ) ) game ( name "Spy vs Spy - Operation Boobytrap (USA)" description "Spy vs Spy - Operation Boobytrap (USA)" - rom ( name "Spy vs Spy - Operation Boobytrap (USA).gb" size 131072 crc 6D40E5A2 md5 00408B7C09C99B8EA15B8EBB66E69130 sha1 1A84BB71A8E655F9741F825D515CB9CE02CFAB9A ) + rom ( name "Spy vs Spy - Operation Boobytrap (USA).gb" size 131072 crc 6d40e5a2 sha1 1A84BB71A8E655F9741F825D515CB9CE02CFAB9A ) ) game ( name "Square Deal - The Game of Two-Dimensional Poker (USA)" description "Square Deal - The Game of Two-Dimensional Poker (USA)" - rom ( name "Square Deal - The Game of Two-Dimensional Poker (USA).gb" size 65536 crc 8B882745 md5 C9CE9D01B622EFCE61CD4F002C628203 sha1 ACE72E1D6607B162BDAA88499DB9828444ECD2C0 flags verified ) -) - -game ( - name "Star Hawk (Europe)" - description "Star Hawk (Europe)" - rom ( name "Star Hawk (Europe).gb" size 131072 crc E032E502 md5 C284B8A9019020336C89B680FB6552E4 sha1 4C22E06CB98119923126F6500568CE9F136A33C5 flags verified ) + rom ( name "Square Deal - The Game of Two-Dimensional Poker (USA).gb" size 65536 crc 8b882745 sha1 ACE72E1D6607B162BDAA88499DB9828444ECD2C0 flags verified ) ) game ( name "Star Sweep (Japan) (SGB Enhanced)" description "Star Sweep (Japan) (SGB Enhanced)" - rom ( name "Star Sweep (Japan) (SGB Enhanced).gb" size 262144 crc D6FD967C md5 05C256D964E31BD02A23F27E812CFD78 sha1 CAABAA2E9CBAB27859DB80EF6B0E90E7B94B3BD0 flags verified ) + rom ( name "Star Sweep (Japan) (SGB Enhanced).gb" size 262144 crc d6fd967c sha1 CAABAA2E9CBAB27859DB80EF6B0E90E7B94B3BD0 flags verified ) ) game ( name "Star Trek - 25th Anniversary (USA, Europe)" description "Star Trek - 25th Anniversary (USA, Europe)" - rom ( name "Star Trek - 25th Anniversary (USA, Europe).gb" size 131072 crc 605DE43A md5 E1B8B8158C54DF9188D54C4D5331E53D sha1 BCA2E328FE76D877F09251F2EFD5438116F0648C flags verified ) + rom ( name "Star Trek - 25th Anniversary (USA, Europe).gb" size 131072 crc 605de43a sha1 BCA2E328FE76D877F09251F2EFD5438116F0648C flags verified ) ) game ( name "Star Trek - The Next Generation (Germany)" description "Star Trek - The Next Generation (Germany)" - rom ( name "Star Trek - The Next Generation (Germany).gb" size 131072 crc 129616B3 md5 4D949294F3CDA07F2D12E5F73E6CAEAA sha1 1B89DB710C22C563C764B667C3897D817B05F18A flags verified ) + rom ( name "Star Trek - The Next Generation (Germany).gb" size 131072 crc 129616b3 sha1 1B89DB710C22C563C764B667C3897D817B05F18A flags verified ) ) game ( name "Star Trek - The Next Generation (Spain)" description "Star Trek - The Next Generation (Spain)" - rom ( name "Star Trek - The Next Generation (Spain).gb" size 131072 crc 4FDED9C4 md5 0D7CA0B0355F8EDDC2846EAA8DAC218C sha1 890ED0AA9453FD1A38EEFE77F761155382471A56 flags verified ) + rom ( name "Star Trek - The Next Generation (Spain).gb" size 131072 crc 4fded9c4 sha1 890ED0AA9453FD1A38EEFE77F761155382471A56 flags verified ) ) game ( name "Star Trek - The Next Generation (USA, Europe)" description "Star Trek - The Next Generation (USA, Europe)" - rom ( name "Star Trek - The Next Generation (USA, Europe).gb" size 131072 crc 3A5A56CB md5 C9791E6CD453AEEF19C722924521D381 sha1 8A50EB7863BF6ABF329F218AEA8BBD354A1BD970 flags verified ) + rom ( name "Star Trek - The Next Generation (USA, Europe).gb" size 131072 crc 3a5a56cb sha1 8A50EB7863BF6ABF329F218AEA8BBD354A1BD970 flags verified ) ) game ( name "Star Trek Generations - Beyond the Nexus (Europe) (SGB Enhanced)" description "Star Trek Generations - Beyond the Nexus (Europe) (SGB Enhanced)" - rom ( name "Star Trek Generations - Beyond the Nexus (Europe) (SGB Enhanced).gb" size 131072 crc D925D15D md5 1897E54CA0AF5F6C83FDB92AE6D02E2F sha1 47AF2970D4FEADA0B59DB59AF6130B1999BB5F3F flags verified ) + rom ( name "Star Trek Generations - Beyond the Nexus (Europe) (SGB Enhanced).gb" size 131072 crc d925d15d sha1 47AF2970D4FEADA0B59DB59AF6130B1999BB5F3F flags verified ) ) game ( name "Star Trek Generations - Beyond the Nexus (USA) (SGB Enhanced)" description "Star Trek Generations - Beyond the Nexus (USA) (SGB Enhanced)" - rom ( name "Star Trek Generations - Beyond the Nexus (USA) (SGB Enhanced).gb" size 131072 crc 9F2D11C6 md5 ECA9FE803D60FF7F1B8A740A1ACCC63B sha1 86A97AD95738BBCBBE94FC9911D6FD6A92A7A636 ) + rom ( name "Star Trek Generations - Beyond the Nexus (USA) (SGB Enhanced).gb" size 131072 crc 9f2d11c6 sha1 86A97AD95738BBCBBE94FC9911D6FD6A92A7A636 ) ) game ( name "Star Wars (Europe)" description "Star Wars (Europe)" - rom ( name "Star Wars (Europe).gb" size 131072 crc 7E3F6BBE md5 8A874449C207AF6E4726337CA899E35A sha1 3A6028708D9FB23A27104201FA8725A5DFB3B161 ) + rom ( name "Star Wars (Europe).gb" size 131072 crc 7e3f6bbe sha1 3A6028708D9FB23A27104201FA8725A5DFB3B161 flags verified ) ) game ( name "Star Wars (USA)" description "Star Wars (USA)" - rom ( name "Star Wars (USA).gb" size 131072 crc B01DA1AE md5 63098FDE8F2DCB977C9A8F0389E0D033 sha1 82C4114312EFDC86C578E8683941A950FC2BB4C3 flags verified ) + rom ( name "Star Wars (USA).gb" size 131072 crc b01da1ae sha1 82C4114312EFDC86C578E8683941A950FC2BB4C3 flags verified ) ) game ( - name "Star Wars (USA, Europe) (Rev A)" - description "Star Wars (USA, Europe) (Rev A)" - rom ( name "Star Wars (USA, Europe) (Rev A).gb" size 131072 crc 5D8DEB5B md5 CB1DCE08C78C509A876C494D6333F45C sha1 F6563F526FC786C8666D75DFBA9E6D42D787EA89 flags verified ) + name "Star Wars (USA, Europe) (Rev 1)" + description "Star Wars (USA, Europe) (Rev 1)" + rom ( name "Star Wars (USA, Europe) (Rev 1).gb" size 131072 crc 5d8deb5b sha1 F6563F526FC786C8666D75DFBA9E6D42D787EA89 flags verified ) ) game ( - name "Star Wars - The Empire Strikes Back (Europe)" - description "Star Wars - The Empire Strikes Back (Europe)" - rom ( name "Star Wars - The Empire Strikes Back (Europe).gb" size 131072 crc 240C589D md5 5664CDC54D539374C8D318C6DA06969E sha1 C8458C870E6AC535AAFF6BF97EC47FB3CB0DAA8A flags verified ) + name "Star Wars - The Empire Strikes Back (USA, Europe)" + description "Star Wars - The Empire Strikes Back (USA, Europe)" + rom ( name "Star Wars - The Empire Strikes Back (USA, Europe).gb" size 131072 crc 240c589d sha1 C8458C870E6AC535AAFF6BF97EC47FB3CB0DAA8A flags verified ) ) game ( name "Star Wars - The Empire Strikes Back (USA)" description "Star Wars - The Empire Strikes Back (USA)" - rom ( name "Star Wars - The Empire Strikes Back (USA).gb" size 131072 crc A0FFF8E7 md5 05F7B63C25B4871440968FD4CE25440A sha1 9CA1D6D479F5A3BEB32F2461637B489F245323FF ) + rom ( name "Star Wars - The Empire Strikes Back (USA).gb" size 131072 crc a0fff8e7 sha1 9CA1D6D479F5A3BEB32F2461637B489F245323FF flags verified ) ) game ( name "Stargate (USA, Europe)" description "Stargate (USA, Europe)" - rom ( name "Stargate (USA, Europe).gb" size 131072 crc 4789295C md5 04BDE16BEDA3F9D7CEC4509A04A75946 sha1 3D2D65252FD57DC1D96C234A436FA377A769C708 flags verified ) + rom ( name "Stargate (USA, Europe).gb" size 131072 crc 4789295c sha1 3D2D65252FD57DC1D96C234A436FA377A769C708 flags verified ) +) + +game ( + name "StarHawk (Europe)" + description "StarHawk (Europe)" + rom ( name "StarHawk (Europe).gb" size 131072 crc e032e502 sha1 4C22E06CB98119923126F6500568CE9F136A33C5 flags verified ) ) game ( name "Stop That Roach! (USA)" description "Stop That Roach! (USA)" - rom ( name "Stop That Roach! (USA).gb" size 131072 crc 86107477 md5 1A316519500424AE9A2649746C4C83AB sha1 B7265343BD77F966B31F871FD471559266E5FC82 flags verified ) + rom ( name "Stop That Roach! (USA).gb" size 131072 crc 86107477 sha1 B7265343BD77F966B31F871FD471559266E5FC82 flags verified ) ) game ( name "Street Fighter II (Japan) (SGB Enhanced)" description "Street Fighter II (Japan) (SGB Enhanced)" - rom ( name "Street Fighter II (Japan) (SGB Enhanced).gb" size 524288 crc C775F488 md5 C87119B643FF4DE3E2614FF10BD0C6EA sha1 52FDAC69097E9323AB867E0139E860B9AD55D500 ) + rom ( name "Street Fighter II (Japan) (SGB Enhanced).gb" size 524288 crc c775f488 sha1 52FDAC69097E9323AB867E0139E860B9AD55D500 ) ) game ( - name "Street Fighter II (USA, Europe) (Rev A) (SGB Enhanced)" - description "Street Fighter II (USA, Europe) (Rev A) (SGB Enhanced)" - rom ( name "Street Fighter II (USA, Europe) (Rev A) (SGB Enhanced).gb" size 524288 crc 54A0AAA3 md5 2CF83DF10495AD163C88698C6C44F1EF sha1 3B6ECF34043C0BCF2AC279EAF30B9D1B0D941E91 flags verified ) + name "Street Fighter II (USA, Europe) (Rev 1) (SGB Enhanced)" + description "Street Fighter II (USA, Europe) (Rev 1) (SGB Enhanced)" + rom ( name "Street Fighter II (USA, Europe) (Rev 1) (SGB Enhanced).gb" size 524288 crc 54a0aaa3 sha1 3B6ECF34043C0BCF2AC279EAF30B9D1B0D941E91 flags verified ) ) game ( name "Street Fighter II (USA) (SGB Enhanced)" description "Street Fighter II (USA) (SGB Enhanced)" - serial "DMG-ASFE-USA" - rom ( name "Street Fighter II (USA) (SGB Enhanced).gb" size 524288 crc 0B29830A md5 DC3EF8D3FAD26CBA840327CC428CADBC sha1 05711638648654E75CA6A563411DAEC3251C2EF0 ) + rom ( name "Street Fighter II (USA) (SGB Enhanced).gb" size 524288 crc 0b29830a sha1 05711638648654E75CA6A563411DAEC3251C2EF0 flags verified ) ) game ( name "Street Racer (Japan)" description "Street Racer (Japan)" - rom ( name "Street Racer (Japan).gb" size 131072 crc 5BBACAA8 md5 4EA0A34A76DA9ED232D514987BA89D90 sha1 2E5E0610A7C535980B6A185CAB83248F6D6096B3 flags verified ) + rom ( name "Street Racer (Japan).gb" size 131072 crc 5bbacaa8 sha1 2E5E0610A7C535980B6A185CAB83248F6D6096B3 flags verified ) ) game ( name "Street Racer (USA, Europe)" description "Street Racer (USA, Europe)" - rom ( name "Street Racer (USA, Europe).gb" size 131072 crc FCFB4CE4 md5 0BF2F0FE9537A2A6B6F8F2E037CB66B7 sha1 4E1D17772EB939CB0A3BCE73E4378384D96836CE flags verified ) + rom ( name "Street Racer (USA, Europe).gb" size 131072 crc fcfb4ce4 sha1 4E1D17772EB939CB0A3BCE73E4378384D96836CE flags verified ) ) game ( name "Sumo Fighter (USA)" description "Sumo Fighter (USA)" - rom ( name "Sumo Fighter (USA).gb" size 131072 crc BADC7CEE md5 E76FB477EF0E8163E83F9FAC15FFF7E9 sha1 48F225F86985D5FB09877E028BAAD8A6F3EE8D95 flags verified ) + rom ( name "Sumo Fighter (USA).gb" size 131072 crc badc7cee sha1 48F225F86985D5FB09877E028BAAD8A6F3EE8D95 flags verified ) ) game ( name "Sumou Fighter - Toukaidou Basho (Japan)" description "Sumou Fighter - Toukaidou Basho (Japan)" - rom ( name "Sumou Fighter - Toukaidou Basho (Japan).gb" size 131072 crc A6905FB2 md5 173896FB9F93FB39ED87A58981E82E36 sha1 DE575DF6A3752FE3A2013A752054B7B76975E367 flags verified ) + rom ( name "Sumou Fighter - Toukaidou Basho (Japan).gb" size 131072 crc a6905fb2 sha1 DE575DF6A3752FE3A2013A752054B7B76975E367 flags verified ) ) game ( name "Sunsoft Grand Prix (Europe)" description "Sunsoft Grand Prix (Europe)" - rom ( name "Sunsoft Grand Prix (Europe).gb" size 65536 crc 8C5DEE4D md5 24D19F1069AC583462713060DF18A753 sha1 EA2445E062C535F8D8A3129D7016F5E8A7AC82CF flags verified ) + rom ( name "Sunsoft Grand Prix (Europe).gb" size 65536 crc 8c5dee4d sha1 EA2445E062C535F8D8A3129D7016F5E8A7AC82CF flags verified ) ) game ( name "Super B-Daman - Fighting Phoenix (Japan) (SGB Enhanced)" description "Super B-Daman - Fighting Phoenix (Japan) (SGB Enhanced)" - rom ( name "Super B-Daman - Fighting Phoenix (Japan) (SGB Enhanced).gb" size 524288 crc 239711EC md5 C6ADF7C0B2A3EA59FA6E59BCF7F1DC4A sha1 36EAC648D0406C84D6708695F30BC8739D1BC648 flags verified ) + rom ( name "Super B-Daman - Fighting Phoenix (Japan) (SGB Enhanced).gb" size 524288 crc 239711ec sha1 36EAC648D0406C84D6708695F30BC8739D1BC648 flags verified ) ) game ( name "Super Battletank (Europe)" description "Super Battletank (Europe)" - rom ( name "Super Battletank (Europe).gb" size 131072 crc 31A227ED md5 FCC37BC406EEF113B046F564A9D2A449 sha1 4931B578626ABF8FD2E7B6E344234E7E688A1406 ) + rom ( name "Super Battletank (Europe).gb" size 131072 crc 31a227ed sha1 4931B578626ABF8FD2E7B6E344234E7E688A1406 ) ) game ( - name "Super Battletank - War in the Gulf (USA)" - description "Super Battletank - War in the Gulf (USA)" - rom ( name "Super Battletank - War in the Gulf (USA).gb" size 131072 crc DA27E798 md5 85B010930CCBB4A7E1BD2ADAADCF00A5 sha1 7AD8CB997676B30BEFDEBB7FAE2A341D3712CEF1 ) + name "Super Battletank (USA)" + description "Super Battletank (USA)" + rom ( name "Super Battletank (USA).gb" size 131072 crc da27e798 sha1 7AD8CB997676B30BEFDEBB7FAE2A341D3712CEF1 flags verified ) ) game ( name "Super Bikkuriman - Densetsu no Sekiban (Japan)" description "Super Bikkuriman - Densetsu no Sekiban (Japan)" - rom ( name "Super Bikkuriman - Densetsu no Sekiban (Japan).gb" size 262144 crc C1E1A041 md5 42F06D0E5FA65BF245F52249385B94A6 sha1 B7DAC857947FCE1069145A1F5D560C26AA3C8F42 ) + rom ( name "Super Bikkuriman - Densetsu no Sekiban (Japan).gb" size 262144 crc c1e1a041 sha1 B7DAC857947FCE1069145A1F5D560C26AA3C8F42 ) ) game ( name "Super Black Bass (USA)" description "Super Black Bass (USA)" - rom ( name "Super Black Bass (USA).gb" size 524288 crc 6B497842 md5 426F96E31186B3A6E73A624D97B3B2DC sha1 4D3CB96DA714D785DFBCC3BA242F9A7A221C9CBB ) + rom ( name "Super Black Bass (USA).gb" size 524288 crc 6b497842 sha1 4D3CB96DA714D785DFBCC3BA242F9A7A221C9CBB ) ) game ( name "Super Black Bass Pocket (Japan) (SGB Enhanced)" description "Super Black Bass Pocket (Japan) (SGB Enhanced)" - rom ( name "Super Black Bass Pocket (Japan) (SGB Enhanced).gb" size 1048576 crc 8A7C1678 md5 596B9A0CA8ED82011A83ACA42119C6BF sha1 1FB714757E9A0AD02C96FEB57A0D04163E44DC74 flags verified ) + rom ( name "Super Black Bass Pocket (Japan) (SGB Enhanced).gb" size 1048576 crc 8a7c1678 sha1 1FB714757E9A0AD02C96FEB57A0D04163E44DC74 flags verified ) ) game ( name "Super Black Bass Pocket 2 (Japan) (SGB Enhanced)" description "Super Black Bass Pocket 2 (Japan) (SGB Enhanced)" - rom ( name "Super Black Bass Pocket 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 68A553B6 md5 D2CFE884E32423402FB7C71E319CF4ED sha1 86EC8D2E1A3151878B3D6A6C22D14A1AC7D26E39 flags verified ) + rom ( name "Super Black Bass Pocket 2 (Japan) (SGB Enhanced).gb" size 1048576 crc 68a553b6 sha1 86EC8D2E1A3151878B3D6A6C22D14A1AC7D26E39 flags verified ) ) game ( name "Super Bombliss (Japan) (SGB Enhanced)" description "Super Bombliss (Japan) (SGB Enhanced)" - rom ( name "Super Bombliss (Japan) (SGB Enhanced).gb" size 131072 crc B503FFAD md5 FD01CB80C21DA79311461E8DA0E97891 sha1 8F44CD2D819A3CD0AB697E60939D5921E29609AC flags verified ) + rom ( name "Super Bombliss (Japan) (SGB Enhanced).gb" size 131072 crc b503ffad sha1 8F44CD2D819A3CD0AB697E60939D5921E29609AC flags verified ) ) game ( name "Super Breakout (USA)" description "Super Breakout (USA)" - rom ( name "Super Breakout (USA).gb" size 131072 crc 1DC0F813 md5 C216547FF3FC2794BB6EAB9C84032BEA sha1 F98FF68B3004212D09904C5DB5CCFCF1D20405C3 ) + rom ( name "Super Breakout (USA).gb" size 131072 crc 1dc0f813 sha1 F98FF68B3004212D09904C5DB5CCFCF1D20405C3 flags verified ) ) game ( name "Super Chase H.Q. (USA, Europe)" description "Super Chase H.Q. (USA, Europe)" - rom ( name "Super Chase H.Q. (USA, Europe).gb" size 131072 crc 630E0E00 md5 EBDB99BF19C9066BE71485C3C9187B82 sha1 D5184C1849D8E0ADDD4E1D31812068931BF98ADC flags verified ) + rom ( name "Super Chase H.Q. (USA, Europe).gb" size 131072 crc 630e0e00 sha1 D5184C1849D8E0ADDD4E1D31812068931BF98ADC flags verified ) ) game ( name "Super Chinese Fighter GB (Japan) (SGB Enhanced)" description "Super Chinese Fighter GB (Japan) (SGB Enhanced)" - rom ( name "Super Chinese Fighter GB (Japan) (SGB Enhanced).gb" size 1048576 crc B526A116 md5 7178B4386827602226F40F2CD264E322 sha1 081A6F607C4A07FC0BAB2F86CF0D1ADFF1173239 flags verified ) + rom ( name "Super Chinese Fighter GB (Japan) (SGB Enhanced).gb" size 1048576 crc b526a116 sha1 081A6F607C4A07FC0BAB2F86CF0D1ADFF1173239 flags verified ) ) game ( name "Super Chinese Land (Japan)" description "Super Chinese Land (Japan)" - rom ( name "Super Chinese Land (Japan).gb" size 65536 crc 037D966A md5 05919B282F38ABB78C82740733F4DF79 sha1 1810B088F5CB395512A04BA6A3C47D9AB74AA8CC flags verified ) + rom ( name "Super Chinese Land (Japan).gb" size 65536 crc 037d966a sha1 1810B088F5CB395512A04BA6A3C47D9AB74AA8CC flags verified ) ) game ( - name "Super Chinese Land 1.2.3' (Japan) (SGB Enhanced)" - description "Super Chinese Land 1.2.3' (Japan) (SGB Enhanced)" - rom ( name "Super Chinese Land 1.2.3' (Japan) (SGB Enhanced).gb" size 1048576 crc 7D1D8FDC md5 8BEA8CF270169A042BDAE88F694C90B4 sha1 2C2A1C2DE0C2A88BC0A73B44F04F2CA434573D68 flags verified ) + name "Super Chinese Land 1-2-3' (Japan) (SGB Enhanced)" + description "Super Chinese Land 1-2-3' (Japan) (SGB Enhanced)" + rom ( name "Super Chinese Land 1-2-3' (Japan) (SGB Enhanced).gb" size 1048576 crc 7d1d8fdc sha1 2C2A1C2DE0C2A88BC0A73B44F04F2CA434573D68 flags verified ) ) game ( name "Super Chinese Land 2 (Japan)" description "Super Chinese Land 2 (Japan)" - rom ( name "Super Chinese Land 2 (Japan).gb" size 262144 crc 88508483 md5 763111E514AE572A530EB9465B9BC2EF sha1 7F355E4A02FBEFA3F539FA95F089C8A48508A937 flags verified ) + rom ( name "Super Chinese Land 2 (Japan).gb" size 262144 crc 88508483 sha1 7F355E4A02FBEFA3F539FA95F089C8A48508A937 flags verified ) ) game ( name "Super Chinese Land 3 (Japan) (SGB Enhanced)" description "Super Chinese Land 3 (Japan) (SGB Enhanced)" - rom ( name "Super Chinese Land 3 (Japan) (SGB Enhanced).gb" size 262144 crc E01CAF0B md5 095CFB0C56A564BC13239787B01C525D sha1 6D8EF3FDD1702D629C679636698E1D483FC3723B flags verified ) + rom ( name "Super Chinese Land 3 (Japan) (SGB Enhanced).gb" size 262144 crc e01caf0b sha1 6D8EF3FDD1702D629C679636698E1D483FC3723B flags verified ) ) game ( name "Super Donkey Kong GB (Japan) (SGB Enhanced)" description "Super Donkey Kong GB (Japan) (SGB Enhanced)" - rom ( name "Super Donkey Kong GB (Japan) (SGB Enhanced).gb" size 524288 crc 695F4600 md5 5C3C43FDC01CE3296BAAC197DC53B060 sha1 FCA5EBC5EEBC20B0088423631719FB2DC862B276 flags verified ) + rom ( name "Super Donkey Kong GB (Japan) (SGB Enhanced).gb" size 524288 crc 695f4600 sha1 FCA5EBC5EEBC20B0088423631719FB2DC862B276 flags verified ) ) game ( name "Super Hunchback (Europe)" description "Super Hunchback (Europe)" - rom ( name "Super Hunchback (Europe).gb" size 131072 crc 2359D61E md5 7B622D314E82F49E57A14ACA3435F814 sha1 9EA125F907FA610205E9C09A08802B1A128E4FF7 flags verified ) + rom ( name "Super Hunchback (Europe).gb" size 131072 crc 2359d61e sha1 9EA125F907FA610205E9C09A08802B1A128E4FF7 flags verified ) ) game ( name "Super Hunchback (Japan)" description "Super Hunchback (Japan)" - rom ( name "Super Hunchback (Japan).gb" size 131072 crc F20078C2 md5 2AC6A2561254AD50284F4C9650B30447 sha1 608092D4BE5D32D5B8B4D50C2D9284A00EA885CB ) + rom ( name "Super Hunchback (Japan).gb" size 131072 crc f20078c2 sha1 608092D4BE5D32D5B8B4D50C2D9284A00EA885CB ) ) game ( name "Super Hunchback (USA)" description "Super Hunchback (USA)" - rom ( name "Super Hunchback (USA).gb" size 131072 crc 1A45706E md5 F5E132763E20E45F407258D3C6EC0C61 sha1 9D53FBFEEEC5A1A8352177C157CE615621C4B30C ) + rom ( name "Super Hunchback (USA).gb" size 131072 crc 1a45706e sha1 9D53FBFEEEC5A1A8352177C157CE615621C4B30C ) ) game ( name "Super James Pond (Europe)" description "Super James Pond (Europe)" - rom ( name "Super James Pond (Europe).gb" size 131072 crc 6DC1BB2C md5 C4B03180037D53CB64B93634439ACEA0 sha1 CACB8A79CF66DCB8C3D4F71C94D535CF9E5AD63B flags verified ) + rom ( name "Super James Pond (Europe).gb" size 131072 crc 6dc1bb2c sha1 CACB8A79CF66DCB8C3D4F71C94D535CF9E5AD63B flags verified ) ) game ( name "Super Kick Off (Europe) (En,Fr,De,It,Nl)" description "Super Kick Off (Europe) (En,Fr,De,It,Nl)" - rom ( name "Super Kick Off (Europe) (En,Fr,De,It,Nl).gb" size 131072 crc 4B1DFE3D md5 7D6EB2F521FEBCF05CB445F6F37B3BA3 sha1 C178DAFC472DE4C8DCDBC8361EE078641AE61B84 flags verified ) + rom ( name "Super Kick Off (Europe) (En,Fr,De,It,Nl).gb" size 131072 crc 4b1dfe3d sha1 C178DAFC472DE4C8DCDBC8361EE078641AE61B84 flags verified ) ) game ( name "Super Mario Land (World)" description "Super Mario Land (World)" - rom ( name "Super Mario Land (World).gb" size 65536 crc 90776841 md5 B48161623F12F86FEC88320166A21FCE sha1 3A4DDB39B234A67FFB361EE7ABC3D23E0A8B1C89 flags verified ) + rom ( name "Super Mario Land (World).gb" size 65536 crc 90776841 sha1 3A4DDB39B234A67FFB361EE7ABC3D23E0A8B1C89 flags verified ) ) game ( - name "Super Mario Land (World) (Rev A)" - description "Super Mario Land (World) (Rev A)" - rom ( name "Super Mario Land (World) (Rev A).gb" size 65536 crc 2C27EC70 md5 B259FEB41811C7E4E1DC200167985C84 sha1 418203621B887CAA090215D97E3F509B79AFFD3E flags verified ) + name "Super Mario Land (World) (Rev 1)" + description "Super Mario Land (World) (Rev 1)" + rom ( name "Super Mario Land (World) (Rev 1).gb" size 65536 crc 2c27ec70 sha1 418203621B887CAA090215D97E3F509B79AFFD3E flags verified ) ) game ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe)" description "Super Mario Land 2 - 6 Golden Coins (USA, Europe)" - rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb" size 524288 crc D5EC24E4 md5 A8413347D5DF8C9D14F97F0330D67BCE sha1 BBA408539ECBF8D322324956D859BC86E2A9977B flags verified ) + rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe).gb" size 524288 crc d5ec24e4 sha1 BBA408539ECBF8D322324956D859BC86E2A9977B flags verified ) ) game ( - name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A)" - description "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A)" - rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev A).gb" size 524288 crc E6F886E5 md5 1D2C316F9F32727261328C7A49B22E2C sha1 96E3A314561FB394CDF51101F9178A32713C2313 ) + name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 1)" + description "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 1)" + rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 1).gb" size 524288 crc e6f886e5 sha1 96E3A314561FB394CDF51101F9178A32713C2313 flags verified ) ) game ( - name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B)" - description "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B)" - rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev B).gb" size 524288 crc 635A9112 md5 4BD6E929EC716A5C7FE7DC684860D551 sha1 D11D94FA3C36B9F72E925070B66BB4F16D31001E flags verified ) + name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 2)" + description "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 2)" + rom ( name "Super Mario Land 2 - 6 Golden Coins (USA, Europe) (Rev 2).gb" size 524288 crc 635a9112 sha1 D11D94FA3C36B9F72E925070B66BB4F16D31001E flags verified ) ) game ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan)" description "Super Mario Land 2 - 6-tsu no Kinka (Japan)" - rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan).gb" size 524288 crc A715DAF5 md5 98DAB710BDF256C1F1CF92C31D58D632 sha1 DC410E83F06EBD63AE5BD97E1B9562F0C887BE37 flags verified ) + rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan).gb" size 524288 crc a715daf5 sha1 DC410E83F06EBD63AE5BD97E1B9562F0C887BE37 flags verified ) ) game ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 2)" description "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 2)" - rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 2).gb" size 524288 crc 29E0911A md5 9EFEF8CEA73BAFBAAEB779B97356149F sha1 AAADB040EE6D85418E12F9993BEB4F2CB8DC9953 flags verified ) + rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 2).gb" size 524288 crc 29e0911a sha1 AAADB040EE6D85418E12F9993BEB4F2CB8DC9953 flags verified ) ) game ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 1)" description "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 1)" - rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 1).gb" size 524288 crc BF733E10 md5 7C2419BDDFD72711E90F54EF63695B07 sha1 F536D4D76A22668B8672BB291E4C738ABC55D759 ) + rom ( name "Super Mario Land 2 - 6-tsu no Kinka (Japan) (Rev 1).gb" size 524288 crc bf733e10 sha1 F536D4D76A22668B8672BB291E4C738ABC55D759 flags verified ) ) game ( name "Super Momotarou Dentetsu (Japan)" description "Super Momotarou Dentetsu (Japan)" - rom ( name "Super Momotarou Dentetsu (Japan).gb" size 262144 crc 4CA6D91A md5 DBE1E995AF2F9C28A06FE5845F04DA7B sha1 C142845225145F1ECE8AA4CDFD207402146EDFC0 flags verified ) + rom ( name "Super Momotarou Dentetsu (Japan).gb" size 262144 crc 4ca6d91a sha1 C142845225145F1ECE8AA4CDFD207402146EDFC0 flags verified ) ) game ( name "Super Momotarou Dentetsu II (Japan)" description "Super Momotarou Dentetsu II (Japan)" - rom ( name "Super Momotarou Dentetsu II (Japan).gb" size 262144 crc E8B4891F md5 4C30D454B5520414FD81D5FFA51375C5 sha1 4974D8E868CC359DCA73312749B71B0F163DF92E flags verified ) + rom ( name "Super Momotarou Dentetsu II (Japan).gb" size 262144 crc e8b4891f sha1 4974D8E868CC359DCA73312749B71B0F163DF92E flags verified ) ) game ( name "Super Off Road (USA, Europe)" description "Super Off Road (USA, Europe)" - rom ( name "Super Off Road (USA, Europe).gb" size 131072 crc 3E2810BE md5 85D05F95C07ED1B7D787062FE4D2E251 sha1 ACDE7750BCF99D7BB76B895534FDA43ECE222DFA flags verified ) + rom ( name "Super Off Road (USA, Europe).gb" size 131072 crc 3e2810be sha1 ACDE7750BCF99D7BB76B895534FDA43ECE222DFA flags verified ) ) game ( name "Super Pachinko Taisen (Japan) (SGB Enhanced)" description "Super Pachinko Taisen (Japan) (SGB Enhanced)" - rom ( name "Super Pachinko Taisen (Japan) (SGB Enhanced).gb" size 262144 crc CDE0FF00 md5 93BD30DC9A63696DC8A07F0353566FE7 sha1 642F4F6B043D8886D02552430BF3B3C87142AD2D flags verified ) + rom ( name "Super Pachinko Taisen (Japan) (SGB Enhanced).gb" size 262144 crc cde0ff00 sha1 642F4F6B043D8886D02552430BF3B3C87142AD2D flags verified ) ) game ( name "Super R.C. Pro-Am (USA, Europe)" description "Super R.C. Pro-Am (USA, Europe)" - rom ( name "Super R.C. Pro-Am (USA, Europe).gb" size 131072 crc 7960F33F md5 9BA2999EF3ECF9E27AC6C88E995C9D7A sha1 37C0A74532ED283F56E940BB5C38E757A0EEE6E0 flags verified ) + rom ( name "Super R.C. Pro-Am (USA, Europe).gb" size 131072 crc 7960f33f sha1 37C0A74532ED283F56E940BB5C38E757A0EEE6E0 flags verified ) ) game ( name "Super Robot Taisen (Japan)" description "Super Robot Taisen (Japan)" - rom ( name "Super Robot Taisen (Japan).gb" size 131072 crc 7DD9D7D6 md5 7BB8A5BC9E55A05EBA1A3FCBF460A9B5 sha1 267D77866C798D33C973FFF25D246FFF584BF9A3 flags verified ) + rom ( name "Super Robot Taisen (Japan).gb" size 131072 crc 7dd9d7d6 sha1 267D77866C798D33C973FFF25D246FFF584BF9A3 flags verified ) ) game ( name "Super Scrabble (USA)" description "Super Scrabble (USA)" - rom ( name "Super Scrabble (USA).gb" size 131072 crc 3874B7A2 md5 5C39C161B85481D7154F19081FF40F42 sha1 59755C83DC26015C4084296AB06600FFC235F026 ) + rom ( name "Super Scrabble (USA).gb" size 131072 crc 3874b7a2 sha1 59755C83DC26015C4084296AB06600FFC235F026 ) ) game ( name "Super Snakey (Japan) (SGB Enhanced)" description "Super Snakey (Japan) (SGB Enhanced)" - rom ( name "Super Snakey (Japan) (SGB Enhanced).gb" size 65536 crc 984D0F7F md5 770A5DAEB07A68BE86E72ED16E1A38D9 sha1 F4746AACE9190196CA82003B8E479A130926035E flags verified ) + rom ( name "Super Snakey (Japan) (SGB Enhanced).gb" size 65536 crc 984d0f7f sha1 F4746AACE9190196CA82003B8E479A130926035E flags verified ) ) game ( name "Super Star Wars - Return of the Jedi (USA, Europe) (SGB Enhanced)" description "Super Star Wars - Return of the Jedi (USA, Europe) (SGB Enhanced)" - rom ( name "Super Star Wars - Return of the Jedi (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6CB73DC7 md5 55945A517D1E89003003D51C7EC938BE sha1 4947F04548DDCF22A6F064601DE48925099D1E1D flags verified ) + rom ( name "Super Star Wars - Return of the Jedi (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6cb73dc7 sha1 4947F04548DDCF22A6F064601DE48925099D1E1D flags verified ) ) game ( name "Super Street Basketball (Japan)" description "Super Street Basketball (Japan)" - rom ( name "Super Street Basketball (Japan).gb" size 131072 crc A269559F md5 B8EA135492AC908DDA8BB695FFBBC813 sha1 4180A7A7F7E1F8DE07875246A3079A6D1507FA06 ) + rom ( name "Super Street Basketball (Japan).gb" size 131072 crc a269559f sha1 4180A7A7F7E1F8DE07875246A3079A6D1507FA06 flags verified ) ) game ( name "Super Street Basketball 2 (Japan) (SGB Enhanced)" description "Super Street Basketball 2 (Japan) (SGB Enhanced)" - rom ( name "Super Street Basketball 2 (Japan) (SGB Enhanced).gb" size 131072 crc 8090C9CC md5 D0A4D58A42B46B891D1C92D6AF37F934 sha1 3B52FA182C42E3D058D341AEE46FCFC63AE978EB flags verified ) + rom ( name "Super Street Basketball 2 (Japan) (SGB Enhanced).gb" size 131072 crc 8090c9cc sha1 3B52FA182C42E3D058D341AEE46FCFC63AE978EB flags verified ) ) game ( name "Superman (USA, Europe) (SGB Enhanced)" description "Superman (USA, Europe) (SGB Enhanced)" - rom ( name "Superman (USA, Europe) (SGB Enhanced).gb" size 131072 crc 358E0091 md5 A55E4143925F5CBE2B929CC5F598BBE9 sha1 3A987CB4BA6F33717EA70D7388EC1DFE6AB934E8 flags verified ) + rom ( name "Superman (USA, Europe) (SGB Enhanced).gb" size 131072 crc 358e0091 sha1 3A987CB4BA6F33717EA70D7388EC1DFE6AB934E8 flags verified ) ) game ( name "Suzuki Aguri no F-1 Super Driving (Japan)" description "Suzuki Aguri no F-1 Super Driving (Japan)" - rom ( name "Suzuki Aguri no F-1 Super Driving (Japan).gb" size 262144 crc E82692D9 md5 ADF6023F4BFC67CBBF09A42F0D0CE27A sha1 98D0E39251413F2F3BF2F001C48CCF88F27190BA ) + rom ( name "Suzuki Aguri no F-1 Super Driving (Japan).gb" size 262144 crc e82692d9 sha1 98D0E39251413F2F3BF2F001C48CCF88F27190BA ) ) game ( name "Swamp Thing (USA, Europe)" description "Swamp Thing (USA, Europe)" - rom ( name "Swamp Thing (USA, Europe).gb" size 131072 crc 76AE62C8 md5 85CCD61E2298B5F9B26312E8E182F10E sha1 1FF322B5F44D21C951DCDF8D062D99FFA65827E3 flags verified ) + rom ( name "Swamp Thing (USA, Europe).gb" size 131072 crc 76ae62c8 sha1 1FF322B5F44D21C951DCDF8D062D99FFA65827E3 flags verified ) ) game ( name "Sword of Hope II, The (USA)" description "Sword of Hope II, The (USA)" - rom ( name "Sword of Hope II, The (USA).gb" size 262144 crc 5B7FF38C md5 64F7F8AF18F75A9B3767E4637E693BE7 sha1 3CCB37FD8E6E39A9E8421EE6F1AE199B4586AFC1 flags verified ) + rom ( name "Sword of Hope II, The (USA).gb" size 262144 crc 5b7ff38c sha1 3CCB37FD8E6E39A9E8421EE6F1AE199B4586AFC1 flags verified ) ) game ( name "Sword of Hope, The (Germany)" description "Sword of Hope, The (Germany)" - rom ( name "Sword of Hope, The (Germany).gb" size 131072 crc 498E0E9F md5 92B87220F7F18AFD29BE272DF70563B0 sha1 4D442BDA629F64A277D0F6BCC7E7FA640294BD7E flags verified ) + rom ( name "Sword of Hope, The (Germany).gb" size 131072 crc 498e0e9f sha1 4D442BDA629F64A277D0F6BCC7E7FA640294BD7E flags verified ) ) game ( name "Sword of Hope, The (Spain)" description "Sword of Hope, The (Spain)" - rom ( name "Sword of Hope, The (Spain).gb" size 131072 crc 28C311D7 md5 42048CE08886F2ADCC4F004E002BED50 sha1 DBD0FD8F870B883D19455F2D276EDC1028C9D916 flags verified ) + rom ( name "Sword of Hope, The (Spain).gb" size 131072 crc 28c311d7 sha1 DBD0FD8F870B883D19455F2D276EDC1028C9D916 flags verified ) ) game ( name "Sword of Hope, The (Sweden)" description "Sword of Hope, The (Sweden)" - rom ( name "Sword of Hope, The (Sweden).gb" size 131072 crc C7E48C7C md5 B8DE7E1EF842F68D1D33538E621A9248 sha1 FDA0CC9B3C02F6DBC1FB44636C98DCC4DFBCE5EC ) + rom ( name "Sword of Hope, The (Sweden).gb" size 131072 crc c7e48c7c sha1 FDA0CC9B3C02F6DBC1FB44636C98DCC4DFBCE5EC ) ) game ( name "Sword of Hope, The (USA)" description "Sword of Hope, The (USA)" - rom ( name "Sword of Hope, The (USA).gb" size 131072 crc 7E923846 md5 7138D95583FC38EE7B3CF18DE5E09E89 sha1 5F30147162E2A38DBB90A233F22DF0A6AA3D99FB flags verified ) + rom ( name "Sword of Hope, The (USA).gb" size 131072 crc 7e923846 sha1 5F30147162E2A38DBB90A233F22DF0A6AA3D99FB flags verified ) ) game ( name "T2 - The Arcade Game (Japan)" description "T2 - The Arcade Game (Japan)" - rom ( name "T2 - The Arcade Game (Japan).gb" size 131072 crc 7EC795FA md5 83F5DA7271A970C28CB2A1F366E89616 sha1 363EDD30041B562CE522F68E451FEEE5E94EF03F ) + rom ( name "T2 - The Arcade Game (Japan).gb" size 131072 crc 7ec795fa sha1 363EDD30041B562CE522F68E451FEEE5E94EF03F ) ) game ( name "T2 - The Arcade Game (USA, Europe)" description "T2 - The Arcade Game (USA, Europe)" - rom ( name "T2 - The Arcade Game (USA, Europe).gb" size 131072 crc 00F09C7F md5 43E26F216D50106A8FCCBCC04CDA0C29 sha1 A362A05B2616BCA1375D3F4F979D12BDB9BCA53A flags verified ) + rom ( name "T2 - The Arcade Game (USA, Europe).gb" size 131072 crc 00f09c7f sha1 A362A05B2616BCA1375D3F4F979D12BDB9BCA53A flags verified ) ) game ( name "Taikyoku Renju (Japan) (En,Ja)" description "Taikyoku Renju (Japan) (En,Ja)" - rom ( name "Taikyoku Renju (Japan) (En,Ja).gb" size 65536 crc 62A31DE6 md5 FC9D18538596C136F4CC9FC64D044A76 sha1 4BD7E9944BE0F71258B9955C77C0696484E9773A flags verified ) + rom ( name "Taikyoku Renju (Japan) (En,Ja).gb" size 65536 crc 62a31de6 sha1 4BD7E9944BE0F71258B9955C77C0696484E9773A flags verified ) ) game ( name "Tail 'Gator (USA, Europe)" description "Tail 'Gator (USA, Europe)" - rom ( name "Tail 'Gator (USA, Europe).gb" size 65536 crc C5ACCE7C md5 CAC94925BF098982D31F7C9A2C296D25 sha1 ED5F1110A9DB4C48D26D53AF0973E8B46FE7E4E1 flags verified ) + rom ( name "Tail 'Gator (USA, Europe).gb" size 65536 crc c5acce7c sha1 ED5F1110A9DB4C48D26D53AF0973E8B46FE7E4E1 flags verified ) ) game ( name "Taito Chase H.Q. (Japan)" description "Taito Chase H.Q. (Japan)" - rom ( name "Taito Chase H.Q. (Japan).gb" size 131072 crc C58BB4F5 md5 0A96C9C737A07148FD065B3C121DCBB2 sha1 D448C5C63A0CCA4F7C4EE806FF928C564D40D386 flags verified ) + rom ( name "Taito Chase H.Q. (Japan).gb" size 131072 crc c58bb4f5 sha1 D448C5C63A0CCA4F7C4EE806FF928C564D40D386 flags verified ) ) game ( name "Taito Variety Pack (Japan)" description "Taito Variety Pack (Japan)" - rom ( name "Taito Variety Pack (Japan).gb" size 524288 crc 6DBAA5E8 md5 FC84B2E016917D5B0E7DE412D9F8C269 sha1 53995F1B9C8A0BF8545414BD5E5DEFEF617B7A55 flags verified ) + rom ( name "Taito Variety Pack (Japan).gb" size 524288 crc 6dbaa5e8 sha1 53995F1B9C8A0BF8545414BD5E5DEFEF617B7A55 flags verified ) ) game ( name "Taiyou no Tenshi Marlowe - Ohanabatake wa Dai-panic (Japan)" description "Taiyou no Tenshi Marlowe - Ohanabatake wa Dai-panic (Japan)" - rom ( name "Taiyou no Tenshi Marlowe - Ohanabatake wa Dai-panic (Japan).gb" size 262144 crc 1132C6BB md5 022FD2B0CBAAC8C7551A7DB1CC861F5B sha1 3B9F13100A797623D1700CCFEFF0B31DA52F5DC3 ) + rom ( name "Taiyou no Tenshi Marlowe - Ohanabatake wa Dai-panic (Japan).gb" size 262144 crc 1132c6bb sha1 3B9F13100A797623D1700CCFEFF0B31DA52F5DC3 ) ) game ( name "Taiyou no Yuusha - Fighbird GB (Japan)" description "Taiyou no Yuusha - Fighbird GB (Japan)" - rom ( name "Taiyou no Yuusha - Fighbird GB (Japan).gb" size 131072 crc 723EB882 md5 5BD352E85F75A8314E4DCE538CB956C6 sha1 7A2B9864BF2A93D271694D9BC7EEDB55F0F15FAD flags verified ) + rom ( name "Taiyou no Yuusha - Fighbird GB (Japan).gb" size 131072 crc 723eb882 sha1 7A2B9864BF2A93D271694D9BC7EEDB55F0F15FAD flags verified ) ) game ( name "Takahashi Meijin no Bouken-jima II (Japan)" description "Takahashi Meijin no Bouken-jima II (Japan)" - rom ( name "Takahashi Meijin no Bouken-jima II (Japan).gb" size 131072 crc F1071E08 md5 1A4777D04E6CC718FD7E2499B9C23C55 sha1 504D9096C9EACE691AD23B2119749BC24F6E7D45 flags verified ) + rom ( name "Takahashi Meijin no Bouken-jima II (Japan).gb" size 131072 crc f1071e08 sha1 504D9096C9EACE691AD23B2119749BC24F6E7D45 flags verified ) ) game ( name "Takahashi Meijin no Bouken-jima III (Japan)" description "Takahashi Meijin no Bouken-jima III (Japan)" - rom ( name "Takahashi Meijin no Bouken-jima III (Japan).gb" size 262144 crc F8FC0B41 md5 A291DD1F541FAC1D57019E4A3D0FFD08 sha1 E3FE857A1B7F00A6F7862D7DD401063F98FD0CB6 ) + rom ( name "Takahashi Meijin no Bouken-jima III (Japan).gb" size 262144 crc f8fc0b41 sha1 E3FE857A1B7F00A6F7862D7DD401063F98FD0CB6 ) ) game ( name "Takeda Nobuhiro no Ace Striker (Japan)" description "Takeda Nobuhiro no Ace Striker (Japan)" - rom ( name "Takeda Nobuhiro no Ace Striker (Japan).gb" size 262144 crc 7FF546DF md5 1FAD0B21E68BD05E2F29B2E5FD861719 sha1 E354310C9946F48EB325C070E9C2C5CCB2E9F429 ) + rom ( name "Takeda Nobuhiro no Ace Striker (Japan).gb" size 262144 crc 7ff546df sha1 E354310C9946F48EB325C070E9C2C5CCB2E9F429 ) ) game ( name "TaleSpin (Europe)" description "TaleSpin (Europe)" - rom ( name "TaleSpin (Europe).gb" size 131072 crc D29DDC91 md5 8D0454B8CCE374E863D535E2654F326B sha1 4CA2962C76F9015246663564B9C7006B5FA37A03 ) + rom ( name "TaleSpin (Europe).gb" size 131072 crc d29ddc91 sha1 4CA2962C76F9015246663564B9C7006B5FA37A03 ) ) game ( name "TaleSpin (USA)" description "TaleSpin (USA)" - rom ( name "TaleSpin (USA).gb" size 131072 crc DE383E73 md5 26C65DA146FAA09505C554447792E493 sha1 155EB5458C971A9A84E3BE19711994CA2A4C24D8 flags verified ) + rom ( name "TaleSpin (USA).gb" size 131072 crc de383e73 sha1 155EB5458C971A9A84E3BE19711994CA2A4C24D8 flags verified ) ) game ( name "Tamagotchi (France) (SGB Enhanced)" description "Tamagotchi (France) (SGB Enhanced)" - rom ( name "Tamagotchi (France) (SGB Enhanced).gb" size 524288 crc 084C2401 md5 79EDE10E81D8697137F6FFF7BB322A30 sha1 0F4E508F90E52A869EFB245894A362E5F677C2ED ) + rom ( name "Tamagotchi (France) (SGB Enhanced).gb" size 524288 crc 084c2401 sha1 0F4E508F90E52A869EFB245894A362E5F677C2ED ) ) game ( name "Tamagotchi (USA, Europe) (SGB Enhanced)" description "Tamagotchi (USA, Europe) (SGB Enhanced)" - rom ( name "Tamagotchi (USA, Europe) (SGB Enhanced).gb" size 524288 crc DBF1BD20 md5 C7920EB4B478C4D7513F2F43B7DBB9CF sha1 7368EC190BED39429812A26E18B2D3E153CF4E81 flags verified ) + rom ( name "Tamagotchi (USA, Europe) (SGB Enhanced).gb" size 524288 crc dbf1bd20 sha1 7368EC190BED39429812A26E18B2D3E153CF4E81 flags verified ) ) game ( - name "Tarzan (USA, Europe)" - description "Tarzan (USA, Europe)" - rom ( name "Tarzan (USA, Europe).gb" size 131072 crc C2F50FB3 md5 3485E210E798DF389E4FFC1270F86382 sha1 EAFF826C9256358D7920DE3956A8AB563D004D51 flags verified ) + name "Tarzan - Lord of the Jungle (USA, Europe)" + description "Tarzan - Lord of the Jungle (USA, Europe)" + rom ( name "Tarzan - Lord of the Jungle (USA, Europe).gb" size 131072 crc c2f50fb3 sha1 EAFF826C9256358D7920DE3956A8AB563D004D51 flags verified ) ) game ( name "Tasmania Monogatari (Japan)" description "Tasmania Monogatari (Japan)" - rom ( name "Tasmania Monogatari (Japan).gb" size 32768 crc 9EA867A7 md5 D413F826B00D3F2384555490D0F1271D sha1 6D036755C55C84B05FE1C015CC567F1889D27576 flags verified ) + rom ( name "Tasmania Monogatari (Japan).gb" size 32768 crc 9ea867a7 sha1 6D036755C55C84B05FE1C015CC567F1889D27576 flags verified ) ) game ( name "Tasmania Story (USA)" description "Tasmania Story (USA)" - rom ( name "Tasmania Story (USA).gb" size 32768 crc A33C4FFF md5 46972F66B5C73B6B19FE21077B195669 sha1 70E206BCD2C5C55EC1270BCB63CBFE8F5D049363 ) + rom ( name "Tasmania Story (USA).gb" size 32768 crc a33c4fff sha1 70E206BCD2C5C55EC1270BCB63CBFE8F5D049363 ) ) game ( name "Taz-Mania (Europe)" description "Taz-Mania (Europe)" - rom ( name "Taz-Mania (Europe).gb" size 131072 crc 0860B667 md5 BB922CE354FC5CAEC500F99985A07C39 sha1 C184E8E11EF2388C60B69D445A46FC22A11D175E flags verified ) -) - -game ( - name "Taz-Mania (USA, Europe)" - description "Taz-Mania (USA, Europe)" - rom ( name "Taz-Mania (USA, Europe).gb" size 262144 crc 22D07CF6 md5 9DB0E1E39AA5A40471911A40E12BA739 sha1 D36D731BD2644EE84C7CF77A2C1D319851E4D6BB flags verified ) + rom ( name "Taz-Mania (Europe).gb" size 131072 crc 0860b667 sha1 C184E8E11EF2388C60B69D445A46FC22A11D175E flags verified ) ) game ( name "Taz-Mania 2 (USA)" description "Taz-Mania 2 (USA)" - rom ( name "Taz-Mania 2 (USA).gb" size 131072 crc 4CCB65E0 md5 985BF1D3FDF54038DBDE36FD372FBE2C sha1 60116A304E85F04209DC7EB64D9649DC41C963F6 ) -) - -game ( - name "Tecmo Bowl (Japan)" - description "Tecmo Bowl (Japan)" - rom ( name "Tecmo Bowl (Japan).gb" size 262144 crc CFD74E34 md5 DC8B474C2A31DA3A494C80970D2892BF sha1 2447006C578E1DF0256E9155C8B65FA2A6B0004B flags verified ) + rom ( name "Taz-Mania 2 (USA).gb" size 131072 crc 4ccb65e0 sha1 60116A304E85F04209DC7EB64D9649DC41C963F6 ) ) game ( name "Tecmo Bowl (USA)" description "Tecmo Bowl (USA)" - rom ( name "Tecmo Bowl (USA).gb" size 262144 crc E4F29760 md5 DC2732DBA9121AAD355FA2E1DFBBB069 sha1 A3D7559DB6AEBF77EC6A682B7D39C1976F80C7A1 ) + rom ( name "Tecmo Bowl (USA).gb" size 262144 crc e4f29760 sha1 A3D7559DB6AEBF77EC6A682B7D39C1976F80C7A1 ) +) + +game ( + name "Tecmo Bowl GB (Japan)" + description "Tecmo Bowl GB (Japan)" + rom ( name "Tecmo Bowl GB (Japan).gb" size 262144 crc cfd74e34 sha1 2447006C578E1DF0256E9155C8B65FA2A6B0004B flags verified ) ) game ( name "Teenage Mutant Hero Turtles - Fall of the Foot Clan (Europe)" description "Teenage Mutant Hero Turtles - Fall of the Foot Clan (Europe)" - rom ( name "Teenage Mutant Hero Turtles - Fall of the Foot Clan (Europe).gb" size 131072 crc ED8A73FB md5 3172F2D0C417107DA132F8437C43763B sha1 CF1D432B93E6A606D95BF7397A088B79CD69E108 flags verified ) + rom ( name "Teenage Mutant Hero Turtles - Fall of the Foot Clan (Europe).gb" size 131072 crc ed8a73fb sha1 CF1D432B93E6A606D95BF7397A088B79CD69E108 flags verified ) ) game ( name "Teenage Mutant Hero Turtles II - Back from the Sewers (Europe)" description "Teenage Mutant Hero Turtles II - Back from the Sewers (Europe)" - rom ( name "Teenage Mutant Hero Turtles II - Back from the Sewers (Europe).gb" size 262144 crc CF24506C md5 B439F2CA31E47F7AC4EA4A95CC6C9FA5 sha1 350FFF58E59114EF37B232C8588A44910BD02D27 flags verified ) + rom ( name "Teenage Mutant Hero Turtles II - Back from the Sewers (Europe).gb" size 262144 crc cf24506c sha1 350FFF58E59114EF37B232C8588A44910BD02D27 flags verified ) ) game ( name "Teenage Mutant Hero Turtles III - Radical Rescue (Europe)" description "Teenage Mutant Hero Turtles III - Radical Rescue (Europe)" - rom ( name "Teenage Mutant Hero Turtles III - Radical Rescue (Europe).gb" size 131072 crc 9F3245F3 md5 7768609B189E788AB08C8AAC165B9F4C sha1 BD0AECB9B752EEF5A9628AC9C649CAD1EFB8CB62 ) + rom ( name "Teenage Mutant Hero Turtles III - Radical Rescue (Europe).gb" size 131072 crc 9f3245f3 sha1 BD0AECB9B752EEF5A9628AC9C649CAD1EFB8CB62 ) ) game ( name "Teenage Mutant Ninja Turtles (Japan)" description "Teenage Mutant Ninja Turtles (Japan)" - rom ( name "Teenage Mutant Ninja Turtles (Japan).gb" size 131072 crc 74078236 md5 3E7D080982AF3AEDB9C7E9DC5486B468 sha1 1F17169D70365831537376BEB2477374649F830B flags verified ) + rom ( name "Teenage Mutant Ninja Turtles (Japan).gb" size 131072 crc 74078236 sha1 1F17169D70365831537376BEB2477374649F830B flags verified ) ) game ( name "Teenage Mutant Ninja Turtles - Fall of the Foot Clan (USA)" description "Teenage Mutant Ninja Turtles - Fall of the Foot Clan (USA)" - rom ( name "Teenage Mutant Ninja Turtles - Fall of the Foot Clan (USA).gb" size 131072 crc 5A6984C3 md5 AD868E84FB6071A3B6A211D16E6CBB66 sha1 6E8A43BC0C18129D74FF3322658A2CE8C24D201E flags verified ) + rom ( name "Teenage Mutant Ninja Turtles - Fall of the Foot Clan (USA).gb" size 131072 crc 5a6984c3 sha1 6E8A43BC0C18129D74FF3322658A2CE8C24D201E flags verified ) ) game ( name "Teenage Mutant Ninja Turtles 2 (Japan)" description "Teenage Mutant Ninja Turtles 2 (Japan)" - rom ( name "Teenage Mutant Ninja Turtles 2 (Japan).gb" size 262144 crc 84E6FB25 md5 BC40E81C4DB84DD46F7B52C8BCCF49B8 sha1 27E254854D72195DE4BC5146D69D30CB3C10912A flags verified ) + rom ( name "Teenage Mutant Ninja Turtles 2 (Japan).gb" size 262144 crc 84e6fb25 sha1 27E254854D72195DE4BC5146D69D30CB3C10912A flags verified ) ) game ( name "Teenage Mutant Ninja Turtles 3 - Turtles Kikiippatsu (Japan)" description "Teenage Mutant Ninja Turtles 3 - Turtles Kikiippatsu (Japan)" - rom ( name "Teenage Mutant Ninja Turtles 3 - Turtles Kikiippatsu (Japan).gb" size 131072 crc 55153BB5 md5 6A0F10C18D253A68BA5D33256C8CCF4C sha1 15FD427B7ED6ABE0B8D5685C17D01A96FA41DE49 ) + rom ( name "Teenage Mutant Ninja Turtles 3 - Turtles Kikiippatsu (Japan).gb" size 131072 crc 55153bb5 sha1 15FD427B7ED6ABE0B8D5685C17D01A96FA41DE49 ) ) game ( name "Teenage Mutant Ninja Turtles II - Back from the Sewers (USA)" description "Teenage Mutant Ninja Turtles II - Back from the Sewers (USA)" - rom ( name "Teenage Mutant Ninja Turtles II - Back from the Sewers (USA).gb" size 262144 crc 44F51C73 md5 0221DE99D11F50F79430C8FF9B430994 sha1 08AABD7BE3D4B78A8B124A58AFAE4FEC758B225F ) + rom ( name "Teenage Mutant Ninja Turtles II - Back from the Sewers (USA).gb" size 262144 crc 44f51c73 sha1 08AABD7BE3D4B78A8B124A58AFAE4FEC758B225F ) ) game ( name "Teenage Mutant Ninja Turtles III - Radical Rescue (USA)" description "Teenage Mutant Ninja Turtles III - Radical Rescue (USA)" - rom ( name "Teenage Mutant Ninja Turtles III - Radical Rescue (USA).gb" size 131072 crc 58832BBC md5 E6104DF1FEB1318FF1764C791EB4CE0E sha1 29F5DE9E4C0F21BF8BFFC721DACF1790446A5923 flags verified ) + rom ( name "Teenage Mutant Ninja Turtles III - Radical Rescue (USA).gb" size 131072 crc 58832bbc sha1 29F5DE9E4C0F21BF8BFFC721DACF1790446A5923 flags verified ) ) game ( name "Teke Teke! Asmik-kun World (Japan)" description "Teke Teke! Asmik-kun World (Japan)" - rom ( name "Teke Teke! Asmik-kun World (Japan).gb" size 65536 crc A817450D md5 563C4C81878DB48D8A0B6091F4C1CD92 sha1 389CC31472B87EC70E3EA6487F8AD9198887BB89 flags verified ) + rom ( name "Teke Teke! Asmik-kun World (Japan).gb" size 65536 crc a817450d sha1 389CC31472B87EC70E3EA6487F8AD9198887BB89 flags verified ) ) game ( name "Tekichuu Rush (Japan)" description "Tekichuu Rush (Japan)" - rom ( name "Tekichuu Rush (Japan).gb" size 65536 crc 7B903A6F md5 64E365D21F0E58D80749A50E26330DDB sha1 037B677A369FC892E08C268A8334D7F48B1FA05C flags verified ) + rom ( name "Tekichuu Rush (Japan).gb" size 65536 crc 7b903a6f sha1 037B677A369FC892E08C268A8334D7F48B1FA05C flags verified ) ) game ( name "Tekkyu Fight! - The Great Battle Gaiden (Japan)" description "Tekkyu Fight! - The Great Battle Gaiden (Japan)" - rom ( name "Tekkyu Fight! - The Great Battle Gaiden (Japan).gb" size 131072 crc B8DA8EB5 md5 959834B1D0ACEFCF840134FAE4C49FDE sha1 06A6AB3BA59286772F915053CFCD6E1E873358B1 flags verified ) + rom ( name "Tekkyu Fight! - The Great Battle Gaiden (Japan).gb" size 131072 crc b8da8eb5 sha1 06A6AB3BA59286772F915053CFCD6E1E873358B1 flags verified ) ) game ( name "Tenchi o Kurau (Japan)" description "Tenchi o Kurau (Japan)" - rom ( name "Tenchi o Kurau (Japan).gb" size 262144 crc A9018354 md5 8C69230B2E8BBE15CEE83E89A7CB19DC sha1 312BC91B1B857CC7EC0CB8BC7CFA80BFE10D7B4B flags verified ) + rom ( name "Tenchi o Kurau (Japan).gb" size 262144 crc a9018354 sha1 312BC91B1B857CC7EC0CB8BC7CFA80BFE10D7B4B flags verified ) ) game ( name "Tenjin Kaisen (Japan)" description "Tenjin Kaisen (Japan)" - rom ( name "Tenjin Kaisen (Japan).gb" size 131072 crc B71396A6 md5 E1254F4AF3BA70F0937E92F14F04AC91 sha1 7D3CDCE222E27CB9AC958C590936D7B8270BA34D flags verified ) + rom ( name "Tenjin Kaisen (Japan).gb" size 131072 crc b71396a6 sha1 7D3CDCE222E27CB9AC958C590936D7B8270BA34D flags verified ) ) game ( name "Tennis (World)" description "Tennis (World)" - rom ( name "Tennis (World).gb" size 32768 crc 5009215F md5 7D621DCBBCE12B73574C42F40DEEC275 sha1 EC45A932FB3FC21394FEF5E27E7FE9ECCD0C7F70 flags verified ) + rom ( name "Tennis (World).gb" size 32768 crc 5009215f sha1 EC45A932FB3FC21394FEF5E27E7FE9ECCD0C7F70 flags verified ) ) game ( name "Terminator 2 - Judgment Day (USA, Europe)" description "Terminator 2 - Judgment Day (USA, Europe)" - rom ( name "Terminator 2 - Judgment Day (USA, Europe).gb" size 131072 crc 21848101 md5 133AE23114BF442FEF6ACCCD1B8E187A sha1 D2B94304971900DC2FF4945AD5CB445BFE434A5C flags verified ) + rom ( name "Terminator 2 - Judgment Day (USA, Europe).gb" size 131072 crc 21848101 sha1 D2B94304971900DC2FF4945AD5CB445BFE434A5C flags verified ) ) game ( name "Tesserae (Europe) (En,Fr,De,Es,It)" description "Tesserae (Europe) (En,Fr,De,Es,It)" - rom ( name "Tesserae (Europe) (En,Fr,De,Es,It).gb" size 32768 crc 679B6530 md5 08B5EA1083E8E62B5BF7A75823FE5B33 sha1 69C2D689C52A3430A84AA8C9F020A2CE3D9A3C55 ) + rom ( name "Tesserae (Europe) (En,Fr,De,Es,It).gb" size 32768 crc 679b6530 sha1 69C2D689C52A3430A84AA8C9F020A2CE3D9A3C55 flags verified ) ) game ( name "Tesserae (USA)" description "Tesserae (USA)" - rom ( name "Tesserae (USA).gb" size 32768 crc C77E316F md5 95517367DD10F6476BCB39A2329EF55A sha1 9506A7EA6664BB6C65DFCF0476F209B65D9306FB ) + rom ( name "Tesserae (USA).gb" size 32768 crc c77e316f sha1 9506A7EA6664BB6C65DFCF0476F209B65D9306FB ) ) game ( name "Tetris (Japan) (En)" description "Tetris (Japan) (En)" - rom ( name "Tetris (Japan) (En).gb" size 32768 crc 63F9407D md5 084F1E457749CDEC86183189BD88CE69 sha1 3F2A6407C9900AD5817EE1CFB3609C5EE17400FC flags verified ) + rom ( name "Tetris (Japan) (En).gb" size 32768 crc 63f9407d sha1 3F2A6407C9900AD5817EE1CFB3609C5EE17400FC flags verified ) ) game ( - name "Tetris (World) (Rev A)" - description "Tetris (World) (Rev A)" - rom ( name "Tetris (World) (Rev A).gb" size 32768 crc 46DF91AD md5 982ED5D2B12A0377EB14BCDC4123744E sha1 74591CC9501AF93873F9A5D3EB12DA12C0723BBC flags verified ) + name "Tetris (World) (Rev 1)" + description "Tetris (World) (Rev 1)" + rom ( name "Tetris (World) (Rev 1).gb" size 32768 crc 46df91ad sha1 74591CC9501AF93873F9A5D3EB12DA12C0723BBC flags verified ) ) game ( name "Tetris 2 (USA, Europe) (SGB Enhanced)" description "Tetris 2 (USA, Europe) (SGB Enhanced)" - rom ( name "Tetris 2 (USA, Europe) (SGB Enhanced).gb" size 131072 crc EA19A9D9 md5 0A2E27E279EE4FAAC326B0CF620B269B sha1 1F88BE9DEA864EAA74C3B5CE3488E61139818E8D flags verified ) + rom ( name "Tetris 2 (USA, Europe) (SGB Enhanced).gb" size 131072 crc ea19a9d9 sha1 1F88BE9DEA864EAA74C3B5CE3488E61139818E8D flags verified ) ) game ( name "Tetris 2 (USA)" description "Tetris 2 (USA)" - rom ( name "Tetris 2 (USA).gb" size 131072 crc AA4A1EDB md5 9DDC6F4F0DC369008CBD2AC4EC561E75 sha1 EC7B3419C08F1A5713AFFF2B26C1534D91602338 flags verified ) + rom ( name "Tetris 2 (USA).gb" size 131072 crc aa4a1edb sha1 EC7B3419C08F1A5713AFFF2B26C1534D91602338 flags verified ) +) + +game ( + name "Tetris 2 (USA, Europe) (Rev 1) (SGB Enhanced)" + description "Tetris 2 (USA, Europe) (Rev 1) (SGB Enhanced)" + rom ( name "Tetris 2 (USA, Europe) (Rev 1) (SGB Enhanced).gb" size 131072 crc 25c3100a sha1 51BDCEED8FC384B593444A5306B6A46A4672C96B flags verified ) ) game ( name "Tetris Attack (USA) (SGB Enhanced)" description "Tetris Attack (USA) (SGB Enhanced)" - rom ( name "Tetris Attack (USA) (SGB Enhanced).gb" size 524288 crc B76C769B md5 7FBDA0C87AF7701BB5E75C2A77BB0143 sha1 3DE8D7F30322BC50008AB0D917ACD0A934B5B195 flags verified ) + rom ( name "Tetris Attack (USA) (SGB Enhanced).gb" size 524288 crc b76c769b sha1 3DE8D7F30322BC50008AB0D917ACD0A934B5B195 flags verified ) ) game ( - name "Tetris Attack (USA, Europe) (Rev A) (SGB Enhanced)" - description "Tetris Attack (USA, Europe) (Rev A) (SGB Enhanced)" - rom ( name "Tetris Attack (USA, Europe) (Rev A) (SGB Enhanced).gb" size 524288 crc 5EE45A4D md5 8517AC370FC46971D8A8C106BDE4D4C4 sha1 85B4B0D5A5A0417E10FED853419FE65975A6071F flags verified ) + name "Tetris Attack (USA, Europe) (Rev 1) (SGB Enhanced)" + description "Tetris Attack (USA, Europe) (Rev 1) (SGB Enhanced)" + rom ( name "Tetris Attack (USA, Europe) (Rev 1) (SGB Enhanced).gb" size 524288 crc 5ee45a4d sha1 85B4B0D5A5A0417E10FED853419FE65975A6071F flags verified ) ) game ( name "Tetris Blast (USA, Europe) (SGB Enhanced)" description "Tetris Blast (USA, Europe) (SGB Enhanced)" - rom ( name "Tetris Blast (USA, Europe) (SGB Enhanced).gb" size 131072 crc 7BE5A73F md5 0AFFC9DF2E1220EA4573DEB6CB2D4B32 sha1 14DE1E47820B8AEF8475D1BA94EA3D49CC45D06C flags verified ) + rom ( name "Tetris Blast (USA, Europe) (SGB Enhanced).gb" size 131072 crc 7be5a73f sha1 14DE1E47820B8AEF8475D1BA94EA3D49CC45D06C flags verified ) ) game ( name "Tetris Flash (Japan) (SGB Enhanced)" description "Tetris Flash (Japan) (SGB Enhanced)" - rom ( name "Tetris Flash (Japan) (SGB Enhanced).gb" size 131072 crc 9DFCB385 md5 6776C3CF0EF69035529D05342F072446 sha1 EE30C75E068AEFE131B880D611D987C41A421470 flags verified ) + rom ( name "Tetris Flash (Japan) (SGB Enhanced).gb" size 131072 crc 9dfcb385 sha1 EE30C75E068AEFE131B880D611D987C41A421470 flags verified ) ) game ( name "Tetris Plus (Japan) (SGB Enhanced)" description "Tetris Plus (Japan) (SGB Enhanced)" - rom ( name "Tetris Plus (Japan) (SGB Enhanced).gb" size 262144 crc 2EC9120A md5 D9CB4470F5320CAC32FC2BC17E1E9D7B sha1 DBB20951409739F1E11FFBCD8B0AF1E802BF693A flags verified ) + rom ( name "Tetris Plus (Japan) (SGB Enhanced).gb" size 262144 crc 2ec9120a sha1 DBB20951409739F1E11FFBCD8B0AF1E802BF693A flags verified ) ) game ( name "Tetris Plus (USA, Europe) (SGB Enhanced)" description "Tetris Plus (USA, Europe) (SGB Enhanced)" - rom ( name "Tetris Plus (USA, Europe) (SGB Enhanced).gb" size 262144 crc DAFC3BFF md5 4511333EEECB3C9F20874D595424447C sha1 DFAB75AB6BDC0765BA9A5D33A93FFDB114A49CBF flags verified ) -) - -game ( - name "Thunderbirds (Japan)" - description "Thunderbirds (Japan)" - rom ( name "Thunderbirds (Japan).gb" size 131072 crc 149E9393 md5 6949E7E7307B0885898E5330E8A7E9CC sha1 440169376982AA89CEDDE08EDBC9EFDFAFC6C7F1 ) + rom ( name "Tetris Plus (USA, Europe) (SGB Enhanced).gb" size 262144 crc dafc3bff sha1 DFAB75AB6BDC0765BA9A5D33A93FFDB114A49CBF flags verified ) ) game ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" description "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" - rom ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De).gb" size 262144 crc 55FC585F md5 8FDFFDE2DB7F8DA5CDB60A49D77A6B32 sha1 A26A769AAC6060705F24C3E0DDE367B62962E921 ) + rom ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De).gb" size 262144 crc 55fc585f sha1 A26A769AAC6060705F24C3E0DDE367B62962E921 ) ) game ( name "Tintin in Tibet (Europe) (En,Fr,De,Nl) (SGB Enhanced)" description "Tintin in Tibet (Europe) (En,Fr,De,Nl) (SGB Enhanced)" - rom ( name "Tintin in Tibet (Europe) (En,Fr,De,Nl) (SGB Enhanced).gb" size 262144 crc 5D2BD778 md5 EEF71C64F1A51F5E32AB4E6E5E2CC5E8 sha1 8D8978FBD5A5634E2CCE940122039D575E7B3646 ) + rom ( name "Tintin in Tibet (Europe) (En,Fr,De,Nl) (SGB Enhanced).gb" size 262144 crc 5d2bd778 sha1 8D8978FBD5A5634E2CCE940122039D575E7B3646 flags verified ) +) + +game ( + name "Tintin in Tibet (Europe) (En,Es,It,Sv) (SGB Enhanced)" + description "Tintin in Tibet (Europe) (En,Es,It,Sv) (SGB Enhanced)" + rom ( name "Tintin in Tibet (Europe) (En,Es,It,Sv) (SGB Enhanced).gb" size 262144 crc 7a7d820f sha1 A69BEE8C26A520B648A780C67E4A73D54E1BF812 flags verified ) ) game ( name "Tiny Toon Adventures (Japan)" description "Tiny Toon Adventures (Japan)" - rom ( name "Tiny Toon Adventures (Japan).gb" size 131072 crc FB13462B md5 1CEB3148A1B68B2BA9EADA0393F987FC sha1 08948315649160C62546F541F173808595F75149 ) + rom ( name "Tiny Toon Adventures (Japan).gb" size 131072 crc fb13462b sha1 08948315649160C62546F541F173808595F75149 ) ) game ( name "Tiny Toon Adventures - Babs' Big Break (USA, Europe)" description "Tiny Toon Adventures - Babs' Big Break (USA, Europe)" - rom ( name "Tiny Toon Adventures - Babs' Big Break (USA, Europe).gb" size 131072 crc 9B5E6219 md5 CBB45188C780CE5BBDF502CEB2B9994A sha1 7BAA81C93EA86A5DDB9B26545A446FE9B8979590 flags verified ) -) - -game ( - name "Tiny Toon Adventures - Dokidoki Sport Festival (Japan)" - description "Tiny Toon Adventures - Dokidoki Sport Festival (Japan)" - rom ( name "Tiny Toon Adventures - Dokidoki Sport Festival (Japan).gb" size 131072 crc 3FA10931 md5 72DFA391AABB34D0A047443EE11C83AC sha1 E4B8D9BED45083472141F6856A13B04825164166 ) + rom ( name "Tiny Toon Adventures - Babs' Big Break (USA, Europe).gb" size 131072 crc 9b5e6219 sha1 7BAA81C93EA86A5DDB9B26545A446FE9B8979590 flags verified ) ) game ( name "Tiny Toon Adventures - Wacky Sports (Europe)" description "Tiny Toon Adventures - Wacky Sports (Europe)" - rom ( name "Tiny Toon Adventures - Wacky Sports (Europe).gb" size 131072 crc D731BDA2 md5 664C613EAAAE388D828261FE8A7EDBB6 sha1 5B3E522F92C87E67A6D6C1922CE8DF4314F7F504 flags verified ) + rom ( name "Tiny Toon Adventures - Wacky Sports (Europe).gb" size 131072 crc d731bda2 sha1 5B3E522F92C87E67A6D6C1922CE8DF4314F7F504 flags verified ) ) game ( name "Tiny Toon Adventures - Wacky Sports (USA)" description "Tiny Toon Adventures - Wacky Sports (USA)" - rom ( name "Tiny Toon Adventures - Wacky Sports (USA).gb" size 131072 crc D3904BE9 md5 038BA19B06F5D3B56E9BDA495B609C54 sha1 F44ADC4A41331E31627D23305579BD4E493610DE ) + rom ( name "Tiny Toon Adventures - Wacky Sports (USA).gb" size 131072 crc d3904be9 sha1 F44ADC4A41331E31627D23305579BD4E493610DE ) ) game ( - name "Tiny Toon Adventures 2 (Japan)" - description "Tiny Toon Adventures 2 (Japan)" - rom ( name "Tiny Toon Adventures 2 (Japan).gb" size 131072 crc 0FD47F8A md5 7E893BD4B6C404843DF52288FF681325 sha1 2A32B1761F512616613E42DAF700B9D718883EB6 ) + name "Tiny Toon Adventures 2 - Buster Bunny no Kattobi Daibouken (Japan)" + description "Tiny Toon Adventures 2 - Buster Bunny no Kattobi Daibouken (Japan)" + rom ( name "Tiny Toon Adventures 2 - Buster Bunny no Kattobi Daibouken (Japan).gb" size 131072 crc 0fd47f8a sha1 2A32B1761F512616613E42DAF700B9D718883EB6 ) ) game ( name "Tiny Toon Adventures 2 - Montana's Movie Madness (USA, Europe)" description "Tiny Toon Adventures 2 - Montana's Movie Madness (USA, Europe)" - rom ( name "Tiny Toon Adventures 2 - Montana's Movie Madness (USA, Europe).gb" size 131072 crc C5C7868D md5 7AA389F71808DC989A38B41009A32851 sha1 B76AA64CC4123B7900569FF9DB680935198DB73F flags verified ) + rom ( name "Tiny Toon Adventures 2 - Montana's Movie Madness (USA, Europe).gb" size 131072 crc c5c7868d sha1 B76AA64CC4123B7900569FF9DB680935198DB73F flags verified ) +) + +game ( + name "Tiny Toon Adventures 3 - Dokidoki Sport Festival (Japan)" + description "Tiny Toon Adventures 3 - Dokidoki Sport Festival (Japan)" + rom ( name "Tiny Toon Adventures 3 - Dokidoki Sport Festival (Japan).gb" size 131072 crc 3fa10931 sha1 E4B8D9BED45083472141F6856A13B04825164166 ) ) game ( name "Tip Off (Europe)" description "Tip Off (Europe)" - rom ( name "Tip Off (Europe).gb" size 131072 crc EAF523EC md5 A617CA41254CC6DF7B82FA18E411010D sha1 A43EE2C068053E49DFC6E22A0CD781DF357905EC ) + rom ( name "Tip Off (Europe).gb" size 131072 crc eaf523ec sha1 A43EE2C068053E49DFC6E22A0CD781DF357905EC ) ) game ( - name "Titus the Fox to Marrakech and Back (USA, Europe)" - description "Titus the Fox to Marrakech and Back (USA, Europe)" - rom ( name "Titus the Fox to Marrakech and Back (USA, Europe).gb" size 262144 crc 814FA146 md5 63811BC7F768C0DE33FB2C4C702E9533 sha1 BA0037AEB21DE0BBBA3F9294A7861D90AEFA5008 flags verified ) + name "Titus the Fox (USA, Europe)" + description "Titus the Fox (USA, Europe)" + rom ( name "Titus the Fox (USA, Europe).gb" size 262144 crc 814fa146 sha1 BA0037AEB21DE0BBBA3F9294A7861D90AEFA5008 flags verified ) ) game ( name "Tokio Senki - Eiyuu Retsuden (Japan)" description "Tokio Senki - Eiyuu Retsuden (Japan)" - rom ( name "Tokio Senki - Eiyuu Retsuden (Japan).gb" size 131072 crc 9DB7DCC3 md5 EECF87A2C5DBF9F8D2AF9976B0F01F4E sha1 1AA4F93A4AD0E0A273A723C70E01494F04B1F214 ) + rom ( name "Tokio Senki - Eiyuu Retsuden (Japan).gb" size 131072 crc 9db7dcc3 sha1 1AA4F93A4AD0E0A273A723C70E01494F04B1F214 ) ) game ( name "Tokoro's Mahjong Jr. (Japan) (SGB Enhanced)" description "Tokoro's Mahjong Jr. (Japan) (SGB Enhanced)" - rom ( name "Tokoro's Mahjong Jr. (Japan) (SGB Enhanced).gb" size 262144 crc 56AFCA4C md5 9E6E3CC5A71EE19204028F13FEAE395A sha1 BC6AE2ADE135EF59AA1A213DF004252149937AA8 flags verified ) + rom ( name "Tokoro's Mahjong Jr. (Japan) (SGB Enhanced).gb" size 262144 crc 56afca4c sha1 BC6AE2ADE135EF59AA1A213DF004252149937AA8 flags verified ) ) game ( name "Tokyo Disneyland - Fantasy Tour (Japan) (SGB Enhanced)" description "Tokyo Disneyland - Fantasy Tour (Japan) (SGB Enhanced)" - rom ( name "Tokyo Disneyland - Fantasy Tour (Japan) (SGB Enhanced).gb" size 524288 crc 28B85584 md5 6DB7AA2399E9B6723E41E47C73379216 sha1 E413B0AB506CB12B68439CCC0A72E4664C112378 flags verified ) + rom ( name "Tokyo Disneyland - Fantasy Tour (Japan) (SGB Enhanced).gb" size 524288 crc 28b85584 sha1 E413B0AB506CB12B68439CCC0A72E4664C112378 flags verified ) ) game ( name "Tokyo Disneyland - Mickey no Cinderella-jou Mystery Tour (Japan) (SGB Enhanced)" description "Tokyo Disneyland - Mickey no Cinderella-jou Mystery Tour (Japan) (SGB Enhanced)" - rom ( name "Tokyo Disneyland - Mickey no Cinderella-jou Mystery Tour (Japan) (SGB Enhanced).gb" size 524288 crc 77D69349 md5 E39F8E545DADB5A6D77CA1487AE85C8F sha1 8E7AB2D9477F58254DB3DFEA749E12F535DC104C ) + rom ( name "Tokyo Disneyland - Mickey no Cinderella-jou Mystery Tour (Japan) (SGB Enhanced).gb" size 524288 crc 77d69349 sha1 8E7AB2D9477F58254DB3DFEA749E12F535DC104C ) ) game ( name "Tom & Jerry (USA, Europe)" description "Tom & Jerry (USA, Europe)" - rom ( name "Tom & Jerry (USA, Europe).gb" size 131072 crc 0636D89E md5 5AF4D81459E7E34ADFC4E065C98DD643 sha1 732C02F610D5614FCE0A092D920CF3484D0CFD38 flags verified ) + rom ( name "Tom & Jerry (USA, Europe).gb" size 131072 crc 0636d89e sha1 732C02F610D5614FCE0A092D920CF3484D0CFD38 flags verified ) ) game ( name "Tom and Jerry - Frantic Antics! (USA, Europe)" description "Tom and Jerry - Frantic Antics! (USA, Europe)" - rom ( name "Tom and Jerry - Frantic Antics! (USA, Europe).gb" size 131072 crc C2DBD1AA md5 CB61AFD7708D90D976F585EDEBCAAA89 sha1 9F8ADF286E5CE5868C758B1C2F195EF596A3DF2B flags verified ) + rom ( name "Tom and Jerry - Frantic Antics! (USA, Europe).gb" size 131072 crc c2dbd1aa sha1 9F8ADF286E5CE5868C758B1C2F195EF596A3DF2B flags verified ) ) game ( name "Tom to Jerry (Japan)" description "Tom to Jerry (Japan)" - rom ( name "Tom to Jerry (Japan).gb" size 131072 crc CA836E6D md5 40B4238E683EEA908A09F978CE5AFF2A sha1 ACCBA2ABD506321934E5E7B49A14BBBFAA261171 ) + rom ( name "Tom to Jerry (Japan).gb" size 131072 crc ca836e6d sha1 ACCBA2ABD506321934E5E7B49A14BBBFAA261171 ) ) game ( name "Tom to Jerry Part 2 (Japan)" description "Tom to Jerry Part 2 (Japan)" - rom ( name "Tom to Jerry Part 2 (Japan).gb" size 131072 crc DD19A9EC md5 2D932DC975FC98D294DFAB7D70E553EF sha1 ADCF89690D0DAF0D8E007B6B404305EF4DEC689B ) + rom ( name "Tom to Jerry Part 2 (Japan).gb" size 131072 crc dd19a9ec sha1 ADCF89690D0DAF0D8E007B6B404305EF4DEC689B ) ) game ( name "Top Gun - Guts & Glory (USA, Europe)" description "Top Gun - Guts & Glory (USA, Europe)" - rom ( name "Top Gun - Guts & Glory (USA, Europe).gb" size 131072 crc 0506C12B md5 5E022ADF9659A754A6C2A8E1CE1DE117 sha1 F23604C43798C6066B1D34FA8168A26108C64731 flags verified ) + rom ( name "Top Gun - Guts & Glory (USA, Europe).gb" size 131072 crc 0506c12b sha1 F23604C43798C6066B1D34FA8168A26108C64731 flags verified ) ) game ( name "Top Rank Tennis (USA)" description "Top Rank Tennis (USA)" - rom ( name "Top Rank Tennis (USA).gb" size 262144 crc 3C4E29B4 md5 C7FE0019FDC5887641CD6A1BB193DDD6 sha1 2FA95DFE097B31FC1A94A5E864308B417BF832D4 flags verified ) + rom ( name "Top Rank Tennis (USA).gb" size 262144 crc 3c4e29b4 sha1 2FA95DFE097B31FC1A94A5E864308B417BF832D4 flags verified ) ) game ( name "Top Ranking Tennis (Europe)" description "Top Ranking Tennis (Europe)" - rom ( name "Top Ranking Tennis (Europe).gb" size 262144 crc D577D8E0 md5 EA82922267095A2268D76E4F21D4FF93 sha1 E628B00E7F88742C99CBB51FAE4BE0D0CFA77405 flags verified ) + rom ( name "Top Ranking Tennis (Europe).gb" size 262144 crc d577d8e0 sha1 E628B00E7F88742C99CBB51FAE4BE0D0CFA77405 flags verified ) ) game ( name "Torpedo Range (Japan)" description "Torpedo Range (Japan)" - rom ( name "Torpedo Range (Japan).gb" size 131072 crc 1FB35885 md5 CC0CC9F187765DBF3054585D5B33A6EC sha1 4CD1702228D3D82ABDA1672F21B79446385A2C68 ) + rom ( name "Torpedo Range (Japan).gb" size 131072 crc 1fb35885 sha1 4CD1702228D3D82ABDA1672F21B79446385A2C68 ) ) game ( name "Torpedo Range (USA)" description "Torpedo Range (USA)" - rom ( name "Torpedo Range (USA).gb" size 131072 crc ED9882A9 md5 2B42E312AFBEE6599CE413A8784E4E68 sha1 0AAC562F0F62916839CFFE472AA21E0CEE6269F0 flags verified ) + rom ( name "Torpedo Range (USA).gb" size 131072 crc ed9882a9 sha1 0AAC562F0F62916839CFFE472AA21E0CEE6269F0 flags verified ) ) game ( name "Total Carnage (USA, Europe)" description "Total Carnage (USA, Europe)" - rom ( name "Total Carnage (USA, Europe).gb" size 131072 crc 3700927F md5 6E8EA043087F4CA441866B03389575E2 sha1 A735C8D212C5FCB47A1D25599EDB1FB815593DD1 flags verified ) + rom ( name "Total Carnage (USA, Europe).gb" size 131072 crc 3700927f sha1 A735C8D212C5FCB47A1D25599EDB1FB815593DD1 flags verified ) ) game ( name "Totsugeki Valations (Japan)" description "Totsugeki Valations (Japan)" - rom ( name "Totsugeki Valations (Japan).gb" size 65536 crc F2119A2D md5 98CCEDC1E48C22C6F505B6AC79A944FF sha1 CD4317BBF8774370D7C84B216C950D4867342793 flags verified ) + rom ( name "Totsugeki Valations (Japan).gb" size 65536 crc f2119a2d sha1 CD4317BBF8774370D7C84B216C950D4867342793 flags verified ) ) game ( name "Totsugeki! Ponkotsu Tank (Japan)" description "Totsugeki! Ponkotsu Tank (Japan)" - rom ( name "Totsugeki! Ponkotsu Tank (Japan).gb" size 131072 crc 9B5B7BFF md5 0E4A3A1F29F20DEA45638B2B72BC8A68 sha1 2BAABB0B3E846E31188388E43EF822A03C777EAD ) + rom ( name "Totsugeki! Ponkotsu Tank (Japan).gb" size 131072 crc 9b5b7bff sha1 2BAABB0B3E846E31188388E43EF822A03C777EAD flags verified ) ) game ( name "Tottemo! Lucky Man - Lucky Cookie Minna Daisuki!! (Japan) (SGB Enhanced)" description "Tottemo! Lucky Man - Lucky Cookie Minna Daisuki!! (Japan) (SGB Enhanced)" - rom ( name "Tottemo! Lucky Man - Lucky Cookie Minna Daisuki!! (Japan) (SGB Enhanced).gb" size 262144 crc 8F9E28AD md5 3208775B434D8228D1BF950B91A39E70 sha1 25E5E07B4945145F2681F0C991583335826C4F82 flags verified ) + rom ( name "Tottemo! Lucky Man - Lucky Cookie Minna Daisuki!! (Japan) (SGB Enhanced).gb" size 262144 crc 8f9e28ad sha1 25E5E07B4945145F2681F0C991583335826C4F82 flags verified ) ) game ( name "Toxic Crusaders (USA)" description "Toxic Crusaders (USA)" - rom ( name "Toxic Crusaders (USA).gb" size 131072 crc EA59C6E3 md5 EEE449A4C33F41681D0C44FEEB91AC91 sha1 236420607BE545E0156F2DF0A5982C46BC6E10E3 flags verified ) + rom ( name "Toxic Crusaders (USA).gb" size 131072 crc ea59c6e3 sha1 236420607BE545E0156F2DF0A5982C46BC6E10E3 flags verified ) ) game ( name "Toy Story (Europe) (SGB Enhanced)" description "Toy Story (Europe) (SGB Enhanced)" - rom ( name "Toy Story (Europe) (SGB Enhanced).gb" size 524288 crc D8E5060F md5 508E937DC634F36D738D65734F3AE0AB sha1 0120D5097F06EA6E222E5CEB31484F3375AF6F5B flags verified ) + rom ( name "Toy Story (Europe) (SGB Enhanced).gb" size 524288 crc d8e5060f sha1 0120D5097F06EA6E222E5CEB31484F3375AF6F5B flags verified ) ) game ( name "Toy Story (USA) (SGB Enhanced)" description "Toy Story (USA) (SGB Enhanced)" - rom ( name "Toy Story (USA) (SGB Enhanced).gb" size 524288 crc D34287CC md5 D4E7CAF41D3A12FACC5D7D5185631567 sha1 AC2CDBD6AE42EDCF407F02150ADD2C0442EC116C ) + rom ( name "Toy Story (USA) (SGB Enhanced).gb" size 524288 crc d34287cc sha1 AC2CDBD6AE42EDCF407F02150ADD2C0442EC116C ) ) game ( - name "Toy Story (USA) (Rev A) (SGB Enhanced)" - description "Toy Story (USA) (Rev A) (SGB Enhanced)" - rom ( name "Toy Story (USA) (Rev A) (SGB Enhanced).gb" size 524288 crc 6F36B6ED md5 344ED70FE1A7A8CC904EDA886543252C sha1 04227FCD3E049465F4499FEFE6519322EE492A82 ) + name "Toy Story (USA) (Rev 1) (SGB Enhanced)" + description "Toy Story (USA) (Rev 1) (SGB Enhanced)" + rom ( name "Toy Story (USA) (Rev 1) (SGB Enhanced).gb" size 524288 crc 6f36b6ed sha1 04227FCD3E049465F4499FEFE6519322EE492A82 ) ) game ( name "Track & Field (USA, Europe)" description "Track & Field (USA, Europe)" - rom ( name "Track & Field (USA, Europe).gb" size 131072 crc C0EF39F0 md5 E07A8D8AC2A2770EA1A808AC517384CC sha1 577A9F03ADDA485855C9164B4B8A2A351C214E3B flags verified ) + rom ( name "Track & Field (USA, Europe).gb" size 131072 crc c0ef39f0 sha1 577A9F03ADDA485855C9164B4B8A2A351C214E3B flags verified ) ) game ( name "Track Meet (USA, Europe)" description "Track Meet (USA, Europe)" - rom ( name "Track Meet (USA, Europe).gb" size 131072 crc 7B5DC3E4 md5 9AB4E706B5DD1BB68B4E29A0174C330D sha1 5ECB205B1B85F6C88D36386BE071A6473DE87221 flags verified ) + rom ( name "Track Meet (USA, Europe).gb" size 131072 crc 7b5dc3e4 sha1 5ECB205B1B85F6C88D36386BE071A6473DE87221 flags verified ) ) game ( name "Track Meet - Mezase! Barcelona (Japan)" description "Track Meet - Mezase! Barcelona (Japan)" - rom ( name "Track Meet - Mezase! Barcelona (Japan).gb" size 131072 crc 48D37CD2 md5 2EBBF49D18833D07D6DAE4E128CA1136 sha1 0F60CED77232215D86B9C4555CAF9880CCE008B7 flags verified ) + rom ( name "Track Meet - Mezase! Barcelona (Japan).gb" size 131072 crc 48d37cd2 sha1 0F60CED77232215D86B9C4555CAF9880CCE008B7 flags verified ) ) game ( name "Trappers Tengoku - Spy vs Spy (Japan)" description "Trappers Tengoku - Spy vs Spy (Japan)" - rom ( name "Trappers Tengoku - Spy vs Spy (Japan).gb" size 131072 crc AFEFD085 md5 15F0B057AB8B7B53914129B3BBAB6610 sha1 C9EB687F6DE7B821255FDD0CBF14F68AD789F97F ) + rom ( name "Trappers Tengoku - Spy vs Spy (Japan).gb" size 131072 crc afefd085 sha1 C9EB687F6DE7B821255FDD0CBF14F68AD789F97F ) ) game ( name "Trax (USA, Europe)" description "Trax (USA, Europe)" - rom ( name "Trax (USA, Europe).gb" size 131072 crc 4A38BE7D md5 89ECF5B28D5CC84208CFC39DC2D96598 sha1 3F3A31ED7E47319C5815DD6E31CA27A52377423C flags verified ) + rom ( name "Trax (USA, Europe).gb" size 131072 crc 4a38be7d sha1 3F3A31ED7E47319C5815DD6E31CA27A52377423C flags verified ) ) game ( name "Trip World (Europe)" description "Trip World (Europe)" - rom ( name "Trip World (Europe).gb" size 262144 crc 85D910B9 md5 C46E059A69D9B3B4B0B9D8D303C559B3 sha1 ADC10A23DD33D40740F5C8C086DFCB97B8389286 flags verified ) + rom ( name "Trip World (Europe).gb" size 262144 crc 85d910b9 sha1 ADC10A23DD33D40740F5C8C086DFCB97B8389286 flags verified ) ) game ( name "Trip World (Japan)" description "Trip World (Japan)" - rom ( name "Trip World (Japan).gb" size 262144 crc 11568E64 md5 E0A81DCC3AA0DB3896C6F46E0ED3FC80 sha1 AC19D49906E72AAEBEFFA9AB7106EB346A5EFA07 ) + rom ( name "Trip World (Japan).gb" size 262144 crc 11568e64 sha1 AC19D49906E72AAEBEFFA9AB7106EB346A5EFA07 ) ) game ( name "True Lies (USA, Europe)" description "True Lies (USA, Europe)" - rom ( name "True Lies (USA, Europe).gb" size 262144 crc EDEC63E6 md5 C013958FA8447BE55F1E037ED4A1A9F9 sha1 95DDA9821E6755C12FEC9D4C0C9DB8BB515843A6 flags verified ) + rom ( name "True Lies (USA, Europe).gb" size 262144 crc edec63e6 sha1 95DDA9821E6755C12FEC9D4C0C9DB8BB515843A6 flags verified ) ) game ( name "Trump Boy (Japan)" description "Trump Boy (Japan)" - rom ( name "Trump Boy (Japan).gb" size 32768 crc FD16AC45 md5 CE9FBFC61EC6310A524CEC0E89A9E487 sha1 192CCF904E028A44D0D959BFAE8FE4A9DCD4394E flags verified ) + rom ( name "Trump Boy (Japan).gb" size 32768 crc fd16ac45 sha1 192CCF904E028A44D0D959BFAE8FE4A9DCD4394E flags verified ) ) game ( name "Trump Boy II (Japan)" description "Trump Boy II (Japan)" - rom ( name "Trump Boy II (Japan).gb" size 65536 crc 39157849 md5 EF6F92C23B5D2BE7DB647B7D6152EC13 sha1 AC526CF1B1463B2AF83E2B3EEF3680CAA5DAE94F ) + rom ( name "Trump Boy II (Japan).gb" size 65536 crc 39157849 sha1 AC526CF1B1463B2AF83E2B3EEF3680CAA5DAE94F ) ) game ( name "Trump Collection GB (Japan)" description "Trump Collection GB (Japan)" - rom ( name "Trump Collection GB (Japan).gb" size 131072 crc 8341BE0F md5 E2133FC6F1D81CE8AA1C955C616DD1FE sha1 FD8AF42FECEF8D1C826DF7FED7859E2B03D861BA flags verified ) + rom ( name "Trump Collection GB (Japan).gb" size 131072 crc 8341be0f sha1 FD8AF42FECEF8D1C826DF7FED7859E2B03D861BA flags verified ) ) game ( name "Tsumego Series 1 - Fujisawa Hideyuki Meiyo Kisei (Japan) (SGB Enhanced)" description "Tsumego Series 1 - Fujisawa Hideyuki Meiyo Kisei (Japan) (SGB Enhanced)" - rom ( name "Tsumego Series 1 - Fujisawa Hideyuki Meiyo Kisei (Japan) (SGB Enhanced).gb" size 131072 crc CEEE6A61 md5 E01B48974B0DCD4B7DE479AC4D3D207C sha1 4C16E7298713DE7741CEB6513FA50A8B12432578 ) + rom ( name "Tsumego Series 1 - Fujisawa Hideyuki Meiyo Kisei (Japan) (SGB Enhanced).gb" size 131072 crc ceee6a61 sha1 4C16E7298713DE7741CEB6513FA50A8B12432578 flags verified ) ) game ( name "Tsumeshougi - Hyakuban Shoubu (Japan)" description "Tsumeshougi - Hyakuban Shoubu (Japan)" - rom ( name "Tsumeshougi - Hyakuban Shoubu (Japan).gb" size 65536 crc 43E2A5C0 md5 FE739C4BFDF652AF8D09ED778C429480 sha1 257A73694A6535AAFA58D346B06D2EE386989578 ) + rom ( name "Tsumeshougi - Hyakuban Shoubu (Japan).gb" size 65536 crc 43e2a5c0 sha1 257A73694A6535AAFA58D346B06D2EE386989578 ) ) game ( name "Tsumeshougi - Kanki Godan (Japan) (SGB Enhanced)" description "Tsumeshougi - Kanki Godan (Japan) (SGB Enhanced)" - rom ( name "Tsumeshougi - Kanki Godan (Japan) (SGB Enhanced).gb" size 131072 crc D5434C94 md5 F44BD95417B6A3D229282B0F5FB9BD53 sha1 2E54FAF9F97B6E590CAACB26294BDAFE40CA7214 ) + rom ( name "Tsumeshougi - Kanki Godan (Japan) (SGB Enhanced).gb" size 131072 crc d5434c94 sha1 2E54FAF9F97B6E590CAACB26294BDAFE40CA7214 ) ) game ( name "Tsumeshougi - Kanki Godan (Japan) (Beta) (SGB Enhanced)" description "Tsumeshougi - Kanki Godan (Japan) (Beta) (SGB Enhanced)" - rom ( name "Tsumeshougi - Kanki Godan (Japan) (Beta) (SGB Enhanced).gb" size 131072 crc 9995EE1A md5 B0AFDADB0804B98CD2BA41E2C59E251F sha1 EAE6CDB4425DDAE51BEE0E7D0AA956B72E897743 ) + rom ( name "Tsumeshougi - Kanki Godan (Japan) (Beta) (SGB Enhanced).gb" size 131072 crc 9995ee1a sha1 EAE6CDB4425DDAE51BEE0E7D0AA956B72E897743 flags verified ) ) game ( name "Tsumeshougi - Mondai Teikyou Shougi Sekai (Japan)" description "Tsumeshougi - Mondai Teikyou Shougi Sekai (Japan)" - rom ( name "Tsumeshougi - Mondai Teikyou Shougi Sekai (Japan).gb" size 65536 crc 6403AF06 md5 1DD179D971829C8A9CA55100390A26F5 sha1 D4D200C152B9FA1AF758333210BEF2649F0271EC ) + rom ( name "Tsumeshougi - Mondai Teikyou Shougi Sekai (Japan).gb" size 65536 crc 6403af06 sha1 D4D200C152B9FA1AF758333210BEF2649F0271EC flags verified ) ) game ( name "Tsuri Sensei (Japan) (SGB Enhanced)" description "Tsuri Sensei (Japan) (SGB Enhanced)" - rom ( name "Tsuri Sensei (Japan) (SGB Enhanced).gb" size 524288 crc DC324100 md5 CBE4DF9625A9145D00426F0E92E162F9 sha1 BE079A98F072C4B694A10154C351379529897FF6 ) + rom ( name "Tsuri Sensei (Japan) (SGB Enhanced).gb" size 524288 crc dc324100 sha1 BE079A98F072C4B694A10154C351379529897FF6 ) ) game ( name "Tumble Pop (Japan)" description "Tumble Pop (Japan)" - rom ( name "Tumble Pop (Japan).gb" size 131072 crc 881AFD62 md5 B3AF8BCD6DE27BA829C075AFFBC9F839 sha1 84A97F2DB289951CBA2EB6F7369BD6629C2687B2 ) + rom ( name "Tumble Pop (Japan).gb" size 131072 crc 881afd62 sha1 84A97F2DB289951CBA2EB6F7369BD6629C2687B2 ) ) game ( name "Tumble Pop (USA, Europe)" description "Tumble Pop (USA, Europe)" - rom ( name "Tumble Pop (USA, Europe).gb" size 131072 crc 8A3AAB31 md5 9038A85BE1595DE2A4F16B6F6DB0F3FD sha1 1B5A9B71BC14F9725B37FA0A166253F1047943B1 flags verified ) + rom ( name "Tumble Pop (USA, Europe).gb" size 131072 crc 8a3aab31 sha1 1B5A9B71BC14F9725B37FA0A166253F1047943B1 flags verified ) ) game ( - name "Turn and Burn (USA)" - description "Turn and Burn (USA)" - rom ( name "Turn and Burn (USA).gb" size 131072 crc 91394BD8 md5 18B83C9003CAEE31ED0E843A92C119A9 sha1 28BF175C8B3990F97039062C22D80BC7A524F060 ) + name "Turn and Burn - The F-14 Dogfight Simulator (USA)" + description "Turn and Burn - The F-14 Dogfight Simulator (USA)" + rom ( name "Turn and Burn - The F-14 Dogfight Simulator (USA).gb" size 131072 crc 91394bd8 sha1 28BF175C8B3990F97039062C22D80BC7A524F060 ) ) game ( name "Turok - Battle of the Bionosaurs (Japan)" description "Turok - Battle of the Bionosaurs (Japan)" - rom ( name "Turok - Battle of the Bionosaurs (Japan).gb" size 262144 crc C88E751D md5 412075E19F160DF8C3571AE37184D827 sha1 332517218856313559C483C57256977E0CE07AD7 ) + rom ( name "Turok - Battle of the Bionosaurs (Japan).gb" size 262144 crc c88e751d sha1 332517218856313559C483C57256977E0CE07AD7 ) ) game ( name "Turok - Battle of the Bionosaurs (USA, Europe) (En,Fr,De,Es)" description "Turok - Battle of the Bionosaurs (USA, Europe) (En,Fr,De,Es)" - rom ( name "Turok - Battle of the Bionosaurs (USA, Europe) (En,Fr,De,Es).gb" size 262144 crc 518C2D2F md5 FE68B048F7F77454F73DDEF30C16316F sha1 8DCECC535909EF9D1B6DAC658FA41DDCBB75C208 flags verified ) + rom ( name "Turok - Battle of the Bionosaurs (USA, Europe) (En,Fr,De,Es).gb" size 262144 crc 518c2d2f sha1 8DCECC535909EF9D1B6DAC658FA41DDCBB75C208 flags verified ) ) game ( name "Turrican (USA, Europe)" description "Turrican (USA, Europe)" - rom ( name "Turrican (USA, Europe).gb" size 131072 crc 2359BF0C md5 6534EFF4DFF0000F66A0059F0B84E71E sha1 3023B2B831BE9FE7DB62857F1B353700A1C31C75 flags verified ) + rom ( name "Turrican (USA, Europe).gb" size 131072 crc 2359bf0c sha1 3023B2B831BE9FE7DB62857F1B353700A1C31C75 flags verified ) ) game ( name "TV Champion (Japan) (SGB Enhanced)" description "TV Champion (Japan) (SGB Enhanced)" - rom ( name "TV Champion (Japan) (SGB Enhanced).gb" size 262144 crc 18F64779 md5 DE0FF9F3AD6C9DFD3F83F18E5A931A77 sha1 EDDC884FF0FEA50DC059B650728D2D3507461DFE ) + rom ( name "TV Champion (Japan) (SGB Enhanced).gb" size 262144 crc 18f64779 sha1 EDDC884FF0FEA50DC059B650728D2D3507461DFE ) ) game ( name "Twin (Japan)" description "Twin (Japan)" - rom ( name "Twin (Japan).gb" size 131072 crc 2413ACAA md5 1FCBB5903A90FB4875FDF2FC128F0D7F sha1 2075027F6A45D1D970908254680077F3D18A3B1F flags verified ) + rom ( name "Twin (Japan).gb" size 131072 crc 2413acaa sha1 2075027F6A45D1D970908254680077F3D18A3B1F flags verified ) ) game ( name "TwinBee da!! (Japan)" description "TwinBee da!! (Japan)" - rom ( name "TwinBee da!! (Japan).gb" size 131072 crc 017FD6F5 md5 0325E6464931DCE2A777635E71EEE877 sha1 8F1C54D2116118BA085B384A01EA0C410AD2DEAC flags verified ) + rom ( name "TwinBee da!! (Japan).gb" size 131072 crc 017fd6f5 sha1 8F1C54D2116118BA085B384A01EA0C410AD2DEAC flags verified ) ) game ( name "Uchiiwai - Kyoudaijingi no Puzzle Game (Japan)" description "Uchiiwai - Kyoudaijingi no Puzzle Game (Japan)" - rom ( name "Uchiiwai - Kyoudaijingi no Puzzle Game (Japan).gb" size 65536 crc 8059BC15 md5 EB43C1DF87041D6B82E789A2B46927BE sha1 8992F55380B6AE7DA14DCC3B3158C5C160953A1C ) + rom ( name "Uchiiwai - Kyoudaijingi no Puzzle Game (Japan).gb" size 65536 crc 8059bc15 sha1 8992F55380B6AE7DA14DCC3B3158C5C160953A1C ) ) game ( name "Uchuu no Kishi Tekkaman Blade (Japan)" description "Uchuu no Kishi Tekkaman Blade (Japan)" - rom ( name "Uchuu no Kishi Tekkaman Blade (Japan).gb" size 131072 crc 22D8889E md5 801548B89F31101653539988D7635DBA sha1 ED7370F4D59CCE1EDB76E28BDCBE5E79FA3C07C4 ) + rom ( name "Uchuu no Kishi Tekkaman Blade (Japan).gb" size 131072 crc 22d8889e sha1 ED7370F4D59CCE1EDB76E28BDCBE5E79FA3C07C4 flags verified ) ) game ( name "Uchuu Senkan Yamato (Japan)" description "Uchuu Senkan Yamato (Japan)" - rom ( name "Uchuu Senkan Yamato (Japan).gb" size 262144 crc 5BF747F8 md5 CEE4EFE750F6BB6AD685A9D1D912A1CA sha1 574CFB77817D3466672A9B39E6E8D467295FFD66 ) + rom ( name "Uchuu Senkan Yamato (Japan).gb" size 262144 crc 5bf747f8 sha1 574CFB77817D3466672A9B39E6E8D467295FFD66 ) ) game ( name "Ultima - Runes of Virtue (USA)" description "Ultima - Runes of Virtue (USA)" - rom ( name "Ultima - Runes of Virtue (USA).gb" size 131072 crc C44A0F1E md5 411C3D168141D10EDDD93243F2A7765F sha1 8D911CBBC6BD1518A85282DEF7F01D3ADD16E596 flags verified ) + rom ( name "Ultima - Runes of Virtue (USA).gb" size 131072 crc c44a0f1e sha1 8D911CBBC6BD1518A85282DEF7F01D3ADD16E596 flags verified ) ) game ( name "Ultima - Runes of Virtue II (USA)" description "Ultima - Runes of Virtue II (USA)" - rom ( name "Ultima - Runes of Virtue II (USA).gb" size 262144 crc C449FBBF md5 15CD267D7805FE9F1769E9644A9CEC2E sha1 99C4FBF832EDB9B58960EC744AE784B55C7D63D2 flags verified ) + rom ( name "Ultima - Runes of Virtue II (USA).gb" size 262144 crc c449fbbf sha1 99C4FBF832EDB9B58960EC744AE784B55C7D63D2 flags verified ) ) game ( name "Ultima - Ushinawareta Runes (Japan)" description "Ultima - Ushinawareta Runes (Japan)" - rom ( name "Ultima - Ushinawareta Runes (Japan).gb" size 131072 crc D2F94181 md5 DD519F58F68E27B70C29CF19500A0154 sha1 3A1D88736E13436CDE15029DADD951B0B1C637E5 flags verified ) + rom ( name "Ultima - Ushinawareta Runes (Japan).gb" size 131072 crc d2f94181 sha1 3A1D88736E13436CDE15029DADD951B0B1C637E5 flags verified ) ) game ( - name "Ultima - Ushinawareta Runes II (Japan)" - description "Ultima - Ushinawareta Runes II (Japan)" - rom ( name "Ultima - Ushinawareta Runes II (Japan).gb" size 262144 crc 796FD6A5 md5 F391C76A46776967729B8607B4A3AACB sha1 F83A209C29E324578E74FB1CC7B3C990DD5A67A9 ) + name "Ultima - Ushinawareta Runes 2 (Japan)" + description "Ultima - Ushinawareta Runes 2 (Japan)" + rom ( name "Ultima - Ushinawareta Runes 2 (Japan).gb" size 262144 crc 796fd6a5 sha1 F83A209C29E324578E74FB1CC7B3C990DD5A67A9 ) ) game ( name "Ultra Golf (USA)" description "Ultra Golf (USA)" - rom ( name "Ultra Golf (USA).gb" size 131072 crc 12DE9BAC md5 0A1CBC05D75C2BD3E01AAD3ACB4E4019 sha1 A20C0A995A91B20646564965705FAD129474E9BF ) + rom ( name "Ultra Golf (USA).gb" size 131072 crc 12de9bac sha1 A20C0A995A91B20646564965705FAD129474E9BF ) ) game ( name "Ultraman (Japan)" description "Ultraman (Japan)" - rom ( name "Ultraman (Japan).gb" size 131072 crc 5944C3ED md5 1B5AEBB54D59121D8DC3188929295607 sha1 A4FBE124B257109BA9566FAE59AC008F52317F2D ) + rom ( name "Ultraman (Japan).gb" size 131072 crc 5944c3ed sha1 A4FBE124B257109BA9566FAE59AC008F52317F2D ) ) game ( name "Ultraman Ball (Japan) (SGB Enhanced)" description "Ultraman Ball (Japan) (SGB Enhanced)" - rom ( name "Ultraman Ball (Japan) (SGB Enhanced).gb" size 131072 crc 468D1A2E md5 90A0BC783FBE56748989D8FAD9AE48ED sha1 3CDFCFB1A88D0CBFEB1C7B12751409FAF69BBA02 ) + rom ( name "Ultraman Ball (Japan) (SGB Enhanced).gb" size 131072 crc 468d1a2e sha1 3CDFCFB1A88D0CBFEB1C7B12751409FAF69BBA02 ) ) game ( name "Ultraman Chou Toushi Gekiden (Japan) (SGB Enhanced)" description "Ultraman Chou Toushi Gekiden (Japan) (SGB Enhanced)" - rom ( name "Ultraman Chou Toushi Gekiden (Japan) (SGB Enhanced).gb" size 262144 crc B904230D md5 9BE2B2635BD25B97A7599AB1DF84A49A sha1 1A55B76A4039FB6FF1EF0B1914DD9A7CCDDDE2B2 ) + rom ( name "Ultraman Chou Toushi Gekiden (Japan) (SGB Enhanced).gb" size 262144 crc b904230d sha1 1A55B76A4039FB6FF1EF0B1914DD9A7CCDDDE2B2 ) ) game ( name "Ultraman Club - Tekikaijuu o Hakken seyo! (Japan)" description "Ultraman Club - Tekikaijuu o Hakken seyo! (Japan)" - rom ( name "Ultraman Club - Tekikaijuu o Hakken seyo! (Japan).gb" size 65536 crc 91EDA860 md5 3ABA896B1761F25D558B2EE409E0137F sha1 298B912DD8CDDC078B60B75718ECA25870142A18 flags verified ) + rom ( name "Ultraman Club - Tekikaijuu o Hakken seyo! (Japan).gb" size 65536 crc 91eda860 sha1 298B912DD8CDDC078B60B75718ECA25870142A18 flags verified ) ) game ( name "Umi no Nushi Tsuri 2 (Japan) (SGB Enhanced)" description "Umi no Nushi Tsuri 2 (Japan) (SGB Enhanced)" - rom ( name "Umi no Nushi Tsuri 2 (Japan) (SGB Enhanced).gb" size 524288 crc 19FF5B3E md5 27A131651700B396D593AF89E625325F sha1 8E533BEA9CE1CE1F5A984E7CC4414F02BC98F1C1 flags verified ) + rom ( name "Umi no Nushi Tsuri 2 (Japan) (SGB Enhanced).gb" size 524288 crc 19ff5b3e sha1 8E533BEA9CE1CE1F5A984E7CC4414F02BC98F1C1 flags verified ) ) game ( name "Undercover Cops Gaiden - Hakaishin Garumaa (Japan)" description "Undercover Cops Gaiden - Hakaishin Garumaa (Japan)" - rom ( name "Undercover Cops Gaiden - Hakaishin Garumaa (Japan).gb" size 262144 crc B7AF37F5 md5 5294A5FED7E88A6F76707979C83017D6 sha1 E391EA099CE371EEF858D57E6C2DA63A25944472 ) + rom ( name "Undercover Cops Gaiden - Hakaishin Garumaa (Japan).gb" size 262144 crc b7af37f5 sha1 E391EA099CE371EEF858D57E6C2DA63A25944472 ) ) game ( name "Universal Soldier (USA, Europe)" description "Universal Soldier (USA, Europe)" - rom ( name "Universal Soldier (USA, Europe).gb" size 262144 crc 99AE9D06 md5 545277C74A3FBEDA2C9213D49659FFDD sha1 DBAF863D66A1E4C0A4F022BB2B228F0547674CDE flags verified ) + rom ( name "Universal Soldier (USA, Europe).gb" size 262144 crc 99ae9d06 sha1 DBAF863D66A1E4C0A4F022BB2B228F0547674CDE flags verified ) ) game ( name "Uno - Small World (Japan)" description "Uno - Small World (Japan)" - rom ( name "Uno - Small World (Japan).gb" size 262144 crc A37C022D md5 FE877B7AC3F3093144907F4C971FA940 sha1 4A0EB686CBEE455197E0890210FADE5C21B4954B ) + rom ( name "Uno - Small World (Japan).gb" size 262144 crc a37c022d sha1 4A0EB686CBEE455197E0890210FADE5C21B4954B ) ) game ( name "Uno 2 - Small World (Japan) (SGB Enhanced)" description "Uno 2 - Small World (Japan) (SGB Enhanced)" - rom ( name "Uno 2 - Small World (Japan) (SGB Enhanced).gb" size 131072 crc A7AD65EF md5 82D3FADE3EDBDD033752B8C1DD72481B sha1 D2D281DA240779A3605356513132687A485C0B39 ) + rom ( name "Uno 2 - Small World (Japan) (SGB Enhanced).gb" size 131072 crc a7ad65ef sha1 D2D281DA240779A3605356513132687A485C0B39 ) ) game ( name "Uoozu (Japan)" description "Uoozu (Japan)" - rom ( name "Uoozu (Japan).gb" size 65536 crc F7E1C9C5 md5 E0E45A92AAF878544DE84EF4867B8595 sha1 D1B466B5A46DE120D18309EFADE02D1745760D70 ) + rom ( name "Uoozu (Japan).gb" size 65536 crc f7e1c9c5 sha1 D1B466B5A46DE120D18309EFADE02D1745760D70 flags verified ) ) game ( name "Urban Strike (USA, Europe) (SGB Enhanced)" description "Urban Strike (USA, Europe) (SGB Enhanced)" - rom ( name "Urban Strike (USA, Europe) (SGB Enhanced).gb" size 524288 crc 89625945 md5 D42A0F2F9205E81CBBBE132711D69D58 sha1 6BC1010AAD73D2CDE677F897ADB77684D9B508ED flags verified ) + rom ( name "Urban Strike (USA, Europe) (SGB Enhanced).gb" size 524288 crc 89625945 sha1 6BC1010AAD73D2CDE677F897ADB77684D9B508ED flags verified ) ) game ( name "Urusei Yatsura - Miss Tomobiki o Sagase! (Japan)" description "Urusei Yatsura - Miss Tomobiki o Sagase! (Japan)" - rom ( name "Urusei Yatsura - Miss Tomobiki o Sagase! (Japan).gb" size 262144 crc 56800C6B md5 073F048EBEA0012BCA0649ED1277078D sha1 F7AC15B9B38027AE473120748E9686C985A40E87 flags verified ) + rom ( name "Urusei Yatsura - Miss Tomobiki o Sagase! (Japan).gb" size 262144 crc 56800c6b sha1 F7AC15B9B38027AE473120748E9686C985A40E87 flags verified ) ) game ( name "V-Rally - Championship Edition (Europe) (En,Fr,De)" description "V-Rally - Championship Edition (Europe) (En,Fr,De)" - rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De).gb" size 262144 crc D149652B md5 FB0ADFF5EFE92C9D3A26BE9313BCC236 sha1 67D2A6E41B6A1D8372808535AC8C8222D7C53480 flags verified ) + rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De).gb" size 262144 crc d149652b sha1 67D2A6E41B6A1D8372808535AC8C8222D7C53480 flags verified ) ) game ( name "Vattle Giuce (Japan)" description "Vattle Giuce (Japan)" - rom ( name "Vattle Giuce (Japan).gb" size 131072 crc 956B603C md5 813755DE3D7338C9442F072ED52F52B3 sha1 CA41CD69249A9EE703ACFAD044759BAA42EF2C9A flags verified ) + rom ( name "Vattle Giuce (Japan).gb" size 131072 crc 956b603c sha1 CA41CD69249A9EE703ACFAD044759BAA42EF2C9A flags verified ) ) game ( name "Vegas Stakes (USA, Europe) (SGB Enhanced)" description "Vegas Stakes (USA, Europe) (SGB Enhanced)" - rom ( name "Vegas Stakes (USA, Europe) (SGB Enhanced).gb" size 524288 crc C8BE05D8 md5 F597728869D7CA129F507E723D17BCA1 sha1 93CDF04A473DCFD7F8F4FB06CC0AF857D16D00F2 flags verified ) + rom ( name "Vegas Stakes (USA, Europe) (SGB Enhanced).gb" size 524288 crc c8be05d8 sha1 93CDF04A473DCFD7F8F4FB06CC0AF857D16D00F2 flags verified ) ) game ( name "Velious - Roland no Majuu (Japan)" description "Velious - Roland no Majuu (Japan)" - rom ( name "Velious - Roland no Majuu (Japan).gb" size 65536 crc 0817AA32 md5 F45CACA57F16D21FF0FD7AA431FE4B6A sha1 DD29DA7D83BA9DAEBF16101E2CA8CC807EECA89D flags verified ) + rom ( name "Velious - Roland no Majuu (Japan).gb" size 65536 crc 0817aa32 sha1 DD29DA7D83BA9DAEBF16101E2CA8CC807EECA89D flags verified ) ) game ( name "Velious II - Fukushuu no Jashin (Japan)" description "Velious II - Fukushuu no Jashin (Japan)" - rom ( name "Velious II - Fukushuu no Jashin (Japan).gb" size 131072 crc B55EB427 md5 08C8EF36FD4979E404DFE041ADDDFCA5 sha1 D0B009BEF968DA587148623F9727128CE1AA80E8 ) + rom ( name "Velious II - Fukushuu no Jashin (Japan).gb" size 131072 crc b55eb427 sha1 D0B009BEF968DA587148623F9727128CE1AA80E8 ) ) game ( name "Versus Hero - Kakutou Ou e no Michi (Japan)" description "Versus Hero - Kakutou Ou e no Michi (Japan)" - rom ( name "Versus Hero - Kakutou Ou e no Michi (Japan).gb" size 131072 crc 449CF2E4 md5 80BC594310A940FEB9512CF3233BED71 sha1 AC60BEECCCEA7537AD6C6779176D92056C1436FE flags verified ) + rom ( name "Versus Hero - Kakutou Ou e no Michi (Japan).gb" size 131072 crc 449cf2e4 sha1 AC60BEECCCEA7537AD6C6779176D92056C1436FE flags verified ) ) game ( name "Virtual Wars (Japan)" description "Virtual Wars (Japan)" - rom ( name "Virtual Wars (Japan).gb" size 131072 crc 220BBCB6 md5 0B72B9F0C2CE0B832C650BBCC974B023 sha1 CB256EE50FB5106C84D96F2F23CF18DE3AFBD276 ) + rom ( name "Virtual Wars (Japan).gb" size 131072 crc 220bbcb6 sha1 CB256EE50FB5106C84D96F2F23CF18DE3AFBD276 ) ) game ( name "Vitamina Oukoku Monogatari (Japan)" description "Vitamina Oukoku Monogatari (Japan)" - rom ( name "Vitamina Oukoku Monogatari (Japan).gb" size 262144 crc 89A7AECA md5 D3D63BF466E63AF0601016F87FFC3EE2 sha1 D4195257A2DEBE78AA4DD433A324AEC335AD36D1 ) + rom ( name "Vitamina Oukoku Monogatari (Japan).gb" size 262144 crc 89a7aeca sha1 D4195257A2DEBE78AA4DD433A324AEC335AD36D1 flags verified ) ) game ( name "Volley Fire (Japan)" description "Volley Fire (Japan)" - rom ( name "Volley Fire (Japan).gb" size 32768 crc 0D06EA32 md5 308F35E84B1984ABA38814DB00A4E769 sha1 4C90E2C4A0B24983B339AF8C0405CD5F4BF8881F ) + rom ( name "Volley Fire (Japan).gb" size 32768 crc 0d06ea32 sha1 4C90E2C4A0B24983B339AF8C0405CD5F4BF8881F flags verified ) ) game ( name "VS Battler (Japan)" description "VS Battler (Japan)" - rom ( name "VS Battler (Japan).gb" size 65536 crc 20AE389A md5 B394B99267DA2B55C74FC67C369C1057 sha1 5F99C7767CBBF5AD9164805214875D7054F49F14 flags verified ) + rom ( name "VS Battler (Japan).gb" size 65536 crc 20ae389a sha1 5F99C7767CBBF5AD9164805214875D7054F49F14 flags verified ) ) game ( name "Wario Blast featuring Bomberman! (USA, Europe) (SGB Enhanced)" description "Wario Blast featuring Bomberman! (USA, Europe) (SGB Enhanced)" - rom ( name "Wario Blast featuring Bomberman! (USA, Europe) (SGB Enhanced).gb" size 262144 crc 927B57A1 md5 14FE7234EE4BCB14ADF20C743F084A35 sha1 279FB0223E362DB553B739B1B8F9C18B81D92413 flags verified ) + rom ( name "Wario Blast featuring Bomberman! (USA, Europe) (SGB Enhanced).gb" size 262144 crc 927b57a1 sha1 279FB0223E362DB553B739B1B8F9C18B81D92413 flags verified ) ) game ( name "Wario Land - Super Mario Land 3 (World)" description "Wario Land - Super Mario Land 3 (World)" - rom ( name "Wario Land - Super Mario Land 3 (World).gb" size 524288 crc 40BE3889 md5 D9D957771484EF846D4E8D241F6F2815 sha1 AE65800302438E37A99E623A71D1C954D73C843E flags verified ) + rom ( name "Wario Land - Super Mario Land 3 (World).gb" size 524288 crc 40be3889 sha1 AE65800302438E37A99E623A71D1C954D73C843E flags verified ) ) game ( name "Wario Land II (USA, Europe) (SGB Enhanced)" description "Wario Land II (USA, Europe) (SGB Enhanced)" - rom ( name "Wario Land II (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 9C54358D md5 E5E8910D436ACB9FD218559A216501A3 sha1 C65820B2E52D00E6CE60E0A432FAB002FEC4386F flags verified ) + rom ( name "Wario Land II (USA, Europe) (SGB Enhanced).gb" size 1048576 crc 9c54358d sha1 C65820B2E52D00E6CE60E0A432FAB002FEC4386F flags verified ) ) game ( - name "Water World (Europe)" - description "Water World (Europe)" - rom ( name "Water World (Europe).gb" size 262144 crc 4786FD6E md5 93E66350FFD7403827914B80D233C989 sha1 E669D47B124A1E12D73F4AC80D8B4C0F917CB058 flags verified ) + name "Waterworld (Europe)" + description "Waterworld (Europe)" + rom ( name "Waterworld (Europe).gb" size 262144 crc 4786fd6e sha1 E669D47B124A1E12D73F4AC80D8B4C0F917CB058 flags verified ) ) game ( name "Wave Race (USA, Europe)" description "Wave Race (USA, Europe)" - rom ( name "Wave Race (USA, Europe).gb" size 131072 crc A6595506 md5 10FD41703B816FCB2A3D6766574B98F9 sha1 87ECDFE518F1707429FDBDC21D12BBFE1FF52252 flags verified ) + rom ( name "Wave Race (USA, Europe).gb" size 131072 crc a6595506 sha1 87ECDFE518F1707429FDBDC21D12BBFE1FF52252 flags verified ) ) game ( name "Wayne's World (USA)" description "Wayne's World (USA)" - rom ( name "Wayne's World (USA).gb" size 262144 crc 829EA425 md5 A2B68B9472BDE2D2FEE32C2EC87FF017 sha1 7165B8F31F1C5F783C8CAD0399A3D71E87091BA2 ) + rom ( name "Wayne's World (USA).gb" size 262144 crc 829ea425 sha1 7165B8F31F1C5F783C8CAD0399A3D71E87091BA2 ) ) game ( - name "WCW Main Event (USA, Europe)" - description "WCW Main Event (USA, Europe)" - rom ( name "WCW Main Event (USA, Europe).gb" size 131072 crc 974E712B md5 69A775EA530E2390F2F97CB648A567A8 sha1 481750149A0C4812128F0607A6DA338CFDDF2CEA flags verified ) + name "WCW - The Main Event (USA, Europe)" + description "WCW - The Main Event (USA, Europe)" + rom ( name "WCW - The Main Event (USA, Europe).gb" size 131072 crc 974e712b sha1 481750149A0C4812128F0607A6DA338CFDDF2CEA flags verified ) ) game ( name "We're Back! - A Dinosaur's Story (USA, Europe)" description "We're Back! - A Dinosaur's Story (USA, Europe)" - rom ( name "We're Back! - A Dinosaur's Story (USA, Europe).gb" size 131072 crc C811560B md5 C0D8ED063B30614C71D15D4D0FF08FFE sha1 EF58224F406CDF66BBE3797E2EF82A453FB1C18C flags verified ) + rom ( name "We're Back! - A Dinosaur's Story (USA, Europe).gb" size 131072 crc c811560b sha1 EF58224F406CDF66BBE3797E2EF82A453FB1C18C flags verified ) ) game ( name "Wedding Peach - Jamapii Panic (Japan) (SGB Enhanced)" description "Wedding Peach - Jamapii Panic (Japan) (SGB Enhanced)" - rom ( name "Wedding Peach - Jamapii Panic (Japan) (SGB Enhanced).gb" size 262144 crc 9812A6C6 md5 1CB08C8447160F9757D1A48331FB05A2 sha1 B10BEA6E0E57A19CDE7F02C7E97227E002CFC6B3 ) + rom ( name "Wedding Peach - Jamapii Panic (Japan) (SGB Enhanced).gb" size 262144 crc 9812a6c6 sha1 B10BEA6E0E57A19CDE7F02C7E97227E002CFC6B3 ) ) game ( name "Welcome Nakayoshi Park (Japan)" description "Welcome Nakayoshi Park (Japan)" - rom ( name "Welcome Nakayoshi Park (Japan).gb" size 262144 crc F6E2BAAE md5 7D5928376A16252833A1EDA86FB65448 sha1 8779A1557BA0DE3C5C8B770413F30BD31717B2EF ) + rom ( name "Welcome Nakayoshi Park (Japan).gb" size 262144 crc f6e2baae sha1 8779A1557BA0DE3C5C8B770413F30BD31717B2EF ) ) game ( name "Wheel of Fortune (USA)" description "Wheel of Fortune (USA)" - rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408FE48 md5 EE81C7D7481BB6DB26BEF691BF9D5645 sha1 43DE94EDA492BFABBDC6E232AF9CBD9DF080DFD5 flags verified ) + rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408fe48 sha1 43DE94EDA492BFABBDC6E232AF9CBD9DF080DFD5 flags verified ) ) game ( name "Who Framed Roger Rabbit (Europe)" description "Who Framed Roger Rabbit (Europe)" - rom ( name "Who Framed Roger Rabbit (Europe).gb" size 131072 crc DBEED84E md5 34310686415C87DFE69882A6AD3F548F sha1 4D59882150FC28733902E5E6DE8F19A751BD7913 ) + rom ( name "Who Framed Roger Rabbit (Europe).gb" size 131072 crc dbeed84e sha1 4D59882150FC28733902E5E6DE8F19A751BD7913 flags verified ) ) game ( name "Who Framed Roger Rabbit (USA)" description "Who Framed Roger Rabbit (USA)" - rom ( name "Who Framed Roger Rabbit (USA).gb" size 131072 crc B93138FA md5 692FC5A0B6A9893D6EA25326C55CAAE5 sha1 7E52D507B96FB06C46EF2C885FE58238A3BCF4A8 flags verified ) + rom ( name "Who Framed Roger Rabbit (USA).gb" size 131072 crc b93138fa sha1 7E52D507B96FB06C46EF2C885FE58238A3BCF4A8 flags verified ) ) game ( name "Who Framed Roger Rabbit (Spain)" description "Who Framed Roger Rabbit (Spain)" - rom ( name "Who Framed Roger Rabbit (Spain).gb" size 131072 crc CD11C917 md5 1D0889833ED086C6B11C1FC4D40F9F3A sha1 D92515A09D78099238565BB0F1873F57F00B6728 flags verified ) + rom ( name "Who Framed Roger Rabbit (Spain).gb" size 131072 crc cd11c917 sha1 D92515A09D78099238565BB0F1873F57F00B6728 flags verified ) ) game ( name "Wild Snake (USA) (SGB Enhanced)" description "Wild Snake (USA) (SGB Enhanced)" - rom ( name "Wild Snake (USA) (SGB Enhanced).gb" size 65536 crc 72462125 md5 F9302265FCBC4178C84AAEAC3138AF97 sha1 0EA5C37262BA60EF97DD14F8F673F951534CCD38 ) + rom ( name "Wild Snake (USA) (SGB Enhanced).gb" size 65536 crc 72462125 sha1 0EA5C37262BA60EF97DD14F8F673F951534CCD38 ) ) game ( name "Winner's Horse (Japan)" description "Winner's Horse (Japan)" - rom ( name "Winner's Horse (Japan).gb" size 131072 crc 14E91757 md5 C8D156A2D4F38F56EC3AA9E405E540B3 sha1 4D3A56C78EDE434C55994B0452B74358FADF78FE flags verified ) + rom ( name "Winner's Horse (Japan).gb" size 131072 crc 14e91757 sha1 4D3A56C78EDE434C55994B0452B74358FADF78FE flags verified ) ) game ( name "Winter Gold (Europe)" description "Winter Gold (Europe)" - rom ( name "Winter Gold (Europe).gb" size 131072 crc 3C4CD245 md5 560C9262B03CF479B6EE544E09C161B4 sha1 6AB5C2EE2157E81B5584562A5E386FB7434B3F80 ) + rom ( name "Winter Gold (Europe).gb" size 131072 crc 3c4cd245 sha1 6AB5C2EE2157E81B5584562A5E386FB7434B3F80 ) ) game ( - name "Wizardry Gaiden 1 - Joou no Junan (Japan)" - description "Wizardry Gaiden 1 - Joou no Junan (Japan)" - rom ( name "Wizardry Gaiden 1 - Joou no Junan (Japan).gb" size 262144 crc 4D640E73 md5 14D6A5E430452DCA394BD3E641DC327B sha1 E3D03144E4C15522A1469A87EB07130C1884E225 ) + name "Wizardry Gaiden I - Joou no Junan (Japan)" + description "Wizardry Gaiden I - Joou no Junan (Japan)" + rom ( name "Wizardry Gaiden I - Joou no Junan (Japan).gb" size 262144 crc 4d640e73 sha1 E3D03144E4C15522A1469A87EB07130C1884E225 ) ) game ( - name "Wizardry Gaiden 2 - Kodai Koutei no Noroi (Japan)" - description "Wizardry Gaiden 2 - Kodai Koutei no Noroi (Japan)" - rom ( name "Wizardry Gaiden 2 - Kodai Koutei no Noroi (Japan).gb" size 262144 crc F6826D12 md5 177F5FC642F650E45BAE33B10BA1FE48 sha1 8DC0AB82462D4AB287D8155E8EAB7E796EB7C766 flags verified ) + name "Wizardry Gaiden II - Kodai Koutei no Noroi (Japan)" + description "Wizardry Gaiden II - Kodai Koutei no Noroi (Japan)" + rom ( name "Wizardry Gaiden II - Kodai Koutei no Noroi (Japan).gb" size 262144 crc f6826d12 sha1 8DC0AB82462D4AB287D8155E8EAB7E796EB7C766 flags verified ) ) game ( - name "Wizardry Gaiden 3 - Yami no Seiten (Japan)" - description "Wizardry Gaiden 3 - Yami no Seiten (Japan)" - rom ( name "Wizardry Gaiden 3 - Yami no Seiten (Japan).gb" size 524288 crc 32C94538 md5 2BE59D4C20728300C84A71FCFCB565F9 sha1 E169014CF1F12B956F8DFF040DDB063EA4F7CAB9 ) + name "Wizardry Gaiden III - Yami no Seiten (Japan)" + description "Wizardry Gaiden III - Yami no Seiten (Japan)" + rom ( name "Wizardry Gaiden III - Yami no Seiten (Japan).gb" size 524288 crc 32c94538 sha1 E169014CF1F12B956F8DFF040DDB063EA4F7CAB9 ) ) game ( - name "Wizards & Warriors Chapter X - The Fortress of Fear (USA, Europe)" - description "Wizards & Warriors Chapter X - The Fortress of Fear (USA, Europe)" - rom ( name "Wizards & Warriors Chapter X - The Fortress of Fear (USA, Europe).gb" size 65536 crc 104EB503 md5 F9445B104EBB70D8FB91C8C64452C0A4 sha1 22A514056E58263DC08602778BC3BF2C0CA6E681 flags verified ) + name "Wizards & Warriors X - The Fortress of Fear (USA, Europe)" + description "Wizards & Warriors X - The Fortress of Fear (USA, Europe)" + rom ( name "Wizards & Warriors X - The Fortress of Fear (USA, Europe).gb" size 65536 crc 104eb503 sha1 22A514056E58263DC08602778BC3BF2C0CA6E681 flags verified ) ) game ( name "Wordtris (USA)" description "Wordtris (USA)" - rom ( name "Wordtris (USA).gb" size 131072 crc 075A8231 md5 29C71C474C2FA00EEAC79DDB55C2C174 sha1 AB68498646FB2CA1DF9443E6A80062C30B3EA4F9 ) + rom ( name "Wordtris (USA).gb" size 131072 crc 075a8231 sha1 AB68498646FB2CA1DF9443E6A80062C30B3EA4F9 ) +) + +game ( + name "Wordtris (USA) (Beta)" + description "Wordtris (USA) (Beta)" + rom ( name "Wordtris (USA) (Beta).gb" size 131072 crc c2d7d11b sha1 97544A78925F6BB095C7B2F14878B2E1467DC7D1 flags verified ) ) game ( name "WordZap (USA)" description "WordZap (USA)" - rom ( name "WordZap (USA).gb" size 65536 crc E8E57B50 md5 E9AB23A96409060054A05344B536B33C sha1 3B38771E97EB6CD5E053AC8908482F59DC07248B ) + rom ( name "WordZap (USA).gb" size 65536 crc e8e57b50 sha1 3B38771E97EB6CD5E053AC8908482F59DC07248B ) ) game ( name "World Beach Volley - 1991 GB Cup (Japan)" description "World Beach Volley - 1991 GB Cup (Japan)" - rom ( name "World Beach Volley - 1991 GB Cup (Japan).gb" size 131072 crc A2894581 md5 7ECA7A38F204DFA33DC3A4C039A92176 sha1 8FFB79814859A705070A6612313E853DD452A9FF ) + rom ( name "World Beach Volley - 1991 GB Cup (Japan).gb" size 131072 crc a2894581 sha1 8FFB79814859A705070A6612313E853DD452A9FF flags verified ) ) game ( name "World Beach Volley - 1992 GB Cup (Europe)" description "World Beach Volley - 1992 GB Cup (Europe)" - rom ( name "World Beach Volley - 1992 GB Cup (Europe).gb" size 131072 crc 4023E085 md5 54CDFD90C8038846714643B2A68C6BB8 sha1 0D98DD2A489D0C26F153203E14D5997EB2365847 ) + rom ( name "World Beach Volley - 1992 GB Cup (Europe).gb" size 131072 crc 4023e085 sha1 0D98DD2A489D0C26F153203E14D5997EB2365847 flags verified ) ) game ( name "World Bowling (Japan)" description "World Bowling (Japan)" - rom ( name "World Bowling (Japan).gb" size 32768 crc 47FEADF2 md5 70DAEC5B8CDF7E870A8B21A1B1253945 sha1 C99595DE26E63E65D61446DC0338256B9831601A flags verified ) + rom ( name "World Bowling (Japan).gb" size 32768 crc 47feadf2 sha1 C99595DE26E63E65D61446DC0338256B9831601A flags verified ) ) game ( name "World Bowling (USA)" description "World Bowling (USA)" - rom ( name "World Bowling (USA).gb" size 32768 crc 896E76A2 md5 E8D2A7833FD082F8CC62277D02E84A30 sha1 F579890B04B33965C009DD3B7300623691AE206A ) + rom ( name "World Bowling (USA).gb" size 32768 crc 896e76a2 sha1 F579890B04B33965C009DD3B7300623691AE206A ) ) game ( name "World Circuit Series (USA)" description "World Circuit Series (USA)" - rom ( name "World Circuit Series (USA).gb" size 131072 crc 77C3AA0B md5 D9774AF8EDB8969ADFD3693D5D7AB166 sha1 9AA2B4330A2B8FFD117A871660F2526C4B2B4753 ) + rom ( name "World Circuit Series (USA).gb" size 131072 crc 77c3aa0b sha1 9AA2B4330A2B8FFD117A871660F2526C4B2B4753 ) ) game ( name "World Cup 98 (USA, Europe) (SGB Enhanced)" description "World Cup 98 (USA, Europe) (SGB Enhanced)" - rom ( name "World Cup 98 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6A3272B1 md5 EC4B05B3483B384691886FEBFFDD7A77 sha1 F71A802596D2A56EE3E708ECAC90735D42757E5B flags verified ) + rom ( name "World Cup 98 (USA, Europe) (SGB Enhanced).gb" size 524288 crc 6a3272b1 sha1 F71A802596D2A56EE3E708ECAC90735D42757E5B flags verified ) ) game ( name "World Cup Striker (Japan)" description "World Cup Striker (Japan)" - rom ( name "World Cup Striker (Japan).gb" size 131072 crc FDEFA88D md5 C5F51C42357790B7693198FC06F82390 sha1 9CF86669D784A724EEB3409DF732CE84AFD38942 ) + rom ( name "World Cup Striker (Japan).gb" size 131072 crc fdefa88d sha1 9CF86669D784A724EEB3409DF732CE84AFD38942 ) ) game ( - name "World Cup USA '94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" - description "World Cup USA '94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" - rom ( name "World Cup USA '94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gb" size 262144 crc 60231F83 md5 83D0886E246045CFA5B12B7861521C04 sha1 1BD9910825A1BA3A9A9AD9084C8BE0AF04F2545F flags verified ) + name "World Cup USA 94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" + description "World Cup USA 94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv)" + rom ( name "World Cup USA 94 (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gb" size 262144 crc 60231f83 sha1 1BD9910825A1BA3A9A9AD9084C8BE0AF04F2545F flags verified ) ) game ( - name "World Cup USA '94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv)" - description "World Cup USA '94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv)" - rom ( name "World Cup USA '94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv).gb" size 262144 crc 9D27F9DE md5 17142AF806C86F45808A94550F2303D8 sha1 6F9FB96A4551B4C5B3C6D8928B9A561D1CC28ACD ) + name "World Cup USA 94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv)" + description "World Cup USA 94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv)" + rom ( name "World Cup USA 94 (Japan) (En,Fr,De,Es,It,Nl,Pt,Sv).gb" size 262144 crc 9d27f9de sha1 6F9FB96A4551B4C5B3C6D8928B9A561D1CC28ACD ) ) game ( name "World Heroes 2 Jet (USA, Europe) (SGB Enhanced)" description "World Heroes 2 Jet (USA, Europe) (SGB Enhanced)" - rom ( name "World Heroes 2 Jet (USA, Europe) (SGB Enhanced).gb" size 524288 crc 67303954 md5 8272E012F5C953450A3E2EFD88D41AEB sha1 3C5F213104E1BF968A01E0CFFBE7B5B5120E0458 flags verified ) + rom ( name "World Heroes 2 Jet (USA, Europe) (SGB Enhanced).gb" size 524288 crc 67303954 sha1 3C5F213104E1BF968A01E0CFFBE7B5B5120E0458 flags verified ) ) game ( name "World Ice Hockey (Japan)" description "World Ice Hockey (Japan)" - rom ( name "World Ice Hockey (Japan).gb" size 131072 crc 4E345023 md5 98E7D7FE08BE476B3E8D5989FB8B301C sha1 A4ED60DD7354DE12C4AF04F874AC1FD648F6684B ) + rom ( name "World Ice Hockey (Japan).gb" size 131072 crc 4e345023 sha1 A4ED60DD7354DE12C4AF04F874AC1FD648F6684B ) ) game ( name "World Soccer GB (Japan) (SGB Enhanced)" description "World Soccer GB (Japan) (SGB Enhanced)" - rom ( name "World Soccer GB (Japan) (SGB Enhanced).gb" size 524288 crc 57D21EF4 md5 74110EED9C357F1749C4A8F82D637908 sha1 ACA208DABD8D110CF0334103DCB8DD28B68E450D ) + rom ( name "World Soccer GB (Japan) (SGB Enhanced).gb" size 524288 crc 57d21ef4 sha1 ACA208DABD8D110CF0334103DCB8DD28B68E450D ) ) game ( name "Worms (Europe)" description "Worms (Europe)" - rom ( name "Worms (Europe).gb" size 262144 crc 2EBC40C2 md5 45DCC259728A00118FE86F841D48564F sha1 26137CA97B840C63A462BCF85677A5F3DB67FADF flags verified ) + rom ( name "Worms (Europe).gb" size 262144 crc 2ebc40c2 sha1 26137CA97B840C63A462BCF85677A5F3DB67FADF flags verified ) ) game ( name "WWF King of the Ring (Japan)" description "WWF King of the Ring (Japan)" - rom ( name "WWF King of the Ring (Japan).gb" size 131072 crc 3AB55613 md5 DBA637D1573394056A89CB97EC78000A sha1 3751261D8113C7B937F9E077803AF514F443AFBC ) + rom ( name "WWF King of the Ring (Japan).gb" size 131072 crc 3ab55613 sha1 3751261D8113C7B937F9E077803AF514F443AFBC ) ) game ( name "WWF King of the Ring (USA, Europe)" description "WWF King of the Ring (USA, Europe)" - rom ( name "WWF King of the Ring (USA, Europe).gb" size 131072 crc 7F0CD87C md5 8FFAB7C16A215D3E2CCE01FA24FBDF4F sha1 FD17015D8F85F407427C8AA3E68FB0A32DC072A8 flags verified ) + rom ( name "WWF King of the Ring (USA, Europe).gb" size 131072 crc 7f0cd87c sha1 FD17015D8F85F407427C8AA3E68FB0A32DC072A8 flags verified ) ) game ( name "WWF Raw (USA, Europe)" description "WWF Raw (USA, Europe)" - rom ( name "WWF Raw (USA, Europe).gb" size 262144 crc 1889552F md5 6D2AB72FC3F632493A04FD432508067D sha1 03EB3A9A2AF1E24E7DE9DE21A13DC677F46B06CE flags verified ) + rom ( name "WWF Raw (USA, Europe).gb" size 262144 crc 1889552f sha1 03EB3A9A2AF1E24E7DE9DE21A13DC677F46B06CE flags verified ) ) game ( name "WWF Superstars (Japan)" description "WWF Superstars (Japan)" - rom ( name "WWF Superstars (Japan).gb" size 131072 crc F28E5AA1 md5 3D08D0DBE1FA865E3D2E87578CCED5F5 sha1 F3101BB0F1FE3F9160E7892DFD70582325E1C44F flags verified ) + rom ( name "WWF Superstars (Japan).gb" size 131072 crc f28e5aa1 sha1 F3101BB0F1FE3F9160E7892DFD70582325E1C44F flags verified ) ) game ( name "WWF Superstars (USA, Europe)" description "WWF Superstars (USA, Europe)" - rom ( name "WWF Superstars (USA, Europe).gb" size 131072 crc ADBC4E0A md5 BA544265B8D949CF35984CD23AF63DA8 sha1 957A7D33A1569158F7B1882362262A6AB391FF5B flags verified ) + rom ( name "WWF Superstars (USA, Europe).gb" size 131072 crc adbc4e0a sha1 957A7D33A1569158F7B1882362262A6AB391FF5B flags verified ) ) game ( name "WWF Superstars 2 (Japan)" description "WWF Superstars 2 (Japan)" - rom ( name "WWF Superstars 2 (Japan).gb" size 131072 crc CA12D752 md5 C551445D0DA819E3717E5BB600A81D06 sha1 9B0DAA79A455B46F13A7866B575CB229EC9DADF8 ) + rom ( name "WWF Superstars 2 (Japan).gb" size 131072 crc ca12d752 sha1 9B0DAA79A455B46F13A7866B575CB229EC9DADF8 ) ) game ( name "WWF Superstars 2 (USA, Europe)" description "WWF Superstars 2 (USA, Europe)" - rom ( name "WWF Superstars 2 (USA, Europe).gb" size 131072 crc 8ECE1C04 md5 07006FE2F7363D475E34FBF63E4E94D1 sha1 F5F2A16A9EA5694E3198CB6A9A16BCBCA75BE12F flags verified ) + rom ( name "WWF Superstars 2 (USA, Europe).gb" size 131072 crc 8ece1c04 sha1 F5F2A16A9EA5694E3198CB6A9A16BCBCA75BE12F flags verified ) ) game ( name "WWF War Zone (USA, Europe)" description "WWF War Zone (USA, Europe)" - rom ( name "WWF War Zone (USA, Europe).gb" size 262144 crc 6015B7E1 md5 4F99D49908E027125473445EA1937817 sha1 6EF34105A8944E5AA8E44F3AEBB68B9BB45E9105 flags verified ) + rom ( name "WWF War Zone (USA, Europe).gb" size 262144 crc 6015b7e1 sha1 6EF34105A8944E5AA8E44F3AEBB68B9BB45E9105 flags verified ) ) game ( name "X (Japan)" description "X (Japan)" - rom ( name "X (Japan).gb" size 262144 crc 75E1D268 md5 988516A3D733132AF304B1C6710A923A sha1 C72F0B494CEBA72DB244266CB29E4D2B4D514263 flags verified ) + rom ( name "X (Japan).gb" size 262144 crc 75e1d268 sha1 C72F0B494CEBA72DB244266CB29E4D2B4D514263 flags verified ) ) game ( - name "X (USA) (Proto)" - description "X (USA) (Proto)" - rom ( name "X (USA) (Proto).gb" size 245760 crc CD555712 md5 9BFA774D2474D63FDACDBE951573375A sha1 B1C5B60B82AAA0B824F7BF67FC8F111377CCFB6A ) + name "Xenon 2 (USA, Europe)" + description "Xenon 2 (USA, Europe)" + rom ( name "Xenon 2 (USA, Europe).gb" size 131072 crc de398678 sha1 00D76805E1EF3FE0EB5E8FC045CC22DECFBE216B flags verified ) ) game ( name "Xenon 2 - Megablast (Japan)" description "Xenon 2 - Megablast (Japan)" - rom ( name "Xenon 2 - Megablast (Japan).gb" size 131072 crc 2FEB70D2 md5 1C031BA472EF04CF76DC63B15D96AAC2 sha1 6B2F009B7A443E5EAD48A2864BFB1D29096ED6A0 ) -) - -game ( - name "Xenon 2 - Megablast (USA, Europe)" - description "Xenon 2 - Megablast (USA, Europe)" - rom ( name "Xenon 2 - Megablast (USA, Europe).gb" size 131072 crc DE398678 md5 02D7DF9A5AC5D859672B56BE46343BE1 sha1 00D76805E1EF3FE0EB5E8FC045CC22DECFBE216B flags verified ) -) - -game ( - name "XVII Olympic Winter Games, The - Lillehammer 1994 (USA)" - description "XVII Olympic Winter Games, The - Lillehammer 1994 (USA)" - rom ( name "XVII Olympic Winter Games, The - Lillehammer 1994 (USA).gb" size 131072 crc 1A98F0A4 md5 C593B63CBD4B151A2FD1861C73634B0A sha1 95D664A8A0B74D6993501847D4CE065913BD1E08 ) + rom ( name "Xenon 2 - Megablast (Japan).gb" size 131072 crc 2feb70d2 sha1 6B2F009B7A443E5EAD48A2864BFB1D29096ED6A0 ) ) game ( name "Yakuman (Japan)" description "Yakuman (Japan)" - rom ( name "Yakuman (Japan).gb" size 32768 crc 3134EA60 md5 2ACFC8D0213B186552124FB8B3085FA1 sha1 3FDB9EA690C0F035DD0DCC98B1DCC83AC5154E17 ) + rom ( name "Yakuman (Japan).gb" size 32768 crc 3134ea60 sha1 3FDB9EA690C0F035DD0DCC98B1DCC83AC5154E17 flags verified ) ) game ( - name "Yakuman (Japan) (Rev A)" - description "Yakuman (Japan) (Rev A)" - rom ( name "Yakuman (Japan) (Rev A).gb" size 32768 crc 90CB60C1 md5 2E8D69BD73C3DEEE6C076C0A2DA25617 sha1 A4DB4509382D8A65E8BA4B799ADD6F98DBD9BC01 flags verified ) + name "Yakuman (Japan) (Rev 1)" + description "Yakuman (Japan) (Rev 1)" + rom ( name "Yakuman (Japan) (Rev 1).gb" size 32768 crc 90cb60c1 sha1 A4DB4509382D8A65E8BA4B799ADD6F98DBD9BC01 flags verified ) ) game ( name "Yannick Noah Tennis (France)" description "Yannick Noah Tennis (France)" - rom ( name "Yannick Noah Tennis (France).gb" size 65536 crc 402D4D47 md5 38412BA58B750D1A838137ADE975F62A sha1 5BC39C44DA587A89BEF7478617C402855A1B5B24 ) + rom ( name "Yannick Noah Tennis (France).gb" size 65536 crc 402d4d47 sha1 5BC39C44DA587A89BEF7478617C402855A1B5B24 ) ) game ( - name "Yogi Bear in Yogi Bear's Goldrush (Europe)" - description "Yogi Bear in Yogi Bear's Goldrush (Europe)" - rom ( name "Yogi Bear in Yogi Bear's Goldrush (Europe).gb" size 131072 crc 6E7BB436 md5 84FC4878829FDFF7D1C6D92C67AE35EA sha1 4E9452FEAFFA508CF40CD89FBC28F215060D28E5 flags verified ) + name "Yogi Bear's Gold Rush (Europe)" + description "Yogi Bear's Gold Rush (Europe)" + rom ( name "Yogi Bear's Gold Rush (Europe).gb" size 131072 crc 6e7bb436 sha1 4E9452FEAFFA508CF40CD89FBC28F215060D28E5 flags verified ) ) game ( - name "Yogi Bear in Yogi Bear's Goldrush (USA)" - description "Yogi Bear in Yogi Bear's Goldrush (USA)" - rom ( name "Yogi Bear in Yogi Bear's Goldrush (USA).gb" size 131072 crc A86BD81B md5 1337510DC9DE85723FF1778524C5007F sha1 D701B98B34C61EA230DF1CA9561E1C9474928EBF flags verified ) + name "Yogi Bear's Gold Rush (USA)" + description "Yogi Bear's Gold Rush (USA)" + rom ( name "Yogi Bear's Gold Rush (USA).gb" size 131072 crc a86bd81b sha1 D701B98B34C61EA230DF1CA9561E1C9474928EBF flags verified ) ) game ( name "Yomihon Yumegoyomi - Tenjin Kaisen 2 (Japan)" description "Yomihon Yumegoyomi - Tenjin Kaisen 2 (Japan)" - rom ( name "Yomihon Yumegoyomi - Tenjin Kaisen 2 (Japan).gb" size 262144 crc 211C4611 md5 71D7C219ED1CC63BFC6D77E62F6E2227 sha1 781BB266B4C9AA59A2DB4C278D2D2FE41A60EBB2 ) + rom ( name "Yomihon Yumegoyomi - Tenjin Kaisen 2 (Japan).gb" size 262144 crc 211c4611 sha1 781BB266B4C9AA59A2DB4C278D2D2FE41A60EBB2 ) ) game ( name "Yoshi (USA)" description "Yoshi (USA)" - rom ( name "Yoshi (USA).gb" size 65536 crc F2F4BCCA md5 A8804C8514619CC918960C2008ED65D1 sha1 1B6E41C2270CE67E6FE15CC4977EF2DEBDD6E6CE ) + rom ( name "Yoshi (USA).gb" size 65536 crc f2f4bcca sha1 1B6E41C2270CE67E6FE15CC4977EF2DEBDD6E6CE ) ) game ( name "Yoshi no Cookie (Japan)" description "Yoshi no Cookie (Japan)" - rom ( name "Yoshi no Cookie (Japan).gb" size 131072 crc A37255FE md5 95E0CE560FE647B955FA1D3B2808ACFA sha1 3B19C51B4E7E7275265B90E991FAF6CF64A8085A flags verified ) + rom ( name "Yoshi no Cookie (Japan).gb" size 131072 crc a37255fe sha1 3B19C51B4E7E7275265B90E991FAF6CF64A8085A flags verified ) ) game ( name "Yoshi no Panepon (Japan) (SGB Enhanced)" description "Yoshi no Panepon (Japan) (SGB Enhanced)" - rom ( name "Yoshi no Panepon (Japan) (SGB Enhanced).gb" size 524288 crc 3BEB7239 md5 11BE7FF8141F8D7A5C8CCA903151F0BA sha1 C54D0A33A562C93B9E1243FD9C615B5F92671E58 flags verified ) + rom ( name "Yoshi no Panepon (Japan) (SGB Enhanced).gb" size 524288 crc 3beb7239 sha1 C54D0A33A562C93B9E1243FD9C615B5F92671E58 flags verified ) ) game ( name "Yoshi no Tamago (Japan)" description "Yoshi no Tamago (Japan)" - rom ( name "Yoshi no Tamago (Japan).gb" size 65536 crc 9B6FCC76 md5 0CCB1E6BEB86D79A7A5DAD81EB6C73A9 sha1 5CB61DEE0EB3F9D35775A607803D06C8CEBCB842 flags verified ) + rom ( name "Yoshi no Tamago (Japan).gb" size 65536 crc 9b6fcc76 sha1 5CB61DEE0EB3F9D35775A607803D06C8CEBCB842 flags verified ) ) game ( name "Yoshi's Cookie (USA, Europe)" description "Yoshi's Cookie (USA, Europe)" - rom ( name "Yoshi's Cookie (USA, Europe).gb" size 131072 crc 75336712 md5 BC1A3848092BDC900C157996C29A7783 sha1 233DCC94D86951DDF167AAA82EC9B94B87B29E2D flags verified ) + rom ( name "Yoshi's Cookie (USA, Europe).gb" size 131072 crc 75336712 sha1 233DCC94D86951DDF167AAA82EC9B94B87B29E2D flags verified ) ) game ( name "Yousei Monogatari - Rod Land (Japan)" description "Yousei Monogatari - Rod Land (Japan)" - rom ( name "Yousei Monogatari - Rod Land (Japan).gb" size 65536 crc 2355BE94 md5 7AF2043D1766513DC576B549D104FA2A sha1 4710264C4837F44BD58673C53725976950DE10E9 ) + rom ( name "Yousei Monogatari - Rod Land (Japan).gb" size 65536 crc 2355be94 sha1 4710264C4837F44BD58673C53725976950DE10E9 ) ) game ( name "Yu Yu Hakusho (Japan)" description "Yu Yu Hakusho (Japan)" - rom ( name "Yu Yu Hakusho (Japan).gb" size 262144 crc 7103B4AC md5 D120872AD4F5B3E67CC5561550F2D142 sha1 E4BCD2875AECD45095CE47AAE90BD87F7558BC0F flags verified ) + rom ( name "Yu Yu Hakusho (Japan).gb" size 262144 crc 7103b4ac sha1 E4BCD2875AECD45095CE47AAE90BD87F7558BC0F flags verified ) ) game ( name "Yu Yu Hakusho Dai-2-dan - Ankoku Bujutsukai Hen (Japan)" description "Yu Yu Hakusho Dai-2-dan - Ankoku Bujutsukai Hen (Japan)" - rom ( name "Yu Yu Hakusho Dai-2-dan - Ankoku Bujutsukai Hen (Japan).gb" size 262144 crc 6A6D7350 md5 473DA7CA1A6A8AD23EC28C2F838BCE20 sha1 3B28391763E43676389A97620E52908D02510E44 flags verified ) + rom ( name "Yu Yu Hakusho Dai-2-dan - Ankoku Bujutsukai Hen (Japan).gb" size 262144 crc 6a6d7350 sha1 3B28391763E43676389A97620E52908D02510E44 flags verified ) ) game ( name "Yu Yu Hakusho Dai-3-dan - Makai no Tobira Hen (Japan)" description "Yu Yu Hakusho Dai-3-dan - Makai no Tobira Hen (Japan)" - rom ( name "Yu Yu Hakusho Dai-3-dan - Makai no Tobira Hen (Japan).gb" size 262144 crc 25C618F6 md5 2057201D3FD4A137EE8C74C73B0A7B03 sha1 FFAFF18CC2028CA7F823ED1C2A025ED5A61D1B9D flags verified ) + rom ( name "Yu Yu Hakusho Dai-3-dan - Makai no Tobira Hen (Japan).gb" size 262144 crc 25c618f6 sha1 FFAFF18CC2028CA7F823ED1C2A025ED5A61D1B9D flags verified ) ) game ( name "Yu Yu Hakusho Dai-4-dan - Makai Touitsu Hen (Japan) (SGB Enhanced)" description "Yu Yu Hakusho Dai-4-dan - Makai Touitsu Hen (Japan) (SGB Enhanced)" - rom ( name "Yu Yu Hakusho Dai-4-dan - Makai Touitsu Hen (Japan) (SGB Enhanced).gb" size 262144 crc 3E7C6B2B md5 BFC83DD55F64F6C472EF45D3592A7B92 sha1 14A8E39F1ADFA6ACCE11F902EB6763C73ABABA47 flags verified ) + rom ( name "Yu Yu Hakusho Dai-4-dan - Makai Touitsu Hen (Japan) (SGB Enhanced).gb" size 262144 crc 3e7c6b2b sha1 14A8E39F1ADFA6ACCE11F902EB6763C73ABABA47 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced)" description "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced)" - rom ( name "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced).gb" size 1048576 crc 8875EC54 md5 770A917F18E0AA1F3BB027D0783F548B sha1 07AE4A6437F00F6AF462BF84FD0AC1CF345C8365 flags verified ) + rom ( name "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced).gb" size 1048576 crc 8875ec54 sha1 07AE4A6437F00F6AF462BF84FD0AC1CF345C8365 flags verified ) ) game ( name "Zelda no Densetsu - Yume o Miru Shima (Japan)" description "Zelda no Densetsu - Yume o Miru Shima (Japan)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan).gb" size 524288 crc 39A6684E md5 AE08C1F73F822116060EF58293B94ED8 sha1 FA38601C371CA327166BF52BE1094697D41A80F3 ) + rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan).gb" size 524288 crc 39a6684e sha1 FA38601C371CA327166BF52BE1094697D41A80F3 ) ) game ( - name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A)" - description "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev A).gb" size 524288 crc EA20B82A md5 3AFBE0CF110FC6AD8DEF8377ECFFC34D sha1 80F5D111C7E2D79D39F6C25A37B54C3196D2BD12 flags verified ) + name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1)" + description "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1).gb" size 524288 crc ea20b82a sha1 80F5D111C7E2D79D39F6C25A37B54C3196D2BD12 flags verified ) ) game ( name "Zen - Intergalactic Ninja (Europe)" description "Zen - Intergalactic Ninja (Europe)" - rom ( name "Zen - Intergalactic Ninja (Europe).gb" size 131072 crc 642C7EBE md5 5F855203B56886FCB88C54692144C553 sha1 0E753ED48E28A0E6A820AC9B8403C50C004F22E2 ) + rom ( name "Zen - Intergalactic Ninja (Europe).gb" size 131072 crc 642c7ebe sha1 0E753ED48E28A0E6A820AC9B8403C50C004F22E2 ) ) game ( name "Zen - Intergalactic Ninja (USA)" description "Zen - Intergalactic Ninja (USA)" - rom ( name "Zen - Intergalactic Ninja (USA).gb" size 131072 crc 88190730 md5 A517826D1CC3984A141F0F08D3AD72EE sha1 47BBC472071770783B3D930141390F48741176AF ) + rom ( name "Zen - Intergalactic Ninja (USA).gb" size 131072 crc 88190730 sha1 47BBC472071770783B3D930141390F48741176AF ) ) game ( name "Zen-Nihon Pro Wrestling Jet (Japan) (SGB Enhanced)" description "Zen-Nihon Pro Wrestling Jet (Japan) (SGB Enhanced)" - rom ( name "Zen-Nihon Pro Wrestling Jet (Japan) (SGB Enhanced).gb" size 262144 crc 119BCAD5 md5 06AD6E6281B355040575AAD2EE22C9A6 sha1 60D3B8618BB80C61CA29BCCC7C1AF9244A6C1764 ) + rom ( name "Zen-Nihon Pro Wrestling Jet (Japan) (SGB Enhanced).gb" size 262144 crc 119bcad5 sha1 60D3B8618BB80C61CA29BCCC7C1AF9244A6C1764 flags verified ) ) game ( name "Zerd no Densetsu (Japan)" description "Zerd no Densetsu (Japan)" - rom ( name "Zerd no Densetsu (Japan).gb" size 131072 crc 492EDB36 md5 FD280448AE0F60BAE1D10016A87FC1ED sha1 8DB8AD90505D9A2B4485E903B9F5D67BB9C0C149 flags verified ) + rom ( name "Zerd no Densetsu (Japan).gb" size 131072 crc 492edb36 sha1 8DB8AD90505D9A2B4485E903B9F5D67BB9C0C149 flags verified ) ) game ( name "Zerd no Densetsu 2 - Xerd!! Gishin no Ryouiki (Japan)" description "Zerd no Densetsu 2 - Xerd!! Gishin no Ryouiki (Japan)" - rom ( name "Zerd no Densetsu 2 - Xerd!! Gishin no Ryouiki (Japan).gb" size 524288 crc A197BDB7 md5 10CC4382F2C77400D7E2A0CCFFBECDF2 sha1 CFA91DA4120C6E1EE0F1F121D944D44532506CFA flags verified ) + rom ( name "Zerd no Densetsu 2 - Xerd!! Gishin no Ryouiki (Japan).gb" size 524288 crc a197bdb7 sha1 CFA91DA4120C6E1EE0F1F121D944D44532506CFA flags verified ) ) game ( name "Zettai Muteki Raijin-Oh (Japan)" description "Zettai Muteki Raijin-Oh (Japan)" - rom ( name "Zettai Muteki Raijin-Oh (Japan).gb" size 65536 crc 7D03727D md5 E870BCCBC307FB32228FA8E4545EDF35 sha1 6269CA535EEA41F4BCFEF99F512F435DAF06C6E3 flags verified ) + rom ( name "Zettai Muteki Raijin-Oh (Japan).gb" size 65536 crc 7d03727d sha1 6269CA535EEA41F4BCFEF99F512F435DAF06C6E3 flags verified ) ) game ( name "Zoids Densetsu (Japan)" description "Zoids Densetsu (Japan)" - rom ( name "Zoids Densetsu (Japan).gb" size 65536 crc C32DCA06 md5 A77E8144B00215385EBF8490A539E4BE sha1 5D6016B605EA22901150BC5735BC13BA64AAF3C6 ) + rom ( name "Zoids Densetsu (Japan).gb" size 65536 crc c32dca06 sha1 5D6016B605EA22901150BC5735BC13BA64AAF3C6 ) ) game ( name "Zool - Ninja of the 'Nth' Dimension (Europe)" description "Zool - Ninja of the 'Nth' Dimension (Europe)" - rom ( name "Zool - Ninja of the 'Nth' Dimension (Europe).gb" size 131072 crc AE13E227 md5 1425BC943F215CBA23F1EC8C4BC22BBC sha1 6DF1086910AE33D6A699DF3AD428B901AB851BB4 flags verified ) + rom ( name "Zool - Ninja of the 'Nth' Dimension (Europe).gb" size 131072 crc ae13e227 sha1 6DF1086910AE33D6A699DF3AD428B901AB851BB4 flags verified ) ) game ( name "Zool - Ninja of the 'Nth' Dimension (USA)" description "Zool - Ninja of the 'Nth' Dimension (USA)" - rom ( name "Zool - Ninja of the 'Nth' Dimension (USA).gb" size 131072 crc EF54B46E md5 52700EA227C3A31F170CCBC6A052A7A8 sha1 5C1B1AF8E70CD23F5F72848D03FCC56869D18BE7 ) + rom ( name "Zool - Ninja of the 'Nth' Dimension (USA).gb" size 131072 crc ef54b46e sha1 5C1B1AF8E70CD23F5F72848D03FCC56869D18BE7 ) ) game ( name "Zoop (Japan)" description "Zoop (Japan)" - rom ( name "Zoop (Japan).gb" size 65536 crc 10E1A10C md5 0B10A49804C027C57201C61835ACAD77 sha1 89A74970761700D591C2AFFC47C9306F49D22BA8 ) + rom ( name "Zoop (Japan).gb" size 65536 crc 10e1a10c sha1 89A74970761700D591C2AFFC47C9306F49D22BA8 ) ) game ( name "Zoop (USA, Europe)" description "Zoop (USA, Europe)" - rom ( name "Zoop (USA, Europe).gb" size 65536 crc 14F8B6BB md5 2387654E0E8E63BFC5F85D9BD7AA6AC3 sha1 1E0390D456066B9FBE1FAFF5F7404D4593A2B839 flags verified ) + rom ( name "Zoop (USA, Europe).gb" size 65536 crc 14f8b6bb sha1 1E0390D456066B9FBE1FAFF5F7404D4593A2B839 flags verified ) ) clrmamepro ( name "Nintendo - Game Boy Color" description "Nintendo - Game Boy Color" - version 20160214-074643 - comment "no-intro | www.no-intro.org" + version 20190505-032128 + author "akubi, Bent, BigFred, BitLooter, C. V. Reynolds, coraz, darthcloud, Densetsu, DeriLoko3, foxe, fuzzball, Hiccup, hking0036, kazumi213, Money_114, NGEfreak, omonim2007, PPLToast, relax, Rifu, Tauwasser, Whovian9369, xuom2, zg" + homepage No-Intro + url "http://www.no-intro.org" ) game ( - name "[BIOS] Nintendo Game Boy Color Boot ROM (World)" - description "[BIOS] Nintendo Game Boy Color Boot ROM (World)" - rom ( name "[BIOS] Nintendo Game Boy Color Boot ROM (World).gbc" size 2304 crc 41884E46 md5 DBFCE9DB9DEAA2567F6A84FDE55F9680 sha1 1293D68BF9643BC4F36954C1E80E38F39864528D ) + name "[BIOS] Nintendo Game Boy Color Boot ROM (World) (Rev 1)" + description "[BIOS] Nintendo Game Boy Color Boot ROM (World) (Rev 1)" + rom ( name "[BIOS] Nintendo Game Boy Color Boot ROM (World) (Rev 1).gbc" size 2304 crc 41884e46 sha1 1293D68BF9643BC4F36954C1E80E38F39864528D flags verified ) +) + +game ( + name "[BIOS] Nintendo Game Boy Color Boot ROM (Japan) (En)" + description "[BIOS] Nintendo Game Boy Color Boot ROM (Japan) (En)" + rom ( name "[BIOS] Nintendo Game Boy Color Boot ROM (Japan) (En).gbc" size 2304 crc e8ef5318 sha1 DF5A0D2D49DE38FBD31CC2AAB8E62C8550E655C0 flags verified ) ) game ( name "007 - The World Is Not Enough (USA, Europe)" description "007 - The World Is Not Enough (USA, Europe)" - rom ( name "007 - The World Is Not Enough (USA, Europe).gbc" size 2097152 crc E038E666 md5 1F1FB3CF8783F880BC796D667BE60231 sha1 DD6E952B730C4BD85F8734156D43A2616B68C053 flags verified ) + rom ( name "007 - The World Is Not Enough (USA, Europe).gbc" size 2097152 crc e038e666 sha1 DD6E952B730C4BD85F8734156D43A2616B68C053 flags verified ) ) game ( name "10-Pin Bowling (USA) (Rumble Version)" description "10-Pin Bowling (USA) (Rumble Version)" - rom ( name "10-Pin Bowling (USA) (Rumble Version).gbc" size 1048576 crc 720C7023 md5 6B055C6D12E477FBFD7BED1B495D56F7 sha1 EB0A65DC3069AE5261B04437FFAC5EFC12697C2A ) + rom ( name "10-Pin Bowling (USA) (Rumble Version).gbc" size 1048576 crc 720c7023 sha1 EB0A65DC3069AE5261B04437FFAC5EFC12697C2A ) ) game ( name "10-Pin Bowling (Europe)" description "10-Pin Bowling (Europe)" - rom ( name "10-Pin Bowling (Europe).gbc" size 1048576 crc 5449CAC0 md5 85C0C028E6177CDA40401F14D16699F4 sha1 90D78BF2F51EED998002D8733D6E223B6478F487 ) + rom ( name "10-Pin Bowling (Europe).gbc" size 1048576 crc 5449cac0 sha1 90D78BF2F51EED998002D8733D6E223B6478F487 flags verified ) ) game ( name "102 Dalmatas - Cachorros Al Rescate (Spain)" description "102 Dalmatas - Cachorros Al Rescate (Spain)" - rom ( name "102 Dalmatas - Cachorros Al Rescate (Spain).gbc" size 1048576 crc F2128908 md5 2A65D5C037463FE93127D45D4145A0A6 sha1 EAF3BD27CF7CB084068C5A139DA5383A74105FFA ) + rom ( name "102 Dalmatas - Cachorros Al Rescate (Spain).gbc" size 1048576 crc f2128908 sha1 EAF3BD27CF7CB084068C5A139DA5383A74105FFA flags verified ) ) game ( name "102 Dalmatians - Puppies to the Rescue (USA, Europe)" description "102 Dalmatians - Puppies to the Rescue (USA, Europe)" - rom ( name "102 Dalmatians - Puppies to the Rescue (USA, Europe).gbc" size 1048576 crc 56B83539 md5 2B7E2442D503CE368FC93A9EBF0F70EF sha1 9F0F45D84E60E9C6F52FDE14E1C0A49992AED025 flags verified ) + rom ( name "102 Dalmatians - Puppies to the Rescue (USA, Europe).gbc" size 1048576 crc 56b83539 sha1 9F0F45D84E60E9C6F52FDE14E1C0A49992AED025 flags verified ) ) game ( name "102 Dalmatiens a la Rescousse, Les (France)" description "102 Dalmatiens a la Rescousse, Les (France)" - rom ( name "102 Dalmatiens a la Rescousse, Les (France).gbc" size 1048576 crc E84191A8 md5 0DDB1E2111A510557484F942AC78B915 sha1 BA028395DE3456DC232BAC24EDA84A30E15F5550 ) + rom ( name "102 Dalmatiens a la Rescousse, Les (France).gbc" size 1048576 crc e84191a8 sha1 BA028395DE3456DC232BAC24EDA84A30E15F5550 ) ) game ( name "102 Dalmatiner (Germany)" description "102 Dalmatiner (Germany)" - rom ( name "102 Dalmatiner (Germany).gbc" size 1048576 crc 725A3483 md5 A649EF1410AE4C24020FB8B0113739E3 sha1 69109B87DAE04FCB9B65374165527D03845A2DC3 ) + rom ( name "102 Dalmatiner (Germany).gbc" size 1048576 crc 725a3483 sha1 69109B87DAE04FCB9B65374165527D03845A2DC3 ) ) game ( name "1942 (USA, Europe)" description "1942 (USA, Europe)" - rom ( name "1942 (USA, Europe).gbc" size 1048576 crc 87431672 md5 A31652B6D1E7FC647C4AF7B9DFE05FF5 sha1 D960E951B18D07E79D046313DF49C18313664224 flags verified ) + rom ( name "1942 (USA, Europe).gbc" size 1048576 crc 87431672 sha1 D960E951B18D07E79D046313DF49C18313664224 flags verified ) ) game ( name "3-D Ultra Pinball - Thrillride (USA) (Rumble Version)" description "3-D Ultra Pinball - Thrillride (USA) (Rumble Version)" - rom ( name "3-D Ultra Pinball - Thrillride (USA) (Rumble Version).gbc" size 524288 crc 1766E558 md5 B9CF8D2416F8A6DD3B412AFD91337F40 sha1 2B704415803CF6172A1D07912B1155C51576A511 ) + rom ( name "3-D Ultra Pinball - Thrillride (USA) (Rumble Version).gbc" size 524288 crc 1766e558 sha1 2B704415803CF6172A1D07912B1155C51576A511 ) ) game ( name "31 in 1 (Taiwan) (31B-001, Sachen) (Unl)" description "31 in 1 (Taiwan) (31B-001, Sachen) (Unl)" - rom ( name "31 in 1 (Taiwan) (31B-001, Sachen) (Unl).gbc" size 2097152 crc 0EB8DDFB md5 F56A4DD7E30CA39CFE6DA0E6E6A28668 sha1 8FA0D40DC4C239108304E8799413A69A5668404C flags verified ) + rom ( name "31 in 1 (Taiwan) (31B-001, Sachen) (Unl).gbc" size 2097152 crc 0eb8ddfb sha1 8FA0D40DC4C239108304E8799413A69A5668404C flags verified ) ) game ( name "31-in-1 Mighty Mix (Australia) (31B-001, Sachen) (Unl)" description "31-in-1 Mighty Mix (Australia) (31B-001, Sachen) (Unl)" - rom ( name "31-in-1 Mighty Mix (Australia) (31B-001, Sachen) (Unl).gbc" size 2097152 crc 21524051 md5 A08B575B947D0249CDF214FC130706CE sha1 C0C2A65B1485A2768962CB97BA2F9B668528453A ) + rom ( name "31-in-1 Mighty Mix (Australia) (31B-001, Sachen) (Unl).gbc" size 2097152 crc 21524051 sha1 C0C2A65B1485A2768962CB97BA2F9B668528453A flags verified ) ) game ( name "3D Pocket Pool (Europe) (En,Fr,De,Es,It,Nl)" description "3D Pocket Pool (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "3D Pocket Pool (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8CDAB77F md5 429E6DA4B32D8CAA22E78D92C0FEBD12 sha1 11EE7BA924F80E1C546AF4749EA46AC5C8C75A5D ) + rom ( name "3D Pocket Pool (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8cdab77f sha1 11EE7BA924F80E1C546AF4749EA46AC5C8C75A5D ) ) game ( name "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl)" description "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl)" - rom ( name "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl).gbc" size 524288 crc 42A2FDF8 md5 BA2F38D5C6B03AA44D892B56395A683B sha1 79A4FADDFD1ACA397E56D7895E45B1BC12900DAB flags verified ) + rom ( name "4 in 1 + 8 in 1 (World) (4B-001, 4B-009, 8B-001, Sachen) (Unl).gbc" size 524288 crc 42a2fdf8 sha1 79A4FADDFD1ACA397E56D7895E45B1BC12900DAB flags verified ) ) game ( name "4 in 1 + 8 in 1 (World) (4B-002, 4B-004, 8B-002, Sachen) (Unl)" description "4 in 1 + 8 in 1 (World) (4B-002, 4B-004, 8B-002, Sachen) (Unl)" - rom ( name "4 in 1 + 8 in 1 (World) (4B-002, 4B-004, 8B-002, Sachen) (Unl).gbc" size 524288 crc E7224F14 md5 37F4AD4A7BAED1ED6EB62787734C00AE sha1 2D7D6CDC49EC71E20BE9C752CEAF38C5E2C29C5F flags verified ) + rom ( name "4 in 1 + 8 in 1 (World) (4B-002, 4B-004, 8B-002, Sachen) (Unl).gbc" size 524288 crc e7224f14 sha1 2D7D6CDC49EC71E20BE9C752CEAF38C5E2C29C5F flags verified ) ) game ( name "4 in 1 + 8 in 1 (World) (4B-005, 4B-006, 8B-003, Sachen) (Unl)" description "4 in 1 + 8 in 1 (World) (4B-005, 4B-006, 8B-003, Sachen) (Unl)" - rom ( name "4 in 1 + 8 in 1 (World) (4B-005, 4B-006, 8B-003, Sachen) (Unl).gbc" size 524288 crc B18465D2 md5 CB2F61EA9D959F7270EEC59A5EB51AFF sha1 40B4F3147EE7F79DBD64A862074CE50A7B4445EC flags verified ) + rom ( name "4 in 1 + 8 in 1 (World) (4B-005, 4B-006, 8B-003, Sachen) (Unl).gbc" size 524288 crc b18465d2 sha1 40B4F3147EE7F79DBD64A862074CE50A7B4445EC flags verified ) ) game ( name "4 in 1 + 8 in 1 (World) (4B-007, 4B-008, 8B-004, Sachen) (Unl)" description "4 in 1 + 8 in 1 (World) (4B-007, 4B-008, 8B-004, Sachen) (Unl)" - rom ( name "4 in 1 + 8 in 1 (World) (4B-007, 4B-008, 8B-004, Sachen) (Unl).gbc" size 524288 crc 0A504426 md5 AF8E059196FCDD29CC0FC417D3ABF9FF sha1 9C436BB4E2C666A92D4F695C776C2751CD3EB3B6 flags verified ) + rom ( name "4 in 1 + 8 in 1 (World) (4B-007, 4B-008, 8B-004, Sachen) (Unl).gbc" size 524288 crc 0a504426 sha1 9C436BB4E2C666A92D4F695C776C2751CD3EB3B6 flags verified ) ) game ( - name "4x4 World Trophy (Europe) (En,Fr,De,Es,It)" - description "4x4 World Trophy (Europe) (En,Fr,De,Es,It)" - rom ( name "4x4 World Trophy (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc F62AD75E md5 5878A145E365FA1841B22E837C3226FF sha1 369E359D1B9A80FDDA756411A395594B3D955100 flags verified ) + name "4x4 World Trophy (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "4x4 World Trophy (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "4x4 World Trophy (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc f62ad75e sha1 369E359D1B9A80FDDA756411A395594B3D955100 flags verified ) ) game ( - name "6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" - description "6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" - rom ( name "6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl).gbc" size 2097152 crc FB60D1C5 md5 C4114CDAE922B6B483F6C076B822719B sha1 8670282E7EA22235E374D5DCD1BEB5AC54B35FE6 ) -) - -game ( - name "720 Degrees (USA, Europe)" - description "720 Degrees (USA, Europe)" - rom ( name "720 Degrees (USA, Europe).gbc" size 1048576 crc E633841F md5 221A0E464F5F0C3D38494939B1765A24 sha1 78C0117C8EE32CFA605AC34EEDF707CC535B3987 flags verified ) + name "720 Degrees (USA, Europe) (GB Compatible)" + description "720 Degrees (USA, Europe) (GB Compatible)" + rom ( name "720 Degrees (USA, Europe) (GB Compatible).gbc" size 1048576 crc e633841f sha1 78C0117C8EE32CFA605AC34EEDF707CC535B3987 flags verified ) ) game ( name "Action Man - Search for Base X (USA, Europe)" description "Action Man - Search for Base X (USA, Europe)" - rom ( name "Action Man - Search for Base X (USA, Europe).gbc" size 1048576 crc 1226499E md5 D9D85B81D1B0B4D3C86C95A6E1846F5A sha1 4B62B0344B8FED07CEB967F9A9C45BBEED3DC592 flags verified ) + rom ( name "Action Man - Search for Base X (USA, Europe).gbc" size 1048576 crc 1226499e sha1 4B62B0344B8FED07CEB967F9A9C45BBEED3DC592 flags verified ) ) game ( name "Action Replay Online (Europe) (Unl)" description "Action Replay Online (Europe) (Unl)" - rom ( name "Action Replay Online (Europe) (Unl).gbc" size 131072 crc 04C8C858 md5 E718083D717D4262D3F26EBA4040F8E4 sha1 FA441C5E376B54B3503596FE8177B3A9AD79A9A8 ) -) - -game ( - name "Adventures of Elmo in Grouchland, The (Europe)" - description "Adventures of Elmo in Grouchland, The (Europe)" - rom ( name "Adventures of Elmo in Grouchland, The (Europe).gbc" size 1048576 crc 41228EE7 md5 ADA59E7DAFE1A6B70ADD7020959C1B23 sha1 AF1C3912DA946D858F9EEB10A3B9D95CBB6A00D8 flags verified ) -) - -game ( - name "Adventures of Elmo in Grouchland, The (USA)" - description "Adventures of Elmo in Grouchland, The (USA)" - rom ( name "Adventures of Elmo in Grouchland, The (USA).gbc" size 262144 crc 2C4C2A5F md5 CBDC5112EB8B9878FA5FE905E0ACA556 sha1 60F240476D2FAC81B1EFB83E1128E6223C766F15 ) + rom ( name "Action Replay Online (Europe) (Unl).gbc" size 131072 crc 04c8c858 sha1 FA441C5E376B54B3503596FE8177B3A9AD79A9A8 ) ) game ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" description "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc D0D3DFED md5 29DEFF80E9E8D734F77D8590AC5CDCE9 sha1 7919C5E6AA8D040B1F7953345B376D999CF22B18 flags verified ) + rom ( name "Adventures of the Smurfs, The (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc d0d3dfed sha1 7919C5E6AA8D040B1F7953345B376D999CF22B18 flags verified ) ) game ( name "AirForce Delta (Japan)" description "AirForce Delta (Japan)" - rom ( name "AirForce Delta (Japan).gbc" size 1048576 crc 5DFFF5E2 md5 9D64F8607E9BC3E788F30FFF123BE448 sha1 593DF751CC6B1A7AF7F50A9C9CFCEDF8287384DC ) + rom ( name "AirForce Delta (Japan).gbc" size 1048576 crc 5dfff5e2 sha1 593DF751CC6B1A7AF7F50A9C9CFCEDF8287384DC ) ) game ( name "AirForce Delta (USA)" description "AirForce Delta (USA)" - rom ( name "AirForce Delta (USA).gbc" size 1048576 crc FF31CC92 md5 EE37C79E8DF6475D90E99E527823F92F sha1 82530325B940E14EDEA459879289B4DCE1818066 ) + rom ( name "AirForce Delta (USA).gbc" size 1048576 crc ff31cc92 sha1 82530325B940E14EDEA459879289B4DCE1818066 ) ) game ( name "Aladdin (Europe) (En,Fr,De,Es,It,Nl)" description "Aladdin (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Aladdin (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 446573CD md5 BAD95D30C38A92E7906FEECB6D6BD272 sha1 23335B9654766275831115A54F5142C4CB9183FE ) + rom ( name "Aladdin (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 446573cd sha1 23335B9654766275831115A54F5142C4CB9183FE ) ) game ( name "Aladdin (USA)" description "Aladdin (USA)" - rom ( name "Aladdin (USA).gbc" size 1048576 crc A91EC059 md5 644C2C3CF2DC2E3FCE741844E497A18F sha1 97B46BF9862C9A1EF73D41F18B3693C6D9C73C06 flags verified ) + rom ( name "Aladdin (USA).gbc" size 1048576 crc a91ec059 sha1 97B46BF9862C9A1EF73D41F18B3693C6D9C73C06 flags verified ) ) game ( name "Alfred's Adventure (Europe) (En,Fr,De,Es,It)" description "Alfred's Adventure (Europe) (En,Fr,De,Es,It)" - rom ( name "Alfred's Adventure (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 6F9EF15E md5 BCC135B000C1C54F12F4AE87C7673B0C sha1 81C1ACF0E87755A8C16F0BEEB3524B3EC04455EA ) + rom ( name "Alfred's Adventure (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 6f9ef15e sha1 81C1ACF0E87755A8C16F0BEEB3524B3EC04455EA ) ) game ( name "Alice in Wonderland (Europe) (En,Fr,De,Es)" description "Alice in Wonderland (Europe) (En,Fr,De,Es)" - rom ( name "Alice in Wonderland (Europe) (En,Fr,De,Es).gbc" size 2097152 crc 85545D81 md5 265DE745B9B6C8E84E02ACBF80D0428E sha1 EA8647CCE2D4B5F7993190C6E485669CC6046A29 ) + rom ( name "Alice in Wonderland (Europe) (En,Fr,De,Es).gbc" size 2097152 crc 85545d81 sha1 EA8647CCE2D4B5F7993190C6E485669CC6046A29 ) ) game ( name "Alice in Wonderland (USA)" description "Alice in Wonderland (USA)" - rom ( name "Alice in Wonderland (USA).gbc" size 2097152 crc 3199F65F md5 0ED5B9FFE7AD90D819CAC810D05B669C sha1 02C49003D5EB1498F239149089A517CDFB6BDA0B ) + rom ( name "Alice in Wonderland (USA).gbc" size 2097152 crc 3199f65f sha1 02C49003D5EB1498F239149089A517CDFB6BDA0B ) ) game ( name "Aliens - Thanatos Encounter (USA, Europe)" description "Aliens - Thanatos Encounter (USA, Europe)" - rom ( name "Aliens - Thanatos Encounter (USA, Europe).gbc" size 1048576 crc BEC3C24B md5 73A78663A6388BF4D1C56E05BBF790D4 sha1 E1B1C79C15A34984DDDBE270FC6770B32A31A0D7 flags verified ) + rom ( name "Aliens - Thanatos Encounter (USA, Europe).gbc" size 1048576 crc bec3c24b sha1 E1B1C79C15A34984DDDBE270FC6770B32A31A0D7 flags verified ) ) game ( - name "All Star Tennis 2000 (Europe)" - description "All Star Tennis 2000 (Europe)" - rom ( name "All Star Tennis 2000 (Europe).gbc" size 1048576 crc 952B94E5 md5 C5E3BB77000C5D3755E816F6C0EED489 sha1 50F99B0FC5C2F5EDC2E76BA973CC42FB0A1A02C8 flags verified ) + name "All Star Tennis 2000 (Europe) (GB Compatible)" + description "All Star Tennis 2000 (Europe) (GB Compatible)" + rom ( name "All Star Tennis 2000 (Europe) (GB Compatible).gbc" size 1048576 crc 952b94e5 sha1 50F99B0FC5C2F5EDC2E76BA973CC42FB0A1A02C8 flags verified ) ) game ( name "All-Star Baseball 2000 (USA, Europe)" description "All-Star Baseball 2000 (USA, Europe)" - rom ( name "All-Star Baseball 2000 (USA, Europe).gbc" size 1048576 crc E17F59A5 md5 0B23D35E7BF1F136DF8A7C8F24103DFC sha1 7156AC04B7D249007F62B4B509B4661190977908 flags verified ) + rom ( name "All-Star Baseball 2000 (USA, Europe).gbc" size 1048576 crc e17f59a5 sha1 7156AC04B7D249007F62B4B509B4661190977908 flags verified ) ) game ( name "All-Star Baseball 2001 (USA)" description "All-Star Baseball 2001 (USA)" - rom ( name "All-Star Baseball 2001 (USA).gbc" size 1048576 crc BC562466 md5 6122CAEEC0DAAB1BFA89C2AF317DCBD6 sha1 F702DF64D368B763187A5B1263A60FB3E842962B ) + rom ( name "All-Star Baseball 2001 (USA).gbc" size 1048576 crc bc562466 sha1 F702DF64D368B763187A5B1263A60FB3E842962B ) ) game ( name "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl)" description "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc 7FF2042F md5 30EC849758F703D7071E2AC28E048101 sha1 818259159B5E7D3775584B478D4FD36F6A25FCAA flags verified ) + rom ( name "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc 7ff2042f sha1 818259159B5E7D3775584B478D4FD36F6A25FCAA flags verified ) ) game ( name "Alone in the Dark - The New Nightmare (USA) (En,Fr,Es)" description "Alone in the Dark - The New Nightmare (USA) (En,Fr,Es)" - rom ( name "Alone in the Dark - The New Nightmare (USA) (En,Fr,Es).gbc" size 4194304 crc C145C036 md5 D97055E4A2FD4624FC924C4834ACE35E sha1 A348AEAC500D0D8FDAF90F5277631A026504FF44 ) + rom ( name "Alone in the Dark - The New Nightmare (USA) (En,Fr,Es).gbc" size 4194304 crc c145c036 sha1 A348AEAC500D0D8FDAF90F5277631A026504FF44 ) ) game ( - name "Animal Breeder 3 (Japan) (SGB Enhanced)" - description "Animal Breeder 3 (Japan) (SGB Enhanced)" - rom ( name "Animal Breeder 3 (Japan) (SGB Enhanced).gbc" size 4194304 crc C62A4C30 md5 3F0F1CC327FF1BE267B226B85B7A11C6 sha1 F5E6E770A681BB6EBA255E2584F9ED343E5D9F98 flags verified ) + name "Animal Breeder 3 (Japan) (SGB Enhanced) (GB Compatible)" + description "Animal Breeder 3 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Animal Breeder 3 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc c62a4c30 sha1 F5E6E770A681BB6EBA255E2584F9ED343E5D9F98 flags verified ) ) game ( name "Animal Breeder 4 (Japan)" description "Animal Breeder 4 (Japan)" - rom ( name "Animal Breeder 4 (Japan).gbc" size 4194304 crc 83D838C3 md5 22D11B8D9670FB9B4CA84368F0F50CEE sha1 2F7854CFC227ECC395551EA4C0B62256F0757514 flags verified ) + rom ( name "Animal Breeder 4 (Japan).gbc" size 4194304 crc 83d838c3 sha1 2F7854CFC227ECC395551EA4C0B62256F0757514 flags verified ) ) game ( name "Animastar GB (Japan)" description "Animastar GB (Japan)" - rom ( name "Animastar GB (Japan).gbc" size 2097152 crc B14920F0 md5 26C14F848115AF6246B8F514FBEB6DAB sha1 4F141E012FC46CAB0DD36655C2548DFAED0A862F flags verified ) + rom ( name "Animastar GB (Japan).gbc" size 2097152 crc b14920f0 sha1 4F141E012FC46CAB0DD36655C2548DFAED0A862F flags verified ) ) game ( name "Animorphs (Europe) (En,Fr,De,Es,It)" description "Animorphs (Europe) (En,Fr,De,Es,It)" - rom ( name "Animorphs (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 7FD46DA1 md5 6D9AB3B90805908D732C275157E29C79 sha1 C936A5B3C005F72DE5032C4A067A7D95AB2735FA ) + rom ( name "Animorphs (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 7fd46da1 sha1 C936A5B3C005F72DE5032C4A067A7D95AB2735FA ) ) game ( name "Animorphs (USA)" description "Animorphs (USA)" - rom ( name "Animorphs (USA).gbc" size 1048576 crc B4F293CC md5 12E82CB028ED40CDC0C80B2D2E3CF0CB sha1 B3E5B34D5E97C49720861FABB6A29D557029279C ) + rom ( name "Animorphs (USA).gbc" size 1048576 crc b4f293cc sha1 B3E5B34D5E97C49720861FABB6A29D557029279C ) ) game ( name "Anpfiff - Der RTL Fussball-Manager (Germany)" description "Anpfiff - Der RTL Fussball-Manager (Germany)" - rom ( name "Anpfiff - Der RTL Fussball-Manager (Germany).gbc" size 1048576 crc B54D264A md5 D55433C70617D18BB078426E8CD99708 sha1 4C5BD67EEE82A36CF695DB12169BC4393225FAA0 flags verified ) + rom ( name "Anpfiff - Der RTL Fussball-Manager (Germany).gbc" size 1048576 crc b54d264a sha1 4C5BD67EEE82A36CF695DB12169BC4393225FAA0 flags verified ) ) game ( - name "Antz (Europe) (En,Fr,De,Es,It,Nl)" - description "Antz (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Antz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 4839E0C1 md5 E4C1111DCC4DC23860CE016DAF584DC1 sha1 2CBA2B024EDB4B702D2ACABEFBCB310F4D6E2075 ) + name "Antz (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Antz (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Antz (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 4839e0c1 sha1 2CBA2B024EDB4B702D2ACABEFBCB310F4D6E2075 ) ) game ( - name "Antz (USA) (En,Fr,Es)" - description "Antz (USA) (En,Fr,Es)" - rom ( name "Antz (USA) (En,Fr,Es).gbc" size 1048576 crc DC0BE439 md5 A4B695325AC28BE2E388F5B9186987BA sha1 85684D5891E4EC0F9FDF61B644BDF0FFBF1BA219 ) + name "Antz (USA) (En,Fr,Es) (GB Compatible)" + description "Antz (USA) (En,Fr,Es) (GB Compatible)" + rom ( name "Antz (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc dc0be439 sha1 85684D5891E4EC0F9FDF61B644BDF0FFBF1BA219 flags verified ) ) game ( name "Antz Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Antz Racing (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Antz Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc F625A959 md5 CB9C9001A0DF32E6F89216E291684836 sha1 E4FF55112A76DA72F30582476F15358527518CFD flags verified ) + rom ( name "Antz Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f625a959 sha1 E4FF55112A76DA72F30582476F15358527518CFD flags verified ) ) game ( name "Antz Racing (USA) (En,Fr,De,Es,It,Nl)" description "Antz Racing (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Antz Racing (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc DFDF90C0 md5 87397DB3151F3DD5B53CDFBB24A98588 sha1 806E641B911B302F5BE2A80B6003F473D1A10A88 flags verified ) + rom ( name "Antz Racing (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc dfdf90c0 sha1 806E641B911B302F5BE2A80B6003F473D1A10A88 flags verified ) ) game ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl)" description "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 67C7F85C md5 9C3800BABD418A937F4429BBAAF2B81D sha1 D8DDF04BAAD3BEADEDF85847964F986BA89BC5EE ) + rom ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 67c7f85c sha1 D8DDF04BAAD3BEADEDF85847964F986BA89BC5EE ) ) game ( - name "Aqualife (Japan) (SGB Enhanced)" - description "Aqualife (Japan) (SGB Enhanced)" - rom ( name "Aqualife (Japan) (SGB Enhanced).gbc" size 1048576 crc E243FEB4 md5 B40DBE0F8AC98EDE81F05C37DD0F67B1 sha1 69EAF53ECCDAF98CD7CC0D436209F511B558D761 ) + name "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" + description "Aqualife (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Aqualife (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e243feb4 sha1 69EAF53ECCDAF98CD7CC0D436209F511B558D761 flags verified ) ) game ( - name "Arcade Hits - Joust & Defender (USA, Europe)" - description "Arcade Hits - Joust & Defender (USA, Europe)" - rom ( name "Arcade Hits - Joust & Defender (USA, Europe).gbc" size 1048576 crc 4C1ECECB md5 341249F65F19579B9D335C807982B6FA sha1 F0F35970517090165797568448B5EF5CAD8E4952 flags verified ) -) - -game ( - name "Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe)" - description "Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe)" - rom ( name "Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe).gbc" size 1048576 crc F40199C9 md5 8FFCF9DA76AA9BA1C5B1789A92F47D21 sha1 8DC667E7D44B46AD42EC7E465091CFACC0009974 flags verified ) -) - -game ( - name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced)" - description "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced)" - rom ( name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced).gbc" size 1048576 crc 8EE043EA md5 9ABAF0DFEB58B76D6B5CCE4B42756C8E sha1 FB781637DDAC30CEBB1865BA939F49BB2B0B5146 ) + name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" + description "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8ee043ea sha1 FB781637DDAC30CEBB1865BA939F49BB2B0B5146 ) ) game ( name "Armada - FX Racers (USA)" description "Armada - FX Racers (USA)" - rom ( name "Armada - FX Racers (USA).gbc" size 1048576 crc D952CBAB md5 43527E9AFF69649306C749DA2D3C72C0 sha1 B8F911E6D6DC37B9BBFD565F6919A94F17BF3073 ) + rom ( name "Armada - FX Racers (USA).gbc" size 1048576 crc d952cbab sha1 B8F911E6D6DC37B9BBFD565F6919A94F17BF3073 ) ) game ( name "Armorines - Project S.W.A.R.M. (USA, Europe) (En,De)" description "Armorines - Project S.W.A.R.M. (USA, Europe) (En,De)" - rom ( name "Armorines - Project S.W.A.R.M. (USA, Europe) (En,De).gbc" size 1048576 crc EA3B9C73 md5 0B2AB6C8EE77D7DC6856EBFFCFEB9C43 sha1 2BE58EE1A3A76D1259A044C6C7C9DCD6DACF8405 flags verified ) + rom ( name "Armorines - Project S.W.A.R.M. (USA, Europe) (En,De).gbc" size 1048576 crc ea3b9c73 sha1 2BE58EE1A3A76D1259A044C6C7C9DCD6DACF8405 flags verified ) ) game ( name "Army Men (USA, Europe) (En,Fr,De)" description "Army Men (USA, Europe) (En,Fr,De)" - rom ( name "Army Men (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 34411753 md5 C75BF50B9FEC4E89CED9A2BDFBEB4245 sha1 E98CEA1A113BA4774CE26AB16D61625F0870B6AD flags verified ) + rom ( name "Army Men (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 34411753 sha1 E98CEA1A113BA4774CE26AB16D61625F0870B6AD flags verified ) ) game ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De)" description "Army Men - Air Combat (USA, Europe) (En,Fr,De)" - rom ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De).gbc" size 1048576 crc B0D1DE8C md5 C48DE261BB5111681BD77CA5F0D68A1B sha1 4E1D964D31013E79ECAE4A49DCD3777CC7E06AF2 flags verified ) + rom ( name "Army Men - Air Combat (USA, Europe) (En,Fr,De).gbc" size 1048576 crc b0d1de8c sha1 4E1D964D31013E79ECAE4A49DCD3777CC7E06AF2 flags verified ) ) game ( name "Army Men - Sarge's Heroes 2 (USA, Europe) (En,Fr,De)" description "Army Men - Sarge's Heroes 2 (USA, Europe) (En,Fr,De)" - rom ( name "Army Men - Sarge's Heroes 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 71B857EA md5 3DC508D4DA71F2E89CA63B42899741A4 sha1 9A2ADB5639C80282D7465F9C5D30ACB669991D8E flags verified ) + rom ( name "Army Men - Sarge's Heroes 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 71b857ea sha1 9A2ADB5639C80282D7465F9C5D30ACB669991D8E flags verified ) ) game ( name "Army Men 2 (USA, Europe) (En,Fr,De)" description "Army Men 2 (USA, Europe) (En,Fr,De)" - rom ( name "Army Men 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 2272BACA md5 66A744231189D65DB54AA4D670975C5A sha1 6E52DCACA1A97AE557C4C87E4281667A9D9B14C5 flags verified ) + rom ( name "Army Men 2 (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 2272baca sha1 6E52DCACA1A97AE557C4C87E4281667A9D9B14C5 flags verified ) ) game ( name "Arthur's Absolutely Fun Day! (USA)" description "Arthur's Absolutely Fun Day! (USA)" - rom ( name "Arthur's Absolutely Fun Day! (USA).gbc" size 1048576 crc F03599A3 md5 3D630CB2FF52E7FEDFCA6C938B82FA24 sha1 CF1323CFD3FBE8BA8C9766A87A7C68D8B7E729F9 ) + rom ( name "Arthur's Absolutely Fun Day! (USA).gbc" size 1048576 crc f03599a3 sha1 CF1323CFD3FBE8BA8C9766A87A7C68D8B7E729F9 ) ) game ( name "Asterix & Obelix (Europe) (En,Fr,De,Es)" description "Asterix & Obelix (Europe) (En,Fr,De,Es)" - rom ( name "Asterix & Obelix (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6628CDEE md5 6EFC4C27D06564F9000667C029AD02A3 sha1 5F36071DF7BE289C169768B1683947E972D26996 ) + rom ( name "Asterix & Obelix (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6628cdee sha1 5F36071DF7BE289C169768B1683947E972D26996 ) ) game ( - name "Asterix & Obelix vs Caesar (Europe) (En,Fr,De,Es,Nl)" - description "Asterix & Obelix vs Caesar (Europe) (En,Fr,De,Es,Nl)" - rom ( name "Asterix & Obelix vs Caesar (Europe) (En,Fr,De,Es,Nl).gbc" size 1048576 crc 71043D76 md5 B7D6335B8D3A34B15CE0B631BB9731A2 sha1 A4B892D269957D84570C07856C81F48F037B5A03 ) + name "Asterix & Obelix Contre Cesar (Europe) (En,Fr,De,Es,Nl) (GB Compatible)" + description "Asterix & Obelix Contre Cesar (Europe) (En,Fr,De,Es,Nl) (GB Compatible)" + rom ( name "Asterix & Obelix Contre Cesar (Europe) (En,Fr,De,Es,Nl) (GB Compatible).gbc" size 1048576 crc 71043d76 sha1 A4B892D269957D84570C07856C81F48F037B5A03 flags verified ) ) game ( - name "Asterix - Search for Dogmatix (Europe) (En,Fr,De,Es,It,Nl)" - description "Asterix - Search for Dogmatix (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Asterix - Search for Dogmatix (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 408DC5C6 md5 1FAA6E2A7EC92B95CE32FA2682038B9B sha1 5C7207137AB422D3326D183D3433DB161D8ECBC5 flags verified ) + name "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl)" + description "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Asterix - Sur la Trace D'Idefix (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 408dc5c6 sha1 5C7207137AB422D3326D183D3433DB161D8ECBC5 flags verified ) ) game ( - name "Asteroids (USA, Europe)" - description "Asteroids (USA, Europe)" - rom ( name "Asteroids (USA, Europe).gbc" size 1048576 crc 89D5D936 md5 CFAC8209D5119235F678303DFB3CC0F2 sha1 026F031E1BB787A4390E7873227DCB52A069A6E0 flags verified ) + name "Asteroids (USA, Europe) (GB Compatible)" + description "Asteroids (USA, Europe) (GB Compatible)" + rom ( name "Asteroids (USA, Europe) (GB Compatible).gbc" size 1048576 crc 89d5d936 sha1 026F031E1BB787A4390E7873227DCB52A069A6E0 flags verified ) ) game ( name "Atlantis - The Lost Empire (Europe) (En,Es,It)" description "Atlantis - The Lost Empire (Europe) (En,Es,It)" - rom ( name "Atlantis - The Lost Empire (Europe) (En,Es,It).gbc" size 2097152 crc 28F7D5E3 md5 E24141ED6FC94B149BBF43B4BD9658E8 sha1 EF4AB0DD852FFD1418C803C05DDCB245B3A4348D ) + rom ( name "Atlantis - The Lost Empire (Europe) (En,Es,It).gbc" size 2097152 crc 28f7d5e3 sha1 EF4AB0DD852FFD1418C803C05DDCB245B3A4348D flags verified ) ) game ( name "Atlantis - The Lost Empire (Europe) (Fr,De,Nl)" description "Atlantis - The Lost Empire (Europe) (Fr,De,Nl)" - rom ( name "Atlantis - The Lost Empire (Europe) (Fr,De,Nl).gbc" size 2097152 crc 4E052510 md5 C046F62BB3BAF1F8398F5E3FB93DD82A sha1 19DF06E2A8BE1336A6AEC8C86649B95B206DC54F ) + rom ( name "Atlantis - The Lost Empire (Europe) (Fr,De,Nl).gbc" size 2097152 crc 4e052510 sha1 19DF06E2A8BE1336A6AEC8C86649B95B206DC54F flags verified ) ) game ( name "Atlantis - The Lost Empire (USA, Europe)" description "Atlantis - The Lost Empire (USA, Europe)" - rom ( name "Atlantis - The Lost Empire (USA, Europe).gbc" size 2097152 crc D594D24B md5 5AAB47CF957C82C969BBC0A93232F883 sha1 AB5DD8EFA36B33CE9AA090B3D990E8FC8828F7E2 flags verified ) + rom ( name "Atlantis - The Lost Empire (USA, Europe).gbc" size 2097152 crc d594d24b sha1 AB5DD8EFA36B33CE9AA090B3D990E8FC8828F7E2 flags verified ) ) game ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" description "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" - rom ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan).gbc" size 2097152 crc 476EDE93 md5 C74C728CE3177A3A9ABC5870B6762885 sha1 73B95F3B92C2D48A2580F7AC10950D56AEFFB94D flags verified ) + rom ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan).gbc" size 2097152 crc 476ede93 sha1 73B95F3B92C2D48A2580F7AC10950D56AEFFB94D flags verified ) ) game ( name "ATV Racing (Europe) (Unl)" description "ATV Racing (Europe) (Unl)" - rom ( name "ATV Racing (Europe) (Unl).gbc" size 262144 crc 7987D5CD md5 3426BFE0C82DA4C6705F996891579A24 sha1 B3C6C2970C3BFA95FB2EEF10E2160F55F52D8E1A flags verified ) + rom ( name "ATV Racing (Europe) (Unl).gbc" size 262144 crc 7987d5cd sha1 B3C6C2970C3BFA95FB2EEF10E2160F55F52D8E1A flags verified ) ) game ( name "ATV Racing & Karate Joe (Europe) (Unl)" description "ATV Racing & Karate Joe (Europe) (Unl)" - rom ( name "ATV Racing & Karate Joe (Europe) (Unl).gbc" size 524288 crc A07B6E79 md5 B702980F1562A0D66106FF8722675EB9 sha1 3701028D66564625933A3868340813E6D7C36B7B ) + rom ( name "ATV Racing & Karate Joe (Europe) (Unl).gbc" size 524288 crc a07b6e79 sha1 3701028D66564625933A3868340813E6D7C36B7B ) ) game ( name "ATV Racing & Karate Joe (Europe) (Alternate) (Unl)" description "ATV Racing & Karate Joe (Europe) (Alternate) (Unl)" - rom ( name "ATV Racing & Karate Joe (Europe) (Alternate) (Unl).gbc" size 524288 crc 6908F4AF md5 6F0A4D09A4A40CA93A528F2409BB872C sha1 95287B440139E88D90700F892D1DA60AAA4DA778 ) + rom ( name "ATV Racing & Karate Joe (Europe) (Alternate) (Unl).gbc" size 524288 crc 6908f4af sha1 95287B440139E88D90700F892D1DA60AAA4DA778 ) ) game ( name "Austin Powers - Oh, Behave! (Europe) (En,Fr,De,Es,It)" description "Austin Powers - Oh, Behave! (Europe) (En,Fr,De,Es,It)" - rom ( name "Austin Powers - Oh, Behave! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc BF99F8CB md5 1CDC49E8F8340C2CE27FD3F5CDD3D618 sha1 A5D29D48B9BC3E1FA476E475DA24C2D80985188D ) + rom ( name "Austin Powers - Oh, Behave! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc bf99f8cb sha1 A5D29D48B9BC3E1FA476E475DA24C2D80985188D ) ) game ( name "Austin Powers - Oh, Behave! (USA)" description "Austin Powers - Oh, Behave! (USA)" - rom ( name "Austin Powers - Oh, Behave! (USA).gbc" size 4194304 crc BB89190E md5 2ABA33E89CACA45C9091B25A276DD4C6 sha1 AA6CB6AB4FE083CBE0274C40BD30E0013A2F7645 ) + rom ( name "Austin Powers - Oh, Behave! (USA).gbc" size 4194304 crc bb89190e sha1 AA6CB6AB4FE083CBE0274C40BD30E0013A2F7645 ) ) game ( name "Austin Powers - Welcome to my Underground Lair! (Europe) (En,Fr,De,Es,It)" description "Austin Powers - Welcome to my Underground Lair! (Europe) (En,Fr,De,Es,It)" - rom ( name "Austin Powers - Welcome to my Underground Lair! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 693F50DA md5 93226CE541766D8B8B7D1F70866AD530 sha1 02C7C61928AB82B4A8A07BB067D5F5CA32511DF7 flags verified ) + rom ( name "Austin Powers - Welcome to my Underground Lair! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 693f50da sha1 02C7C61928AB82B4A8A07BB067D5F5CA32511DF7 flags verified ) ) game ( name "Austin Powers - Welcome to my Underground Lair! (USA)" description "Austin Powers - Welcome to my Underground Lair! (USA)" - rom ( name "Austin Powers - Welcome to my Underground Lair! (USA).gbc" size 4194304 crc ABA42B78 md5 1B2190911DB606DCE58D694E8B591E69 sha1 69B5106A124BDE38184875C0DD08DE437360BC14 ) + rom ( name "Austin Powers - Welcome to my Underground Lair! (USA).gbc" size 4194304 crc aba42b78 sha1 69B5106A124BDE38184875C0DD08DE437360BC14 ) ) game ( name "Aventures de Buzz l'Eclair, Les (France)" description "Aventures de Buzz l'Eclair, Les (France)" - rom ( name "Aventures de Buzz l'Eclair, Les (France).gbc" size 524288 crc 841674B0 md5 E1AE3E808F17B972D063A0BB0D58888E sha1 4C4C51883B6C73627CA9B04BB0B24E6BAB072F29 ) + rom ( name "Aventures de Buzz l'Eclair, Les (France).gbc" size 524288 crc 841674b0 sha1 4C4C51883B6C73627CA9B04BB0B24E6BAB072F29 ) ) game ( name "Azarashi Sentai Inazuma - Dokidoki Daisakusen! (Japan)" description "Azarashi Sentai Inazuma - Dokidoki Daisakusen! (Japan)" - rom ( name "Azarashi Sentai Inazuma - Dokidoki Daisakusen! (Japan).gbc" size 1048576 crc 98F63BD4 md5 E5D8AEA67AEF0EE94ACF1ED35900EA74 sha1 F4278B01F445562D17A9A2FD8DD5C9BC9D32008E ) + rom ( name "Azarashi Sentai Inazuma - Dokidoki Daisakusen! (Japan).gbc" size 1048576 crc 98f63bd4 sha1 F4278B01F445562D17A9A2FD8DD5C9BC9D32008E flags verified ) ) game ( - name "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced)" - description "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 2097152 crc F9CCAB09 md5 F6B6DDFAAF03392DC469F4EED49EC15D sha1 81D9ACD0E27639F90E38E918A4B0A96FA565D1D9 flags verified ) + name "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Azure Dreams (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc f9ccab09 sha1 81D9ACD0E27639F90E38E918A4B0A96FA565D1D9 flags verified ) ) game ( - name "Azure Dreams (USA) (SGB Enhanced)" - description "Azure Dreams (USA) (SGB Enhanced)" - rom ( name "Azure Dreams (USA) (SGB Enhanced).gbc" size 1048576 crc 71D52876 md5 464ACBE3C82887DB897C39CDBA877237 sha1 1EBC365058DBB4D4F7CCAD6185F4364D584BF250 flags verified ) + name "Azure Dreams (USA) (SGB Enhanced) (GB Compatible)" + description "Azure Dreams (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Azure Dreams (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 71d52876 sha1 1EBC365058DBB4D4F7CCAD6185F4364D584BF250 flags verified ) ) game ( - name "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced)" - description "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced)" - rom ( name "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced).gbc" size 1048576 crc DDCE76D6 md5 BA1195224261ABD308DB025D69EE2227 sha1 4904102846A5FD0176C6F4BFD421F86FB1FAB45B ) + name "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced) (GB Compatible)" + description "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "B-Daman Bakugaiden - Victory e no Michi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ddce76d6 sha1 4904102846A5FD0176C6F4BFD421F86FB1FAB45B flags verified ) ) game ( name "B-Daman Bakugaiden V - Final Mega Tune (Japan)" description "B-Daman Bakugaiden V - Final Mega Tune (Japan)" - rom ( name "B-Daman Bakugaiden V - Final Mega Tune (Japan).gbc" size 2097152 crc 547A9A69 md5 A10A70354CC998E31F0B5FB27C471C37 sha1 7933FE70912EE74F14199A149EDE69BDB153F4AD ) + rom ( name "B-Daman Bakugaiden V - Final Mega Tune (Japan).gbc" size 2097152 crc 547a9a69 sha1 7933FE70912EE74F14199A149EDE69BDB153F4AD ) ) game ( - name "Babe and Friends (Europe) (En,Fr,De,Es,It)" - description "Babe and Friends (Europe) (En,Fr,De,Es,It)" - rom ( name "Babe and Friends (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc B3681854 md5 146BC8912C207C200535B84C5ACFB06A sha1 52A560185B7E77E5286771F7851F69323512658E ) + name "Babe and Friends (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Babe and Friends (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Babe and Friends (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc b3681854 sha1 52A560185B7E77E5286771F7851F69323512658E flags verified ) ) game ( - name "Babe and Friends (USA)" - description "Babe and Friends (USA)" - rom ( name "Babe and Friends (USA).gbc" size 1048576 crc E25407F1 md5 5423B2D603C9D4381594AA3D68441A69 sha1 51A4FD838903039B60BF5C13677CBEA6BBB7D368 ) + name "Babe and Friends (USA) (GB Compatible)" + description "Babe and Friends (USA) (GB Compatible)" + rom ( name "Babe and Friends (USA) (GB Compatible).gbc" size 1048576 crc e25407f1 sha1 51A4FD838903039B60BF5C13677CBEA6BBB7D368 ) ) game ( name "Baby Felix - Halloween (Europe) (En,Fr,De,Es,It,Nl)" description "Baby Felix - Halloween (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Baby Felix - Halloween (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 7DED5C71 md5 45C4B87D2E3FE86FCCC6941FFD724098 sha1 6C924F693E08E32C0E59F386CD728BEB32D00105 ) + rom ( name "Baby Felix - Halloween (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 7ded5c71 sha1 6C924F693E08E32C0E59F386CD728BEB32D00105 ) ) game ( - name "Backgammon (Europe) (En,Fr,De,Es)" - description "Backgammon (Europe) (En,Fr,De,Es)" - rom ( name "Backgammon (Europe) (En,Fr,De,Es).gbc" size 1048576 crc D33D6F7B md5 FF1B35A16B0ECA8E1FB10AF164E66421 sha1 B634A2980EFE1378ECB26A761241D48F4604E5F0 ) + name "Back to Earth 3D (Europe) (Demo)" + description "Back to Earth 3D (Europe) (Demo)" + rom ( name "Back to Earth 3D (Europe) (Demo).gbc" size 262144 crc d4255616 sha1 716722ED8756B656BBA00CBFF116F883E629CFD2 flags verified ) ) game ( - name "Backgammon (Japan)" - description "Backgammon (Japan)" - rom ( name "Backgammon (Japan).gbc" size 1048576 crc 712A49B3 md5 D14C8CBCCA2510A3C92107312999BEBC sha1 EB8B70E445174A812044CA5B101BDCB00C389940 ) + name "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" + description "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" + rom ( name "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible).gbc" size 1048576 crc d33d6f7b sha1 B634A2980EFE1378ECB26A761241D48F4604E5F0 ) +) + +game ( + name "Backgammon (Japan) (GB Compatible)" + description "Backgammon (Japan) (GB Compatible)" + rom ( name "Backgammon (Japan) (GB Compatible).gbc" size 1048576 crc 712a49b3 sha1 EB8B70E445174A812044CA5B101BDCB00C389940 ) ) game ( name "Bad Badtz-Maru Robo Battle (Japan)" description "Bad Badtz-Maru Robo Battle (Japan)" - rom ( name "Bad Badtz-Maru Robo Battle (Japan).gbc" size 2097152 crc 4DD29B09 md5 21C2DD91AE2D46C006C00CACA96D2B6B sha1 DA06158A4D3AED781E77A5F69FAAF522B0A98CBD ) + rom ( name "Bad Badtz-Maru Robo Battle (Japan).gbc" size 2097152 crc 4dd29b09 sha1 DA06158A4D3AED781E77A5F69FAAF522B0A98CBD flags verified ) ) game ( - name "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced)" - description "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced)" - rom ( name "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced).gbc" size 1048576 crc 5C95D5A2 md5 60DF8A170849C5F5A6F94B1531A29A34 sha1 952933A658F0B4182619E7184F49AA4A47FC5F84 flags verified ) + name "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced) (GB Compatible)" + description "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Bakukyuu Renpatsu!! Super B-Daman - Gekitan! Rising Valkyrie!! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 5c95d5a2 sha1 952933A658F0B4182619E7184F49AA4A47FC5F84 flags verified ) ) game ( name "Bakusou Dekotora Densetsu GB Special - Otoko Dokyou no Tenka Touitsu (Japan)" description "Bakusou Dekotora Densetsu GB Special - Otoko Dokyou no Tenka Touitsu (Japan)" - rom ( name "Bakusou Dekotora Densetsu GB Special - Otoko Dokyou no Tenka Touitsu (Japan).gbc" size 1048576 crc 92C8B9B5 md5 4D6CE58AC78078D47A807CB326C3919A sha1 50B115869BB9C488B3766C58EE44DE63A84BA489 flags verified ) + rom ( name "Bakusou Dekotora Densetsu GB Special - Otoko Dokyou no Tenka Touitsu (Japan).gbc" size 1048576 crc 92c8b9b5 sha1 50B115869BB9C488B3766C58EE44DE63A84BA489 flags verified ) ) game ( - name "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan)" - description "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan)" - rom ( name "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan).gbc" size 1048576 crc D514C9A0 md5 CEB1A6C3CE3D2921C0FB65F420F811FA sha1 1F8088A739DF180ECCEAFF1B37ED5C1A50772405 flags verified ) + name "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan) (GB Compatible)" + description "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan) (GB Compatible)" + rom ( name "Bakusou Senki Metal Walker GB - Koutetsu no Yuujou (Japan) (GB Compatible).gbc" size 1048576 crc d514c9a0 sha1 1F8088A739DF180ECCEAFF1B37ED5C1A50772405 flags verified ) ) game ( name "Bakuten Shoot Beyblade (Japan)" description "Bakuten Shoot Beyblade (Japan)" - rom ( name "Bakuten Shoot Beyblade (Japan).gbc" size 2097152 crc BC306EA4 md5 50F6FE2488600B1B80B8DEA0AEEAC2E1 sha1 68D41BCA8D2AC8E9A6855460B15E6045ACD341A1 ) + rom ( name "Bakuten Shoot Beyblade (Japan).gbc" size 2097152 crc bc306ea4 sha1 68D41BCA8D2AC8E9A6855460B15E6045ACD341A1 ) ) game ( - name "Ballistic (USA)" - description "Ballistic (USA)" - rom ( name "Ballistic (USA).gbc" size 524288 crc A9050F72 md5 3B783F3FDED9C61F2F9BB1D956BFD6CD sha1 28DFDC00EC7E353F4AAE4C65D671300C0B97AB90 ) + name "Ballistic (USA) (GB Compatible)" + description "Ballistic (USA) (GB Compatible)" + rom ( name "Ballistic (USA) (GB Compatible).gbc" size 524288 crc a9050f72 sha1 28DFDC00EC7E353F4AAE4C65D671300C0B97AB90 ) ) game ( - name "Balloon Fight GB (Japan) (NP, SGB Enhanced)" - description "Balloon Fight GB (Japan) (NP, SGB Enhanced)" - rom ( name "Balloon Fight GB (Japan) (NP, SGB Enhanced).gbc" size 262144 crc D2AF64CE md5 F94F61E6BEAEC6222E0D35229E2E271E sha1 DBAA1BF9061DE0F052704D6A33892341A38F2152 ) + name "Balloon Fight GB (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Balloon Fight GB (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Balloon Fight GB (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc d2af64ce sha1 DBAA1BF9061DE0F052704D6A33892341A38F2152 ) ) game ( - name "Barbie - Aventura Submarina (Spain)" - description "Barbie - Aventura Submarina (Spain)" - rom ( name "Barbie - Aventura Submarina (Spain).gbc" size 1048576 crc 0CF2B7F2 md5 28DD8318BD521B42243AF4546062ECAB sha1 7B342745F14F0A2245B961CFD6E23D1B2E98C249 ) + name "Barbie - Aventura Submarina (Spain) (GB Compatible)" + description "Barbie - Aventura Submarina (Spain) (GB Compatible)" + rom ( name "Barbie - Aventura Submarina (Spain) (GB Compatible).gbc" size 1048576 crc 0cf2b7f2 sha1 7B342745F14F0A2245B961CFD6E23D1B2E98C249 flags verified ) ) game ( - name "Barbie - Avventure nell'Oceano (Italy)" - description "Barbie - Avventure nell'Oceano (Italy)" - rom ( name "Barbie - Avventure nell'Oceano (Italy).gbc" size 1048576 crc 59645A18 md5 8565F7B388A1741FE41A8C972D95869E sha1 79EA73D94D2402525C718563B5613BEE71B69B44 ) + name "Barbie - Avventure nell'Oceano (Italy) (GB Compatible)" + description "Barbie - Avventure nell'Oceano (Italy) (GB Compatible)" + rom ( name "Barbie - Avventure nell'Oceano (Italy) (GB Compatible).gbc" size 1048576 crc 59645a18 sha1 79EA73D94D2402525C718563B5613BEE71B69B44 flags verified ) ) game ( - name "Barbie - Chasse au Tresor Sous-Marine (France)" - description "Barbie - Chasse au Tresor Sous-Marine (France)" - rom ( name "Barbie - Chasse au Tresor Sous-Marine (France).gbc" size 1048576 crc 4068E981 md5 21D99FB62922E3538C0B11749A7DB8E4 sha1 BC44D39CCE1F3143E9FA830EDE2B4126A4D61B54 ) + name "Barbie - Chasse au Tresor Sous-Marine (France) (GB Compatible)" + description "Barbie - Chasse au Tresor Sous-Marine (France) (GB Compatible)" + rom ( name "Barbie - Chasse au Tresor Sous-Marine (France) (GB Compatible).gbc" size 1048576 crc 4068e981 sha1 BC44D39CCE1F3143E9FA830EDE2B4126A4D61B54 ) ) game ( - name "Barbie - Diepzee Avontuur (Netherlands)" - description "Barbie - Diepzee Avontuur (Netherlands)" - rom ( name "Barbie - Diepzee Avontuur (Netherlands).gbc" size 1048576 crc 39C6B8DF md5 CC130E8228A37ECC3D38F7F34AAFEDAA sha1 3E93DF9512819679DEAC989895DE398A6159645C ) + name "Barbie - Diepzee Avontuur (Netherlands) (GB Compatible)" + description "Barbie - Diepzee Avontuur (Netherlands) (GB Compatible)" + rom ( name "Barbie - Diepzee Avontuur (Netherlands) (GB Compatible).gbc" size 1048576 crc 39c6b8df sha1 3E93DF9512819679DEAC989895DE398A6159645C flags verified ) ) game ( - name "Barbie - Fashion Pack Games (USA, Europe)" - description "Barbie - Fashion Pack Games (USA, Europe)" - rom ( name "Barbie - Fashion Pack Games (USA, Europe).gbc" size 1048576 crc 09EE93A8 md5 45EEADE46BD85F80AF13AF9DCE572B9C sha1 FECBDE9125D2CE9C8E772F9078EBACCD196CAA43 flags verified ) + name "Barbie - Fashion Pack Games (USA, Europe) (GB Compatible)" + description "Barbie - Fashion Pack Games (USA, Europe) (GB Compatible)" + rom ( name "Barbie - Fashion Pack Games (USA, Europe) (GB Compatible).gbc" size 1048576 crc 09ee93a8 sha1 FECBDE9125D2CE9C8E772F9078EBACCD196CAA43 flags verified ) ) game ( name "Barbie - Magic Genie Adventure (USA)" description "Barbie - Magic Genie Adventure (USA)" - rom ( name "Barbie - Magic Genie Adventure (USA).gbc" size 1048576 crc 57F1A202 md5 829DA007514E8A1CCC7EFE6A7EE5226F sha1 30E779F19CD8F8C979BDA38DD90E9798C742A66C ) + rom ( name "Barbie - Magic Genie Adventure (USA).gbc" size 1048576 crc 57f1a202 sha1 30E779F19CD8F8C979BDA38DD90E9798C742A66C ) ) game ( - name "Barbie - Meeres Abenteuer (Germany)" - description "Barbie - Meeres Abenteuer (Germany)" - rom ( name "Barbie - Meeres Abenteuer (Germany).gbc" size 1048576 crc 5E46D64A md5 CE1B3EFD190F51E089BEC904E92A5F01 sha1 C392AEFB3D657CAE6602E285F5FB57EC079A818E flags verified ) + name "Barbie - Meeres Abenteuer (Germany) (GB Compatible)" + description "Barbie - Meeres Abenteuer (Germany) (GB Compatible)" + rom ( name "Barbie - Meeres Abenteuer (Germany) (GB Compatible).gbc" size 1048576 crc 5e46d64a sha1 C392AEFB3D657CAE6602E285F5FB57EC079A818E flags verified ) ) game ( - name "Barbie - Ocean Discovery (Europe)" - description "Barbie - Ocean Discovery (Europe)" - rom ( name "Barbie - Ocean Discovery (Europe).gbc" size 1048576 crc FDC8E7F1 md5 0D4F6B00B4A1B047EF13A91537F7314A sha1 C0C37864E17F11FFFA8B8A61A0ABE4B2B80C235C ) + name "Barbie - Ocean Discovery (Europe) (GB Compatible)" + description "Barbie - Ocean Discovery (Europe) (GB Compatible)" + rom ( name "Barbie - Ocean Discovery (Europe) (GB Compatible).gbc" size 1048576 crc fdc8e7f1 sha1 C0C37864E17F11FFFA8B8A61A0ABE4B2B80C235C ) ) game ( - name "Barbie - Ocean Discovery (USA)" - description "Barbie - Ocean Discovery (USA)" - rom ( name "Barbie - Ocean Discovery (USA).gbc" size 1048576 crc 746936C6 md5 89DE435CB69325B42D569015CA09F49F sha1 FAB988692A19D53E71FC754DEA3A01506B104D9F ) + name "Barbie - Ocean Discovery (USA) (GB Compatible)" + description "Barbie - Ocean Discovery (USA) (GB Compatible)" + rom ( name "Barbie - Ocean Discovery (USA) (GB Compatible).gbc" size 1048576 crc 746936c6 sha1 FAB988692A19D53E71FC754DEA3A01506B104D9F ) ) game ( name "Barbie - Pet Rescue (Europe) (En,Fr,De,Es,It)" description "Barbie - Pet Rescue (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie - Pet Rescue (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 48E638CE md5 DCCB2ADEC6B97AC35614414A427ABDBB sha1 191A42E0EAF6AFB58BC8AACA0EE8DAD0641594D4 ) + rom ( name "Barbie - Pet Rescue (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 48e638ce sha1 191A42E0EAF6AFB58BC8AACA0EE8DAD0641594D4 flags verified ) ) game ( name "Barbie - Pet Rescue (USA)" description "Barbie - Pet Rescue (USA)" - rom ( name "Barbie - Pet Rescue (USA).gbc" size 1048576 crc 1FC972CC md5 BBFD881158BAE49739DCE7E60C6AEAB2 sha1 FFED44AB063C4181D5DF85FF1304DE10FA6392CD ) -) - -game ( - name "Barbie - Shelly Club (Europe) (En,Fr,De,Es,It)" - description "Barbie - Shelly Club (Europe) (En,Fr,De,Es,It)" - rom ( name "Barbie - Shelly Club (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 767CAA42 md5 0FC64C4AEE8AA7A11ED80C4E93F63F47 sha1 F81FE7427484D9C2AF043819690FAE9B81B29813 flags verified ) + rom ( name "Barbie - Pet Rescue (USA).gbc" size 1048576 crc 1fc972cc sha1 FFED44AB063C4181D5DF85FF1304DE10FA6392CD ) ) game ( name "Barca Total 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca)" description "Barca Total 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca)" - rom ( name "Barca Total 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc CD15ED36 md5 522910C5DAF605B45745FA97CDA41F84 sha1 24B8F400D74E9F0AA82D27D82A3B15DB3E743240 ) + rom ( name "Barca Total 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc cd15ed36 sha1 24B8F400D74E9F0AA82D27D82A3B15DB3E743240 ) ) game ( - name "Barcode Taisen Bardigun (Japan) (SGB Enhanced)" - description "Barcode Taisen Bardigun (Japan) (SGB Enhanced)" - rom ( name "Barcode Taisen Bardigun (Japan) (SGB Enhanced).gbc" size 1048576 crc DDFCF4B7 md5 00CA1749B004D4C38CDFC884BD547F72 sha1 BC7847DEE730BA274F3C3CCB511F1DAD6B6A93C7 flags verified ) + name "Barcode Taisen Bardigun (Japan) (SGB Enhanced) (GB Compatible)" + description "Barcode Taisen Bardigun (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Barcode Taisen Bardigun (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ddfcf4b7 sha1 BC7847DEE730BA274F3C3CCB511F1DAD6B6A93C7 flags verified ) ) game ( - name "Bass Masters Classic (USA, Europe)" - description "Bass Masters Classic (USA, Europe)" - rom ( name "Bass Masters Classic (USA, Europe).gbc" size 1048576 crc B70028E4 md5 3BFA6ECA3E26C8B4EE8E31AC7064085A sha1 B1BD238640E99E3584C8C4E4FA174FF144B600D6 flags verified ) + name "Barcode Taisen Bardigun (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Barcode Taisen Bardigun (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Barcode Taisen Bardigun (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f6d291a9 sha1 21E386F60FCD3694C4A308DE9E178762C5175B6C flags verified ) +) + +game ( + name "Bass Masters Classic (USA, Europe) (GB Compatible)" + description "Bass Masters Classic (USA, Europe) (GB Compatible)" + rom ( name "Bass Masters Classic (USA, Europe) (GB Compatible).gbc" size 1048576 crc b70028e4 sha1 B1BD238640E99E3584C8C4E4FA174FF144B600D6 flags verified ) +) + +game ( + name "Batman - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl)" + description "Batman - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Batman - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc e025067b sha1 DBC6C729DDE21ABF324E2A055D819F088E696C0C flags verified ) +) + +game ( + name "Batman - Chaos in Gotham (USA)" + description "Batman - Chaos in Gotham (USA)" + rom ( name "Batman - Chaos in Gotham (USA).gbc" size 1048576 crc b241a4f3 sha1 DE2D6A53316011B60FBC9A946F510EFFE42EDE5E ) ) game ( name "Batman Beyond - Return of the Joker (Japan) (NP)" description "Batman Beyond - Return of the Joker (Japan) (NP)" - rom ( name "Batman Beyond - Return of the Joker (Japan) (NP).gbc" size 1048576 crc B8B1F8F8 md5 CDF275A96518EFD2236F0BBB5321C0E3 sha1 47C8A56FA67D4982ED36FCA56EF0F33C451A0C49 flags verified ) + rom ( name "Batman Beyond - Return of the Joker (Japan) (NP).gbc" size 1048576 crc b8b1f8f8 sha1 47C8A56FA67D4982ED36FCA56EF0F33C451A0C49 flags verified ) ) game ( name "Batman Beyond - Return of the Joker (USA)" description "Batman Beyond - Return of the Joker (USA)" - rom ( name "Batman Beyond - Return of the Joker (USA).gbc" size 1048576 crc B32F4586 md5 DD9E7C40F202F2C3963930E195D75F4D sha1 8C69EB7EC5BC809EDC8CAA255576F919EA722DAD ) + rom ( name "Batman Beyond - Return of the Joker (USA).gbc" size 1048576 crc b32f4586 sha1 8C69EB7EC5BC809EDC8CAA255576F919EA722DAD ) ) game ( name "Batman of the Future - Return of the Joker (Europe) (En,Fr,De)" description "Batman of the Future - Return of the Joker (Europe) (En,Fr,De)" - rom ( name "Batman of the Future - Return of the Joker (Europe) (En,Fr,De).gbc" size 1048576 crc F9D5B399 md5 19CD9D45C6BB221613101B22C72593B2 sha1 102AA62C873B7316B1B019D895989DCDEDB776A9 ) + rom ( name "Batman of the Future - Return of the Joker (Europe) (En,Fr,De).gbc" size 1048576 crc f9d5b399 sha1 102AA62C873B7316B1B019D895989DCDEDB776A9 ) ) game ( name "Battle Fishers (Japan)" description "Battle Fishers (Japan)" - rom ( name "Battle Fishers (Japan).gbc" size 2097152 crc C99CF3C5 md5 2376C643827D665E9883FFD1B5AC5B37 sha1 25D063B151C2D45A14D6952196490615B7E341C5 ) + rom ( name "Battle Fishers (Japan).gbc" size 2097152 crc c99cf3c5 sha1 25D063B151C2D45A14D6952196490615B7E341C5 ) ) game ( - name "Battleship (USA, Europe)" - description "Battleship (USA, Europe)" - rom ( name "Battleship (USA, Europe).gbc" size 1048576 crc 8E6F8037 md5 FD1F17AA8C4B5C2963DB8B0444673A3D sha1 48A6CC9C5695378A118DEB6B1035C15A26D476D7 flags verified ) + name "Battleship (USA, Europe) (GB Compatible)" + description "Battleship (USA, Europe) (GB Compatible)" + rom ( name "Battleship (USA, Europe) (GB Compatible).gbc" size 1048576 crc 8e6f8037 sha1 48A6CC9C5695378A118DEB6B1035C15A26D476D7 flags verified ) ) game ( name "BattleTanx (Europe) (En,Fr,De)" description "BattleTanx (Europe) (En,Fr,De)" - rom ( name "BattleTanx (Europe) (En,Fr,De).gbc" size 1048576 crc 2FCECB70 md5 4B146CE804A9B9C90467742508A67B5F sha1 D9F52594F79257DC616428A694C1F2C808797361 ) + rom ( name "BattleTanx (Europe) (En,Fr,De).gbc" size 1048576 crc 2fcecb70 sha1 D9F52594F79257DC616428A694C1F2C808797361 flags verified ) ) game ( name "BattleTanx (USA)" description "BattleTanx (USA)" - rom ( name "BattleTanx (USA).gbc" size 1048576 crc 4431F8E7 md5 4CA71B12D89A5BCFCC52095081AE9F51 sha1 5078584E86C0B6F4687C424CC00BBD762BA6573A ) + rom ( name "BattleTanx (USA).gbc" size 1048576 crc 4431f8e7 sha1 5078584E86C0B6F4687C424CC00BBD762BA6573A ) ) game ( name "Beach'n Ball (Europe) (En,Fr,De,Es,It)" description "Beach'n Ball (Europe) (En,Fr,De,Es,It)" - rom ( name "Beach'n Ball (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 82D1A721 md5 576E3A9D7DA60439C8FB28C81B56FE5A sha1 90C0AB55136235D75A4E35BD5B0D90A99D2A42C4 flags verified ) -) - -game ( - name "Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl)" - description "Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 48C99939 md5 82880772EBD67B839C497DFE4308A0A0 sha1 A5C2BB5244FE0FD6D2710C832F66F8F8B8C2BBAB flags verified ) -) - -game ( - name "Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl)" - description "Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 851C8710 md5 AFE51A74C6967711DDD263E3998B7AFD sha1 E4C1C58025A083C067F752490C1FBD816C93D072 flags verified ) + rom ( name "Beach'n Ball (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 82d1a721 sha1 90C0AB55136235D75A4E35BD5B0D90A99D2A42C4 flags verified ) ) game ( name "Beast Fighter (Taiwan) (En) (1B-001, Sachen) (Unl)" description "Beast Fighter (Taiwan) (En) (1B-001, Sachen) (Unl)" - rom ( name "Beast Fighter (Taiwan) (En) (1B-001, Sachen) (Unl).gbc" size 131072 crc 0BC7A3C6 md5 A1D7687A557DD2A3948C9F498703F4A3 sha1 BB76BC7EA3482E775EFDBBF112455921D11AC317 ) + rom ( name "Beast Fighter (Taiwan) (En) (1B-001, Sachen) (Unl).gbc" size 131072 crc 0bc7a3c6 sha1 BB76BC7EA3482E775EFDBBF112455921D11AC317 flags verified ) ) game ( - name "Beatmania GB (Japan) (SGB Enhanced)" - description "Beatmania GB (Japan) (SGB Enhanced)" - rom ( name "Beatmania GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 0D9CB195 md5 E7C022031CB882912E81970EB63D4F61 sha1 640C4633FE8EC60B767C15A094C87AB7E113D555 flags verified ) + name "Beatmania GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Beatmania GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Beatmania GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0d9cb195 sha1 640C4633FE8EC60B767C15A094C87AB7E113D555 flags verified ) ) game ( name "Beatmania GB - Gotcha Mix 2 (Japan)" description "Beatmania GB - Gotcha Mix 2 (Japan)" - rom ( name "Beatmania GB - Gotcha Mix 2 (Japan).gbc" size 2097152 crc B92A6D16 md5 490CF7B762F7B735F249C3A3107C3E55 sha1 DCD054D461CDE099DF09ED61A77B05FBACD7AF0B ) + rom ( name "Beatmania GB - Gotcha Mix 2 (Japan).gbc" size 2097152 crc b92a6d16 sha1 DCD054D461CDE099DF09ED61A77B05FBACD7AF0B ) ) game ( - name "Beatmania GB2 - Gotcha Mix (Japan) (SGB Enhanced)" - description "Beatmania GB2 - Gotcha Mix (Japan) (SGB Enhanced)" - rom ( name "Beatmania GB2 - Gotcha Mix (Japan) (SGB Enhanced).gbc" size 1048576 crc 59BEB372 md5 25F20CDC0F6F70D0BC5430A9B0D48742 sha1 B6273C434E880D6F9B5F4F6F53307BDA9902FFF1 flags verified ) + name "Beatmania GB 2 - Gotcha Mix (Japan) (SGB Enhanced) (GB Compatible)" + description "Beatmania GB 2 - Gotcha Mix (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Beatmania GB 2 - Gotcha Mix (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 59beb372 sha1 B6273C434E880D6F9B5F4F6F53307BDA9902FFF1 flags verified ) ) game ( - name "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced)" - description "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced)" - rom ( name "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced).gbc" size 1048576 crc E4C410F0 md5 6D51DCD9012C1140F73D7FD753698ABF sha1 2DD29D52972948724F989008F7896D0ADCBA67C4 flags verified ) + name "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + description "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + rom ( name "Beauty and the Beast - A Board Game Adventure (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e4c410f0 sha1 2DD29D52972948724F989008F7896D0ADCBA67C4 flags verified ) ) game ( - name "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced)" - description "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced)" - rom ( name "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced).gbc" size 1048576 crc 6DE1D581 md5 FA826469AB786988785B6EF36E902010 sha1 6D389C7AFF887D7FFE3739E78753CF81CC71D04C ) + name "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced) (GB Compatible)" + description "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Beauty and the Beast - A Board Game Adventure (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6de1d581 sha1 6D389C7AFF887D7FFE3739E78753CF81CC71D04C ) ) game ( name "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany)" description "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany)" - rom ( name "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany).gbc" size 2097152 crc 51972995 md5 39E9649316E36BAD957E98A2170DF6D0 sha1 560FC8468ED559A72087F630EFF015FFB8DE22CA flags verified ) + rom ( name "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany).gbc" size 2097152 crc 51972995 sha1 560FC8468ED559A72087F630EFF015FFB8DE22CA flags verified ) ) game ( name "Beyblade - Fighting Tournament (Japan)" description "Beyblade - Fighting Tournament (Japan)" - rom ( name "Beyblade - Fighting Tournament (Japan).gbc" size 2097152 crc 1EC9DB95 md5 B061DB3DD5861ADDEAF22A83AF802491 sha1 ACA5562C6747BC2F127ADA53F853B099ED6E12CD ) + rom ( name "Beyblade - Fighting Tournament (Japan).gbc" size 2097152 crc 1ec9db95 sha1 ACA5562C6747BC2F127ADA53F853B099ED6E12CD ) ) game ( name "Bibi Blocksberg - Im Bann der Hexenkugel (Germany)" description "Bibi Blocksberg - Im Bann der Hexenkugel (Germany)" - rom ( name "Bibi Blocksberg - Im Bann der Hexenkugel (Germany).gbc" size 1048576 crc 4D39FBFE md5 237662AB7A441DE5042F347342C6080B sha1 1E26308BA5EE640540430A0B02D5F30E3BE38832 flags verified ) + rom ( name "Bibi Blocksberg - Im Bann der Hexenkugel (Germany).gbc" size 1048576 crc 4d39fbfe sha1 1E26308BA5EE640540430A0B02D5F30E3BE38832 flags verified ) ) game ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany)" description "Bibi und Tina - Fohlen Felix in Gefahr (Germany)" - rom ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany).gbc" size 1048576 crc 8874ACD4 md5 E91752013F0FB62CF0E52873C412CEEB sha1 59843CED1E9CBCB02C6ACBB8F533EC77B314882C flags verified ) + rom ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany).gbc" size 1048576 crc 8874acd4 sha1 59843CED1E9CBCB02C6ACBB8F533EC77B314882C flags verified ) ) game ( - name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced)" - description "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced)" - rom ( name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced).gbc" size 2097152 crc 5BE2517C md5 4CF9559ECE4F20E20F0A0DF646F4B68B sha1 C3C608F1B3581A070C9B7EB65B6FB6D1B72D98D3 ) + name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 5be2517c sha1 C3C608F1B3581A070C9B7EB65B6FB6D1B72D98D3 flags verified ) ) game ( name "Billy Bob's Huntin' 'n' Fishin' (USA, Europe)" description "Billy Bob's Huntin' 'n' Fishin' (USA, Europe)" - rom ( name "Billy Bob's Huntin' 'n' Fishin' (USA, Europe).gbc" size 1048576 crc FA1E6853 md5 70739BD1B6EB0ECB06FE5954F94D74FC sha1 9331FB3103A23340192968715ADAA1E4EF140329 flags verified ) + rom ( name "Billy Bob's Huntin' 'n' Fishin' (USA, Europe).gbc" size 1048576 crc fa1e6853 sha1 9331FB3103A23340192968715ADAA1E4EF140329 flags verified ) ) game ( name "Biohazard Gaiden (Japan)" description "Biohazard Gaiden (Japan)" - rom ( name "Biohazard Gaiden (Japan).gbc" size 2097152 crc C2531D36 md5 06545852ED3F3CD018C95F6D3C5FBBEE sha1 09CA57FEDC0C876F6C172E0DC73D616A6D66EA69 ) + rom ( name "Biohazard Gaiden (Japan).gbc" size 2097152 crc c2531d36 sha1 09CA57FEDC0C876F6C172E0DC73D616A6D66EA69 ) ) game ( name "Bionic Commando - Elite Forces (USA, Australia)" description "Bionic Commando - Elite Forces (USA, Australia)" - rom ( name "Bionic Commando - Elite Forces (USA, Australia).gbc" size 2097152 crc A663CF31 md5 B3347B3219A7183697E83655F4628827 sha1 33C28A2183F8B95CC2D8E0B6A0B005BFC230F1FC flags verified ) + rom ( name "Bionic Commando - Elite Forces (USA, Australia).gbc" size 2097152 crc a663cf31 sha1 33C28A2183F8B95CC2D8E0B6A0B005BFC230F1FC flags verified ) ) game ( - name "Black Bass - Lure Fishing (USA, Europe)" - description "Black Bass - Lure Fishing (USA, Europe)" - rom ( name "Black Bass - Lure Fishing (USA, Europe).gbc" size 1048576 crc E44977DC md5 A30B8E40344BCFBEB08110C79DE4AF14 sha1 0E8D93CD183A53ABA67780372C71CCA71E92A9C1 flags verified ) + name "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" + description "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" + rom ( name "Black Bass - Lure Fishing (USA, Europe) (GB Compatible).gbc" size 1048576 crc e44977dc sha1 0E8D93CD183A53ABA67780372C71CCA71E92A9C1 flags verified ) ) game ( name "Black Onyx, The (Japan)" description "Black Onyx, The (Japan)" - rom ( name "Black Onyx, The (Japan).gbc" size 1048576 crc 582FE338 md5 69B87B5555A44BCABA30B3F4A53275D8 sha1 B0F009023A25E575B59E55DEC07CDA2826F48B65 ) + rom ( name "Black Onyx, The (Japan).gbc" size 1048576 crc 582fe338 sha1 B0F009023A25E575B59E55DEC07CDA2826F48B65 ) ) game ( name "Blade (USA, Europe)" description "Blade (USA, Europe)" - rom ( name "Blade (USA, Europe).gbc" size 1048576 crc 2DD5907F md5 6B3CEB7BB280C0C0CB7543FE33925CB7 sha1 AAAD2F4ED8DBB4455704896F8FF0BC70E7D50B65 flags verified ) + rom ( name "Blade (USA, Europe).gbc" size 1048576 crc 2dd5907f sha1 AAAD2F4ED8DBB4455704896F8FF0BC70E7D50B65 flags verified ) ) game ( - name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced)" - description "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced)" - rom ( name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 2F91E17C md5 756664AA0C9418B200946AA4E1DDDF53 sha1 8B2E83D7F2B7D72D5CC1AC81C28C2173AD2FC9BA flags verified ) + name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2f91e17c sha1 8B2E83D7F2B7D72D5CC1AC81C28C2173AD2FC9BA flags verified ) ) game ( name "Blue's Clues - Blue's Alphabet Book (USA)" description "Blue's Clues - Blue's Alphabet Book (USA)" - rom ( name "Blue's Clues - Blue's Alphabet Book (USA).gbc" size 1048576 crc 748D1345 md5 6AF9BB4957485A0F5CEBC9B44E805392 sha1 F703B54746CB2EF08DEBA2518CE7B7A3836142AA ) + rom ( name "Blue's Clues - Blue's Alphabet Book (USA).gbc" size 1048576 crc 748d1345 sha1 F703B54746CB2EF08DEBA2518CE7B7A3836142AA ) ) game ( name "Boarder Zone (USA)" description "Boarder Zone (USA)" - rom ( name "Boarder Zone (USA).gbc" size 2097152 crc A7152869 md5 8907AAB5ACF0ED74753D6F573E81BE91 sha1 116020A7C2D87ED16436E7710CFED7A93E81289A ) + rom ( name "Boarder Zone (USA).gbc" size 2097152 crc a7152869 sha1 116020A7C2D87ED16436E7710CFED7A93E81289A ) ) game ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,De,Es,Nl)" description "Bob the Builder - Fix it Fun! (Europe) (En,Fr,De,Es,Nl)" - rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,De,Es,Nl).gbc" size 1048576 crc EA33FE3D md5 19B640026DA40602272559D1ED35BBBA sha1 167561998C356253C7092AD200DD1BC5386446A7 ) + rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,De,Es,Nl).gbc" size 1048576 crc ea33fe3d sha1 167561998C356253C7092AD200DD1BC5386446A7 ) ) game ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,It)" description "Bob the Builder - Fix it Fun! (Europe) (En,Fr,It)" - rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,It).gbc" size 1048576 crc A8EBD88B md5 D7B8309532D3316447A9202CB2F19018 sha1 476C75CBC05431E692DEC8F4E10BCEE9D3F5431A ) + rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Fr,It).gbc" size 1048576 crc a8ebd88b sha1 476C75CBC05431E692DEC8F4E10BCEE9D3F5431A flags verified ) ) game ( name "Bob the Builder - Fix it Fun! (Europe) (En,Sv,No,Da,Fi)" description "Bob the Builder - Fix it Fun! (Europe) (En,Sv,No,Da,Fi)" - rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Sv,No,Da,Fi).gbc" size 1048576 crc F319E823 md5 65DDB5E5DB1B3F932D44A28C802E63CC sha1 DF4993587CFF869C4824A5A771DB5C26A748C9EA ) + rom ( name "Bob the Builder - Fix it Fun! (Europe) (En,Sv,No,Da,Fi).gbc" size 1048576 crc f319e823 sha1 DF4993587CFF869C4824A5A771DB5C26A748C9EA flags verified ) ) game ( name "Bob the Builder - Fix it Fun! (USA)" description "Bob the Builder - Fix it Fun! (USA)" - rom ( name "Bob the Builder - Fix it Fun! (USA).gbc" size 1048576 crc 93FA37BD md5 215988E7A70CFBD0F45FE5C247EE0C55 sha1 68BD9A1932D4E5333AB5B4DFE0D28F126E5D470F ) + rom ( name "Bob the Builder - Fix it Fun! (USA).gbc" size 1048576 crc 93fa37bd sha1 68BD9A1932D4E5333AB5B4DFE0D28F126E5D470F ) ) game ( name "Boku no Camp-jou (Japan)" description "Boku no Camp-jou (Japan)" - rom ( name "Boku no Camp-jou (Japan).gbc" size 2097152 crc C87120B5 md5 29C545699436AB55EF3F801D9C4498B0 sha1 349509AF42DF8B8C5797838C5CDA4BBAE8643017 ) + rom ( name "Boku no Camp-jou (Japan).gbc" size 2097152 crc c87120b5 sha1 349509AF42DF8B8C5797838C5CDA4BBAE8643017 ) ) game ( - name "Bokujou Monogatari GB2 (Japan)" - description "Bokujou Monogatari GB2 (Japan)" - rom ( name "Bokujou Monogatari GB2 (Japan).gbc" size 2097152 crc EE993302 md5 245C759EFFDA3CF83E2CAF274C93C8AA sha1 D2AE9BC5709AA60DD5D433CD353DBB171DB2EF28 flags verified ) + name "Bokujou Monogatari 2 GB (Japan) (GB Compatible)" + description "Bokujou Monogatari 2 GB (Japan) (GB Compatible)" + rom ( name "Bokujou Monogatari 2 GB (Japan) (GB Compatible).gbc" size 2097152 crc ee993302 sha1 D2AE9BC5709AA60DD5D433CD353DBB171DB2EF28 flags verified ) ) game ( - name "Bokujou Monogatari GB3 - Boy Meets Girl (Japan)" - description "Bokujou Monogatari GB3 - Boy Meets Girl (Japan)" - rom ( name "Bokujou Monogatari GB3 - Boy Meets Girl (Japan).gbc" size 2097152 crc 3A18B41F md5 CF364669FE4197209FDE5D0C32713D53 sha1 E7FCEB85A78C78403711521FE5FC8F86260425D0 flags verified ) + name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan)" + description "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan)" + rom ( name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan).gbc" size 2097152 crc 3a18b41f sha1 E7FCEB85A78C78403711521FE5FC8F86260425D0 flags verified ) +) + +game ( + name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1)" + description "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1)" + rom ( name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1).gbc" size 2097152 crc 75af0e84 sha1 ACB2E549FB7D107D20507AF88C36F40234F74958 flags verified ) ) game ( name "Bomber Man Max - Ain Version (Japan)" description "Bomber Man Max - Ain Version (Japan)" - rom ( name "Bomber Man Max - Ain Version (Japan).gbc" size 2097152 crc 545E0DA2 md5 54C8522C1D924A05BB05AC6673F023E6 sha1 7416D9430A8163CD2F953C990EF8AD325725E53A ) + rom ( name "Bomber Man Max - Ain Version (Japan).gbc" size 2097152 crc 545e0da2 sha1 7416D9430A8163CD2F953C990EF8AD325725E53A ) ) game ( name "Bomber Man Max - Hikari no Yuusha (Japan)" description "Bomber Man Max - Hikari no Yuusha (Japan)" - rom ( name "Bomber Man Max - Hikari no Yuusha (Japan).gbc" size 2097152 crc 7A44CE88 md5 C720432FE26CEFBB5B177920CE20CD80 sha1 9C38166E83E45707CBC2E0AFF38FD4590DCE7C3F ) + rom ( name "Bomber Man Max - Hikari no Yuusha (Japan).gbc" size 2097152 crc 7a44ce88 sha1 9C38166E83E45707CBC2E0AFF38FD4590DCE7C3F ) ) game ( name "Bomber Man Max - Yami no Senshi (Japan)" description "Bomber Man Max - Yami no Senshi (Japan)" - rom ( name "Bomber Man Max - Yami no Senshi (Japan).gbc" size 2097152 crc 48B60E8E md5 76C04694DB94B72AFA78DD6612DFE4A9 sha1 12ADDFB8F890A44B87EFB900E9D6AD5028B58936 ) + rom ( name "Bomber Man Max - Yami no Senshi (Japan).gbc" size 2097152 crc 48b60e8e sha1 12ADDFB8F890A44B87EFB900E9D6AD5028B58936 ) ) game ( - name "Bomber Man Quest (Japan) (SGB Enhanced)" - description "Bomber Man Quest (Japan) (SGB Enhanced)" - rom ( name "Bomber Man Quest (Japan) (SGB Enhanced).gbc" size 1048576 crc 55210934 md5 632793107D6A279A2F38236955353906 sha1 B1187036734C40606CB1D5E35A6C120EE618E491 flags verified ) + name "Bomber Man Quest (Japan) (SGB Enhanced) (GB Compatible)" + description "Bomber Man Quest (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Bomber Man Quest (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 55210934 sha1 B1187036734C40606CB1D5E35A6C120EE618E491 flags verified ) ) game ( name "Bomberman Max - Blue Champion (USA)" description "Bomberman Max - Blue Champion (USA)" - rom ( name "Bomberman Max - Blue Champion (USA).gbc" size 2097152 crc 5CCB66CF md5 C987F711DFB9CBA8DC1174219877360F sha1 BB1120B0116EDA3FC157C66766BEFFCC7A04F826 flags verified ) + rom ( name "Bomberman Max - Blue Champion (USA).gbc" size 2097152 crc 5ccb66cf sha1 BB1120B0116EDA3FC157C66766BEFFCC7A04F826 flags verified ) ) game ( name "Bomberman Max - Red Challenger (USA)" description "Bomberman Max - Red Challenger (USA)" - rom ( name "Bomberman Max - Red Challenger (USA).gbc" size 2097152 crc 4853F586 md5 1757723CF346BE2CEA58D0FC4ED4CFA9 sha1 369CE985157C55BBAD6C24F49A0AD4009DEC5F56 flags verified ) + rom ( name "Bomberman Max - Red Challenger (USA).gbc" size 2097152 crc 4853f586 sha1 369CE985157C55BBAD6C24F49A0AD4009DEC5F56 flags verified ) ) game ( - name "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced)" - description "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 2097152 crc 5A9B9AE6 md5 E6F36322946499F2F55B724C3DB916CD sha1 088ACE0CFD6B3AA637B96C01106F6B1D88BA53FA flags verified ) + name "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Bomberman Quest (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 5a9b9ae6 sha1 088ACE0CFD6B3AA637B96C01106F6B1D88BA53FA flags verified ) ) game ( - name "Bomberman Quest (USA) (SGB Enhanced)" - description "Bomberman Quest (USA) (SGB Enhanced)" - rom ( name "Bomberman Quest (USA) (SGB Enhanced).gbc" size 1048576 crc A089C656 md5 AD358F284C3303DB01212016ED3944D5 sha1 4436F6EE03F7A8B2F235B64E26400C0E951D8A3A ) + name "Bomberman Quest (USA) (SGB Enhanced) (GB Compatible)" + description "Bomberman Quest (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Bomberman Quest (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc a089c656 sha1 4436F6EE03F7A8B2F235B64E26400C0E951D8A3A ) ) game ( name "Bomberman Selection (Korea)" description "Bomberman Selection (Korea)" - rom ( name "Bomberman Selection (Korea).gbc" size 1048576 crc AF2B426E md5 D0C6FFC3602D91C0B2B1B0461553DE33 sha1 52451464A9F4DD5FAEFE4594954CBCE03BFF0D05 flags verified ) + rom ( name "Bomberman Selection (Korea).gbc" size 1048576 crc af2b426e sha1 52451464A9F4DD5FAEFE4594954CBCE03BFF0D05 flags verified ) ) game ( name "Bouken! Dondoko-tou (Japan)" description "Bouken! Dondoko-tou (Japan)" - rom ( name "Bouken! Dondoko-tou (Japan).gbc" size 2097152 crc 5FE759C7 md5 889E643C52CA6916A4948F4D1B8B955B sha1 C054ABFEA01A3CEB7B20B27E7EA937ABE5157834 ) + rom ( name "Bouken! Dondoko-tou (Japan).gbc" size 2097152 crc 5fe759c7 sha1 C054ABFEA01A3CEB7B20B27E7EA937ABE5157834 ) ) game ( name "Brave Saga - Shinshou Astaria (Japan)" description "Brave Saga - Shinshou Astaria (Japan)" - rom ( name "Brave Saga - Shinshou Astaria (Japan).gbc" size 2097152 crc 5D5D294A md5 339D4C36FBA10397018040E0A4CD1F94 sha1 952B9E16A938B986A6216B8DB6D62F71C4F853FA ) + rom ( name "Brave Saga - Shinshou Astaria (Japan).gbc" size 2097152 crc 5d5d294a sha1 952B9E16A938B986A6216B8DB6D62F71C4F853FA flags verified ) ) game ( name "Buffy the Vampire Slayer (USA, Europe)" description "Buffy the Vampire Slayer (USA, Europe)" - rom ( name "Buffy the Vampire Slayer (USA, Europe).gbc" size 1048576 crc 5692E262 md5 49561C4082206A7E5D5CA2032BE81EED sha1 3310A9CFCAD457A6D4D31B63D8258313051C581E flags verified ) + rom ( name "Buffy the Vampire Slayer (USA, Europe).gbc" size 1048576 crc 5692e262 sha1 3310A9CFCAD457A6D4D31B63D8258313051C581E flags verified ) ) game ( - name "Bug's Life, A (Europe) (SGB Enhanced)" - description "Bug's Life, A (Europe) (SGB Enhanced)" - rom ( name "Bug's Life, A (Europe) (SGB Enhanced).gbc" size 1048576 crc DB93E0F6 md5 549B54077FD122943E076F4C2350BE05 sha1 DFC7B45C8F2D45CBF5C7578294CA569D2CF22DCD flags verified ) + name "Bug's Life, A (Europe) (SGB Enhanced) (GB Compatible)" + description "Bug's Life, A (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Bug's Life, A (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc db93e0f6 sha1 DFC7B45C8F2D45CBF5C7578294CA569D2CF22DCD ) ) game ( - name "Bug's Life, A (USA) (SGB Enhanced)" - description "Bug's Life, A (USA) (SGB Enhanced)" - rom ( name "Bug's Life, A (USA) (SGB Enhanced).gbc" size 1048576 crc 8360047A md5 64D2D5DF9D0E5035EF549A189FBDB475 sha1 4C689CE3B99A5B585A452B095D72A688391EA0EB ) + name "Bug's Life, A (USA) (SGB Enhanced) (GB Compatible)" + description "Bug's Life, A (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Bug's Life, A (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8360047a sha1 4C689CE3B99A5B585A452B095D72A688391EA0EB ) ) game ( - name "Bugs Bunny & Lola Bunny - Operation Carrots (Europe) (En,Fr,De,Es,It,Nl)" - description "Bugs Bunny & Lola Bunny - Operation Carrots (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Bugs Bunny & Lola Bunny - Operation Carrots (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc F0CC407F md5 D5A558F3F63771AC1E40D53976E090EF sha1 BA004FAC4524B82FD74A9037A37734D0ABA07E50 flags verified ) + name "Bugs Bunny & Lola Bunny - Operation Carrot Patch (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Bugs Bunny & Lola Bunny - Operation Carrot Patch (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Bugs Bunny & Lola Bunny - Operation Carrot Patch (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc f0cc407f sha1 BA004FAC4524B82FD74A9037A37734D0ABA07E50 flags verified ) ) game ( - name "Bugs Bunny - Crazy Castle 3 (Japan)" - description "Bugs Bunny - Crazy Castle 3 (Japan)" - rom ( name "Bugs Bunny - Crazy Castle 3 (Japan).gbc" size 1048576 crc AE839CAE md5 8D4E41EB71DDA41EF945512EB3B53FB3 sha1 403356D76A267D79FA5B72158DE4E280B970160B ) + name "Bugs Bunny - Crazy Castle 3 (Japan) (GB Compatible)" + description "Bugs Bunny - Crazy Castle 3 (Japan) (GB Compatible)" + rom ( name "Bugs Bunny - Crazy Castle 3 (Japan) (GB Compatible).gbc" size 1048576 crc ae839cae sha1 403356D76A267D79FA5B72158DE4E280B970160B ) ) game ( - name "Bugs Bunny - Crazy Castle 3 (USA, Europe)" - description "Bugs Bunny - Crazy Castle 3 (USA, Europe)" - rom ( name "Bugs Bunny - Crazy Castle 3 (USA, Europe).gbc" size 1048576 crc 7A2801FB md5 2EBF6F830013D8702EEBF93955DB52D5 sha1 F4AC94B7F59191F8D4ADC1B5B5AC39BEE5DFD064 flags verified ) + name "Bugs Bunny - Crazy Castle 3 (USA, Europe) (GB Compatible)" + description "Bugs Bunny - Crazy Castle 3 (USA, Europe) (GB Compatible)" + rom ( name "Bugs Bunny - Crazy Castle 3 (USA, Europe) (GB Compatible).gbc" size 1048576 crc 7a2801fb sha1 F4AC94B7F59191F8D4ADC1B5B5AC39BEE5DFD064 flags verified ) +) + +game ( + name "Bugs Bunny - Crazy Castle 4 (Japan)" + description "Bugs Bunny - Crazy Castle 4 (Japan)" + rom ( name "Bugs Bunny - Crazy Castle 4 (Japan).gbc" size 1048576 crc d6387eaa sha1 E4A198D4ACF5AC987071A1D2B91501CACA62269B ) ) game ( name "Bugs Bunny et le Chateau des Catastrophes (France)" description "Bugs Bunny et le Chateau des Catastrophes (France)" - serial "CGB-AO4F-FRA" - rom ( name "Bugs Bunny et le Chateau des Catastrophes (France).gbc" size 1048576 crc 6DA8E6EB md5 7FBBFA00A51547639750E69FF802FA76 sha1 19590017C888266C285360F824F5EF6CEA166287 ) + rom ( name "Bugs Bunny et le Chateau des Catastrophes (France).gbc" size 1048576 crc 6da8e6eb sha1 19590017C888266C285360F824F5EF6CEA166287 flags verified ) ) game ( - name "Bugs Bunny in Crazy Castle 4 (Europe)" - description "Bugs Bunny in Crazy Castle 4 (Europe)" - rom ( name "Bugs Bunny in Crazy Castle 4 (Europe).gbc" size 1048576 crc 53155E60 md5 C8FAFCBB7A673765ADE44B404B734A92 sha1 3654F532A77035B3FC5BF7B0E1AE6941FC649B6A flags verified ) + name "Bugs Bunny in - Crazy Castle 4 (Europe)" + description "Bugs Bunny in - Crazy Castle 4 (Europe)" + rom ( name "Bugs Bunny in - Crazy Castle 4 (Europe).gbc" size 1048576 crc 53155e60 sha1 3654F532A77035B3FC5BF7B0E1AE6941FC649B6A flags verified ) ) game ( - name "Bugs Bunny in Crazy Castle 4 (Japan)" - description "Bugs Bunny in Crazy Castle 4 (Japan)" - rom ( name "Bugs Bunny in Crazy Castle 4 (Japan).gbc" size 1048576 crc D6387EAA md5 30567B9D1CF0881FEE0E15CDFDC250DA sha1 E4A198D4ACF5AC987071A1D2B91501CACA62269B ) -) - -game ( - name "Bugs Bunny in Crazy Castle 4 (USA)" - description "Bugs Bunny in Crazy Castle 4 (USA)" - rom ( name "Bugs Bunny in Crazy Castle 4 (USA).gbc" size 1048576 crc 98DBFFE0 md5 0877A4B1765287C5B50EA53A47A1D7AD sha1 A22B9765E901B2A23A48C44B0B829AB73B9C1A82 ) + name "Bugs Bunny in - Crazy Castle 4 (USA)" + description "Bugs Bunny in - Crazy Castle 4 (USA)" + rom ( name "Bugs Bunny in - Crazy Castle 4 (USA).gbc" size 1048576 crc 98dbffe0 sha1 A22B9765E901B2A23A48C44B0B829AB73B9C1A82 ) ) game ( name "Bundesliga Stars 2001 (Germany)" description "Bundesliga Stars 2001 (Germany)" - rom ( name "Bundesliga Stars 2001 (Germany).gbc" size 1048576 crc 5622B551 md5 1CFA8223F124F56CCA9C8BC2C661A21D sha1 9803734C45FA54463F7E2B8CE3EEA3CA4D4EBDF4 flags verified ) + rom ( name "Bundesliga Stars 2001 (Germany).gbc" size 1048576 crc 5622b551 sha1 9803734C45FA54463F7E2B8CE3EEA3CA4D4EBDF4 flags verified ) ) game ( name "Burai Senshi Color (Japan)" description "Burai Senshi Color (Japan)" - rom ( name "Burai Senshi Color (Japan).gbc" size 1048576 crc E52FBD12 md5 7BBD65416CED257DA963FAA58536CF84 sha1 A3B140586AAC09F959260C5673DFED2ED58C1469 ) + rom ( name "Burai Senshi Color (Japan).gbc" size 1048576 crc e52fbd12 sha1 A3B140586AAC09F959260C5673DFED2ED58C1469 ) ) game ( - name "Burger Burger Pocket (Japan) (SGB Enhanced)" - description "Burger Burger Pocket (Japan) (SGB Enhanced)" - rom ( name "Burger Burger Pocket (Japan) (SGB Enhanced).gbc" size 1048576 crc 1ABCEDBE md5 A9A4D4DB13B2C35F0E260BF067087055 sha1 F4579D4BB3B39F572FDF033DF01A84A925FB3F2E ) + name "Burger Burger Pocket - Hamburger Simulation (Japan) (SGB Enhanced) (GB Compatible)" + description "Burger Burger Pocket - Hamburger Simulation (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Burger Burger Pocket - Hamburger Simulation (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1abcedbe sha1 F4579D4BB3B39F572FDF033DF01A84A925FB3F2E ) ) game ( name "Burger Paradise International (Japan)" description "Burger Paradise International (Japan)" - rom ( name "Burger Paradise International (Japan).gbc" size 1048576 crc 9092B0EB md5 A7A083BD154392A188DC8ED62C145EA4 sha1 71072A7F0165769649BCE8C31C36F67BB0E02963 ) + rom ( name "Burger Paradise International (Japan).gbc" size 1048576 crc 9092b0eb sha1 71072A7F0165769649BCE8C31C36F67BB0E02963 flags verified ) ) game ( - name "Bust-A-Move 4 (USA, Europe)" - description "Bust-A-Move 4 (USA, Europe)" - rom ( name "Bust-A-Move 4 (USA, Europe).gbc" size 524288 crc 8E818E6F md5 DC835FA5664AA83FF90DC2FF6CC83F24 sha1 DFB5C960336ECBE074B36FDCD8C7A8F1B194DF32 flags verified ) + name "Bust-A-Move 4 (USA, Europe) (GB Compatible)" + description "Bust-A-Move 4 (USA, Europe) (GB Compatible)" + rom ( name "Bust-A-Move 4 (USA, Europe) (GB Compatible).gbc" size 524288 crc 8e818e6f sha1 DFB5C960336ECBE074B36FDCD8C7A8F1B194DF32 flags verified ) ) game ( name "Bust-A-Move Millennium (USA, Europe)" description "Bust-A-Move Millennium (USA, Europe)" - rom ( name "Bust-A-Move Millennium (USA, Europe).gbc" size 1048576 crc F8DA0C4A md5 E98124B30408C00786068387353E39E5 sha1 2C14B4C82072F2A55F9F699956F71071481808EC flags verified ) + rom ( name "Bust-A-Move Millennium (USA, Europe).gbc" size 1048576 crc f8da0c4a sha1 2C14B4C82072F2A55F9F699956F71071481808EC flags verified ) ) game ( name "Buzz Lightyear of Star Command (USA, Europe)" description "Buzz Lightyear of Star Command (USA, Europe)" - rom ( name "Buzz Lightyear of Star Command (USA, Europe).gbc" size 524288 crc 84E29B87 md5 560E27A4D80B88280D8AD7358467C301 sha1 314DACD9A5D60769105F2CDE60A245074CB51C15 flags verified ) + rom ( name "Buzz Lightyear of Star Command (USA, Europe).gbc" size 524288 crc 84e29b87 sha1 314DACD9A5D60769105F2CDE60A245074CB51C15 flags verified ) ) game ( name "Caesars Palace II (USA, Europe)" description "Caesars Palace II (USA, Europe)" - rom ( name "Caesars Palace II (USA, Europe).gbc" size 1048576 crc 351BA5EA md5 64396458BB3A82F26F522E85291B5FC5 sha1 B7520B3C91813DF9A447C11CCC4D4381F106CA52 flags verified ) + rom ( name "Caesars Palace II (USA, Europe).gbc" size 1048576 crc 351ba5ea sha1 B7520B3C91813DF9A447C11CCC4D4381F106CA52 flags verified ) ) game ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It)" description "Cannon Fodder (Europe) (En,Fr,De,Es,It)" - rom ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 824C3BF3 md5 3DD6B4DD7DA7F2B412F92C2509B9F1DF sha1 9A6901CAD65E6D0CE89AF8442688FEC6A9FEDD43 ) + rom ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 824c3bf3 sha1 9A6901CAD65E6D0CE89AF8442688FEC6A9FEDD43 ) ) game ( name "Cannon Fodder (USA) (En,Fr,De,Es,It)" description "Cannon Fodder (USA) (En,Fr,De,Es,It)" - rom ( name "Cannon Fodder (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 26F8E1A0 md5 762D6C94874D8AC894AD100C0A4B50AB sha1 CC601984A2B52B44CF135E42BCAC1BEC44B7A6A3 ) + rom ( name "Cannon Fodder (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 26f8e1a0 sha1 CC601984A2B52B44CF135E42BCAC1BEC44B7A6A3 flags verified ) +) + +game ( + name "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" + description "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" + rom ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta).gbc" size 4194304 crc 222c9dc6 sha1 CEE465F6987C2D580CC96FAC703025989208E683 flags verified ) ) game ( name "Captain Buzz Lightyear - Star Command (Germany)" description "Captain Buzz Lightyear - Star Command (Germany)" - rom ( name "Captain Buzz Lightyear - Star Command (Germany).gbc" size 524288 crc F06D296C md5 542543461273C69E6966D2599F382ECA sha1 376BCD39491FE275A3773716FFAF0259E4852340 flags verified ) + rom ( name "Captain Buzz Lightyear - Star Command (Germany).gbc" size 524288 crc f06d296c sha1 376BCD39491FE275A3773716FFAF0259E4852340 flags verified ) ) game ( name "Card Sharks (USA) (Proto)" description "Card Sharks (USA) (Proto)" - rom ( name "Card Sharks (USA) (Proto).gbc" size 262144 crc E2B2DCFE md5 20BCF9A299D0F8DE3C36F01C16813162 sha1 F5E1850EFA9AC1DF8A879815D4193A1157408CA3 ) + rom ( name "Card Sharks (USA) (Proto).gbc" size 262144 crc e2b2dcfe sha1 F5E1850EFA9AC1DF8A879815D4193A1157408CA3 flags verified ) ) game ( - name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan)" - description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan)" - rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan).gbc" size 524288 crc 89BA58ED md5 049DA443C6BD96A0365CBC68B7D0E2EB sha1 8A11954329DCABE4BB39CB522505545A41DA5356 ) + name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (GB Compatible)" + description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (GB Compatible)" + rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (GB Compatible).gbc" size 524288 crc 89ba58ed sha1 8A11954329DCABE4BB39CB522505545A41DA5356 ) ) game ( - name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev A)" - description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev A)" - rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev A).gbc" size 524288 crc 43F28E22 md5 D054A2C3A5F203E9930D8C4B88CD6A33 sha1 B3926AC213B9F88F570B0587FAE89E3151018D63 ) + name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 1) (GB Compatible)" + description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 1) (GB Compatible)" + rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 1) (GB Compatible).gbc" size 524288 crc 43f28e22 sha1 B3926AC213B9F88F570B0587FAE89E3151018D63 flags verified ) ) game ( - name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev B)" - description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev B)" - rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev B).gbc" size 524288 crc 7243E258 md5 60F6FBDD07D01AD1835269FDEAEBB83D sha1 A53E7F8D95375AEA144E870977B0966CC1FD4B94 flags verified ) + name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 2) (GB Compatible)" + description "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 2) (GB Compatible)" + rom ( name "Cardcaptor Sakura - Itsumo Sakura-chan to Issho (Japan) (Rev 2) (GB Compatible).gbc" size 524288 crc 7243e258 sha1 A53E7F8D95375AEA144E870977B0966CC1FD4B94 flags verified ) ) game ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan)" description "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan)" - rom ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan).gbc" size 2097152 crc F78F7998 md5 3A998A2EC99C89696C9B23BBBD87F116 sha1 1809154979B289750B572A61DA1DC93B1B76360F ) + rom ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan).gbc" size 2097152 crc f78f7998 sha1 1809154979B289750B572A61DA1DC93B1B76360F ) ) game ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" description "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 15430979 md5 67F1A15025B979833F4C5AA0EF561954 sha1 76E898C00F47628710EAEF7551A7D1FE04E2A2BC flags verified ) + rom ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 15430979 sha1 76E898C00F47628710EAEF7551A7D1FE04E2A2BC flags verified ) +) + +game ( + name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + description "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl) (Beta)" + rom ( name "Carl Lewis Athletics 2000 (Europe) (En,Fr,De,Es,It,Nl) (Beta).gbc" size 1048576 crc da8d6283 sha1 0A94857F23640B36117B7BFE4CE7CC291DA63C58 ) ) game ( name "Carmageddon - Carpocalypse Now (Germany)" description "Carmageddon - Carpocalypse Now (Germany)" - rom ( name "Carmageddon - Carpocalypse Now (Germany).gbc" size 2097152 crc B447BC06 md5 4A58B26EF9624192AFE5542F790CDB01 sha1 505B29E070CE034B179169D834ABB3969E84C7E0 flags verified ) + rom ( name "Carmageddon - Carpocalypse Now (Germany).gbc" size 2097152 crc b447bc06 sha1 505B29E070CE034B179169D834ABB3969E84C7E0 flags verified ) ) game ( name "Carmageddon - Carpocalypse Now (USA, Europe) (En,Fr,Es,It)" description "Carmageddon - Carpocalypse Now (USA, Europe) (En,Fr,Es,It)" - rom ( name "Carmageddon - Carpocalypse Now (USA, Europe) (En,Fr,Es,It).gbc" size 2097152 crc BB482ED7 md5 F73C5CC4935EDE64F5B2D62754C90262 sha1 DF37636BBD57A426E23D21581376D7E3A87C7933 flags verified ) + rom ( name "Carmageddon - Carpocalypse Now (USA, Europe) (En,Fr,Es,It).gbc" size 2097152 crc bb482ed7 sha1 DF37636BBD57A426E23D21581376D7E3A87C7933 flags verified ) ) game ( name "Casper (Europe) (En,Es,It)" description "Casper (Europe) (En,Es,It)" - rom ( name "Casper (Europe) (En,Es,It).gbc" size 1048576 crc DAEFE53C md5 BA199806FD4F5AF5F76FD9C1515B299D sha1 1A964811C1D808403C4BAE1ADC7B7F78BF610399 ) + rom ( name "Casper (Europe) (En,Es,It).gbc" size 1048576 crc daefe53c sha1 1A964811C1D808403C4BAE1ADC7B7F78BF610399 flags verified ) ) game ( name "Casper (Europe) (En,Fr,De)" description "Casper (Europe) (En,Fr,De)" - rom ( name "Casper (Europe) (En,Fr,De).gbc" size 1048576 crc E6B9F155 md5 FDF70472390282FE62765A0838318E52 sha1 0A8560A35157DC5270309A7B4C0227E2F2A8C461 ) + rom ( name "Casper (Europe) (En,Fr,De).gbc" size 1048576 crc e6b9f155 sha1 0A8560A35157DC5270309A7B4C0227E2F2A8C461 ) ) game ( name "Casper (USA)" description "Casper (USA)" - rom ( name "Casper (USA).gbc" size 1048576 crc C775D653 md5 E99687D3558FD7FC4AF702EA1ABD9957 sha1 82AC50380C3ED39FAD13CC0BBE35E6457806A294 ) + rom ( name "Casper (USA).gbc" size 1048576 crc c775d653 sha1 82AC50380C3ED39FAD13CC0BBE35E6457806A294 ) ) game ( - name "Caterpillar Construction Zone (USA, Europe)" - description "Caterpillar Construction Zone (USA, Europe)" - rom ( name "Caterpillar Construction Zone (USA, Europe).gbc" size 1048576 crc D20DC670 md5 046AF13647ED4777510AA86FCB753BF9 sha1 0EC92EA836C729EFEBCD76282F90DFB579396AA6 flags verified ) + name "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" + description "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" + rom ( name "Caterpillar Construction Zone (USA, Europe) (GB Compatible).gbc" size 1048576 crc d20dc670 sha1 0EC92EA836C729EFEBCD76282F90DFB579396AA6 flags verified ) ) game ( name "Catwoman (Europe)" description "Catwoman (Europe)" - rom ( name "Catwoman (Europe).gbc" size 1048576 crc 41E78645 md5 482A7FE10C3E3D10127BBB08447A15CB sha1 E2446731ABEF2A3C78A0BFA5D2BBDA0084B7B3EA ) + rom ( name "Catwoman (Europe).gbc" size 1048576 crc 41e78645 sha1 E2446731ABEF2A3C78A0BFA5D2BBDA0084B7B3EA ) ) game ( name "Catwoman (USA)" description "Catwoman (USA)" - rom ( name "Catwoman (USA).gbc" size 1048576 crc 12F0C196 md5 2692494CEF091B908B02C9046BDD876C sha1 C6F364D15FE9C0982B6A03EE67FD463DC32E7ED0 ) + rom ( name "Catwoman (USA).gbc" size 1048576 crc 12f0c196 sha1 C6F364D15FE9C0982B6A03EE67FD463DC32E7ED0 ) ) game ( - name "Catz - Your Virtual Petz Palz (Europe)" - description "Catz - Your Virtual Petz Palz (Europe)" - rom ( name "Catz - Your Virtual Petz Palz (Europe).gbc" size 1048576 crc 099D6555 md5 349AEBF94C9AE3E1DCE9D2A01894BAE8 sha1 16B749D0C57C6D837364B3C55A353647304A55A0 ) + name "Catz (Europe)" + description "Catz (Europe)" + rom ( name "Catz (Europe).gbc" size 1048576 crc 099d6555 sha1 16B749D0C57C6D837364B3C55A353647304A55A0 ) ) game ( - name "Catz - Your Virtual Petz Palz (USA)" - description "Catz - Your Virtual Petz Palz (USA)" - rom ( name "Catz - Your Virtual Petz Palz (USA).gbc" size 1048576 crc 769A2C5A md5 695E4A82D1A97859365E3B5D5BA28E8C sha1 5C3C9A4D85A92779C7E8304F2C122296F62F9A9C ) + name "Catz (USA)" + description "Catz (USA)" + rom ( name "Catz (USA).gbc" size 1048576 crc 769a2c5a sha1 5C3C9A4D85A92779C7E8304F2C122296F62F9A9C ) ) game ( - name "Centipede (Europe) (En,Fr,De,Es,It,Nl)" - description "Centipede (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Centipede (Europe) (En,Fr,De,Es,It,Nl).gbc" size 524288 crc 255DB8BE md5 54F81E8D2232AF2503E0E03EEEEB39CE sha1 F8D2A8EAB2A8A76A51006D438849509837F008D3 flags verified ) + name "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 524288 crc 255db8be sha1 F8D2A8EAB2A8A76A51006D438849509837F008D3 flags verified ) ) game ( - name "Centipede (USA)" - description "Centipede (USA)" - rom ( name "Centipede (USA).gbc" size 1048576 crc 13AD07B1 md5 6815EC13F522FD65637BE46220371704 sha1 3E964FB53517C286B97375E6988208987F7BFA21 ) + name "Centipede (USA) (GB Compatible)" + description "Centipede (USA) (GB Compatible)" + rom ( name "Centipede (USA) (GB Compatible).gbc" size 1048576 crc 13ad07b1 sha1 3E964FB53517C286B97375E6988208987F7BFA21 ) ) game ( name "Championship Motocross 2001 featuring Ricky Carmichael (USA, Europe)" description "Championship Motocross 2001 featuring Ricky Carmichael (USA, Europe)" - rom ( name "Championship Motocross 2001 featuring Ricky Carmichael (USA, Europe).gbc" size 1048576 crc CBB336ED md5 63942B9B7FF673988FDBFBE8E1FDFC78 sha1 3712801102DF2B17D1DEB75FBE7FDA0C1A596DB0 flags verified ) + rom ( name "Championship Motocross 2001 featuring Ricky Carmichael (USA, Europe).gbc" size 1048576 crc cbb336ed sha1 3712801102DF2B17D1DEB75FBE7FDA0C1A596DB0 flags verified ) ) game ( - name "Chase H.Q. - Secret Police (Europe) (SGB Enhanced)" - description "Chase H.Q. - Secret Police (Europe) (SGB Enhanced)" - rom ( name "Chase H.Q. - Secret Police (Europe) (SGB Enhanced).gbc" size 1048576 crc CFDF816B md5 FC03E910EC8028A30F15FEEE2243D9CB sha1 E8770AEB76042FE5001DD48F55379350FA092A6F ) + name "Chase H.Q. - Secret Police (Europe) (SGB Enhanced) (GB Compatible)" + description "Chase H.Q. - Secret Police (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Chase H.Q. - Secret Police (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc cfdf816b sha1 E8770AEB76042FE5001DD48F55379350FA092A6F ) ) game ( - name "Chase H.Q. - Secret Police (USA) (SGB Enhanced)" - description "Chase H.Q. - Secret Police (USA) (SGB Enhanced)" - rom ( name "Chase H.Q. - Secret Police (USA) (SGB Enhanced).gbc" size 1048576 crc 7C7FDEFC md5 FF92E59C47A990815BC548E5E253C390 sha1 030B45EB8929C1512826F288E4BA035E0083505C ) + name "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible)" + description "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7c7fdefc sha1 030B45EB8929C1512826F288E4BA035E0083505C ) ) game ( - name "Checkmate (Japan) (En,Ja)" - description "Checkmate (Japan) (En,Ja)" - rom ( name "Checkmate (Japan) (En,Ja).gbc" size 1048576 crc 1AAB415D md5 628804DB7252B7BB5A51F6AAEA4B7077 sha1 84E6C93DAF1AB6C59BD23C0358A0704A663556B5 ) + name "Checkmate (Japan) (En,Ja) (GB Compatible)" + description "Checkmate (Japan) (En,Ja) (GB Compatible)" + rom ( name "Checkmate (Japan) (En,Ja) (GB Compatible).gbc" size 1048576 crc 1aab415d sha1 84E6C93DAF1AB6C59BD23C0358A0704A663556B5 ) ) game ( name "Chee-Chai Alien (Japan) (Rumble Version)" description "Chee-Chai Alien (Japan) (Rumble Version)" - rom ( name "Chee-Chai Alien (Japan) (Rumble Version).gbc" size 4194304 crc 9E988FFE md5 94F4306CB0C27686661E37A96EEF730B sha1 DEC72ED497EB207D0E0AF142C05FC813DAB04385 flags verified ) + rom ( name "Chee-Chai Alien (Japan) (Rumble Version).gbc" size 4194304 crc 9e988ffe sha1 DEC72ED497EB207D0E0AF142C05FC813DAB04385 flags verified ) ) game ( - name "Chessmaster (USA, Europe)" - description "Chessmaster (USA, Europe)" - rom ( name "Chessmaster (USA, Europe).gbc" size 1048576 crc 1C13DBB0 md5 F0AE420D6CE590BAAC5B2CA03F4B2BA6 sha1 84930FA75ECCC34A8E9FB6A0387791D437D1A442 flags verified ) + name "Chessmaster (USA, Europe) (GB Compatible)" + description "Chessmaster (USA, Europe) (GB Compatible)" + rom ( name "Chessmaster (USA, Europe) (GB Compatible).gbc" size 1048576 crc 1c13dbb0 sha1 84930FA75ECCC34A8E9FB6A0387791D437D1A442 flags verified ) ) game ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan)" description "Chi to Ase to Namida no Koukou Yakyuu (Japan)" - rom ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan).gbc" size 1048576 crc 3C39BCAB md5 8347EFB46014904144D40510D5C9FA05 sha1 172D7A7048851A2D0A0BE1F21A2A60176F038E01 ) + rom ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan).gbc" size 1048576 crc 3c39bcab sha1 172D7A7048851A2D0A0BE1F21A2A60176F038E01 ) ) game ( name "Chibi Maruko-chan - Go Chounai Minna de Game Da yo! (Japan)" description "Chibi Maruko-chan - Go Chounai Minna de Game Da yo! (Japan)" - rom ( name "Chibi Maruko-chan - Go Chounai Minna de Game Da yo! (Japan).gbc" size 1048576 crc 20FAA0D1 md5 E77BBFC1FFB3C846752410A371E098CE sha1 31A0E557B36382F260A8297226E14737217C9763 ) + rom ( name "Chibi Maruko-chan - Go Chounai Minna de Game Da yo! (Japan).gbc" size 1048576 crc 20faa0d1 sha1 31A0E557B36382F260A8297226E14737217C9763 ) ) game ( name "Chicken Run (USA, Europe) (En,Fr,De,Es,It)" description "Chicken Run (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Chicken Run (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc F8BD2A01 md5 BDA8C4E5E18070924261823E5FCA655C sha1 8DFD72E622C39ED8FD03046253474F38FB482C77 flags verified ) + rom ( name "Chicken Run (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc f8bd2a01 sha1 8DFD72E622C39ED8FD03046253474F38FB482C77 flags verified ) ) game ( name "Chiki Chiki Machine Mou Race (Japan)" description "Chiki Chiki Machine Mou Race (Japan)" - rom ( name "Chiki Chiki Machine Mou Race (Japan).gbc" size 1048576 crc 36C04BE0 md5 EFA5853DDAE4AB47301B2CA0416583A9 sha1 77CCF3A535E21E28D73059D3BFE42B58FEE17D2A ) + rom ( name "Chiki Chiki Machine Mou Race (Japan).gbc" size 1048576 crc 36c04be0 sha1 77CCF3A535E21E28D73059D3BFE42B58FEE17D2A flags verified ) ) game ( - name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced)" - description "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced)" - rom ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced).gbc" size 2097152 crc 65610CA4 md5 3611927BE3C7835C594120C4BFDD8D31 sha1 8AF215C632599AAAB9BC4614194AC45802407BBC flags verified ) + name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Choro Q - Hyper Customable GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 65610ca4 sha1 8AF215C632599AAAB9BC4614194AC45802407BBC flags verified ) ) game ( - name "Classic Bubble Bobble (Europe) (SGB Enhanced)" - description "Classic Bubble Bobble (Europe) (SGB Enhanced)" - rom ( name "Classic Bubble Bobble (Europe) (SGB Enhanced).gbc" size 1048576 crc A0F66D87 md5 83F1B6F79B8F0FECC4427EFC9FA7D732 sha1 3C52B09072077C210AF93E4B13C3EE0886676F83 ) + name "Classic Bubble Bobble (Europe) (SGB Enhanced) (GB Compatible)" + description "Classic Bubble Bobble (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Classic Bubble Bobble (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc a0f66d87 sha1 3C52B09072077C210AF93E4B13C3EE0886676F83 ) ) game ( - name "Classic Bubble Bobble (USA) (SGB Enhanced)" - description "Classic Bubble Bobble (USA) (SGB Enhanced)" - rom ( name "Classic Bubble Bobble (USA) (SGB Enhanced).gbc" size 1048576 crc C1B22246 md5 4BC8467ED91A94BA23648706B551CEF5 sha1 6E3739C0538467C220750F2E8D474433692BAC09 ) + name "Classic Bubble Bobble (USA) (SGB Enhanced) (GB Compatible)" + description "Classic Bubble Bobble (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Classic Bubble Bobble (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c1b22246 sha1 6E3739C0538467C220750F2E8D474433692BAC09 ) ) game ( name "Colin McRae Rally (Europe)" description "Colin McRae Rally (Europe)" - rom ( name "Colin McRae Rally (Europe).gbc" size 2097152 crc E93AF9C8 md5 8FBC58CE16CC0C571EB43A8038C97E83 sha1 0B824BA294248C185967BC813EBA1FAA26A320CC ) + rom ( name "Colin McRae Rally (Europe).gbc" size 2097152 crc e93af9c8 sha1 0B824BA294248C185967BC813EBA1FAA26A320CC ) ) game ( - name "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced)" - description "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced)" - rom ( name "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced).gbc" size 524288 crc FBE5DE37 md5 59DBF67358B671E2C8DCD9F89EBAF378 sha1 A8D9A6631F1D203D99BE38FB90135C10E5F0C880 ) + name "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced) (GB Compatible)" + description "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Columns GB - Tezuka Osamu Characters (Japan) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc fbe5de37 sha1 A8D9A6631F1D203D99BE38FB90135C10E5F0C880 ) ) game ( name "Command Master (Japan)" description "Command Master (Japan)" - rom ( name "Command Master (Japan).gbc" size 2097152 crc D10B5645 md5 4D3E8BF64B69EB56C5F1786CEF422C59 sha1 F1D3A1FF7A76C49CE3E094CA994D488DBDADF9A2 flags verified ) + rom ( name "Command Master (Japan).gbc" size 2097152 crc d10b5645 sha1 F1D3A1FF7A76C49CE3E094CA994D488DBDADF9A2 flags verified ) ) game ( name "Commander Keen (USA, Europe)" description "Commander Keen (USA, Europe)" - rom ( name "Commander Keen (USA, Europe).gbc" size 1048576 crc 4AF4CC9C md5 94D2AA3FBDA301F9C0D0C16E00743183 sha1 A00B7BDAAEDEB67AD7E7555139301C8B4C92EDEA flags verified ) + rom ( name "Commander Keen (USA, Europe).gbc" size 1048576 crc 4af4cc9c sha1 A00B7BDAAEDEB67AD7E7555139301C8B4C92EDEA flags verified ) ) game ( - name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced)" - description "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced).gbc" size 2097152 crc A50BE9A8 md5 FEE6336F969C9E72E9B78BE53D512C1E sha1 E9C3B1BB20EA74F363191EA9144009D1B13246BB flags verified ) + name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Conker's Pocket Tales (USA, Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc a50be9a8 sha1 E9C3B1BB20EA74F363191EA9144009D1B13246BB flags verified ) ) game ( name "Cool Bricks (Europe) (En,Fr,De,Es,It)" description "Cool Bricks (Europe) (En,Fr,De,Es,It)" - rom ( name "Cool Bricks (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 04FE7790 md5 5A7673F1E61CD707BDC880FF76396A3D sha1 0F0410E2EE2CE1A9E6B12399492F8BD2DDF67406 ) + rom ( name "Cool Bricks (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 04fe7790 sha1 0F0410E2EE2CE1A9E6B12399492F8BD2DDF67406 ) ) game ( - name "Cool Hand (Europe) (En,Fr,De)" - description "Cool Hand (Europe) (En,Fr,De)" - rom ( name "Cool Hand (Europe) (En,Fr,De).gbc" size 524288 crc E6C91FB8 md5 3355DC278915F314E263BA0A8E91C8F7 sha1 D116A77C501D5E553D1490993F8C0A9A92C3EA0C ) + name "Cool Hand (Europe) (En,Fr,De) (GB Compatible)" + description "Cool Hand (Europe) (En,Fr,De) (GB Compatible)" + rom ( name "Cool Hand (Europe) (En,Fr,De) (GB Compatible).gbc" size 524288 crc e6c91fb8 sha1 D116A77C501D5E553D1490993F8C0A9A92C3EA0C ) ) game ( name "Crazy Bikers (Europe)" description "Crazy Bikers (Europe)" - rom ( name "Crazy Bikers (Europe).gbc" size 1048576 crc 53E02B87 md5 D6311339384CB70C35975C8D30A1CD98 sha1 C625608B5165E971827AF8434E72D8CA8D200AB8 ) + rom ( name "Crazy Bikers (Europe).gbc" size 1048576 crc 53e02b87 sha1 C625608B5165E971827AF8434E72D8CA8D200AB8 ) ) game ( name "Croc (USA, Europe)" description "Croc (USA, Europe)" - rom ( name "Croc (USA, Europe).gbc" size 1048576 crc 4664A167 md5 0552078F981C2EF3977F2DFEEE19510A sha1 DAC6DE548743C6B51A3DAA5903C28B7FCCDB6CB2 flags verified ) + rom ( name "Croc (USA, Europe).gbc" size 1048576 crc 4664a167 sha1 DAC6DE548743C6B51A3DAA5903C28B7FCCDB6CB2 flags verified ) ) game ( name "Croc 2 (USA, Europe)" description "Croc 2 (USA, Europe)" - rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc C1D60129 md5 03A8BCAB4B2975FA2D850D18C728EA9C sha1 FA29D6C4239405B12B320BB6E8A65CA2083A4B1C flags verified ) + rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc c1d60129 sha1 FA29D6C4239405B12B320BB6E8A65CA2083A4B1C flags verified ) ) game ( - name "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced)" - description "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 1048576 crc B7B91FE9 md5 B4DA49116EAF8E63D5DD912BC8DA33F4 sha1 67BCAC922B14A6FDE311CA693F297248CEEBBEA6 ) + name "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Cross Country Racing (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b7b91fe9 sha1 67BCAC922B14A6FDE311CA693F297248CEEBBEA6 ) ) game ( name "Cross Hunter - Monster Hunter Version (Japan)" description "Cross Hunter - Monster Hunter Version (Japan)" - rom ( name "Cross Hunter - Monster Hunter Version (Japan).gbc" size 4194304 crc 48E1BA7D md5 986BCB950DF452ADE78FFF94A83C56F3 sha1 15383FDBA1BCA2C11ED00DC271B4A6F69D500F75 ) + rom ( name "Cross Hunter - Monster Hunter Version (Japan).gbc" size 4194304 crc 48e1ba7d sha1 15383FDBA1BCA2C11ED00DC271B4A6F69D500F75 ) ) game ( name "Cross Hunter - Treasure Hunter Version (Japan)" description "Cross Hunter - Treasure Hunter Version (Japan)" - rom ( name "Cross Hunter - Treasure Hunter Version (Japan).gbc" size 4194304 crc 623C1516 md5 D31BAD86D4C8397C85ECF1C8338AFE66 sha1 B54FCDEBD54484113923B899EED7C63550609F74 ) + rom ( name "Cross Hunter - Treasure Hunter Version (Japan).gbc" size 4194304 crc 623c1516 sha1 B54FCDEBD54484113923B899EED7C63550609F74 ) ) game ( name "Cross Hunter - X Hunter Version (Japan)" description "Cross Hunter - X Hunter Version (Japan)" - rom ( name "Cross Hunter - X Hunter Version (Japan).gbc" size 4194304 crc 858010E0 md5 6CF89F96AF36735E4F26247F93767AFE sha1 2C9D8994635957F1080D785F47A596E02880BE6C ) + rom ( name "Cross Hunter - X Hunter Version (Japan).gbc" size 4194304 crc 858010e0 sha1 2C9D8994635957F1080D785F47A596E02880BE6C ) ) game ( name "Cruis'n Exotica (USA)" description "Cruis'n Exotica (USA)" - rom ( name "Cruis'n Exotica (USA).gbc" size 2097152 crc 9562E7E8 md5 3AF0CF37EADD6E98FDC43D4B3967C966 sha1 E3F7BAB776D76048A6CF1745FB4D8ECAF2D44F46 ) + rom ( name "Cruis'n Exotica (USA).gbc" size 2097152 crc 9562e7e8 sha1 E3F7BAB776D76048A6CF1745FB4D8ECAF2D44F46 ) ) game ( name "Crystalis (USA)" description "Crystalis (USA)" - rom ( name "Crystalis (USA).gbc" size 2097152 crc 909BB02D md5 F36A0ED25A601C039B1171D9DAF241D6 sha1 85D9CFAAE2AE4995D834CC9B95EC3126707A6332 flags verified ) + rom ( name "Crystalis (USA).gbc" size 2097152 crc 909bb02d sha1 85D9CFAAE2AE4995D834CC9B95EC3126707A6332 flags verified ) ) game ( name "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It)" description "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It)" - rom ( name "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 9F883B0F md5 9EB8BE5600D2408352BF9EF32B91D1DF sha1 D62B85C664E0A42C84E56B939A201FE90D05A360 ) + rom ( name "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 9f883b0f sha1 D62B85C664E0A42C84E56B939A201FE90D05A360 ) ) game ( name "CyberTiger (USA, Europe)" description "CyberTiger (USA, Europe)" - rom ( name "CyberTiger (USA, Europe).gbc" size 1048576 crc E470CAFA md5 7A36423EC39604D7043336AF71145010 sha1 3EB14447BD2A349BE16EB6E51066C65A51B35E69 flags verified ) + rom ( name "CyberTiger (USA, Europe).gbc" size 1048576 crc e470cafa sha1 3EB14447BD2A349BE16EB6E51066C65A51B35E69 flags verified ) ) game ( name "Cyborg Kuro-chan - Devil Fukkatsu (Japan)" description "Cyborg Kuro-chan - Devil Fukkatsu (Japan)" - rom ( name "Cyborg Kuro-chan - Devil Fukkatsu (Japan).gbc" size 1048576 crc 392D630F md5 2082A3C919F07C076AA7DE6363544536 sha1 B544D1A49128BC5AB3664CED872D2D1DCC51B667 flags verified ) + rom ( name "Cyborg Kuro-chan - Devil Fukkatsu (Japan).gbc" size 1048576 crc 392d630f sha1 B544D1A49128BC5AB3664CED872D2D1DCC51B667 flags verified ) ) game ( name "Cyborg Kuro-chan 2 - White Woods no Gyakushuu (Japan)" description "Cyborg Kuro-chan 2 - White Woods no Gyakushuu (Japan)" - rom ( name "Cyborg Kuro-chan 2 - White Woods no Gyakushuu (Japan).gbc" size 1048576 crc E86BF12E md5 3C6C0BF27C82EEA13DFC9697E0CACF57 sha1 8CE6261DE9DC2AE1A02A2AC00FA45B855FAE34A2 flags verified ) + rom ( name "Cyborg Kuro-chan 2 - White Woods no Gyakushuu (Japan).gbc" size 1048576 crc e86bf12e sha1 8CE6261DE9DC2AE1A02A2AC00FA45B855FAE34A2 flags verified ) ) game ( name "Daa! Daa! Daa! - Totsuzen Card de Battle de Uranai de! (Japan)" description "Daa! Daa! Daa! - Totsuzen Card de Battle de Uranai de! (Japan)" - rom ( name "Daa! Daa! Daa! - Totsuzen Card de Battle de Uranai de! (Japan).gbc" size 1048576 crc F41BB392 md5 B250EE7CE8D2EAAE25379723E054516C sha1 B716720F25EC84FA51181125494A009345D0B20F ) + rom ( name "Daa! Daa! Daa! - Totsuzen Card de Battle de Uranai de! (Japan).gbc" size 1048576 crc f41bb392 sha1 B716720F25EC84FA51181125494A009345D0B20F flags verified ) ) game ( - name "Daffy Duck - Fowl Play (USA, Europe)" - description "Daffy Duck - Fowl Play (USA, Europe)" - rom ( name "Daffy Duck - Fowl Play (USA, Europe).gbc" size 1048576 crc 45EBF09C md5 882A7B4D2CADEDD7ED2E21D22CA8F93D sha1 5D9373D934DC3C672FF426960D565D8CF635925B flags verified ) + name "Daffy Duck - Fowl Play (USA, Europe) (GB Compatible)" + description "Daffy Duck - Fowl Play (USA, Europe) (GB Compatible)" + rom ( name "Daffy Duck - Fowl Play (USA, Europe) (GB Compatible).gbc" size 1048576 crc 45ebf09c sha1 5D9373D934DC3C672FF426960D565D8CF635925B flags verified ) ) game ( - name "Daffy Duck - Subette Koron de Taikin Mochi (Japan)" - description "Daffy Duck - Subette Koron de Taikin Mochi (Japan)" - rom ( name "Daffy Duck - Subette Koron de Taikin Mochi (Japan).gbc" size 1048576 crc 5B4507D9 md5 AA0CCC0C4D2472B5FB657ABA003EFB81 sha1 5578B7973A65EEA2F09C6150B9154377D237DA75 ) + name "Daffy Duck - Subette Koron de Oogane Mochi (Japan) (GB Compatible)" + description "Daffy Duck - Subette Koron de Oogane Mochi (Japan) (GB Compatible)" + rom ( name "Daffy Duck - Subette Koron de Oogane Mochi (Japan) (GB Compatible).gbc" size 1048576 crc 5b4507d9 sha1 5578B7973A65EEA2F09C6150B9154377D237DA75 ) ) game ( - name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced)" - description "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced)" - rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced).gbc" size 2097152 crc 2F368DA6 md5 57A7D3D3E7D67EC7D72DE5701D9227D8 sha1 0854B7EA4791A460C75CE9096583934B1AF053E8 flags verified ) + name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible)" + description "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 2f368da6 sha1 0854B7EA4791A460C75CE9096583934B1AF053E8 flags verified ) ) game ( name "Daikaijuu Monogatari - Poyon no Dungeon Room 2 (Japan)" description "Daikaijuu Monogatari - Poyon no Dungeon Room 2 (Japan)" - rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room 2 (Japan).gbc" size 2097152 crc 5E312730 md5 78959C37152E546C5C7C271AE418A453 sha1 E9BC47EFD971F2CAF9EBE9B4D85516D3813D8247 ) + rom ( name "Daikaijuu Monogatari - Poyon no Dungeon Room 2 (Japan).gbc" size 2097152 crc 5e312730 sha1 E9BC47EFD971F2CAF9EBE9B4D85516D3813D8247 flags verified ) ) game ( - name "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced)" - description "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced)" - rom ( name "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced).gbc" size 1048576 crc 692D6794 md5 FF0001C209FC894C26B339A1519F38A6 sha1 7BF6E2D7FC58E8ABE61785E413BCF4150FA8BEE5 flags verified ) + name "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced) (GB Compatible)" + description "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Daikaijuu Monogatari - The Miracle of the Zone II (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 692d6794 sha1 7BF6E2D7FC58E8ABE61785E413BCF4150FA8BEE5 flags verified ) ) game ( - name "Daikatana (Europe) (En,Fr,It)" - description "Daikatana (Europe) (En,Fr,It)" - rom ( name "Daikatana (Europe) (En,Fr,It).gbc" size 1048576 crc D9062E49 md5 D1934B308085C92B2EE492FAA0D159C2 sha1 A5C5B52247B2AB78CD9CAD19AA752E07C3DF86EF ) -) - -game ( - name "Daikatana (Europe) (Fr,De,Es)" - description "Daikatana (Europe) (Fr,De,Es)" - rom ( name "Daikatana (Europe) (Fr,De,Es).gbc" size 1048576 crc F7E83313 md5 037034765C049438B82B30BC1A551165 sha1 B699FC3BC587E5DF25235A6C7F74FEC307F476FE ) + name "Daikatana (USA) (Proto) (2000-04-19)" + description "Daikatana (USA) (Proto) (2000-04-19)" + rom ( name "Daikatana (USA) (Proto) (2000-04-19).gbc" size 4194304 crc 351862bb sha1 361D05119AA6671415A8C583150DBFA4DFD93E5E flags verified ) ) game ( name "Daikatana GB (Japan) (NP)" description "Daikatana GB (Japan) (NP)" - rom ( name "Daikatana GB (Japan) (NP).gbc" size 1048576 crc 2BB01AAD md5 5F5535BF79444EC15502DB9C81E58CED sha1 268AEF9FA88A4921BDC10C1828CD88B49D65635E ) + rom ( name "Daikatana GB (Japan) (NP).gbc" size 1048576 crc 2bb01aad sha1 268AEF9FA88A4921BDC10C1828CD88B49D65635E ) ) game ( - name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced)" - description "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced)" - rom ( name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced).gbc" size 1048576 crc E2071293 md5 7455EA4FB9BC8AC752B4E43FD6864B7F sha1 2D961353E7242BABCE49DDA8D017A459F4EF7609 ) + name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced) (GB Compatible)" + description "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Daiku no Gen-san - Kachikachi no Tonkachi ga Kachi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e2071293 sha1 2D961353E7242BABCE49DDA8D017A459F4EF7609 ) ) game ( name "Dance Dance Revolution GB (Japan)" description "Dance Dance Revolution GB (Japan)" - rom ( name "Dance Dance Revolution GB (Japan).gbc" size 2097152 crc C64FF2B6 md5 C7CF1E919682B3EE613DD155CC12A15A sha1 5BE4CC1A810B48B843B60B5B37B2012A47E5742B ) + rom ( name "Dance Dance Revolution GB (Japan).gbc" size 2097152 crc c64ff2b6 sha1 5BE4CC1A810B48B843B60B5B37B2012A47E5742B ) ) game ( name "Dance Dance Revolution GB - Disney Mix (Japan)" description "Dance Dance Revolution GB - Disney Mix (Japan)" - rom ( name "Dance Dance Revolution GB - Disney Mix (Japan).gbc" size 2097152 crc B31A59BF md5 DBADA1FDFABA283BEDE36852843F5ED8 sha1 91C653D792DDAADF6CAB9F6B1D62D4194CD23C1A ) + rom ( name "Dance Dance Revolution GB - Disney Mix (Japan).gbc" size 2097152 crc b31a59bf sha1 91C653D792DDAADF6CAB9F6B1D62D4194CD23C1A ) ) game ( - name "Dance Dance Revolution GB2 (Japan)" - description "Dance Dance Revolution GB2 (Japan)" - rom ( name "Dance Dance Revolution GB2 (Japan).gbc" size 2097152 crc 565FEC36 md5 7F306F573CA9759FA2F7AA167CA2DD74 sha1 D44E2905B9436BE7B278BC30816023375A677EA1 ) + name "Dance Dance Revolution GB 2 (Japan)" + description "Dance Dance Revolution GB 2 (Japan)" + rom ( name "Dance Dance Revolution GB 2 (Japan).gbc" size 2097152 crc 565fec36 sha1 D44E2905B9436BE7B278BC30816023375A677EA1 ) ) game ( - name "Dance Dance Revolution GB3 (Japan)" - description "Dance Dance Revolution GB3 (Japan)" - rom ( name "Dance Dance Revolution GB3 (Japan).gbc" size 2097152 crc 58F26F36 md5 3CED79AD60AB5195058D5D658550F04F sha1 E23A69AD358623BE715908860E8E6BF04020552C ) + name "Dance Dance Revolution GB 3 (Japan)" + description "Dance Dance Revolution GB 3 (Japan)" + rom ( name "Dance Dance Revolution GB 3 (Japan).gbc" size 2097152 crc 58f26f36 sha1 E23A69AD358623BE715908860E8E6BF04020552C ) ) game ( - name "Dancing Furby (Japan)" - description "Dancing Furby (Japan)" - rom ( name "Dancing Furby (Japan).gbc" size 1048576 crc 3263F692 md5 ED517A9923865F4E4945CA4095313FE2 sha1 F3F7E37D64EEF74D65456BAE490E0A0B25897AC0 ) + name "Dancing Furby (Japan) (GB Compatible)" + description "Dancing Furby (Japan) (GB Compatible)" + rom ( name "Dancing Furby (Japan) (GB Compatible).gbc" size 1048576 crc 3263f692 sha1 F3F7E37D64EEF74D65456BAE490E0A0B25897AC0 flags verified ) ) game ( name "Data-Navi Pro Yakyuu (Japan)" description "Data-Navi Pro Yakyuu (Japan)" - rom ( name "Data-Navi Pro Yakyuu (Japan).gbc" size 1048576 crc C958AD75 md5 3DBEFE8C7CA45427696016902C2EE452 sha1 408FDA7442F00A315E6B1F39963B00BC4264A142 ) + rom ( name "Data-Navi Pro Yakyuu (Japan).gbc" size 1048576 crc c958ad75 sha1 408FDA7442F00A315E6B1F39963B00BC4264A142 ) ) game ( name "Data-Navi Pro Yakyuu 2 (Japan)" description "Data-Navi Pro Yakyuu 2 (Japan)" - rom ( name "Data-Navi Pro Yakyuu 2 (Japan).gbc" size 1048576 crc 96071AD0 md5 1F669FBC8F7DD8FEE1AFEE6052A807D4 sha1 F59CF8BA729F6992D348F6BB14D24695E357F492 ) + rom ( name "Data-Navi Pro Yakyuu 2 (Japan).gbc" size 1048576 crc 96071ad0 sha1 F59CF8BA729F6992D348F6BB14D24695E357F492 ) ) game ( name "Dave Mirra Freestyle BMX (USA, Europe)" description "Dave Mirra Freestyle BMX (USA, Europe)" - rom ( name "Dave Mirra Freestyle BMX (USA, Europe).gbc" size 1048576 crc 2DF6E230 md5 1E062837D15D5E4E43BB2253207115AE sha1 7D03BBC95A6D0E67186AB110266E8EEB0066D16B flags verified ) + rom ( name "Dave Mirra Freestyle BMX (USA, Europe).gbc" size 1048576 crc 2df6e230 sha1 7D03BBC95A6D0E67186AB110266E8EEB0066D16B flags verified ) ) game ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It)" description "David Beckham Soccer (Europe) (En,Fr,De,Es,It)" - rom ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 753BDCE4 md5 745821122E423C09308AB2A97D645E20 sha1 01567D19FCBFEEAE38DF505EC689998936351380 ) + rom ( name "David Beckham Soccer (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 753bdce4 sha1 01567D19FCBFEEAE38DF505EC689998936351380 ) +) + +game ( + name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" + description "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "David O'Leary's Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c25ee35a sha1 BE0703EE2667DDC53CFF9D6C7D22B30D272C0738 flags verified ) ) game ( name "Deadly Skies (Europe) (En,Fr,De)" description "Deadly Skies (Europe) (En,Fr,De)" - rom ( name "Deadly Skies (Europe) (En,Fr,De).gbc" size 1048576 crc 402DE378 md5 8E7298D92BD4EAEC572A7F1BCB223200 sha1 AA9118DA41E7D29385352F29593AED8C016329D1 flags verified ) + rom ( name "Deadly Skies (Europe) (En,Fr,De).gbc" size 1048576 crc 402de378 sha1 AA9118DA41E7D29385352F29593AED8C016329D1 flags verified ) ) game ( - name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced)" - description "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced)" - rom ( name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced).gbc" size 1048576 crc 0FD34427 md5 793C57F58D4E9C92088C333B129D1C7E sha1 8598594285F0342B3D93C447B475FADD4722C6CB flags verified ) + name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced) (GB Compatible)" + description "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0fd34427 sha1 8598594285F0342B3D93C447B475FADD4722C6CB flags verified ) ) game ( name "Deer Hunter (USA)" description "Deer Hunter (USA)" - rom ( name "Deer Hunter (USA).gbc" size 1048576 crc 40A715FB md5 11D3CA80AD24431BABBEC7A675D83BED sha1 87A012E82F2361760AE337B30E9D41EF2245419A ) + rom ( name "Deer Hunter (USA).gbc" size 1048576 crc 40a715fb sha1 87A012E82F2361760AE337B30E9D41EF2245419A ) +) + +game ( + name "Deja Vu I & II (Japan)" + description "Deja Vu I & II (Japan)" + rom ( name "Deja Vu I & II (Japan).gbc" size 1048576 crc baf2cc96 sha1 4F3AF0A47DE674531C0FEDE3783F8C6CC7F31CCA ) ) game ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (En,Fr)" description "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (En,Fr)" - rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (En,Fr).gbc" size 1048576 crc 71F798B5 md5 E51C03FC9ED1A31A9E2BE404F9E01068 sha1 10C2ED4098A07979426D359DA57A5289C6BC73FE ) + rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (En,Fr).gbc" size 1048576 crc 71f798b5 sha1 10C2ED4098A07979426D359DA57A5289C6BC73FE ) ) game ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (Fr,De)" description "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (Fr,De)" - rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (Fr,De).gbc" size 1048576 crc C6E7F3C6 md5 497E32BEEFACE0C5DAC4BFE84A5964B6 sha1 ED1A11E2A02FC11D6B58DEDF65CE57EEB430E6E3 ) -) - -game ( - name "Deja Vu I & II - The Casebooks of Ace Harding (Japan)" - description "Deja Vu I & II - The Casebooks of Ace Harding (Japan)" - rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (Japan).gbc" size 1048576 crc BAF2CC96 md5 07876BD62ABBE5FD8878A0363E23A42F sha1 4F3AF0A47DE674531C0FEDE3783F8C6CC7F31CCA ) + rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (Europe) (Fr,De).gbc" size 1048576 crc c6e7f3c6 sha1 ED1A11E2A02FC11D6B58DEDF65CE57EEB430E6E3 ) ) game ( name "Deja Vu I & II - The Casebooks of Ace Harding (USA)" description "Deja Vu I & II - The Casebooks of Ace Harding (USA)" - rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (USA).gbc" size 1048576 crc AD0937F4 md5 D63504EA68F55D3C290CD01D71D4D1CC sha1 63266FC1F0A14678D5CD5DD1C5E3658EF4A944C3 ) + rom ( name "Deja Vu I & II - The Casebooks of Ace Harding (USA).gbc" size 1048576 crc ad0937f4 sha1 63266FC1F0A14678D5CD5DD1C5E3658EF4A944C3 ) ) game ( name "Dejiko no Mahjong Party (Japan)" description "Dejiko no Mahjong Party (Japan)" - rom ( name "Dejiko no Mahjong Party (Japan).gbc" size 2097152 crc C5501FCE md5 314FDDCEC1489EFE4A4F959D353EE4DB sha1 D9DD4196A85BCEEE6E77A317A357E9E0B14D26EB ) + rom ( name "Dejiko no Mahjong Party (Japan).gbc" size 2097152 crc c5501fce sha1 D9DD4196A85BCEEE6E77A317A357E9E0B14D26EB flags verified ) ) game ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It)" description "Denki Blocks! (Europe) (En,Fr,De,Es,It)" - rom ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 38F00974 md5 E4594F3D22FCE6B71642A9F3049A6054 sha1 CF4037DB23525937E6DCEEA7343A9EA7A22F928D flags verified ) + rom ( name "Denki Blocks! (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 38f00974 sha1 CF4037DB23525937E6DCEEA7343A9EA7A22F928D flags verified ) ) game ( name "Densha de Go! (Japan)" description "Densha de Go! (Japan)" - rom ( name "Densha de Go! (Japan).gbc" size 4194304 crc 14375072 md5 0E63965664DF3BF3217254A22422CC86 sha1 9661A5CFA2DC4FEDBCA1F15B69CF81A3FC7FC097 ) + rom ( name "Densha de Go! (Japan).gbc" size 4194304 crc 14375072 sha1 9661A5CFA2DC4FEDBCA1F15B69CF81A3FC7FC097 ) ) game ( name "Densha de Go! 2 (Japan)" description "Densha de Go! 2 (Japan)" - rom ( name "Densha de Go! 2 (Japan).gbc" size 8388608 crc B72603FC md5 AB58102005B510A2D905ED7DE9D6267A sha1 63BCCA7177712A9BC6F032C83C2E129D9B9AF0FA flags verified ) + rom ( name "Densha de Go! 2 (Japan).gbc" size 8388608 crc b72603fc sha1 63BCCA7177712A9BC6F032C83C2E129D9B9AF0FA flags verified ) ) game ( name "Dexter's Laboratory - Robot Rampage (USA, Europe)" description "Dexter's Laboratory - Robot Rampage (USA, Europe)" - rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc D24D6601 md5 2A147B2D7731AC26A999390C3F5FF2AC sha1 DB107AF55DF07FB8C771C712B05D6AEBB175E3C5 flags verified ) + rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc d24d6601 sha1 DB107AF55DF07FB8C771C712B05D6AEBB175E3C5 flags verified ) ) game ( - name "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced)" - description "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced)" - rom ( name "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced).gbc" size 2097152 crc D9F071BB md5 ACB10288F383C6B475E11E936AA56C70 sha1 F571A591A2F4FC4F70897E380FDBE9011BE75F8D flags verified ) + name "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced) (GB Compatible)" + description "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dino Breeder 3 - Gaia Fukkatsu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d9f071bb sha1 F571A591A2F4FC4F70897E380FDBE9011BE75F8D flags verified ) ) game ( - name "Dino Breeder 4 (Japan) (SGB Enhanced)" - description "Dino Breeder 4 (Japan) (SGB Enhanced)" - rom ( name "Dino Breeder 4 (Japan) (SGB Enhanced).gbc" size 2097152 crc B0106777 md5 4563D42DB3B0C9F2E14C1CAD7725BB34 sha1 B25681DEFDA961837A28BE1432076B65574FD1BE flags verified ) + name "Dino Breeder 4 (Japan) (SGB Enhanced) (GB Compatible)" + description "Dino Breeder 4 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dino Breeder 4 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b0106777 sha1 B25681DEFDA961837A28BE1432076B65574FD1BE flags verified ) ) game ( name "Dinosaur (Europe) (En,Fr,De,Es,It)" description "Dinosaur (Europe) (En,Fr,De,Es,It)" - rom ( name "Dinosaur (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 0AA8D0CC md5 6D0D0D7DE2730B9F9FDEEB4E202D5115 sha1 9123D3528BF295C5CBA4284CA276AF23A32EC725 flags verified ) + rom ( name "Dinosaur (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 0aa8d0cc sha1 9123D3528BF295C5CBA4284CA276AF23A32EC725 flags verified ) ) game ( name "Dinosaur (USA)" description "Dinosaur (USA)" - rom ( name "Dinosaur (USA).gbc" size 2097152 crc 276ECAAE md5 DDECBA0A4E0D1373FAD858316FAF6F33 sha1 F566C37AB95537D88F6D1AB91804F47F7C0B4027 ) + rom ( name "Dinosaur (USA).gbc" size 2097152 crc 276ecaae sha1 F566C37AB95537D88F6D1AB91804F47F7C0B4027 ) ) game ( name "Dinosaur (USA) (Beta)" description "Dinosaur (USA) (Beta)" - rom ( name "Dinosaur (USA) (Beta).gbc" size 2097152 crc 0B087FE7 md5 D0C1449229A8208D0E6753FA05685DF3 sha1 E8042138B56777733E8E9E397EA084CF61383CD9 ) + rom ( name "Dinosaur (USA) (Beta).gbc" size 2097152 crc 0b087fe7 sha1 E8042138B56777733E8E9E397EA084CF61383CD9 ) ) game ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl)" description "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc F4609FE3 md5 B077F0ACBB5D2CA07A2D9C035856E01E sha1 D0CAF4B5172651AEE2BBE38EFDAE084CE3D7A7FF ) + rom ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f4609fe3 sha1 D0CAF4B5172651AEE2BBE38EFDAE084CE3D7A7FF ) ) game ( name "Diva Starz (Europe)" description "Diva Starz (Europe)" - rom ( name "Diva Starz (Europe).gbc" size 1048576 crc 4476E79F md5 3ED4D88927E2EA0D4F75826F1B60D4A1 sha1 9AE754470A116555373A47EAE0FE611160219925 ) + rom ( name "Diva Starz (Europe).gbc" size 1048576 crc 4476e79f sha1 9AE754470A116555373A47EAE0FE611160219925 flags verified ) ) game ( name "Diva Starz (France)" description "Diva Starz (France)" - rom ( name "Diva Starz (France).gbc" size 1048576 crc FC1B36D1 md5 6BD1DEA9AF1ED4356C23043CB8AF91AE sha1 FCBFBEF077FEEC07F93B867DE5B537F45812D5A4 ) + rom ( name "Diva Starz (France).gbc" size 1048576 crc fc1b36d1 sha1 FCBFBEF077FEEC07F93B867DE5B537F45812D5A4 flags verified ) ) game ( name "Diva Starz (Germany)" description "Diva Starz (Germany)" - rom ( name "Diva Starz (Germany).gbc" size 1048576 crc 56095F86 md5 F012B129CEBD445C8B63F4DDC475BB26 sha1 286D16D697CAA2DFC1EBCAD88A9633DD45C20E67 flags verified ) + rom ( name "Diva Starz (Germany).gbc" size 1048576 crc 56095f86 sha1 286D16D697CAA2DFC1EBCAD88A9633DD45C20E67 flags verified ) ) game ( name "Diva Starz - Mall Mania (USA)" description "Diva Starz - Mall Mania (USA)" - rom ( name "Diva Starz - Mall Mania (USA).gbc" size 1048576 crc EBE0ECD6 md5 B71D8408E211D4AE4DAF7745AF550B18 sha1 1D0EDB87404409F1E4C124503BE4CC59165C01DA ) + rom ( name "Diva Starz - Mall Mania (USA).gbc" size 1048576 crc ebe0ecd6 sha1 1D0EDB87404409F1E4C124503BE4CC59165C01DA ) ) game ( - name "Dogz - Your Virtual Petz Palz (Europe)" - description "Dogz - Your Virtual Petz Palz (Europe)" - rom ( name "Dogz - Your Virtual Petz Palz (Europe).gbc" size 1048576 crc CE8DD179 md5 227444A8CC81DC579BA4FB76C9CB8B46 sha1 AD1E238F180EAA55B4C76CD39A03A88F28DC9649 ) + name "Dogz (Europe)" + description "Dogz (Europe)" + rom ( name "Dogz (Europe).gbc" size 1048576 crc ce8dd179 sha1 AD1E238F180EAA55B4C76CD39A03A88F28DC9649 ) ) game ( - name "Dogz - Your Virtual Petz Palz (USA)" - description "Dogz - Your Virtual Petz Palz (USA)" - rom ( name "Dogz - Your Virtual Petz Palz (USA).gbc" size 1048576 crc A8397183 md5 4040E7A81EE393909429F0BFCBEB1E47 sha1 D0D4C661E2CED3664FF07B15F2FB2C57A63D2DAD ) + name "Dogz (USA)" + description "Dogz (USA)" + rom ( name "Dogz (USA).gbc" size 1048576 crc a8397183 sha1 D0D4C661E2CED3664FF07B15F2FB2C57A63D2DAD ) ) game ( - name "Dokapon! - Millennium Quest (Japan) (SGB Enhanced)" - description "Dokapon! - Millennium Quest (Japan) (SGB Enhanced)" - rom ( name "Dokapon! - Millennium Quest (Japan) (SGB Enhanced).gbc" size 2097152 crc 4FE9E966 md5 E7775EFDDF4D0A5E6A9E8534F5EFC2EF sha1 2AC27B1F9B8821FCF1CB4BF347156E29DCDE689C flags verified ) + name "Dokapon! - Millennium Quest (Japan) (SGB Enhanced) (GB Compatible)" + description "Dokapon! - Millennium Quest (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dokapon! - Millennium Quest (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4fe9e966 sha1 2AC27B1F9B8821FCF1CB4BF347156E29DCDE689C flags verified ) ) game ( name "Doki x Doki Sasete!! (Japan)" description "Doki x Doki Sasete!! (Japan)" - rom ( name "Doki x Doki Sasete!! (Japan).gbc" size 2097152 crc 19A73F60 md5 1D535AAC30B714E3AD5ECCF17025ECE2 sha1 D2D424BDD151222AA8316DB1FD1DF2CAFCB3A15D ) + rom ( name "Doki x Doki Sasete!! (Japan).gbc" size 2097152 crc 19a73f60 sha1 D2D424BDD151222AA8316DB1FD1DF2CAFCB3A15D flags verified ) ) game ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan)" description "Dokidoki Densetsu - Mahoujin Guruguru (Japan)" - rom ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan).gbc" size 4194304 crc 83E47A1A md5 E6A3D906BC47516138CA14578601AF02 sha1 1B4627699B45AF36A42E75C1A217B40FB5BEC4BA flags verified ) + rom ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan).gbc" size 4194304 crc 83e47a1a sha1 1B4627699B45AF36A42E75C1A217B40FB5BEC4BA flags verified ) ) game ( name "Donald Duck - Daisy o Sukue! (Japan)" description "Donald Duck - Daisy o Sukue! (Japan)" - rom ( name "Donald Duck - Daisy o Sukue! (Japan).gbc" size 4194304 crc 333C124C md5 CD4CA93B289AA0D7EF6A26B848E5E06A sha1 46ECFE890CB225563BCD45F8607962840B5FD587 ) + rom ( name "Donald Duck - Daisy o Sukue! (Japan).gbc" size 4194304 crc 333c124c sha1 46ECFE890CB225563BCD45F8607962840B5FD587 ) ) game ( name "Donald Duck - Goin' Quackers (USA) (En,Fr,De,Es,It)" description "Donald Duck - Goin' Quackers (USA) (En,Fr,De,Es,It)" - rom ( name "Donald Duck - Goin' Quackers (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 4685909B md5 4FD68C1CF8B57E90A5B11B054FC68B46 sha1 F2FA670FD20485B3BC1875DC8D31FB40374942BD ) + rom ( name "Donald Duck - Goin' Quackers (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 4685909b sha1 F2FA670FD20485B3BC1875DC8D31FB40374942BD ) ) game ( name "Donald Duck - Quack Attack (Europe) (En,Fr,De,Es,It)" description "Donald Duck - Quack Attack (Europe) (En,Fr,De,Es,It)" - rom ( name "Donald Duck - Quack Attack (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 07A13B5B md5 5315C21EAFFDE4A641A02D89F18E2A95 sha1 946E473AD7F363295F2C4BB488618F2325F51004 flags verified ) + rom ( name "Donald Duck - Quack Attack (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 07a13b5b sha1 946E473AD7F363295F2C4BB488618F2325F51004 flags verified ) ) game ( name "Donkey Kong 2001 (Japan)" description "Donkey Kong 2001 (Japan)" - rom ( name "Donkey Kong 2001 (Japan).gbc" size 4194304 crc CB065EBA md5 EF2A181785CC591AC53E960C68E14216 sha1 5BE5500D9FF9C4416DF77816EBD21CCA7A0B19DE flags verified ) + rom ( name "Donkey Kong 2001 (Japan).gbc" size 4194304 crc cb065eba sha1 5BE5500D9FF9C4416DF77816EBD21CCA7A0B19DE flags verified ) ) game ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It)" description "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc B1743477 md5 DC94079146EE90D7DD7D72280A3FAAD5 sha1 32522DFCE902D564E69348541348AFC054307F65 flags verified ) + rom ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc b1743477 sha1 32522DFCE902D564E69348541348AFC054307F65 flags verified ) ) game ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It) (Sample)" description "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It) (Sample)" - rom ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It) (Sample).gbc" size 4194304 crc 945C3653 md5 7841066AC7182F036E85682A18AD8134 sha1 6B21D4D43FE8AC234E7FB81A167F313CF044D5B6 ) + rom ( name "Donkey Kong Country (USA, Europe) (En,Fr,De,Es,It) (Sample).gbc" size 4194304 crc 945c3653 sha1 6B21D4D43FE8AC234E7FB81A167F313CF044D5B6 ) ) game ( name "Donkey Kong GB - Dinky Kong & Dixie Kong (Japan)" description "Donkey Kong GB - Dinky Kong & Dixie Kong (Japan)" - rom ( name "Donkey Kong GB - Dinky Kong & Dixie Kong (Japan).gbc" size 1048576 crc 28D7E8D3 md5 22AFE691095C65F34AEABA3C283B2A9C sha1 55B133B739A5472D477336647CB9EC97B7FA85A2 flags verified ) + rom ( name "Donkey Kong GB - Dinky Kong & Dixie Kong (Japan).gbc" size 1048576 crc 28d7e8d3 sha1 55B133B739A5472D477336647CB9EC97B7FA85A2 flags verified ) ) game ( - name "Doraemon - Aruke Aruke Labyrinth (Japan)" - description "Doraemon - Aruke Aruke Labyrinth (Japan)" - rom ( name "Doraemon - Aruke Aruke Labyrinth (Japan).gbc" size 1048576 crc F6D79A79 md5 1DDDF21BCC96C84A9294BDB411A49728 sha1 F825279FEEC357BABA2B39423AA596CE02E34921 ) + name "Doraemon - Aruke Aruke Labyrinth (Japan) (GB Compatible)" + description "Doraemon - Aruke Aruke Labyrinth (Japan) (GB Compatible)" + rom ( name "Doraemon - Aruke Aruke Labyrinth (Japan) (GB Compatible).gbc" size 1048576 crc f6d79a79 sha1 F825279FEEC357BABA2B39423AA596CE02E34921 flags verified ) ) game ( - name "Doraemon - Kimi to Pet no Monogatari (Japan)" - description "Doraemon - Kimi to Pet no Monogatari (Japan)" - rom ( name "Doraemon - Kimi to Pet no Monogatari (Japan).gbc" size 1048576 crc 2FA46211 md5 9BBE3CB922A017053D86D1355EE69794 sha1 1FB01A4A492243C1768BDBF5DB88FD95D0CC4F59 ) + name "Doraemon - Kimi to Pet no Monogatari (Japan) (GB Compatible)" + description "Doraemon - Kimi to Pet no Monogatari (Japan) (GB Compatible)" + rom ( name "Doraemon - Kimi to Pet no Monogatari (Japan) (GB Compatible).gbc" size 1048576 crc 2fa46211 sha1 1FB01A4A492243C1768BDBF5DB88FD95D0CC4F59 ) ) game ( - name "Doraemon Kart 2 (Japan) (SGB Enhanced)" - description "Doraemon Kart 2 (Japan) (SGB Enhanced)" - rom ( name "Doraemon Kart 2 (Japan) (SGB Enhanced).gbc" size 1048576 crc CF1A2038 md5 D0009C14CFDCD02695D84D068C0D4ABE sha1 B29695B9944C030C518140341D748D1A1F21F982 ) + name "Doraemon Kart 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Doraemon Kart 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Doraemon Kart 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc cf1a2038 sha1 B29695B9944C030C518140341D748D1A1F21F982 flags verified ) ) game ( - name "Doraemon Memories - Nobita no Omoide Daibouken (Japan)" - description "Doraemon Memories - Nobita no Omoide Daibouken (Japan)" - rom ( name "Doraemon Memories - Nobita no Omoide Daibouken (Japan).gbc" size 1048576 crc D187CEC4 md5 1F0E9DA07447DE982BC0FBC0EB3A5D24 sha1 3152A167021FF536186051C42C6E8F131D72AD41 flags verified ) + name "Doraemon Memories - Nobita no Omoide Daibouken (Japan) (GB Compatible)" + description "Doraemon Memories - Nobita no Omoide Daibouken (Japan) (GB Compatible)" + rom ( name "Doraemon Memories - Nobita no Omoide Daibouken (Japan) (GB Compatible).gbc" size 1048576 crc d187cec4 sha1 3152A167021FF536186051C42C6E8F131D72AD41 flags verified ) ) game ( name "Doraemon no Quiz Boy (Japan)" description "Doraemon no Quiz Boy (Japan)" - rom ( name "Doraemon no Quiz Boy (Japan).gbc" size 1048576 crc 3BBF9EA8 md5 509CA3DC125131B1A4B1667CCC64FD27 sha1 FD05ADB1A6FACE86FF263883FDF4CEBF14E055E9 ) + rom ( name "Doraemon no Quiz Boy (Japan).gbc" size 1048576 crc 3bbf9ea8 sha1 FD05ADB1A6FACE86FF263883FDF4CEBF14E055E9 ) ) game ( - name "Doraemon no Quiz Boy (Japan) (Rev A)" - description "Doraemon no Quiz Boy (Japan) (Rev A)" - rom ( name "Doraemon no Quiz Boy (Japan) (Rev A).gbc" size 1048576 crc 915356E3 md5 7F6C3F5388D3BCC0D02E8A2EA0D5E988 sha1 AE48F07E608D76143A4A51F18F9454CD990D766A flags verified ) + name "Doraemon no Quiz Boy (Japan) (Rev 1)" + description "Doraemon no Quiz Boy (Japan) (Rev 1)" + rom ( name "Doraemon no Quiz Boy (Japan) (Rev 1).gbc" size 1048576 crc 915356e3 sha1 AE48F07E608D76143A4A51F18F9454CD990D766A flags verified ) ) game ( name "Doraemon no Quiz Boy 2 (Japan)" description "Doraemon no Quiz Boy 2 (Japan)" - rom ( name "Doraemon no Quiz Boy 2 (Japan).gbc" size 1048576 crc 9E80199A md5 15BEDC4919965732CBFB301F11E5B36A sha1 C6B5FFC4B8F7C106807ED7E2C72E37090D3FAA97 flags verified ) + rom ( name "Doraemon no Quiz Boy 2 (Japan).gbc" size 1048576 crc 9e80199a sha1 C6B5FFC4B8F7C106807ED7E2C72E37090D3FAA97 flags verified ) ) game ( name "Doraemon no Study Boy - Gakushuu Kanji Game (Japan)" description "Doraemon no Study Boy - Gakushuu Kanji Game (Japan)" - rom ( name "Doraemon no Study Boy - Gakushuu Kanji Game (Japan).gbc" size 1048576 crc 67413F65 md5 D10D56951B817115477D72A855D7C025 sha1 1F8AAD0FC2A8D03244C69F3A6D80AF1A21164DDC ) + rom ( name "Doraemon no Study Boy - Gakushuu Kanji Game (Japan).gbc" size 1048576 crc 67413f65 sha1 1F8AAD0FC2A8D03244C69F3A6D80AF1A21164DDC flags verified ) ) game ( name "Doraemon no Study Boy - Kanji Yomikaki Master (Japan)" description "Doraemon no Study Boy - Kanji Yomikaki Master (Japan)" - rom ( name "Doraemon no Study Boy - Kanji Yomikaki Master (Japan).gbc" size 1048576 crc 70156DA7 md5 E599E5AAB2CFE2FC95D340A5C910D87E sha1 4B7EC303305DAED053243B125A9AEBC44F3E221E flags verified ) + rom ( name "Doraemon no Study Boy - Kanji Yomikaki Master (Japan).gbc" size 1048576 crc 70156da7 sha1 4B7EC303305DAED053243B125A9AEBC44F3E221E flags verified ) ) game ( name "Doraemon no Study Boy - Kuku Game (Japan)" description "Doraemon no Study Boy - Kuku Game (Japan)" - rom ( name "Doraemon no Study Boy - Kuku Game (Japan).gbc" size 1048576 crc A8A353D8 md5 7F0D28D7C0268B55BB8682224C178308 sha1 9B5C8B89B6E69D3803FBD43B2FE5130AD6D2F50B ) + rom ( name "Doraemon no Study Boy - Kuku Game (Japan).gbc" size 1048576 crc a8a353d8 sha1 9B5C8B89B6E69D3803FBD43B2FE5130AD6D2F50B ) ) game ( name "Doug - La Grande Aventure (France)" description "Doug - La Grande Aventure (France)" - rom ( name "Doug - La Grande Aventure (France).gbc" size 1048576 crc A9E62F1A md5 01FB7107B8432D3EED3E131605D682A3 sha1 818804E3BC300B0A027A4E34055412C58D73F05E ) + rom ( name "Doug - La Grande Aventure (France).gbc" size 1048576 crc a9e62f1a sha1 818804E3BC300B0A027A4E34055412C58D73F05E ) ) game ( name "Doug's Big Game (Germany)" description "Doug's Big Game (Germany)" - rom ( name "Doug's Big Game (Germany).gbc" size 1048576 crc 5DC254D1 md5 535AC79C69B22ED21CC9AF0D4C10BEA8 sha1 DF95173E91CD83BF7CB617629541C815E1AD3577 flags verified ) + rom ( name "Doug's Big Game (Germany).gbc" size 1048576 crc 5dc254d1 sha1 DF95173E91CD83BF7CB617629541C815E1AD3577 flags verified ) ) game ( name "Doug's Big Game (USA)" description "Doug's Big Game (USA)" - rom ( name "Doug's Big Game (USA).gbc" size 1048576 crc 08E3D065 md5 19E0D71A2A6090E0F59607CA4DA9B156 sha1 BE8B0F966A43954084244CCD636AD3BB5A8B721C ) + rom ( name "Doug's Big Game (USA).gbc" size 1048576 crc 08e3d065 sha1 BE8B0F966A43954084244CCD636AD3BB5A8B721C ) ) game ( name "Doug's Big Game (Europe)" description "Doug's Big Game (Europe)" - rom ( name "Doug's Big Game (Europe).gbc" size 1048576 crc B6FFBCCA md5 8D4B4907E207A824A065B0012B22C62C sha1 E9C207BB9B03B5762AFD53C8F5295703CC1474B1 ) + rom ( name "Doug's Big Game (Europe).gbc" size 1048576 crc b6ffbcca sha1 E9C207BB9B03B5762AFD53C8F5295703CC1474B1 flags verified ) ) game ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" description "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" - rom ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan).gbc" size 2097152 crc EC168A61 md5 448AF6D54CE1886456C98209F53ABDC7 sha1 7810EA39EDD661D2A9E95F57C9847D7E5A172FF6 flags verified ) + rom ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan).gbc" size 2097152 crc ec168a61 sha1 7810EA39EDD661D2A9E95F57C9847D7E5A172FF6 flags verified ) ) game ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It)" description "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It)" - rom ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2F7AEF51 md5 192AEC8DCA7656463BE56991F497CFF3 sha1 815F252F761E0FD3F29B7ACF32B2360264AEFAB1 flags verified ) + rom ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2f7aef51 sha1 815F252F761E0FD3F29B7ACF32B2360264AEFAB1 flags verified ) ) game ( name "Dracula - Crazy Vampire (USA)" description "Dracula - Crazy Vampire (USA)" - rom ( name "Dracula - Crazy Vampire (USA).gbc" size 1048576 crc 283742E4 md5 0B943EFDF2CA967827A4C7BF951F6448 sha1 049727B428B01C5309A86039007C97BED7BF856A ) + rom ( name "Dracula - Crazy Vampire (USA).gbc" size 1048576 crc 283742e4 sha1 049727B428B01C5309A86039007C97BED7BF856A ) ) game ( name "Dragon Ball Z - Densetsu no Chou Senshi-tachi (Japan)" description "Dragon Ball Z - Densetsu no Chou Senshi-tachi (Japan)" - rom ( name "Dragon Ball Z - Densetsu no Chou Senshi-tachi (Japan).gbc" size 2097152 crc 7D28689A md5 A94A1C6268555926CA1A3B439A2FB65C sha1 B094AE04FE665371CF0F5CB6942A67A379E8E645 flags verified ) + rom ( name "Dragon Ball Z - Densetsu no Chou Senshi-tachi (Japan).gbc" size 2097152 crc 7d28689a sha1 B094AE04FE665371CF0F5CB6942A67A379E8E645 flags verified ) ) game ( name "Dragon Ball Z - Guerreros de Leyenda (Spain)" description "Dragon Ball Z - Guerreros de Leyenda (Spain)" - rom ( name "Dragon Ball Z - Guerreros de Leyenda (Spain).gbc" size 2097152 crc 9DAD6E23 md5 9324855FEF2227A4410725ED20845BFB sha1 0318FA8930608CBF4DC69A8B6E2A41C96A51EA04 ) + rom ( name "Dragon Ball Z - Guerreros de Leyenda (Spain).gbc" size 2097152 crc 9dad6e23 sha1 0318FA8930608CBF4DC69A8B6E2A41C96A51EA04 ) ) game ( name "Dragon Ball Z - I Leggendari Super Guerrieri (Italy)" description "Dragon Ball Z - I Leggendari Super Guerrieri (Italy)" - rom ( name "Dragon Ball Z - I Leggendari Super Guerrieri (Italy).gbc" size 2097152 crc A888A049 md5 4CDE8DAC14B8ACE83F8A4716CCB2DBF0 sha1 56DEE34337A8893097CBFFD7EA8AFF76CAEF92D0 flags verified ) + rom ( name "Dragon Ball Z - I Leggendari Super Guerrieri (Italy).gbc" size 2097152 crc a888a049 sha1 56DEE34337A8893097CBFFD7EA8AFF76CAEF92D0 flags verified ) ) game ( name "Dragon Ball Z - Legendaere Superkaempfer (Germany)" description "Dragon Ball Z - Legendaere Superkaempfer (Germany)" - rom ( name "Dragon Ball Z - Legendaere Superkaempfer (Germany).gbc" size 2097152 crc EC7DFDC1 md5 B587D5AE7C464408526489B67DFCA07D sha1 8EB99E87C58A471B9AF5F91B2AEAB2BF4EC516D9 flags verified ) + rom ( name "Dragon Ball Z - Legendaere Superkaempfer (Germany).gbc" size 2097152 crc ec7dfdc1 sha1 8EB99E87C58A471B9AF5F91B2AEAB2BF4EC516D9 flags verified ) ) game ( name "Dragon Ball Z - Legendary Super Warriors (Europe)" description "Dragon Ball Z - Legendary Super Warriors (Europe)" - rom ( name "Dragon Ball Z - Legendary Super Warriors (Europe).gbc" size 2097152 crc 7BF836DB md5 C663691B1ECA7EEEB501C4D00B4B186F sha1 C190D34BEAC5157E98076D6A94FFA3033579B7A2 ) + rom ( name "Dragon Ball Z - Legendary Super Warriors (Europe).gbc" size 2097152 crc 7bf836db sha1 C190D34BEAC5157E98076D6A94FFA3033579B7A2 ) ) game ( name "Dragon Ball Z - Legendary Super Warriors (USA)" description "Dragon Ball Z - Legendary Super Warriors (USA)" - rom ( name "Dragon Ball Z - Legendary Super Warriors (USA).gbc" size 2097152 crc 025AA88A md5 AC46BC779E1E844674DE1D4C13D06F96 sha1 E8184E1AE44D744AA54A082BD9979A46E144E6FB ) + rom ( name "Dragon Ball Z - Legendary Super Warriors (USA).gbc" size 2097152 crc 025aa88a sha1 E8184E1AE44D744AA54A082BD9979A46E144E6FB flags verified ) ) game ( name "Dragon Ball Z - Les Guerriers Legendaires (France)" description "Dragon Ball Z - Les Guerriers Legendaires (France)" - rom ( name "Dragon Ball Z - Les Guerriers Legendaires (France).gbc" size 2097152 crc C07E9438 md5 FFA003FA747731A9FD547260598538CB sha1 F5F0BC375F4559C9A0D62B52AFD2EEE18273C193 ) + rom ( name "Dragon Ball Z - Les Guerriers Legendaires (France).gbc" size 2097152 crc c07e9438 sha1 F5F0BC375F4559C9A0D62B52AFD2EEE18273C193 ) ) game ( - name "Dragon Dance (USA) (SGB Enhanced)" - description "Dragon Dance (USA) (SGB Enhanced)" - rom ( name "Dragon Dance (USA) (SGB Enhanced).gbc" size 262144 crc 0602DBE1 md5 0C6A0F2ADD131CA4AFD24763FE3C3A04 sha1 A28BFABC4DB62AD5AA6BFE29114B0878429586CC ) + name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" + description "Dragon Dance (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Dance (USA) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 0602dbe1 sha1 A28BFABC4DB62AD5AA6BFE29114B0878429586CC ) ) game ( - name "Dragon Quest I & II (Japan) (SGB Enhanced)" - description "Dragon Quest I & II (Japan) (SGB Enhanced)" - rom ( name "Dragon Quest I & II (Japan) (SGB Enhanced).gbc" size 2097152 crc A053B42E md5 5045139EB57B9D6CDFA1366F473A1E4C sha1 8CFDFB7A76DD0012AF3B441E162FCD37E4370958 flags verified ) + name "Dragon Quest I & II (Japan) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest I & II (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest I & II (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc a053b42e sha1 8CFDFB7A76DD0012AF3B441E162FCD37E4370958 flags verified ) ) game ( name "Dragon Quest III - Soshite Densetsu e... (Japan)" description "Dragon Quest III - Soshite Densetsu e... (Japan)" - rom ( name "Dragon Quest III - Soshite Densetsu e... (Japan).gbc" size 4194304 crc 21078C16 md5 729934DDB7AA39779A456523A81B4A45 sha1 1F30968A5EBD32643ACD32351E78E68CFFFB8AE9 flags verified ) + rom ( name "Dragon Quest III - Soshite Densetsu e... (Japan).gbc" size 4194304 crc 21078c16 sha1 1F30968A5EBD32643ACD32351E78E68CFFFB8AE9 flags verified ) ) game ( - name "Dragon Quest Monsters (Germany) (SGB Enhanced)" - description "Dragon Quest Monsters (Germany) (SGB Enhanced)" - rom ( name "Dragon Quest Monsters (Germany) (SGB Enhanced).gbc" size 2097152 crc 2A82B63B md5 08BCA718C62E3C2870A2DF107FC0A562 sha1 AE8A05D616785391BA4BBDCA4C408D4A641C6683 flags verified ) + name "Dragon Quest Monsters (Germany) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest Monsters (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest Monsters (Germany) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 2a82b63b sha1 AE8A05D616785391BA4BBDCA4C408D4A641C6683 flags verified ) ) game ( - name "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced)" - description "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced)" - rom ( name "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced).gbc" size 2097152 crc 4702C4F1 md5 5254EA1935C43057358D2EFBA26C60C8 sha1 EEBAF3D553BB915340E64CB85022EB8344DDF1B0 flags verified ) + name "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest Monsters - Terry no Wonderland (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4702c4f1 sha1 EEBAF3D553BB915340E64CB85022EB8344DDF1B0 flags verified ) ) game ( - name "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev A) (SGB Enhanced)" - description "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev A) (SGB Enhanced).gbc" size 2097152 crc D263D88D md5 B28C999D1B43E8E39998827FF39965CC sha1 A32198D1645741979E24956AFD6479B64C258647 flags verified ) + name "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest Monsters - Terry no Wonderland (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d263d88d sha1 A32198D1645741979E24956AFD6479B64C258647 flags verified ) ) game ( - name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced)" - description "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced)" - rom ( name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced).gbc" size 4194304 crc 68BA18D7 md5 F47EDC51D53AE8F416898B80BD3022A1 sha1 9193778B28E2E4A6303E09CB4170CA00D0058AE5 ) + name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Iru no Bouken (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 68ba18d7 sha1 9193778B28E2E4A6303E09CB4170CA00D0058AE5 flags verified ) ) game ( - name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced)" - description "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced)" - rom ( name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced).gbc" size 4194304 crc 2C428A87 md5 979EB4FD473C344CB2CFC6EA4211CA5A sha1 5D2DAEC53938805236328A0F8A614DEBFFA34048 flags verified ) + name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced) (GB Compatible)" + description "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 2c428a87 sha1 5D2DAEC53938805236328A0F8A614DEBFFA34048 flags verified ) +) + +game ( + name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (Rev 1)" + description "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (Rev 1)" + rom ( name "Dragon Quest Monsters 2 - Maruta no Fushigi na Kagi - Ruka no Tabidachi (Japan) (Rev 1).gbc" size 4194304 crc 649e8d97 sha1 217FAAF8E7D60545BD07F818A3B3373843E6318D flags verified ) ) game ( name "Dragon Tales - Dragon Adventures (USA)" description "Dragon Tales - Dragon Adventures (USA)" - rom ( name "Dragon Tales - Dragon Adventures (USA).gbc" size 1048576 crc DE390609 md5 27791FF8BB7993EBBA8C8F2CF353A6B3 sha1 3DAA96D9D66F686077F03F0820C63F751047E791 ) + rom ( name "Dragon Tales - Dragon Adventures (USA).gbc" size 1048576 crc de390609 sha1 3DAA96D9D66F686077F03F0820C63F751047E791 flags verified ) ) game ( name "Dragon Tales - Dragon Wings (Europe)" description "Dragon Tales - Dragon Wings (Europe)" - rom ( name "Dragon Tales - Dragon Wings (Europe).gbc" size 1048576 crc 137D7B45 md5 834FB201A446065C06E34F192F8586D0 sha1 FA30510EB396143B3B0025005EE82DE207562E65 ) + rom ( name "Dragon Tales - Dragon Wings (Europe).gbc" size 1048576 crc 137d7b45 sha1 FA30510EB396143B3B0025005EE82DE207562E65 ) ) game ( name "Dragon Tales - Dragon Wings (USA)" description "Dragon Tales - Dragon Wings (USA)" - rom ( name "Dragon Tales - Dragon Wings (USA).gbc" size 1048576 crc 191D31EC md5 9A43179573D212B528D8F74DA044511C sha1 DE220565BFDD27E48DE4BA886CD3C135953140E5 ) + rom ( name "Dragon Tales - Dragon Wings (USA).gbc" size 1048576 crc 191d31ec sha1 DE220565BFDD27E48DE4BA886CD3C135953140E5 ) ) game ( - name "Dragon Warrior I & II (USA) (SGB Enhanced)" - description "Dragon Warrior I & II (USA) (SGB Enhanced)" - rom ( name "Dragon Warrior I & II (USA) (SGB Enhanced).gbc" size 2097152 crc 71D693DA md5 C3987A4D734C37B7D8324F654A45DE70 sha1 01C4E2145365A12560D162116378F1991807EF95 flags verified ) + name "Dragon Warrior I & II (USA) (SGB Enhanced) (GB Compatible)" + description "Dragon Warrior I & II (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Warrior I & II (USA) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 71d693da sha1 01C4E2145365A12560D162116378F1991807EF95 flags verified ) ) game ( name "Dragon Warrior III (USA)" description "Dragon Warrior III (USA)" - rom ( name "Dragon Warrior III (USA).gbc" size 4194304 crc 0FD9C59C md5 B74B6132326BAFCD75E415DDCD9A2932 sha1 581A12695AE42BECAA078AC2694A11767A96DC61 flags verified ) + rom ( name "Dragon Warrior III (USA).gbc" size 4194304 crc 0fd9c59c sha1 581A12695AE42BECAA078AC2694A11767A96DC61 flags verified ) ) game ( - name "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced)" - description "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced)" - rom ( name "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced).gbc" size 2097152 crc E56C35B1 md5 1CA6579359F21D8E27B446F865BF6B83 sha1 728E458D4B13CDC8A0026DC28C5A14F1D72D9DA4 flags verified ) + name "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Warrior Monsters (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc e56c35b1 sha1 728E458D4B13CDC8A0026DC28C5A14F1D72D9DA4 flags verified ) ) game ( - name "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced)" - description "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced)" - rom ( name "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced).gbc" size 4194304 crc AB7BFDD5 md5 F71AC6AC4BB335F59BFD2B594D47AB49 sha1 76901B7E5CADF9611DD4FAC52E8501155C1E33A2 ) + name "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced) (GB Compatible)" + description "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Warrior Monsters 2 - Cobi's Journey (USA) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc ab7bfdd5 sha1 76901B7E5CADF9611DD4FAC52E8501155C1E33A2 ) ) game ( - name "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced)" - description "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced)" - rom ( name "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced).gbc" size 4194304 crc 35EC5FB2 md5 8E79DCDEE0E15EF069B3F376A0FEE37D sha1 A68451E7D3ACCD81B240C4B60A1F552E39211EDE ) + name "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced) (GB Compatible)" + description "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Dragon Warrior Monsters 2 - Tara's Adventure (USA) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 35ec5fb2 sha1 A68451E7D3ACCD81B240C4B60A1F552E39211EDE ) ) game ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh)" description "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh)" - rom ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh).gbc" size 4194304 crc BF076CA5 md5 947F96CFD5BAB7A03EC2F3FC0AE9238D sha1 15FB0865314E43A83910D52CCA7307502AAB29FC flags verified ) + rom ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh).gbc" size 4194304 crc bf076ca5 sha1 15FB0865314E43A83910D52CCA7307502AAB29FC flags verified ) ) game ( name "Driver (Europe) (En,Fr,De,Es,It)" description "Driver (Europe) (En,Fr,De,Es,It)" - rom ( name "Driver (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc E9E67403 md5 FAAB6966E9ED5E80FF724CAFDE1E903D sha1 5001F0F4904CA4FB6AB287B52136D00AC94B49D7 ) + rom ( name "Driver (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc e9e67403 sha1 5001F0F4904CA4FB6AB287B52136D00AC94B49D7 flags verified ) ) game ( name "Driver - You are the Wheelman (USA) (En,Fr,De,Es,It)" description "Driver - You are the Wheelman (USA) (En,Fr,De,Es,It)" - rom ( name "Driver - You are the Wheelman (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc D4C7F6DF md5 413E1ACD7847D628364163EB2C97CECD sha1 9ADD1E67F39F900F2C004E4D8BBD1FEC368EEF4C ) + rom ( name "Driver - You are the Wheelman (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc d4c7f6df sha1 9ADD1E67F39F900F2C004E4D8BBD1FEC368EEF4C ) ) game ( - name "Dropzone (Europe)" - description "Dropzone (Europe)" - rom ( name "Dropzone (Europe).gbc" size 262144 crc 1E71B67E md5 B3142AAE557BC4E04E2F0F740FAE9577 sha1 E5BB7C075C2953E99CA2ABE66592810125FEBF0A flags verified ) + name "Dropzone (Europe) (GB Compatible)" + description "Dropzone (Europe) (GB Compatible)" + rom ( name "Dropzone (Europe) (GB Compatible).gbc" size 262144 crc 1e71b67e sha1 E5BB7C075C2953E99CA2ABE66592810125FEBF0A flags verified ) ) game ( - name "DT - Lords of Genomes (Japan) (SGB Enhanced)" - description "DT - Lords of Genomes (Japan) (SGB Enhanced)" - rom ( name "DT - Lords of Genomes (Japan) (SGB Enhanced).gbc" size 4194304 crc 42CEB854 md5 48B5FEA61742D75E98782803D14871F3 sha1 66988A201F77CD4C33FB0A9B3981FF5831206C9D ) + name "DT - Lords of Genomes (Japan) (SGB Enhanced) (GB Compatible)" + description "DT - Lords of Genomes (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "DT - Lords of Genomes (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 42ceb854 sha1 66988A201F77CD4C33FB0A9B3981FF5831206C9D flags verified ) ) game ( name "Duke Nukem (Europe) (En,Fr,De,Es,It)" description "Duke Nukem (Europe) (En,Fr,De,Es,It)" - rom ( name "Duke Nukem (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc FC3D1BB7 md5 B25025224EB338963FC9C0FEE91F2C39 sha1 665961E875350D9335E467C2AD752A4DD3DCAEF4 ) + rom ( name "Duke Nukem (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc fc3d1bb7 sha1 665961E875350D9335E467C2AD752A4DD3DCAEF4 flags verified ) ) game ( name "Duke Nukem (USA) (En,Fr,De,Es,It)" description "Duke Nukem (USA) (En,Fr,De,Es,It)" - rom ( name "Duke Nukem (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 846FC830 md5 B2D3713267C9E21B3DAE3CB5F437FCCD sha1 B9BD0CFE64A7F40C243BC65E0489B5187AD11560 ) + rom ( name "Duke Nukem (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 846fc830 sha1 B9BD0CFE64A7F40C243BC65E0489B5187AD11560 ) ) game ( name "Dukes of Hazzard, The - Racing for Home (Europe) (En,Fr,De)" description "Dukes of Hazzard, The - Racing for Home (Europe) (En,Fr,De)" - rom ( name "Dukes of Hazzard, The - Racing for Home (Europe) (En,Fr,De).gbc" size 2097152 crc 21826ADC md5 DC131A70357D28BC43649C4AD6CD4397 sha1 782337F5338A242BC8CBAEB69CE7F1E87BB0F6B9 flags verified ) + rom ( name "Dukes of Hazzard, The - Racing for Home (Europe) (En,Fr,De).gbc" size 2097152 crc 21826adc sha1 782337F5338A242BC8CBAEB69CE7F1E87BB0F6B9 flags verified ) ) game ( name "Dukes of Hazzard, The - Racing for Home (USA)" description "Dukes of Hazzard, The - Racing for Home (USA)" - rom ( name "Dukes of Hazzard, The - Racing for Home (USA).gbc" size 2097152 crc FB08DCEB md5 193F103B57F5861B55524644BADB4ECD sha1 6A39DFBCE8B86DB84615CDB5FB24012CBBAC7B36 ) + rom ( name "Dukes of Hazzard, The - Racing for Home (USA).gbc" size 2097152 crc fb08dceb sha1 6A39DFBCE8B86DB84615CDB5FB24012CBBAC7B36 ) ) game ( - name "Dungeon Savior (Japan) (SGB Enhanced)" - description "Dungeon Savior (Japan) (SGB Enhanced)" - rom ( name "Dungeon Savior (Japan) (SGB Enhanced).gbc" size 4194304 crc 2BCB5F78 md5 3F56E5776FF9A2B08A0C22F5EACF6017 sha1 766AB65D9420F361D8D9A4754EA8C6B692E34C36 ) + name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" + description "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Dungeon Savior (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 2bcb5f78 sha1 766AB65D9420F361D8D9A4754EA8C6B692E34C36 ) ) game ( name "DX Jinsei Game (Japan)" description "DX Jinsei Game (Japan)" - rom ( name "DX Jinsei Game (Japan).gbc" size 2097152 crc 7E15B3DD md5 E5CF736F37CBBBBE6957E172DE5626FC sha1 CD14FE4E7C7A8A4C6AF76682A954EF24919D89AD flags verified ) + rom ( name "DX Jinsei Game (Japan).gbc" size 2097152 crc 7e15b3dd sha1 CD14FE4E7C7A8A4C6AF76682A954EF24919D89AD flags verified ) ) game ( - name "DX Monopoly GB (Japan) (SGB Enhanced)" - description "DX Monopoly GB (Japan) (SGB Enhanced)" - rom ( name "DX Monopoly GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 3F1E076C md5 4CEC140483BAF799E883E717B8CE81A5 sha1 524D9459D357E209D64A2EF17B4072478F290806 ) + name "DX Monopoly GB (Japan) (SGB Enhanced) (GB Compatible)" + description "DX Monopoly GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "DX Monopoly GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 3f1e076c sha1 524D9459D357E209D64A2EF17B4072478F290806 ) ) game ( name "DynaMike (Europe) (Proto)" description "DynaMike (Europe) (Proto)" - rom ( name "DynaMike (Europe) (Proto).gbc" size 1048576 crc 53C069E9 md5 699E1A69E9579545958F60106BB23A19 sha1 692A583DA5890E83DA5A5EAC8D0D31315DA316DF ) + rom ( name "DynaMike (Europe) (Proto).gbc" size 1048576 crc 53c069e9 sha1 692A583DA5890E83DA5A5EAC8D0D31315DA316DF ) ) game ( name "E.T. - The Extra-Terrestrial - Digital Companion (USA)" description "E.T. - The Extra-Terrestrial - Digital Companion (USA)" - rom ( name "E.T. - The Extra-Terrestrial - Digital Companion (USA).gbc" size 1048576 crc 84872999 md5 51091A6D773823B8731240676D9D25CF sha1 7DD940C8044CCC0E18A511FA32C73551CE30463E ) + rom ( name "E.T. - The Extra-Terrestrial - Digital Companion (USA).gbc" size 1048576 crc 84872999 sha1 7DD940C8044CCC0E18A511FA32C73551CE30463E ) ) game ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (Europe) (En,Fr,De,Es,It,Nl)" description "E.T. - The Extra-Terrestrial - Escape from Planet Earth (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc B25F3DB5 md5 A4A756BE0D12C2BA7CA5A6420BB2198E sha1 95FD6B8F5B4F550D6E28F21F23E2E0794176D9B7 ) + rom ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc b25f3db5 sha1 95FD6B8F5B4F550D6E28F21F23E2E0794176D9B7 flags verified ) ) game ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (USA)" description "E.T. - The Extra-Terrestrial - Escape from Planet Earth (USA)" - rom ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (USA).gbc" size 1048576 crc 086106DE md5 3EE67BD4471E60F4FEC6B0799219A2F5 sha1 D90E6A76A6CADC4B364F36C01345A26E086ADB73 ) + rom ( name "E.T. - The Extra-Terrestrial - Escape from Planet Earth (USA).gbc" size 1048576 crc 086106de sha1 D90E6A76A6CADC4B364F36C01345A26E086ADB73 ) ) game ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (Europe) (En,Fr,De,Es,It,Nl)" description "E.T. - The Extra-Terrestrial and the Cosmic Garden (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8321A1B9 md5 46B9A55A3049A1113BC5430EDAAF9401 sha1 C4F4179F391FC57EA4DB3688D95F2D53533DB995 flags verified ) + rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8321a1b9 sha1 C4F4179F391FC57EA4DB3688D95F2D53533DB995 flags verified ) ) game ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA)" description "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA)" - rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA).gbc" size 1048576 crc 32C87958 md5 F1B1776986BBADFA4E6771395FBC6214 sha1 DA71B581F7415B6535AC4AF2E8FCCD2040C54215 ) + rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA).gbc" size 1048576 crc 32c87958 sha1 DA71B581F7415B6535AC4AF2E8FCCD2040C54215 flags verified ) ) game ( - name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe)" - description "Earthworm Jim - Menace 2 the Galaxy (USA, Europe)" - rom ( name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe).gbc" size 1048576 crc 2E65DAAF md5 002D0D5FD2F668798DA1991B5FD5B4D8 sha1 78F9BD7F8C40274CF7282892A45E814103944060 flags verified ) + name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" + description "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" + rom ( name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible).gbc" size 1048576 crc 2e65daaf sha1 78F9BD7F8C40274CF7282892A45E814103944060 flags verified ) ) game ( name "ECW Hardcore Revolution (USA, Europe)" description "ECW Hardcore Revolution (USA, Europe)" - rom ( name "ECW Hardcore Revolution (USA, Europe).gbc" size 1048576 crc 484EBA10 md5 45AFA73780709DB49CE92EEA952B0BAF sha1 C337D0480E84F5E2B7E28B13C3667B8CF92D9649 flags verified ) + rom ( name "ECW Hardcore Revolution (USA, Europe).gbc" size 1048576 crc 484eba10 sha1 C337D0480E84F5E2B7E28B13C3667B8CF92D9649 flags verified ) +) + +game ( + name "Elemental Fighter (USA) (Proto)" + description "Elemental Fighter (USA) (Proto)" + rom ( name "Elemental Fighter (USA) (Proto).gbc" size 262144 crc 03fc3d03 sha1 92CCE7614474D3F9ED9E3FDBD2E2BB434E074565 flags verified ) ) game ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It)" description "Elevator Action EX (Europe) (En,Fr,De,Es,It)" - rom ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2154763C md5 F88959B615F284CC120CD17F5263D018 sha1 498308EFB907C8DC79C9699D27FF349941FAC23A flags verified ) + rom ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2154763c sha1 498308EFB907C8DC79C9699D27FF349941FAC23A flags verified ) ) game ( name "Elevator Action EX (Japan)" description "Elevator Action EX (Japan)" - rom ( name "Elevator Action EX (Japan).gbc" size 1048576 crc B70C4DDB md5 0979556C11F2EE65A8D9A03B4A1C04D7 sha1 DB91028DE0A07479F53F7449D0A6794D295E0B97 ) + rom ( name "Elevator Action EX (Japan).gbc" size 1048576 crc b70c4ddb sha1 DB91028DE0A07479F53F7449D0A6794D295E0B97 ) ) game ( - name "Elie no Atelier GB (Japan) (SGB Enhanced)" - description "Elie no Atelier GB (Japan) (SGB Enhanced)" - rom ( name "Elie no Atelier GB (Japan) (SGB Enhanced).gbc" size 2097152 crc 7967320E md5 473E78B1D576A052492E1B4B80F4D3B3 sha1 95797142058700B13577C21ED118B6508B84C8A6 flags verified ) -) - -game ( - name "Elmo's 123s (USA)" - description "Elmo's 123s (USA)" - rom ( name "Elmo's 123s (USA).gbc" size 262144 crc 1833FB38 md5 F7E5F82FF68AA678B92E41159DB34E90 sha1 0ACA4297EC6DC582B668681452F1805AAB991BEC ) -) - -game ( - name "Elmo's 123s (Europe)" - description "Elmo's 123s (Europe)" - rom ( name "Elmo's 123s (Europe).gbc" size 1048576 crc 3BF7FCD4 md5 023B5DBE9C3DCB3BC11AB388E8A40FE3 sha1 841BDA2E2C1542C44B45C98A390BA3320EF735CC ) -) - -game ( - name "Elmo's ABCs (Europe)" - description "Elmo's ABCs (Europe)" - rom ( name "Elmo's ABCs (Europe).gbc" size 1048576 crc 20158FBC md5 5DA357EF79ACB5AB8852D145888DD5CB sha1 E98D4D4179CA13C22D0205F118470ECC795928B1 ) -) - -game ( - name "Elmo's ABCs (USA)" - description "Elmo's ABCs (USA)" - rom ( name "Elmo's ABCs (USA).gbc" size 262144 crc CC1FB2A9 md5 DB9D9E20AF969A2EE248AE9AF42A5D36 sha1 C63EA7FF94250F1F7514A01250BBD5F04A5D2037 ) + name "Elie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Elie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Elie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 7967320e sha1 95797142058700B13577C21ED118B6508B84C8A6 flags verified ) ) game ( name "Emperor's New Groove, The (Europe) (En,Fr,De,Es,It)" description "Emperor's New Groove, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Emperor's New Groove, The (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 4CAA8CD0 md5 A308DE3B28CE996E8A1FF16AE8D26919 sha1 245484B940A5AE8C58F77C8EAA7980D266281CED ) + rom ( name "Emperor's New Groove, The (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 4caa8cd0 sha1 245484B940A5AE8C58F77C8EAA7980D266281CED ) ) game ( name "Emperor's New Groove, The (USA)" description "Emperor's New Groove, The (USA)" - rom ( name "Emperor's New Groove, The (USA).gbc" size 2097152 crc 6EBAD539 md5 E98B6A7BB91BB0A7E80E40985EEFB1D0 sha1 BA663289BD5D9D09BC8B9AC2C1D38293DCBA9C02 ) + rom ( name "Emperor's New Groove, The (USA).gbc" size 2097152 crc 6ebad539 sha1 BA663289BD5D9D09BC8B9AC2C1D38293DCBA9C02 ) ) game ( name "ESPN International Track & Field (USA)" description "ESPN International Track & Field (USA)" - rom ( name "ESPN International Track & Field (USA).gbc" size 1048576 crc 4005D541 md5 E1FCD22F776DC38D0BCFFA697794CB1E sha1 397D76C85859D0FA9B58B49F7EAE16F76AD45A17 ) + rom ( name "ESPN International Track & Field (USA).gbc" size 1048576 crc 4005d541 sha1 397D76C85859D0FA9B58B49F7EAE16F76AD45A17 ) ) game ( name "ESPN National Hockey Night (USA)" description "ESPN National Hockey Night (USA)" - rom ( name "ESPN National Hockey Night (USA).gbc" size 2097152 crc 600F61F9 md5 D34ABDA546C5F42E40A2EEB28D029DE4 sha1 3DDF8CF9AFE08C6079737A232EA071CEDAFEAA14 ) + rom ( name "ESPN National Hockey Night (USA).gbc" size 2097152 crc 600f61f9 sha1 3DDF8CF9AFE08C6079737A232EA071CEDAFEAA14 ) ) game ( name "Estpolis Denki - Yomigaeru Densetsu (Japan)" description "Estpolis Denki - Yomigaeru Densetsu (Japan)" - rom ( name "Estpolis Denki - Yomigaeru Densetsu (Japan).gbc" size 2097152 crc 54617416 md5 222AA591B387A4B897B61961EBEB9FDB sha1 DDE3B4FBBEF61B1E20ABC1D71408F59E6C90E79A ) + rom ( name "Estpolis Denki - Yomigaeru Densetsu (Japan).gbc" size 2097152 crc 54617416 sha1 DDE3B4FBBEF61B1E20ABC1D71408F59E6C90E79A ) ) game ( name "European Super League (Europe) (En,Fr,De,Es,It)" description "European Super League (Europe) (En,Fr,De,Es,It)" - rom ( name "European Super League (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 5A0B7C72 md5 0C80CBBAE8650152FBA0278350BD0BD4 sha1 2B403FC1C01AA82645960DF4FE7E93801EF735A3 ) + rom ( name "European Super League (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 5a0b7c72 sha1 2B403FC1C01AA82645960DF4FE7E93801EF735A3 ) ) game ( - name "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 2097152 crc DFD6A908 md5 5E1B4969A76E069ACF2622F7BB05D8D3 sha1 0841F55E18FE6E4A50DF826703DB22681169F2E7 ) + name "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Evel Knievel (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 2097152 crc dfd6a908 sha1 0841F55E18FE6E4A50DF826703DB22681169F2E7 ) ) game ( - name "Evel Knievel (USA)" - description "Evel Knievel (USA)" - rom ( name "Evel Knievel (USA).gbc" size 2097152 crc 51E951B5 md5 F9C554DFCE8383F16E554B61083F0922 sha1 24CAC6AB0151B33D2B1FD06EE01931802FB98267 ) + name "Evel Knievel (USA) (GB Compatible)" + description "Evel Knievel (USA) (GB Compatible)" + rom ( name "Evel Knievel (USA) (GB Compatible).gbc" size 2097152 crc 51e951b5 sha1 24CAC6AB0151B33D2B1FD06EE01931802FB98267 flags verified ) ) game ( name "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" description "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc CC777B98 md5 2C56BDCE336B543DE4653A493B870481 sha1 01E1BF3CEA7CCD7B8853727AC252ADDDC540FA2F ) + rom ( name "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc cc777b98 sha1 01E1BF3CEA7CCD7B8853727AC252ADDDC540FA2F ) ) game ( name "Extreme Sports with the Berenstain Bears (USA, Europe) (En,Fr,De,Es,It)" description "Extreme Sports with the Berenstain Bears (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Extreme Sports with the Berenstain Bears (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 5C0E7B44 md5 E20F2057C2143993C0F844097D0086D5 sha1 EE56328E88729F929DA717221D72826C872253C2 flags verified ) + rom ( name "Extreme Sports with the Berenstain Bears (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 5c0e7b44 sha1 EE56328E88729F929DA717221D72826C872253C2 flags verified ) ) game ( name "F-1 World Grand Prix (Europe) (En,Fr,De,Es)" description "F-1 World Grand Prix (Europe) (En,Fr,De,Es)" - rom ( name "F-1 World Grand Prix (Europe) (En,Fr,De,Es).gbc" size 2097152 crc 8D9A9182 md5 CFB6A98BEF18C56E466D27B885E20F8F sha1 16AA2E02E9B7F236F12A49C3224CA4CC89CDF98C flags verified ) + rom ( name "F-1 World Grand Prix (Europe) (En,Fr,De,Es).gbc" size 2097152 crc 8d9a9182 sha1 16AA2E02E9B7F236F12A49C3224CA4CC89CDF98C flags verified ) +) + +game ( + name "F-1 World Grand Prix (Europe) (Beta)" + description "F-1 World Grand Prix (Europe) (Beta)" + rom ( name "F-1 World Grand Prix (Europe) (Beta).gbc" size 2097152 crc d6496fe9 sha1 9285BB4FBAB8678B65CC8736F43E4EA3895C1CF4 flags verified ) ) game ( name "F-18 Thunder Strike (USA, Europe)" description "F-18 Thunder Strike (USA, Europe)" - rom ( name "F-18 Thunder Strike (USA, Europe).gbc" size 1048576 crc 410FA858 md5 58670204EC7B8791576E3C88BA7C1DDF sha1 530AECAE5B89E580BE8A8D4827BE95522D8319C4 flags verified ) + rom ( name "F-18 Thunder Strike (USA, Europe).gbc" size 1048576 crc 410fa858 sha1 530AECAE5B89E580BE8A8D4827BE95522D8319C4 flags verified ) ) game ( name "F.A. Premier League Stars 2001, The (Europe)" description "F.A. Premier League Stars 2001, The (Europe)" - rom ( name "F.A. Premier League Stars 2001, The (Europe).gbc" size 1048576 crc 5E3844FB md5 2650D134DD6DE865C8C8DBF5A5A385A4 sha1 9FEE426307EBFC373AB60A17F8F2F08D2FF8661C ) + rom ( name "F.A. Premier League Stars 2001, The (Europe).gbc" size 1048576 crc 5e3844fb sha1 9FEE426307EBFC373AB60A17F8F2F08D2FF8661C ) ) game ( name "F1 Championship Season 2000 (Europe) (En,Fr,De,Es,It)" description "F1 Championship Season 2000 (Europe) (En,Fr,De,Es,It)" - rom ( name "F1 Championship Season 2000 (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 5C10315E md5 4448C35BEBF32629E23F64C61CC50565 sha1 DC566028E0E86F32D99D5B0846D4B113525BE0A2 ) + rom ( name "F1 Championship Season 2000 (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 5c10315e sha1 DC566028E0E86F32D99D5B0846D4B113525BE0A2 ) +) + +game ( + name "F1 Championship Season 2000 (Brazil) (En,Fr,De,Es,It)" + description "F1 Championship Season 2000 (Brazil) (En,Fr,De,Es,It)" + rom ( name "F1 Championship Season 2000 (Brazil) (En,Fr,De,Es,It).gbc" size 2097152 crc f4f5ed18 sha1 4731A7442BBFF31C6D470B84938A3F148A4F1F6C flags verified ) +) + +game ( + name "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta) (February, 2000)" + description "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta) (February, 2000)" + rom ( name "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta) (February, 2000).gbc" size 4194304 crc e115ddb1 sha1 E9616A53AB9474C0BB85451FF19B62BED9E7F1A4 ) ) game ( name "F1 Racing Championship (Europe) (En,Fr,De,Es,It)" description "F1 Racing Championship (Europe) (En,Fr,De,Es,It)" - rom ( name "F1 Racing Championship (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc E115DDB1 md5 A7D2695B3DDC268389E36F916815F96D sha1 E9616A53AB9474C0BB85451FF19B62BED9E7F1A4 ) -) - -game ( - name "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta)" - description "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "F1 Racing Championship (Europe) (En,Fr,De,Es,It) (Beta).gbc" size 4194304 crc FC537719 md5 517BC18D9BB321349291B66415A371F4 sha1 3C10FE93521A604F1E312253328CD977236EAE07 ) + rom ( name "F1 Racing Championship (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc fc537719 sha1 3C10FE93521A604F1E312253328CD977236EAE07 ) ) game ( name "F1 World Grand Prix II for Game Boy Color (Europe) (En,Fr,De,Es)" description "F1 World Grand Prix II for Game Boy Color (Europe) (En,Fr,De,Es)" - rom ( name "F1 World Grand Prix II for Game Boy Color (Europe) (En,Fr,De,Es).gbc" size 1048576 crc EEF4A20B md5 5428271D0C9C5EB3DBF28078FAFE2031 sha1 CE114896DA10C8A0A14164CD9958922523491A59 ) + rom ( name "F1 World Grand Prix II for Game Boy Color (Europe) (En,Fr,De,Es).gbc" size 1048576 crc eef4a20b sha1 CE114896DA10C8A0A14164CD9958922523491A59 ) ) game ( name "F1 World Grand Prix II for Game Boy Color (Japan) (En,Ja)" description "F1 World Grand Prix II for Game Boy Color (Japan) (En,Ja)" - rom ( name "F1 World Grand Prix II for Game Boy Color (Japan) (En,Ja).gbc" size 1048576 crc 28453467 md5 BCEEB4182DA245DB9402DD55EEDBA53F sha1 B4D5E42C10C2BCD9204D282E9D91312F34FF768A ) + rom ( name "F1 World Grand Prix II for Game Boy Color (Japan) (En,Ja).gbc" size 1048576 crc 28453467 sha1 B4D5E42C10C2BCD9204D282E9D91312F34FF768A ) ) game ( name "F1 World Grand Prix II for Game Boy Color (USA) (En,Fr,De,Es)" description "F1 World Grand Prix II for Game Boy Color (USA) (En,Fr,De,Es)" - rom ( name "F1 World Grand Prix II for Game Boy Color (USA) (En,Fr,De,Es).gbc" size 1048576 crc 482E10C5 md5 69A6EBC942C7D0ECEF2E514989DEBDE6 sha1 C39E33FD9D5F06BC8F0F74EAFB45FA0C254F9C84 ) + rom ( name "F1 World Grand Prix II for Game Boy Color (USA) (En,Fr,De,Es).gbc" size 1048576 crc 482e10c5 sha1 C39E33FD9D5F06BC8F0F74EAFB45FA0C254F9C84 flags verified ) ) game ( - name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced)" - description "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced)" - rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced).gbc" size 1048576 crc B59A51C4 md5 0591D5637B4C9F304340D941B2AE9E7A sha1 A27B498C6170B4136D2CA8A75C3D529DD6C06639 flags verified ) + name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced) (GB Compatible)" + description "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b59a51c4 sha1 A27B498C6170B4136D2CA8A75C3D529DD6C06639 flags verified ) ) game ( - name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev A) (SGB Enhanced)" - description "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev A) (SGB Enhanced).gbc" size 1048576 crc C4D3628F md5 392E73A2ACD4310487E3BFABDD70293D sha1 D07B600CC9AF8CADC2581A6AC19AADEA79313D69 flags verified ) + name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Fairy Kitty no Kaiun Jiten - Yousei no Kuni no Uranai Shugyou (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c4d3628f sha1 D07B600CC9AF8CADC2581A6AC19AADEA79313D69 flags verified ) ) game ( name "Ferret Monogatari (Japan)" description "Ferret Monogatari (Japan)" - rom ( name "Ferret Monogatari (Japan).gbc" size 1048576 crc 8B742FB5 md5 2E3288D0D0B41D6FCC6BEC6676A78A3E sha1 9A35DBD3D474F838E21584C249232FF8905B14C0 ) + rom ( name "Ferret Monogatari (Japan).gbc" size 1048576 crc 8b742fb5 sha1 9A35DBD3D474F838E21584C249232FF8905B14C0 ) ) game ( - name "FIFA 2000 (USA, Europe) (SGB Enhanced)" - description "FIFA 2000 (USA, Europe) (SGB Enhanced)" - rom ( name "FIFA 2000 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc E6BC2E8C md5 128DC75244ECC2F74D1E50551D888127 sha1 C40DD26A6D600818ECA960BADE3AFA374A19BC12 flags verified ) + name "FGB (USA) (Proto)" + description "FGB (USA) (Proto)" + rom ( name "FGB (USA) (Proto).gbc" size 1048576 crc 800c74b6 sha1 DC41AA4E29AD4C0BA0BB1DEE1E90C7BFB9506A46 flags verified ) +) + +game ( + name "FIFA 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "FIFA 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "FIFA 2000 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e6bc2e8c sha1 C40DD26A6D600818ECA960BADE3AFA374A19BC12 flags verified ) ) game ( name "Fish Files, The (Europe) (En,Fr,De,Es,It)" description "Fish Files, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Fish Files, The (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc D6ABC1F8 md5 EDF021B521A496FE7AFC5E15949F5C80 sha1 07B071CBBCA12234D9EE9BFB0A3F3A47AA2B0BFA ) + rom ( name "Fish Files, The (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc d6abc1f8 sha1 07B071CBBCA12234D9EE9BFB0A3F3A47AA2B0BFA ) ) game ( - name "Fix & Foxi - Episode 1 Lupo (Europe) (En,Fr,De)" - description "Fix & Foxi - Episode 1 Lupo (Europe) (En,Fr,De)" - rom ( name "Fix & Foxi - Episode 1 Lupo (Europe) (En,Fr,De).gbc" size 1048576 crc 5DFC61E8 md5 9F77ADBB0A6AF7BD85D21A8EF9FDEA49 sha1 6D14BF255EB042E7185DA32137F679F4E2C24CE5 ) + name "Fix & Foxi - Episode 1 - Lupo (Europe) (En,Fr,De)" + description "Fix & Foxi - Episode 1 - Lupo (Europe) (En,Fr,De)" + rom ( name "Fix & Foxi - Episode 1 - Lupo (Europe) (En,Fr,De).gbc" size 1048576 crc 5dfc61e8 sha1 6D14BF255EB042E7185DA32137F679F4E2C24CE5 ) ) game ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It) (Beta)" description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It) (Beta).gbc" size 1048576 crc ECCCD908 md5 D5E1AF0598A8DB7B93F57EB2909EDC17 sha1 80EC102F3CF45602C6FACFFCDD44232650897DAB ) + rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It) (Beta).gbc" size 1048576 crc ecccd908 sha1 80EC102F3CF45602C6FACFFCDD44232650897DAB ) ) game ( name "Flintstones, The - Burgertime in Bedrock (USA)" description "Flintstones, The - Burgertime in Bedrock (USA)" - rom ( name "Flintstones, The - Burgertime in Bedrock (USA).gbc" size 1048576 crc 14D8CC5D md5 50E6D9D88450932743161B7512838CCC sha1 065851358F6720D4926FAA42B015DA68CAFA6C28 ) + rom ( name "Flintstones, The - Burgertime in Bedrock (USA).gbc" size 1048576 crc 14d8cc5d sha1 065851358F6720D4926FAA42B015DA68CAFA6C28 ) ) game ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" - serial "CGB-BFSP-EUR" - rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc A5B09726 md5 99825E86250AB53B5EA8AC702930919D sha1 2F7FB1AFEDD6C9657715B45397DC5492E40DFE45 flags verified ) + rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2F7FB1AFEDD6C9657715B45397DC5492E40DFE45 flags verified ) ) game ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 08B9E4AA md5 1DA7187971155F0AED9FFEA798F6E2A6 sha1 3D538B78EF5F1238F47531C069921056B00E33B3 ) + rom ( name "Flipper & Lopaka (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 08b9e4aa sha1 3D538B78EF5F1238F47531C069921056B00E33B3 ) +) + +game ( + name "Floracy (Europe) (Proto) (10.10.2000)" + description "Floracy (Europe) (Proto) (10.10.2000)" + rom ( name "Floracy (Europe) (Proto) (10.10.2000).gbc" size 524288 crc d760ccff sha1 BB24EA021D873990D2E381D711376BA1D300B81F flags verified ) ) game ( name "Force 21 (USA) (En,Fr,De)" description "Force 21 (USA) (En,Fr,De)" - rom ( name "Force 21 (USA) (En,Fr,De).gbc" size 1048576 crc 2DCD0A0A md5 2A447279016F60776B5C0F515B5B97F5 sha1 A1A912851BF265D6228DC807C58339CD51EC9D44 ) + rom ( name "Force 21 (USA) (En,Fr,De).gbc" size 1048576 crc 2dcd0a0a sha1 A1A912851BF265D6228DC807C58339CD51EC9D44 ) ) game ( name "Formula One 2000 (USA)" description "Formula One 2000 (USA)" - rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703C057F md5 3E7736B358B7750BB451D505816D8B11 sha1 7A38195842E536581FDCEA42E4EBE50967581736 ) + rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7A38195842E536581FDCEA42E4EBE50967581736 ) ) game ( name "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" description "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt).gbc" size 1048576 crc 06C8E50A md5 21AE960E6C5A42B498B00FA6F635B1E1 sha1 A5B2D892568BC44424577F0A62228D05AA355EFD flags verified ) + rom ( name "Fort Boyard (Europe) (En,Fr,De,Es,It,Nl,Pt).gbc" size 1048576 crc 06c8e50a sha1 A5B2D892568BC44424577F0A62228D05AA355EFD flags verified ) ) game ( name "Freestyle Scooter (Europe)" description "Freestyle Scooter (Europe)" - rom ( name "Freestyle Scooter (Europe).gbc" size 1048576 crc EE79117D md5 0155BB1D60A477EEEB148033210EECF3 sha1 CF6AE174584BBFB5AE30478841114443ADC00245 ) + rom ( name "Freestyle Scooter (Europe).gbc" size 1048576 crc ee79117d sha1 CF6AE174584BBFB5AE30478841114443ADC00245 flags verified ) ) game ( - name "Frogger (USA) (Rev B)" - description "Frogger (USA) (Rev B)" - rom ( name "Frogger (USA) (Rev B).gbc" size 1048576 crc D9A22E5D md5 7F1830171EEC29AC72AE976D4DFDFC65 sha1 CF4801C7F82519344A50A25E35B1F5C7EE45C9A6 flags verified ) + name "Frogger (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Frogger (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Frogger (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 524288 crc b6bf0672 sha1 538D2FA68E2E877A80BBDF4D58B2B4DCF051C17C flags verified ) ) game ( - name "Frogger (USA) (Rev A)" - description "Frogger (USA) (Rev A)" - rom ( name "Frogger (USA) (Rev A).gbc" size 1048576 crc BA907064 md5 547C0D3FDB1C6EF7ABC7DFF06C457A35 sha1 DB3D21977C17A505936D1E2FC3626A0B43ADDF16 ) + name "Frogger (USA) (GB Compatible)" + description "Frogger (USA) (GB Compatible)" + rom ( name "Frogger (USA) (GB Compatible).gbc" size 1048576 crc af46ea77 sha1 5B7C097A12A8408FD20B81289E03AD9EA2FD2691 ) ) game ( - name "Frogger (Europe) (En,Fr,De,Es,It,Nl)" - description "Frogger (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Frogger (Europe) (En,Fr,De,Es,It,Nl).gbc" size 524288 crc B6BF0672 md5 D5EBDBEDA4156B34E3C0F01D55A4221C sha1 538D2FA68E2E877A80BBDF4D58B2B4DCF051C17C flags verified ) + name "Frogger (USA) (Rev 2) (GB Compatible)" + description "Frogger (USA) (Rev 2) (GB Compatible)" + rom ( name "Frogger (USA) (Rev 2) (GB Compatible).gbc" size 1048576 crc d9a22e5d sha1 CF4801C7F82519344A50A25E35B1F5C7EE45C9A6 flags verified ) ) game ( - name "Frogger (USA)" - description "Frogger (USA)" - rom ( name "Frogger (USA).gbc" size 1048576 crc AF46EA77 md5 D94E22B4C08AB3C7B1929F5490ADCBF2 sha1 5B7C097A12A8408FD20B81289E03AD9EA2FD2691 ) + name "Frogger (USA) (Rev 1) (GB Compatible)" + description "Frogger (USA) (Rev 1) (GB Compatible)" + rom ( name "Frogger (USA) (Rev 1) (GB Compatible).gbc" size 1048576 crc ba907064 sha1 DB3D21977C17A505936D1E2FC3626A0B43ADDF16 flags verified ) ) game ( name "Frogger 2 (USA)" description "Frogger 2 (USA)" - rom ( name "Frogger 2 (USA).gbc" size 1048576 crc 6A2666AA md5 06B0D6B88E54337F3F5C7BBEA373F237 sha1 566E0AFB3A6F25342399A3E39F3FBCACEF68EB72 ) + rom ( name "Frogger 2 (USA).gbc" size 1048576 crc 6a2666aa sha1 566E0AFB3A6F25342399A3E39F3FBCACEF68EB72 ) ) game ( - name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced)" - description "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced)" - rom ( name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced).gbc" size 4194304 crc A7317BB8 md5 B883323E9AE3C85548169BABE3F9B4F0 sha1 7FA5FBB94390876DEE807216C2097CDB42510EFE flags verified ) + name "Frogger 2 (USA) (Rev 1)" + description "Frogger 2 (USA) (Rev 1)" + rom ( name "Frogger 2 (USA) (Rev 1).gbc" size 1048576 crc e3227b7d sha1 0D5028CA6FCC10DF46D11CD4B56E5ADD1DC5E63E flags verified ) ) game ( - name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced)" - description "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced)" - rom ( name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced).gbc" size 4194304 crc C693AA37 md5 DA5586315CA857071D557A8FDE26C108 sha1 459F1AE41F6C5C6464745A23EA42BBBA5385A83B flags verified ) + name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced) (GB Compatible)" + description "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc a7317bb8 sha1 7FA5FBB94390876DEE807216C2097CDB42510EFE flags verified ) ) game ( - name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev A) (SGB Enhanced)" - description "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev A) (SGB Enhanced)" - rom ( name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev A) (SGB Enhanced).gbc" size 4194304 crc A4DDE805 md5 5F43DC79250321F235A1DDC422A2D58D sha1 53DA28B16A4BF0EFAB1F65C21F7931CE4948865B flags verified ) + name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced) (GB Compatible)" + description "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc c693aa37 sha1 459F1AE41F6C5C6464745A23EA42BBBA5385A83B flags verified ) +) + +game ( + name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "From TV Animation One Piece - Yume no Luffy Kaizokudan Tanjou! (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc a4dde805 sha1 53DA28B16A4BF0EFAB1F65C21F7931CE4948865B flags verified ) ) game ( name "Front Line - The Next Mission (Japan)" description "Front Line - The Next Mission (Japan)" - rom ( name "Front Line - The Next Mission (Japan).gbc" size 1048576 crc F48E1643 md5 8C3BCD751EBC34ABC02E666D8FF057C4 sha1 7456B221F95A64F36A70D024477032A4B6615948 ) + rom ( name "Front Line - The Next Mission (Japan).gbc" size 1048576 crc f48e1643 sha1 7456B221F95A64F36A70D024477032A4B6615948 ) ) game ( name "Front Row (Japan)" description "Front Row (Japan)" - rom ( name "Front Row (Japan).gbc" size 1048576 crc 6EEA9243 md5 579291571DAC53916FD552CCEA5B0BB9 sha1 64C8A9459D7C80E297774DAB7775B5EDF59432CC ) + rom ( name "Front Row (Japan).gbc" size 1048576 crc 6eea9243 sha1 64C8A9459D7C80E297774DAB7775B5EDF59432CC ) ) game ( name "Full Time Soccer (Europe) (Unl)" description "Full Time Soccer (Europe) (Unl)" - rom ( name "Full Time Soccer (Europe) (Unl).gbc" size 262144 crc B99BEDA2 md5 991957A67A63F1E54BF34A3715402CA5 sha1 A2B1268DF08B583D033999B894638DADF32E37F4 flags verified ) + rom ( name "Full Time Soccer (Europe) (Unl).gbc" size 262144 crc b99beda2 sha1 A2B1268DF08B583D033999B894638DADF32E37F4 flags verified ) ) game ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl)" description "Full Time Soccer & Hang Time Basketball (Europe) (Unl)" - rom ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl).gbc" size 524288 crc 0634C196 md5 EC1C9035BE5C529795048546B1F35CA5 sha1 AEFB746984B3450B90BBFAA5DE21A252685DDABB flags verified ) + rom ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl).gbc" size 524288 crc 0634c196 sha1 AEFB746984B3450B90BBFAA5DE21A252685DDABB flags verified ) ) game ( - name "Fushigi no Dungeon - Fuurai no Shiren GB2 - Sabaku no Majou (Japan)" - description "Fushigi no Dungeon - Fuurai no Shiren GB2 - Sabaku no Majou (Japan)" - rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB2 - Sabaku no Majou (Japan).gbc" size 4194304 crc 2C97E90F md5 9E3D4FF0BA3D6DEEC5080F6DBED4FEF8 sha1 5264F6D0C4F12C9144DE1D12FDDADBADD82B3E33 ) + name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan)" + description "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan)" + rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan).gbc" size 4194304 crc 2c97e90f sha1 5264F6D0C4F12C9144DE1D12FDDADBADD82B3E33 flags verified ) ) game ( name "Gaiamaster Duel - Card Attackers (Japan)" description "Gaiamaster Duel - Card Attackers (Japan)" - rom ( name "Gaiamaster Duel - Card Attackers (Japan).gbc" size 2097152 crc 78206460 md5 6BB272F9361D57D9796CF2BB3615BF1A sha1 26601CD806C588B232EA1275B2BCB434CCD81E6D ) + rom ( name "Gaiamaster Duel - Card Attackers (Japan).gbc" size 2097152 crc 78206460 sha1 26601CD806C588B232EA1275B2BCB434CCD81E6D ) ) game ( - name "Gakkyuu Ou Yamazaki (Japan) (Rev A)" - description "Gakkyuu Ou Yamazaki (Japan) (Rev A)" - rom ( name "Gakkyuu Ou Yamazaki (Japan) (Rev A).gbc" size 1048576 crc EF2CFD99 md5 52A9D2992A270EE3184553CAF4FDBA2B sha1 3A2718EFA3D1CAC7345FBBCDDB7C3F666FC6C70C flags verified ) + name "Gakkyuu Ou Yamazaki (Japan) (Rev 1) (GB Compatible)" + description "Gakkyuu Ou Yamazaki (Japan) (Rev 1) (GB Compatible)" + rom ( name "Gakkyuu Ou Yamazaki (Japan) (Rev 1) (GB Compatible).gbc" size 1048576 crc ef2cfd99 sha1 3A2718EFA3D1CAC7345FBBCDDB7C3F666FC6C70C flags verified ) ) game ( name "Galaga - Destination Earth (USA)" description "Galaga - Destination Earth (USA)" - rom ( name "Galaga - Destination Earth (USA).gbc" size 1048576 crc E3C4ABC6 md5 17DAE7EC46263600C54687D78B582E5E sha1 E2D16612C7CBEB3DA07BE696D154E366CBB3FCDD ) + rom ( name "Galaga - Destination Earth (USA).gbc" size 1048576 crc e3c4abc6 sha1 E2D16612C7CBEB3DA07BE696D154E366CBB3FCDD ) ) game ( name "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan)" description "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan)" - rom ( name "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan).gbc" size 1048576 crc 28356950 md5 3B9116DCB4A3B4CC943F75B8B7E88212 sha1 8BA0973997BDAEECDF23C45A4FB7E18E06132DFB ) + rom ( name "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan).gbc" size 1048576 crc 28356950 sha1 8BA0973997BDAEECDF23C45A4FB7E18E06132DFB ) ) game ( - name "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced)" - description "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced)" - rom ( name "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 969C8961 md5 CBF4A5B2FF566554B014118E3D0E3E9A sha1 CE81D3260E8C5E1DD241CAF6DE315EB3E63DBC15 flags verified ) + name "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan) (Rev 1)" + description "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan) (Rev 1)" + rom ( name "Gambler Densetsu Tetsuya - Shinjuku Tenun Hen (Japan) (Rev 1).gbc" size 1048576 crc 91739def sha1 B62F8E56B995874C0E1A2533DF5A37F6996DF12E flags verified ) ) game ( - name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced)" - description "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced)" - rom ( name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 1AC625DA md5 F1BB0127347994B46258ADBDA0DC0B16 sha1 64CCB3B41715080A9AA13970678AA9047FC7A9FD flags verified ) + name "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Game & Watch Gallery 2 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 969c8961 sha1 CE81D3260E8C5E1DD241CAF6DE315EB3E63DBC15 flags verified ) ) game ( - name "Game Boy Color (USA) (Promo)" - description "Game Boy Color (USA) (Promo)" - rom ( name "Game Boy Color (USA) (Promo).gbc" size 524288 crc F5E9AA8C md5 0B4F167D39212F40F793FE1EC19421D7 sha1 BCBC9EDE4A06E52E5DEA809E20E0B34901B6AE91 flags verified ) + name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Game & Watch Gallery 3 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1ac625da sha1 64CCB3B41715080A9AA13970678AA9047FC7A9FD flags verified ) ) game ( - name "Game Boy Gallery 3 (Australia) (SGB Enhanced)" - description "Game Boy Gallery 3 (Australia) (SGB Enhanced)" - rom ( name "Game Boy Gallery 3 (Australia) (SGB Enhanced).gbc" size 1048576 crc 6935FEA1 md5 809EC52E50279A174A4908E3EA46DCF6 sha1 FDE6A70E7AD6A3A116D918435F7EFBC1FD95B4CC flags verified ) + name "Game Boy Gallery 3 (Australia) (SGB Enhanced) (GB Compatible)" + description "Game Boy Gallery 3 (Australia) (SGB Enhanced) (GB Compatible)" + rom ( name "Game Boy Gallery 3 (Australia) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6935fea1 sha1 FDE6A70E7AD6A3A116D918435F7EFBC1FD95B4CC flags verified ) ) game ( - name "Game Boy Gallery 3 (Japan) (SGB Enhanced)" - description "Game Boy Gallery 3 (Japan) (SGB Enhanced)" - rom ( name "Game Boy Gallery 3 (Japan) (SGB Enhanced).gbc" size 1048576 crc 149F807E md5 1C7355ED58DAF1EBCCEEA71BA5CBB694 sha1 18C3E0A015FA79C8694B8554E3C46FD67F034C71 flags verified ) + name "Game Boy Gallery 3 (Japan) (SGB Enhanced) (GB Compatible)" + description "Game Boy Gallery 3 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Game Boy Gallery 3 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 149f807e sha1 18C3E0A015FA79C8694B8554E3C46FD67F034C71 flags verified ) ) game ( - name "Game Boy Gallery 4 (Australia) (SGB Enhanced)" - description "Game Boy Gallery 4 (Australia) (SGB Enhanced)" - rom ( name "Game Boy Gallery 4 (Australia) (SGB Enhanced).gbc" size 1048576 crc 2549FDDE md5 FCA034C2494A20C8A75DD1FF0BCC7545 sha1 FB8B98AE16F79FD70D2C0F0911DFCB2FDF1E7149 flags verified ) + name "Game Boy Gallery 4 (Australia) (SGB Enhanced) (GB Compatible)" + description "Game Boy Gallery 4 (Australia) (SGB Enhanced) (GB Compatible)" + rom ( name "Game Boy Gallery 4 (Australia) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2549fdde sha1 FB8B98AE16F79FD70D2C0F0911DFCB2FDF1E7149 flags verified ) ) game ( - name "Game Boy Wars 2 (Japan) (SGB Enhanced)" - description "Game Boy Wars 2 (Japan) (SGB Enhanced)" - rom ( name "Game Boy Wars 2 (Japan) (SGB Enhanced).gbc" size 524288 crc 559EDB5E md5 3833C21CBB63605FC365B5E3AA005994 sha1 9E953E2102902D19F5A4B1C879285C0583A9AC5A ) + name "Game Boy Wars 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Game Boy Wars 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Game Boy Wars 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c69dc37b sha1 DB511650FDC9A6C130ADD7EADA9562B6443B565D flags verified ) ) game ( name "Game Boy Wars 3 (Japan)" description "Game Boy Wars 3 (Japan)" - rom ( name "Game Boy Wars 3 (Japan).gbc" size 1048576 crc 30C26262 md5 748FA9419B35C0E8E43509457AAA1EFA sha1 61E08F96261B5F85C65C70DB5464B4298F9F2CF8 flags verified ) + rom ( name "Game Boy Wars 3 (Japan).gbc" size 1048576 crc 30c26262 sha1 61E08F96261B5F85C65C70DB5464B4298F9F2CF8 flags verified ) ) game ( - name "Game Conveni 21 (Japan)" - description "Game Conveni 21 (Japan)" - rom ( name "Game Conveni 21 (Japan).gbc" size 1048576 crc 994314B3 md5 76A95FEE3D90722FD935C7658512F5CC sha1 6803617ABC46DB83DBEC08D10E03B9F9297F260E ) + name "Game Conveni 21 (Japan) (GB Compatible)" + description "Game Conveni 21 (Japan) (GB Compatible)" + rom ( name "Game Conveni 21 (Japan) (GB Compatible).gbc" size 1048576 crc 994314b3 sha1 6803617ABC46DB83DBEC08D10E03B9F9297F260E flags verified ) +) + +game ( + name "GameBoy Color (World) (Promo)" + description "GameBoy Color (World) (Promo)" + rom ( name "GameBoy Color (World) (Promo).gbc" size 524288 crc f5e9aa8c sha1 BCBC9EDE4A06E52E5DEA809E20E0B34901B6AE91 flags verified ) ) game ( name "Games Frenzy (Europe) (En,Fr,De)" description "Games Frenzy (Europe) (En,Fr,De)" - rom ( name "Games Frenzy (Europe) (En,Fr,De).gbc" size 1048576 crc 308A4CCB md5 3A9E8EAFABF705600D6C6C6EB832A56D sha1 FD3C38D61B723E12614FA5E0B809D083827B9AE5 ) + rom ( name "Games Frenzy (Europe) (En,Fr,De).gbc" size 1048576 crc 308a4ccb sha1 FD3C38D61B723E12614FA5E0B809D083827B9AE5 ) ) game ( name "GameShark Online (USA) (Unl)" description "GameShark Online (USA) (Unl)" - rom ( name "GameShark Online (USA) (Unl).gbc" size 81920 crc C37D21D9 md5 F7DB0C6343B12FBEF11605077AF5D9A2 sha1 22F00E604ACB827A48D4C9E109BA622F59A9D0A9 ) + rom ( name "GameShark Online (USA) (Unl).gbc" size 81920 crc c37d21d9 sha1 22F00E604ACB827A48D4C9E109BA622F59A9D0A9 ) ) game ( - name "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced)" - description "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced)" - rom ( name "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced).gbc" size 2097152 crc 73311CFA md5 7C700360A46F54796802CA7C7BF499C5 sha1 4BC3928F3528A2C566B09613E538253DD128864C flags verified ) + name "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced) (GB Compatible)" + description "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Ganbare Goemon - Mononoke Douchuu Tobidase Nabebugyou! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 73311cfa sha1 4BC3928F3528A2C566B09613E538253DD128864C flags verified ) ) game ( name "Ganbare Goemon - Seikuushi Dynamites Arawaru!! (Japan)" description "Ganbare Goemon - Seikuushi Dynamites Arawaru!! (Japan)" - rom ( name "Ganbare Goemon - Seikuushi Dynamites Arawaru!! (Japan).gbc" size 1048576 crc 2EA8D9D4 md5 B1E72BA9C23587D002BF1059504AD6DB sha1 FC44DD6AC4A91AB32DC7096A364406433B48B7D8 ) + rom ( name "Ganbare Goemon - Seikuushi Dynamites Arawaru!! (Japan).gbc" size 1048576 crc 2ea8d9d4 sha1 FC44DD6AC4A91AB32DC7096A364406433B48B7D8 ) ) game ( - name "Ganbare Goemon - Tengutou no Gyakushuu (Japan)" - description "Ganbare Goemon - Tengutou no Gyakushuu (Japan)" - rom ( name "Ganbare Goemon - Tengutou no Gyakushuu (Japan).gbc" size 1048576 crc D829EB2F md5 18B2C4989209373C0CBA9BC58075B2FD sha1 337CBCBD185A74C6FD5B10823FDA3DCF8DCA30E4 flags verified ) + name "Ganbare Goemon - Tengutou no Gyakushuu (Japan) (GB Compatible)" + description "Ganbare Goemon - Tengutou no Gyakushuu (Japan) (GB Compatible)" + rom ( name "Ganbare Goemon - Tengutou no Gyakushuu (Japan) (GB Compatible).gbc" size 1048576 crc d829eb2f sha1 337CBCBD185A74C6FD5B10823FDA3DCF8DCA30E4 flags verified ) ) game ( name "Ganbare! Nippon! Olympic 2000 (Japan)" description "Ganbare! Nippon! Olympic 2000 (Japan)" - rom ( name "Ganbare! Nippon! Olympic 2000 (Japan).gbc" size 1048576 crc FFD919A7 md5 8707AD4AD9645D2DCFB33821697173A6 sha1 5ABAAC9C4CB3D06E20FCB4C9985A6C4B52E62871 flags verified ) + rom ( name "Ganbare! Nippon! Olympic 2000 (Japan).gbc" size 1048576 crc ffd919a7 sha1 5ABAAC9C4CB3D06E20FCB4C9985A6C4B52E62871 flags verified ) ) game ( name "GB Harobots (Japan)" description "GB Harobots (Japan)" - rom ( name "GB Harobots (Japan).gbc" size 2097152 crc 1C0368FA md5 07DE70BD0E839DD1D4BE2670B2E1D33F sha1 0FC2198938FCD259C525591F74C8AAE4B048F298 ) + rom ( name "GB Harobots (Japan).gbc" size 2097152 crc 1c0368fa sha1 0FC2198938FCD259C525591F74C8AAE4B048F298 flags verified ) ) game ( name "GB Karan Koron Gakuen - Hanafuda Mahjong (Japan)" description "GB Karan Koron Gakuen - Hanafuda Mahjong (Japan)" - rom ( name "GB Karan Koron Gakuen - Hanafuda Mahjong (Japan).gbc" size 2097152 crc AABA1EA4 md5 3513F4DBF6D283121C6A070F3B92F9DF sha1 8E84F233279C543799663BD7C62B4F2FB84E5DFF ) + rom ( name "GB Karan Koron Gakuen - Hanafuda Mahjong (Japan).gbc" size 2097152 crc aaba1ea4 sha1 8E84F233279C543799663BD7C62B4F2FB84E5DFF ) ) game ( - name "GB Memory Multi Menu (Japan) (NP, SGB Enhanced)" - description "GB Memory Multi Menu (Japan) (NP, SGB Enhanced)" - rom ( name "GB Memory Multi Menu (Japan) (NP, SGB Enhanced).gbc" size 131072 crc EC823CC1 md5 187E24E1A76EEDE2853755760DEE5108 sha1 0781EAECB7FD25C068E396B5EB02C6231BAF6EA3 ) + name "GB Memory Multi Menu (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "GB Memory Multi Menu (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "GB Memory Multi Menu (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 131072 crc ec823cc1 sha1 0781EAECB7FD25C068E396B5EB02C6231BAF6EA3 ) ) game ( name "Geheimnis der Happy Hippo-Insel, Das (Germany)" description "Geheimnis der Happy Hippo-Insel, Das (Germany)" - rom ( name "Geheimnis der Happy Hippo-Insel, Das (Germany).gbc" size 1048576 crc 25B480C3 md5 3BC2DB27BAFF012307501C31D49922AC sha1 F2AB35743F477A98007665F2A5686AB4DA2B9049 flags verified ) + rom ( name "Geheimnis der Happy Hippo-Insel, Das (Germany).gbc" size 1048576 crc 25b480c3 sha1 F2AB35743F477A98007665F2A5686AB4DA2B9049 flags verified ) +) + +game ( + name "Gekido (Europe) (Proto)" + description "Gekido (Europe) (Proto)" + rom ( name "Gekido (Europe) (Proto).gbc" size 262144 crc 4869c684 sha1 41B65A1399F92162F06423CB27D6EE25D3FCFA8D flags verified ) ) game ( name "Gekisou Dangun Racer - Onsoku Buster Dangun Dan (Japan)" description "Gekisou Dangun Racer - Onsoku Buster Dangun Dan (Japan)" - rom ( name "Gekisou Dangun Racer - Onsoku Buster Dangun Dan (Japan).gbc" size 2097152 crc 06FCCEFC md5 19DFB14A0D31742F02BFA101D5054169 sha1 0B9C99A614D31CC0CB4047DEEEE6DE76B64A5F8B ) + rom ( name "Gekisou Dangun Racer - Onsoku Buster Dangun Dan (Japan).gbc" size 2097152 crc 06fccefc sha1 0B9C99A614D31CC0CB4047DEEEE6DE76B64A5F8B flags verified ) ) game ( - name "Gem Gem Monster (Japan) (SGB Enhanced)" - description "Gem Gem Monster (Japan) (SGB Enhanced)" - rom ( name "Gem Gem Monster (Japan) (SGB Enhanced).gbc" size 1048576 crc DE7505C0 md5 286B53AA6F97E97A8D2C26801C8B2E91 sha1 8B1396CF9DBC77246B3443810282B8B9BCB65A67 ) + name "Gem Gem Monster (Japan) (SGB Enhanced) (GB Compatible)" + description "Gem Gem Monster (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Gem Gem Monster (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc de7505c0 sha1 8B1396CF9DBC77246B3443810282B8B9BCB65A67 ) ) game ( name "Gensou Maden Saiyuuki - Sabaku no Shijin (Japan)" description "Gensou Maden Saiyuuki - Sabaku no Shijin (Japan)" - rom ( name "Gensou Maden Saiyuuki - Sabaku no Shijin (Japan).gbc" size 1048576 crc 918A40E7 md5 09F75CC7DC00A7AE8AE4B586092FE045 sha1 9226B76621495AE0FC893C0A835973605414638F ) + rom ( name "Gensou Maden Saiyuuki - Sabaku no Shijin (Japan).gbc" size 1048576 crc 918a40e7 sha1 9226B76621495AE0FC893C0A835973605414638F flags verified ) ) game ( - name "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced)" - description "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced)" - rom ( name "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc 9EBDB6C6 md5 84973A134E9E4245D8138AC11807CA3F sha1 8A04A1C6374DF1D6393A8AF395422B63AAD2E3D1 flags verified ) + name "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Get Chuu Club - Minna no Konchuu Daizukan (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9ebdb6c6 sha1 8A04A1C6374DF1D6393A8AF395422B63AAD2E3D1 flags verified ) ) game ( - name "Gex - Enter the Gecko (USA, Europe)" - description "Gex - Enter the Gecko (USA, Europe)" - rom ( name "Gex - Enter the Gecko (USA, Europe).gbc" size 1048576 crc DCCC7514 md5 F0462EBA75D879C40668E20D1DBDB612 sha1 A05A530B3272634C8D3FEDB6FD6EAF8B00B5CF9C flags verified ) + name "Gex - Enter the Gecko (USA, Europe) (GB Compatible)" + description "Gex - Enter the Gecko (USA, Europe) (GB Compatible)" + rom ( name "Gex - Enter the Gecko (USA, Europe) (GB Compatible).gbc" size 1048576 crc dccc7514 sha1 A05A530B3272634C8D3FEDB6FD6EAF8B00B5CF9C flags verified ) ) game ( name "Gex 3 - Deep Cover Gecko (Europe) (En,Fr,De,Es,It)" description "Gex 3 - Deep Cover Gecko (Europe) (En,Fr,De,Es,It)" - rom ( name "Gex 3 - Deep Cover Gecko (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 025F305D md5 89D563BCC7B6F2F087CDAFA8A78A8AA7 sha1 176EC4347CE08B15214E68FCEC39C9C4C57AD773 ) + rom ( name "Gex 3 - Deep Cover Gecko (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 025f305d sha1 176EC4347CE08B15214E68FCEC39C9C4C57AD773 ) ) game ( name "Gex 3 - Deep Pocket Gecko (USA)" description "Gex 3 - Deep Pocket Gecko (USA)" - rom ( name "Gex 3 - Deep Pocket Gecko (USA).gbc" size 2097152 crc 85A98C7D md5 91EB6DB42E92E2DF05CC2B40F0DBC2F0 sha1 0DA71536A3E92DD537C7067EC1014A262DBC3837 ) + rom ( name "Gex 3 - Deep Pocket Gecko (USA).gbc" size 2097152 crc 85a98c7d sha1 0DA71536A3E92DD537C7067EC1014A262DBC3837 ) ) game ( - name "Ghosts'n Goblins (USA, Europe)" - description "Ghosts'n Goblins (USA, Europe)" - rom ( name "Ghosts'n Goblins (USA, Europe).gbc" size 1048576 crc AE024C23 md5 9B846E9A4EB6B80CDBC8E6C82F2B9E9E sha1 AF9E69FC65FBE0D4FABE145472C1340E9F541A7B flags verified ) + name "Ghosts'n Goblins (USA, Europe) (GB Compatible)" + description "Ghosts'n Goblins (USA, Europe) (GB Compatible)" + rom ( name "Ghosts'n Goblins (USA, Europe) (GB Compatible).gbc" size 1048576 crc ae024c23 sha1 AF9E69FC65FBE0D4FABE145472C1340E9F541A7B flags verified ) ) game ( name "Gift (Europe)" description "Gift (Europe)" - rom ( name "Gift (Europe).gbc" size 1048576 crc 1B0034E8 md5 75B4FAFFD8E9C0277B911D1D0E6ECE6A sha1 A8C6B7CA2E4ED75CF037625B603CFC8AB67C0AEF flags verified ) + rom ( name "Gift (Europe).gbc" size 1048576 crc 1b0034e8 sha1 A8C6B7CA2E4ED75CF037625B603CFC8AB67C0AEF flags verified ) ) game ( name "Gift (Europe) (Sample)" description "Gift (Europe) (Sample)" - rom ( name "Gift (Europe) (Sample).gbc" size 1048576 crc D8E357BA md5 BCF3E2445346B4EF40C1278B4B46408C sha1 A9E2D5E1FD5D3993ACB87888D287612A09ECAA8B ) + rom ( name "Gift (Europe) (Sample).gbc" size 1048576 crc d8e357ba sha1 A9E2D5E1FD5D3993ACB87888D287612A09ECAA8B ) ) game ( name "Gifty (Germany) (En)" description "Gifty (Germany) (En)" - rom ( name "Gifty (Germany) (En).gbc" size 1048576 crc B97A8CB8 md5 D1B2C36DEF4B361645EAE44F6A0C53EA sha1 F92997128F6BCE74F5E5C0787F98FA3D2B6C3133 flags verified ) + rom ( name "Gifty (Germany) (En).gbc" size 1048576 crc b97a8cb8 sha1 F92997128F6BCE74F5E5C0787F98FA3D2B6C3133 flags verified ) ) game ( - name "Glocal Hexcite (Japan) (SGB Enhanced)" - description "Glocal Hexcite (Japan) (SGB Enhanced)" - rom ( name "Glocal Hexcite (Japan) (SGB Enhanced).gbc" size 1048576 crc F1908391 md5 E019B0790EF6E7B2DD39AFDBEC8BA651 sha1 7D13220593C8D89AF1B4CAE955CAACFF7DF3817A ) + name "Glocal Hexcite (Japan) (SGB Enhanced) (GB Compatible)" + description "Glocal Hexcite (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Glocal Hexcite (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f1908391 sha1 7D13220593C8D89AF1B4CAE955CAACFF7DF3817A ) ) game ( name "Gobs of Games (USA) (En,Fr,De)" description "Gobs of Games (USA) (En,Fr,De)" - rom ( name "Gobs of Games (USA) (En,Fr,De).gbc" size 1048576 crc 2E61C391 md5 BA1D07A8282202081AF5AD985F0C31AD sha1 89695361CCBCA372662F6634678A40EA676076A7 ) + rom ( name "Gobs of Games (USA) (En,Fr,De).gbc" size 1048576 crc 2e61c391 sha1 89695361CCBCA372662F6634678A40EA676076A7 ) ) game ( - name "Godzilla - The Series (Europe) (En,Fr,De)" - description "Godzilla - The Series (Europe) (En,Fr,De)" - rom ( name "Godzilla - The Series (Europe) (En,Fr,De).gbc" size 1048576 crc 2A073369 md5 149073AFD1CF8AE83783143A166592F7 sha1 05942143AC24489FC61AD9F8385E4D02E216804D ) + name "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" + description "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" + rom ( name "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc 2a073369 sha1 05942143AC24489FC61AD9F8385E4D02E216804D flags verified ) ) game ( - name "Godzilla - The Series (USA) (En,Fr,De)" - description "Godzilla - The Series (USA) (En,Fr,De)" - rom ( name "Godzilla - The Series (USA) (En,Fr,De).gbc" size 1048576 crc DD716EFE md5 7B4345DAF8EBDA416A84C5932BF817EC sha1 56EC20CF1F2613BC2DCDF88D27E8AF7378F7D334 ) + name "Godzilla - The Series (USA) (En,Fr,De) (GB Compatible)" + description "Godzilla - The Series (USA) (En,Fr,De) (GB Compatible)" + rom ( name "Godzilla - The Series (USA) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc dd716efe sha1 56EC20CF1F2613BC2DCDF88D27E8AF7378F7D334 ) ) game ( name "Godzilla - The Series - Monster Wars (Europe) (En,Fr,De)" description "Godzilla - The Series - Monster Wars (Europe) (En,Fr,De)" - rom ( name "Godzilla - The Series - Monster Wars (Europe) (En,Fr,De).gbc" size 1048576 crc A6007CE1 md5 6F67B154450BD3D88924C179F8165721 sha1 829C7EFB45A9E32EE63CD6C9FE5716E457BE7222 ) + rom ( name "Godzilla - The Series - Monster Wars (Europe) (En,Fr,De).gbc" size 1048576 crc a6007ce1 sha1 829C7EFB45A9E32EE63CD6C9FE5716E457BE7222 flags verified ) ) game ( name "Godzilla - The Series - Monster Wars (USA) (En,Fr,De)" description "Godzilla - The Series - Monster Wars (USA) (En,Fr,De)" - rom ( name "Godzilla - The Series - Monster Wars (USA) (En,Fr,De).gbc" size 1048576 crc E7EBB394 md5 597BD5A8AA26AF757CBA57AFF575EAA3 sha1 4137C24412DEB560F2DAB36F55C89253CA750B26 ) + rom ( name "Godzilla - The Series - Monster Wars (USA) (En,Fr,De).gbc" size 1048576 crc e7ebb394 sha1 4137C24412DEB560F2DAB36F55C89253CA750B26 ) ) game ( name "Gold and Glory - The Road to El Dorado (Europe) (En,Fr,De,Es,It,Nl)" description "Gold and Glory - The Road to El Dorado (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Gold and Glory - The Road to El Dorado (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc B16F1752 md5 041B8A455B63BEB718D70C8F89FAC9D3 sha1 89487F0B06A261BB2D3DD64D2A40C42ED9B4F63F ) + rom ( name "Gold and Glory - The Road to El Dorado (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc b16f1752 sha1 89487F0B06A261BB2D3DD64D2A40C42ED9B4F63F ) ) game ( name "Gold and Glory - The Road to El Dorado (USA)" description "Gold and Glory - The Road to El Dorado (USA)" - rom ( name "Gold and Glory - The Road to El Dorado (USA).gbc" size 1048576 crc B7D49490 md5 7BF3B13931F2A50EBE071A18EA14F28B sha1 D78B266757F8C2F53B0E8679161B1BF7828D9045 ) + rom ( name "Gold and Glory - The Road to El Dorado (USA).gbc" size 1048576 crc b7d49490 sha1 D78B266757F8C2F53B0E8679161B1BF7828D9045 ) ) game ( - name "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc BB9B597D md5 51F21F61592F05E712B36A0BF10A34A6 sha1 1501EA3BB5AA70562306F6DF40E5B61CEA93DE7E ) + name "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Golden Goal (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 1048576 crc bb9b597d sha1 1501EA3BB5AA70562306F6DF40E5B61CEA93DE7E flags verified ) ) game ( - name "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv)" - description "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 14D1ADBE md5 781AFD1E98B3743C835FCC16DF624895 sha1 ABA65E7ECA59F6FD90D4266DF1478BAD68D1E74E flags verified ) + name "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Golden Goal (Germany) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 1048576 crc 14d1adbe sha1 ABA65E7ECA59F6FD90D4266DF1478BAD68D1E74E flags verified ) ) game ( - name "Golf Daisuki! (Japan) (SGB Enhanced)" - description "Golf Daisuki! (Japan) (SGB Enhanced)" - rom ( name "Golf Daisuki! (Japan) (SGB Enhanced).gbc" size 2097152 crc 80444A86 md5 EF24106662AE769DBA0C410933736332 sha1 D245A267B1B1D056E0F5AF4BA732C66C8DEADDE2 ) + name "Golf Daisuki! (Japan) (SGB Enhanced) (GB Compatible)" + description "Golf Daisuki! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Golf Daisuki! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 80444a86 sha1 D245A267B1B1D056E0F5AF4BA732C66C8DEADDE2 ) ) game ( - name "Golf de Ohasuta (Japan)" - description "Golf de Ohasuta (Japan)" - rom ( name "Golf de Ohasuta (Japan).gbc" size 524288 crc 38273BDD md5 CB2969699AC7DECA731D67AA473E0024 sha1 8A19713515C4CD6983DA57F76924BABC090AF654 ) + name "Golf de Ohasuta (Japan) (GB Compatible)" + description "Golf de Ohasuta (Japan) (GB Compatible)" + rom ( name "Golf de Ohasuta (Japan) (GB Compatible).gbc" size 524288 crc 38273bdd sha1 8A19713515C4CD6983DA57F76924BABC090AF654 ) ) game ( - name "Golf Ou (Japan) (SGB Enhanced)" - description "Golf Ou (Japan) (SGB Enhanced)" - rom ( name "Golf Ou (Japan) (SGB Enhanced).gbc" size 4194304 crc 634B2D43 md5 296A232C36D6457301FD8AB9D9E35290 sha1 D196AF0AAF77CA67F9784D0CCD1EF4B25ABED5C2 ) + name "Golf Ou - The King of Golf (Japan) (SGB Enhanced) (GB Compatible)" + description "Golf Ou - The King of Golf (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Golf Ou - The King of Golf (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 634b2d43 sha1 D196AF0AAF77CA67F9784D0CCD1EF4B25ABED5C2 ) ) game ( name "Gonta no Okiraku Daibouken (Japan)" description "Gonta no Okiraku Daibouken (Japan)" - rom ( name "Gonta no Okiraku Daibouken (Japan).gbc" size 1048576 crc E45E99D2 md5 52E260E54D59FD16CD5CC588123D3E48 sha1 49E4156716A47D46006AD287EC46C28C573A74A5 flags verified ) + rom ( name "Gonta no Okiraku Daibouken (Japan).gbc" size 1048576 crc e45e99d2 sha1 49E4156716A47D46006AD287EC46C28C573A74A5 flags verified ) ) game ( - name "Goraku Ou Tango! (Japan)" - description "Goraku Ou Tango! (Japan)" - rom ( name "Goraku Ou Tango! (Japan).gbc" size 1048576 crc 81FB43E1 md5 139334587DB40E73F0CADCB06CA0CE61 sha1 1D49232763C1422A00CBB893D0F900C44A2CCF54 ) + name "Goraku Ou Tango! (Japan) (GB Compatible)" + description "Goraku Ou Tango! (Japan) (GB Compatible)" + rom ( name "Goraku Ou Tango! (Japan) (GB Compatible).gbc" size 1048576 crc 81fb43e1 sha1 1D49232763C1422A00CBB893D0F900C44A2CCF54 ) ) game ( - name "Grand Theft Auto (Europe) (En,Fr,De,Es,It)" - description "Grand Theft Auto (Europe) (En,Fr,De,Es,It)" - rom ( name "Grand Theft Auto (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 25BA9231 md5 2F4F1776863912BFC63EA49A19E4231B sha1 B6C1693BA5BF2C914D910E94286BDA8F3FBD100E flags verified ) + name "Grand Theft Auto (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Grand Theft Auto (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Grand Theft Auto (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 4194304 crc 25ba9231 sha1 B6C1693BA5BF2C914D910E94286BDA8F3FBD100E flags verified ) ) game ( - name "Grand Theft Auto (USA)" - description "Grand Theft Auto (USA)" - rom ( name "Grand Theft Auto (USA).gbc" size 4194304 crc 924DE366 md5 3322493D6B7A70BFDEA6F6231CEB1CE0 sha1 A0C9D9A95BF2CCECA7922F4375555B8EDEE9EA6B ) + name "Grand Theft Auto (USA) (GB Compatible)" + description "Grand Theft Auto (USA) (GB Compatible)" + rom ( name "Grand Theft Auto (USA) (GB Compatible).gbc" size 4194304 crc 924de366 sha1 A0C9D9A95BF2CCECA7922F4375555B8EDEE9EA6B ) ) game ( name "Grand Theft Auto 2 (Europe) (En,Fr,De,Es,It)" description "Grand Theft Auto 2 (Europe) (En,Fr,De,Es,It)" - rom ( name "Grand Theft Auto 2 (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc AD563BD9 md5 7DE54692E7B42E945B318D20079A5EFD sha1 A7577D81DE3AB03B93B364F9E775C303C842DAD2 flags verified ) + rom ( name "Grand Theft Auto 2 (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc ad563bd9 sha1 A7577D81DE3AB03B93B364F9E775C303C842DAD2 flags verified ) ) game ( name "Grand Theft Auto 2 (USA)" description "Grand Theft Auto 2 (USA)" - rom ( name "Grand Theft Auto 2 (USA).gbc" size 2097152 crc 68610203 md5 05A9C516D6E744135A6303AA5B4A8887 sha1 6FD4B31D410CA98452ADA0A1F3C0E2590E7DF099 ) + rom ( name "Grand Theft Auto 2 (USA).gbc" size 2097152 crc 68610203 sha1 6FD4B31D410CA98452ADA0A1F3C0E2590E7DF099 ) ) game ( name "Grandia - Parallel Trippers (Japan)" description "Grandia - Parallel Trippers (Japan)" - rom ( name "Grandia - Parallel Trippers (Japan).gbc" size 4194304 crc 23223670 md5 5679DE3C41C63C6B9DC9432C7ED1105A sha1 647B7CC5FA415EF7081AA37CD787EB41D2A3E574 flags verified ) + rom ( name "Grandia - Parallel Trippers (Japan).gbc" size 4194304 crc 23223670 sha1 647B7CC5FA415EF7081AA37CD787EB41D2A3E574 flags verified ) ) game ( name "Granduel - Shinki Dungeon no Hihou (Japan)" description "Granduel - Shinki Dungeon no Hihou (Japan)" - rom ( name "Granduel - Shinki Dungeon no Hihou (Japan).gbc" size 2097152 crc D589C501 md5 E69DA049D745B89FD28C79FE20A2B861 sha1 7FE6DA989E95A6E228C8D01AD650ED26EE42551B flags verified ) + rom ( name "Granduel - Shinki Dungeon no Hihou (Japan).gbc" size 2097152 crc d589c501 sha1 7FE6DA989E95A6E228C8D01AD650ED26EE42551B flags verified ) ) game ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample)" description "Granduel - Shinki Dungeon no Hihou (Japan) (Sample)" - rom ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample).gbc" size 2097152 crc 7122136D md5 C23C356A1ED788942E7D0B2CDAC2FD36 sha1 534FC9AE5800EB935460F145E1BBC57F77AB2555 ) + rom ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample).gbc" size 2097152 crc 7122136d sha1 534FC9AE5800EB935460F145E1BBC57F77AB2555 flags verified ) ) game ( - name "Great Battle Pocket, The (Japan) (SGB Enhanced)" - description "Great Battle Pocket, The (Japan) (SGB Enhanced)" - rom ( name "Great Battle Pocket, The (Japan) (SGB Enhanced).gbc" size 1048576 crc B471C095 md5 E952D78A439E47AB4D77B563973797D5 sha1 617752E18894590B5959F565F1CDBFD218141E7D ) + name "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" + description "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b471c095 sha1 617752E18894590B5959F565F1CDBFD218141E7D ) ) game ( - name "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt)" - description "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 053BC315 md5 D05A9DA7CD90CC9822E9655FB5476D54 sha1 D18E30A434262F7BF46A8DB2E5F62CE19B7ECFAA ) + name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt)" + description "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt)" + rom ( name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 053bc315 sha1 D18E30A434262F7BF46A8DB2E5F62CE19B7ECFAA ) ) game ( - name "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta)" - description "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta)" - rom ( name "Gremlins Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta).gbc" size 1048576 crc C38D52E7 md5 95DE0EB82C6013224A449FD972006D6F sha1 675623B58FA0D307355C77D7A4783AF7927681E9 ) + name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta)" + description "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta)" + rom ( name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta).gbc" size 1048576 crc c38d52e7 sha1 675623B58FA0D307355C77D7A4783AF7927681E9 ) ) game ( name "Grinch (Japan)" description "Grinch (Japan)" - rom ( name "Grinch (Japan).gbc" size 1048576 crc 432DC371 md5 83F1F765EFDD8D41CDD4F63EDCE42AFF sha1 33412209EF2B952E82F5D0B3F7BB035EFEBCF480 flags verified ) + rom ( name "Grinch (Japan).gbc" size 1048576 crc 432dc371 sha1 33412209EF2B952E82F5D0B3F7BB035EFEBCF480 flags verified ) ) game ( name "Grinch, The (Europe) (En,Fr,De)" description "Grinch, The (Europe) (En,Fr,De)" - rom ( name "Grinch, The (Europe) (En,Fr,De).gbc" size 1048576 crc 9ED6059A md5 B50EF76B1E81615CF079C373B50C0AB9 sha1 DF0ED2C6FAD2D511037AB9269571F24146103237 flags verified ) + rom ( name "Grinch, The (Europe) (En,Fr,De).gbc" size 1048576 crc 9ed6059a sha1 DF0ED2C6FAD2D511037AB9269571F24146103237 flags verified ) ) game ( name "Grinch, The (USA)" description "Grinch, The (USA)" - rom ( name "Grinch, The (USA).gbc" size 1048576 crc C5A47896 md5 42AD3639F6ABF013D5DACD4358ABF6CA sha1 84C2397FE07011511225B9D9F442F16C026576D3 ) + rom ( name "Grinch, The (USA).gbc" size 1048576 crc c5a47896 sha1 84C2397FE07011511225B9D9F442F16C026576D3 ) ) game ( - name "Guruguru Garakutas (Japan) (SGB Enhanced)" - description "Guruguru Garakutas (Japan) (SGB Enhanced)" - rom ( name "Guruguru Garakutas (Japan) (SGB Enhanced).gbc" size 1048576 crc 7EAEEEAC md5 1767860F9FC19EB7DA610616C1A35B89 sha1 86FEA7DD8D815A51C1B75B816125AB4BA731DBA1 ) + name "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" + description "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7eaeeeac sha1 86FEA7DD8D815A51C1B75B816125AB4BA731DBA1 ) ) game ( name "Guruguru Town Hanamaru-kun (Japan)" description "Guruguru Town Hanamaru-kun (Japan)" - rom ( name "Guruguru Town Hanamaru-kun (Japan).gbc" size 1048576 crc 03FBFC9E md5 7752B2476871760A8C00B06DF93A89B7 sha1 D147400BB9831B30A4E75F3570A1844F674E866C ) + rom ( name "Guruguru Town Hanamaru-kun (Japan).gbc" size 1048576 crc 03fbfc9e sha1 D147400BB9831B30A4E75F3570A1844F674E866C flags verified ) ) game ( - name "Gute Zeiten Schlechte Zeiten Quiz (Germany)" - description "Gute Zeiten Schlechte Zeiten Quiz (Germany)" - rom ( name "Gute Zeiten Schlechte Zeiten Quiz (Germany).gbc" size 1048576 crc 5F13A2D4 md5 A9CC81BFFB2D1D3A9CAA38F04E6F6C1D sha1 611D8AB71BDEB6B0FD292118676E85E940D11BD4 flags verified ) + name "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible)" + description "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible)" + rom ( name "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible).gbc" size 1048576 crc 5f13a2d4 sha1 611D8AB71BDEB6B0FD292118676E85E940D11BD4 flags verified ) ) game ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" description "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" - rom ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan).gbc" size 4194304 crc B17DC263 md5 3309FE5963175FA0AE6CC6ABE34DBC53 sha1 B72E885BAEEB27CB32DE5B5DCEDB632537898C33 flags verified ) + rom ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan).gbc" size 4194304 crc b17dc263 sha1 B72E885BAEEB27CB32DE5B5DCEDB632537898C33 flags verified ) ) game ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt)" description "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 70F3B431 md5 2E20E9CBFF75913F4E123242A404A2A9 sha1 15BF27A7847817FBBB9CB7729B8046A6D70164C5 ) + rom ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 70f3b431 sha1 15BF27A7847817FBBB9CB7729B8046A6D70164C5 ) ) game ( - name "Hamster Club (Japan)" - description "Hamster Club (Japan)" - rom ( name "Hamster Club (Japan).gbc" size 2097152 crc 8A4D86A0 md5 08261D984F5E0D103191D7BBAE8FBA50 sha1 6AB81C4DEC3263502A1781B600218285836C5302 flags verified ) + name "Hamster Club (Japan) (GB Compatible)" + description "Hamster Club (Japan) (GB Compatible)" + rom ( name "Hamster Club (Japan) (GB Compatible).gbc" size 2097152 crc 8a4d86a0 sha1 6AB81C4DEC3263502A1781B600218285836C5302 flags verified ) ) game ( name "Hamster Club - Awasete Chuu (Japan)" description "Hamster Club - Awasete Chuu (Japan)" - rom ( name "Hamster Club - Awasete Chuu (Japan).gbc" size 1048576 crc D56D68FF md5 7D78CACD5EEE9569EBC1B85FF9F05C90 sha1 AD4148B716F8A379578E6D862B06D435396FACCC ) + rom ( name "Hamster Club - Awasete Chuu (Japan).gbc" size 1048576 crc d56d68ff sha1 AD4148B716F8A379578E6D862B06D435396FACCC flags verified ) ) game ( name "Hamster Club - Oshiema Chuu (Japan)" description "Hamster Club - Oshiema Chuu (Japan)" - rom ( name "Hamster Club - Oshiema Chuu (Japan).gbc" size 2097152 crc 79CEEF4E md5 C9146A0BF581D7F99AEEAC0E8DFA04DF sha1 E2739F49CE29D1F7FE1CB94808230E7C2AD781E3 ) + rom ( name "Hamster Club - Oshiema Chuu (Japan).gbc" size 2097152 crc 79ceef4e sha1 E2739F49CE29D1F7FE1CB94808230E7C2AD781E3 flags verified ) ) game ( - name "Hamster Club 2 (Japan)" - description "Hamster Club 2 (Japan)" - rom ( name "Hamster Club 2 (Japan).gbc" size 4194304 crc 2FB398F9 md5 D73B7F013AB9E347398683363F720AB7 sha1 DCEF750A73D813841CFCB871B5BB5F021A7B7285 ) + name "Hamster Club 2 (Japan) (GB Compatible)" + description "Hamster Club 2 (Japan) (GB Compatible)" + rom ( name "Hamster Club 2 (Japan) (GB Compatible).gbc" size 4194304 crc 2fb398f9 sha1 DCEF750A73D813841CFCB871B5BB5F021A7B7285 ) ) game ( name "Hamster Monogatari GB + Magi Ham no Mahou Shoujo (Japan)" description "Hamster Monogatari GB + Magi Ham no Mahou Shoujo (Japan)" - rom ( name "Hamster Monogatari GB + Magi Ham no Mahou Shoujo (Japan).gbc" size 4194304 crc ABD59939 md5 9C6A9C38B987E50001153AD12EB5FCC8 sha1 B3300B1DF2CD6A42F112624D5EB2803D45EB3054 ) + rom ( name "Hamster Monogatari GB + Magi Ham no Mahou Shoujo (Japan).gbc" size 4194304 crc abd59939 sha1 B3300B1DF2CD6A42F112624D5EB2803D45EB3054 flags verified ) ) game ( - name "Hamster Paradise (Japan) (SGB Enhanced)" - description "Hamster Paradise (Japan) (SGB Enhanced)" - rom ( name "Hamster Paradise (Japan) (SGB Enhanced).gbc" size 1048576 crc F520CB19 md5 81F4CBFFBED0638F59A16203C07E364B sha1 87EBC7E0CFB0803E6E14DA7EEC1B2FAD51C83BA0 flags verified ) + name "Hamster Paradise (Japan) (SGB Enhanced) (GB Compatible)" + description "Hamster Paradise (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hamster Paradise (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f520cb19 sha1 87EBC7E0CFB0803E6E14DA7EEC1B2FAD51C83BA0 flags verified ) ) game ( name "Hamster Paradise 2 (Japan)" description "Hamster Paradise 2 (Japan)" - rom ( name "Hamster Paradise 2 (Japan).gbc" size 2097152 crc 542C78B6 md5 A290F281CDE7D00059E0E567BFFB0D3B sha1 CF19FD582D8881779E7E34E1D6CD8FD5B7129F53 ) + rom ( name "Hamster Paradise 2 (Japan).gbc" size 2097152 crc 542c78b6 sha1 CF19FD582D8881779E7E34E1D6CD8FD5B7129F53 ) ) game ( - name "Hamster Paradise 2 (Japan) (Rev A)" - description "Hamster Paradise 2 (Japan) (Rev A)" - rom ( name "Hamster Paradise 2 (Japan) (Rev A).gbc" size 2097152 crc B9E1F3B0 md5 DEEF0140C464BFF3435061B90E01B70D sha1 140100D96D165EE399F5CD18F5AEC962FDE714B6 flags verified ) + name "Hamster Paradise 2 (Japan) (Rev 1)" + description "Hamster Paradise 2 (Japan) (Rev 1)" + rom ( name "Hamster Paradise 2 (Japan) (Rev 1).gbc" size 2097152 crc b9e1f3b0 sha1 140100D96D165EE399F5CD18F5AEC962FDE714B6 flags verified ) ) game ( name "Hamster Paradise 3 (Japan)" description "Hamster Paradise 3 (Japan)" - rom ( name "Hamster Paradise 3 (Japan).gbc" size 4194304 crc 14CAC67C md5 18ECA52A51880410614CFC4AD65EE34C sha1 9D8E482AFAD5B8786BF289640FC275B7787FBEA3 ) + rom ( name "Hamster Paradise 3 (Japan).gbc" size 4194304 crc 14cac67c sha1 9D8E482AFAD5B8786BF289640FC275B7787FBEA3 flags verified ) ) game ( name "Hamster Paradise 4 (Japan)" description "Hamster Paradise 4 (Japan)" - rom ( name "Hamster Paradise 4 (Japan).gbc" size 4194304 crc C460DC88 md5 1C1F455209D6400EB3C7C091F6608723 sha1 177CB46C44346EABBEB06F5D7929C77AFC798DB9 ) + rom ( name "Hamster Paradise 4 (Japan).gbc" size 4194304 crc c460dc88 sha1 177CB46C44346EABBEB06F5D7929C77AFC798DB9 flags verified ) ) game ( name "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It)" description "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It)" - rom ( name "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 45BE9D9B md5 06157785417D6FE5C73388EB573981DC sha1 047D9DEDB77A448D31CD5DCE23F4C3DD8714DAFE ) + rom ( name "Hamtaro - Ham-Hams Unite! (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 45be9d9b sha1 047D9DEDB77A448D31CD5DCE23F4C3DD8714DAFE ) ) game ( name "Hamtaro - Ham-Hams Unite! (USA)" description "Hamtaro - Ham-Hams Unite! (USA)" - rom ( name "Hamtaro - Ham-Hams Unite! (USA).gbc" size 2097152 crc 1271117F md5 48CE279084E1FC7A9136CC211F4FAD5D sha1 9770BF59E932B41882839CE9EEC033F576094FEE ) + rom ( name "Hamtaro - Ham-Hams Unite! (USA).gbc" size 2097152 crc 1271117f sha1 9770BF59E932B41882839CE9EEC033F576094FEE flags verified ) ) game ( name "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan)" description "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan)" - rom ( name "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan).gbc" size 1048576 crc FF454711 md5 8E7D7B91C08169D779FDA0A49C4DD3B7 sha1 79C38BC527C9DA2C27D1D9DC85924360D7CD66D3 flags verified ) + rom ( name "Hamunaptra - Ushinawareta Sabaku no Miyako (Japan).gbc" size 1048576 crc ff454711 sha1 79C38BC527C9DA2C27D1D9DC85924360D7CD66D3 flags verified ) ) game ( name "Hana Yori Dango - Another Love Story (Japan)" description "Hana Yori Dango - Another Love Story (Japan)" - rom ( name "Hana Yori Dango - Another Love Story (Japan).gbc" size 2097152 crc 469F0284 md5 E1AF297B7083E1958352BBC5655EF480 sha1 9A403476FA3325D5D48AD0686727B9C715EBAEF9 ) + rom ( name "Hana Yori Dango - Another Love Story (Japan).gbc" size 2097152 crc 469f0284 sha1 9A403476FA3325D5D48AD0686727B9C715EBAEF9 flags verified ) ) game ( - name "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced)" - description "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced)" - rom ( name "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced).gbc" size 1048576 crc 6E988C07 md5 500C3AD63568B78FE3DF71782BDF8592 sha1 791EA554DE774DE622BB4FB6BC2BF42955A201B3 flags verified ) + name "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced) (GB Compatible)" + description "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hanasaka Tenshi Tenten-kun no Beat Breaker (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6e988c07 sha1 791EA554DE774DE622BB4FB6BC2BF42955A201B3 flags verified ) ) game ( name "Hands of Time (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Hands of Time (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Hands of Time (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc F519F4C3 md5 CECC79084E6515E9C59CE8D63D49EACE sha1 AE07E529F1C98432F37FA674EE4DE6305807A92B flags verified ) + rom ( name "Hands of Time (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f519f4c3 sha1 AE07E529F1C98432F37FA674EE4DE6305807A92B flags verified ) ) game ( name "Hang Time Basketball (Europe) (Unl)" description "Hang Time Basketball (Europe) (Unl)" - rom ( name "Hang Time Basketball (Europe) (Unl).gbc" size 262144 crc 3207B7D9 md5 008EDE5B89C08375FE58D6597A15A21A sha1 340201C045C020BE6DE3504FDECBCE1FF07A2139 flags verified ) + rom ( name "Hang Time Basketball (Europe) (Unl).gbc" size 262144 crc 3207b7d9 sha1 340201C045C020BE6DE3504FDECBCE1FF07A2139 flags verified ) ) game ( name "Harley-Davidson Motor Cycles - Race Across America (USA)" description "Harley-Davidson Motor Cycles - Race Across America (USA)" - rom ( name "Harley-Davidson Motor Cycles - Race Across America (USA).gbc" size 1048576 crc 644BAC84 md5 0CCC5CD15A646417EFB5FA9EA920FCE3 sha1 3777B4F69D6AF13B3FD94CAADAD4661D5904399E ) + rom ( name "Harley-Davidson Motor Cycles - Race Across America (USA).gbc" size 1048576 crc 644bac84 sha1 3777B4F69D6AF13B3FD94CAADAD4661D5904399E ) ) game ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,Da)" description "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,Da)" - rom ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,Da).gbc" size 4194304 crc 136E9D0C md5 BC60280596BCE42D050B764B647DC39B sha1 E3B9B22E3E528EFC41E5B57FC9B3DCFA75DCD443 flags verified ) + rom ( name "Harry Potter and the Chamber of Secrets (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,Da).gbc" size 4194304 crc 136e9d0c sha1 E3B9B22E3E528EFC41E5B57FC9B3DCFA75DCD443 flags verified ) ) game ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" description "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" - rom ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 4194304 crc 4FD8B7C5 md5 BA85A2AE8AA5829C440EEF2D5549506C sha1 4E6F676EC15E0E6238CB81853B5A74BBB20657A1 flags verified ) + rom ( name "Harry Potter and the Sorcerer's Stone (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 4194304 crc 4fd8b7c5 sha1 4E6F676EC15E0E6238CB81853B5A74BBB20657A1 flags verified ) ) game ( name "Harry Potter to Kenja no Ishi (Japan)" description "Harry Potter to Kenja no Ishi (Japan)" - rom ( name "Harry Potter to Kenja no Ishi (Japan).gbc" size 4194304 crc 2DA2686A md5 34D61C282C372F97B55F8DAE1EF94FB7 sha1 A4FB5A1F3CDEBD989617A1964ADA8DF4AB491E36 ) + rom ( name "Harry Potter to Kenja no Ishi (Japan).gbc" size 4194304 crc 2da2686a sha1 A4FB5A1F3CDEBD989617A1964ADA8DF4AB491E36 flags verified ) ) game ( - name "Harvest Moon 2 GBC (Europe) (SGB Enhanced)" - description "Harvest Moon 2 GBC (Europe) (SGB Enhanced)" - rom ( name "Harvest Moon 2 GBC (Europe) (SGB Enhanced).gbc" size 2097152 crc 160CA990 md5 74C9FE928DD97AE193E9F937CE340DCC sha1 4DC14FB6A6057B7FABBCF29BD21F331170F84420 ) + name "Harvest Moon 2 GBC (Europe) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon 2 GBC (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon 2 GBC (Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 160ca990 sha1 4DC14FB6A6057B7FABBCF29BD21F331170F84420 ) ) game ( - name "Harvest Moon 2 GBC (Germany) (SGB Enhanced)" - description "Harvest Moon 2 GBC (Germany) (SGB Enhanced)" - rom ( name "Harvest Moon 2 GBC (Germany) (SGB Enhanced).gbc" size 2097152 crc 32A04C29 md5 121CEC82C0C9E7C476060AD2521739D4 sha1 697179ECBFB138F1CEFF5DD3FF414DE06E12AD80 ) + name "Harvest Moon 2 GBC (Germany) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon 2 GBC (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon 2 GBC (Germany) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 32a04c29 sha1 697179ECBFB138F1CEFF5DD3FF414DE06E12AD80 ) ) game ( - name "Harvest Moon 2 GBC (USA) (SGB Enhanced)" - description "Harvest Moon 2 GBC (USA) (SGB Enhanced)" - rom ( name "Harvest Moon 2 GBC (USA) (SGB Enhanced).gbc" size 2097152 crc 08906220 md5 A539A7A02639395AD8D7723199C81EAE sha1 DA745AA63684F53FB3EE6C19463ED4C132441CCB ) + name "Harvest Moon 2 GBC (USA) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon 2 GBC (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon 2 GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 08906220 sha1 DA745AA63684F53FB3EE6C19463ED4C132441CCB ) ) game ( name "Harvest Moon 3 GBC (USA)" description "Harvest Moon 3 GBC (USA)" - rom ( name "Harvest Moon 3 GBC (USA).gbc" size 2097152 crc A0D67417 md5 0FF9DF46ACA45161D1DFA7EEE8509C1F sha1 5313C62C51B9B5417F764FE67B687F403F9765BB ) + rom ( name "Harvest Moon 3 GBC (USA).gbc" size 2097152 crc a0d67417 sha1 5313C62C51B9B5417F764FE67B687F403F9765BB ) ) game ( - name "Harvest Moon GB (Europe) (SGB Enhanced)" - description "Harvest Moon GB (Europe) (SGB Enhanced)" - rom ( name "Harvest Moon GB (Europe) (SGB Enhanced).gbc" size 1048576 crc C8A6F68A md5 A5BC2E2AD58BBD78609478A60DCDA8D7 sha1 EA464CB16446855ED60CF714CA5B3DED02D82B1E ) + name "Harvest Moon GB (Europe) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon GB (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon GB (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c8a6f68a sha1 EA464CB16446855ED60CF714CA5B3DED02D82B1E ) ) game ( - name "Harvest Moon GB (Germany) (SGB Enhanced)" - description "Harvest Moon GB (Germany) (SGB Enhanced)" - rom ( name "Harvest Moon GB (Germany) (SGB Enhanced).gbc" size 1048576 crc D3896652 md5 1C9F1847AE4832BDD53F39968750D505 sha1 22E06880AFE664051498714B3EDB2E18F26F7961 flags verified ) + name "Harvest Moon GB (Germany) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon GB (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon GB (Germany) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d3896652 sha1 22E06880AFE664051498714B3EDB2E18F26F7961 flags verified ) ) game ( - name "Harvest Moon GB (USA) (SGB Enhanced)" - description "Harvest Moon GB (USA) (SGB Enhanced)" - rom ( name "Harvest Moon GB (USA) (SGB Enhanced).gbc" size 1048576 crc AB5738A1 md5 498C0A50A5E5CDE16127617A97AD6162 sha1 D407B9C20C5381F46EC460858539A5B6F559E04F ) + name "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible)" + description "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ab5738a1 sha1 D407B9C20C5381F46EC460858539A5B6F559E04F ) ) game ( - name "Hello Kitty no Beads Factory (Japan) (SGB Enhanced)" - description "Hello Kitty no Beads Factory (Japan) (SGB Enhanced)" - rom ( name "Hello Kitty no Beads Factory (Japan) (SGB Enhanced).gbc" size 1048576 crc 12F74CD4 md5 842B07D0ADD5A3A88BD55653331671DD sha1 539DDBE7F73B33FFB886143DD14869D486F3FECF ) + name "Hello Kitty no Beads Factory (Japan) (SGB Enhanced) (GB Compatible)" + description "Hello Kitty no Beads Factory (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hello Kitty no Beads Factory (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 12f74cd4 sha1 539DDBE7F73B33FFB886143DD14869D486F3FECF ) ) game ( name "Hello Kitty no Happy House (Japan)" description "Hello Kitty no Happy House (Japan)" - rom ( name "Hello Kitty no Happy House (Japan).gbc" size 4194304 crc 159FE5E7 md5 0121AA4C2909FF7DFF2190B7889956FD sha1 B5CBABEC048E1F77FEE7830BDB564F21369FAEEF ) + rom ( name "Hello Kitty no Happy House (Japan).gbc" size 4194304 crc 159fe5e7 sha1 B5CBABEC048E1F77FEE7830BDB564F21369FAEEF flags verified ) ) game ( - name "Hello Kitty no Magical Museum (Japan) (SGB Enhanced)" - description "Hello Kitty no Magical Museum (Japan) (SGB Enhanced)" - rom ( name "Hello Kitty no Magical Museum (Japan) (SGB Enhanced).gbc" size 1048576 crc F6768930 md5 B868FA9F3CECFA2D39DF43A5D1B13B60 sha1 462E5120831C2298BB5138BF25B4C8C72B372407 flags verified ) + name "Hello Kitty no Magical Museum (Japan) (SGB Enhanced) (GB Compatible)" + description "Hello Kitty no Magical Museum (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hello Kitty no Magical Museum (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f6768930 sha1 462E5120831C2298BB5138BF25B4C8C72B372407 flags verified ) ) game ( - name "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced)" - description "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced)" - rom ( name "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced).gbc" size 1048576 crc 45F4159B md5 5F9BBF43DF1837FE1C1D960286513FCB sha1 C290DBD29A6246EB001F35F973C0E664AF2C97B1 ) + name "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced) (GB Compatible)" + description "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hello Kitty no Sweet Adventure - Daniel-kun ni Aitai (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 45f4159b sha1 C290DBD29A6246EB001F35F973C0E664AF2C97B1 ) ) game ( name "Hello Kitty to Dear Daniel no Dream Adventure (Japan)" description "Hello Kitty to Dear Daniel no Dream Adventure (Japan)" - rom ( name "Hello Kitty to Dear Daniel no Dream Adventure (Japan).gbc" size 1048576 crc 018EED29 md5 15F4DF0EFE9F42CBAAAC09C866CBFD21 sha1 A726C5847112289720D6587BF63778C839245C49 ) + rom ( name "Hello Kitty to Dear Daniel no Dream Adventure (Japan).gbc" size 1048576 crc 018eed29 sha1 A726C5847112289720D6587BF63778C839245C49 ) ) game ( - name "Hello Kitty's Cube Frenzy (USA)" - description "Hello Kitty's Cube Frenzy (USA)" - rom ( name "Hello Kitty's Cube Frenzy (USA).gbc" size 1048576 crc 937729F6 md5 29F236DD1A64C15A7C1F66110579CCC3 sha1 6F15379553A0EC8A8174B85A35EAA4085DEC6B43 ) + name "Hello Kitty's Cube Frenzy (USA) (GB Compatible)" + description "Hello Kitty's Cube Frenzy (USA) (GB Compatible)" + rom ( name "Hello Kitty's Cube Frenzy (USA) (GB Compatible).gbc" size 1048576 crc 937729f6 sha1 6F15379553A0EC8A8174B85A35EAA4085DEC6B43 ) ) game ( name "Hercules - The Legendary Journeys (Europe) (En,Fr,De,Es,It,Nl)" description "Hercules - The Legendary Journeys (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Hercules - The Legendary Journeys (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc C0EDE71F md5 D69FDC8DAFD38AB4F48CC6A6B8FA1DF9 sha1 AE521E5011B2B67DE489374C3E9C5EC8AD8C0EE6 ) + rom ( name "Hercules - The Legendary Journeys (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c0ede71f sha1 AE521E5011B2B67DE489374C3E9C5EC8AD8C0EE6 ) ) game ( - name "Hero Hero Kun (Japan)" - description "Hero Hero Kun (Japan)" - rom ( name "Hero Hero Kun (Japan).gbc" size 2097152 crc 8CABDCA4 md5 FBD15FA51A3BCE25D9041CC522AF7FB4 sha1 E7B0944FC2C9FFB4E7F997357327470E15798D63 ) + name "Hero Hero-kun (Japan)" + description "Hero Hero-kun (Japan)" + rom ( name "Hero Hero-kun (Japan).gbc" size 2097152 crc 8cabdca4 sha1 E7B0944FC2C9FFB4E7F997357327470E15798D63 ) ) game ( name "Heroes of Might and Magic (USA) (En,Fr,De)" description "Heroes of Might and Magic (USA) (En,Fr,De)" - rom ( name "Heroes of Might and Magic (USA) (En,Fr,De).gbc" size 1048576 crc BB0672A6 md5 6A2A5AB0DC979F162CBFA4389D1CD71F sha1 209D8A9CDD240A8C73D03D8575373BFA53948869 ) + rom ( name "Heroes of Might and Magic (USA) (En,Fr,De).gbc" size 1048576 crc bb0672a6 sha1 209D8A9CDD240A8C73D03D8575373BFA53948869 ) ) game ( name "Heroes of Might and Magic (Europe) (En,Fr,De)" description "Heroes of Might and Magic (Europe) (En,Fr,De)" - rom ( name "Heroes of Might and Magic (Europe) (En,Fr,De).gbc" size 1048576 crc E0B9FD3B md5 2AE0C6E8F9831D6E8F1ABAC86B01E7D6 sha1 D6471849187EDCF68E61ED98558D9326A44CF2DC ) + rom ( name "Heroes of Might and Magic (Europe) (En,Fr,De).gbc" size 1048576 crc e0b9fd3b sha1 D6471849187EDCF68E61ED98558D9326A44CF2DC flags verified ) ) game ( name "Heroes of Might and Magic II (USA) (En,Fr,De)" description "Heroes of Might and Magic II (USA) (En,Fr,De)" - rom ( name "Heroes of Might and Magic II (USA) (En,Fr,De).gbc" size 1048576 crc 53156D4D md5 AD37726C92F43AD7915225B7EAF94FFD sha1 1D6AE18073C8B789C288039B0F579EBF15D1F03C ) + rom ( name "Heroes of Might and Magic II (USA) (En,Fr,De).gbc" size 1048576 crc 53156d4d sha1 1D6AE18073C8B789C288039B0F579EBF15D1F03C ) ) game ( - name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced)" - description "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced)" - rom ( name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 84084E5F md5 4B068708FB29FDABBEE834114FE4A09D sha1 BB00FF88AF717B45E08EF421AC77E0546870B1F4 flags verified ) + name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 84084e5f sha1 BB00FF88AF717B45E08EF421AC77E0546870B1F4 flags verified ) ) game ( name "Hiryuu no Ken - Retsuden GB (Japan)" description "Hiryuu no Ken - Retsuden GB (Japan)" - rom ( name "Hiryuu no Ken - Retsuden GB (Japan).gbc" size 1048576 crc BDAE91E8 md5 5165FAA424C006A72CCACDD62BF61726 sha1 75DB7ACDFA206E539C385B928DA07C6B0C776308 ) + rom ( name "Hiryuu no Ken - Retsuden GB (Japan).gbc" size 1048576 crc bdae91e8 sha1 75DB7ACDFA206E539C385B928DA07C6B0C776308 ) ) game ( name "Hissatsu Pachinko Boy - CR Monster House (Japan)" description "Hissatsu Pachinko Boy - CR Monster House (Japan)" - rom ( name "Hissatsu Pachinko Boy - CR Monster House (Japan).gbc" size 1048576 crc 70F10315 md5 DDC44D19F27100E9E9CF440820436152 sha1 35EE6E33B11BA8C02F1BF2DCDAF96C1E135982AB ) + rom ( name "Hissatsu Pachinko Boy - CR Monster House (Japan).gbc" size 1048576 crc 70f10315 sha1 35EE6E33B11BA8C02F1BF2DCDAF96C1E135982AB ) ) game ( - name "Hole In One Golf (USA) (Rumble Version) (SGB Enhanced)" - description "Hole In One Golf (USA) (Rumble Version) (SGB Enhanced)" - rom ( name "Hole In One Golf (USA) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc 27A53965 md5 B60DBF70D1A54E327A1CD668ADE9F43B sha1 D0C2FB49177BC1CF145503EB48BDE3BD196EA1D9 ) + name "Hole in One Golf (USA) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Hole in One Golf (USA) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Hole in One Golf (USA) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 27a53965 sha1 D0C2FB49177BC1CF145503EB48BDE3BD196EA1D9 ) ) game ( - name "Hollywood Pinball (Europe) (En,Fr,De,It)" - description "Hollywood Pinball (Europe) (En,Fr,De,It)" - rom ( name "Hollywood Pinball (Europe) (En,Fr,De,It).gbc" size 1048576 crc 8BD1F635 md5 9889AFC5B4E72C9F96DB8E6B4260F6B7 sha1 2D179E034DBD19E48AEE31FFDC504305444CC84A ) + name "Hollywood Pinball (Europe) (En,Fr,De,It) (GB Compatible)" + description "Hollywood Pinball (Europe) (En,Fr,De,It) (GB Compatible)" + rom ( name "Hollywood Pinball (Europe) (En,Fr,De,It) (GB Compatible).gbc" size 1048576 crc 8bd1f635 sha1 2D179E034DBD19E48AEE31FFDC504305444CC84A ) ) game ( - name "Hollywood Pinball (Japan)" - description "Hollywood Pinball (Japan)" - rom ( name "Hollywood Pinball (Japan).gbc" size 1048576 crc 77D7E5B7 md5 E2B6CFC93021D361AB1CAC347499B493 sha1 FF77EC892F2331E895774555183FB1CFFB88CA6E ) + name "Hollywood Pinball (Japan) (GB Compatible)" + description "Hollywood Pinball (Japan) (GB Compatible)" + rom ( name "Hollywood Pinball (Japan) (GB Compatible).gbc" size 1048576 crc 77d7e5b7 sha1 FF77EC892F2331E895774555183FB1CFFB88CA6E ) ) game ( - name "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced)" - description "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 1048576 crc ABD8CEAE md5 D7F3A39D4FDE196FBE2DDBB2A6E575A3 sha1 01AD2928E923C415671E6306D6D73016A1CA7BB9 flags verified ) + name "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Holy Magic Century (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc abd8ceae sha1 01AD2928E923C415671E6306D6D73016A1CA7BB9 flags verified ) ) game ( name "Honkaku Hanafuda GB (Japan)" description "Honkaku Hanafuda GB (Japan)" - rom ( name "Honkaku Hanafuda GB (Japan).gbc" size 1048576 crc 05DCBD55 md5 EFE18A36FC03264E23CCBB81FEF2BEBA sha1 24E116249E569D79A280C8F4104934B369C32D79 ) + rom ( name "Honkaku Hanafuda GB (Japan).gbc" size 1048576 crc 05dcbd55 sha1 24E116249E569D79A280C8F4104934B369C32D79 ) ) game ( - name "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced)" - description "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced)" - rom ( name "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced).gbc" size 1048576 crc 3A96E868 md5 138EE068183A17684CA3AACFC1E3E38E sha1 A0E5A6B00CC31670949F7D8CDEEC2486D0EC986F ) + name "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced) (GB Compatible)" + description "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Honkaku Shougi - Shougi Ou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 3a96e868 sha1 A0E5A6B00CC31670949F7D8CDEEC2486D0EC986F ) ) game ( - name "Honkaku Taisen Shougi Ayumu (Japan)" - description "Honkaku Taisen Shougi Ayumu (Japan)" - rom ( name "Honkaku Taisen Shougi Ayumu (Japan).gbc" size 1048576 crc 89140949 md5 472B425740F0603FA3B566E028E871BD sha1 5B71C264A69902D77888243DF92E8C93ACE6732B ) + name "Honkaku Taisen Shougi Ayumu (Japan) (GB Compatible)" + description "Honkaku Taisen Shougi Ayumu (Japan) (GB Compatible)" + rom ( name "Honkaku Taisen Shougi Ayumu (Japan) (GB Compatible).gbc" size 1048576 crc 89140949 sha1 5B71C264A69902D77888243DF92E8C93ACE6732B ) ) game ( - name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced)" - description "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced)" - rom ( name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced).gbc" size 1048576 crc 8ED4BBBA md5 1639E77B02227D996F17FF5BEC16C1B8 sha1 222487F14AAAA8F0BB536A09238E63AC95636208 ) + name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible)" + description "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8ed4bbba sha1 222487F14AAAA8F0BB536A09238E63AC95636208 ) ) game ( - name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced)" - description "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced)" - rom ( name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 72A5E820 md5 9A908FD85216B1B3A994EC75D2CF9318 sha1 EABF2BC053BA6A440A834D6BCD0B45A7432A9A20 flags verified ) + name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 72a5e820 sha1 EABF2BC053BA6A440A834D6BCD0B45A7432A9A20 flags verified ) ) game ( name "Hoyle Card Games (USA)" description "Hoyle Card Games (USA)" - rom ( name "Hoyle Card Games (USA).gbc" size 1048576 crc DD5D3713 md5 83087E1A3FA7160A59EE7E4F0B5C3671 sha1 5EB733FA50E21F124A5362287DA439DC199E3773 ) + rom ( name "Hoyle Card Games (USA).gbc" size 1048576 crc dd5d3713 sha1 5EB733FA50E21F124A5362287DA439DC199E3773 ) ) game ( name "Hoyle Casino (USA)" description "Hoyle Casino (USA)" - rom ( name "Hoyle Casino (USA).gbc" size 1048576 crc 413473B0 md5 E0245D992101BE481C355E3E2C2CBB83 sha1 827EFA6D7B56E919B95AE52C451BE2A40D870822 ) + rom ( name "Hoyle Casino (USA).gbc" size 1048576 crc 413473b0 sha1 827EFA6D7B56E919B95AE52C451BE2A40D870822 ) ) game ( name "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" description "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" - rom ( name "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 1048576 crc 685CAFCC md5 0762FC989C52652B2660F26BE0830F20 sha1 BB2721DD0866B9B7F41E590287569FC09339CC6A flags verified ) + rom ( name "Hugo - Black Diamond Fever (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 1048576 crc 685cafcc sha1 BB2721DD0866B9B7F41E590287569FC09339CC6A flags verified ) ) game ( name "Hugo - The Evil Mirror (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" description "Hugo - The Evil Mirror (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi)" - rom ( name "Hugo - The Evil Mirror (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 1048576 crc 24B76CD0 md5 18C5DDDE4BCFFD1DDCBA490EB529F0D7 sha1 E5F29C654687221C5E4D4BDBC456FD08F32946A6 ) + rom ( name "Hugo - The Evil Mirror (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da,Fi).gbc" size 1048576 crc 24b76cd0 sha1 E5F29C654687221C5E4D4BDBC456FD08F32946A6 flags verified ) ) game ( - name "Hugo 2 1-2 (Germany)" - description "Hugo 2 1-2 (Germany)" - rom ( name "Hugo 2 1-2 (Germany).gbc" size 1048576 crc FAB64B18 md5 F1A64423CC8CC50338AB69FEEE3199F6 sha1 5D89A8B4DE6E6B2BA5BE3434F0A1EEE03077EEDA flags verified ) + name "Hugo 2 1-2 (Germany) (GB Compatible)" + description "Hugo 2 1-2 (Germany) (GB Compatible)" + rom ( name "Hugo 2 1-2 (Germany) (GB Compatible).gbc" size 1048576 crc fab64b18 sha1 5D89A8B4DE6E6B2BA5BE3434F0A1EEE03077EEDA flags verified ) ) game ( - name "Hunter X Hunter - Hunter no Keifu (Japan)" - description "Hunter X Hunter - Hunter no Keifu (Japan)" - rom ( name "Hunter X Hunter - Hunter no Keifu (Japan).gbc" size 4194304 crc A1361642 md5 62922E55A0A4A4E9E90248CEB13B3C56 sha1 CF31B713B6039BA18675FA5D4CAA83934AE1F216 ) + name "Hunter x Hunter - Hunter no Keifu (Japan)" + description "Hunter x Hunter - Hunter no Keifu (Japan)" + rom ( name "Hunter x Hunter - Hunter no Keifu (Japan).gbc" size 4194304 crc a1361642 sha1 CF31B713B6039BA18675FA5D4CAA83934AE1F216 flags verified ) ) game ( - name "Hunter X Hunter - Kindan no Hihou (Japan)" - description "Hunter X Hunter - Kindan no Hihou (Japan)" - rom ( name "Hunter X Hunter - Kindan no Hihou (Japan).gbc" size 1048576 crc D23C6A75 md5 8AC8F913B5F1E31582DE191B367648A9 sha1 EF131FB2752B8FF996BF1AAAEBD22887E380AA31 ) + name "Hunter x Hunter - Kindan no Hihou (Japan)" + description "Hunter x Hunter - Kindan no Hihou (Japan)" + rom ( name "Hunter x Hunter - Kindan no Hihou (Japan).gbc" size 1048576 crc d23c6a75 sha1 EF131FB2752B8FF996BF1AAAEBD22887E380AA31 ) ) game ( name "Hype - The Time Quest (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Hype - The Time Quest (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Hype - The Time Quest (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gbc" size 1048576 crc 24846D65 md5 7039B471857D20F77A5BA7F48065ED53 sha1 8E26E7E2E64D4BF866B67387586FC5C4A9C56855 ) + rom ( name "Hype - The Time Quest (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gbc" size 1048576 crc 24846d65 sha1 8E26E7E2E64D4BF866B67387586FC5C4A9C56855 ) +) + +game ( + name "Hype - The Time Quest (Brazil)" + description "Hype - The Time Quest (Brazil)" + rom ( name "Hype - The Time Quest (Brazil).gbc" size 1048576 crc cafb8035 sha1 7C7DCA7C48DC478D0278C273BA37723B9E9DCE5B flags verified ) ) game ( name "Hyper Olympic - Winter 2000 (Japan)" description "Hyper Olympic - Winter 2000 (Japan)" - rom ( name "Hyper Olympic - Winter 2000 (Japan).gbc" size 1048576 crc A9B8F072 md5 167E663A1CE00E6A510DD8257FA36A48 sha1 B8B0EA6E8A1093E7171FFE0EFF73967A6CC00BCE flags verified ) + rom ( name "Hyper Olympic - Winter 2000 (Japan).gbc" size 1048576 crc a9b8f072 sha1 B8B0EA6E8A1093E7171FFE0EFF73967A6CC00BCE flags verified ) ) game ( - name "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced)" - description "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced)" - rom ( name "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 77F76EBC md5 1E67314232E073B75F092F058078074D sha1 6DABAFE260B53E61A810CBAE2F14287ADAFFFD8E flags verified ) + name "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Hyper Olympic Series - Track & Field GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 77f76ebc sha1 6DABAFE260B53E61A810CBAE2F14287ADAFFFD8E flags verified ) ) game ( name "Ide Yousuke no Mahjong Kyoushitsu GB (Japan)" description "Ide Yousuke no Mahjong Kyoushitsu GB (Japan)" - rom ( name "Ide Yousuke no Mahjong Kyoushitsu GB (Japan).gbc" size 2097152 crc 61DF88CA md5 C2432F63206255EE5E616C0D7862538C sha1 E4138F45980D60700C758BABFA1473C03B24D247 ) + rom ( name "Ide Yousuke no Mahjong Kyoushitsu GB (Japan).gbc" size 2097152 crc 61df88ca sha1 E4138F45980D60700C758BABFA1473C03B24D247 ) ) game ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De)" description "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De)" - rom ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 7FFF1142 md5 4ADC91B001CF02DC42D2C0339535B8F9 sha1 6D568438AA3B9B67C55ADED582CEC136B15C46D7 flags verified ) + rom ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 7fff1142 sha1 6D568438AA3B9B67C55ADED582CEC136B15C46D7 flags verified ) +) + +game ( + name "Infinity (USA) (Proto) (2001-03-22)" + description "Infinity (USA) (Proto) (2001-03-22)" + rom ( name "Infinity (USA) (Proto) (2001-03-22).gbc" size 2097152 crc 4ade94aa sha1 FDFD6D4CBEBBF64FC7D1264F0450BE270BE89823 flags verified ) ) game ( name "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl)" description "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 3390B056 md5 8B9A9F5125206B262348356BE15BF598 sha1 55C02B81FA854938CA3CB3E5B725A6A72F711E7B ) + rom ( name "Inspector Gadget - Operation Madkactus (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 3390b056 sha1 55C02B81FA854938CA3CB3E5B725A6A72F711E7B ) ) game ( name "Inspector Gadget - Operation Madkactus (USA)" description "Inspector Gadget - Operation Madkactus (USA)" - rom ( name "Inspector Gadget - Operation Madkactus (USA).gbc" size 1048576 crc 1AF0B489 md5 F9594360B2A4ED8745B63304063BAABB sha1 B0FA81A35E605948DF3B7F1FCB5893BAB99D9D6A ) + rom ( name "Inspector Gadget - Operation Madkactus (USA).gbc" size 1048576 crc 1af0b489 sha1 B0FA81A35E605948DF3B7F1FCB5893BAB99D9D6A ) ) game ( name "International Karate 2000 (Europe)" description "International Karate 2000 (Europe)" - rom ( name "International Karate 2000 (Europe).gbc" size 1048576 crc 12E00808 md5 86C1B5F04495E22EEDBEC15E1A320FF3 sha1 515477A2695F89827B2DC5495D9D43EC79A6CC09 ) + rom ( name "International Karate 2000 (Europe).gbc" size 1048576 crc 12e00808 sha1 515477A2695F89827B2DC5495D9D43EC79A6CC09 ) ) game ( - name "International Rally (USA) (SGB Enhanced)" - description "International Rally (USA) (SGB Enhanced)" - rom ( name "International Rally (USA) (SGB Enhanced).gbc" size 1048576 crc B85FD752 md5 8E1C9863CF7AD15C824F2AF6ACF130C4 sha1 AC09080EFB22ED401DDC827045E72AB054DA1763 ) + name "International Rally (USA) (SGB Enhanced) (GB Compatible)" + description "International Rally (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "International Rally (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b85fd752 sha1 AC09080EFB22ED401DDC827045E72AB054DA1763 flags verified ) ) game ( name "International Superstar Soccer 2000 (Europe)" description "International Superstar Soccer 2000 (Europe)" - rom ( name "International Superstar Soccer 2000 (Europe).gbc" size 2097152 crc 57EA1EC8 md5 C202F380D697A36347AA1FB628E89C4B sha1 3EF4ADAFF3A9D36DC6986A5944280162768C441D ) + rom ( name "International Superstar Soccer 2000 (Europe).gbc" size 2097152 crc 57ea1ec8 sha1 3EF4ADAFF3A9D36DC6986A5944280162768C441D ) ) game ( name "International Superstar Soccer 2000 (USA)" description "International Superstar Soccer 2000 (USA)" - rom ( name "International Superstar Soccer 2000 (USA).gbc" size 2097152 crc E8FA7203 md5 344B42A5BF2F591C0EC86CAE24238D6D sha1 117415D3620FAB07066CD5A3FFB438D05BFD940A ) + rom ( name "International Superstar Soccer 2000 (USA).gbc" size 2097152 crc e8fa7203 sha1 117415D3620FAB07066CD5A3FFB438D05BFD940A flags verified ) ) game ( - name "International Superstar Soccer 99 (Europe) (SGB Enhanced)" - description "International Superstar Soccer 99 (Europe) (SGB Enhanced)" - rom ( name "International Superstar Soccer 99 (Europe) (SGB Enhanced).gbc" size 1048576 crc 1B76D115 md5 DD1505A3F4D7289B37107C6A98931EB4 sha1 D9D9FFFB463D4C35F8A1A753908CDDFBE17FC671 flags verified ) + name "International Superstar Soccer 99 (Europe) (SGB Enhanced) (GB Compatible)" + description "International Superstar Soccer 99 (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "International Superstar Soccer 99 (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1b76d115 sha1 D9D9FFFB463D4C35F8A1A753908CDDFBE17FC671 flags verified ) ) game ( - name "International Superstar Soccer 99 (USA) (SGB Enhanced)" - description "International Superstar Soccer 99 (USA) (SGB Enhanced)" - serial "DMG-AWZE-USA" - rom ( name "International Superstar Soccer 99 (USA) (SGB Enhanced).gbc" size 1048576 crc 9D0290A7 md5 36DF5EBE75980AC4409DEAD125247BCE sha1 6F491E6F919A677627090F949B8E69ABB8BFD1DB ) + name "International Superstar Soccer 99 (USA) (SGB Enhanced) (GB Compatible)" + description "International Superstar Soccer 99 (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "International Superstar Soccer 99 (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9d0290a7 sha1 6F491E6F919A677627090F949B8E69ABB8BFD1DB flags verified ) ) game ( - name "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced)" - description "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced)" - rom ( name "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced).gbc" size 1048576 crc 327EC81F md5 C48AB40A864707E54688B9CF8DB15FAA sha1 3AECAC0876DAC69E9E1FB6F6C311D0AF050F1F48 flags verified ) + name "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced) (GB Compatible)" + description "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced) (GB Compatible)" + rom ( name "International Track & Field (Europe) (En,Fr,De,It) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 327ec81f sha1 3AECAC0876DAC69E9E1FB6F6C311D0AF050F1F48 flags verified ) ) game ( - name "International Track & Field (USA) (SGB Enhanced)" - description "International Track & Field (USA) (SGB Enhanced)" - rom ( name "International Track & Field (USA) (SGB Enhanced).gbc" size 1048576 crc 803D5D57 md5 F855638AD74A7B31CCA5786A32BB8868 sha1 80B7591470D0A26FE7CF5C80C8BFF5D34F79F569 ) + name "International Track & Field (USA) (SGB Enhanced) (GB Compatible)" + description "International Track & Field (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "International Track & Field (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 803d5d57 sha1 80B7591470D0A26FE7CF5C80C8BFF5D34F79F569 ) ) game ( name "International Track & Field - Summer Games (Europe)" description "International Track & Field - Summer Games (Europe)" - rom ( name "International Track & Field - Summer Games (Europe).gbc" size 1048576 crc D826C75F md5 B9795B5D6397D36C1666C3A0BADA059F sha1 53E158CB23FA79026345DAE775D9F020218F8BB2 flags verified ) + rom ( name "International Track & Field - Summer Games (Europe).gbc" size 1048576 crc d826c75f sha1 53E158CB23FA79026345DAE775D9F020218F8BB2 flags verified ) ) game ( - name "It's a World Rally (Japan) (SGB Enhanced)" - description "It's a World Rally (Japan) (SGB Enhanced)" - rom ( name "It's a World Rally (Japan) (SGB Enhanced).gbc" size 1048576 crc 39E34650 md5 EC3EF08BB6D73B1B57958322D1085DAD sha1 31A289823468285AC786AFE7DE38201235983E35 ) + name "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" + description "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 39e34650 sha1 31A289823468285AC786AFE7DE38201235983E35 ) ) game ( name "Itsudemo Pachinko GB - CR Monster House (Japan)" description "Itsudemo Pachinko GB - CR Monster House (Japan)" - rom ( name "Itsudemo Pachinko GB - CR Monster House (Japan).gbc" size 1048576 crc 834091BA md5 D5B4FD7FD703B447BCB8E1F78865208F sha1 C07C9FC27E0C2CAB09A55CD7C6A3ECC06DA13AEC ) + rom ( name "Itsudemo Pachinko GB - CR Monster House (Japan).gbc" size 1048576 crc 834091ba sha1 C07C9FC27E0C2CAB09A55CD7C6A3ECC06DA13AEC ) ) game ( name "J.League Excite Stage GB (Japan)" description "J.League Excite Stage GB (Japan)" - rom ( name "J.League Excite Stage GB (Japan).gbc" size 1048576 crc B3F38F16 md5 064F9DC3A19E5B6E41F646943254674E sha1 76F708659D790E1A2BF3915591499A4A8904974B ) + rom ( name "J.League Excite Stage GB (Japan).gbc" size 1048576 crc b3f38f16 sha1 76F708659D790E1A2BF3915591499A4A8904974B ) ) game ( name "J.League Excite Stage Tactics (Japan)" description "J.League Excite Stage Tactics (Japan)" - rom ( name "J.League Excite Stage Tactics (Japan).gbc" size 2097152 crc 558F4631 md5 2F93E10FD3392D96FFFCD10ABE7D9696 sha1 7862BE5EFE19D84B205062A7E77E5A317F7E17FC ) + rom ( name "J.League Excite Stage Tactics (Japan).gbc" size 2097152 crc 558f4631 sha1 7862BE5EFE19D84B205062A7E77E5A317F7E17FC ) ) game ( - name "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced)" - description "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced)" - rom ( name "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced).gbc" size 2097152 crc CFF5325A md5 58FF2F0F26205C5BD8C9AECB9973CB6A sha1 C2D9548E845ED9A76A0E6DAE81BB80023564A9F2 ) + name "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced) (GB Compatible)" + description "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Jack no Daibouken - Daimaou no Gyakushuu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cff5325a sha1 C2D9548E845ED9A76A0E6DAE81BB80023564A9F2 ) ) game ( - name "Jagainu-kun (Japan)" - description "Jagainu-kun (Japan)" - rom ( name "Jagainu-kun (Japan).gbc" size 1048576 crc AEB634C5 md5 2C8F92EA472FB0DBA87B45E9E580A84A sha1 C8CF0523C2CF562D2B2E79B2FE8845E6943A0BE4 flags verified ) + name "Jagainu-kun (Japan) (GB Compatible)" + description "Jagainu-kun (Japan) (GB Compatible)" + rom ( name "Jagainu-kun (Japan) (GB Compatible).gbc" size 1048576 crc aeb634c5 sha1 C8CF0523C2CF562D2B2E79B2FE8845E6943A0BE4 flags verified ) ) game ( name "Jankyuusei - Cosplay Paradise (Japan)" description "Jankyuusei - Cosplay Paradise (Japan)" - rom ( name "Jankyuusei - Cosplay Paradise (Japan).gbc" size 4194304 crc D60E1C0A md5 E923107E9C8B13A769371D041EE383D2 sha1 45DB3E3C0752C59FC20803945593FD8B9264240E ) + rom ( name "Jankyuusei - Cosplay Paradise (Japan).gbc" size 4194304 crc d60e1c0a sha1 45DB3E3C0752C59FC20803945593FD8B9264240E ) ) game ( name "Janosch - Das grosse Panama-Spiel (Germany)" description "Janosch - Das grosse Panama-Spiel (Germany)" - rom ( name "Janosch - Das grosse Panama-Spiel (Germany).gbc" size 1048576 crc 32C8EE13 md5 AF584EEA2B34AFDBB6193348ECB58F11 sha1 0B514E2B77B9DA69D10FA1F3D79C0727F625DE82 flags verified ) + rom ( name "Janosch - Das grosse Panama-Spiel (Germany).gbc" size 1048576 crc 32c8ee13 sha1 0B514E2B77B9DA69D10FA1F3D79C0727F625DE82 flags verified ) ) game ( name "Jay und die Spielzeugdiebe (Germany)" description "Jay und die Spielzeugdiebe (Germany)" - rom ( name "Jay und die Spielzeugdiebe (Germany).gbc" size 1048576 crc 73F4F6DA md5 29F2B4C6D1F163F728E79F9C7400E016 sha1 DD01D68BAB2D3615F173E4C9C94DA56248FAB580 flags verified ) + rom ( name "Jay und die Spielzeugdiebe (Germany).gbc" size 1048576 crc 73f4f6da sha1 DD01D68BAB2D3615F173E4C9C94DA56248FAB580 flags verified ) ) game ( - name "Jeff Gordon XS Racing (USA)" - description "Jeff Gordon XS Racing (USA)" - rom ( name "Jeff Gordon XS Racing (USA).gbc" size 1048576 crc A41ED926 md5 4E745E7FEBE4214C484D9C1E0A62AE57 sha1 3939BD5C3BA034EBB19395D4292F82B703629468 ) + name "Jeff Gordon XS Racing (USA) (GB Compatible)" + description "Jeff Gordon XS Racing (USA) (GB Compatible)" + rom ( name "Jeff Gordon XS Racing (USA) (GB Compatible).gbc" size 1048576 crc a41ed926 sha1 3939BD5C3BA034EBB19395D4292F82B703629468 ) ) game ( name "Jeremy McGrath Supercross 2000 (USA, Europe)" description "Jeremy McGrath Supercross 2000 (USA, Europe)" - rom ( name "Jeremy McGrath Supercross 2000 (USA, Europe).gbc" size 1048576 crc F0F9ABE6 md5 0143DBB62B1A88E7CCE65F9779CE9D4B sha1 5B48252BDE9F47D0FFD33F0E84CF30EC769946E7 flags verified ) + rom ( name "Jeremy McGrath Supercross 2000 (USA, Europe).gbc" size 1048576 crc f0f9abe6 sha1 5B48252BDE9F47D0FFD33F0E84CF30EC769946E7 flags verified ) ) game ( - name "Jet de Go! (Japan)" - description "Jet de Go! (Japan)" - rom ( name "Jet de Go! (Japan).gbc" size 2097152 crc 20C4CCF6 md5 2864C52D74320121BC8603E61F7DCE64 sha1 97BF75AFA0089DDB342EA7046B7CD113BA2C6FEC ) + name "Jet de Go! - Let's go by Airliner (Japan)" + description "Jet de Go! - Let's go by Airliner (Japan)" + rom ( name "Jet de Go! - Let's go by Airliner (Japan).gbc" size 2097152 crc 20c4ccf6 sha1 97BF75AFA0089DDB342EA7046B7CD113BA2C6FEC ) +) + +game ( + name "Jim Henson's Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl)" + description "Jim Henson's Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Jim Henson's Bear in the Big Blue House (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 48c99939 sha1 A5C2BB5244FE0FD6D2710C832F66F8F8B8C2BBAB flags verified ) +) + +game ( + name "Jim Henson's Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl)" + description "Jim Henson's Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl)" + rom ( name "Jim Henson's Bear in the Big Blue House (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 851c8710 sha1 E4C1C58025A083C067F752490C1FBD816C93D072 flags verified ) +) + +game ( + name "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P)" + description "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P)" + rom ( name "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P).gbc" size 2097152 crc 0fafa3f2 sha1 DC9288BC4B2A2093EA298514A91C3B2B4101691B flags verified ) +) + +game ( + name "Jim Henson's Muppets (USA)" + description "Jim Henson's Muppets (USA)" + rom ( name "Jim Henson's Muppets (USA).gbc" size 2097152 crc 3c476c6f sha1 77AD190AD107C57B167E3837757A4C7F990A867E ) +) + +game ( + name "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P) (GB Compatible)" + description "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P) (GB Compatible)" + rom ( name "Jim Henson's Muppets (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P) (GB Compatible).gbc" size 4194304 crc 3204b92c sha1 6E042FC6029493A429557A6FDCE111C03F9EDE1B flags verified ) ) game ( name "Jimmy White's Cueball (Europe)" description "Jimmy White's Cueball (Europe)" - rom ( name "Jimmy White's Cueball (Europe).gbc" size 1048576 crc 27632F4F md5 8E23226758BE3AE7A83803F9147ADA5E sha1 ED9A76A235EDD862F642B4DC974CD37126A267A8 flags verified ) + rom ( name "Jimmy White's Cueball (Europe).gbc" size 1048576 crc 27632f4f sha1 ED9A76A235EDD862F642B4DC974CD37126A267A8 flags verified ) ) game ( - name "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced)" - description "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced)" - rom ( name "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced).gbc" size 1048576 crc C8D46E99 md5 3C2A7051B554CF70183CFA5D99AD021F sha1 D2C4AE3808D9A24CBD4C6C8E43184CA0EF2D8373 flags verified ) + name "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced) (GB Compatible)" + description "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Jinsei Game - Tomodachi Takusan Tsukurou yo! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c8d46e99 sha1 D2C4AE3808D9A24CBD4C6C8E43184CA0EF2D8373 flags verified ) ) game ( name "Jisedai Begoma Battle Beyblade (Japan)" description "Jisedai Begoma Battle Beyblade (Japan)" - rom ( name "Jisedai Begoma Battle Beyblade (Japan).gbc" size 2097152 crc 9C56977E md5 E1836B1EC913A6BFA1E02FC250727FA9 sha1 FC2AF4EBD10CA20158D231089A8378F6C4641329 ) + rom ( name "Jisedai Begoma Battle Beyblade (Japan).gbc" size 2097152 crc 9c56977e sha1 FC2AF4EBD10CA20158D231089A8378F6C4641329 ) ) game ( - name "Jissen ni Yakudatsu Tsumego (Japan) (Rev A)" - description "Jissen ni Yakudatsu Tsumego (Japan) (Rev A)" - rom ( name "Jissen ni Yakudatsu Tsumego (Japan) (Rev A).gbc" size 262144 crc 55EFA05E md5 D315DC5767C97E99D3D2AEC84D6EA226 sha1 5FF7F6F2A1911E97EB71A3B3788A89745CFA5D31 flags verified ) + name "Jissen ni Yakudatsu Tsumego (Japan) (Rev 1)" + description "Jissen ni Yakudatsu Tsumego (Japan) (Rev 1)" + rom ( name "Jissen ni Yakudatsu Tsumego (Japan) (Rev 1).gbc" size 262144 crc 55efa05e sha1 5FF7F6F2A1911E97EB71A3B3788A89745CFA5D31 flags verified ) ) game ( - name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced)" - description "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced)" - rom ( name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced).gbc" size 1048576 crc 9FA5CDB5 md5 A36188FAE0070066BA5989CEBAF2A1B6 sha1 A332817B9561DCAB7D1F3DC0CF300E1656B253C3 ) + name "John Romero's Daikatana (Europe) (En,Fr,It)" + description "John Romero's Daikatana (Europe) (En,Fr,It)" + rom ( name "John Romero's Daikatana (Europe) (En,Fr,It).gbc" size 1048576 crc d9062e49 sha1 A5C5B52247B2AB78CD9CAD19AA752E07C3DF86EF ) +) + +game ( + name "John Romero's Daikatana (Europe) (Fr,De,Es)" + description "John Romero's Daikatana (Europe) (Fr,De,Es)" + rom ( name "John Romero's Daikatana (Europe) (Fr,De,Es).gbc" size 1048576 crc f7e83313 sha1 B699FC3BC587E5DF25235A6C7F74FEC307F476FE ) +) + +game ( + name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced) (GB Compatible)" + description "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Joryuu Janshi ni Chousen GB - Watashi-tachi ni Chousen Shitene! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9fa5cdb5 sha1 A332817B9561DCAB7D1F3DC0CF300E1656B253C3 ) ) game ( name "JumpStart Dino Adventure - Field Trip (USA)" description "JumpStart Dino Adventure - Field Trip (USA)" - rom ( name "JumpStart Dino Adventure - Field Trip (USA).gbc" size 1048576 crc 6D50772D md5 CC5A11A92E0A0F6F476341237EFA4B10 sha1 97D328C36FCB17A65D398F0696C819136D1B03DC ) + rom ( name "JumpStart Dino Adventure - Field Trip (USA).gbc" size 1048576 crc 6d50772d sha1 97D328C36FCB17A65D398F0696C819136D1B03DC ) ) game ( name "Jungle Book, The - Mowgli's Wild Adventure (Europe) (En,Fr,De,Es,It)" description "Jungle Book, The - Mowgli's Wild Adventure (Europe) (En,Fr,De,Es,It)" - rom ( name "Jungle Book, The - Mowgli's Wild Adventure (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc B609ECEA md5 173A37C4D4AAE04766AA0ABBF385233D sha1 960F8E7E7C72F3466EED4EBFA87FBF3B18053745 ) + rom ( name "Jungle Book, The - Mowgli's Wild Adventure (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc b609ecea sha1 960F8E7E7C72F3466EED4EBFA87FBF3B18053745 ) ) game ( name "Jungle Book, The - Mowgli's Wild Adventure (USA) (En,Fr,De,Es,It)" description "Jungle Book, The - Mowgli's Wild Adventure (USA) (En,Fr,De,Es,It)" - rom ( name "Jungle Book, The - Mowgli's Wild Adventure (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 9B6B755F md5 2F7BB3BEBBF2DEB2B8F3ED62D041FA57 sha1 A76A8692246893545663BE9D1E4A6F2C1370ED09 ) + rom ( name "Jungle Book, The - Mowgli's Wild Adventure (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 9b6b755f sha1 A76A8692246893545663BE9D1E4A6F2C1370ED09 ) ) game ( name "Jurassic Boy 2 (World) (Rev 1) (Sachen) (No Copyright) (Unl)" description "Jurassic Boy 2 (World) (Rev 1) (Sachen) (No Copyright) (Unl)" - rom ( name "Jurassic Boy 2 (World) (Rev 1) (Sachen) (No Copyright) (Unl).gbc" size 262144 crc A3BA0DB4 md5 06445DA47ED612C8F7FC8911C673F7FE sha1 1A2522D29CFBEB195488ED6EA79C36382B3B28BE ) + rom ( name "Jurassic Boy 2 (World) (Rev 1) (Sachen) (No Copyright) (Unl).gbc" size 262144 crc a3ba0db4 sha1 1A2522D29CFBEB195488ED6EA79C36382B3B28BE flags verified ) ) game ( name "Jurassic Boy II + Thunder Blast Man (World) (1B-002, 1B-003, Sachen) (Unl)" description "Jurassic Boy II + Thunder Blast Man (World) (1B-002, 1B-003, Sachen) (Unl) (included Sachen(R) copyright in the title screen - possibly an earlier revision)" - rom ( name "Jurassic Boy II + Thunder Blast Man (World) (1B-002, 1B-003, Sachen) (Unl).gbc" size 524288 crc 497BE52B md5 0834C2990995CBD2C76DB538FF93C5BA sha1 4D7F15ED30DCC6DDEEA1863EE8D786E3933CA92F flags verified ) + rom ( name "Jurassic Boy II + Thunder Blast Man (World) (1B-002, 1B-003, Sachen) (Unl).gbc" size 524288 crc 497be52b sha1 4D7F15ED30DCC6DDEEA1863EE8D786E3933CA92F flags verified ) ) game ( - name "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced)" - description "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced)" - rom ( name "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced).gbc" size 2097152 crc 4039C187 md5 5BD9F0923DC29BD9E566933C3C3E7902 sha1 A89304600330A62800751F16E231924FA9CF6E4D flags verified ) + name "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced) (GB Compatible)" + description "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Juukou Senki Bullet Battlers (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4039c187 sha1 A89304600330A62800751F16E231924FA9CF6E4D flags verified ) ) game ( name "K.O. - The Pro Boxing (Japan)" description "K.O. - The Pro Boxing (Japan)" - rom ( name "K.O. - The Pro Boxing (Japan).gbc" size 1048576 crc 69F08C89 md5 AE29AED4E24109E18FFE893DA6B77FEE sha1 6FCA09DABFCF087156263F656B80FF57065BCBFE ) + rom ( name "K.O. - The Pro Boxing (Japan).gbc" size 1048576 crc 69f08c89 sha1 6FCA09DABFCF087156263F656B80FF57065BCBFE ) ) game ( name "Kaept'n Blaubaer - Die verrueckte Schatzsuche (Germany)" description "Kaept'n Blaubaer - Die verrueckte Schatzsuche (Germany)" - rom ( name "Kaept'n Blaubaer - Die verrueckte Schatzsuche (Germany).gbc" size 1048576 crc 77E13DBE md5 433D5DF048561D0A276A56B210E25D9B sha1 57C29638D77E8A1589C411085AA2C99108D96BF2 flags verified ) + rom ( name "Kaept'n Blaubaer - Die verrueckte Schatzsuche (Germany).gbc" size 1048576 crc 77e13dbe sha1 57C29638D77E8A1589C411085AA2C99108D96BF2 flags verified ) ) game ( - name "Kaitei Densetsu!! Treasure World (Japan)" - description "Kaitei Densetsu!! Treasure World (Japan)" - rom ( name "Kaitei Densetsu!! Treasure World (Japan).gbc" size 1048576 crc 4C7258D9 md5 59FED43CD1489169D3C51B87988E7ABE sha1 FE1CBA586C0FF61628E52890B5AC40D1B7C4CBEE ) + name "Kaitei Densetsu!! Treasure World (Japan) (GB Compatible)" + description "Kaitei Densetsu!! Treasure World (Japan) (GB Compatible)" + rom ( name "Kaitei Densetsu!! Treasure World (Japan) (GB Compatible).gbc" size 1048576 crc 4c7258d9 sha1 FE1CBA586C0FF61628E52890B5AC40D1B7C4CBEE ) ) game ( - name "Kakurenbo Battle Monster Tactics (Japan)" - description "Kakurenbo Battle Monster Tactics (Japan)" - rom ( name "Kakurenbo Battle Monster Tactics (Japan).gbc" size 2097152 crc 9CFA76C3 md5 EA3CFB50763DF7977B3E45B280066742 sha1 45BF50F9FF80DF20D25D40CC8F78D829D6A8FAB7 flags verified ) + name "Kakurenbo Battle - Monster Tactics (Japan)" + description "Kakurenbo Battle - Monster Tactics (Japan)" + rom ( name "Kakurenbo Battle - Monster Tactics (Japan).gbc" size 2097152 crc 9cfa76c3 sha1 45BF50F9FF80DF20D25D40CC8F78D829D6A8FAB7 flags verified ) ) game ( - name "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced)" - description "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced)" - rom ( name "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced).gbc" size 1048576 crc 459A126B md5 F418CDE12A87673DA824D354A92F93E5 sha1 6A972325C07687B51FE6DBB3813BF54E1721668F flags verified ) + name "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kakutou Ryouri Densetsu Bistro Recipe - Gekitou Foodon Battle Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 459a126b sha1 6A972325C07687B51FE6DBB3813BF54E1721668F flags verified ) ) game ( - name "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced)" - description "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced)" - rom ( name "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced).gbc" size 1048576 crc 4FBEC464 md5 56D9D8B1DA2A329456A101031850E32B sha1 C9FA1B1A24A0098EADD7E3FA4EE19F1B615A618F ) + name "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kakutou Ryouri Densetsu Bistro Recipe - Kettou Bistgarm Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4fbec464 sha1 C9FA1B1A24A0098EADD7E3FA4EE19F1B615A618F flags verified ) ) game ( - name "Kanji Boy (Japan) (SGB Enhanced)" - description "Kanji Boy (Japan) (SGB Enhanced)" - rom ( name "Kanji Boy (Japan) (SGB Enhanced).gbc" size 4194304 crc 18CAA513 md5 53A98FBFDDC370EDD2DE8EB0AF5AA7AC sha1 3876D5F64113E5365B42D30945F51F40B1D22D47 ) + name "Kanji Boy (Japan) (SGB Enhanced) (GB Compatible)" + description "Kanji Boy (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kanji Boy (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 18caa513 sha1 3876D5F64113E5365B42D30945F51F40B1D22D47 flags verified ) ) game ( - name "Kanji Boy 2 (Japan) (SGB Enhanced)" - description "Kanji Boy 2 (Japan) (SGB Enhanced)" - rom ( name "Kanji Boy 2 (Japan) (SGB Enhanced).gbc" size 4194304 crc 81FD8918 md5 CE6CD6DCCC2DE88A8FDC4D08612AF359 sha1 4D382DE7FD6912C0CD8CA15032E6F75409D0A97B ) + name "Kanji Boy 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Kanji Boy 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kanji Boy 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 81fd8918 sha1 4D382DE7FD6912C0CD8CA15032E6F75409D0A97B ) ) game ( name "Kanji Boy 3 (Japan)" description "Kanji Boy 3 (Japan)" - rom ( name "Kanji Boy 3 (Japan).gbc" size 4194304 crc 2D4D8597 md5 51C8578D742AE2306B863776738F6772 sha1 EA9064F703354B7FBEEF0DD55084B16F2F7797BA ) + rom ( name "Kanji Boy 3 (Japan).gbc" size 4194304 crc 2d4d8597 sha1 EA9064F703354B7FBEEF0DD55084B16F2F7797BA flags verified ) ) game ( - name "Kanji de Puzzle (Japan)" - description "Kanji de Puzzle (Japan)" - rom ( name "Kanji de Puzzle (Japan).gbc" size 1048576 crc 25EFA1D7 md5 F274752501C49963B509168CB9CDD818 sha1 A0F108D3838AC820B2EE3167E93886B979115006 ) + name "Kanji de Puzzle (Japan) (GB Compatible)" + description "Kanji de Puzzle (Japan) (GB Compatible)" + rom ( name "Kanji de Puzzle (Japan) (GB Compatible).gbc" size 1048576 crc 25efa1d7 sha1 A0F108D3838AC820B2EE3167E93886B979115006 ) ) game ( - name "Kanzume Monsters Parfait (Japan) (SGB Enhanced)" - description "Kanzume Monsters Parfait (Japan) (SGB Enhanced)" - rom ( name "Kanzume Monsters Parfait (Japan) (SGB Enhanced).gbc" size 1048576 crc 6D5B59C0 md5 59B05DFC07CB8DE90DE975EA64AF29BD sha1 62F431D8E1EFDC93A36751CE5F4740D05D999348 ) + name "Kanzume Monsters Parfait (Japan) (SGB Enhanced) (GB Compatible)" + description "Kanzume Monsters Parfait (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kanzume Monsters Parfait (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6d5b59c0 sha1 62F431D8E1EFDC93A36751CE5F4740D05D999348 ) ) game ( - name "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced)" - description "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced)" - rom ( name "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced).gbc" size 1048576 crc 6C568E06 md5 72D6DC97291E659D0C36E977147C2FD2 sha1 9217169DC3F42562D71A7EDABC3B42E36EC8304B ) + name "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Karamuchou wa Oosawagi! - Okawari! (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6c568e06 sha1 9217169DC3F42562D71A7EDABC3B42E36EC8304B ) ) game ( - name "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced)" - description "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced)" - rom ( name "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced).gbc" size 1048576 crc DD948071 md5 2CB6BC70FB6A25E988BA4EBBA7F769D8 sha1 CB6079DC290ACE0DAAFDD40353E4477E4A37C8F7 ) + name "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced) (GB Compatible)" + description "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Karamuchou wa Oosawagi! - Polinkies to Okashina Nakama-tachi (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc dd948071 sha1 CB6079DC290ACE0DAAFDD40353E4477E4A37C8F7 ) ) game ( name "Karate Joe (Europe) (Unl)" description "Karate Joe (Europe) (Unl)" - rom ( name "Karate Joe (Europe) (Unl).gbc" size 262144 crc B8A54E29 md5 3ABEFFB860D9E7BEA74CE18D0E67029D sha1 BC9E760DCC851A01240B49B28CDE8FE5AB18DF91 flags verified ) + rom ( name "Karate Joe (Europe) (Unl).gbc" size 262144 crc b8a54e29 sha1 BC9E760DCC851A01240B49B28CDE8FE5AB18DF91 flags verified ) ) game ( - name "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced)" - description "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced)" - rom ( name "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced).gbc" size 1048576 crc BF80C897 md5 216CB5875DE8FC71D04F7378592BF782 sha1 857FB62DC310268E0B92E9383C6B6FD61AA33FA0 ) + name "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced) (GB Compatible)" + description "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kaseki Sousei Reborn II - Monster Digger (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bf80c897 sha1 857FB62DC310268E0B92E9383C6B6FD61AA33FA0 flags verified ) ) game ( - name "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced)" - description "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced)" - rom ( name "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced).gbc" size 1048576 crc A262269F md5 E96FAD823B6771C00C04DAB88EDE40BB sha1 C3BA0D2B82D66EF1B5C0DEE8813A5F965631ED75 ) + name "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible)" + description "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Katou Hifumi Kudan - Shougi Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc a262269f sha1 C3BA0D2B82D66EF1B5C0DEE8813A5F965631ED75 ) ) game ( - name "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced)" - description "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced)" - rom ( name "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc F0B09DDB md5 8CE641B1EFBF76CC5F2A841942345A0F sha1 DBDAC654D4056ADE51A139614192742CE8800D7E flags verified ) + name "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Kawa no Nushi Tsuri 4 (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f0b09ddb sha1 DBDAC654D4056ADE51A139614192742CE8800D7E flags verified ) ) game ( - name "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced)" - description "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced)" - rom ( name "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced).gbc" size 1048576 crc 44767443 md5 C8FF99C216603FF09733BB4F80E2BC61 sha1 8392ECCBAC1D8AE23782C6D29D3EE604A03B5C05 flags verified ) + name "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced) (GB Compatible)" + description "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kawaii Pet Shop Monogatari (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 44767443 sha1 8392ECCBAC1D8AE23782C6D29D3EE604A03B5C05 flags verified ) ) game ( - name "Kawaii Pet Shop Monogatari 2 (Japan)" - description "Kawaii Pet Shop Monogatari 2 (Japan)" - rom ( name "Kawaii Pet Shop Monogatari 2 (Japan).gbc" size 2097152 crc 3791DCA1 md5 25BD0EC7F8959A9A29C4AF3C7D6FDDDE sha1 76DC291937ADBE7EBAB4C1681ECF1FC7EA3A6074 ) + name "Kawaii Pet Shop Monogatari 2 (Japan) (GB Compatible)" + description "Kawaii Pet Shop Monogatari 2 (Japan) (GB Compatible)" + rom ( name "Kawaii Pet Shop Monogatari 2 (Japan) (GB Compatible).gbc" size 2097152 crc 3791dca1 sha1 76DC291937ADBE7EBAB4C1681ECF1FC7EA3A6074 ) +) + +game ( + name "Kawaii Pet Shop Monogatari 2 (Japan) (Rev 1) (GB Compatible)" + description "Kawaii Pet Shop Monogatari 2 (Japan) (Rev 1) (GB Compatible)" + rom ( name "Kawaii Pet Shop Monogatari 2 (Japan) (Rev 1) (GB Compatible).gbc" size 2097152 crc 6fce1ad0 sha1 58EA410EBBEE5EDC18644C0467FE9EA03D179B1C flags verified ) ) game ( name "Keep the Balance (Europe) (En,Fr,De,Es,It)" description "Keep the Balance (Europe) (En,Fr,De,Es,It)" - rom ( name "Keep the Balance (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc B868E846 md5 D5161ED7380AF488B22302691C9A33CD sha1 A0BBBB00F0AD1C62AD766B378C9A6C15FBD54991 flags verified ) + rom ( name "Keep the Balance (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc b868e846 sha1 A0BBBB00F0AD1C62AD766B378C9A6C15FBD54991 flags verified ) ) game ( - name "Keibajou e Ikou! Wide (Japan)" - description "Keibajou e Ikou! Wide (Japan)" - rom ( name "Keibajou e Ikou! Wide (Japan).gbc" size 1048576 crc 710286EA md5 1E842A5C2F90BF6E476B08DA5333963D sha1 120C3888F7206AC8B06CEA5E9B81DBCD87109EBF ) + name "Keibajou e Ikou! Wide (Japan) (GB Compatible)" + description "Keibajou e Ikou! Wide (Japan) (GB Compatible)" + rom ( name "Keibajou e Ikou! Wide (Japan) (GB Compatible).gbc" size 1048576 crc 710286ea sha1 120C3888F7206AC8B06CEA5E9B81DBCD87109EBF ) ) game ( - name "Keitai Denjuu Telefang - Power Version (Japan)" - description "Keitai Denjuu Telefang - Power Version (Japan)" - serial "(PA)DMG-BTXJ-JPN" - rom ( name "Keitai Denjuu Telefang - Power Version (Japan).gbc" size 2097152 crc 8B61CFCC md5 04F7EA139FEF2BC2E3F70B2C23933D2E sha1 BAAF7FB9F9958CA22982BA0600BC0CB8A7FC4764 ) + name "Keitai Denjuu Telefang - Power Version (Japan) (GB Compatible)" + description "Keitai Denjuu Telefang - Power Version (Japan) (GB Compatible)" + rom ( name "Keitai Denjuu Telefang - Power Version (Japan) (GB Compatible).gbc" size 2097152 crc 8b61cfcc sha1 BAAF7FB9F9958CA22982BA0600BC0CB8A7FC4764 flags verified ) ) game ( - name "Keitai Denjuu Telefang - Speed Version (Japan)" - description "Keitai Denjuu Telefang - Speed Version (Japan)" - rom ( name "Keitai Denjuu Telefang - Speed Version (Japan).gbc" size 2097152 crc FB528F66 md5 EBFE05828463CC004898E6A95EE57FEA sha1 1C273F9078C580E85E5C49E7114058F3E0FE5CCA flags verified ) + name "Keitai Denjuu Telefang - Speed Version (Japan) (GB Compatible)" + description "Keitai Denjuu Telefang - Speed Version (Japan) (GB Compatible)" + rom ( name "Keitai Denjuu Telefang - Speed Version (Japan) (GB Compatible).gbc" size 2097152 crc fb528f66 sha1 1C273F9078C580E85E5C49E7114058F3E0FE5CCA flags verified ) ) game ( - name "Kelly Club - Clubhouse Fun (USA)" - description "Kelly Club - Clubhouse Fun (USA)" - rom ( name "Kelly Club - Clubhouse Fun (USA).gbc" size 1048576 crc 6E39EBC4 md5 0107666C622E3BF3E225ECC6FE4FEE42 sha1 D47519A0295C3A76BC68C54AE94CCCE039BCD3EE ) + name "Kelly Club (USA)" + description "Kelly Club (USA)" + rom ( name "Kelly Club (USA).gbc" size 1048576 crc 6e39ebc4 sha1 D47519A0295C3A76BC68C54AE94CCCE039BCD3EE ) ) game ( name "Ken Griffey Jr.'s Slugfest (USA)" description "Ken Griffey Jr.'s Slugfest (USA)" - rom ( name "Ken Griffey Jr.'s Slugfest (USA).gbc" size 1048576 crc 1E64D19C md5 869D388027E0498E3D9994B0DC71984A sha1 2362BDD8C26F30ADB871259CE2D909AC6D505E36 ) + rom ( name "Ken Griffey Jr.'s Slugfest (USA).gbc" size 1048576 crc 1e64d19c sha1 2362BDD8C26F30ADB871259CE2D909AC6D505E36 ) ) game ( - name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced)" - description "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced)" - rom ( name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced).gbc" size 1048576 crc 72895639 md5 ADFB8D9DC0D5633B1C385BE79F3B425F sha1 DB690F46D37E0273C69F24BADBB44588A363A84F ) + name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" + description "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kettou Transformers Beast Wars - Beast Senshi Saikyou Ketteisen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 72895639 sha1 DB690F46D37E0273C69F24BADBB44588A363A84F flags verified ) ) game ( name "Kidou Senkan Nadesico - Ruri Ruri Mahjong (Japan)" description "Kidou Senkan Nadesico - Ruri Ruri Mahjong (Japan)" - rom ( name "Kidou Senkan Nadesico - Ruri Ruri Mahjong (Japan).gbc" size 2097152 crc 6427CD7A md5 3F26686ACCD8714584B966D277973873 sha1 7F3F408F3835BC8AA9312BA76374436BFBE136FE flags verified ) + rom ( name "Kidou Senkan Nadesico - Ruri Ruri Mahjong (Japan).gbc" size 2097152 crc 6427cd7a sha1 7F3F408F3835BC8AA9312BA76374436BFBE136FE flags verified ) ) game ( name "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan)" description "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan)" - rom ( name "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan).gbc" size 1048576 crc 223BB19C md5 1A0AAC7A746E247879D6B970BF9A9F32 sha1 8ABD4406EC19BFECD6D675285FA73EF2D5EA622E ) + rom ( name "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan).gbc" size 1048576 crc 223bb19c sha1 8ABD4406EC19BFECD6D675285FA73EF2D5EA622E flags verified ) ) game ( - name "Kindaichi Shounen no Jikenbo - 10nenme no Shoutaijou (Japan) (SGB Enhanced)" - description "Kindaichi Shounen no Jikenbo - 10nenme no Shoutaijou (Japan) (SGB Enhanced)" - rom ( name "Kindaichi Shounen no Jikenbo - 10nenme no Shoutaijou (Japan) (SGB Enhanced).gbc" size 2097152 crc DE52FFDC md5 3AD65B50C81A79F826EEDC19EDCF48F4 sha1 468EA148EB15EAC3B771A2520E0B5248EA5085A1 ) + name "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible)" + description "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kindaichi Shounen no Jikenbo - 10 Nenme no Shoutaijou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc de52ffdc sha1 468EA148EB15EAC3B771A2520E0B5248EA5085A1 ) ) game ( - name "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced)" - description "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced)" - rom ( name "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced).gbc" size 1048576 crc E2E4328B md5 D4876D692DCB6CA68786E1DF3AF361A6 sha1 75D7E35FEA257D8DA4C1EFCDD6EBDCA020C648A6 flags verified ) + name "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced) (GB Compatible)" + description "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kinniku Banzuke GB - Chousensha wa Kimida! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e2e4328b sha1 75D7E35FEA257D8DA4C1EFCDD6EBDCA020C648A6 flags verified ) ) game ( - name "Kinniku Banzuke GB2 - Mezase! Muscle Champion (Japan) (SGB Enhanced)" - description "Kinniku Banzuke GB2 - Mezase! Muscle Champion (Japan) (SGB Enhanced)" - rom ( name "Kinniku Banzuke GB2 - Mezase! Muscle Champion (Japan) (SGB Enhanced).gbc" size 2097152 crc 42DE9092 md5 20102ABB2A331FF4CC101D3513C891CD sha1 5EA803B820FF865A4470D7F82B36DA6B82F3CAEC flags verified ) + name "Kinniku Banzuke GB 2 - Mezase! Muscle Champion (Japan) (SGB Enhanced) (GB Compatible)" + description "Kinniku Banzuke GB 2 - Mezase! Muscle Champion (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Kinniku Banzuke GB 2 - Mezase! Muscle Champion (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 42de9092 sha1 5EA803B820FF865A4470D7F82B36DA6B82F3CAEC flags verified ) ) game ( - name "Kinniku Banzuke GB3 - Shinseiki Survival Retsuden! (Japan)" - description "Kinniku Banzuke GB3 - Shinseiki Survival Retsuden! (Japan)" - rom ( name "Kinniku Banzuke GB3 - Shinseiki Survival Retsuden! (Japan).gbc" size 4194304 crc E2F6253E md5 C0B8EDC2CCEFC3ED95CF68C84A813609 sha1 2E5D5ADCDBEDF45C6EBDA0F90CCFA787A24C24D0 ) + name "Kinniku Banzuke GB 3 - Shinseiki Survival Retsuden! (Japan)" + description "Kinniku Banzuke GB 3 - Shinseiki Survival Retsuden! (Japan)" + rom ( name "Kinniku Banzuke GB 3 - Shinseiki Survival Retsuden! (Japan).gbc" size 4194304 crc e2f6253e sha1 2E5D5ADCDBEDF45C6EBDA0F90CCFA787A24C24D0 flags verified ) ) game ( name "Kirby - Tilt 'n' Tumble (USA)" description "Kirby - Tilt 'n' Tumble (USA)" - rom ( name "Kirby - Tilt 'n' Tumble (USA).gbc" size 1048576 crc E541ACF1 md5 F2E24776D93082362C9B435ABC167D89 sha1 6AB8D666E2BEBBB3FEE7796C8968AAB2EA21B8F9 flags verified ) + rom ( name "Kirby - Tilt 'n' Tumble (USA).gbc" size 1048576 crc e541acf1 sha1 6AB8D666E2BEBBB3FEE7796C8968AAB2EA21B8F9 flags verified ) ) game ( name "Kirikou (Europe) (En,Fr,De,Es,It,Pt)" description "Kirikou (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Kirikou (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 783BC02D md5 469EE8270B66DAD56379B29D160EE48C sha1 B047DB711BBEF8F8D32FB64AA8E120FC01D1FB76 ) -) - -game ( - name "Kisekae Monogatari (Japan) (SGB Enhanced)" - description "Kisekae Monogatari (Japan) (SGB Enhanced)" - rom ( name "Kisekae Monogatari (Japan) (SGB Enhanced).gbc" size 2097152 crc 934F4B0A md5 EFC589169180E3B278BE99AF8CAE1A64 sha1 8BDD3BD414DA91C6EA05BC29435E09B0B72E3790 ) + rom ( name "Kirikou (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 783bc02d sha1 B047DB711BBEF8F8D32FB64AA8E120FC01D1FB76 ) ) game ( name "Kisekae Series 2 - Oshare Nikki (Japan)" description "Kisekae Series 2 - Oshare Nikki (Japan)" - rom ( name "Kisekae Series 2 - Oshare Nikki (Japan).gbc" size 2097152 crc 948F4A96 md5 D01E66FA8D96D2C6B1FD029856D7C14B sha1 054065759FF04C508378796CA12A4B578E1C174C ) + rom ( name "Kisekae Series 2 - Oshare Nikki (Japan).gbc" size 2097152 crc 948f4a96 sha1 054065759FF04C508378796CA12A4B578E1C174C ) ) game ( - name "Kisekae Series 2 - Oshare Nikki (Japan) (Rev A)" - description "Kisekae Series 2 - Oshare Nikki (Japan) (Rev A)" - rom ( name "Kisekae Series 2 - Oshare Nikki (Japan) (Rev A).gbc" size 2097152 crc E915337C md5 6B63533C97A27DEDC48AAE58D4E47C1F sha1 1896EC1AA7EDB56774AFA5D8B93E941AA1E838EB flags verified ) + name "Kisekae Series 2 - Oshare Nikki (Japan) (Rev 1)" + description "Kisekae Series 2 - Oshare Nikki (Japan) (Rev 1)" + rom ( name "Kisekae Series 2 - Oshare Nikki (Japan) (Rev 1).gbc" size 2097152 crc e915337c sha1 1896EC1AA7EDB56774AFA5D8B93E941AA1E838EB flags verified ) ) game ( name "Kisekae Series 3 - Kisekae Hamster (Japan)" description "Kisekae Series 3 - Kisekae Hamster (Japan)" - rom ( name "Kisekae Series 3 - Kisekae Hamster (Japan).gbc" size 2097152 crc A29D862F md5 6736E0DC64FA3584ED48B1A9D845ABCB sha1 76C0F2E1559FFEC3C77043A6DF08B6E7240854E2 ) + rom ( name "Kisekae Series 3 - Kisekae Hamster (Japan).gbc" size 2097152 crc a29d862f sha1 76C0F2E1559FFEC3C77043A6DF08B6E7240854E2 flags verified ) ) game ( name "Klax (USA, Europe)" description "Klax (USA, Europe)" - rom ( name "Klax (USA, Europe).gbc" size 1048576 crc 7181CBD0 md5 3BD0DAD0C695A534B9E89264E09E2B11 sha1 23B5601748BDA8E0DBA69E589FA2B6D2D79781B3 flags verified ) + rom ( name "Klax (USA, Europe).gbc" size 1048576 crc 7181cbd0 sha1 23B5601748BDA8E0DBA69E589FA2B6D2D79781B3 flags verified ) ) game ( - name "Klustar (Europe) (En,Fr,De,Es,It)" - description "Klustar (Europe) (En,Fr,De,Es,It)" - rom ( name "Klustar (Europe) (En,Fr,De,Es,It).gbc" size 262144 crc 577E1521 md5 ACB6B136FA26888D42B5F95871A75EAA sha1 B78D832E5D39180D84BF13DDE81B923717CB35AA flags verified ) + name "Klustar (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Klustar (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Klustar (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 262144 crc 577e1521 sha1 B78D832E5D39180D84BF13DDE81B923717CB35AA flags verified ) ) game ( - name "Klustar (USA)" - description "Klustar (USA)" - rom ( name "Klustar (USA).gbc" size 262144 crc 3F8D6041 md5 D0308455BA266CC5B0CD6CA9B671CB4B sha1 096748F23F61E83837568C4070A34572D11FF48E ) + name "Klustar (USA) (GB Compatible)" + description "Klustar (USA) (GB Compatible)" + rom ( name "Klustar (USA) (GB Compatible).gbc" size 262144 crc 3f8d6041 sha1 096748F23F61E83837568C4070A34572D11FF48E ) ) game ( name "Knockout Kings (USA, Europe)" description "Knockout Kings (USA, Europe)" - rom ( name "Knockout Kings (USA, Europe).gbc" size 1048576 crc A0D64934 md5 64FA89B64514A71651C1B8DC629BA8F3 sha1 A04D86A384C5C417BF9F1219EB14829D0459F469 flags verified ) + rom ( name "Knockout Kings (USA, Europe).gbc" size 1048576 crc a0d64934 sha1 A04D86A384C5C417BF9F1219EB14829D0459F469 flags verified ) ) game ( name "Koenig der Loewen, Der - Simbas grosses Abenteuer (Germany)" description "Koenig der Loewen, Der - Simbas grosses Abenteuer (Germany)" - rom ( name "Koenig der Loewen, Der - Simbas grosses Abenteuer (Germany).gbc" size 1048576 crc EA11E39C md5 BB8E268F1413ADBBBF8654DAA5C645B4 sha1 E04DAABFDB6C9147A030FFB892BF77EAFB1B0BA2 ) + rom ( name "Koenig der Loewen, Der - Simbas grosses Abenteuer (Germany).gbc" size 1048576 crc ea11e39c sha1 E04DAABFDB6C9147A030FFB892BF77EAFB1B0BA2 flags verified ) ) game ( - name "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced)" - description "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced)" - rom ( name "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced).gbc" size 1048576 crc D6050F64 md5 7187FE377729DB40928FB6C6EE5A0809 sha1 6BF1D7517C762A8B692E149529D826504B8F483E ) + name "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Koguru Guruguru - Guruguru to Nakayoshi (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d6050f64 sha1 6BF1D7517C762A8B692E149529D826504B8F483E ) ) game ( - name "Konami GB Collection Vol.1 (Europe)" - description "Konami GB Collection Vol.1 (Europe)" - rom ( name "Konami GB Collection Vol.1 (Europe).gbc" size 1048576 crc 203F8727 md5 70CCAF1C458DC09B7C703191EF9B8541 sha1 760ABB9E3950F39BF01320E414A4F4D516E04C83 ) + name "Konami GB Collection Vol.1 (Europe) (GB Compatible)" + description "Konami GB Collection Vol.1 (Europe) (GB Compatible)" + rom ( name "Konami GB Collection Vol.1 (Europe) (GB Compatible).gbc" size 1048576 crc 203f8727 sha1 760ABB9E3950F39BF01320E414A4F4D516E04C83 ) ) game ( - name "Konami GB Collection Vol.2 (Europe)" - description "Konami GB Collection Vol.2 (Europe)" - rom ( name "Konami GB Collection Vol.2 (Europe).gbc" size 1048576 crc A6499792 md5 ED679655B3721327EA36C857C554427A sha1 7A726CAC1D459986EDEBD2CC8F4A84D7369353DD flags verified ) + name "Konami GB Collection Vol.2 (Europe) (GB Compatible)" + description "Konami GB Collection Vol.2 (Europe) (GB Compatible)" + rom ( name "Konami GB Collection Vol.2 (Europe) (GB Compatible).gbc" size 1048576 crc a6499792 sha1 7A726CAC1D459986EDEBD2CC8F4A84D7369353DD flags verified ) ) game ( - name "Konami GB Collection Vol.3 (Europe)" - description "Konami GB Collection Vol.3 (Europe)" - rom ( name "Konami GB Collection Vol.3 (Europe).gbc" size 1048576 crc D4D6243D md5 98F7778539E22307D074CF0ABB37D05C sha1 748248B0F837B89F00A8AF868F2262D27302EB5C flags verified ) + name "Konami GB Collection Vol.3 (Europe) (GB Compatible)" + description "Konami GB Collection Vol.3 (Europe) (GB Compatible)" + rom ( name "Konami GB Collection Vol.3 (Europe) (GB Compatible).gbc" size 1048576 crc d4d6243d sha1 748248B0F837B89F00A8AF868F2262D27302EB5C flags verified ) ) game ( - name "Konami GB Collection Vol.4 (Europe)" - description "Konami GB Collection Vol.4 (Europe)" - rom ( name "Konami GB Collection Vol.4 (Europe).gbc" size 1048576 crc 8800F1C9 md5 F3414D53473E2CC43347774CC5F40495 sha1 4C0C9E9CBA36BFE5588E2A2DC799D207AFD1321E flags verified ) + name "Konami GB Collection Vol.4 (Europe) (GB Compatible)" + description "Konami GB Collection Vol.4 (Europe) (GB Compatible)" + rom ( name "Konami GB Collection Vol.4 (Europe) (GB Compatible).gbc" size 1048576 crc 8800f1c9 sha1 4C0C9E9CBA36BFE5588E2A2DC799D207AFD1321E flags verified ) ) game ( name "Konami Winter Games (Europe)" description "Konami Winter Games (Europe)" - rom ( name "Konami Winter Games (Europe).gbc" size 1048576 crc 1C644040 md5 538F4D9036A7841CB157B9023346C540 sha1 2B51F52560226DEC0467E5BF4897CD12E8453888 ) + rom ( name "Konami Winter Games (Europe).gbc" size 1048576 crc 1c644040 sha1 2B51F52560226DEC0467E5BF4897CD12E8453888 ) ) game ( name "Konchuu Fighters (Japan)" description "Konchuu Fighters (Japan)" - rom ( name "Konchuu Fighters (Japan).gbc" size 2097152 crc C6758B0B md5 E27E5D2079FB84A439DBAFDA7C6E2EF1 sha1 8BB171B72C3BB761DE07954299B5AA379145E8F1 ) + rom ( name "Konchuu Fighters (Japan).gbc" size 2097152 crc c6758b0b sha1 8BB171B72C3BB761DE07954299B5AA379145E8F1 flags verified ) ) game ( - name "Konchuu Hakase 2 (Japan) (SGB Enhanced)" - description "Konchuu Hakase 2 (Japan) (SGB Enhanced)" - rom ( name "Konchuu Hakase 2 (Japan) (SGB Enhanced).gbc" size 2097152 crc B6381744 md5 0DB5276E6A52112BCB71DD20F4F39782 sha1 E4BCFB94AA1C09A013A03F26F978B32E74F70D23 flags verified ) + name "Konchuu Hakase 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Konchuu Hakase 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Konchuu Hakase 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b6381744 sha1 E4BCFB94AA1C09A013A03F26F978B32E74F70D23 flags verified ) ) game ( name "Konchuu Hakase 3 (Japan)" description "Konchuu Hakase 3 (Japan)" - rom ( name "Konchuu Hakase 3 (Japan).gbc" size 2097152 crc 380F19ED md5 41B5E9D960CEAFC89E8BD740C2C74DC5 sha1 4066434FE741A071E2072AEE44FDF1B5EECDE258 ) + rom ( name "Konchuu Hakase 3 (Japan).gbc" size 2097152 crc 380f19ed sha1 4066434FE741A071E2072AEE44FDF1B5EECDE258 ) ) game ( name "Korokoro Kirby (Japan)" description "Korokoro Kirby (Japan)" - rom ( name "Korokoro Kirby (Japan).gbc" size 1048576 crc C0FACE3D md5 6AE02BF9FC6765129B06734AC13E4DA4 sha1 8DD46F6D34C831C910C4574F252FA47CE6F67261 flags verified ) + rom ( name "Korokoro Kirby (Japan).gbc" size 1048576 crc c0face3d sha1 8DD46F6D34C831C910C4574F252FA47CE6F67261 flags verified ) ) game ( name "Koto Battle - Tengai no Moribito (Japan)" description "Koto Battle - Tengai no Moribito (Japan)" - rom ( name "Koto Battle - Tengai no Moribito (Japan).gbc" size 2097152 crc 430EB1E1 md5 43351CD46357BD1615A713490401FDA8 sha1 AC30025352026B34A0D9CCEDE82862F6E04AAF00 ) + rom ( name "Koto Battle - Tengai no Moribito (Japan).gbc" size 2097152 crc 430eb1e1 sha1 AC30025352026B34A0D9CCEDE82862F6E04AAF00 ) ) game ( - name "Koushien Pocket (Japan) (SGB Enhanced)" - description "Koushien Pocket (Japan) (SGB Enhanced)" - rom ( name "Koushien Pocket (Japan) (SGB Enhanced).gbc" size 1048576 crc 6910FF3A md5 5C07E6AFF1E2CDAC8EC09554981AB0C9 sha1 A677BF07C67925DED32799D6A8EB63EC99C01BB7 ) + name "Koushien Pocket (Japan) (SGB Enhanced) (GB Compatible)" + description "Koushien Pocket (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Koushien Pocket (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6910ff3a sha1 A677BF07C67925DED32799D6A8EB63EC99C01BB7 flags verified ) ) game ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It)" description "Land Before Time, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc F253E082 md5 634C5B73113B589530BC70CFB5CE3598 sha1 9D7A8B923116093B9EE9415603A4AC9D15DCF8E3 ) + rom ( name "Land Before Time, The (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc f253e082 sha1 9D7A8B923116093B9EE9415603A4AC9D15DCF8E3 flags verified ) ) game ( name "Land Before Time, The (USA)" description "Land Before Time, The (USA)" - rom ( name "Land Before Time, The (USA).gbc" size 1048576 crc BCE9CB16 md5 691D6D252E22CBC7F039D0975582CA8F sha1 320524E7EE7061AF3BB6E89A0C4B68C517A75752 ) + rom ( name "Land Before Time, The (USA).gbc" size 1048576 crc bce9cb16 sha1 320524E7EE7061AF3BB6E89A0C4B68C517A75752 ) ) game ( - name "Las Vegas Cool Hand (USA)" - description "Las Vegas Cool Hand (USA)" - rom ( name "Las Vegas Cool Hand (USA).gbc" size 524288 crc BEF1CDE4 md5 BA205296796AD7CDC8CA180B280714D1 sha1 C7423C03E5976F85DE361FE1B83DFEE11E75A60F flags verified ) + name "Las Vegas Cool Hand (USA) (GB Compatible)" + description "Las Vegas Cool Hand (USA) (GB Compatible)" + rom ( name "Las Vegas Cool Hand (USA) (GB Compatible).gbc" size 524288 crc bef1cde4 sha1 C7423C03E5976F85DE361FE1B83DFEE11E75A60F flags verified ) ) game ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gbc" size 1048576 crc F90A3DAE md5 37824FAEEDC1D562CAE1CEEE675C6AC8 sha1 772539821E4B703259B2E2AD535D74A03FA22760 ) + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da).gbc" size 1048576 crc f90a3dae sha1 772539821E4B703259B2E2AD535D74A03FA22760 ) ) game ( name "Laura (USA)" description "Laura (USA)" - rom ( name "Laura (USA).gbc" size 1048576 crc E2BFF286 md5 637B90B33AEB3688187C6AC73DB3488E sha1 3FE3EB99EE818C94E9A07E19640AF6A2AAD33903 ) + rom ( name "Laura (USA).gbc" size 1048576 crc e2bff286 sha1 3FE3EB99EE818C94E9A07E19640AF6A2AAD33903 flags verified ) ) game ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" description "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It)" - rom ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1B49D07D md5 165550E557314F88DECD95A7409A24CE sha1 CB4847CD63C8CC52F04BF4D86D54954BE3D8FC1A ) + rom ( name "Le Mans 24 Hours (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1b49d07d sha1 CB4847CD63C8CC52F04BF4D86D54954BE3D8FC1A ) ) game ( - name "Legend of the River King 2 (Europe) (SGB Enhanced)" - description "Legend of the River King 2 (Europe) (SGB Enhanced)" - rom ( name "Legend of the River King 2 (Europe) (SGB Enhanced).gbc" size 1048576 crc F24D010A md5 052CD45A69AF16F025A545B29BC8F450 sha1 AE8EE704B968576CF2CD0A93DC5B42F8F63C48EB ) + name "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" + description "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f24d010a sha1 AE8EE704B968576CF2CD0A93DC5B42F8F63C48EB ) ) game ( - name "Legend of the River King 2 (USA) (SGB Enhanced)" - description "Legend of the River King 2 (USA) (SGB Enhanced)" - rom ( name "Legend of the River King 2 (USA) (SGB Enhanced).gbc" size 1048576 crc 840FD525 md5 3519C45CE55AAD2F0565513723C90672 sha1 1155F2D5CC56C8275855B02A8B3826648CC5E904 ) + name "Legend of the River King 2 (USA) (SGB Enhanced) (GB Compatible)" + description "Legend of the River King 2 (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of the River King 2 (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 840fd525 sha1 1155F2D5CC56C8275855B02A8B3826648CC5E904 ) ) game ( - name "Legend of the River King GB (Europe) (SGB Enhanced)" - description "Legend of the River King GB (Europe) (SGB Enhanced)" - rom ( name "Legend of the River King GB (Europe) (SGB Enhanced).gbc" size 1048576 crc 87EF9530 md5 CB5FE636114FCB0925D08CECED82DC23 sha1 31A5A32625532DED19D6ECCFC283C4F049AE31B5 ) + name "Legend of the River King GB (Europe) (SGB Enhanced) (GB Compatible)" + description "Legend of the River King GB (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of the River King GB (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 87ef9530 sha1 31A5A32625532DED19D6ECCFC283C4F049AE31B5 ) ) game ( - name "Legend of the River King GB (Germany) (SGB Enhanced)" - description "Legend of the River King GB (Germany) (SGB Enhanced)" - rom ( name "Legend of the River King GB (Germany) (SGB Enhanced).gbc" size 1048576 crc 1241F3F5 md5 C74C40B7DA1A54568F4D5CCD3EB56090 sha1 E0E0522BA283DF632ADBF2FE6F9ABA85E1A7EFEC ) + name "Legend of the River King GB (Germany) (SGB Enhanced) (GB Compatible)" + description "Legend of the River King GB (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of the River King GB (Germany) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1241f3f5 sha1 E0E0522BA283DF632ADBF2FE6F9ABA85E1A7EFEC ) ) game ( - name "Legend of the River King GB (USA) (SGB Enhanced)" - description "Legend of the River King GB (USA) (SGB Enhanced)" - rom ( name "Legend of the River King GB (USA) (SGB Enhanced).gbc" size 1048576 crc 7E821F47 md5 B397066E3CAD5AE33A31E4ADFFF0BFF5 sha1 1773C4719C3134845A91FEF3A897034D5A70825E ) + name "Legend of the River King GBC (USA) (SGB Enhanced) (GB Compatible)" + description "Legend of the River King GBC (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of the River King GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7e821f47 sha1 1773C4719C3134845A91FEF3A897034D5A70825E ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced).gbc" size 1048576 crc F48824FE md5 1043FD167D0ED9C4094E3C9D8E757F1E sha1 9A679E30B03E119A21AE7DAAC65E73E0EF4E0894 flags verified ) + name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f48824fe sha1 9A679E30B03E119A21AE7DAAC65E73E0EF4E0894 flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (France) (Rev A) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (France) (Rev A) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Rev A) (SGB Enhanced).gbc" size 1048576 crc 4E2B75E7 md5 68242187B65166B5F8225B20E2021659 sha1 B5E4DF1A67432C609FA0F23519315297C6DCDC1D ) + name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4e2b75e7 sha1 B5E4DF1A67432C609FA0F23519315297C6DCDC1D flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced).gbc" size 1048576 crc FED5959B md5 E91FD46E7092D32CA264F21853F09539 sha1 8CD9D786547BFB3DDBE16AD2A84A36CF895AC16E ) + name "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc fed5959b sha1 8CD9D786547BFB3DDBE16AD2A84A36CF895AC16E ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev A) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev A) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev A) (SGB Enhanced).gbc" size 1048576 crc EFB76777 md5 B0080C2F1919A4BB0EA73B788F4A6786 sha1 7F5C39FA297CB17ABF51C6F91FBDEBC9F07E3DE8 flags verified ) + name "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc efb76777 sha1 7F5C39FA297CB17ABF51C6F91FBDEBC9F07E3DE8 flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 97822948 md5 07C211479386825042EFB4AD31BB525F sha1 D90AC17E9BF17B6C61624AD9F05447BDB5EFC01A flags verified ) + name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 97822948 sha1 D90AC17E9BF17B6C61624AD9F05447BDB5EFC01A flags verified ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev A) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev A) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev A) (SGB Enhanced).gbc" size 1048576 crc B38EB9DE md5 CCBB56212E3DBAA9007D389A17E9D075 sha1 363D184D9B1E9FAA5A2FACD80897B7E118446164 ) + name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b38eb9de sha1 363D184D9B1E9FAA5A2FACD80897B7E118446164 ) ) game ( - name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev B) (SGB Enhanced)" - description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev B) (SGB Enhanced)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev B) (SGB Enhanced).gbc" size 1048576 crc 06887A34 md5 7351DAA3C0A91D8F6FE2FBCCA6182478 sha1 1C091225688D966928CC74336DBEF2E07D12A47C flags verified ) + name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (USA, Europe) (Rev 2) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 06887a34 sha1 1C091225688D966928CC74336DBEF2E07D12A47C flags verified ) ) game ( name "Legend of Zelda, The - Oracle of Ages (Europe) (En,Fr,De,Es,It)" description "Legend of Zelda, The - Oracle of Ages (Europe) (En,Fr,De,Es,It)" - rom ( name "Legend of Zelda, The - Oracle of Ages (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 5933E3FA md5 825DE040EA4DFF66661693F8712B1BDB sha1 9F2DFF3C46406839F839A8D535353DFC1E3E8670 flags verified ) + rom ( name "Legend of Zelda, The - Oracle of Ages (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 5933e3fa sha1 9F2DFF3C46406839F839A8D535353DFC1E3E8670 flags verified ) ) game ( - name "Legend of Zelda, The - Oracle of Ages (USA)" - description "Legend of Zelda, The - Oracle of Ages (USA)" - rom ( name "Legend of Zelda, The - Oracle of Ages (USA).gbc" size 1048576 crc 3800A387 md5 C4639CC61C049E5A085526BB6CAC03BB sha1 880374FB978B18AF4AA529E2E32F7FFB4D7DD2F4 flags verified ) + name "Legend of Zelda, The - Oracle of Ages (USA, Australia)" + description "Legend of Zelda, The - Oracle of Ages (USA, Australia)" + rom ( name "Legend of Zelda, The - Oracle of Ages (USA, Australia).gbc" size 1048576 crc 3800a387 sha1 880374FB978B18AF4AA529E2E32F7FFB4D7DD2F4 flags verified ) ) game ( name "Legend of Zelda, The - Oracle of Seasons (Europe) (En,Fr,De,Es,It)" description "Legend of Zelda, The - Oracle of Seasons (Europe) (En,Fr,De,Es,It)" - rom ( name "Legend of Zelda, The - Oracle of Seasons (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc DBAC1357 md5 4CA44CBDD4E05C9B3C22DA96D3DE6338 sha1 360B9408E569BA826212EAC1EBEA1B09573CB48C flags verified ) + rom ( name "Legend of Zelda, The - Oracle of Seasons (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc dbac1357 sha1 360B9408E569BA826212EAC1EBEA1B09573CB48C flags verified ) ) game ( - name "Legend of Zelda, The - Oracle of Seasons (USA)" - description "Legend of Zelda, The - Oracle of Seasons (USA)" - rom ( name "Legend of Zelda, The - Oracle of Seasons (USA).gbc" size 1048576 crc D7E9F5D7 md5 F2DC6C4E093E4F8C6CBEA80E8DBD62CB sha1 BA1268290FB2B1B70505D2D7B5825FC8A4816A4B flags verified ) + name "Legend of Zelda, The - Oracle of Seasons (USA, Australia)" + description "Legend of Zelda, The - Oracle of Seasons (USA, Australia)" + rom ( name "Legend of Zelda, The - Oracle of Seasons (USA, Australia).gbc" size 1048576 crc d7e9f5d7 sha1 BA1268290FB2B1B70505D2D7B5825FC8A4816A4B flags verified ) ) game ( name "LEGO Alpha Team (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "LEGO Alpha Team (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "LEGO Alpha Team (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 690C0373 md5 E041A65713AC7070C9D16CB6501E1A6E sha1 4BD3BF401E861FE9991A58B523622C68138274E6 ) + rom ( name "LEGO Alpha Team (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 690c0373 sha1 4BD3BF401E861FE9991A58B523622C68138274E6 ) ) game ( name "LEGO Alpha Team (USA)" description "LEGO Alpha Team (USA)" - rom ( name "LEGO Alpha Team (USA).gbc" size 1048576 crc 6D7EC41B md5 E79CE8C2B2E9EA0C0907CFBFADAA8744 sha1 B5D521D5B7504442C886944A6FB7DD830A28B496 ) + rom ( name "LEGO Alpha Team (USA).gbc" size 1048576 crc 6d7ec41b sha1 B5D521D5B7504442C886944A6FB7DD830A28B496 ) ) game ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 921ABB21 md5 2A1EFEF6D25431529B0D2F5063F63A17 sha1 B70A22669256735ABAE16A32BB5F8944CFF4A37C ) + rom ( name "LEGO Island 2 - The Brickster's Revenge (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 921abb21 sha1 B70A22669256735ABAE16A32BB5F8944CFF4A37C ) ) game ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr,Es)" description "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr,Es)" - rom ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr,Es).gbc" size 1048576 crc B14FA7E7 md5 1D0EA47375FCA723C0F86A5178E545F3 sha1 CD49BDE3C3641E34CFBC1D55FD08D54CCC5B099B ) + rom ( name "LEGO Island 2 - The Brickster's Revenge (USA) (En,Fr,Es).gbc" size 1048576 crc b14fa7e7 sha1 CD49BDE3C3641E34CFBC1D55FD08D54CCC5B099B ) ) game ( name "LEGO Racers (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "LEGO Racers (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "LEGO Racers (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 0A109F13 md5 0E13C1506562050AB39BC7D0FCD41ECF sha1 25877740F157DB965A2CAF30F081A89B6C13DF23 flags verified ) + rom ( name "LEGO Racers (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 0a109f13 sha1 25877740F157DB965A2CAF30F081A89B6C13DF23 flags verified ) ) game ( name "LEGO Racers (USA) (En,Fr,Es)" description "LEGO Racers (USA) (En,Fr,Es)" - rom ( name "LEGO Racers (USA) (En,Fr,Es).gbc" size 1048576 crc F6865B09 md5 A2D07E7DA188092C88EF6D9FD2E5EAA4 sha1 8E46D2920BCCC9A67FCFED404D0F8DD1BD9CB807 ) + rom ( name "LEGO Racers (USA) (En,Fr,Es).gbc" size 1048576 crc f6865b09 sha1 8E46D2920BCCC9A67FCFED404D0F8DD1BD9CB807 flags verified ) ) game ( name "LEGO Stunt Rally (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" description "LEGO Stunt Rally (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da)" - rom ( name "LEGO Stunt Rally (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 05CC01FB md5 3D75B453859C2C6F1C84B68CA987ADDA sha1 32DC01DB6A5AF637E96A6D83895C352D920FBA04 ) + rom ( name "LEGO Stunt Rally (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gbc" size 1048576 crc 05cc01fb sha1 32DC01DB6A5AF637E96A6D83895C352D920FBA04 ) ) game ( name "LEGO Stunt Rally (USA)" description "LEGO Stunt Rally (USA)" - rom ( name "LEGO Stunt Rally (USA).gbc" size 1048576 crc DA084760 md5 C468C6D714A2D86E2F68BDCDBB40B658 sha1 106CB59AC42C3573DCF27B448503AB4D3029D90A ) + rom ( name "LEGO Stunt Rally (USA).gbc" size 1048576 crc da084760 sha1 106CB59AC42C3573DCF27B448503AB4D3029D90A ) ) game ( - name "Lemmings (USA)" - description "Lemmings (USA)" - rom ( name "Lemmings (USA).gbc" size 4194304 crc 97E5CE2F md5 0476C7220327D99E3D039FAAA4CDDE8F sha1 2662B9FDFB243392EC1268FEEA993ED36AC840B1 ) + name "Lemmings & Oh No! More Lemmings (USA)" + description "Lemmings & Oh No! More Lemmings (USA)" + rom ( name "Lemmings & Oh No! More Lemmings (USA).gbc" size 4194304 crc 97e5ce2f sha1 2662B9FDFB243392EC1268FEEA993ED36AC840B1 ) ) game ( - name "Lil' Monster (USA) (SGB Enhanced)" - description "Lil' Monster (USA) (SGB Enhanced)" - rom ( name "Lil' Monster (USA) (SGB Enhanced).gbc" size 1048576 crc C6859B34 md5 17233EAF718E241F290D6590EF1B42A9 sha1 CB812599F23F8812FF756E269A621DE39B1B1DEF ) + name "Lemmings VS (Japan)" + description "Lemmings VS (Japan)" + rom ( name "Lemmings VS (Japan).gbc" size 4194304 crc 947d45ae sha1 2EBB428A53ACBCBC215F37BB263E44D94F547473 ) +) + +game ( + name "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" + description "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Lil' Monster (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c6859b34 sha1 CB812599F23F8812FF756E269A621DE39B1B1DEF ) ) game ( name "Lion King, The - Simba's Mighty Adventure (USA, Europe)" description "Lion King, The - Simba's Mighty Adventure (USA, Europe)" - rom ( name "Lion King, The - Simba's Mighty Adventure (USA, Europe).gbc" size 1048576 crc D5B4B7BB md5 67117CC76E2B270E65C2778C734F905F sha1 4FCB6698E4FD6BB03812A35ED545EC68B7C11FA7 flags verified ) + rom ( name "Lion King, The - Simba's Mighty Adventure (USA, Europe).gbc" size 1048576 crc d5b4b7bb sha1 4FCB6698E4FD6BB03812A35ED545EC68B7C11FA7 flags verified ) ) game ( name "Little Magic (Japan)" description "Little Magic (Japan)" - rom ( name "Little Magic (Japan).gbc" size 1048576 crc CA38283D md5 2BB74ACE01CABE5D71DFCC329179B4AE sha1 4CD610BE44A9FBFDE9DE81167F1E4051A62B01A9 ) + rom ( name "Little Magic (Japan).gbc" size 1048576 crc ca38283d sha1 4CD610BE44A9FBFDE9DE81167F1E4051A62B01A9 ) ) game ( name "Little Mermaid II, The - Pinball Frenzy (Europe) (En,Fr,De,Es,It)" description "Little Mermaid II, The - Pinball Frenzy (Europe) (En,Fr,De,Es,It)" - rom ( name "Little Mermaid II, The - Pinball Frenzy (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 9FEC297E md5 F19153C5BC422A2B1B13A4B9FF5D7BD9 sha1 C84C653EADA20161C8D0AA966303B378FE5FEEF1 flags verified ) + rom ( name "Little Mermaid II, The - Pinball Frenzy (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 9fec297e sha1 C84C653EADA20161C8D0AA966303B378FE5FEEF1 flags verified ) ) game ( name "Little Mermaid II, The - Pinball Frenzy (USA) (En,Fr,De,Es,It) (Rumble Version)" description "Little Mermaid II, The - Pinball Frenzy (USA) (En,Fr,De,Es,It) (Rumble Version)" - rom ( name "Little Mermaid II, The - Pinball Frenzy (USA) (En,Fr,De,Es,It) (Rumble Version).gbc" size 1048576 crc 364F9CCD md5 7F8C472F3C7BD1EEC56A3BAD10A2E94C sha1 0940A1A86127CF8228A6A015035D8189218F57DB flags verified ) + rom ( name "Little Mermaid II, The - Pinball Frenzy (USA) (En,Fr,De,Es,It) (Rumble Version).gbc" size 1048576 crc 364f9ccd sha1 0940A1A86127CF8228A6A015035D8189218F57DB flags verified ) ) game ( name "Little Nicky (USA)" description "Little Nicky (USA)" - rom ( name "Little Nicky (USA).gbc" size 2097152 crc 27310900 md5 246526C5A9DD42E6BF8D35708CA24EE9 sha1 F2FA3AE6BB82EBF31C4863B64B330716BD839362 ) + rom ( name "Little Nicky (USA).gbc" size 2097152 crc 27310900 sha1 F2FA3AE6BB82EBF31C4863B64B330716BD839362 ) ) game ( name "LNF Stars 2001 (France)" description "LNF Stars 2001 (France)" - rom ( name "LNF Stars 2001 (France).gbc" size 1048576 crc F8BF3EE7 md5 138ADD8906346EAF244E8E7ED79EC42A sha1 07A0E1C0DDDE6371DBAF25FD016BDC77C0ECA090 ) + rom ( name "LNF Stars 2001 (France).gbc" size 1048576 crc f8bf3ee7 sha1 07A0E1C0DDDE6371DBAF25FD016BDC77C0ECA090 ) ) game ( - name "Lode Runner - Domudomu Dan no Yabou (Japan)" - description "Lode Runner - Domudomu Dan no Yabou (Japan)" - rom ( name "Lode Runner - Domudomu Dan no Yabou (Japan).gbc" size 1048576 crc ECEAB84E md5 7BCF428844D32B279B7C25FB98F98A73 sha1 C49569E4453F18B00BCF5EA3DE43DEE9BA3B4499 ) + name "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" + description "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" + rom ( name "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible).gbc" size 1048576 crc eceab84e sha1 C49569E4453F18B00BCF5EA3DE43DEE9BA3B4499 ) ) game ( - name "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced)" - description "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced)" - rom ( name "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 66E166BB md5 B14BF550163B000A7D1BA3CAA43AC508 sha1 3431247FFAE511B6C2A836759E5ED0545D11BA05 ) + name "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Lodoss-tou Senki - Eiyuu Kishiden GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 66e166bb sha1 3431247FFAE511B6C2A836759E5ED0545D11BA05 flags verified ) ) game ( name "Logical (Europe)" description "Logical (Europe)" - rom ( name "Logical (Europe).gbc" size 1048576 crc 5EEE76C4 md5 49B48529D5291796A96659468C41CC54 sha1 BFCC97D28A0FE90521258DE9CDF75A8ABB5FBD0B flags verified ) + rom ( name "Logical (Europe).gbc" size 1048576 crc 5eee76c4 sha1 BFCC97D28A0FE90521258DE9CDF75A8ABB5FBD0B flags verified ) ) game ( name "Logical (USA)" description "Logical (USA)" - rom ( name "Logical (USA).gbc" size 1048576 crc D67275F7 md5 EAC27E6D4CD1D38D07F2A18AD8169AF1 sha1 3163071800753F29F2CE6142931356D8D6DFBE68 ) + rom ( name "Logical (USA).gbc" size 1048576 crc d67275f7 sha1 3163071800753F29F2CE6142931356D8D6DFBE68 ) ) game ( - name "Looney Tunes (Europe)" - description "Looney Tunes (Europe)" - rom ( name "Looney Tunes (Europe).gbc" size 1048576 crc 76CF3E3A md5 A539A0AE1B1ED8034FC3A4733B4298C3 sha1 E631EAA8F7BE44A1F41E06878CA81BD3FA779F6B flags verified ) + name "Looney Tunes (Europe) (GB Compatible)" + description "Looney Tunes (Europe) (GB Compatible)" + rom ( name "Looney Tunes (Europe) (GB Compatible).gbc" size 1048576 crc 76cf3e3a sha1 E631EAA8F7BE44A1F41E06878CA81BD3FA779F6B flags verified ) ) game ( - name "Looney Tunes (USA)" - description "Looney Tunes (USA)" - rom ( name "Looney Tunes (USA).gbc" size 1048576 crc 4EF3DDD7 md5 F687B51A0FAB72E03766356B62261A49 sha1 80A0E66754CE81A01385941459B9EA15A450B2B6 flags verified ) + name "Looney Tunes (USA) (GB Compatible)" + description "Looney Tunes (USA) (GB Compatible)" + rom ( name "Looney Tunes (USA) (GB Compatible).gbc" size 1048576 crc 4ef3ddd7 sha1 80A0E66754CE81A01385941459B9EA15A450B2B6 flags verified ) ) game ( - name "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es)" - description "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es)" - rom ( name "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es).gbc" size 1048576 crc 11FB5617 md5 B6C357BB1A544FB1F8731CBDC3046596 sha1 4D8FA4D930F7F2BA7D674EED1C5A284F20C434CA ) + name "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es) (GB Compatible)" + description "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es) (GB Compatible)" + rom ( name "Looney Tunes - Carrot Crazy (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc 11fb5617 sha1 4D8FA4D930F7F2BA7D674EED1C5A284F20C434CA ) ) game ( - name "Looney Tunes - Twouble! (USA) (En,Fr,Es)" - description "Looney Tunes - Twouble! (USA) (En,Fr,Es)" - rom ( name "Looney Tunes - Twouble! (USA) (En,Fr,Es).gbc" size 1048576 crc 698D7BE4 md5 1D31FA1E431EC840E5F769FDD019405F sha1 F08BD36A0933AC56EEED2DD235D476D3B80A1F50 ) + name "Looney Tunes - Twouble! (USA) (En,Fr,Es) (GB Compatible)" + description "Looney Tunes - Twouble! (USA) (En,Fr,Es) (GB Compatible)" + rom ( name "Looney Tunes - Twouble! (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc 698d7be4 sha1 F08BD36A0933AC56EEED2DD235D476D3B80A1F50 ) ) game ( name "Looney Tunes Collector - Alert! (USA) (En,Fr,Es)" description "Looney Tunes Collector - Alert! (USA) (En,Fr,Es)" - rom ( name "Looney Tunes Collector - Alert! (USA) (En,Fr,Es).gbc" size 2097152 crc 54509D24 md5 164C4FCFE733D89FFF3DDC42B017C5CA sha1 54C4F732A8C328A9331A8A500438B1B1E9472B39 ) + rom ( name "Looney Tunes Collector - Alert! (USA) (En,Fr,Es).gbc" size 2097152 crc 54509d24 sha1 54C4F732A8C328A9331A8A500438B1B1E9472B39 ) ) game ( name "Looney Tunes Collector - Martian Alert! (Europe) (En,Fr,De,Es,It,Nl)" description "Looney Tunes Collector - Martian Alert! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Looney Tunes Collector - Martian Alert! (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 5D85DFAD md5 9562A0AAD16857F2F1A8E4169163C18A sha1 645C4CF67FAF33248D2102F137A605DE94305796 flags verified ) + rom ( name "Looney Tunes Collector - Martian Alert! (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 5d85dfad sha1 645C4CF67FAF33248D2102F137A605DE94305796 flags verified ) ) game ( name "Looney Tunes Collector - Martian Quest! (Japan)" description "Looney Tunes Collector - Martian Quest! (Japan)" - rom ( name "Looney Tunes Collector - Martian Quest! (Japan).gbc" size 2097152 crc BC46A2D2 md5 74F0CA3425914DF4AF3210541FF619C8 sha1 450E43CF2D9CFA18856B3F3312E2194F132DBB1B ) + rom ( name "Looney Tunes Collector - Martian Quest! (Japan).gbc" size 2097152 crc bc46a2d2 sha1 450E43CF2D9CFA18856B3F3312E2194F132DBB1B flags verified ) ) game ( name "Looney Tunes Collector - Martian Revenge! (Europe) (En,Fr,De,Es,It,Nl)" description "Looney Tunes Collector - Martian Revenge! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Looney Tunes Collector - Martian Revenge! (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 22952662 md5 F765E4019C3AB207C5804CA530173A31 sha1 9E17AF53EF89E2D436096C88DD293B838026B75F ) + rom ( name "Looney Tunes Collector - Martian Revenge! (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 22952662 sha1 9E17AF53EF89E2D436096C88DD293B838026B75F ) ) game ( name "Looney Tunes Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Looney Tunes Racing (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Looney Tunes Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 7EFDCA8A md5 8B8064A09B8FC56182AB423EBAD9381B sha1 2552C1F0E864E1689E59F8D80837BFFDFFA211FA ) + rom ( name "Looney Tunes Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 7efdca8a sha1 2552C1F0E864E1689E59F8D80837BFFDFFA211FA flags verified ) ) game ( name "Looney Tunes Racing (USA) (En,Fr,De,Es,It,Nl)" description "Looney Tunes Racing (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Looney Tunes Racing (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 66792CDE md5 35119708963EE94AE7B634D364C07D50 sha1 249759398FB9E484B00E0D5416DA2411C79D2D39 ) + rom ( name "Looney Tunes Racing (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 66792cde sha1 249759398FB9E484B00E0D5416DA2411C79D2D39 ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc 29E193C5 md5 A9EE6C9625C9BD187BC7FD90DF3A4FC4 sha1 8CC512784D323F7C0BFE36848C5F7FDC49257285 ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 29e193c5 sha1 8CC512784D323F7C0BFE36848C5F7FDC49257285 ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc D54D5836 md5 693E77E4CD9C3845693F695A87F4444A sha1 C88AE04F7ADBEC5AD40EDEC650198CBE58A561BD ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc d54d5836 sha1 C88AE04F7ADBEC5AD40EDEC650198CBE58A561BD ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc E078D9F8 md5 8DBAB7618855360B2029BDF2841067AB sha1 A7FAA970E71D38C68948B646D3DCB9CBEA1DF995 ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc e078d9f8 sha1 A7FAA970E71D38C68948B646D3DCB9CBEA1DF995 ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc 065A3BF5 md5 417AE48B7E288B62FE2540541244FC31 sha1 42721B99B427E51F7E815C852BF53E807C52DD65 ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 065a3bf5 sha1 42721B99B427E51F7E815C852BF53E807C52DD65 ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc C0287CF2 md5 DE3C7F4B7DF2D8C95EA1C5C622C332E8 sha1 7425BD94790866BF716FD3C23886A5CDC06F1AAD ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc c0287cf2 sha1 7425BD94790866BF716FD3C23886A5CDC06F1AAD ) ) game ( - name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc 267B5253 md5 68E0DB3785BC843790D6DE9C3877003F sha1 F977D3DD6395066BBEA729EA547C7A81E1C4464D ) + name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Hirameku Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 267b5253 sha1 F977D3DD6395066BBEA729EA547C7A81E1C4464D ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc D457CC6C md5 6F5ACA1F721A92EB956286809F2AF28D sha1 CB14866337CAECD5458EDC72F2D56F2C8C028411 ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc d457cc6c sha1 CB14866337CAECD5458EDC72F2D56F2C8C028411 ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc A30AD68D md5 74A81CF1C74134091DA70B06380285FC sha1 BBB3C1B9D0DCFABC177F443EA11EFA6B6E3112E1 ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-2-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc a30ad68d sha1 BBB3C1B9D0DCFABC177F443EA11EFA6B6E3112E1 ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc 3EF25533 md5 C16F93EF289C6524DFF09B8906EEF668 sha1 9822FECF183D3D0A6E9AF80696463B09E1F31A60 ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 3ef25533 sha1 9822FECF183D3D0A6E9AF80696463B09E1F31A60 ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc 9C932F0D md5 21D547EA7229128618079C792FD94E2A sha1 1D0DBAC5283D6E7459AFB0E4B4A194BBE79A798B ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Dai-3-gou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 9c932f0d sha1 1D0DBAC5283D6E7459AFB0E4B4A194BBE79A798B ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced).gbc" size 262144 crc 094FFD1E md5 41C2515A1DDA83AADFD0A134BC62656B sha1 5A476F79DB61AA8C6F32BBABD82FADE5CDE811D2 ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 094ffd1e sha1 5A476F79DB61AA8C6F32BBABD82FADE5CDE811D2 ) ) game ( - name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced)" - description "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced)" - rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev A) (NP, SGB Enhanced).gbc" size 262144 crc 8019C6F5 md5 E77282A547CA0586CF396CCAC3262F84 sha1 4A9D7A35BC073399CBE852D356AFA3772C5A7788 ) + name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + description "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible)" + rom ( name "Loppi Puzzle Magazine - Kangaeru Puzzle Soukangou (Japan) (Rev 1) (NP, SGB Enhanced) (GB Compatible).gbc" size 262144 crc 8019c6f5 sha1 4A9D7A35BC073399CBE852D356AFA3772C5A7788 ) ) game ( name "Love Hina Party (Japan)" description "Love Hina Party (Japan)" - rom ( name "Love Hina Party (Japan).gbc" size 2097152 crc 034D2686 md5 BA01289E8D646E1407F70275A50114B3 sha1 D3551D99BB03E7945862CC8F1C3C095477119CF2 ) + rom ( name "Love Hina Party (Japan).gbc" size 2097152 crc 034d2686 sha1 D3551D99BB03E7945862CC8F1C3C095477119CF2 flags verified ) ) game ( name "Love Hina Pocket (Japan)" description "Love Hina Pocket (Japan)" - rom ( name "Love Hina Pocket (Japan).gbc" size 4194304 crc 1C877ABD md5 71A4659AE44B6594E75F98E013CE6853 sha1 912C09F99BDAE6E7FCD62D0C6F727E5FFF93DB70 ) + rom ( name "Love Hina Pocket (Japan).gbc" size 4194304 crc 1c877abd sha1 912C09F99BDAE6E7FCD62D0C6F727E5FFF93DB70 ) ) game ( - name "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced)" - description "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced)" - rom ( name "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced).gbc" size 524288 crc 3AEBFAD8 md5 74A6B62520A30FF28D5A7D19A7108C27 sha1 3C06FE05909AD632B761C6A1C00BC69DA81AA358 ) + name "Love Hina Pocket (Japan) (Rev 1)" + description "Love Hina Pocket (Japan) (Rev 1)" + rom ( name "Love Hina Pocket (Japan) (Rev 1).gbc" size 4194304 crc 55dd0ba6 sha1 B29ABEE319CCB223E5D1A4F88982FB53E538D527 flags verified ) +) + +game ( + name "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced) (GB Compatible)" + description "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Luca no Puzzle de Daibouken! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 3aebfad8 sha1 3C06FE05909AD632B761C6A1C00BC69DA81AA358 ) ) game ( name "Lucky Luke (Europe) (En,Fr,De,Es)" description "Lucky Luke (Europe) (En,Fr,De,Es)" - rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 412FB57C md5 EB76FDA958F100FB791111B928FFE46F sha1 36B59251751A55285DBEDC3BD4B33B2C73B811C9 ) + rom ( name "Lucky Luke (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 412fb57c sha1 36B59251751A55285DBEDC3BD4B33B2C73B811C9 ) ) game ( name "Lucky Luke (USA) (En,Fr,De,Es)" description "Lucky Luke (USA) (En,Fr,De,Es)" - rom ( name "Lucky Luke (USA) (En,Fr,De,Es).gbc" size 1048576 crc A5E29F34 md5 7CF3670A8F345344E4789E41503D7DA6 sha1 EBF61143A16BE4BFC0C99A7FEB9455685F86ACFA ) + rom ( name "Lucky Luke (USA) (En,Fr,De,Es).gbc" size 1048576 crc a5e29f34 sha1 EBF61143A16BE4BFC0C99A7FEB9455685F86ACFA flags verified ) ) game ( name "Lucky Luke - Desperado Train (Europe) (En,Fr,De,Es,It,Nl)" description "Lucky Luke - Desperado Train (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Lucky Luke - Desperado Train (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc CE7F108A md5 31770F7197EA4A7FF99CAD7CEF5C58B8 sha1 857DDA99BDB15C49918C633DBCB73BD96EF7BAE9 ) + rom ( name "Lucky Luke - Desperado Train (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc ce7f108a sha1 857DDA99BDB15C49918C633DBCB73BD96EF7BAE9 ) ) game ( name "Lufia - The Legend Returns (Europe) (En,De)" description "Lufia - The Legend Returns (Europe) (En,De)" - rom ( name "Lufia - The Legend Returns (Europe) (En,De).gbc" size 2097152 crc 470DCB1D md5 1FF9B71A347A7DEED87BCEDEB7C5EA70 sha1 10FAAEFBA4C97D8392BB0231CF898A77DB4F73F2 flags verified ) + rom ( name "Lufia - The Legend Returns (Europe) (En,De).gbc" size 2097152 crc 470dcb1d sha1 10FAAEFBA4C97D8392BB0231CF898A77DB4F73F2 flags verified ) ) game ( name "Lufia - The Legend Returns (USA)" description "Lufia - The Legend Returns (USA)" - rom ( name "Lufia - The Legend Returns (USA).gbc" size 2097152 crc 5BAE3C04 md5 A00012533E76649F4E7E1B7AA5A9EE07 sha1 9EB52C525620E7BDA619F2161961071E8996C0DB flags verified ) + rom ( name "Lufia - The Legend Returns (USA).gbc" size 2097152 crc 5bae3c04 sha1 9EB52C525620E7BDA619F2161961071E8996C0DB flags verified ) ) game ( name "M&M's Minis Madness (Europe)" description "M&M's Minis Madness (Europe)" - rom ( name "M&M's Minis Madness (Europe).gbc" size 1048576 crc 60683BC4 md5 0BFAC235A5BD9CD57D7B3E7E83993458 sha1 D0B18A3ACF9495DB5AF52B5C28DF4129F48010BF ) + rom ( name "M&M's Minis Madness (Europe).gbc" size 1048576 crc 60683bc4 sha1 D0B18A3ACF9495DB5AF52B5C28DF4129F48010BF flags verified ) ) game ( name "M&M's Minis Madness (Germany)" description "M&M's Minis Madness (Germany)" - rom ( name "M&M's Minis Madness (Germany).gbc" size 1048576 crc A666F54D md5 0650CBE5E04F8968D5C09740AF7AA152 sha1 9CCC1F1F0B6BD65913E60E2F9B7D5F9859B46535 flags verified ) + rom ( name "M&M's Minis Madness (Germany).gbc" size 1048576 crc a666f54d sha1 9CCC1F1F0B6BD65913E60E2F9B7D5F9859B46535 flags verified ) ) game ( name "M&M's Minis Madness (USA)" description "M&M's Minis Madness (USA)" - rom ( name "M&M's Minis Madness (USA).gbc" size 1048576 crc 8649D7A0 md5 C7BCDD8ACE2DFAC5FDCE889880472F80 sha1 7CC20E133A66163C6DEC140E960B5BE3848CCD44 ) + rom ( name "M&M's Minis Madness (USA).gbc" size 1048576 crc 8649d7a0 sha1 7CC20E133A66163C6DEC140E960B5BE3848CCD44 ) ) game ( name "M&M's Minis Madness (USA) (Sample)" description "M&M's Minis Madness (USA) (Sample)" - rom ( name "M&M's Minis Madness (USA) (Sample).gbc" size 1048576 crc 83293B1B md5 71B646AC71DBAE8984995EF51324F5F5 sha1 2A0D0B7AA3B96B05BC020DA496F2CE08E8FAC190 ) + rom ( name "M&M's Minis Madness (USA) (Sample).gbc" size 1048576 crc 83293b1b sha1 2A0D0B7AA3B96B05BC020DA496F2CE08E8FAC190 ) ) game ( name "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" description "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" - rom ( name "Macross 7 - Ginga no Heart o Furuwasero!! (Japan).gbc" size 2097152 crc 2B7ABBA4 md5 4FA0F6E7388F072C8BB76761F8068868 sha1 88746C361CFBDAC49E5D72807B396A6667C42229 ) + rom ( name "Macross 7 - Ginga no Heart o Furuwasero!! (Japan).gbc" size 2097152 crc 2b7abba4 sha1 88746C361CFBDAC49E5D72807B396A6667C42229 ) ) game ( - name "Madden NFL 2000 (USA, Europe) (SGB Enhanced)" - description "Madden NFL 2000 (USA, Europe) (SGB Enhanced)" - rom ( name "Madden NFL 2000 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 482944AA md5 071AD15A9890F73890C4E0DEDD07793E sha1 DF03F3E5E3F6FD3905DC332B307B5566F0F35252 flags verified ) + name "Madden NFL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Madden NFL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Madden NFL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 482944aa sha1 DF03F3E5E3F6FD3905DC332B307B5566F0F35252 flags verified ) ) game ( name "Madden NFL 2001 (USA)" description "Madden NFL 2001 (USA)" - rom ( name "Madden NFL 2001 (USA).gbc" size 1048576 crc 160E9E3C md5 0D9DBB213DB66CC0121A7F916181F612 sha1 5F7C156B7A141A8F373D626F53C9CE8B95CEC880 ) + rom ( name "Madden NFL 2001 (USA).gbc" size 1048576 crc 160e9e3c sha1 5F7C156B7A141A8F373D626F53C9CE8B95CEC880 ) ) game ( name "Madden NFL 2002 (USA)" description "Madden NFL 2002 (USA)" - rom ( name "Madden NFL 2002 (USA).gbc" size 1048576 crc DE1338D2 md5 B62CD45AF888F008BE2DDB84B778AF4E sha1 F32926053B8E565C2A3634C68A456D459E1F01A0 ) + rom ( name "Madden NFL 2002 (USA).gbc" size 1048576 crc de1338d2 sha1 F32926053B8E565C2A3634C68A456D459E1F01A0 ) ) game ( name "Magi Nation (USA)" description "Magi Nation (USA)" - rom ( name "Magi Nation (USA).gbc" size 2097152 crc 5042450B md5 1624F857098CA278B15629914F48352B sha1 9972A7BCA43210B4B6C0B3F6EE5D1957A865E12D ) + rom ( name "Magi Nation (USA).gbc" size 2097152 crc 5042450b sha1 9972A7BCA43210B4B6C0B3F6EE5D1957A865E12D flags verified ) ) game ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" description "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" - rom ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan).gbc" size 1048576 crc 15E5D499 md5 F722B68C0F532ED567397A3E53909CCF sha1 3B13FC974D68A8B057AB8133A0BA7E3FBAC23F11 ) + rom ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan).gbc" size 1048576 crc 15e5d499 sha1 3B13FC974D68A8B057AB8133A0BA7E3FBAC23F11 ) ) game ( name "Magical Drop (Europe) (En,Fr,De)" description "Magical Drop (Europe) (En,Fr,De)" - rom ( name "Magical Drop (Europe) (En,Fr,De).gbc" size 1048576 crc EA9EE203 md5 618946A1D8D7154C200FE278EF030140 sha1 8EF276F9C6A64D7CEC527BCBA8D1B7223DE0E01C flags verified ) + rom ( name "Magical Drop (Europe) (En,Fr,De).gbc" size 1048576 crc ea9ee203 sha1 8EF276F9C6A64D7CEC527BCBA8D1B7223DE0E01C flags verified ) ) game ( name "Magical Drop (USA)" description "Magical Drop (USA)" - rom ( name "Magical Drop (USA).gbc" size 1048576 crc E4188A79 md5 AF157E560D1FF87970C1BD2EE90D0932 sha1 2106B22776A87825D3EDB408503E719F4927C3E6 ) + rom ( name "Magical Drop (USA).gbc" size 1048576 crc e4188a79 sha1 2106B22776A87825D3EDB408503E719F4927C3E6 ) ) game ( name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv)" description "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 0A421839 md5 7FD49763F6A8ACEB6AEA4CFE601A8B10 sha1 3C315F3F77002456F09DF9643BE323608AE72088 flags verified ) + rom ( name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 0a421839 sha1 3C315F3F77002456F09DF9643BE323608AE72088 flags verified ) ) game ( - name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev A)" - description "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev A)" - rom ( name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev A).gbc" size 1048576 crc C82BE2F4 md5 4FF574FADD50A18D7E93FE0D7DC4C8D1 sha1 950B30B267B0F0B79D7E85E91B8536B096B6A1B2 ) + name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev 1)" + description "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev 1)" + rom ( name "Magical Tetris Challenge (Europe) (En,Fr,De,Es,It,Nl,Sv) (Rev 1).gbc" size 1048576 crc c82be2f4 sha1 950B30B267B0F0B79D7E85E91B8536B096B6A1B2 ) ) game ( name "Magical Tetris Challenge (USA)" description "Magical Tetris Challenge (USA)" - rom ( name "Magical Tetris Challenge (USA).gbc" size 1048576 crc F53CF66C md5 A13623A452327EDE4553EE2BD1B89A1A sha1 7CDB0BF463AD87EC8A68A564C3F03DBC890EDD7E ) + rom ( name "Magical Tetris Challenge (USA).gbc" size 1048576 crc f53cf66c sha1 7CDB0BF463AD87EC8A68A564C3F03DBC890EDD7E ) ) game ( - name "Mahjong Joou (Japan) (SGB Enhanced)" - description "Mahjong Joou (Japan) (SGB Enhanced)" - rom ( name "Mahjong Joou (Japan) (SGB Enhanced).gbc" size 1048576 crc 7D83A5E8 md5 D53652B59F1D8B50D1B30D75A44F4135 sha1 68F2326F7FA70D0ED0207BD087C6FE26EC6F9A53 ) + name "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" + description "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7d83a5e8 sha1 68F2326F7FA70D0ED0207BD087C6FE26EC6F9A53 ) ) game ( - name "Mahjong Quest (Japan) (SGB Enhanced)" - description "Mahjong Quest (Japan) (SGB Enhanced)" - rom ( name "Mahjong Quest (Japan) (SGB Enhanced).gbc" size 1048576 crc C870B88F md5 8B25AD9BD8ECD09A346C736011EA612B sha1 3AB49CE8AA69013C1B2D9427926513E21D5EFE1D ) + name "Mahjong Quest (Japan) (SGB Enhanced) (GB Compatible)" + description "Mahjong Quest (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Mahjong Quest (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c870b88f sha1 3AB49CE8AA69013C1B2D9427926513E21D5EFE1D ) ) game ( - name "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev A) (SGB Enhanced)" - description "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev A) (SGB Enhanced).gbc" size 2097152 crc 0D16A545 md5 C9A5171978E3587475BD6FFB17300B75 sha1 A56E2A42D4A0B21E656BC928E4451CF0623486CF flags verified ) + name "Majokko Mari-chan no Kisekae Monogatari (Japan) (SGB Enhanced) (GB Compatible)" + description "Majokko Mari-chan no Kisekae Monogatari (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Majokko Mari-chan no Kisekae Monogatari (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 934f4b0a sha1 8BDD3BD414DA91C6EA05BC29435E09B0B72E3790 ) +) + +game ( + name "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Majokko Mari-chan no Kisekae Monogatari (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 0d16a545 sha1 A56E2A42D4A0B21E656BC928E4451CF0623486CF flags verified ) ) game ( name "Marble Madness (USA, Europe)" description "Marble Madness (USA, Europe)" - rom ( name "Marble Madness (USA, Europe).gbc" size 1048576 crc 4EC78785 md5 D2711FF066F40C4E6C471B79DA0F08B7 sha1 32C84B75B10BD00812589F3C8CFD537518F021C6 flags verified ) + rom ( name "Marble Madness (USA, Europe).gbc" size 1048576 crc 4ec78785 sha1 32C84B75B10BD00812589F3C8CFD537518F021C6 flags verified ) ) game ( - name "Marie no Atelier GB (Japan) (SGB Enhanced)" - description "Marie no Atelier GB (Japan) (SGB Enhanced)" - rom ( name "Marie no Atelier GB (Japan) (SGB Enhanced).gbc" size 2097152 crc 6144FC66 md5 FE97E6BB194BD38E5BAEB889B4C8E251 sha1 F2B175DA93054372531BC7D839BDBF3192C6A5EB flags verified ) + name "Marie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Marie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Marie no Atelier GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 6144fc66 sha1 F2B175DA93054372531BC7D839BDBF3192C6A5EB flags verified ) ) game ( name "Mario Family (Japan)" description "Mario Family (Japan)" - rom ( name "Mario Family (Japan).gbc" size 2097152 crc AB3F3CEF md5 4CF10B2C7AE81E62E82DA32DE3A9D48E sha1 4A3C1C84A486864B84E110456E4B9A4E582FDBB8 ) + rom ( name "Mario Family (Japan).gbc" size 2097152 crc ab3f3cef sha1 4A3C1C84A486864B84E110456E4B9A4E582FDBB8 flags verified ) ) game ( name "Mario Golf (Europe)" description "Mario Golf (Europe)" - rom ( name "Mario Golf (Europe).gbc" size 2097152 crc A132417D md5 71156F1794556ACD255AE256D8195E32 sha1 AE3AEC0D376C1BC5B83AE4C4C1E245C3AB2B9392 flags verified ) + rom ( name "Mario Golf (Europe).gbc" size 2097152 crc a132417d sha1 AE3AEC0D376C1BC5B83AE4C4C1E245C3AB2B9392 flags verified ) ) game ( name "Mario Golf (USA)" description "Mario Golf (USA)" - rom ( name "Mario Golf (USA).gbc" size 2097152 crc 905AD0CB md5 83F791645CE282093A9D59C121FFC49D sha1 7F2062E51B4FC87378C1D5E6B9578C9277B94E0B ) + rom ( name "Mario Golf (USA).gbc" size 2097152 crc 905ad0cb sha1 7F2062E51B4FC87378C1D5E6B9578C9277B94E0B ) ) game ( name "Mario Golf GB (Japan)" description "Mario Golf GB (Japan)" - rom ( name "Mario Golf GB (Japan).gbc" size 2097152 crc 4CA2191A md5 C43CE6E1C66E6FCFC259762A9244A63D sha1 5658666A30288C6104F01985018A213E851067DE flags verified ) + rom ( name "Mario Golf GB (Japan).gbc" size 2097152 crc 4ca2191a sha1 5658666A30288C6104F01985018A213E851067DE flags verified ) ) game ( name "Mario Tennis (Europe)" description "Mario Tennis (Europe)" - rom ( name "Mario Tennis (Europe).gbc" size 2097152 crc 0510D601 md5 A320F9DE83767BB1BC1BBBC6FBD96011 sha1 550DCC99D0A56BBB13AE3ABB2A4193B830E54970 ) + rom ( name "Mario Tennis (Europe).gbc" size 2097152 crc 0510d601 sha1 550DCC99D0A56BBB13AE3ABB2A4193B830E54970 flags verified ) ) game ( name "Mario Tennis (USA)" description "Mario Tennis (USA)" - rom ( name "Mario Tennis (USA).gbc" size 2097152 crc A781C63C md5 50AF67F7321D84BD052F0E793EE0613C sha1 414BA58340A27FC27B127BC01455B32764151FF0 flags verified ) + rom ( name "Mario Tennis (USA).gbc" size 2097152 crc a781c63c sha1 414BA58340A27FC27B127BC01455B32764151FF0 flags verified ) ) game ( name "Mario Tennis GB (Japan)" description "Mario Tennis GB (Japan)" - rom ( name "Mario Tennis GB (Japan).gbc" size 2097152 crc 19070962 md5 D7F63BBB351A95D73D085A58C8E9F449 sha1 AD003D51B5A7ADB7BEB8B946CDF467DB6D940204 flags verified ) + rom ( name "Mario Tennis GB (Japan).gbc" size 2097152 crc 19070962 sha1 AD003D51B5A7ADB7BEB8B946CDF467DB6D940204 flags verified ) ) game ( name "Marvin Strikes Back! (USA) (En,Fr,Es)" description "Marvin Strikes Back! (USA) (En,Fr,Es)" - rom ( name "Marvin Strikes Back! (USA) (En,Fr,Es).gbc" size 2097152 crc 11B4788C md5 FDF704AFF61AD3E6848642241DDB6032 sha1 6E420EF902A52A5A932E0932D0AEB11C3D71FDA2 ) + rom ( name "Marvin Strikes Back! (USA) (En,Fr,Es).gbc" size 2097152 crc 11b4788c sha1 6E420EF902A52A5A932E0932D0AEB11C3D71FDA2 flags verified ) ) game ( - name "Mary-Kate & Ashley - Get a Clue! (USA, Europe)" - description "Mary-Kate & Ashley - Get a Clue! (USA, Europe)" - rom ( name "Mary-Kate & Ashley - Get a Clue! (USA, Europe).gbc" size 1048576 crc 46FAA730 md5 CC7639A2269210338B52E626096A99D9 sha1 4D7884E985A07AC640C3DDD1B9B482C205C5A709 flags verified ) + name "Mary-Kate & Ashley - Get a Clue! (USA, Europe) (GB Compatible)" + description "Mary-Kate & Ashley - Get a Clue! (USA, Europe) (GB Compatible)" + rom ( name "Mary-Kate & Ashley - Get a Clue! (USA, Europe) (GB Compatible).gbc" size 1048576 crc 46faa730 sha1 4D7884E985A07AC640C3DDD1B9B482C205C5A709 flags verified ) ) game ( name "Mary-Kate and Ashley - Crush Course (USA, Europe)" description "Mary-Kate and Ashley - Crush Course (USA, Europe)" - rom ( name "Mary-Kate and Ashley - Crush Course (USA, Europe).gbc" size 1048576 crc 69DB3CD8 md5 D219A65AA70FD9E1E75C65BDF97913DA sha1 11B2A52E19862A907D340A35A49D206059F21369 flags verified ) + rom ( name "Mary-Kate and Ashley - Crush Course (USA, Europe).gbc" size 1048576 crc 69db3cd8 sha1 11B2A52E19862A907D340A35A49D206059F21369 flags verified ) ) game ( - name "Mary-Kate and Ashley - Pocket Planner (USA, Europe)" - description "Mary-Kate and Ashley - Pocket Planner (USA, Europe)" - rom ( name "Mary-Kate and Ashley - Pocket Planner (USA, Europe).gbc" size 1048576 crc 84A880B9 md5 9D80032F7D8DDDB30AABF19455E9C6E3 sha1 138472B98387169425B6A652BE6CC8594E031BBE flags verified ) + name "Mary-Kate and Ashley - Pocket Planner (USA, Europe) (GB Compatible)" + description "Mary-Kate and Ashley - Pocket Planner (USA, Europe) (GB Compatible)" + rom ( name "Mary-Kate and Ashley - Pocket Planner (USA, Europe) (GB Compatible).gbc" size 1048576 crc 84a880b9 sha1 138472B98387169425B6A652BE6CC8594E031BBE flags verified ) ) game ( name "Mary-Kate and Ashley - Winners Circle (USA, Europe)" description "Mary-Kate and Ashley - Winners Circle (USA, Europe)" - rom ( name "Mary-Kate and Ashley - Winners Circle (USA, Europe).gbc" size 1048576 crc 35D6DDCC md5 9DE083FF607F9A8022FDE52D598160E8 sha1 B12133AF5EA63D05C2625CC46D1FFA55D19054FC flags verified ) + rom ( name "Mary-Kate and Ashley - Winners Circle (USA, Europe).gbc" size 1048576 crc 35d6ddcc sha1 B12133AF5EA63D05C2625CC46D1FFA55D19054FC flags verified ) ) game ( name "Mask of Zorro, The (Europe)" description "Mask of Zorro, The (Europe)" - rom ( name "Mask of Zorro, The (Europe).gbc" size 1048576 crc 909C870F md5 A119452D83B0A2E72BFC0AC706325667 sha1 20FD1B3ED55A21FD6BF62A29EF8B57DDF1C0C73E flags verified ) + rom ( name "Mask of Zorro, The (Europe).gbc" size 1048576 crc 909c870f sha1 20FD1B3ED55A21FD6BF62A29EF8B57DDF1C0C73E flags verified ) ) game ( name "Mask of Zorro, The (USA)" description "Mask of Zorro, The (USA)" - rom ( name "Mask of Zorro, The (USA).gbc" size 1048576 crc 2C92AD12 md5 A0CEAF6EBF640A48E2BF54478D2E4A63 sha1 134C03F90B21FACF8720783C5DCEFB182E3839EC ) + rom ( name "Mask of Zorro, The (USA).gbc" size 1048576 crc 2c92ad12 sha1 134C03F90B21FACF8720783C5DCEFB182E3839EC ) ) game ( name "Mat Hoffman's Pro BMX (USA, Europe)" description "Mat Hoffman's Pro BMX (USA, Europe)" - rom ( name "Mat Hoffman's Pro BMX (USA, Europe).gbc" size 1048576 crc 515C1459 md5 8BF8F9A1E0080D257820EC5506A3FC8F sha1 15F58D2647FD772C8D08E6C0A23911F1F486AEE2 flags verified ) + rom ( name "Mat Hoffman's Pro BMX (USA, Europe).gbc" size 1048576 crc 515c1459 sha1 15F58D2647FD772C8D08E6C0A23911F1F486AEE2 flags verified ) ) game ( name "Matchbox Emergency Patrol (USA, Europe)" description "Matchbox Emergency Patrol (USA, Europe)" - rom ( name "Matchbox Emergency Patrol (USA, Europe).gbc" size 2097152 crc A3F23D7E md5 B717E9A48B44A5D367E8BCB4A5E68535 sha1 8697A1A2D3575527C06114B422BD855384CF8905 flags verified ) + rom ( name "Matchbox Emergency Patrol (USA, Europe).gbc" size 2097152 crc a3f23d7e sha1 8697A1A2D3575527C06114B422BD855384CF8905 flags verified ) ) game ( name "Maus, Die (Europe) (En,Fr,De,Es)" description "Maus, Die (Europe) (En,Fr,De,Es)" - rom ( name "Maus, Die (Europe) (En,Fr,De,Es).gbc" size 1048576 crc E7BD4A49 md5 F9BE99D213760BA2E9525ABEA1DE3CB6 sha1 23B612AB97B9D5E0454F9AE91B7BDBD50DF91131 flags verified ) + rom ( name "Maus, Die (Europe) (En,Fr,De,Es).gbc" size 1048576 crc e7bd4a49 sha1 23B612AB97B9D5E0454F9AE91B7BDBD50DF91131 flags verified ) ) game ( name "Maus, Die - Verrueckte Olympiade (Germany)" description "Maus, Die - Verrueckte Olympiade (Germany)" - rom ( name "Maus, Die - Verrueckte Olympiade (Germany).gbc" size 1048576 crc FD11138E md5 0CD10ACB3C569FAECD01B9CED51021B2 sha1 861F53EC6D5981B5F5237777FD776299D90F4CC0 flags verified ) + rom ( name "Maus, Die - Verrueckte Olympiade (Germany).gbc" size 1048576 crc fd11138e sha1 861F53EC6D5981B5F5237777FD776299D90F4CC0 flags verified ) ) game ( - name "Maya the Bee & Her Friends (Europe) (En,Fr,De,Es)" - description "Maya the Bee & Her Friends (Europe) (En,Fr,De,Es)" - rom ( name "Maya the Bee & Her Friends (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 983B1D26 md5 184F5D0FBB190AE2D7242E0A7EC4A407 sha1 522D7F33FD39BD00F48208743FB2246EF0BD3FF1 ) + name "Maya the Bee & Her Friends (Europe) (En,Fr,De) (GB Compatible)" + description "Maya the Bee & Her Friends (Europe) (En,Fr,De) (GB Compatible)" + rom ( name "Maya the Bee & Her Friends (Europe) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc 983b1d26 sha1 522D7F33FD39BD00F48208743FB2246EF0BD3FF1 ) ) game ( name "Maya the Bee - Garden Adventures (Europe) (En,Fr,De,Es)" description "Maya the Bee - Garden Adventures (Europe) (En,Fr,De,Es)" - rom ( name "Maya the Bee - Garden Adventures (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 142B6EFB md5 45DB77FB2F2923C33FF9D521D5EAECCE sha1 E46EA15B4C780A49E29E86516CB1EC5A03BDDDCE ) + rom ( name "Maya the Bee - Garden Adventures (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 142b6efb sha1 E46EA15B4C780A49E29E86516CB1EC5A03BDDDCE ) ) game ( name "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" description "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" - rom ( name "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan).gbc" size 2097152 crc 66328695 md5 E6009A3556E22FA2F42134999759D366 sha1 5198A1C3A2BB2CFD6D5986A71E322CB6F43609BB ) + rom ( name "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan).gbc" size 2097152 crc 66328695 sha1 5198A1C3A2BB2CFD6D5986A71E322CB6F43609BB flags verified ) ) game ( - name "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced)" - description "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced)" - rom ( name "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced).gbc" size 2097152 crc BF6BD446 md5 C0FD19D90D3D876CC321074239C7334E sha1 01ADF621D6E2CBFEC46306D69882FC2EB3D92DE5 ) + name "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Medarot 2 - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc bf6bd446 sha1 01ADF621D6E2CBFEC46306D69882FC2EB3D92DE5 flags verified ) ) game ( - name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced)" - description "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced)" - rom ( name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced).gbc" size 2097152 crc 5B8FFD37 md5 44090E5F80E30ABDDF264B170C236A9E sha1 48FC8C6E84C63EE47F5A2C5E99DC1666D6E9F496 flags verified ) + name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Medarot 2 - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 5b8ffd37 sha1 48FC8C6E84C63EE47F5A2C5E99DC1666D6E9F496 flags verified ) ) game ( - name "Medarot 2 - Parts Collection (Japan) (SGB Enhanced)" - description "Medarot 2 - Parts Collection (Japan) (SGB Enhanced)" - rom ( name "Medarot 2 - Parts Collection (Japan) (SGB Enhanced).gbc" size 2097152 crc 159673DB md5 5F797C8C175237B9EF0D9A6888A4A239 sha1 62E6E2800025918A0DF9CEB31418DCBFE9E64289 flags verified ) + name "Medarot 2 - Parts Collection (Japan) (SGB Enhanced) (GB Compatible)" + description "Medarot 2 - Parts Collection (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Medarot 2 - Parts Collection (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 159673db sha1 62E6E2800025918A0DF9CEB31418DCBFE9E64289 flags verified ) ) game ( name "Medarot 3 - Kabuto Version (Japan)" description "Medarot 3 - Kabuto Version (Japan)" - rom ( name "Medarot 3 - Kabuto Version (Japan).gbc" size 4194304 crc E655632C md5 CBC55F3BB98F8C0443917AE477E56E51 sha1 5478069C840B5B13E2413771F35FDC844D1974F1 flags verified ) + rom ( name "Medarot 3 - Kabuto Version (Japan).gbc" size 4194304 crc e655632c sha1 5478069C840B5B13E2413771F35FDC844D1974F1 flags verified ) ) game ( name "Medarot 3 - Kuwagata Version (Japan)" description "Medarot 3 - Kuwagata Version (Japan)" - rom ( name "Medarot 3 - Kuwagata Version (Japan).gbc" size 4194304 crc BC617834 md5 DABFBDC9ABA5F2EDC21F884C52881E0D sha1 5207698702D206046DD105B07E0C0BBDBC6ED39C ) + rom ( name "Medarot 3 - Kuwagata Version (Japan).gbc" size 4194304 crc bc617834 sha1 5207698702D206046DD105B07E0C0BBDBC6ED39C flags verified ) ) game ( name "Medarot 3 - Parts Collection - Z kara no Chousenjou (Japan)" description "Medarot 3 - Parts Collection - Z kara no Chousenjou (Japan)" - rom ( name "Medarot 3 - Parts Collection - Z kara no Chousenjou (Japan).gbc" size 2097152 crc EE2D977F md5 3B789F606B4B249F1557F55CF102D45E sha1 3F13CED98EE7EDF3504559C111825C6F0997F3D9 ) + rom ( name "Medarot 3 - Parts Collection - Z kara no Chousenjou (Japan).gbc" size 2097152 crc ee2d977f sha1 3F13CED98EE7EDF3504559C111825C6F0997F3D9 flags verified ) ) game ( name "Medarot 4 - Kabuto Version (Japan)" description "Medarot 4 - Kabuto Version (Japan)" - rom ( name "Medarot 4 - Kabuto Version (Japan).gbc" size 4194304 crc C192A368 md5 C5EFFC311C2248D6DE58B487E729406B sha1 A62A00EE6095B3DCDF347FBB7C536B51976A109F ) + rom ( name "Medarot 4 - Kabuto Version (Japan).gbc" size 4194304 crc c192a368 sha1 A62A00EE6095B3DCDF347FBB7C536B51976A109F flags verified ) ) game ( name "Medarot 4 - Kuwagata Version (Japan)" description "Medarot 4 - Kuwagata Version (Japan)" - rom ( name "Medarot 4 - Kuwagata Version (Japan).gbc" size 4194304 crc 6A29B9D8 md5 7E9F03DCBF376FB935553684D6C7D8F5 sha1 10B3E69D19897FD233915E3949D02BE71AF0E521 flags verified ) + rom ( name "Medarot 4 - Kuwagata Version (Japan).gbc" size 4194304 crc 6a29b9d8 sha1 10B3E69D19897FD233915E3949D02BE71AF0E521 flags verified ) ) game ( name "Medarot 5 - Susutake Mura no Tenkousei - Kabuto (Japan)" description "Medarot 5 - Susutake Mura no Tenkousei - Kabuto (Japan)" - rom ( name "Medarot 5 - Susutake Mura no Tenkousei - Kabuto (Japan).gbc" size 4194304 crc A3C1756E md5 6CC1CFBD1FC01B948E03F507C530260D sha1 7F52ECB2A057D99B0448D82E3B5263EB92C2396C flags verified ) + rom ( name "Medarot 5 - Susutake Mura no Tenkousei - Kabuto (Japan).gbc" size 4194304 crc a3c1756e sha1 7F52ECB2A057D99B0448D82E3B5263EB92C2396C flags verified ) ) game ( name "Medarot 5 - Susutake Mura no Tenkousei - Kuwagata (Japan)" description "Medarot 5 - Susutake Mura no Tenkousei - Kuwagata (Japan)" - rom ( name "Medarot 5 - Susutake Mura no Tenkousei - Kuwagata (Japan).gbc" size 4194304 crc 014083A8 md5 11893F422BCFE26E22889A0FCDF61547 sha1 3FCC292449DA992F04C61D9117F3D5CC1BEF446F flags verified ) + rom ( name "Medarot 5 - Susutake Mura no Tenkousei - Kuwagata (Japan).gbc" size 4194304 crc 014083a8 sha1 3FCC292449DA992F04C61D9117F3D5CC1BEF446F flags verified ) ) game ( - name "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced)" - description "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced)" - rom ( name "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced).gbc" size 2097152 crc 4F03D80A md5 B1DBA18C324554A433893073599777A7 sha1 B7A02CEE93169F73675B562D09D10175684EC77F flags verified ) + name "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Medarot Cardrobottle - Kabuto Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4f03d80a sha1 B7A02CEE93169F73675B562D09D10175684EC77F flags verified ) ) game ( - name "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced)" - description "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced)" - rom ( name "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced).gbc" size 2097152 crc A3735F81 md5 6EAB24805E2DEA9C991D679FD00A5D87 sha1 26B5516170EA0FA1669CAFB9484E1AEB5D2CAE6C flags verified ) + name "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Medarot Cardrobottle - Kuwagata Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc a3735f81 sha1 26B5516170EA0FA1669CAFB9484E1AEB5D2CAE6C flags verified ) ) game ( - name "Mega Man Xtreme (USA, Europe)" - description "Mega Man Xtreme (USA, Europe)" - rom ( name "Mega Man Xtreme (USA, Europe).gbc" size 1048576 crc 3A4D94D5 md5 4681F5B931A2E60CA163FACD1ADF56ED sha1 C877449BA0889FDCACF23C49B0611D0CA57283C5 flags verified ) + name "Mega Man Xtreme (USA, Europe) (GB Compatible)" + description "Mega Man Xtreme (USA, Europe) (GB Compatible)" + rom ( name "Mega Man Xtreme (USA, Europe) (GB Compatible).gbc" size 1048576 crc 3a4d94d5 sha1 C877449BA0889FDCACF23C49B0611D0CA57283C5 flags verified ) ) game ( name "Mega Man Xtreme 2 (USA, Europe)" description "Mega Man Xtreme 2 (USA, Europe)" - rom ( name "Mega Man Xtreme 2 (USA, Europe).gbc" size 1048576 crc 8FEDB6D8 md5 1F64989765F605D05CBD013E7FFCC352 sha1 CB1811AC8969F6B683DF954B57138DD28EBB40FF flags verified ) + rom ( name "Mega Man Xtreme 2 (USA, Europe).gbc" size 1048576 crc 8fedb6d8 sha1 CB1811AC8969F6B683DF954B57138DD28EBB40FF flags verified ) ) game ( - name "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced)" - description "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced)" - rom ( name "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced).gbc" size 1048576 crc BD9BA639 md5 9F4382352A6FD43C844C3ACED7CD842A sha1 419C5AFDBC9B59E05E7861DE8CC59EE367CD29F0 ) + name "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced) (GB Compatible)" + description "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Megami Tensei Gaiden - Last Bible (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bd9ba639 sha1 419C5AFDBC9B59E05E7861DE8CC59EE367CD29F0 flags verified ) ) game ( - name "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced)" - description "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced)" - rom ( name "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced).gbc" size 1048576 crc 9CAA00B5 md5 7E32DC8B60413CFAA24F941691E545D2 sha1 84DF9508BDD8B24DFB19A74744FEC492FFFEE56D ) + name "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced) (GB Compatible)" + description "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Megami Tensei Gaiden - Last Bible II (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9caa00b5 sha1 84DF9508BDD8B24DFB19A74744FEC492FFFEE56D ) ) game ( - name "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced)" - description "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced)" - rom ( name "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced).gbc" size 1048576 crc 3B5F24FC md5 3A3E92C106A8674642E0EE3C0C793A9F sha1 A418FF2F97536E105B4F0A1BD4BB3FA31F911A7D flags verified ) + name "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced) (GB Compatible)" + description "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Meitantei Conan - Karakuri Jiin Satsujin Jiken (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 3b5f24fc sha1 A418FF2F97536E105B4F0A1BD4BB3FA31F911A7D flags verified ) ) game ( - name "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced)" - description "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced)" - rom ( name "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced).gbc" size 1048576 crc E620FAE2 md5 F5325EAF1ECBF7CD6E1E561A3B5D77F7 sha1 CD3F8015E5B708F1EB14C374042A1701EEAAFC4F flags verified ) + name "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced) (GB Compatible)" + description "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Meitantei Conan - Kigantou Hihou Densetsu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e620fae2 sha1 CD3F8015E5B708F1EB14C374042A1701EEAAFC4F flags verified ) ) game ( - name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced)" - description "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced)" - rom ( name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced).gbc" size 2097152 crc CABDD802 md5 EA991B38B2A74D10C6D075F509D9B555 sha1 0858A619D716B0191713734D506D9F113F0D1C62 ) + name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible)" + description "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cabdd802 sha1 0858A619D716B0191713734D506D9F113F0D1C62 ) ) game ( - name "Men in Black - The Series (USA, Europe) (SGB Enhanced)" - description "Men in Black - The Series (USA, Europe) (SGB Enhanced)" - rom ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 65B8B343 md5 42FF80B90350D30AAFE41EA2C71A79BF sha1 7CEB1C82BDD185546C3DD5D2653788D74D811F7A flags verified ) + name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 65b8b343 sha1 7CEB1C82BDD185546C3DD5D2653788D74D811F7A flags verified ) ) game ( name "Men in Black 2 - The Series (Europe) (En,Fr,De)" description "Men in Black 2 - The Series (Europe) (En,Fr,De)" - rom ( name "Men in Black 2 - The Series (Europe) (En,Fr,De).gbc" size 1048576 crc CA675933 md5 D99A820E6FABC76264EE1A08B41EF794 sha1 F1527FD7F82329EF676A6D475596E7D91C4065CC ) + rom ( name "Men in Black 2 - The Series (Europe) (En,Fr,De).gbc" size 1048576 crc ca675933 sha1 F1527FD7F82329EF676A6D475596E7D91C4065CC ) ) game ( name "Men in Black 2 - The Series (USA) (En,Fr,De)" description "Men in Black 2 - The Series (USA) (En,Fr,De)" - rom ( name "Men in Black 2 - The Series (USA) (En,Fr,De).gbc" size 1048576 crc 8B63F36F md5 9CF75B247EC97B8838181AD75D5F983A sha1 CCFB89824E81D128A26A38F3E2C49AAE1E9752ED ) + rom ( name "Men in Black 2 - The Series (USA) (En,Fr,De).gbc" size 1048576 crc 8b63f36f sha1 CCFB89824E81D128A26A38F3E2C49AAE1E9752ED ) ) game ( name "Merlin (Europe) (En,Fr,De,Es,It,Nl)" description "Merlin (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Merlin (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc C5290CEE md5 943D6C35C9B43494B90FFBDE49EAC53F sha1 96EE6A40ABF4BCBB90F3EA7C232FB3866333A202 ) + rom ( name "Merlin (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc c5290cee sha1 96EE6A40ABF4BCBB90F3EA7C232FB3866333A202 ) ) game ( name "MetaFight EX (Japan)" description "MetaFight EX (Japan)" - rom ( name "MetaFight EX (Japan).gbc" size 1048576 crc 00733C77 md5 CD679208722A1C68EC9537394D6B2D35 sha1 95057ADDEC90061CFAB3E5C5C56D4F87FFC9D00E ) + rom ( name "MetaFight EX (Japan).gbc" size 1048576 crc 00733c77 sha1 95057ADDEC90061CFAB3E5C5C56D4F87FFC9D00E ) ) game ( name "Metal Gear - Ghost Babel (Japan)" description "Metal Gear - Ghost Babel (Japan)" - rom ( name "Metal Gear - Ghost Babel (Japan).gbc" size 2097152 crc 7831F84D md5 7830328F323BD77D52A6985B1B10031F sha1 CA9C35B578171F7AC4957EBB838195E806B5C1E8 ) + rom ( name "Metal Gear - Ghost Babel (Japan).gbc" size 2097152 crc 7831f84d sha1 CA9C35B578171F7AC4957EBB838195E806B5C1E8 ) ) game ( name "Metal Gear Solid (Europe) (En,Fr,De,Es,It)" description "Metal Gear Solid (Europe) (En,Fr,De,Es,It)" - rom ( name "Metal Gear Solid (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 16796957 md5 7971C95AD9745FE20DF52E03CD52F636 sha1 488BFF9C4CEE9E692A05B3938FD7B2014E743EAC flags verified ) + rom ( name "Metal Gear Solid (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 16796957 sha1 488BFF9C4CEE9E692A05B3938FD7B2014E743EAC flags verified ) ) game ( name "Metal Gear Solid (USA)" description "Metal Gear Solid (USA)" - rom ( name "Metal Gear Solid (USA).gbc" size 2097152 crc 04B0C5D6 md5 F6DD1B1E5747412B9E5F25376C972D5A sha1 2266499CFA10351B23FEFD2216308867D1F1558B flags verified ) + rom ( name "Metal Gear Solid (USA).gbc" size 2097152 crc 04b0c5d6 sha1 2266499CFA10351B23FEFD2216308867D1F1558B flags verified ) ) game ( - name "Metal Walker (USA)" - description "Metal Walker (USA)" - rom ( name "Metal Walker (USA).gbc" size 1048576 crc 3BE68391 md5 82D17BEB1AEFD1B93621D6FA61DFA1CB sha1 1CCB07D705EF68E078440118C178B87646E9B724 flags verified ) + name "Metal Walker (USA) (GB Compatible)" + description "Metal Walker (USA) (GB Compatible)" + rom ( name "Metal Walker (USA) (GB Compatible).gbc" size 1048576 crc 3be68391 sha1 1CCB07D705EF68E078440118C178B87646E9B724 flags verified ) ) game ( name "Metamode (Japan)" description "Metamode (Japan)" - rom ( name "Metamode (Japan).gbc" size 2097152 crc A76EED5B md5 017CDE0DB5D27525AF84123F1CE81EDF sha1 1C1D74C810B90CF4D2EE32859EAEA569A5B45C3F flags verified ) + rom ( name "Metamode (Japan).gbc" size 2097152 crc a76eed5b sha1 1C1D74C810B90CF4D2EE32859EAEA569A5B45C3F flags verified ) ) game ( name "Mia Hamm Soccer Shootout (USA)" description "Mia Hamm Soccer Shootout (USA)" - rom ( name "Mia Hamm Soccer Shootout (USA).gbc" size 1048576 crc D77971C0 md5 C1CF2D44F37A31FA7D5CDC7D523FD145 sha1 82E7C25BDEE895A6DFDC01AD3E94138BF7B98E59 ) + rom ( name "Mia Hamm Soccer Shootout (USA).gbc" size 1048576 crc d77971c0 sha1 82E7C25BDEE895A6DFDC01AD3E94138BF7B98E59 ) ) game ( name "Mickey's Racing Adventure (USA, Europe) (En,Fr,De,Es,It)" description "Mickey's Racing Adventure (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Mickey's Racing Adventure (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc D5E845F4 md5 221D3B96DF7D86291B553A7CB4702DEC sha1 E93E8CDE531DBCA8A5CC40A8A4E3936F13541F01 flags verified ) + rom ( name "Mickey's Racing Adventure (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc d5e845f4 sha1 E93E8CDE531DBCA8A5CC40A8A4E3936F13541F01 flags verified ) ) game ( name "Mickey's Speedway USA (USA, Europe) (En,Fr,De,Es)" description "Mickey's Speedway USA (USA, Europe) (En,Fr,De,Es)" - rom ( name "Mickey's Speedway USA (USA, Europe) (En,Fr,De,Es).gbc" size 4194304 crc 11763934 md5 FF9B78E1F399FC2BD665B8A08BA27456 sha1 EDD7F3FECFEF81BCD5445B6B5DF89CA2BE897D2F flags verified ) + rom ( name "Mickey's Speedway USA (USA, Europe) (En,Fr,De,Es).gbc" size 4194304 crc 11763934 sha1 EDD7F3FECFEF81BCD5445B6B5DF89CA2BE897D2F flags verified ) ) game ( name "Micro Machines 1 and 2 - Twin Turbo (USA, Europe)" description "Micro Machines 1 and 2 - Twin Turbo (USA, Europe)" - rom ( name "Micro Machines 1 and 2 - Twin Turbo (USA, Europe).gbc" size 2097152 crc 5DD337EB md5 A721520DF37C636ED924DBC268CDD753 sha1 18B5C14EE3B3F3C16B9D641C3B3824B15C0A0C78 flags verified ) + rom ( name "Micro Machines 1 and 2 - Twin Turbo (USA, Europe).gbc" size 2097152 crc 5dd337eb sha1 18B5C14EE3B3F3C16B9D641C3B3824B15C0A0C78 flags verified ) ) game ( name "Micro Machines V3 (USA, Europe)" description "Micro Machines V3 (USA, Europe)" - rom ( name "Micro Machines V3 (USA, Europe).gbc" size 2097152 crc B8064453 md5 B6EA71372C0ACB3CDC8CC64A4B2ADD2E sha1 8E9EFBE195BCECFEC4B233921B22B2E7FCE38D3A flags verified ) + rom ( name "Micro Machines V3 (USA, Europe).gbc" size 2097152 crc b8064453 sha1 8E9EFBE195BCECFEC4B233921B22B2E7FCE38D3A flags verified ) ) game ( name "Micro Maniacs (Europe)" description "Micro Maniacs (Europe)" - rom ( name "Micro Maniacs (Europe).gbc" size 2097152 crc E66E093B md5 AA7235FBDF5F0C7FB5A67BC6D24DD4DF sha1 53773090E44E0A24A4481249541D48EA1432E83D ) + rom ( name "Micro Maniacs (Europe).gbc" size 2097152 crc e66e093b sha1 53773090E44E0A24A4481249541D48EA1432E83D ) ) game ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (Europe) (En,Fr,De,Es,It)" description "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (Europe) (En,Fr,De,Es,It)" - rom ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc EE4CBA24 md5 94716503C16F0387F9F78962BCA5B30C sha1 0AF8EA56FCBF49C49D6815D316B1CD80CD8E1538 ) + rom ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc ee4cba24 sha1 0AF8EA56FCBF49C49D6815D316B1CD80CD8E1538 ) ) game ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (USA)" description "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (USA)" - rom ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (USA).gbc" size 1048576 crc 0777B8D7 md5 45A4CEFCA0B17CA193869BF6D6134D7C sha1 EDF2B960209D8763A330C72FCFD890B360864AEB ) + rom ( name "Microsoft - The 6 in 1 Puzzle Collection Entertainment Pack (USA).gbc" size 1048576 crc 0777b8d7 sha1 EDF2B960209D8763A330C72FCFD890B360864AEB flags verified ) ) game ( name "Microsoft - The Best of Entertainment Pack (Europe)" description "Microsoft - The Best of Entertainment Pack (Europe)" - rom ( name "Microsoft - The Best of Entertainment Pack (Europe).gbc" size 1048576 crc 0F02D708 md5 C576F119CB3AD8AD7B5F18E6755232F3 sha1 BE52FA14E66F4B35C66F434DB61DA4CFCEC71762 flags verified ) + rom ( name "Microsoft - The Best of Entertainment Pack (Europe).gbc" size 1048576 crc 0f02d708 sha1 BE52FA14E66F4B35C66F434DB61DA4CFCEC71762 flags verified ) ) game ( name "Microsoft - The Best of Entertainment Pack (USA)" description "Microsoft - The Best of Entertainment Pack (USA)" - rom ( name "Microsoft - The Best of Entertainment Pack (USA).gbc" size 1048576 crc D2D88CFA md5 81433716E1A23AEFE5DE0FC03EF55519 sha1 38B4814AFD24BF1FFFA382ED3396B6413ABC5616 ) + rom ( name "Microsoft - The Best of Entertainment Pack (USA).gbc" size 1048576 crc d2d88cfa sha1 38B4814AFD24BF1FFFA382ED3396B6413ABC5616 ) ) game ( name "Microsoft Pinball Arcade (USA)" description "Microsoft Pinball Arcade (USA)" - rom ( name "Microsoft Pinball Arcade (USA).gbc" size 1048576 crc 504F55C5 md5 31F7A606B52E8D10FC010B4EFE9FB514 sha1 DA4593EDB37BE892374E00D0174E45FF6301C907 flags verified ) + rom ( name "Microsoft Pinball Arcade (USA).gbc" size 1048576 crc 504f55c5 sha1 DA4593EDB37BE892374E00D0174E45FF6301C907 flags verified ) ) game ( name "Microsoft Pinball Arcade (Europe)" description "Microsoft Pinball Arcade (Europe)" - rom ( name "Microsoft Pinball Arcade (Europe).gbc" size 1048576 crc 4EB7DB14 md5 49BC624C902FCB2E4892E5C823C987D0 sha1 F2874F0F3023D96EDBDB94E5C0DC181D8BAA3EFB flags verified ) + rom ( name "Microsoft Pinball Arcade (Europe).gbc" size 1048576 crc 4eb7db14 sha1 F2874F0F3023D96EDBDB94E5C0DC181D8BAA3EFB flags verified ) +) + +game ( + name "Midway presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" + description "Midway presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" + rom ( name "Midway presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible).gbc" size 1048576 crc 4c1ececb sha1 F0F35970517090165797568448B5EF5CAD8E4952 flags verified ) +) + +game ( + name "Midway presents Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe) (GB Compatible)" + description "Midway presents Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe) (GB Compatible)" + rom ( name "Midway presents Arcade Hits - Moon Patrol & Spy Hunter (USA, Europe) (GB Compatible).gbc" size 1048576 crc f40199c9 sha1 8DC667E7D44B46AD42EC7E465091CFACC0009974 flags verified ) ) game ( name "Millennium Winter Sports (USA)" description "Millennium Winter Sports (USA)" - rom ( name "Millennium Winter Sports (USA).gbc" size 1048576 crc B57DABAE md5 9F6135616B201739AF43236FCFD5C273 sha1 F47321C3C1217467DC48240BF53B50ED9630B28A ) + rom ( name "Millennium Winter Sports (USA).gbc" size 1048576 crc b57dabae sha1 F47321C3C1217467DC48240BF53B50ED9630B28A ) ) game ( - name "Minna no Shougi - Shokyuu Hen (Japan)" - description "Minna no Shougi - Shokyuu Hen (Japan)" - rom ( name "Minna no Shougi - Shokyuu Hen (Japan).gbc" size 1048576 crc 5CB4FC8A md5 8D2A6B487AADE7CA05696548C2EFB181 sha1 777088B9A3963E55DD6F90A523A84ED58A008149 ) + name "Minna no Shougi - Shokyuu Hen (Japan) (GB Compatible)" + description "Minna no Shougi - Shokyuu Hen (Japan) (GB Compatible)" + rom ( name "Minna no Shougi - Shokyuu Hen (Japan) (GB Compatible).gbc" size 1048576 crc 5cb4fc8a sha1 777088B9A3963E55DD6F90A523A84ED58A008149 flags verified ) +) + +game ( + name "Minna no Shougi - Shokyuu Hen (Japan) (Rev 1)" + description "Minna no Shougi - Shokyuu Hen (Japan) (Rev 1)" + rom ( name "Minna no Shougi - Shokyuu Hen (Japan) (Rev 1).gbc" size 1048576 crc f766015a sha1 948D2015C29342FDB6052940A5D65E771B0A81D0 flags verified ) ) game ( name "Minnie & Friends - Yume no Kuni o Sagashite (Japan)" description "Minnie & Friends - Yume no Kuni o Sagashite (Japan)" - rom ( name "Minnie & Friends - Yume no Kuni o Sagashite (Japan).gbc" size 2097152 crc D47AE577 md5 5323967B4E46C4A76EA3576675BE42AC sha1 146F336D16D165590D09F41F44BA52A81816A033 flags verified ) + rom ( name "Minnie & Friends - Yume no Kuni o Sagashite (Japan).gbc" size 2097152 crc d47ae577 sha1 146F336D16D165590D09F41F44BA52A81816A033 flags verified ) ) game ( name "Missile Command (Europe)" description "Missile Command (Europe)" - rom ( name "Missile Command (Europe).gbc" size 1048576 crc 18216E26 md5 708F4C9E41D17B8F4FB11CC227FE9989 sha1 BA4C1C10CFEB74584338D49A64F835995AF734FD flags verified ) + rom ( name "Missile Command (Europe).gbc" size 1048576 crc 18216e26 sha1 BA4C1C10CFEB74584338D49A64F835995AF734FD flags verified ) ) game ( name "Missile Command (USA) (Rumble Version)" description "Missile Command (USA) (Rumble Version)" - rom ( name "Missile Command (USA) (Rumble Version).gbc" size 1048576 crc 47543C51 md5 1FC58F4E3A2437F4C20C9812162797D8 sha1 7BD68586DF8754CBC81B2DCBB6E2B5DE43F812E8 ) + rom ( name "Missile Command (USA) (Rumble Version).gbc" size 1048576 crc 47543c51 sha1 7BD68586DF8754CBC81B2DCBB6E2B5DE43F812E8 ) ) game ( - name "Mission Impossible (Europe) (En,Fr,De,Es,It)" - description "Mission Impossible (Europe) (En,Fr,De,Es,It)" - rom ( name "Mission Impossible (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 0AF32BAA md5 AFF1AA8C293DC5E26FA704EB1693DC0C sha1 5EB8DAD248FF23809016A2515657089116E8DF33 ) + name "Mission - Impossible (Europe) (En,Fr,De,Es,It)" + description "Mission - Impossible (Europe) (En,Fr,De,Es,It)" + rom ( name "Mission - Impossible (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 0af32baa sha1 5EB8DAD248FF23809016A2515657089116E8DF33 ) ) game ( - name "Mission Impossible (USA) (En,Fr,Es)" - description "Mission Impossible (USA) (En,Fr,Es)" - rom ( name "Mission Impossible (USA) (En,Fr,Es).gbc" size 1048576 crc 41230D11 md5 11454CE5A4AD703C29B3A8BDC8B5C3AB sha1 A987998CF57D2EB2275DE94CD0E81254B711CCAC ) + name "Mission - Impossible (USA) (En,Fr,Es)" + description "Mission - Impossible (USA) (En,Fr,Es)" + rom ( name "Mission - Impossible (USA) (En,Fr,Es).gbc" size 1048576 crc 41230d11 sha1 A987998CF57D2EB2275DE94CD0E81254B711CCAC ) ) game ( name "Mizuki Shigeru no Shin Youkaiden (Japan)" description "Mizuki Shigeru no Shin Youkaiden (Japan)" - rom ( name "Mizuki Shigeru no Shin Youkaiden (Japan).gbc" size 4194304 crc FC1F100F md5 600C8C4D9FCC759DAE5055297B0EBB5F sha1 AB12770558FB95434BBA0DA0D3B8A91E2D9179FB ) + rom ( name "Mizuki Shigeru no Shin Youkaiden (Japan).gbc" size 4194304 crc fc1f100f sha1 AB12770558FB95434BBA0DA0D3B8A91E2D9179FB ) ) game ( name "Mobile Golf (Japan)" description "Mobile Golf (Japan)" - rom ( name "Mobile Golf (Japan).gbc" size 4194304 crc 35FC5B32 md5 FBF1FFE76883DFFCCA299228C81F171F sha1 FDE414FC9EFEF2C30D1A9E0A2ED35AD2EFC0EDEE flags verified ) + rom ( name "Mobile Golf (Japan).gbc" size 4194304 crc 35fc5b32 sha1 FDE414FC9EFEF2C30D1A9E0A2ED35AD2EFC0EDEE flags verified ) ) game ( name "Mobile Trainer (Japan)" description "Mobile Trainer (Japan)" - rom ( name "Mobile Trainer (Japan).gbc" size 2097152 crc 7226EAD0 md5 AEF9B41FBC898A58FD2AAAEABC2787E9 sha1 ECC0579EDEAF9ECCD722D605CC288CD023C8576A flags verified ) + rom ( name "Mobile Trainer (Japan).gbc" size 2097152 crc 7226ead0 sha1 ECC0579EDEAF9ECCD722D605CC288CD023C8576A flags verified ) ) game ( name "Momotarou Densetsu 1-2 (Japan)" description "Momotarou Densetsu 1-2 (Japan)" - rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc DA7FB08F md5 88938327F7A5A8D11470D14D17F412B3 sha1 ACFFA3417C85BE574AA28432E29E1D40F28A565B flags verified ) + rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc da7fb08f sha1 ACFFA3417C85BE574AA28432E29E1D40F28A565B flags verified ) ) game ( - name "Monkey Puncher (Europe) (SGB Enhanced)" - description "Monkey Puncher (Europe) (SGB Enhanced)" - rom ( name "Monkey Puncher (Europe) (SGB Enhanced).gbc" size 2097152 crc BC1809CE md5 65DA43AEF4C10CFD8FEEE70E842A46AE sha1 87F08F8ADC8DB96CE396BD21F33A804F63826BF3 ) + name "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" + description "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc bc1809ce sha1 87F08F8ADC8DB96CE396BD21F33A804F63826BF3 ) ) game ( - name "Monopoly (Japan) (SGB Enhanced)" - description "Monopoly (Japan) (SGB Enhanced)" - rom ( name "Monopoly (Japan) (SGB Enhanced).gbc" size 1048576 crc 0503E567 md5 92E01E78A83C86C22EE1DCBBF4C7C2F4 sha1 3F42D9B423C15B4C1B997C7A2292AB2CBA1AB23F flags verified ) + name "Monopoly (Japan) (SGB Enhanced) (GB Compatible)" + description "Monopoly (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Monopoly (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0503e567 sha1 3F42D9B423C15B4C1B997C7A2292AB2CBA1AB23F flags verified ) ) game ( - name "Monopoly (USA)" - description "Monopoly (USA)" - rom ( name "Monopoly (USA).gbc" size 1048576 crc E559A717 md5 5F1481260760C69843A61E9060AD7154 sha1 058C34BC2D86CC7D6A3F5263A21946661662F893 ) + name "Monopoly (USA) (GB Compatible)" + description "Monopoly (USA) (GB Compatible)" + rom ( name "Monopoly (USA) (GB Compatible).gbc" size 1048576 crc e559a717 sha1 058C34BC2D86CC7D6A3F5263A21946661662F893 ) ) game ( name "Monster AG, Die (Germany)" description "Monster AG, Die (Germany)" - rom ( name "Monster AG, Die (Germany).gbc" size 1048576 crc 3A9602E8 md5 26B03C986238C85BDA3ED8954115AA39 sha1 AFE20AA46FF136C0DDF6F2692B1BBDE9C30E71F6 ) + rom ( name "Monster AG, Die (Germany).gbc" size 1048576 crc 3a9602e8 sha1 AFE20AA46FF136C0DDF6F2692B1BBDE9C30E71F6 ) ) game ( - name "Monster Farm Battle Card GB (Japan) (SGB Enhanced)" - description "Monster Farm Battle Card GB (Japan) (SGB Enhanced)" - rom ( name "Monster Farm Battle Card GB (Japan) (SGB Enhanced).gbc" size 2097152 crc 69B88F1E md5 D455F4AE266279DAA36F3F3E54569239 sha1 7E036E175C9E865572AB613AE0F8E6D3642FFB0E flags verified ) + name "Monster Farm Battle Card GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Monster Farm Battle Card GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Monster Farm Battle Card GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 69b88f1e sha1 7E036E175C9E865572AB613AE0F8E6D3642FFB0E flags verified ) ) game ( - name "Monster Race 2 (Japan) (SGB Enhanced)" - description "Monster Race 2 (Japan) (SGB Enhanced)" - rom ( name "Monster Race 2 (Japan) (SGB Enhanced).gbc" size 2097152 crc B985F0D8 md5 C9A1DAB66E0B13D5835C392437B16A5A sha1 8D4A6B4CDAA37B9DAAFF5A05AC5926A407BACCE3 flags verified ) + name "Monster Race 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Monster Race 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Monster Race 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b985f0d8 sha1 8D4A6B4CDAA37B9DAAFF5A05AC5926A407BACCE3 flags verified ) ) game ( - name "Monster Rancher Battle Card GB (USA) (SGB Enhanced)" - description "Monster Rancher Battle Card GB (USA) (SGB Enhanced)" - rom ( name "Monster Rancher Battle Card GB (USA) (SGB Enhanced).gbc" size 2097152 crc 50DDF120 md5 31FC2F3DF8AA15F627574029C3CF03DA sha1 F94DC1DBDF25D9AB7F7ABD3D7878209D404B206D flags verified ) + name "Monster Rancher Battle Card GB (USA) (SGB Enhanced) (GB Compatible)" + description "Monster Rancher Battle Card GB (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Monster Rancher Battle Card GB (USA) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 50ddf120 sha1 F94DC1DBDF25D9AB7F7ABD3D7878209D404B206D flags verified ) ) game ( name "Monster Rancher Explorer (USA)" description "Monster Rancher Explorer (USA)" - rom ( name "Monster Rancher Explorer (USA).gbc" size 1048576 crc 6C35E8F0 md5 F55ED9E6A8FECE5220E9876FB515E222 sha1 649FEC320D3BAFD7A03670EE435A419D2A86C12B ) + rom ( name "Monster Rancher Explorer (USA).gbc" size 1048576 crc 6c35e8f0 sha1 649FEC320D3BAFD7A03670EE435A419D2A86C12B ) ) game ( - name "Monster Traveler (Japan) (Rev A)" - description "Monster Traveler (Japan) (Rev A)" - rom ( name "Monster Traveler (Japan) (Rev A).gbc" size 4194304 crc F60A376E md5 9D1067C75DCBCE5AACABACABB06B95C4 sha1 23842B7AD88A051B14C1676B1F561B933177F150 ) + name "Monster Traveler (Japan) (Rev 1)" + description "Monster Traveler (Japan) (Rev 1)" + rom ( name "Monster Traveler (Japan) (Rev 1).gbc" size 4194304 crc f60a376e sha1 23842B7AD88A051B14C1676B1F561B933177F150 flags verified ) ) game ( name "Monsters, Inc. (Europe) (En,Es,Nl)" description "Monsters, Inc. (Europe) (En,Es,Nl)" - rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gbc" size 1048576 crc 63E3BBB4 md5 F3DAA6CE7708668405674C735BEA9745 sha1 8713B1D51CE33A761F64455B59CD49952B7F7CD1 ) + rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gbc" size 1048576 crc 63e3bbb4 sha1 8713B1D51CE33A761F64455B59CD49952B7F7CD1 flags verified ) ) game ( name "Monsters, Inc. (Europe) (En,Fr,It)" description "Monsters, Inc. (Europe) (En,Fr,It)" - rom ( name "Monsters, Inc. (Europe) (En,Fr,It).gbc" size 1048576 crc 712D40A5 md5 D62E0C703BC1A84E0FCE512F4B9C46E7 sha1 34AB1E38F34287F022C871B6ED2116DED6D4B60D ) + rom ( name "Monsters, Inc. (Europe) (En,Fr,It).gbc" size 1048576 crc 712d40a5 sha1 34AB1E38F34287F022C871B6ED2116DED6D4B60D flags verified ) ) game ( name "Monsters, Inc. (USA, Europe)" description "Monsters, Inc. (USA, Europe)" - rom ( name "Monsters, Inc. (USA, Europe).gbc" size 1048576 crc 183DBB31 md5 5776965258EE78832E7EABC0DB66FF4B sha1 58BEFA4DBE7DAC79BFADCAF259999CDCDDF4F2C8 flags verified ) + rom ( name "Monsters, Inc. (USA, Europe).gbc" size 1048576 crc 183dbb31 sha1 58BEFA4DBE7DAC79BFADCAF259999CDCDDF4F2C8 flags verified ) ) game ( - name "Monsters, Inc. (Europe) (Rev A)" - description "Monsters, Inc. (Europe) (Rev A)" - rom ( name "Monsters, Inc. (Europe) (Rev A).gbc" size 1048576 crc 3726858A md5 4B684B00ECC0CF15536DC5AB58BDD470 sha1 31E64A1CDD25CDC4413E0A1BC15DC22017E881E4 ) + name "Monsters, Inc. (Europe) (Rev 1)" + description "Monsters, Inc. (Europe) (Rev 1)" + rom ( name "Monsters, Inc. (Europe) (Rev 1).gbc" size 1048576 crc 3726858a sha1 31E64A1CDD25CDC4413E0A1BC15DC22017E881E4 flags verified ) ) game ( - name "Montezuma's Return! (Europe) (En,Fr,De,Es,It)" - description "Montezuma's Return! (Europe) (En,Fr,De,Es,It)" - rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It).gbc" size 524288 crc 659693DE md5 EE44254C96FA9318A26A1A5B0A9B48FE sha1 014B174F569984360442FB2142A0E4AE09366DC4 flags verified ) + name "Montezuma's Return! (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Montezuma's Return! (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 524288 crc 659693de sha1 014B174F569984360442FB2142A0E4AE09366DC4 flags verified ) ) game ( - name "Montezuma's Return! (USA) (En,Es)" - description "Montezuma's Return! (USA) (En,Es)" - rom ( name "Montezuma's Return! (USA) (En,Es).gbc" size 524288 crc DE04772F md5 5F821976274F5E6147F2354A6D01F098 sha1 616BB04E0254EF2BA9E1EA629493EFDCC37D807C ) + name "Montezuma's Return! (USA) (En,Es) (GB Compatible)" + description "Montezuma's Return! (USA) (En,Es) (GB Compatible)" + rom ( name "Montezuma's Return! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc de04772f sha1 616BB04E0254EF2BA9E1EA629493EFDCC37D807C ) ) game ( name "Moomin no Daibouken (Japan)" description "Moomin no Daibouken (Japan)" - rom ( name "Moomin no Daibouken (Japan).gbc" size 2097152 crc BD29EE6F md5 F7034B8297393FA04D9752D461F749A5 sha1 0846545CEBEC8B376DB9BDB0D3744C7D157EE980 ) + rom ( name "Moomin no Daibouken (Japan).gbc" size 2097152 crc bd29ee6f sha1 0846545CEBEC8B376DB9BDB0D3744C7D157EE980 flags verified ) ) game ( name "Moomin's Tale (Europe) (En,Fr,De)" description "Moomin's Tale (Europe) (En,Fr,De)" - rom ( name "Moomin's Tale (Europe) (En,Fr,De).gbc" size 1048576 crc 45543BA2 md5 517EF53718009B20D7BF7771AEF191DD sha1 06E57B38B7F9EC71809F309AA7D220AF48CA96B6 ) -) - -game ( - name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" - description "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It)" - rom ( name "Moorhen 3 - The Chicken Chase! (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc B7C1025B md5 7E8280463D7AC79662D8BE587BB6B766 sha1 154DB731F5E1CDA137EB0FAF55A8E4458387485F ) + rom ( name "Moomin's Tale (Europe) (En,Fr,De).gbc" size 1048576 crc 45543ba2 sha1 06E57B38B7F9EC71809F309AA7D220AF48CA96B6 ) ) game ( name "Moorhuhn 2 - Die Jagd geht weiter (Germany)" description "Moorhuhn 2 - Die Jagd geht weiter (Germany)" - rom ( name "Moorhuhn 2 - Die Jagd geht weiter (Germany).gbc" size 1048576 crc ED52CEAF md5 B5FE88BBDE541C28625E32B83239E6F0 sha1 1DE0FA5B1DCAC8C8B188FD141E889461317DC28D flags verified ) + rom ( name "Moorhuhn 2 - Die Jagd geht weiter (Germany).gbc" size 1048576 crc ed52ceaf sha1 1DE0FA5B1DCAC8C8B188FD141E889461317DC28D flags verified ) ) game ( - name "Mortal Kombat 4 (Germany) (SGB Enhanced)" - description "Mortal Kombat 4 (Germany) (SGB Enhanced)" - rom ( name "Mortal Kombat 4 (Germany) (SGB Enhanced).gbc" size 1048576 crc 87588725 md5 7311F937A542BAADF113E9115158CDE3 sha1 1006B279EAB113AFE50F84E714A93C63DE8CBFCF flags verified ) + name "Moorhuhn 3 - ...Es Gibt Huhn! (Europe) (En,Fr,De,Es,It)" + description "Moorhuhn 3 - ...Es Gibt Huhn! (Europe) (En,Fr,De,Es,It)" + rom ( name "Moorhuhn 3 - ...Es Gibt Huhn! (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc b7c1025b sha1 154DB731F5E1CDA137EB0FAF55A8E4458387485F flags verified ) ) game ( - name "Mortal Kombat 4 (USA, Europe) (SGB Enhanced)" - description "Mortal Kombat 4 (USA, Europe) (SGB Enhanced)" - rom ( name "Mortal Kombat 4 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 4EB71448 md5 168AE412B379786F7DF07BD8231BAF44 sha1 EA54FB35CD8C4D4CEA234423A81F8F953B1D33E4 flags verified ) + name "Mortal Kombat 4 (Germany) (En) (SGB Enhanced) (GB Compatible)" + description "Mortal Kombat 4 (Germany) (En) (SGB Enhanced) (GB Compatible)" + rom ( name "Mortal Kombat 4 (Germany) (En) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 87588725 sha1 1006B279EAB113AFE50F84E714A93C63DE8CBFCF flags verified ) +) + +game ( + name "Mortal Kombat 4 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Mortal Kombat 4 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Mortal Kombat 4 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4eb71448 sha1 EA54FB35CD8C4D4CEA234423A81F8F953B1D33E4 flags verified ) ) game ( name "Motocross Maniacs 2 (USA)" description "Motocross Maniacs 2 (USA)" - rom ( name "Motocross Maniacs 2 (USA).gbc" size 1048576 crc 17D27FA9 md5 4D08E5553356AECD728B5EF7D78EE261 sha1 5A0E7A9A71A88EE79529531274EB3696CF0FA42C ) -) - -game ( - name "Mr Nutz (Europe) (En,Fr,De,Es,It,Nl)" - description "Mr Nutz (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Mr Nutz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 4E37C741 md5 83B67B8A10F704A9E3E7CA3814E5B3CA sha1 D60DFFC330F25A61AC1B0B4BA078178585DA6FC6 ) -) - -game ( - name "Mr Nutz (USA) (En,Fr,Es)" - description "Mr Nutz (USA) (En,Fr,Es)" - rom ( name "Mr Nutz (USA) (En,Fr,Es).gbc" size 1048576 crc 59F67529 md5 9BA7B607EC310589C5CCFB1A8149DF59 sha1 43BB8621E3D05E81A7FAA63CD76B0757F3954BA1 ) + rom ( name "Motocross Maniacs 2 (USA).gbc" size 1048576 crc 17d27fa9 sha1 5A0E7A9A71A88EE79529531274EB3696CF0FA42C ) ) game ( name "Mr. Driller (Japan)" description "Mr. Driller (Japan)" - rom ( name "Mr. Driller (Japan).gbc" size 1048576 crc 773729AF md5 B4C21D6CF67F5742EF3A19860EB31D2E sha1 B0D725DACEA717BE7109BD6A81817E717641DA86 ) + rom ( name "Mr. Driller (Japan).gbc" size 1048576 crc 773729af sha1 B0D725DACEA717BE7109BD6A81817E717641DA86 flags verified ) ) game ( name "Mr. Driller (USA)" description "Mr. Driller (USA)" - rom ( name "Mr. Driller (USA).gbc" size 1048576 crc 492C0EBF md5 76FA4014BFBB0EE2B63267AF7AC373F2 sha1 3BFDA5EDB7D125EE99B9235434488876DC6D8245 flags verified ) + rom ( name "Mr. Driller (USA).gbc" size 1048576 crc 492c0ebf sha1 3BFDA5EDB7D125EE99B9235434488876DC6D8245 flags verified ) ) game ( name "Mr. Driller (Europe)" description "Mr. Driller (Europe)" - rom ( name "Mr. Driller (Europe).gbc" size 1048576 crc BDF9B05C md5 8EE55A0AD476A0497A483A30C0B28316 sha1 6163CC65E7697EF77075A3665A234CE5D720AD9C ) + rom ( name "Mr. Driller (Europe).gbc" size 1048576 crc bdf9b05c sha1 6163CC65E7697EF77075A3665A234CE5D720AD9C flags verified ) ) game ( - name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced)" - description "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced)" - rom ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced).gbc" size 524288 crc 103E212D md5 4D090CEAA53D571DB00D7160CA4BE69D sha1 A468F7AD011C1B42EA3144E65607694493E7E4A7 ) + name "Mr. Driller (Japan) (NP)" + description "Mr. Driller (Japan) (NP)" + rom ( name "Mr. Driller (Japan) (NP).gbc" size 524288 crc 35fd440d sha1 FB64FA7DA6A0FEC3E358BB3357E66D68473ADA67 flags verified ) ) game ( - name "Ms. Pac-Man - Special Colour Edition (Europe)" - description "Ms. Pac-Man - Special Colour Edition (Europe)" - rom ( name "Ms. Pac-Man - Special Colour Edition (Europe).gbc" size 1048576 crc F2335DA9 md5 A57D5976214D5F8D52DAE5FAF4354ABB sha1 D0F831165DC9A24E46FED26F90507DADEB5F1E0E ) + name "Mr. Nutz (Europe) (En,Fr,De,Es,It,Nl)" + description "Mr. Nutz (Europe) (En,Fr,De,Es,It,Nl)" + rom ( name "Mr. Nutz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 4e37c741 sha1 D60DFFC330F25A61AC1B0B4BA078178585DA6FC6 ) +) + +game ( + name "Mr. Nutz (USA) (En,Fr,Es)" + description "Mr. Nutz (USA) (En,Fr,Es)" + rom ( name "Mr. Nutz (USA) (En,Fr,Es).gbc" size 1048576 crc 59f67529 sha1 43BB8621E3D05E81A7FAA63CD76B0757F3954BA1 flags verified ) +) + +game ( + name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" + description "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 103e212d sha1 A468F7AD011C1B42EA3144E65607694493E7E4A7 ) +) + +game ( + name "Ms. Pac-Man - Special Colour Edition (Europe) (GB Compatible)" + description "Ms. Pac-Man - Special Colour Edition (Europe) (GB Compatible)" + rom ( name "Ms. Pac-Man - Special Colour Edition (Europe) (GB Compatible).gbc" size 1048576 crc f2335da9 sha1 D0F831165DC9A24E46FED26F90507DADEB5F1E0E ) ) game ( name "MTV Sports - Pure Ride (USA, Europe)" description "MTV Sports - Pure Ride (USA, Europe)" - rom ( name "MTV Sports - Pure Ride (USA, Europe).gbc" size 1048576 crc B7B2354B md5 94E1575453F54CBE157D13EAE6E78D92 sha1 539772ED4ED2A579453DC57BA06E5AAEDA1B4981 flags verified ) + rom ( name "MTV Sports - Pure Ride (USA, Europe).gbc" size 1048576 crc b7b2354b sha1 539772ED4ED2A579453DC57BA06E5AAEDA1B4981 flags verified ) ) game ( name "MTV Sports - Skateboarding featuring Andy MacDonald (USA, Europe)" description "MTV Sports - Skateboarding featuring Andy MacDonald (USA, Europe)" - rom ( name "MTV Sports - Skateboarding featuring Andy MacDonald (USA, Europe).gbc" size 1048576 crc 744561F3 md5 54165D2BF7A040AA31D6D0956408D10D sha1 91B6E99A68293D72DF74528E8077FAE58D9C33C3 flags verified ) + rom ( name "MTV Sports - Skateboarding featuring Andy MacDonald (USA, Europe).gbc" size 1048576 crc 744561f3 sha1 91B6E99A68293D72DF74528E8077FAE58D9C33C3 flags verified ) ) game ( name "MTV Sports - T.J. Lavin's Ultimate BMX (USA, Europe)" description "MTV Sports - T.J. Lavin's Ultimate BMX (USA, Europe)" - rom ( name "MTV Sports - T.J. Lavin's Ultimate BMX (USA, Europe).gbc" size 1048576 crc 904663AF md5 495C72CDAC3CD684B5D56581CCC183E1 sha1 2922D99B87497D1519FB4FDE707B4DFD0B2E24E3 flags verified ) + rom ( name "MTV Sports - T.J. Lavin's Ultimate BMX (USA, Europe).gbc" size 1048576 crc 904663af sha1 2922D99B87497D1519FB4FDE707B4DFD0B2E24E3 flags verified ) ) game ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" description "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" - rom ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 64052B9B md5 EE4FC61AFD79C8A20E57FA04F49AD1B3 sha1 186F541E046C6223EF07DEFB3BA4E065262249B7 ) + rom ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 64052b9b sha1 186F541E046C6223EF07DEFB3BA4E065262249B7 flags verified ) ) game ( name "Mummy Returns, The (USA)" description "Mummy Returns, The (USA)" - rom ( name "Mummy Returns, The (USA).gbc" size 1048576 crc C997F45B md5 B03138AD381D8581F245CA6FF88F9EF8 sha1 6DFD1724110F1ABFF48AB349F89AE11FD201609A ) + rom ( name "Mummy Returns, The (USA).gbc" size 1048576 crc c997f45b sha1 6DFD1724110F1ABFF48AB349F89AE11FD201609A ) ) game ( name "Mummy, The (Europe) (En,Fr,De)" description "Mummy, The (Europe) (En,Fr,De)" - rom ( name "Mummy, The (Europe) (En,Fr,De).gbc" size 1048576 crc 84FC838A md5 68271240C1B372F49B01ADF583C91F83 sha1 E1F312F6499229BDCC11C90306C321EADCDB78CA ) + rom ( name "Mummy, The (Europe) (En,Fr,De).gbc" size 1048576 crc 84fc838a sha1 E1F312F6499229BDCC11C90306C321EADCDB78CA ) ) game ( name "Mummy, The (USA)" description "Mummy, The (USA)" - rom ( name "Mummy, The (USA).gbc" size 1048576 crc C6BA9F27 md5 407E0EDF45B42F88F96774C9F549CF18 sha1 35B10F392D514BCE858C8C64F9C489500466D0FF ) -) - -game ( - name "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P)" - description "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P)" - rom ( name "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AX9P).gbc" size 2097152 crc 0FAFA3F2 md5 3D24F9E876DF8C50573C00119D395B73 sha1 DC9288BC4B2A2093EA298514A91C3B2B4101691B flags verified ) -) - -game ( - name "Muppets, The (USA)" - description "Muppets, The (USA)" - rom ( name "Muppets, The (USA).gbc" size 2097152 crc 3C476C6F md5 3A70F79E33ED4EA546D0BA41A7F2EF25 sha1 77AD190AD107C57B167E3837757A4C7F990A867E ) -) - -game ( - name "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P)" - description "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P)" - rom ( name "Muppets, The (Europe) (En,Fr,De,Es,It,Nl,Sv) (AP9P).gbc" size 4194304 crc 3204B92C md5 9DCF58CE7C379A01C3288975E90624F3 sha1 6E042FC6029493A429557A6FDCE111C03F9EDE1B flags verified ) + rom ( name "Mummy, The (USA).gbc" size 1048576 crc c6ba9f27 sha1 35B10F392D514BCE858C8C64F9C489500466D0FF ) ) game ( name "Muteki Ou Tri-Zenon (Japan)" description "Muteki Ou Tri-Zenon (Japan)" - rom ( name "Muteki Ou Tri-Zenon (Japan).gbc" size 2097152 crc 0BAB7A61 md5 77C35992B64AB7F2642873A5F266AB79 sha1 2A7F422BF9AF9AFF126E47EDE8B5CEEC0630EB08 ) + rom ( name "Muteki Ou Tri-Zenon (Japan).gbc" size 2097152 crc 0bab7a61 sha1 2A7F422BF9AF9AFF126E47EDE8B5CEEC0630EB08 flags verified ) ) game ( - name "N.Y. Race (Europe) (En,Fr,De,Es,It,Pt)" - description "N.Y. Race (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "N.Y. Race (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 62F560D8 md5 B9A686E4DBC7241BDF72ACA235F7F92F sha1 001DECC8331B4BEB94A01A1B6EF08E1BF2920ECE ) + name "Mythri (USA) (Proto)" + description "Mythri (USA) (Proto)" + rom ( name "Mythri (USA) (Proto).gbc" size 524288 crc 664882ac sha1 D79650A853FFFCEF878FEDC690D5E3A607B5B9DF flags verified ) ) game ( name "Nakayoshi Cooking Series 1 - Oishii Cake-ya-san (Japan)" description "Nakayoshi Cooking Series 1 - Oishii Cake-ya-san (Japan)" - rom ( name "Nakayoshi Cooking Series 1 - Oishii Cake-ya-san (Japan).gbc" size 1048576 crc E5C9569A md5 A7F23A751078922169DF0F73A1DB1564 sha1 F98C3209FE712E5696648D946BD63FBCA16B0ED3 ) + rom ( name "Nakayoshi Cooking Series 1 - Oishii Cake-ya-san (Japan).gbc" size 1048576 crc e5c9569a sha1 F98C3209FE712E5696648D946BD63FBCA16B0ED3 ) ) game ( name "Nakayoshi Cooking Series 2 - Oishii Panya-san (Japan)" description "Nakayoshi Cooking Series 2 - Oishii Panya-san (Japan)" - rom ( name "Nakayoshi Cooking Series 2 - Oishii Panya-san (Japan).gbc" size 1048576 crc B9FA3CE4 md5 377447C3F3199D7D58788B1192FD9FB1 sha1 CF1B69A198C8D95F95BC99EB9FB1F3CAED4B961D ) + rom ( name "Nakayoshi Cooking Series 2 - Oishii Panya-san (Japan).gbc" size 1048576 crc b9fa3ce4 sha1 CF1B69A198C8D95F95BC99EB9FB1F3CAED4B961D flags verified ) ) game ( name "Nakayoshi Cooking Series 3 - Tanoshii Obentou (Japan)" description "Nakayoshi Cooking Series 3 - Tanoshii Obentou (Japan)" - rom ( name "Nakayoshi Cooking Series 3 - Tanoshii Obentou (Japan).gbc" size 1048576 crc DD7666CE md5 C40DCFF155901F2D6046FEC19017FE37 sha1 EB56E8A2A2D77141104CDBDD2AD6D0924AE10E88 ) + rom ( name "Nakayoshi Cooking Series 3 - Tanoshii Obentou (Japan).gbc" size 1048576 crc dd7666ce sha1 EB56E8A2A2D77141104CDBDD2AD6D0924AE10E88 ) ) game ( name "Nakayoshi Cooking Series 4 - Tanoshii Dessert (Japan)" description "Nakayoshi Cooking Series 4 - Tanoshii Dessert (Japan)" - rom ( name "Nakayoshi Cooking Series 4 - Tanoshii Dessert (Japan).gbc" size 1048576 crc 7E5C8542 md5 995CEBD28AAA5D94B8A230E9F22606B3 sha1 C86420ABA490DB1E0BFDDA7A4B5DB7F5777C509B flags verified ) + rom ( name "Nakayoshi Cooking Series 4 - Tanoshii Dessert (Japan).gbc" size 1048576 crc 7e5c8542 sha1 C86420ABA490DB1E0BFDDA7A4B5DB7F5777C509B flags verified ) ) game ( name "Nakayoshi Cooking Series 5 - Cake o Tsukurou (Japan)" description "Nakayoshi Cooking Series 5 - Cake o Tsukurou (Japan)" - rom ( name "Nakayoshi Cooking Series 5 - Cake o Tsukurou (Japan).gbc" size 4194304 crc C04539F8 md5 A03E3CD1A2C78BE11E3A52FE995CEC71 sha1 F1B845D5508DA37F3600437609D8CC8743799918 flags verified ) + rom ( name "Nakayoshi Cooking Series 5 - Cake o Tsukurou (Japan).gbc" size 4194304 crc c04539f8 sha1 F1B845D5508DA37F3600437609D8CC8743799918 flags verified ) ) game ( - name "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan)" - description "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan)" - rom ( name "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan).gbc" size 1048576 crc 98D0FCB0 md5 EB14F75BDA32D51B8F5751869743BF7A sha1 AAA59F2500AA82454CB74AEAFA342F8907C82AAF ) + name "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan) (GB Compatible)" + description "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan) (GB Compatible)" + rom ( name "Nakayoshi Pet Series 1 - Kawaii Hamster (Japan) (GB Compatible).gbc" size 1048576 crc 98d0fcb0 sha1 AAA59F2500AA82454CB74AEAFA342F8907C82AAF flags verified ) ) game ( - name "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan)" - description "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan)" - rom ( name "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan).gbc" size 1048576 crc 866095C2 md5 C888149FE40D8D760CE490A74CA98263 sha1 9D155A4DD73785C2CC725184954FC2D44B4D6F34 ) + name "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan) (GB Compatible)" + description "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan) (GB Compatible)" + rom ( name "Nakayoshi Pet Series 2 - Kawaii Usagi (Japan) (GB Compatible).gbc" size 1048576 crc 866095c2 sha1 9D155A4DD73785C2CC725184954FC2D44B4D6F34 flags verified ) ) game ( name "Nakayoshi Pet Series 3 - Kawaii Koinu (Japan)" description "Nakayoshi Pet Series 3 - Kawaii Koinu (Japan)" - rom ( name "Nakayoshi Pet Series 3 - Kawaii Koinu (Japan).gbc" size 1048576 crc FA4E9896 md5 EB8A8817E782CDDB4FE0474922A3405D sha1 2E6F44BDDFFFAD5DEFBCF45CF489151FFE43BCDB ) + rom ( name "Nakayoshi Pet Series 3 - Kawaii Koinu (Japan).gbc" size 1048576 crc fa4e9896 sha1 2E6F44BDDFFFAD5DEFBCF45CF489151FFE43BCDB ) ) game ( name "Nakayoshi Pet Series 4 - Kawaii Koneko (Japan)" description "Nakayoshi Pet Series 4 - Kawaii Koneko (Japan)" - rom ( name "Nakayoshi Pet Series 4 - Kawaii Koneko (Japan).gbc" size 1048576 crc 1A382367 md5 24590D82DA1C0D40B5D4F8E03E4CCA94 sha1 E5D5F1092E991A7538B9D24A12DE35DA21E23EDD ) + rom ( name "Nakayoshi Pet Series 4 - Kawaii Koneko (Japan).gbc" size 1048576 crc 1a382367 sha1 E5D5F1092E991A7538B9D24A12DE35DA21E23EDD ) ) game ( name "Nakayoshi Pet Series 5 - Kawaii Hamster 2 (Japan)" description "Nakayoshi Pet Series 5 - Kawaii Hamster 2 (Japan)" - rom ( name "Nakayoshi Pet Series 5 - Kawaii Hamster 2 (Japan).gbc" size 1048576 crc E5EC7BE5 md5 8D222A58636551F679177E37C83EB134 sha1 8465423089E87BC5A8F3485403C1B8A9B32915A1 ) + rom ( name "Nakayoshi Pet Series 5 - Kawaii Hamster 2 (Japan).gbc" size 1048576 crc e5ec7be5 sha1 8465423089E87BC5A8F3485403C1B8A9B32915A1 flags verified ) ) game ( name "Naminori Yarou! (Japan) (NP)" description "Naminori Yarou! (Japan) (NP)" - rom ( name "Naminori Yarou! (Japan) (NP).gbc" size 1048576 crc AC5E477D md5 9AE9D43FC7EC5570BADF7A19AE006AFD sha1 D305A76307BF05F4D31D395785784BA317A9689F ) + rom ( name "Naminori Yarou! (Japan) (NP).gbc" size 1048576 crc ac5e477d sha1 D305A76307BF05F4D31D395785784BA317A9689F ) ) game ( name "NASCAR 2000 (USA, Europe)" description "NASCAR 2000 (USA, Europe)" - rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54D90A4C md5 42E66DD2C0470D98487EF364E7DAF710 sha1 37D3FFB5AE9BCF4C1CAB7CECE0A19D6B0B45C3A2 flags verified ) + rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54d90a4c sha1 37D3FFB5AE9BCF4C1CAB7CECE0A19D6B0B45C3A2 flags verified ) ) game ( name "NASCAR Challenge (USA) (Rumble Version)" description "NASCAR Challenge (USA) (Rumble Version)" - rom ( name "NASCAR Challenge (USA) (Rumble Version).gbc" size 1048576 crc 39C6B868 md5 5779B8A387C10D39FAF8FD55632375C7 sha1 4282D0D76AF3D022F9E76082BE17522CE5699E54 ) + rom ( name "NASCAR Challenge (USA) (Rumble Version).gbc" size 1048576 crc 39c6b868 sha1 4282D0D76AF3D022F9E76082BE17522CE5699E54 ) ) game ( name "NASCAR Heat (USA)" description "NASCAR Heat (USA)" - rom ( name "NASCAR Heat (USA).gbc" size 1048576 crc FA83B37C md5 D8800AFECF6C190119F508D450F456DF sha1 059411B2C51FBC0C79D2B8911CBF313F14F15738 ) + rom ( name "NASCAR Heat (USA).gbc" size 1048576 crc fa83b37c sha1 059411B2C51FBC0C79D2B8911CBF313F14F15738 ) ) game ( name "NASCAR Racers (USA)" description "NASCAR Racers (USA)" - rom ( name "NASCAR Racers (USA).gbc" size 1048576 crc F39A5C4F md5 144AB8295663F4DC4BCD810C5CDAFE60 sha1 2E1B822AFA8537CD7B2BE8D608C4C000B5B59D46 ) + rom ( name "NASCAR Racers (USA).gbc" size 1048576 crc f39a5c4f sha1 2E1B822AFA8537CD7B2BE8D608C4C000B5B59D46 ) ) game ( name "Nations, The - Land of Legends (Europe) (En,De)" description "Nations, The - Land of Legends (Europe) (En,De)" - rom ( name "Nations, The - Land of Legends (Europe) (En,De).gbc" size 1048576 crc 8C195F49 md5 09419D9ABA3B31D36C09D08D2C1555F8 sha1 2FA6767632E37DC70D97061CBECE2CDBACE7AB1C ) + rom ( name "Nations, The - Land of Legends (Europe) (En,De).gbc" size 1048576 crc 8c195f49 sha1 2FA6767632E37DC70D97061CBECE2CDBACE7AB1C ) ) game ( - name "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced)" - description "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced)" - rom ( name "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced).gbc" size 1048576 crc 001F4754 md5 8CBB9B7401BE513C913A3A54EEE0DA54 sha1 8F8D1A33A71B22C9359DDC1AAE0BD9CAD4CC7456 ) + name "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced) (GB Compatible)" + description "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "NBA 3 on 3 featuring Kobe Bryant (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 001f4754 sha1 8F8D1A33A71B22C9359DDC1AAE0BD9CAD4CC7456 ) ) game ( name "NBA Hoopz (USA)" description "NBA Hoopz (USA)" - rom ( name "NBA Hoopz (USA).gbc" size 1048576 crc 5011A419 md5 E7719BB0D0619E2E5FB10DAB75F78654 sha1 C23D8276C3766D4265AC017BFADA04A664EE4E8F ) + rom ( name "NBA Hoopz (USA).gbc" size 1048576 crc 5011a419 sha1 C23D8276C3766D4265AC017BFADA04A664EE4E8F ) ) game ( - name "NBA In the Zone (USA) (Rev A) (SGB Enhanced)" - description "NBA In the Zone (USA) (Rev A) (SGB Enhanced)" - rom ( name "NBA In the Zone (USA) (Rev A) (SGB Enhanced).gbc" size 1048576 crc BE949F74 md5 B3A3B81D16BF534AFE80200995DFC683 sha1 F4BA926AD640D7B3E9D175FB58C90347DAFCBEF4 ) + name "NBA in the Zone (USA) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "NBA in the Zone (USA) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "NBA in the Zone (USA) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc be949f74 sha1 F4BA926AD640D7B3E9D175FB58C90347DAFCBEF4 ) ) game ( - name "NBA In the Zone 2000 (Europe)" - description "NBA In the Zone 2000 (Europe)" - rom ( name "NBA In the Zone 2000 (Europe).gbc" size 2097152 crc E6AF6D07 md5 E3C757E5F4261E962CACC8A999EC0F87 sha1 773A303C25BC907476BEE20064F2C1F154361D82 flags verified ) + name "NBA in the Zone 2000 (Europe)" + description "NBA in the Zone 2000 (Europe)" + rom ( name "NBA in the Zone 2000 (Europe).gbc" size 2097152 crc e6af6d07 sha1 773A303C25BC907476BEE20064F2C1F154361D82 flags verified ) ) game ( - name "NBA In the Zone 2000 (USA)" - description "NBA In the Zone 2000 (USA)" - rom ( name "NBA In the Zone 2000 (USA).gbc" size 2097152 crc FDB38C49 md5 8B3958E2D61921C787C9A40F4D3F13C0 sha1 57CD13938FB394752F1E070026DF716771561CC2 ) -) - -game ( - name "NBA Jam '99 (USA, Europe)" - description "NBA Jam '99 (USA, Europe)" - rom ( name "NBA Jam '99 (USA, Europe).gbc" size 1048576 crc 84BE0EED md5 1B543C5D0263730A3B862A02BB46F9A1 sha1 F34D0AC01F14C7C2671B6097C2EF891E70826D72 flags verified ) + name "NBA in the Zone 2000 (USA)" + description "NBA in the Zone 2000 (USA)" + rom ( name "NBA in the Zone 2000 (USA).gbc" size 2097152 crc fdb38c49 sha1 57CD13938FB394752F1E070026DF716771561CC2 ) ) game ( name "NBA Jam 2001 (USA, Europe)" description "NBA Jam 2001 (USA, Europe)" - rom ( name "NBA Jam 2001 (USA, Europe).gbc" size 1048576 crc 3AA75F1C md5 14BFCE85AF0AE19AFFBDCEF23A9D6BAF sha1 B1F7230DCCCAECB7AE9B2A0E786EFFAC2FC24497 flags verified ) + rom ( name "NBA Jam 2001 (USA, Europe).gbc" size 1048576 crc 3aa75f1c sha1 B1F7230DCCCAECB7AE9B2A0E786EFFAC2FC24497 flags verified ) ) game ( - name "NBA Pro '99 (Europe) (SGB Enhanced)" - description "NBA Pro '99 (Europe) (SGB Enhanced)" - rom ( name "NBA Pro '99 (Europe) (SGB Enhanced).gbc" size 1048576 crc 748564AE md5 C6CC317C220B2DE231CE6DB9AF40BD83 sha1 6EB56B61B8A77CE1060343F2C99F18C3271FA5F5 flags verified ) + name "NBA Jam 99 (USA, Europe) (GB Compatible)" + description "NBA Jam 99 (USA, Europe) (GB Compatible)" + rom ( name "NBA Jam 99 (USA, Europe) (GB Compatible).gbc" size 1048576 crc 84be0eed sha1 F34D0AC01F14C7C2671B6097C2EF891E70826D72 flags verified ) +) + +game ( + name "NBA Pro 99 (Europe) (SGB Enhanced) (GB Compatible)" + description "NBA Pro 99 (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "NBA Pro 99 (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 748564ae sha1 6EB56B61B8A77CE1060343F2C99F18C3271FA5F5 flags verified ) ) game ( name "NBA Show Time - NBA on NBC (USA)" description "NBA Show Time - NBA on NBC (USA)" - rom ( name "NBA Show Time - NBA on NBC (USA).gbc" size 1048576 crc 7AE23888 md5 E89653BD33D07E1A50A3FF78C2818A53 sha1 A72CD784883F2299B8B51D763FF4F8CF99A103BD ) + rom ( name "NBA Show Time - NBA on NBC (USA).gbc" size 1048576 crc 7ae23888 sha1 A72CD784883F2299B8B51D763FF4F8CF99A103BD ) ) game ( name "Net de Get - Minigame @ 100 (Japan)" description "Net de Get - Minigame @ 100 (Japan)" - rom ( name "Net de Get - Minigame @ 100 (Japan).gbc" size 1048576 crc 6E33D509 md5 77893D4574B1013A0699C4199C271B8A sha1 819EFDE3EBD0F52B080A8307979803914D029035 ) + rom ( name "Net de Get - Minigame @ 100 (Japan).gbc" size 1048576 crc 6e33d509 sha1 819EFDE3EBD0F52B080A8307979803914D029035 flags verified ) ) game ( name "Network Boukenki Bugsite - Alpha Version (Japan)" description "Network Boukenki Bugsite - Alpha Version (Japan)" - rom ( name "Network Boukenki Bugsite - Alpha Version (Japan).gbc" size 2097152 crc D65C8BA1 md5 7F9DBAFD6D16957E9687F89E33765F0B sha1 A5BE33B3CEFA2AF0865CADDB287814C8CCA19EDD flags verified ) + rom ( name "Network Boukenki Bugsite - Alpha Version (Japan).gbc" size 2097152 crc d65c8ba1 sha1 A5BE33B3CEFA2AF0865CADDB287814C8CCA19EDD flags verified ) ) game ( name "Network Boukenki Bugsite - Beta Version (Japan)" description "Network Boukenki Bugsite - Beta Version (Japan)" - rom ( name "Network Boukenki Bugsite - Beta Version (Japan).gbc" size 2097152 crc 56F52663 md5 3C6B37B6162D599E3554689500B23AF1 sha1 0C03E241E2931A0E2E54DE30678334999BEACB48 ) + rom ( name "Network Boukenki Bugsite - Beta Version (Japan).gbc" size 2097152 crc 56f52663 sha1 0C03E241E2931A0E2E54DE30678334999BEACB48 ) ) game ( name "New Addams Family Series, The (Europe) (En,Fr,De,Es,It,Pt)" description "New Addams Family Series, The (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "New Addams Family Series, The (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc FBB97680 md5 2D2A8314F789D490BF83ED3C44538FE3 sha1 87AF7B26281ADC9EFB8B5B5E31A13B8F6BE16042 ) + rom ( name "New Addams Family Series, The (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc fbb97680 sha1 87AF7B26281ADC9EFB8B5B5E31A13B8F6BE16042 ) ) game ( - name "New Adventures of Mary-Kate & Ashley, The (USA, Europe)" - description "New Adventures of Mary-Kate & Ashley, The (USA, Europe)" - rom ( name "New Adventures of Mary-Kate & Ashley, The (USA, Europe).gbc" size 1048576 crc DCA4474E md5 314CF4F2802B6972AA37C7964F5F0159 sha1 D42515A16143319AFAC0D980E9CB080103085F5C flags verified ) + name "New Adventures of Mary-Kate & Ashley, The (USA, Europe) (GB Compatible)" + description "New Adventures of Mary-Kate & Ashley, The (USA, Europe) (GB Compatible)" + rom ( name "New Adventures of Mary-Kate & Ashley, The (USA, Europe) (GB Compatible).gbc" size 1048576 crc dca4474e sha1 D42515A16143319AFAC0D980E9CB080103085F5C flags verified ) ) game ( - name "New Batman Adventures, The - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl)" - description "New Batman Adventures, The - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "New Batman Adventures, The - Chaos in Gotham (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc E025067B md5 4B64F2A44700D5BF9DC0A25A64A9EBB0 sha1 DBC6C729DDE21ABF324E2A055D819F088E696C0C flags verified ) + name "NFL Blitz (USA, Europe) (GB Compatible)" + description "NFL Blitz (USA, Europe) (GB Compatible)" + rom ( name "NFL Blitz (USA, Europe) (GB Compatible).gbc" size 524288 crc d731ded7 sha1 14649B51E40AEEA24CB4D9CBC41B847CADF68067 ) ) game ( - name "New Batman Adventures, The - Chaos in Gotham (USA)" - description "New Batman Adventures, The - Chaos in Gotham (USA)" - rom ( name "New Batman Adventures, The - Chaos in Gotham (USA).gbc" size 1048576 crc B241A4F3 md5 3D818762AA83330CE4426F8005CC374B sha1 DE2D6A53316011B60FBC9A946F510EFFE42EDE5E ) -) - -game ( - name "NFL Blitz (USA)" - description "NFL Blitz (USA)" - rom ( name "NFL Blitz (USA).gbc" size 524288 crc D731DED7 md5 2022AE2CB1BBD83EDEFA3A5BDF2A2B72 sha1 14649B51E40AEEA24CB4D9CBC41B847CADF68067 ) -) - -game ( - name "NFL Blitz (USA, Europe) (Rev A)" - description "NFL Blitz (USA, Europe) (Rev A)" - rom ( name "NFL Blitz (USA, Europe) (Rev A).gbc" size 524288 crc 107D734B md5 331CD9F6AFA7EAB03157A35897AF846E sha1 66B69CBA0705F0670759F01CFD586A50C47C7C89 flags verified ) + name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible)" + description "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible)" + rom ( name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible).gbc" size 524288 crc 107d734b sha1 66B69CBA0705F0670759F01CFD586A50C47C7C89 flags verified ) ) game ( name "NFL Blitz 2000 (USA)" description "NFL Blitz 2000 (USA)" - rom ( name "NFL Blitz 2000 (USA).gbc" size 1048576 crc 090C7DAC md5 5A192FFF3DB17B8FB1ED19867D4BE13A sha1 26E60D551B71AC65FEEF7882062A61C0BAD03664 ) + rom ( name "NFL Blitz 2000 (USA).gbc" size 1048576 crc 090c7dac sha1 26E60D551B71AC65FEEF7882062A61C0BAD03664 ) ) game ( name "NFL Blitz 2001 (USA)" description "NFL Blitz 2001 (USA)" - rom ( name "NFL Blitz 2001 (USA).gbc" size 1048576 crc 61C653AE md5 4F4AD5F3389DA1FC85AF38CF770D4556 sha1 51DA92005E63C427F5EDF030C8A35B33B5E07CFC ) + rom ( name "NFL Blitz 2001 (USA).gbc" size 1048576 crc 61c653ae sha1 51DA92005E63C427F5EDF030C8A35B33B5E07CFC ) ) game ( - name "NHL 2000 (USA, Europe) (SGB Enhanced)" - description "NHL 2000 (USA, Europe) (SGB Enhanced)" - rom ( name "NHL 2000 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc BB625129 md5 2565FDADFB12B92B60B535CEC6492041 sha1 8F7CB463A1438C70310F319E602DF4B13530D96F flags verified ) + name "NHL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "NHL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "NHL 2000 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bb625129 sha1 8F7CB463A1438C70310F319E602DF4B13530D96F flags verified ) ) game ( name "NHL Blades of Steel (USA)" description "NHL Blades of Steel (USA)" - rom ( name "NHL Blades of Steel (USA).gbc" size 1048576 crc A890ADB2 md5 39F214540D2042865211E07C0536CC14 sha1 9A93F90645B929FF0344FD256815F02B3BF33A99 ) + rom ( name "NHL Blades of Steel (USA).gbc" size 1048576 crc a890adb2 sha1 9A93F90645B929FF0344FD256815F02B3BF33A99 ) ) game ( name "NHL Blades of Steel 2000 (USA)" description "NHL Blades of Steel 2000 (USA)" - rom ( name "NHL Blades of Steel 2000 (USA).gbc" size 1048576 crc 8BC5B62A md5 51518F30EB5E6190671017FC9807016D sha1 271782DE2566FB0C36C96D7DEF5F439009371870 ) + rom ( name "NHL Blades of Steel 2000 (USA).gbc" size 1048576 crc 8bc5b62a sha1 271782DE2566FB0C36C96D7DEF5F439009371870 ) ) game ( name "Nicktoons Racing (USA)" description "Nicktoons Racing (USA)" - rom ( name "Nicktoons Racing (USA).gbc" size 1048576 crc A3F079D4 md5 1D0044523075AB0308C598286F804402 sha1 8B023F596D9B37AE442578C02C6BA859BC81C5C6 ) + rom ( name "Nicktoons Racing (USA).gbc" size 1048576 crc a3f079d4 sha1 8B023F596D9B37AE442578C02C6BA859BC81C5C6 ) ) game ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" description "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" - rom ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan).gbc" size 1048576 crc 4631D8BF md5 2CA1D1DD8B0DCCFB129D31987ED81E5F sha1 916BB8C06539CFCF6B4499A2046EA89E17A8874C ) + rom ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan).gbc" size 1048576 crc 4631d8bf sha1 916BB8C06539CFCF6B4499A2046EA89E17A8874C flags verified ) ) game ( name "Nisemon Puzzle da Mon! - Feromon Kyuushutsu Daisakusen! (Japan)" description "Nisemon Puzzle da Mon! - Feromon Kyuushutsu Daisakusen! (Japan)" - rom ( name "Nisemon Puzzle da Mon! - Feromon Kyuushutsu Daisakusen! (Japan).gbc" size 2097152 crc 2F7D62F3 md5 5C7ECB62A755CE577E7D8A943838D45F sha1 8D60E4AF5504FE68277E1DA162E6352D8438900E ) + rom ( name "Nisemon Puzzle da Mon! - Feromon Kyuushutsu Daisakusen! (Japan).gbc" size 2097152 crc 2f7d62f3 sha1 8D60E4AF5504FE68277E1DA162E6352D8438900E flags verified ) ) game ( name "No Fear - Downhill Mountain Biking (Europe)" description "No Fear - Downhill Mountain Biking (Europe)" - rom ( name "No Fear - Downhill Mountain Biking (Europe).gbc" size 1048576 crc 0F69F574 md5 3634A0799DF59541607D3240C4A3295B sha1 D04C3578F3ABED229C9BC44F55FC3A2154E15429 ) + rom ( name "No Fear - Downhill Mountain Biking (Europe).gbc" size 1048576 crc 0f69f574 sha1 D04C3578F3ABED229C9BC44F55FC3A2154E15429 ) ) game ( - name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced)" - description "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced)" - rom ( name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced).gbc" size 1048576 crc 233862D0 md5 F8A6836A0F3448FAE3F2E79BA1D32769 sha1 A61E35306405E41C03B98B162EE14442E77C0DA1 flags verified ) + name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Nobunaga no Yabou - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 233862d0 sha1 A61E35306405E41C03B98B162EE14442E77C0DA1 flags verified ) ) game ( name "Noddy and the Birthday Party (Europe) (En,Fr,De,Es)" description "Noddy and the Birthday Party (Europe) (En,Fr,De,Es)" - rom ( name "Noddy and the Birthday Party (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 845B4E44 md5 A67CB573673F041098F23F868A153019 sha1 9DB01BAF9AEC2DD3DF8DDC583694B1B7AA85AC2C flags verified ) + rom ( name "Noddy and the Birthday Party (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 845b4e44 sha1 9DB01BAF9AEC2DD3DF8DDC583694B1B7AA85AC2C flags verified ) ) game ( name "NSYNC - Get to the Show (USA)" description "NSYNC - Get to the Show (USA)" - rom ( name "NSYNC - Get to the Show (USA).gbc" size 1048576 crc F770878B md5 9017EBE4C004FD9597557E28D711316A sha1 23B031D03A139C4D963099070B0B290F5F806A6D ) + rom ( name "NSYNC - Get to the Show (USA).gbc" size 1048576 crc f770878b sha1 23B031D03A139C4D963099070B0B290F5F806A6D ) ) game ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" description "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" - rom ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version).gbc" size 2097152 crc AC52F6EF md5 5B40590960C204EFD6303B2E89A0CC10 sha1 2C72CFAA3CB1080ED4393E961BF2990A7DF79CBE ) + rom ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version).gbc" size 2097152 crc ac52f6ef sha1 2C72CFAA3CB1080ED4393E961BF2990A7DF79CBE ) +) + +game ( + name "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" + description "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt)" + rom ( name "NYR - New York Race (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 62f560d8 sha1 001DECC8331B4BEB94A01A1B6EF08E1BF2920ECE ) ) game ( name "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca)" description "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca)" - rom ( name "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc 3485761A md5 7784FF1A16B15E8E55A6B43159CC1774 sha1 724AA0F905D7A6E7B9B2B01A477F424AC95EADF9 ) + rom ( name "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc 3485761a sha1 724AA0F905D7A6E7B9B2B01A477F424AC95EADF9 ) ) game ( - name "Oddworld Adventures II (USA) (En,Fr,De,Es,It)" - description "Oddworld Adventures II (USA) (En,Fr,De,Es,It)" - rom ( name "Oddworld Adventures II (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 5C260D5A md5 627C3542307661990802806EBD0ACD90 sha1 A35CCDF0789CE84DF3C12CFE7C4B9B98AF08CA9A ) + name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" + description "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 5c260d5a sha1 A35CCDF0789CE84DF3C12CFE7C4B9B98AF08CA9A ) ) game ( - name "Oddworld Adventures II (Europe) (En,Fr,De,Es,It)" - description "Oddworld Adventures II (Europe) (En,Fr,De,Es,It)" - serial "DMG-AOWP-EUU" - rom ( name "Oddworld Adventures II (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 4B83B14F md5 68715E0A2805E3FC019FEC35A9CFF0D4 sha1 C9D4D1DD1C33A9FA9B54E9F2A7A5F6DD90069B91 flags verified ) + name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Oddworld Adventures 2 (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 4b83b14f sha1 C9D4D1DD1C33A9FA9B54E9F2A7A5F6DD90069B91 flags verified ) ) game ( name "Ohasuta Dance Dance Revolution GB (Japan)" description "Ohasuta Dance Dance Revolution GB (Japan)" - rom ( name "Ohasuta Dance Dance Revolution GB (Japan).gbc" size 2097152 crc E338C118 md5 521F0E017A4266355F3F4DC015F1DD46 sha1 BEC623A9F0D4CA75905BB23595B17D9C33FF0775 flags verified ) + rom ( name "Ohasuta Dance Dance Revolution GB (Japan).gbc" size 2097152 crc e338c118 sha1 BEC623A9F0D4CA75905BB23595B17D9C33FF0775 flags verified ) ) game ( - name "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced)" - description "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced)" - rom ( name "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced).gbc" size 262144 crc 840EF32F md5 C50667BAEE3E2ABDB1588394CC5D4534 sha1 373166BC65DD9B6C5734ADD30A8D278986FC9C98 flags verified ) + name "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced) (GB Compatible)" + description "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Ohasuta Yama-chan & Raymond (Japan) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 840ef32f sha1 373166BC65DD9B6C5734ADD30A8D278986FC9C98 flags verified ) ) game ( name "Oide Rascal (Japan)" description "Oide Rascal (Japan)" - rom ( name "Oide Rascal (Japan).gbc" size 1048576 crc 9E0799F4 md5 8F43BC56783F98E97FE7F51603C1A025 sha1 9B73A9DC4424029261579193FDBD5A30CA84052B ) + rom ( name "Oide Rascal (Japan).gbc" size 1048576 crc 9e0799f4 sha1 9B73A9DC4424029261579193FDBD5A30CA84052B flags verified ) ) game ( - name "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan)" - description "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan)" - rom ( name "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan).gbc" size 1048576 crc D86507C9 md5 A4DF533C6B9B3423F71385E68BD5C421 sha1 F17175F7744F97AD4F9943C5DADD4776AD85E5CB flags verified ) + name "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan) (GB Compatible)" + description "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan) (GB Compatible)" + rom ( name "Ojarumaru - Mangan Jinja no Ennichi de Ojaru! (Japan) (GB Compatible).gbc" size 1048576 crc d86507c9 sha1 F17175F7744F97AD4F9943C5DADD4776AD85E5CB flags verified ) ) game ( - name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan)" - description "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan)" - rom ( name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan).gbc" size 2097152 crc ED7461D2 md5 5C3A09F365CFA467A11F14075B0D5517 sha1 66D87A06D4D951E7695DF73F53793A462509E4D0 flags verified ) + name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan) (GB Compatible)" + description "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan) (GB Compatible)" + rom ( name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan) (GB Compatible).gbc" size 2097152 crc ed7461d2 sha1 66D87A06D4D951E7695DF73F53793A462509E4D0 flags verified ) ) game ( name "Original Moorhuhn Jagd, Die (Germany)" description "Original Moorhuhn Jagd, Die (Germany)" - rom ( name "Original Moorhuhn Jagd, Die (Germany).gbc" size 1048576 crc 714EC204 md5 2382EDC04A323A227EA793E33C749C79 sha1 D4F3FE5BDEED4BBF40D3F1EB6EAB7A69676C6138 flags verified ) + rom ( name "Original Moorhuhn Jagd, Die (Germany).gbc" size 1048576 crc 714ec204 sha1 D4F3FE5BDEED4BBF40D3F1EB6EAB7A69676C6138 flags verified ) ) game ( - name "Othello Millennium (Japan)" - description "Othello Millennium (Japan)" - rom ( name "Othello Millennium (Japan).gbc" size 1048576 crc C7800576 md5 03E6A11B8040B4D56B3C1402C92BBF6D sha1 1546E2B676931C87B4A48E77C761F49A8E39B9E7 ) + name "Othello Millennium (Japan) (GB Compatible)" + description "Othello Millennium (Japan) (GB Compatible)" + rom ( name "Othello Millennium (Japan) (GB Compatible).gbc" size 1048576 crc c7800576 sha1 1546E2B676931C87B4A48E77C761F49A8E39B9E7 flags verified ) ) game ( - name "Other Life - Azure Dreams GB (Japan) (SGB Enhanced)" - description "Other Life - Azure Dreams GB (Japan) (SGB Enhanced)" - rom ( name "Other Life - Azure Dreams GB (Japan) (SGB Enhanced).gbc" size 1048576 crc C6F1ABD4 md5 BBF9B39219ECEC88BEA41B98C8352634 sha1 9E473DF09E962A9ACCC3F6446140B0333F6A088E flags verified ) + name "Other Life - Azure Dreams GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Other Life - Azure Dreams GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Other Life - Azure Dreams GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c6f1abd4 sha1 9E473DF09E962A9ACCC3F6446140B0333F6A088E flags verified ) ) game ( name "Ottifanten - Kommando Stoertebeker (Germany)" description "Ottifanten - Kommando Stoertebeker (Germany)" - rom ( name "Ottifanten - Kommando Stoertebeker (Germany).gbc" size 1048576 crc 3EAC3D1C md5 4713C80F75168F12D7582E63ABB6EDEF sha1 79C774AB9999CEC95087EBE0982B6ABBA8F4AB91 ) + rom ( name "Ottifanten - Kommando Stoertebeker (Germany).gbc" size 1048576 crc 3eac3d1c sha1 79C774AB9999CEC95087EBE0982B6ABBA8F4AB91 ) ) game ( - name "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced)" - description "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced)" - rom ( name "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced).gbc" size 1048576 crc D47C0DCF md5 660FD044F1E744B8A208FC91481C030D sha1 493E37DAC6D8B037E44E64F9F31DBA7F08A89E08 ) + name "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Ou Dorobou Jing - Angel Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d47c0dcf sha1 493E37DAC6D8B037E44E64F9F31DBA7F08A89E08 ) ) game ( - name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced)" - description "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced)" - rom ( name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced).gbc" size 1048576 crc 2A39A874 md5 D106D2513AA3BCF6BA34B7F8CBBFFE28 sha1 71797AA125B88614182CE3D0F8252D6ED8CFA08E ) + name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2a39a874 sha1 71797AA125B88614182CE3D0F8252D6ED8CFA08E ) ) game ( - name "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced)" - description "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced)" - rom ( name "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced).gbc" size 1048576 crc 3F635A4F md5 97A3474440373AF59774D611D5C52C27 sha1 21644C1EF67BDD6038686D8522E957E3DE803237 ) + name "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced) (GB Compatible)" + description "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Owarai Yoiko no Geemumichi - Oyaji Sagashite 3 Choume (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 3f635a4f sha1 21644C1EF67BDD6038686D8522E957E3DE803237 ) ) game ( - name "Pac-Man - Special Color Edition (USA) (SGB Enhanced)" - description "Pac-Man - Special Color Edition (USA) (SGB Enhanced)" - rom ( name "Pac-Man - Special Color Edition (USA) (SGB Enhanced).gbc" size 262144 crc 3485EF86 md5 B81DDB7D86302384EFE1675F75CC35F6 sha1 A0A6F55C15DCA60350B3A74B1973CC13FF328730 ) + name "Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" + description "Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 3485ef86 sha1 A0A6F55C15DCA60350B3A74B1973CC13FF328730 ) ) game ( - name "Pac-Man - Special Colour Edition (Europe)" - description "Pac-Man - Special Colour Edition (Europe)" - rom ( name "Pac-Man - Special Colour Edition (Europe).gbc" size 1048576 crc F565647F md5 8FD828532500C3D3E893FE86B725ADE3 sha1 D80A9D8BA18D5CECFF332BAB48AFDD00BF30DF25 ) + name "Pac-Man - Special Colour Edition (Europe) (GB Compatible)" + description "Pac-Man - Special Colour Edition (Europe) (GB Compatible)" + rom ( name "Pac-Man - Special Colour Edition (Europe) (GB Compatible).gbc" size 1048576 crc f565647f sha1 D80A9D8BA18D5CECFF332BAB48AFDD00BF30DF25 ) ) game ( - name "Pachinko CR Mouretsu Genshijin T (Japan)" - description "Pachinko CR Mouretsu Genshijin T (Japan)" - rom ( name "Pachinko CR Mouretsu Genshijin T (Japan).gbc" size 1048576 crc F75E269E md5 20291BD45093D28B32358527EB9611C5 sha1 3C473F1E5E849D42E5412DC968D0514F1D85855F ) + name "Pachinko CR Mouretsu Genshijin T (Japan) (GB Compatible)" + description "Pachinko CR Mouretsu Genshijin T (Japan) (GB Compatible)" + rom ( name "Pachinko CR Mouretsu Genshijin T (Japan) (GB Compatible).gbc" size 1048576 crc f75e269e sha1 3C473F1E5E849D42E5412DC968D0514F1D85855F ) ) game ( - name "Pachinko Hisshou Guide - Data no Ousama (Japan)" - description "Pachinko Hisshou Guide - Data no Ousama (Japan)" - rom ( name "Pachinko Hisshou Guide - Data no Ousama (Japan).gbc" size 1048576 crc 1A631BAB md5 B12265F9C7139A51D55D354AA5ADE32A sha1 9BA368431D307FF4C4455F9BEFEE2AC9B1EFB64A ) + name "Pachinko Hisshou Guide - Data no Ousama (Japan) (GB Compatible)" + description "Pachinko Hisshou Guide - Data no Ousama (Japan) (GB Compatible)" + rom ( name "Pachinko Hisshou Guide - Data no Ousama (Japan) (GB Compatible).gbc" size 1048576 crc 1a631bab sha1 9BA368431D307FF4C4455F9BEFEE2AC9B1EFB64A ) ) game ( - name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced)" - description "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced)" - rom ( name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced).gbc" size 1048576 crc 1E443D1B md5 0AA1877A6A6DD4C8230FABADA9EA9249 sha1 969D5352C15E3E5DAA891EDCDA91BD48A8380308 ) + name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1e443d1b sha1 969D5352C15E3E5DAA891EDCDA91BD48A8380308 ) ) game ( name "Painter (Europe) (Unl)" description "Painter (Europe) (Unl)" - rom ( name "Painter (Europe) (Unl).gbc" size 262144 crc F4801F21 md5 D4255175D7CBCA6080C31EC839893D05 sha1 78DB482D1D12B4556B6A5B995CE37A2435236A06 flags verified ) + rom ( name "Painter (Europe) (Unl).gbc" size 262144 crc f4801f21 sha1 78DB482D1D12B4556B6A5B995CE37A2435236A06 flags verified ) ) game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" - rom ( name "Paperboy (USA, Europe).gbc" size 1048576 crc C0A98305 md5 EE133AB2F9EA5B18E9A19CE9B599A883 sha1 B96ACF81C82286148C3A2154715AA043E2612A36 flags verified ) + rom ( name "Paperboy (USA, Europe).gbc" size 1048576 crc c0a98305 sha1 B96ACF81C82286148C3A2154715AA043E2612A36 flags verified ) ) game ( name "Papyrus (Europe) (En,Fr,De,Es,It,Nl)" description "Papyrus (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Papyrus (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc DA3A3278 md5 59F3F8585CFC12876DB9A27018D41F78 sha1 422C5F48F307820EE7C610E761A30A8CAB85AED9 ) + rom ( name "Papyrus (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc da3a3278 sha1 422C5F48F307820EE7C610E761A30A8CAB85AED9 ) +) + +game ( + name "PaZeek (USA) (Proto)" + description "PaZeek (USA) (Proto)" + rom ( name "PaZeek (USA) (Proto).gbc" size 262144 crc 952b0028 sha1 590DC27682DACB8A044B68D76AD3A0548973C390 flags verified ) ) game ( name "Perfect Choro Q (Japan)" description "Perfect Choro Q (Japan)" - rom ( name "Perfect Choro Q (Japan).gbc" size 2097152 crc AFA1AAC3 md5 7DAE13AF3D7373116E7C7558BC402BEF sha1 3C7024086F9BEDC223C7D482C309336C250ED039 ) + rom ( name "Perfect Choro Q (Japan).gbc" size 2097152 crc afa1aac3 sha1 3C7024086F9BEDC223C7D482C309336C250ED039 flags verified ) ) game ( name "Perfect Dark (USA, Europe) (En,Fr,De,Es,It) (Rumble Version)" description "Perfect Dark (USA, Europe) (En,Fr,De,Es,It) (Rumble Version)" - rom ( name "Perfect Dark (USA, Europe) (En,Fr,De,Es,It) (Rumble Version).gbc" size 4194304 crc 0601BEF6 md5 840E1DDB2696ECAE487FD264A3C34581 sha1 2D1E47BF3FB4A28FFB82A4FD2AE779EC99AAA87D flags verified ) + rom ( name "Perfect Dark (USA, Europe) (En,Fr,De,Es,It) (Rumble Version).gbc" size 4194304 crc 0601bef6 sha1 2D1E47BF3FB4A28FFB82A4FD2AE779EC99AAA87D flags verified ) ) game ( - name "Phantom Zona (Japan) (SGB Enhanced)" - description "Phantom Zona (Japan) (SGB Enhanced)" - rom ( name "Phantom Zona (Japan) (SGB Enhanced).gbc" size 2097152 crc 3E43F25F md5 A20D6884A7D6BC5610EF4078A72CE460 sha1 BF2162F970A9DBB658AFBDD7354155768DAA96B1 flags verified ) + name "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" + description "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3e43f25f sha1 BF2162F970A9DBB658AFBDD7354155768DAA96B1 flags verified ) ) game ( name "Pia Carrot e Youkoso!! 2.2 (Japan)" description "Pia Carrot e Youkoso!! 2.2 (Japan)" - rom ( name "Pia Carrot e Youkoso!! 2.2 (Japan).gbc" size 4194304 crc 2267360B md5 51825ECAA3162A1C871FE67E4A83F0B9 sha1 E18CD437C52CA37C6C13BA71E0BD50F1B517A8D6 ) + rom ( name "Pia Carrot e Youkoso!! 2.2 (Japan).gbc" size 4194304 crc 2267360b sha1 E18CD437C52CA37C6C13BA71E0BD50F1B517A8D6 ) ) game ( - name "Pitfall - Beyond the Jungle (USA, Europe)" - description "Pitfall - Beyond the Jungle (USA, Europe)" - rom ( name "Pitfall - Beyond the Jungle (USA, Europe).gbc" size 1048576 crc F911BB5D md5 D6DCE5C8DC02CE77D58F8852653E42E4 sha1 249E4C0370961EAFF6BDCFF20A0BD8E42ABA2393 flags verified ) + name "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" + description "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" + rom ( name "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible).gbc" size 1048576 crc f911bb5d sha1 249E4C0370961EAFF6BDCFF20A0BD8E42ABA2393 flags verified ) ) game ( - name "Pitfall GB (Japan)" - description "Pitfall GB (Japan)" - rom ( name "Pitfall GB (Japan).gbc" size 1048576 crc FA09CEBE md5 AE9B4ED5CD8C80029A3C01096963EE19 sha1 5B8ED6B038084890CE198133A7AE8CA93257D0F8 ) + name "Pitfall GB (Japan) (GB Compatible)" + description "Pitfall GB (Japan) (GB Compatible)" + rom ( name "Pitfall GB (Japan) (GB Compatible).gbc" size 1048576 crc fa09cebe sha1 5B8ED6B038084890CE198133A7AE8CA93257D0F8 ) ) game ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl)" description "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc A92DCB79 md5 5F1DC921DF67DE60D3F6EF1A44870142 sha1 FA8CA9A374FA3151AE912C7210B116D9FE0FCE2B ) + rom ( name "Planet of the Apes (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc a92dcb79 sha1 FA8CA9A374FA3151AE912C7210B116D9FE0FCE2B ) ) game ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl)" description "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 91D7CCCA md5 A55B8D588BBAA4EBCB4D53DBB534329F sha1 84B616C937B9DCC7CDCB05F583A4D60467EDE385 ) + rom ( name "Planet of the Apes (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 91d7ccca sha1 84B616C937B9DCC7CDCB05F583A4D60467EDE385 flags verified ) ) game ( name "Player Manager 2001 (Europe) (En,Fr)" description "Player Manager 2001 (Europe) (En,Fr)" - rom ( name "Player Manager 2001 (Europe) (En,Fr).gbc" size 1048576 crc 375C35E0 md5 C954D72F5A9131667AAA06AE185638B4 sha1 6E21A85257361BE76914F418409124C5BC315429 ) + rom ( name "Player Manager 2001 (Europe) (En,Fr).gbc" size 1048576 crc 375c35e0 sha1 6E21A85257361BE76914F418409124C5BC315429 ) ) game ( name "Pocket Billiards - Funk the 9 Ball (Japan)" description "Pocket Billiards - Funk the 9 Ball (Japan)" - rom ( name "Pocket Billiards - Funk the 9 Ball (Japan).gbc" size 1048576 crc 3B46E7C9 md5 5B5F4BBEC087ABC00CE1F834A86BDAE3 sha1 24673A0D0C274D8EDA3B3952D63772C65778B8C3 flags verified ) + rom ( name "Pocket Billiards - Funk the 9 Ball (Japan).gbc" size 1048576 crc 3b46e7c9 sha1 24673A0D0C274D8EDA3B3952D63772C65778B8C3 flags verified ) ) game ( - name "Pocket Bomberman (USA, Europe) (SGB Enhanced)" - description "Pocket Bomberman (USA, Europe) (SGB Enhanced)" - rom ( name "Pocket Bomberman (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc FA2A66E9 md5 2F6B6379F8C7CE5D66A198162F345EAA sha1 B0AE803600E06CD1CC9A0D801F2511C9ECC50584 flags verified ) + name "Pocket Bomberman (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Pocket Bomberman (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Bomberman (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc fa2a66e9 sha1 B0AE803600E06CD1CC9A0D801F2511C9ECC50584 flags verified ) ) game ( - name "Pocket Bowling (Japan)" - description "Pocket Bowling (Japan)" - rom ( name "Pocket Bowling (Japan).gbc" size 524288 crc 26589B79 md5 7B29BF304BE1F747C83CF516239B9C61 sha1 8A29E82BE027A82030C1DC7F7CF9BC9ECF010E64 ) + name "Pocket Bowling (Japan) (GB Compatible)" + description "Pocket Bowling (Japan) (GB Compatible)" + rom ( name "Pocket Bowling (Japan) (GB Compatible).gbc" size 524288 crc 26589b79 sha1 8A29E82BE027A82030C1DC7F7CF9BC9ECF010E64 ) ) game ( - name "Pocket Bowling (USA)" - description "Pocket Bowling (USA)" - rom ( name "Pocket Bowling (USA).gbc" size 524288 crc 3ED30908 md5 8D9C413F30885BE0BB0FE08A1817C842 sha1 5435CCEC39EF27D9CAB626425671BD81E7FA4D55 ) + name "Pocket Bowling (USA) (GB Compatible)" + description "Pocket Bowling (USA) (GB Compatible)" + rom ( name "Pocket Bowling (USA) (GB Compatible).gbc" size 524288 crc 3ed30908 sha1 5435CCEC39EF27D9CAB626425671BD81E7FA4D55 ) ) game ( name "Pocket Color Billiards (Japan)" description "Pocket Color Billiards (Japan)" - rom ( name "Pocket Color Billiards (Japan).gbc" size 1048576 crc 911007E1 md5 6F39124A6DFC3AAA28813286054A5FCB sha1 7D2F568887449D7D34E82022007568C035949539 ) + rom ( name "Pocket Color Billiards (Japan).gbc" size 1048576 crc 911007e1 sha1 7D2F568887449D7D34E82022007568C035949539 flags verified ) ) game ( - name "Pocket Color Block (Japan) (SGB Enhanced)" - description "Pocket Color Block (Japan) (SGB Enhanced)" - rom ( name "Pocket Color Block (Japan) (SGB Enhanced).gbc" size 131072 crc 389CF56F md5 8F293537E992CB718F0D055C6D08F882 sha1 84D243C64F98731965CA78B75AD48F8787D3C907 ) + name "Pocket Color Block (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket Color Block (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Color Block (Japan) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc 389cf56f sha1 84D243C64F98731965CA78B75AD48F8787D3C907 ) ) game ( - name "Pocket Color Mahjong (Japan)" - description "Pocket Color Mahjong (Japan)" - rom ( name "Pocket Color Mahjong (Japan).gbc" size 1048576 crc 08DC0AF4 md5 5416DFAE15DB78CBBB6525051451C284 sha1 23067C8B37F283FACC5C3A8E96C804DDD53AEAF4 ) + name "Pocket Color Mahjong (Japan) (GB Compatible)" + description "Pocket Color Mahjong (Japan) (GB Compatible)" + rom ( name "Pocket Color Mahjong (Japan) (GB Compatible).gbc" size 1048576 crc 08dc0af4 sha1 23067C8B37F283FACC5C3A8E96C804DDD53AEAF4 ) ) game ( - name "Pocket Color Trump (Japan)" - description "Pocket Color Trump (Japan)" - rom ( name "Pocket Color Trump (Japan).gbc" size 1048576 crc C73EB10E md5 315DCDF71E7AF8287FF71C9A79AA8280 sha1 DDC9846964A19E8702F226FFD9060B94A60011C3 ) + name "Pocket Color Trump (Japan) (GB Compatible)" + description "Pocket Color Trump (Japan) (GB Compatible)" + rom ( name "Pocket Color Trump (Japan) (GB Compatible).gbc" size 1048576 crc c73eb10e sha1 DDC9846964A19E8702F226FFD9060B94A60011C3 ) ) game ( name "Pocket Cooking (Japan)" description "Pocket Cooking (Japan)" - rom ( name "Pocket Cooking (Japan).gbc" size 4194304 crc F5AB554D md5 ED002E5B29F7082A6A37191BF5AF1D08 sha1 60A13FC904100655A52DFB61D9ABE77CC126E58C flags verified ) + rom ( name "Pocket Cooking (Japan).gbc" size 4194304 crc f5ab554d sha1 60A13FC904100655A52DFB61D9ABE77CC126E58C flags verified ) ) game ( - name "Pocket Densha 2 (Japan) (SGB Enhanced)" - description "Pocket Densha 2 (Japan) (SGB Enhanced)" - rom ( name "Pocket Densha 2 (Japan) (SGB Enhanced).gbc" size 1048576 crc 4D26E880 md5 EC64D367CDC02CFB9019D058AB5A0FDB sha1 859331F57A964197F271ACAFA7E8DC586E598CF5 ) + name "Pocket Densha 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket Densha 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Densha 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4d26e880 sha1 859331F57A964197F271ACAFA7E8DC586E598CF5 flags verified ) ) game ( - name "Pocket Family GB2 (Japan)" - description "Pocket Family GB2 (Japan)" - rom ( name "Pocket Family GB2 (Japan).gbc" size 2097152 crc 2A273244 md5 C9799917BF3C583453B3DA3CD5547398 sha1 FC88FCF5AAB548936CD6617C4E2EA07B77EE43C8 flags verified ) + name "Pocket Family GB 2 (Japan)" + description "Pocket Family GB 2 (Japan)" + rom ( name "Pocket Family GB 2 (Japan).gbc" size 2097152 crc 2a273244 sha1 FC88FCF5AAB548936CD6617C4E2EA07B77EE43C8 flags verified ) ) game ( - name "Pocket GI Stable (Japan) (SGB Enhanced)" - description "Pocket GI Stable (Japan) (SGB Enhanced)" - rom ( name "Pocket GI Stable (Japan) (SGB Enhanced).gbc" size 2097152 crc C424874E md5 D864D40E51FEA6C3ED7E4E340F4613FD sha1 F818E6284D198F4B394F79CB8511C9B906D69F03 ) + name "Pocket GI Stable (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket GI Stable (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket GI Stable (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc c424874e sha1 F818E6284D198F4B394F79CB8511C9B906D69F03 ) ) game ( name "Pocket GT (Japan)" description "Pocket GT (Japan)" - rom ( name "Pocket GT (Japan).gbc" size 1048576 crc 2AC77C5A md5 0EE28078D6270DF663647E8A3E3FEAF6 sha1 035E2284654751491FAFB9D752740EEFC2AA80CD flags verified ) + rom ( name "Pocket GT (Japan).gbc" size 1048576 crc 2ac77c5a sha1 035E2284654751491FAFB9D752740EEFC2AA80CD flags verified ) ) game ( name "Pocket Hanafuda (Japan)" description "Pocket Hanafuda (Japan)" - rom ( name "Pocket Hanafuda (Japan).gbc" size 262144 crc AF0C51B8 md5 3ABB1CEB5E276926147B127002AA5B92 sha1 339E97A223DA844EFE889E18EACED20756B0BA28 ) + rom ( name "Pocket Hanafuda (Japan).gbc" size 262144 crc af0c51b8 sha1 339E97A223DA844EFE889E18EACED20756B0BA28 ) ) game ( - name "Pocket King (Japan) (SGB Enhanced)" - description "Pocket King (Japan) (SGB Enhanced)" - rom ( name "Pocket King (Japan) (SGB Enhanced).gbc" size 2097152 crc DEE71D44 md5 D9FFED48998C978D6BAD4A23AE2567B9 sha1 CEB6679568DCA09212E758CBF76A170C4719AAE1 flags verified ) + name "Pocket King (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket King (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket King (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc dee71d44 sha1 CEB6679568DCA09212E758CBF76A170C4719AAE1 flags verified ) ) game ( name "Pocket Lure Boy (Japan)" description "Pocket Lure Boy (Japan)" - rom ( name "Pocket Lure Boy (Japan).gbc" size 1048576 crc 35A29628 md5 A42BFEF360186003C6A8A617581A1155 sha1 2CC7337A2B6AC37238AC1CDAF8E7966BD9493295 ) + rom ( name "Pocket Lure Boy (Japan).gbc" size 1048576 crc 35a29628 sha1 2CC7337A2B6AC37238AC1CDAF8E7966BD9493295 ) ) game ( name "Pocket Monsters - Crystal Version (Japan)" description "Pocket Monsters - Crystal Version (Japan)" - rom ( name "Pocket Monsters - Crystal Version (Japan).gbc" size 2097152 crc 270C4ECC md5 9C3AE66BFFB28EA8ED2896822DA02992 sha1 95127B901BBCE2407DAF43CCE9F45D4C27EF635D flags verified ) + rom ( name "Pocket Monsters - Crystal Version (Japan).gbc" size 2097152 crc 270c4ecc sha1 95127B901BBCE2407DAF43CCE9F45D4C27EF635D flags verified ) ) game ( name "Pocket Monsters Eun (Korea)" description "Pocket Monsters Eun (Korea)" - rom ( name "Pocket Monsters Eun (Korea).gbc" size 2097152 crc 9CC1F90F md5 F5E14B069EADDEE42735572BD23F7EF8 sha1 CB22D7E03A74DC3A563FDE6BE8626626B2B392E7 flags verified ) + rom ( name "Pocket Monsters Eun (Korea).gbc" size 2097152 crc 9cc1f90f sha1 CB22D7E03A74DC3A563FDE6BE8626626B2B392E7 flags verified ) ) game ( name "Pocket Monsters Geum (Korea)" description "Pocket Monsters Geum (Korea)" - rom ( name "Pocket Monsters Geum (Korea).gbc" size 2097152 crc 249A7A66 md5 82BD1D9171E60F147D9EEEA13EF07A12 sha1 C0FF3999E1093E1AF59EF3EEA3F1BFD7C1F18A65 flags verified ) + rom ( name "Pocket Monsters Geum (Korea).gbc" size 2097152 crc 249a7a66 sha1 C0FF3999E1093E1AF59EF3EEA3F1BFD7C1F18A65 flags verified ) ) game ( - name "Pocket Monsters Gin (Japan) (SGB Enhanced)" - description "Pocket Monsters Gin (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters Gin (Japan) (SGB Enhanced).gbc" size 1048576 crc BE1B928A md5 1ABB25D01DBEB20F104E44364F56FE03 sha1 FA8C51059C1642FAA570DB56EF089F54D1D2011F flags verified ) + name "Pocket Monsters Gin (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket Monsters Gin (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Monsters Gin (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc be1b928a sha1 FA8C51059C1642FAA570DB56EF089F54D1D2011F flags verified ) ) game ( - name "Pocket Monsters Gin (Japan) (Rev A) (SGB Enhanced)" - description "Pocket Monsters Gin (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Pocket Monsters Gin (Japan) (Rev A) (SGB Enhanced).gbc" size 1048576 crc 0AEA5383 md5 75519C8B57CEA3AC91133B3DEC7658DE sha1 A11D5DDC26EB826086593F82370B15D16404D33E flags verified ) + name "Pocket Monsters Gin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pocket Monsters Gin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Monsters Gin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0aea5383 sha1 A11D5DDC26EB826086593F82370B15D16404D33E flags verified ) ) game ( - name "Pocket Monsters Kin (Japan) (SGB Enhanced)" - description "Pocket Monsters Kin (Japan) (SGB Enhanced)" - rom ( name "Pocket Monsters Kin (Japan) (SGB Enhanced).gbc" size 1048576 crc 524478D4 md5 85BE569FE89F58C40F60480313314C67 sha1 8814F1039450A5D3684B1389F588CCD7EE7C3436 flags verified ) + name "Pocket Monsters Kin (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket Monsters Kin (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Monsters Kin (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 524478d4 sha1 8814F1039450A5D3684B1389F588CCD7EE7C3436 flags verified ) ) game ( - name "Pocket Monsters Kin (Japan) (Rev A) (SGB Enhanced)" - description "Pocket Monsters Kin (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Pocket Monsters Kin (Japan) (Rev A) (SGB Enhanced).gbc" size 1048576 crc 4EF7F2A5 md5 79AECE8A042E4FA57ABA9455C4D21A97 sha1 A222402235D484EE8E39F3F31BAE57CF13DAF585 flags verified ) + name "Pocket Monsters Kin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pocket Monsters Kin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Monsters Kin (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4ef7f2a5 sha1 A222402235D484EE8E39F3F31BAE57CF13DAF585 flags verified ) ) game ( name "Pocket Music (Europe) (En,Fr,De,Es,It)" description "Pocket Music (Europe) (En,Fr,De,Es,It)" - rom ( name "Pocket Music (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1BFB531E md5 84EEDE6BB298DD354F251ECCB1259316 sha1 74DC5EFAB773FDE400304D3DF8034A095AF8A742 ) + rom ( name "Pocket Music (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 1bfb531e sha1 74DC5EFAB773FDE400304D3DF8034A095AF8A742 ) ) game ( name "Pocket no Naka no Oukoku (Japan) (Proto)" description "Pocket no Naka no Oukoku (Japan) (Proto)" - rom ( name "Pocket no Naka no Oukoku (Japan) (Proto).gbc" size 2097152 crc 1EED33C6 md5 16345F768A34B18B8C072C71BC32E2FA sha1 B91750CC805BEB753E3C61A99C256D9CC006D3B8 ) + rom ( name "Pocket no Naka no Oukoku (Japan) (Proto).gbc" size 2097152 crc 1eed33c6 sha1 B91750CC805BEB753E3C61A99C256D9CC006D3B8 ) ) game ( name "Pocket Pro Wrestling - Perfect Wrestler (Japan)" description "Pocket Pro Wrestling - Perfect Wrestler (Japan)" - rom ( name "Pocket Pro Wrestling - Perfect Wrestler (Japan).gbc" size 2097152 crc D4EBBA41 md5 BB5562D1DE66E525271D4673D1376273 sha1 1B029AA7097672C469E48179D45534AB33FCCA1D ) + rom ( name "Pocket Pro Wrestling - Perfect Wrestler (Japan).gbc" size 2097152 crc d4ebba41 sha1 1B029AA7097672C469E48179D45534AB33FCCA1D flags verified ) ) game ( name "Pocket Pro Yakyuu (Japan)" description "Pocket Pro Yakyuu (Japan)" - rom ( name "Pocket Pro Yakyuu (Japan).gbc" size 1048576 crc 2A6EF6A8 md5 3435EA990961400835B057465CE1CA66 sha1 4FBBC6BD6A1631B92218632540E242820EC889CA ) + rom ( name "Pocket Pro Yakyuu (Japan).gbc" size 1048576 crc 2a6ef6a8 sha1 4FBBC6BD6A1631B92218632540E242820EC889CA ) ) game ( - name "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced)" - description "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced)" - rom ( name "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced).gbc" size 1048576 crc 45661EC3 md5 DE204AD9AE3E29CF2C06CEB372EC9CD2 sha1 C2F72FAD1A26AD765EB3036F0C9E9E8945133D3A flags verified ) + name "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced) (GB Compatible)" + description "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pocket Puyo Puyo Sun (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 45661ec3 sha1 C2F72FAD1A26AD765EB3036F0C9E9E8945133D3A flags verified ) ) game ( name "Pocket Puyo Puyo-n (Japan)" description "Pocket Puyo Puyo-n (Japan)" - rom ( name "Pocket Puyo Puyo-n (Japan).gbc" size 1048576 crc 870DB337 md5 AEF66E8A7C75323AE0981FF5A20722A4 sha1 A86D4A24B5DA3444B1967362B13D321B5C4F7A64 ) + rom ( name "Pocket Puyo Puyo-n (Japan).gbc" size 1048576 crc 870db337 sha1 A86D4A24B5DA3444B1967362B13D321B5C4F7A64 flags verified ) +) + +game ( + name "Pocket Puyo Puyo-n (Japan) (Rev 1)" + description "Pocket Puyo Puyo-n (Japan) (Rev 1)" + rom ( name "Pocket Puyo Puyo-n (Japan) (Rev 1).gbc" size 1048576 crc c884037a sha1 3D52805F712E6D1CE22B88DFEBFCAC2A31743FF3 flags verified ) +) + +game ( + name "Pocket Puyo Puyo-n (Japan) (Rev 2)" + description "Pocket Puyo Puyo-n (Japan) (Rev 2)" + rom ( name "Pocket Puyo Puyo-n (Japan) (Rev 2).gbc" size 1048576 crc 573613d7 sha1 09B217161AC326DA63887693281B60751CA2DFCF flags verified ) ) game ( name "Pocket Racing (Europe)" description "Pocket Racing (Europe)" - rom ( name "Pocket Racing (Europe).gbc" size 1048576 crc FBF97372 md5 B8BE3A0807B09038D4FEB48DC2AB1E70 sha1 76CDBD2FE7A2AD49C22083CD49F444EE51C4D140 ) + rom ( name "Pocket Racing (Europe).gbc" size 1048576 crc fbf97372 sha1 76CDBD2FE7A2AD49C22083CD49F444EE51C4D140 ) ) game ( name "Pocket Smash Out (Europe) (Unl)" description "Pocket Smash Out (Europe) (Unl)" - rom ( name "Pocket Smash Out (Europe) (Unl).gbc" size 262144 crc CBD14276 md5 08855304DDB6B3BA9AC65401EF829746 sha1 0A721164053A8B2765EA9826A0958415701CA6F5 flags verified ) + rom ( name "Pocket Smash Out (Europe) (Unl).gbc" size 262144 crc cbd14276 sha1 0A721164053A8B2765EA9826A0958415701CA6F5 flags verified ) ) game ( name "Pocket Smash Out & Race Time (Europe) (Unl)" description "Pocket Smash Out & Race Time (Europe) (Unl)" - rom ( name "Pocket Smash Out & Race Time (Europe) (Unl).gbc" size 524288 crc 0AD5B775 md5 8F3A309320BCEFFBEE2B430E5BB5DE4F sha1 01F68A0A45408DA9892B8CC0A4A9C688DCDD9618 flags verified ) + rom ( name "Pocket Smash Out & Race Time (Europe) (Unl).gbc" size 524288 crc 0ad5b775 sha1 01F68A0A45408DA9892B8CC0A4A9C688DCDD9618 flags verified ) ) game ( name "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt)" description "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc E8F5824F md5 03DA498C5503D8747DC1ECCF1101FCE3 sha1 4D06EA937A02A8F458186A9382994B09A97481A4 ) + rom ( name "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc e8f5824f sha1 4D06EA937A02A8F458186A9382994B09A97481A4 ) ) game ( name "Pokemon - Crystal Version (USA, Europe)" description "Pokemon - Crystal Version (USA, Europe)" - rom ( name "Pokemon - Crystal Version (USA, Europe).gbc" size 2097152 crc EE6F5188 md5 9F2922B235A5EEB78D65594E82EF5DDE sha1 F4CD194BDEE0D04CA4EAC29E09B8E4E9D818C133 ) + rom ( name "Pokemon - Crystal Version (USA, Europe).gbc" size 2097152 crc ee6f5188 sha1 F4CD194BDEE0D04CA4EAC29E09B8E4E9D818C133 ) ) game ( - name "Pokemon - Crystal Version (USA, Europe) (Rev A)" - description "Pokemon - Crystal Version (USA, Europe) (Rev A)" - rom ( name "Pokemon - Crystal Version (USA, Europe) (Rev A).gbc" size 2097152 crc 3358E30A md5 301899B8087289A6436B0A241FBBB474 sha1 F2F52230B536214EF7C9924F483392993E226CFB ) + name "Pokemon - Crystal Version (USA, Europe) (Rev 1)" + description "Pokemon - Crystal Version (USA, Europe) (Rev 1)" + rom ( name "Pokemon - Crystal Version (USA, Europe) (Rev 1).gbc" size 2097152 crc 3358e30a sha1 F2F52230B536214EF7C9924F483392993E226CFB flags verified ) +) + +game ( + name "Pokemon - Crystal Version (Australia)" + description "Pokemon - Crystal Version (Australia)" + rom ( name "Pokemon - Crystal Version (Australia).gbc" size 2097152 crc bb6dd80c sha1 A0FC810F1D4E124434F7BE2C989AB5B5892DDF36 flags verified ) ) game ( name "Pokemon - Edicion Cristal (Spain)" description "Pokemon - Edicion Cristal (Spain)" - rom ( name "Pokemon - Edicion Cristal (Spain).gbc" size 2097152 crc FF0A6F8A md5 8A626340F6B16BA45C1D4E07F2134875 sha1 889A06FC0BB863666865AA69DEF0ADF97945AC2A flags verified ) + rom ( name "Pokemon - Edicion Cristal (Spain).gbc" size 2097152 crc ff0a6f8a sha1 889A06FC0BB863666865AA69DEF0ADF97945AC2A flags verified ) ) game ( - name "Pokemon - Edicion Oro (Spain) (SGB Enhanced)" - description "Pokemon - Edicion Oro (Spain) (SGB Enhanced)" - rom ( name "Pokemon - Edicion Oro (Spain) (SGB Enhanced).gbc" size 2097152 crc 3434A92B md5 9462BC81907E38C59ACCCD739690E6F9 sha1 162EA54C6A3CFF374642E6DD842F9BFFAC847E7B flags verified ) + name "Pokemon - Edicion Oro (Spain) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Edicion Oro (Spain) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Edicion Oro (Spain) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3434a92b sha1 162EA54C6A3CFF374642E6DD842F9BFFAC847E7B flags verified ) ) game ( - name "Pokemon - Edicion Plata (Spain) (SGB Enhanced)" - description "Pokemon - Edicion Plata (Spain) (SGB Enhanced)" - rom ( name "Pokemon - Edicion Plata (Spain) (SGB Enhanced).gbc" size 2097152 crc 1D9FAAC5 md5 2D83FB454DD5687A802425C501854DC2 sha1 05BD978AB2CB104B0AFF3F696896E30885203A18 flags verified ) + name "Pokemon - Edicion Plata (Spain) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Edicion Plata (Spain) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Edicion Plata (Spain) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 1d9faac5 sha1 05BD978AB2CB104B0AFF3F696896E30885203A18 flags verified ) ) game ( - name "Pokemon - Gold Version (USA, Europe) (SGB Enhanced)" - description "Pokemon - Gold Version (USA, Europe) (SGB Enhanced)" - rom ( name "Pokemon - Gold Version (USA, Europe) (SGB Enhanced).gbc" size 2097152 crc 6BDE3C3E md5 A6924CE1F9AD2228E1C6580779B23878 sha1 D8B8A3600A465308C9953DFA04F0081C05BDCB94 flags verified ) + name "Pokemon - Gold Version (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Gold Version (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Gold Version (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 6bde3c3e sha1 D8B8A3600A465308C9953DFA04F0081C05BDCB94 flags verified ) ) game ( - name "Pokemon - Goldene Edition (Germany) (SGB Enhanced)" - description "Pokemon - Goldene Edition (Germany) (SGB Enhanced)" - rom ( name "Pokemon - Goldene Edition (Germany) (SGB Enhanced).gbc" size 2097152 crc 4889DFAA md5 7542EC9B695D4FE38ADFDAAA57364D83 sha1 9254195D461EA942EAAA08CC4B83DE3CF82AEA0D flags verified ) + name "Pokemon - Goldene Edition (Germany) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Goldene Edition (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Goldene Edition (Germany) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4889dfaa sha1 9254195D461EA942EAAA08CC4B83DE3CF82AEA0D flags verified ) ) game ( name "Pokemon - Kristall-Edition (Germany)" description "Pokemon - Kristall-Edition (Germany)" - rom ( name "Pokemon - Kristall-Edition (Germany).gbc" size 2097152 crc 616D85DE md5 A35C0FA2E3B3D1C1779CD9F2352BC427 sha1 ACCB584293BA056152F1FD908439B019017FF2FE ) + rom ( name "Pokemon - Kristall-Edition (Germany).gbc" size 2097152 crc 616d85de sha1 ACCB584293BA056152F1FD908439B019017FF2FE ) ) game ( - name "Pokemon - Silberne Edition (Germany) (SGB Enhanced)" - description "Pokemon - Silberne Edition (Germany) (SGB Enhanced)" - rom ( name "Pokemon - Silberne Edition (Germany) (SGB Enhanced).gbc" size 2097152 crc 96C9DB95 md5 F1F013CD591BC4EA77305BBC9F8CBB3C sha1 8ECC58D621FAAEDF2A934BD2583D527220DF7BB9 flags verified ) + name "Pokemon - Silberne Edition (Germany) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Silberne Edition (Germany) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Silberne Edition (Germany) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 96c9db95 sha1 8ECC58D621FAAEDF2A934BD2583D527220DF7BB9 flags verified ) ) game ( - name "Pokemon - Silver Version (USA, Europe) (SGB Enhanced)" - description "Pokemon - Silver Version (USA, Europe) (SGB Enhanced)" - rom ( name "Pokemon - Silver Version (USA, Europe) (SGB Enhanced).gbc" size 2097152 crc 8AD48636 md5 2AC166169354E84D0E2D7CF4CB40B312 sha1 49B163F7E57702BC939D642A18F591DE55D92DAE flags verified ) + name "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Silberne Edition (Germany) (Beta) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 576f5ced sha1 76FA60D66B2F22A035ADC54C61AAD9A415C894CD flags verified ) ) game ( - name "Pokemon - Version Argent (France) (SGB Enhanced)" - description "Pokemon - Version Argent (France) (SGB Enhanced)" - rom ( name "Pokemon - Version Argent (France) (SGB Enhanced).gbc" size 2097152 crc E0C216EA md5 72448FE75F534F70CD90469DA95EF76F sha1 A4A7E8079B7A53E4D9EF43382BBB1090B9D45D1A ) + name "Pokemon - Silver Version (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Silver Version (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Silver Version (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 8ad48636 sha1 49B163F7E57702BC939D642A18F591DE55D92DAE flags verified ) +) + +game ( + name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc e0c216ea sha1 A4A7E8079B7A53E4D9EF43382BBB1090B9D45D1A ) ) game ( name "Pokemon - Version Cristal (France)" description "Pokemon - Version Cristal (France)" - rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878B2AA7 md5 45D988BDB6CFCC334134DD212CEFB7B8 sha1 C055992B16B7399C687647725CDD1F4F13A2F75C ) + rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878b2aa7 sha1 C055992B16B7399C687647725CDD1F4F13A2F75C ) ) game ( - name "Pokemon - Version Or (France) (SGB Enhanced)" - description "Pokemon - Version Or (France) (SGB Enhanced)" - rom ( name "Pokemon - Version Or (France) (SGB Enhanced).gbc" size 2097152 crc 37A70702 md5 9AF19423C5FA3DBE4FDCC78D2BC7D1C0 sha1 C147C0D8C2B71B7628A7233436F5C052B5B17081 ) + name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 37a70702 sha1 C147C0D8C2B71B7628A7233436F5C052B5B17081 ) ) game ( - name "Pokemon - Versione Argento (Italy) (SGB Enhanced)" - description "Pokemon - Versione Argento (Italy) (SGB Enhanced)" - rom ( name "Pokemon - Versione Argento (Italy) (SGB Enhanced).gbc" size 2097152 crc CBA6D2D4 md5 9357C3DAB850692AC8184CCF655D4EFD sha1 C9ECA9D0A837BEB9137BB7D779E469C54E9F8D77 ) + name "Pokemon - Versione Argento (Italy) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Versione Argento (Italy) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Versione Argento (Italy) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cba6d2d4 sha1 C9ECA9D0A837BEB9137BB7D779E469C54E9F8D77 ) ) game ( name "Pokemon - Versione Cristallo (Italy)" description "Pokemon - Versione Cristallo (Italy)" - rom ( name "Pokemon - Versione Cristallo (Italy).gbc" size 2097152 crc D45AC039 md5 7C513823F65B92A75E29067745839CC8 sha1 6CEE05E5B95BEEAE74B8365AD18EC4A07A8C4AF8 ) + rom ( name "Pokemon - Versione Cristallo (Italy).gbc" size 2097152 crc d45ac039 sha1 6CEE05E5B95BEEAE74B8365AD18EC4A07A8C4AF8 flags verified ) ) game ( - name "Pokemon - Versione Oro (Italy) (SGB Enhanced)" - description "Pokemon - Versione Oro (Italy) (SGB Enhanced)" - rom ( name "Pokemon - Versione Oro (Italy) (SGB Enhanced).gbc" size 2097152 crc 4C184CE3 md5 89BB59DC49B59B0CD30B7384D9860BB8 sha1 032608FE8947B627584A4A0ECCC7BF9AD3588426 flags verified ) + name "Pokemon - Versione Oro (Italy) (SGB Enhanced) (GB Compatible)" + description "Pokemon - Versione Oro (Italy) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon - Versione Oro (Italy) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4c184ce3 sha1 032608FE8947B627584A4A0ECCC7BF9AD3588426 flags verified ) ) game ( - name "Pokemon Card GB (Japan) (SGB Enhanced)" - description "Pokemon Card GB (Japan) (SGB Enhanced)" - rom ( name "Pokemon Card GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 1926F570 md5 1633BEC4CABEC857C0EC67C99D2F982B sha1 2287627C5B4D56BD9A01AAB83408C301B9CF1A6C flags verified ) + name "Pokemon Card GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Pokemon Card GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Card GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1926f570 sha1 2287627C5B4D56BD9A01AAB83408C301B9CF1A6C flags verified ) ) game ( - name "Pokemon Card GB2 - GR Dan Sanjou! (Japan)" - description "Pokemon Card GB2 - GR Dan Sanjou! (Japan)" - rom ( name "Pokemon Card GB2 - GR Dan Sanjou! (Japan).gbc" size 2097152 crc 6C933A14 md5 1134862E84110443190DF460351D4575 sha1 A7E12BCC5F514E3AAD8DE570FD511AAB0A308822 ) + name "Pokemon Card GB 2 - GR Dan Sanjou! (Japan)" + description "Pokemon Card GB 2 - GR Dan Sanjou! (Japan)" + rom ( name "Pokemon Card GB 2 - GR Dan Sanjou! (Japan).gbc" size 2097152 crc 6c933a14 sha1 A7E12BCC5F514E3AAD8DE570FD511AAB0A308822 ) ) game ( name "Pokemon de Panepon (Japan)" description "Pokemon de Panepon (Japan)" - rom ( name "Pokemon de Panepon (Japan).gbc" size 2097152 crc 6BF7E4A6 md5 510EB8C9DF5D3F71E01F5A7898A0A1F1 sha1 110AE6649B4264F88D82760AD6AE4EE7F07DB9B2 flags verified ) + rom ( name "Pokemon de Panepon (Japan).gbc" size 2097152 crc 6bf7e4a6 sha1 110AE6649B4264F88D82760AD6AE4EE7F07DB9B2 flags verified ) ) game ( - name "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced)" - description "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced)" - rom ( name "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced).gbc" size 2097152 crc 39C432A4 md5 3757C89C36BEC5E2093741A3E51D22DF sha1 24C693B8048594E2BF61EC1DC2182E75D81E532D flags verified ) + name "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Pinball (Europe) (En,Fr,De,Es,It) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 39c432a4 sha1 24C693B8048594E2BF61EC1DC2182E75D81E532D flags verified ) ) game ( - name "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced)" - description "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced)" - rom ( name "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc 13C70DE9 md5 852D68F167A5957F5E73954763F36ADA sha1 96D0D854B9B49D724CD1DCBACD6313F0FC6C1C10 flags verified ) + name "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Pinball (Japan) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 13c70de9 sha1 96D0D854B9B49D724CD1DCBACD6313F0FC6C1C10 flags verified ) ) game ( - name "Pokemon Pinball (USA) (Rumble Version) (SGB Enhanced)" - description "Pokemon Pinball (USA) (Rumble Version) (SGB Enhanced)" - rom ( name "Pokemon Pinball (USA) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc 03CE8D9A md5 FBE20570C2E52C937A9395024069BA3C sha1 9402014D14969432142ABFDE728C6F1A10EE4DAC flags verified ) + name "Pokemon Pinball (USA, Australia) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Pokemon Pinball (USA, Australia) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Pinball (USA, Australia) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 03ce8d9a sha1 9402014D14969432142ABFDE728C6F1A10EE4DAC flags verified ) ) game ( name "Pokemon Puzzle Challenge (Europe) (En,Fr,De,Es,It)" description "Pokemon Puzzle Challenge (Europe) (En,Fr,De,Es,It)" - rom ( name "Pokemon Puzzle Challenge (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 8206B1CE md5 C7A879BEFD45BBC5CDAB7413D86FFF76 sha1 E40D6A7F78B449E5A55BAAAEA7E227AB19D510E4 ) + rom ( name "Pokemon Puzzle Challenge (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 8206b1ce sha1 E40D6A7F78B449E5A55BAAAEA7E227AB19D510E4 ) ) game ( - name "Pokemon Puzzle Challenge (USA)" - description "Pokemon Puzzle Challenge (USA)" - rom ( name "Pokemon Puzzle Challenge (USA).gbc" size 2097152 crc D06BBA96 md5 F9EC4CC3C9DF3887DC731CCF53663FFB sha1 BBF952412250AE511B3B862566E424CE6A672F99 ) + name "Pokemon Puzzle Challenge (USA, Australia)" + description "Pokemon Puzzle Challenge (USA, Australia)" + rom ( name "Pokemon Puzzle Challenge (USA, Australia).gbc" size 2097152 crc d06bba96 sha1 BBF952412250AE511B3B862566E424CE6A672F99 flags verified ) ) game ( - name "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced)" - description "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced)" - rom ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced).gbc" size 2097152 crc 966DAEF1 md5 7EB08EF6D67164251EEEABF537FEDCCB sha1 2138A422D135A13C49FCE71229AE36BC1DC4FBB5 ) + name "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 966daef1 sha1 2138A422D135A13C49FCE71229AE36BC1DC4FBB5 ) ) game ( - name "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced)" - description "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 2097152 crc 4523376E md5 4572F09B61A36E94762FF60CBE182834 sha1 868E7B376E39F7D65A735538D90FBE6BBC99D198 flags verified ) + name "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 4523376e sha1 868E7B376E39F7D65A735538D90FBE6BBC99D198 flags verified ) ) game ( - name "Pokemon Trading Card Game (USA) (SGB Enhanced)" - description "Pokemon Trading Card Game (USA) (SGB Enhanced)" - rom ( name "Pokemon Trading Card Game (USA) (SGB Enhanced).gbc" size 1048576 crc 81069D53 md5 219B2CC64E5A052003015D4BD4C622CD sha1 0F8670A583255CFF3E5B7CA71B5D7454D928FC48 flags verified ) + name "Pokemon Trading Card Game (USA, Australia) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (USA, Australia) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (USA, Australia) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 81069d53 sha1 0F8670A583255CFF3E5B7CA71B5D7454D928FC48 flags verified ) +) + +game ( + name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Fr,De) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 942d0b7f sha1 DFFC15F3063A4C2DF84C6361406B41AEC1696D3E flags verified ) +) + +game ( + name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Pokemon Trading Card Game (Europe) (En,Es,It) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3f1d7e58 sha1 C54B81E638B0C45D3569F9F5F0345DF9E95CE975 flags verified ) ) game ( name "Polaris SnoCross (USA) (Rumble Version)" description "Polaris SnoCross (USA) (Rumble Version)" - rom ( name "Polaris SnoCross (USA) (Rumble Version).gbc" size 1048576 crc DD8B189E md5 D0CA48AEE3FFB5FD44FC4D4359C5D44B sha1 E893808FE227A1608C0604382D6A0340EC704C3B ) + rom ( name "Polaris SnoCross (USA) (Rumble Version).gbc" size 1048576 crc dd8b189e sha1 E893808FE227A1608C0604382D6A0340EC704C3B ) ) game ( name "Pong - The Next Level (USA, Europe)" description "Pong - The Next Level (USA, Europe)" - rom ( name "Pong - The Next Level (USA, Europe).gbc" size 1048576 crc 476BD39D md5 0A3DA06446D9A2C7E1EA8149C9026434 sha1 637827A89A0948F6561BF2A018DE6244E2811A99 flags verified ) + rom ( name "Pong - The Next Level (USA, Europe).gbc" size 1048576 crc 476bd39d sha1 637827A89A0948F6561BF2A018DE6244E2811A99 flags verified ) ) game ( name "Pooh and Tigger's Hunny Safari (Europe) (En,Fr,De,Es,It,Nl)" description "Pooh and Tigger's Hunny Safari (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Pooh and Tigger's Hunny Safari (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 8505D139 md5 7A58B84E406BD4DF6B3C3B8807493AA8 sha1 4141887F0B152F8592B905355E11CF43147128C2 flags verified ) + rom ( name "Pooh and Tigger's Hunny Safari (Europe) (En,Fr,De,Es,It,Nl).gbc" size 2097152 crc 8505d139 sha1 4141887F0B152F8592B905355E11CF43147128C2 flags verified ) ) game ( name "Pooh and Tigger's Hunny Safari (USA)" description "Pooh and Tigger's Hunny Safari (USA)" - rom ( name "Pooh and Tigger's Hunny Safari (USA).gbc" size 2097152 crc 622690DA md5 5F872189D58F841B5672D4CB11EC3BBB sha1 934918DA6249723760A356748BF240F57262BD77 ) + rom ( name "Pooh and Tigger's Hunny Safari (USA).gbc" size 2097152 crc 622690da sha1 934918DA6249723760A356748BF240F57262BD77 ) ) game ( name "Pop'n Music GB (Japan)" description "Pop'n Music GB (Japan)" - rom ( name "Pop'n Music GB (Japan).gbc" size 1048576 crc 07E6CA95 md5 10E6DCD0A350076E28B9C598C278B6A2 sha1 F2B31ECDD1DBD3C7C120D436ED8D5E19743E9CF0 ) + rom ( name "Pop'n Music GB (Japan).gbc" size 1048576 crc 07e6ca95 sha1 F2B31ECDD1DBD3C7C120D436ED8D5E19743E9CF0 ) ) game ( name "Pop'n Music GB - Animation Melody (Japan)" description "Pop'n Music GB - Animation Melody (Japan)" - rom ( name "Pop'n Music GB - Animation Melody (Japan).gbc" size 1048576 crc 9B2429A7 md5 7E6D077D50879C57FF70891AAA312E80 sha1 F4442D7E984EBEFC7735E205CA759C2BE3BD1843 ) + rom ( name "Pop'n Music GB - Animation Melody (Japan).gbc" size 1048576 crc 9b2429a7 sha1 F4442D7E984EBEFC7735E205CA759C2BE3BD1843 ) ) game ( name "Pop'n Music GB - Disney Tunes (Japan)" description "Pop'n Music GB - Disney Tunes (Japan)" - rom ( name "Pop'n Music GB - Disney Tunes (Japan).gbc" size 1048576 crc 48C3C6EF md5 92978C96B2368E4AEBD84966AF8BD06F sha1 FF34D9D68C81B82A70ED11AC509EC5DAAF29CD46 ) + rom ( name "Pop'n Music GB - Disney Tunes (Japan).gbc" size 1048576 crc 48c3c6ef sha1 FF34D9D68C81B82A70ED11AC509EC5DAAF29CD46 ) ) game ( name "Pop'n Pop (Europe)" description "Pop'n Pop (Europe)" - rom ( name "Pop'n Pop (Europe).gbc" size 1048576 crc FC67F7E4 md5 A96E95E150E34DB6080724C5EEEC1348 sha1 5874CC64B184692ED03FB860DE058FA3475B1D5C ) + rom ( name "Pop'n Pop (Europe).gbc" size 1048576 crc fc67f7e4 sha1 5874CC64B184692ED03FB860DE058FA3475B1D5C ) ) game ( name "Pop'n Pop (Japan)" description "Pop'n Pop (Japan)" - rom ( name "Pop'n Pop (Japan).gbc" size 1048576 crc 1CFFB764 md5 33A1389FB8BDC2C4CAA3859213140C79 sha1 EF425613296573225E42228CA12BCE5124374206 ) + rom ( name "Pop'n Pop (Japan).gbc" size 1048576 crc 1cffb764 sha1 EF425613296573225E42228CA12BCE5124374206 ) ) game ( name "Portal Runner (USA)" description "Portal Runner (USA)" - rom ( name "Portal Runner (USA).gbc" size 1048576 crc 913AC306 md5 8765EE1FE94C16E934EA0D004291E8B0 sha1 A8347366F15C0E454FA253BAD5B4053D2A9613AA ) + rom ( name "Portal Runner (USA).gbc" size 1048576 crc 913ac306 sha1 A8347366F15C0E454FA253BAD5B4053D2A9613AA ) ) game ( - name "Power Pro Kun Pocket (Japan) (SGB Enhanced)" - description "Power Pro Kun Pocket (Japan) (SGB Enhanced)" - rom ( name "Power Pro Kun Pocket (Japan) (SGB Enhanced).gbc" size 2097152 crc 145540D8 md5 5AB6B2A6F4C48AA8A1E77E31370CDCB3 sha1 F796F9CB259646555F0D429B9337AC6B423755A3 flags verified ) + name "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" + description "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 145540d8 sha1 F796F9CB259646555F0D429B9337AC6B423755A3 flags verified ) ) game ( - name "Power Pro Kun Pocket (Japan) (Rev A) (SGB Enhanced)" - description "Power Pro Kun Pocket (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Power Pro Kun Pocket (Japan) (Rev A) (SGB Enhanced).gbc" size 2097152 crc 894D88F2 md5 38D51BE26C98E1A89CACE0D4F0684F72 sha1 AE145F2DE0D53C19B973C71BAAF3F2CCA2CA395A flags verified ) + name "Power Pro Kun Pocket (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Power Pro Kun Pocket (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Power Pro Kun Pocket (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 894d88f2 sha1 AE145F2DE0D53C19B973C71BAAF3F2CCA2CA395A flags verified ) ) game ( - name "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced)" - description "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced)" - rom ( name "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced).gbc" size 2097152 crc C2A4A3EB md5 2C03CC138BE009ED83F036F919FF8F0A sha1 5C0BA404CF30296DCEEB427A54E3644415C9E8DB flags verified ) + name "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Power Pro Kun Pocket 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc c2a4a3eb sha1 5C0BA404CF30296DCEEB427A54E3644415C9E8DB flags verified ) ) game ( - name "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced)" - description "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced)" - rom ( name "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced).gbc" size 1048576 crc 30E1E567 md5 3286D6B332EDFB46D8504BCEBA7E55D7 sha1 B9B41A90BABA13888AC8F3788B96935F4D394C2C flags verified ) + name "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + description "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + rom ( name "Power Quest (Europe) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 30e1e567 sha1 B9B41A90BABA13888AC8F3788B96935F4D394C2C flags verified ) ) game ( - name "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced)" - description "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced)" - rom ( name "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced).gbc" size 1048576 crc DAD6F6B4 md5 AC1F4AD52996882C60CE83CAC01E9CCF sha1 D1665784A007C122D65F43BD2751DB6B395FF3CD ) -) - -game ( - name "Power Rangers - Lightspeed Rescue (USA, Europe)" - description "Power Rangers - Lightspeed Rescue (USA, Europe)" - rom ( name "Power Rangers - Lightspeed Rescue (USA, Europe).gbc" size 1048576 crc 99869172 md5 C3C4B88E40538C1C99B85313BC88DF6D sha1 E7D0F2F21CDCDA49516F682092D0B2017E82D379 flags verified ) -) - -game ( - name "Power Rangers - Time Force (USA, Europe)" - description "Power Rangers - Time Force (USA, Europe)" - rom ( name "Power Rangers - Time Force (USA, Europe).gbc" size 1048576 crc 17E51443 md5 7510FE2592ACCFA6CCD4745612E64F88 sha1 9C383013C5EC0E1F2C33B95D66CD93A3D0743928 flags verified ) + name "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + description "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible)" + rom ( name "Power Quest (USA) (En,Fr,De,Es,It) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc dad6f6b4 sha1 D1665784A007C122D65F43BD2751DB6B395FF3CD flags verified ) ) game ( name "Power Spike - Pro Beach Volleyball (USA)" description "Power Spike - Pro Beach Volleyball (USA)" - rom ( name "Power Spike - Pro Beach Volleyball (USA).gbc" size 1048576 crc AE57D1C3 md5 AFD9281EAC1EACD73C200CBC69F57B9E sha1 CBF7377E2DFEA331F983B34486AB7761AC75E3AC ) + rom ( name "Power Spike - Pro Beach Volleyball (USA).gbc" size 1048576 crc ae57d1c3 sha1 CBF7377E2DFEA331F983B34486AB7761AC75E3AC ) ) game ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA)" description "Powerpuff Girls, The - Bad Mojo Jojo (USA)" - rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA).gbc" size 2097152 crc 834CAF7A md5 258B7B8E4692D4204DF470487EF2FC3D sha1 92D86EC01E8669BBB8D26A5EC51EFC0F761EEAF4 ) + rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA).gbc" size 2097152 crc 834caf7a sha1 92D86EC01E8669BBB8D26A5EC51EFC0F761EEAF4 ) ) game ( - name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev A)" - description "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev A)" - rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev A).gbc" size 2097152 crc 548A287A md5 4B9D82D91A575CF96657383A26505EFF sha1 D3F74815BEC29AE7D580B112A1C1F913C19AC89E ) + name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 1)" + description "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 1)" + rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 1).gbc" size 2097152 crc 548a287a sha1 D3F74815BEC29AE7D580B112A1C1F913C19AC89E flags verified ) ) game ( - name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev B)" - description "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev B)" - rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev B).gbc" size 2097152 crc A111704F md5 C73B80F668E138C6828C9BCCA13A13BA sha1 98F46ABBD8792BF716928BF2E28AF94AF467EF51 flags verified ) + name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 2)" + description "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 2)" + rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (USA) (Rev 2).gbc" size 2097152 crc a111704f sha1 98F46ABBD8792BF716928BF2E28AF94AF467EF51 flags verified ) ) game ( name "Powerpuff Girls, The - Bad Mojo Jojo (Europe)" description "Powerpuff Girls, The - Bad Mojo Jojo (Europe)" - rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (Europe).gbc" size 2097152 crc 75D1063A md5 FE510196E7FD81B5D9AB9CCA091435D7 sha1 E1FDE0D5C3F428A0932A2CEEAC1889EBCABC3F7E ) -) - -game ( - name "Powerpuff Girls, The - Battle Him (Europe)" - description "Powerpuff Girls, The - Battle Him (Europe)" - rom ( name "Powerpuff Girls, The - Battle Him (Europe).gbc" size 2097152 crc 788859AE md5 86D769E211C85C1AC956C4556E77F8F3 sha1 9D2CBE85C7C0DA6EA4354822F85CD597BFAFF1C5 ) + rom ( name "Powerpuff Girls, The - Bad Mojo Jojo (Europe).gbc" size 2097152 crc 75d1063a sha1 E1FDE0D5C3F428A0932A2CEEAC1889EBCABC3F7E flags verified ) ) game ( name "Powerpuff Girls, The - Battle Him (USA)" description "Powerpuff Girls, The - Battle Him (USA)" - rom ( name "Powerpuff Girls, The - Battle Him (USA).gbc" size 2097152 crc D8455984 md5 565B748F3EE16464BEBDE853770D39D2 sha1 3D90946A2CBE503D040B10958301587998D4E86F ) + rom ( name "Powerpuff Girls, The - Battle Him (USA).gbc" size 2097152 crc d8455984 sha1 3D90946A2CBE503D040B10958301587998D4E86F ) ) game ( - name "Powerpuff Girls, The - Battle Him (USA) (Rev A)" - description "Powerpuff Girls, The - Battle Him (USA) (Rev A)" - rom ( name "Powerpuff Girls, The - Battle Him (USA) (Rev A).gbc" size 2097152 crc E3D6964C md5 57BCDE64A3005D4AAD8DF640F2B5F07C sha1 8F22B2CD9552EB1146F0A78A9C9242C031046E1C ) + name "Powerpuff Girls, The - Battle Him (USA) (Rev 1)" + description "Powerpuff Girls, The - Battle Him (USA) (Rev 1)" + rom ( name "Powerpuff Girls, The - Battle Him (USA) (Rev 1).gbc" size 2097152 crc e3d6964c sha1 8F22B2CD9552EB1146F0A78A9C9242C031046E1C flags verified ) +) + +game ( + name "Powerpuff Girls, The - Battle Him (Europe)" + description "Powerpuff Girls, The - Battle Him (Europe)" + rom ( name "Powerpuff Girls, The - Battle Him (Europe).gbc" size 2097152 crc 788859ae sha1 9D2CBE85C7C0DA6EA4354822F85CD597BFAFF1C5 flags verified ) ) game ( name "Powerpuff Girls, The - Bulle Contre Lui (France)" description "Powerpuff Girls, The - Bulle Contre Lui (France)" - rom ( name "Powerpuff Girls, The - Bulle Contre Lui (France).gbc" size 2097152 crc 7085270C md5 FD5D1AD9FA778895FA24D1FE1ECA52B7 sha1 5C1C53B9C002680C2DA8B24AA31D4A247586263D ) + rom ( name "Powerpuff Girls, The - Bulle Contre Lui (France).gbc" size 2097152 crc 7085270c sha1 5C1C53B9C002680C2DA8B24AA31D4A247586263D flags verified ) ) game ( name "Powerpuff Girls, The - L'Affreux Mojo Jojo (France)" description "Powerpuff Girls, The - L'Affreux Mojo Jojo (France)" - rom ( name "Powerpuff Girls, The - L'Affreux Mojo Jojo (France).gbc" size 2097152 crc 256D166F md5 663EED7079113B1D1E1D7D40E9871CC3 sha1 1B5037F53FB77DD2C9C359052D46E5362C6A9801 ) -) - -game ( - name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev A)" - description "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev A)" - rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev A).gbc" size 2097152 crc 295B3646 md5 C8F68E280F379FF7CC10C8EC4ED89142 sha1 023D4D9374E7FE9844F970DD0004C5D7EEFD2D38 ) -) - -game ( - name "Powerpuff Girls, The - Paint the Townsville Green (Europe)" - description "Powerpuff Girls, The - Paint the Townsville Green (Europe)" - rom ( name "Powerpuff Girls, The - Paint the Townsville Green (Europe).gbc" size 2097152 crc 98E4B0C4 md5 B3E8E32A3F8C3366CB12B4EA7B0A9169 sha1 E214AB665FFAB3682B9833B4E4D0494FC53CD26F flags verified ) + rom ( name "Powerpuff Girls, The - L'Affreux Mojo Jojo (France).gbc" size 2097152 crc 256d166f sha1 1B5037F53FB77DD2C9C359052D46E5362C6A9801 flags verified ) ) game ( name "Powerpuff Girls, The - Paint the Townsville Green (USA)" description "Powerpuff Girls, The - Paint the Townsville Green (USA)" - rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA).gbc" size 2097152 crc 9D47261A md5 967488FC18B9EE5140C33090FEDD7A79 sha1 2D52551FCE2CB6D246C6296BEEB6A8A3DFBC2159 ) + rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA).gbc" size 2097152 crc 9d47261a sha1 2D52551FCE2CB6D246C6296BEEB6A8A3DFBC2159 ) ) game ( - name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev B)" - description "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev B)" - rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev B).gbc" size 2097152 crc 443367AE md5 AEEC41031271F75B5E0B1D132B8A4505 sha1 EF93E793067BBB3748AAC17D661C8C8B68CCEE9B ) + name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 2)" + description "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 2)" + rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 2).gbc" size 2097152 crc 443367ae sha1 EF93E793067BBB3748AAC17D661C8C8B68CCEE9B ) ) game ( - name "Powerpuff Girls, The - Panique A Townsville (France)" - description "Powerpuff Girls, The - Panique A Townsville (France)" - rom ( name "Powerpuff Girls, The - Panique A Townsville (France).gbc" size 2097152 crc 79A417DB md5 69EBFA592721CD1D9C835D1B810B7266 sha1 978D68300B625D8E375571475B4F2C2C1A65FD60 ) + name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 1)" + description "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 1)" + rom ( name "Powerpuff Girls, The - Paint the Townsville Green (USA) (Rev 1).gbc" size 2097152 crc 295b3646 sha1 023D4D9374E7FE9844F970DD0004C5D7EEFD2D38 flags verified ) +) + +game ( + name "Powerpuff Girls, The - Paint the Townsville Green (Europe)" + description "Powerpuff Girls, The - Paint the Townsville Green (Europe)" + rom ( name "Powerpuff Girls, The - Paint the Townsville Green (Europe).gbc" size 2097152 crc 98e4b0c4 sha1 E214AB665FFAB3682B9833B4E4D0494FC53CD26F flags verified ) +) + +game ( + name "Powerpuff Girls, The - Panique a Townsville (France)" + description "Powerpuff Girls, The - Panique a Townsville (France)" + rom ( name "Powerpuff Girls, The - Panique a Townsville (France).gbc" size 2097152 crc 79a417db sha1 978D68300B625D8E375571475B4F2C2C1A65FD60 flags verified ) ) game ( name "Prince Naseem Boxing (Europe) (En,Fr,De)" description "Prince Naseem Boxing (Europe) (En,Fr,De)" - rom ( name "Prince Naseem Boxing (Europe) (En,Fr,De).gbc" size 2097152 crc 91DEF753 md5 033DADE2CC761D6F360DAEECFF9D6F90 sha1 F0500B3CA8A24B3BD2C11E77FBE4C75DB178DFBE ) + rom ( name "Prince Naseem Boxing (Europe) (En,Fr,De).gbc" size 2097152 crc 91def753 sha1 F0500B3CA8A24B3BD2C11E77FBE4C75DB178DFBE ) ) game ( - name "Prince of Persia (USA, Europe) (En,Fr,De,Es,It)" - description "Prince of Persia (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Prince of Persia (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc E6BEC6D1 md5 AFEEC69D5BA3AFA3CE2279FCDA944576 sha1 EF2F6402E8EF367273200E3B07F310EBD80CCDC2 flags verified ) + name "Prince of Persia (USA, Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Prince of Persia (USA, Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Prince of Persia (USA, Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc e6bec6d1 sha1 EF2F6402E8EF367273200E3B07F310EBD80CCDC2 flags verified ) ) game ( name "Pro Darts (USA)" description "Pro Darts (USA)" - rom ( name "Pro Darts (USA).gbc" size 1048576 crc 834A72C0 md5 809059AD595BEC85FFC7BA37EBA29204 sha1 60A89486F747E7440A79774B280B24B6498EF5EA ) + rom ( name "Pro Darts (USA).gbc" size 1048576 crc 834a72c0 sha1 60A89486F747E7440A79774B280B24B6498EF5EA ) ) game ( - name "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv)" - description "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv)" - serial "DMG-AAFF-FRA" - rom ( name "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc A9905932 md5 71608F971986DD740C8E94F61F9CD020 sha1 C43DAA82286D3A910A6A922D4EA722C594A2CDE0 ) + name "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Pro Foot (France) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 1048576 crc a9905932 sha1 C43DAA82286D3A910A6A922D4EA722C594A2CDE0 flags verified ) ) game ( - name "Pro Mahjong Kiwame GB II (Japan) (SGB Enhanced)" - description "Pro Mahjong Kiwame GB II (Japan) (SGB Enhanced)" - rom ( name "Pro Mahjong Kiwame GB II (Japan) (SGB Enhanced).gbc" size 1048576 crc 14F91F86 md5 C21DC91B8BA1032F7FE9D46FC23638EC sha1 2C9C2967400AB9BAD95FFE104763B3190F28AA39 ) + name "Pro Mahjong Kiwame II GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Pro Mahjong Kiwame II GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pro Mahjong Kiwame II GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 14f91f86 sha1 2C9C2967400AB9BAD95FFE104763B3190F28AA39 ) ) game ( - name "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced)" - description "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced)" - rom ( name "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 1461D8D8 md5 17138240C26791C06D557094D0A4D1F5 sha1 B9E7CD7E53FDA3DB329C57971A47D35255BD0B34 ) + name "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Pro Mahjong Tsuwamono GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1461d8d8 sha1 B9E7CD7E53FDA3DB329C57971A47D35255BD0B34 ) ) game ( - name "Pro Mahjong Tsuwamono GB2 (Japan)" - description "Pro Mahjong Tsuwamono GB2 (Japan)" - rom ( name "Pro Mahjong Tsuwamono GB2 (Japan).gbc" size 1048576 crc F03016F5 md5 9D238ED036BB656ACF9765589119F68C sha1 3E49A76D36C39E9A4248A12F88A08AB3E30C96BA ) + name "Pro Mahjong Tsuwamono GB 2 (Japan)" + description "Pro Mahjong Tsuwamono GB 2 (Japan)" + rom ( name "Pro Mahjong Tsuwamono GB 2 (Japan).gbc" size 1048576 crc f03016f5 sha1 3E49A76D36C39E9A4248A12F88A08AB3E30C96BA flags verified ) ) game ( name "Pro Pool (USA) (En,Fr,De)" description "Pro Pool (USA) (En,Fr,De)" - rom ( name "Pro Pool (USA) (En,Fr,De).gbc" size 1048576 crc 04D3031A md5 27AAEB747ED1E125582729BA82FE8C28 sha1 56252A97A3D463103E1047A6E1A64CAD43BEDD4C ) + rom ( name "Pro Pool (USA) (En,Fr,De).gbc" size 1048576 crc 04d3031a sha1 56252A97A3D463103E1047A6E1A64CAD43BEDD4C ) ) game ( name "Pro Pool (Europe) (En,Fr,De)" description "Pro Pool (Europe) (En,Fr,De)" - serial "CGB-BPLP-EUU" - rom ( name "Pro Pool (Europe) (En,Fr,De).gbc" size 1048576 crc 21A4DA64 md5 87B211FE7E0B8080961DDD26245CA1A5 sha1 575C02F73A0BDC357289073F053D8A3969927880 ) + rom ( name "Pro Pool (Europe) (En,Fr,De).gbc" size 1048576 crc 21a4da64 sha1 575C02F73A0BDC357289073F053D8A3969927880 flags verified ) ) game ( name "Project S-11 (USA)" description "Project S-11 (USA)" - rom ( name "Project S-11 (USA).gbc" size 524288 crc 20CEE2E8 md5 8FE6340C822DAA9CB07C7D8AB8509751 sha1 CBEDD34A0C6A2F4E58D05F0BB6D54F7CBCDA815C ) + rom ( name "Project S-11 (USA).gbc" size 524288 crc 20cee2e8 sha1 CBEDD34A0C6A2F4E58D05F0BB6D54F7CBCDA815C ) ) game ( - name "Puchi Carat (Europe) (SGB Enhanced)" - description "Puchi Carat (Europe) (SGB Enhanced)" - rom ( name "Puchi Carat (Europe) (SGB Enhanced).gbc" size 1048576 crc A9A89DDA md5 BE7C823A2C6FEBA614AFA32606EDEBE5 sha1 F703796E5551E12924C070CD8A0E77C6D82073AF ) + name "Puchi Carat (Europe) (SGB Enhanced) (GB Compatible)" + description "Puchi Carat (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Puchi Carat (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc a9a89dda sha1 F703796E5551E12924C070CD8A0E77C6D82073AF ) ) game ( - name "Puchi Carat (Japan) (SGB Enhanced)" - description "Puchi Carat (Japan) (SGB Enhanced)" - rom ( name "Puchi Carat (Japan) (SGB Enhanced).gbc" size 1048576 crc F0D0C36D md5 9F61847DDF25F5244257641BC971C1FD sha1 25ABDA13F97140D412BB00E109BACA8574D5AF6E ) + name "Puchi Carat (Japan) (SGB Enhanced) (GB Compatible)" + description "Puchi Carat (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Puchi Carat (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc f0d0c36d sha1 25ABDA13F97140D412BB00E109BACA8574D5AF6E ) ) game ( name "Pumuckls Abenteuer bei den Piraten (Germany)" description "Pumuckls Abenteuer bei den Piraten (Germany)" - rom ( name "Pumuckls Abenteuer bei den Piraten (Germany).gbc" size 1048576 crc F55CDB79 md5 FC327CDB1F787046DAE8A17305F10261 sha1 1F90E982EAD050796722D98F94E31A836945F84D flags verified ) + rom ( name "Pumuckls Abenteuer bei den Piraten (Germany).gbc" size 1048576 crc f55cdb79 sha1 1F90E982EAD050796722D98F94E31A836945F84D flags verified ) ) game ( name "Pumuckls Abenteuer im Geisterschloss (Germany)" description "Pumuckls Abenteuer im Geisterschloss (Germany)" - rom ( name "Pumuckls Abenteuer im Geisterschloss (Germany).gbc" size 1048576 crc 87FCEC24 md5 96D2795FD83F03986C5142EC288D384E sha1 0FE14EF81B11C854F080E804C5D3CB14601B2794 flags verified ) + rom ( name "Pumuckls Abenteuer im Geisterschloss (Germany).gbc" size 1048576 crc 87fcec24 sha1 0FE14EF81B11C854F080E804C5D3CB14601B2794 flags verified ) ) game ( - name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced)" - description "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced)" - rom ( name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced).gbc" size 1048576 crc 67350BC9 md5 EC0985BDAD4B519C492F07F2D01F1613 sha1 B1802797E892D09E4DA53304D096BDF35BAC1118 ) + name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" + description "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 67350bc9 sha1 B1802797E892D09E4DA53304D096BDF35BAC1118 ) ) game ( - name "Puzz Loop (Japan)" - description "Puzz Loop (Japan)" - rom ( name "Puzz Loop (Japan).gbc" size 1048576 crc AF858234 md5 C4354362E13A4DCDA40B063D96BD6580 sha1 F8B299C665552621CA067886A8F16E842F699487 ) + name "Puzz Loop (Japan) (GB Compatible)" + description "Puzz Loop (Japan) (GB Compatible)" + rom ( name "Puzz Loop (Japan) (GB Compatible).gbc" size 1048576 crc af858234 sha1 F8B299C665552621CA067886A8F16E842F699487 ) ) game ( - name "Puzzle Bobble 4 (Japan)" - description "Puzzle Bobble 4 (Japan)" - rom ( name "Puzzle Bobble 4 (Japan).gbc" size 524288 crc 79A35284 md5 27881DF91CFC52D1671E469F46475D8C sha1 9C1E0055C2067688E066079778A795DBFA70C565 ) + name "Puzzle Bobble 4 (Japan) (GB Compatible)" + description "Puzzle Bobble 4 (Japan) (GB Compatible)" + rom ( name "Puzzle Bobble 4 (Japan) (GB Compatible).gbc" size 524288 crc 79a35284 sha1 9C1E0055C2067688E066079778A795DBFA70C565 flags verified ) ) game ( name "Puzzle Bobble Millennium (Japan)" description "Puzzle Bobble Millennium (Japan)" - rom ( name "Puzzle Bobble Millennium (Japan).gbc" size 1048576 crc 00FDED94 md5 DD53D483612E848D5F636AAC67665F72 sha1 ADBB7B1544CF26E017053137ED7E9668F442E608 ) + rom ( name "Puzzle Bobble Millennium (Japan).gbc" size 1048576 crc 00fded94 sha1 ADBB7B1544CF26E017053137ED7E9668F442E608 ) ) game ( - name "Puzzle de Shoubuyo! Wootama-chan (Japan)" - description "Puzzle de Shoubuyo! Wootama-chan (Japan)" - rom ( name "Puzzle de Shoubuyo! Wootama-chan (Japan).gbc" size 1048576 crc 73ED3042 md5 5DAF6DA4A471C6B9517413EF25E498A5 sha1 2C8630324767675E7F3DA67E3A3071C73174A47D ) + name "Puzzle de Shoubuyo! - Wootama-chan (Japan) (GB Compatible)" + description "Puzzle de Shoubuyo! - Wootama-chan (Japan) (GB Compatible)" + rom ( name "Puzzle de Shoubuyo! - Wootama-chan (Japan) (GB Compatible).gbc" size 1048576 crc 73ed3042 sha1 2C8630324767675E7F3DA67E3A3071C73174A47D ) ) game ( - name "Puzzle Master (USA)" - description "Puzzle Master (USA)" - rom ( name "Puzzle Master (USA).gbc" size 1048576 crc 06EB7A01 md5 90ECC5FB29CC95D58C33D44FE630D12E sha1 CBACCC88628194C82E115A8127CEEB035CD9C0A0 ) + name "Puzzle Master (USA) (GB Compatible)" + description "Puzzle Master (USA) (GB Compatible)" + rom ( name "Puzzle Master (USA) (GB Compatible).gbc" size 1048576 crc 06eb7a01 sha1 CBACCC88628194C82E115A8127CEEB035CD9C0A0 ) ) game ( name "Puzzled (Europe) (En,Fr,De)" description "Puzzled (Europe) (En,Fr,De)" - rom ( name "Puzzled (Europe) (En,Fr,De).gbc" size 1048576 crc 15B44D68 md5 CCDCB901229A2278D0BE673472F411B9 sha1 4E40ECD30A4E9C367F31CF5367C279F88B7DF11C ) + rom ( name "Puzzled (Europe) (En,Fr,De).gbc" size 1048576 crc 15b44d68 sha1 4E40ECD30A4E9C367F31CF5367C279F88B7DF11C ) ) game ( name "Puzzled (USA)" description "Puzzled (USA)" - rom ( name "Puzzled (USA).gbc" size 1048576 crc F03FFDAF md5 9108D1246F11D0E0F2CEC608E79EFD65 sha1 8FD66D88174E429E9B909796745C74640DE7DB29 ) + rom ( name "Puzzled (USA).gbc" size 1048576 crc f03ffdaf sha1 8FD66D88174E429E9B909796745C74640DE7DB29 ) ) game ( name "Q-bert (USA)" description "Q-bert (USA)" - rom ( name "Q-bert (USA).gbc" size 1048576 crc 90F46D7E md5 4A8E3506F98E01FCB0DA5073B83E4E35 sha1 4B2767CA512228B7DB0F814F31CA45C4B92D349B ) + rom ( name "Q-bert (USA).gbc" size 1048576 crc 90f46d7e sha1 4B2767CA512228B7DB0F814F31CA45C4B92D349B ) ) game ( - name "QIX Adventure (Europe)" - description "QIX Adventure (Europe)" - rom ( name "QIX Adventure (Europe).gbc" size 1048576 crc D729DB40 md5 95B284DF7BA2F862406F747B4CA7C380 sha1 95406795E7E1CC5207ECCCAC57D6B77BD0C575A1 ) + name "Qix Adventure (Europe)" + description "Qix Adventure (Europe)" + rom ( name "Qix Adventure (Europe).gbc" size 1048576 crc d729db40 sha1 95406795E7E1CC5207ECCCAC57D6B77BD0C575A1 ) ) game ( - name "QIX Adventure (Japan)" - description "QIX Adventure (Japan)" - rom ( name "QIX Adventure (Japan).gbc" size 1048576 crc 5ACEA4A9 md5 1C3D719F529C1BF57B5B798FC1F3BFE5 sha1 363B284E18A303D1DD3C2AFFC967FCD6912594D8 ) + name "Qix Adventure (Japan)" + description "Qix Adventure (Japan)" + rom ( name "Qix Adventure (Japan).gbc" size 1048576 crc 5acea4a9 sha1 363B284E18A303D1DD3C2AFFC967FCD6912594D8 ) ) game ( - name "Quest - Fantasy Challenge (USA) (SGB Enhanced)" - description "Quest - Fantasy Challenge (USA) (SGB Enhanced)" - rom ( name "Quest - Fantasy Challenge (USA) (SGB Enhanced).gbc" size 1048576 crc 98285775 md5 9E857E7A438ACD2E8D9965F49DD21411 sha1 86812B2CD4304DC7EE2DD3FAF16737B0414AAFFB ) + name "Quest - Brian's Journey (USA) (GB Compatible)" + description "Quest - Brian's Journey (USA) (GB Compatible)" + rom ( name "Quest - Brian's Journey (USA) (GB Compatible).gbc" size 2097152 crc 9ac27645 sha1 DEEF2B6BA0C4E468B90E32AD28F62A32F56DB413 ) ) game ( - name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced)" - description "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced)" - rom ( name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced).gbc" size 1048576 crc CE55A4DE md5 81DD8A336E1B1B705235A7B20A536BC0 sha1 27B1839DEB7FBF384539B3686BA029CA54637196 flags verified ) + name "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible)" + description "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 98285775 sha1 86812B2CD4304DC7EE2DD3FAF16737B0414AAFFB ) ) game ( - name "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced)" - description "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced)" - rom ( name "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced).gbc" size 1048576 crc D903DB7D md5 3B26DFC4E7C55CF86F4A4F3C18344AC7 sha1 AAC9D4D1869FD1374EC7B7A9DE47575F7E5F54B6 ) + name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" + description "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible)" + rom ( name "Quest for Camelot (Europe) (En,Fr,De,Es,It,Nl) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ce55a4de sha1 27B1839DEB7FBF384539B3686BA029CA54637196 flags verified ) ) game ( - name "Quest RPG - Brian's Journey (USA)" - description "Quest RPG - Brian's Journey (USA)" - rom ( name "Quest RPG - Brian's Journey (USA).gbc" size 2097152 crc 9AC27645 md5 93FF3F6B4BFE0A138D8A8897899E8CB0 sha1 DEEF2B6BA0C4E468B90E32AD28F62A32F56DB413 ) + name "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced) (GB Compatible)" + description "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced) (GB Compatible)" + rom ( name "Quest for Camelot (USA) (En,Fr,Es) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d903db7d sha1 AAC9D4D1869FD1374EC7B7A9DE47575F7E5F54B6 flags verified ) ) game ( - name "Qui Qui (Japan)" - description "Qui Qui (Japan)" - rom ( name "Qui Qui (Japan).gbc" size 1048576 crc 56D76BA2 md5 F18339F4C836530BEA39086969D28964 sha1 5617CA94D3C909BEACCAD4702E52FFAAA0279ADD flags verified ) + name "Qui Qui (Japan) (GB Compatible)" + description "Qui Qui (Japan) (GB Compatible)" + rom ( name "Qui Qui (Japan) (GB Compatible).gbc" size 1048576 crc 56d76ba2 sha1 5617CA94D3C909BEACCAD4702E52FFAAA0279ADD flags verified ) ) game ( - name "R-Type DX (Japan)" - description "R-Type DX (Japan)" - rom ( name "R-Type DX (Japan).gbc" size 1048576 crc 3623EBB6 md5 F0568C53B8EC915DDA258955A531F37B sha1 73C6B524136EF7E5318F526561B99DD0488CF36E ) + name "R-Type DX (Japan) (En) (GB Compatible)" + description "R-Type DX (Japan) (En) (GB Compatible)" + rom ( name "R-Type DX (Japan) (En) (GB Compatible).gbc" size 1048576 crc 3623ebb6 sha1 73C6B524136EF7E5318F526561B99DD0488CF36E ) ) game ( - name "R-Type DX (USA, Europe)" - description "R-Type DX (USA, Europe)" - rom ( name "R-Type DX (USA, Europe).gbc" size 1048576 crc FC1D4089 md5 DAE7B7625D41D8A06266B09924154BB2 sha1 E6A5C632B616E520B10B8B7589207C87C0092047 flags verified ) + name "R-Type DX (USA, Europe) (GB Compatible)" + description "R-Type DX (USA, Europe) (GB Compatible)" + rom ( name "R-Type DX (USA, Europe) (GB Compatible).gbc" size 1048576 crc fc1d4089 sha1 E6A5C632B616E520B10B8B7589207C87C0092047 flags verified ) ) game ( name "Race Time (Europe) (Unl)" description "Race Time (Europe) (Unl)" - rom ( name "Race Time (Europe) (Unl).gbc" size 262144 crc 599C867D md5 99C7758531A1E79A1988F0D6BA26D3D4 sha1 157F15E601DFB858630A53313B71E4ECD0BB13E1 flags verified ) + rom ( name "Race Time (Europe) (Unl).gbc" size 262144 crc 599c867d sha1 157F15E601DFB858630A53313B71E4ECD0BB13E1 flags verified ) +) + +game ( + name "Racin' Ratz (USA)" + description "Racin' Ratz (USA)" + rom ( name "Racin' Ratz (USA).gbc" size 1048576 crc d6881014 sha1 32C63BE36093DB84FB5FEC110AD5AF49BE78C4AF ) ) game ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto)" description "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto)" - rom ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto).gbc" size 2097152 crc 81E25D37 md5 3DD14683B58A36F62FF288C7E0EA918D sha1 F16AA29669B15153A63AD92388768E38AA18FBF8 ) + rom ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto).gbc" size 2097152 crc 81e25d37 sha1 F16AA29669B15153A63AD92388768E38AA18FBF8 ) ) game ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It)" description "Rainbow Islands (Europe) (En,Fr,De,Es,It)" - rom ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 6DECC6B3 md5 3C3F9F06B791DF796B55AC94F2188FF2 sha1 15DCF2F868686AEA28611DF69089E1929AC186F9 ) + rom ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 6decc6b3 sha1 15DCF2F868686AEA28611DF69089E1929AC186F9 ) ) game ( name "Raku x Raku - Cut Shuu (Japan)" description "Raku x Raku - Cut Shuu (Japan)" - rom ( name "Raku x Raku - Cut Shuu (Japan).gbc" size 2097152 crc 430CFCF3 md5 62443F663965BA2F3A4181CD694D88A3 sha1 B51A62358C37539021BC980C1699825596B118EF ) + rom ( name "Raku x Raku - Cut Shuu (Japan).gbc" size 2097152 crc 430cfcf3 sha1 B51A62358C37539021BC980C1699825596B118EF flags verified ) ) game ( - name "Raku x Raku - Mishin (Japan)" - description "Raku x Raku - Mishin (Japan)" - rom ( name "Raku x Raku - Mishin (Japan).gbc" size 1048576 crc 0BA0711B md5 24CF64CD73A98125FE476B8488054361 sha1 58BF5DF55D2BAB8877F7EC43110339EBE1A5D4C5 ) + name "Raku x Raku - Mishin (Japan) (GB Compatible)" + description "Raku x Raku - Mishin (Japan) (GB Compatible)" + rom ( name "Raku x Raku - Mishin (Japan) (GB Compatible).gbc" size 1048576 crc 0ba0711b sha1 58BF5DF55D2BAB8877F7EC43110339EBE1A5D4C5 flags verified ) ) game ( name "Raku x Raku - Moji (Japan)" description "Raku x Raku - Moji (Japan)" - rom ( name "Raku x Raku - Moji (Japan).gbc" size 2097152 crc ABE58A8B md5 B39C09E1A033F08D8160BF5DFA4082BC sha1 D9502543C6CD05C7E06A3B89286EEC155AFF83A0 ) + rom ( name "Raku x Raku - Moji (Japan).gbc" size 2097152 crc abe58a8b sha1 D9502543C6CD05C7E06A3B89286EEC155AFF83A0 flags verified ) ) game ( - name "Rampage - World Tour (USA, Europe)" - description "Rampage - World Tour (USA, Europe)" - rom ( name "Rampage - World Tour (USA, Europe).gbc" size 524288 crc B029017F md5 F0BFBDED7125DD312EAF36D16C1556A1 sha1 5064F76557CE4235C8D1D4DA7BAC94E3AF352126 flags verified ) + name "Rampage - World Tour (USA, Europe) (GB Compatible)" + description "Rampage - World Tour (USA, Europe) (GB Compatible)" + rom ( name "Rampage - World Tour (USA, Europe) (GB Compatible).gbc" size 524288 crc b029017f sha1 5064F76557CE4235C8D1D4DA7BAC94E3AF352126 flags verified ) ) game ( name "Rampage 2 - Universal Tour (USA, Europe)" description "Rampage 2 - Universal Tour (USA, Europe)" - rom ( name "Rampage 2 - Universal Tour (USA, Europe).gbc" size 1048576 crc 20B86F1E md5 617DCFAC99F28045B8F4C46B9D75B58E sha1 4F6F14588E385357206F52E2C74B07B44D16F78F flags verified ) + rom ( name "Rampage 2 - Universal Tour (USA, Europe).gbc" size 1048576 crc 20b86f1e sha1 4F6F14588E385357206F52E2C74B07B44D16F78F flags verified ) ) game ( name "Rampart (USA)" description "Rampart (USA)" - rom ( name "Rampart (USA).gbc" size 1048576 crc D5AEED2E md5 2ACEFE79C9813460F0CC80C45D73D0FF sha1 40CEF7A1AF53D2DA5CD7B9D7927F1F64399E69DC ) + rom ( name "Rampart (USA).gbc" size 1048576 crc d5aeed2e sha1 40CEF7A1AF53D2DA5CD7B9D7927F1F64399E69DC ) ) game ( - name "Rats! (USA) (En,Es)" - description "Rats! (USA) (En,Es)" - rom ( name "Rats! (USA) (En,Es).gbc" size 524288 crc 17635AD1 md5 D240328FAACF5583804A30B7003743B3 sha1 5E423DFAB8221B69A641D2E535EBFE1E3759A2E4 ) + name "Rats! (USA) (En,Es) (GB Compatible)" + description "Rats! (USA) (En,Es) (GB Compatible)" + rom ( name "Rats! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc 17635ad1 sha1 5E423DFAB8221B69A641D2E535EBFE1E3759A2E4 ) ) game ( name "Rayman (Europe) (En,Fr,De,Es,It,Nl)" description "Rayman (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Rayman (Europe) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc C430A89A md5 EA9F362F629124C9423A8D9BA933ECED sha1 2E2D674426F2D29195A4BFBD82DCA4C25416E475 flags verified ) + rom ( name "Rayman (Europe) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc c430a89a sha1 2E2D674426F2D29195A4BFBD82DCA4C25416E475 flags verified ) ) game ( name "Rayman (USA) (En,Fr,De,Es,It,Nl)" description "Rayman (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Rayman (USA) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc EDA12F0D md5 B941941050FC32406ECA4733926A3779 sha1 5A6999C0CA4BE80A6259664FDFFBC79FD4BB1ED6 ) + rom ( name "Rayman (USA) (En,Fr,De,Es,It,Nl).gbc" size 4194304 crc eda12f0d sha1 5A6999C0CA4BE80A6259664FDFFBC79FD4BB1ED6 ) ) game ( name "Rayman - Mister Dark no Wana (Japan)" description "Rayman - Mister Dark no Wana (Japan)" - rom ( name "Rayman - Mister Dark no Wana (Japan).gbc" size 4194304 crc 3FDE5BAC md5 DF15CF120BA0DB664ADAB8D52F0E4D57 sha1 EF057156806DDDCC3D0CC5776843C639C6C3CAE4 ) + rom ( name "Rayman - Mister Dark no Wana (Japan).gbc" size 4194304 crc 3fde5bac sha1 EF057156806DDDCC3D0CC5776843C639C6C3CAE4 ) ) game ( - name "Rayman 2 - The Great Escape (Europe) (En,Fr,De,Es,It)" - description "Rayman 2 - The Great Escape (Europe) (En,Fr,De,Es,It)" - rom ( name "Rayman 2 - The Great Escape (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 250015D4 md5 31DDDE6B4C72261181E428AC99103304 sha1 5EA438C5B52696255E8DF74EB19E3CAC1427A14A ) + name "Rayman 2 (USA) (En,Fr,De,Es,It)" + description "Rayman 2 (USA) (En,Fr,De,Es,It)" + rom ( name "Rayman 2 (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 6f5c315d sha1 D984DEAF66933571404EB5BE754972D73EC7FBD5 flags verified ) ) game ( - name "Rayman 2 - The Great Escape (USA) (En,Fr,De,Es,It)" - description "Rayman 2 - The Great Escape (USA) (En,Fr,De,Es,It)" - rom ( name "Rayman 2 - The Great Escape (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 6F5C315D md5 FEB32471EA029A55D7BDEA7E0BDC6961 sha1 D984DEAF66933571404EB5BE754972D73EC7FBD5 ) + name "Rayman 2 Forever (Europe) (En,Fr,De,Es,It)" + description "Rayman 2 Forever (Europe) (En,Fr,De,Es,It)" + rom ( name "Rayman 2 Forever (Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 250015d4 sha1 5EA438C5B52696255E8DF74EB19E3CAC1427A14A ) ) game ( name "Razmoket a Paris, Les - Le Film (France)" description "Razmoket a Paris, Les - Le Film (France)" - rom ( name "Razmoket a Paris, Les - Le Film (France).gbc" size 1048576 crc 094494E9 md5 C569CDA6FF220773EC5FCE7EA38EF777 sha1 ED9EC61DE28DC1A83F0E98E8D651399CB45BD387 flags verified ) + rom ( name "Razmoket a Paris, Les - Le Film (France).gbc" size 1048576 crc 094494e9 sha1 ED9EC61DE28DC1A83F0E98E8D651399CB45BD387 flags verified ) ) game ( name "Razmoket, Les - 100% Angelica (France)" description "Razmoket, Les - 100% Angelica (France)" - rom ( name "Razmoket, Les - 100% Angelica (France).gbc" size 1048576 crc 1D66CB29 md5 30A34DD920FA9F3C62B47EC5384052F0 sha1 A04285AE27DEF1E0B808561099CC2CB86BA94F07 ) + rom ( name "Razmoket, Les - 100% Angelica (France).gbc" size 1048576 crc 1d66cb29 sha1 A04285AE27DEF1E0B808561099CC2CB86BA94F07 ) ) game ( name "Razmoket, Les - Voyage dans le Temps (France)" description "Razmoket, Les - Voyage dans le Temps (France)" - rom ( name "Razmoket, Les - Voyage dans le Temps (France).gbc" size 1048576 crc 2F8FEF3F md5 2425ABDECFA70713B2671299D6A45751 sha1 9587EB9C373399401BDD2208D22425999956733D ) + rom ( name "Razmoket, Les - Voyage dans le Temps (France).gbc" size 1048576 crc 2f8fef3f sha1 9587EB9C373399401BDD2208D22425999956733D ) ) game ( name "Razor Freestyle Scooter (USA)" description "Razor Freestyle Scooter (USA)" - rom ( name "Razor Freestyle Scooter (USA).gbc" size 1048576 crc 5C201286 md5 79F6386969A59D4974AECE5DC7ED1F3F sha1 9360AA3E7062399527686ED55B06FAEAA388178C ) + rom ( name "Razor Freestyle Scooter (USA).gbc" size 1048576 crc 5c201286 sha1 9360AA3E7062399527686ED55B06FAEAA388178C ) ) game ( name "Ready 2 Rumble Boxing (Europe)" description "Ready 2 Rumble Boxing (Europe)" - rom ( name "Ready 2 Rumble Boxing (Europe).gbc" size 2097152 crc BEA36BF9 md5 219538ABD16CECADEE98AB57C7069376 sha1 46DBA4B01CC71F07CEB6472064E0312CA70B31BD flags verified ) + rom ( name "Ready 2 Rumble Boxing (Europe).gbc" size 2097152 crc bea36bf9 sha1 46DBA4B01CC71F07CEB6472064E0312CA70B31BD flags verified ) ) game ( name "Ready 2 Rumble Boxing (USA) (Rumble Version)" description "Ready 2 Rumble Boxing (USA) (Rumble Version)" - rom ( name "Ready 2 Rumble Boxing (USA) (Rumble Version).gbc" size 2097152 crc 345E20A4 md5 D5961426B8EA089E2F74A91A747ACFDB sha1 30EA96BA1F4FFBE2546EAC86F57827138C5D676E flags verified ) + rom ( name "Ready 2 Rumble Boxing (USA) (Rumble Version).gbc" size 2097152 crc 345e20a4 sha1 30EA96BA1F4FFBE2546EAC86F57827138C5D676E flags verified ) ) game ( - name "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced)" - description "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced)" - rom ( name "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced).gbc" size 524288 crc AFFF6BB9 md5 1EBDCE25ED0E2607059D7D09530D4A7E sha1 02C18D98A07B3AF9A1D26D0C3003F8E75C81F4D9 ) + name "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Real Pro Yakyuu! - Central League Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc afff6bb9 sha1 02C18D98A07B3AF9A1D26D0C3003F8E75C81F4D9 flags verified ) ) game ( - name "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced)" - description "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced)" - rom ( name "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced).gbc" size 524288 crc 16B81C36 md5 CBB8140E3F755DBFF588E60DFF4A2D57 sha1 A7A2CD7BBB4CAE171B5F2C798293AFEFE2882AFC flags verified ) + name "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Real Pro Yakyuu! - Pacific League Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 16b81c36 sha1 A7A2CD7BBB4CAE171B5F2C798293AFEFE2882AFC flags verified ) ) game ( name "Rescue Heroes - Fire Frenzy (USA)" description "Rescue Heroes - Fire Frenzy (USA)" - rom ( name "Rescue Heroes - Fire Frenzy (USA).gbc" size 1048576 crc 77A4DC63 md5 45A7802B724DC5431847F60F3E78A302 sha1 A57AEB43EF88FFD09F5028368A3142C3E9F5E792 ) + rom ( name "Rescue Heroes - Fire Frenzy (USA).gbc" size 1048576 crc 77a4dc63 sha1 A57AEB43EF88FFD09F5028368A3142C3E9F5E792 ) ) game ( - name "Reservoir Rat (Europe) (En,Fr,De,Es,It)" - description "Reservoir Rat (Europe) (En,Fr,De,Es,It)" - rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gbc" size 524288 crc 22621803 md5 15B3CBE9A6FFD5B7C5047764798EA911 sha1 7EE86635F9D9735CC57673B08995BE7003FF6082 flags verified ) + name "Reservoir Rat (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Reservoir Rat (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 524288 crc 22621803 sha1 7EE86635F9D9735CC57673B08995BE7003FF6082 flags verified ) ) game ( - name "Resident Evil (Unknown) (Proto) (early)" - description "Resident Evil (Unknown) (Proto) (early)" - rom ( name "Resident Evil (Unknown) (Proto) (early).gbc" size 4194304 crc E6E722C8 md5 C3C3932D5471BC0028ADE1CD7A102D43 sha1 87F8B1BAD965BC9214CCD2932020163418A4E8F1 ) + name "Resident Evil (World) (Proto 1)" + description "Resident Evil (World) (Proto 1)" + rom ( name "Resident Evil (World) (Proto 1).gbc" size 4194304 crc e6e722c8 sha1 87F8B1BAD965BC9214CCD2932020163418A4E8F1 flags verified ) ) game ( - name "Resident Evil (Unknown) (Proto)" - description "Resident Evil (Unknown) (Proto)" - rom ( name "Resident Evil (Unknown) (Proto).gbc" size 4194304 crc 53F7BBA1 md5 FD91D5D69C43F2F0406B3626D625B6E6 sha1 BDA5A658631A5714E761EE1805BAAA0008EE8CDF ) + name "Resident Evil (World) (Proto 2)" + description "Resident Evil (World) (Proto 2)" + rom ( name "Resident Evil (World) (Proto 2).gbc" size 4194304 crc 53f7bba1 sha1 BDA5A658631A5714E761EE1805BAAA0008EE8CDF flags verified ) +) + +game ( + name "Resident Evil (Unknown) (Demo) (Climax Entertainment)" + description "Resident Evil (Unknown) (Demo) (Climax Entertainment)" + rom ( name "Resident Evil (Unknown) (Demo) (Climax Entertainment).gbc" size 524288 crc 1a921065 sha1 BEC002E2D9E7852CD85B720B570F4AE73453B756 flags verified ) ) game ( name "Resident Evil Gaiden (Europe) (En,Fr,De,Es,It)" description "Resident Evil Gaiden (Europe) (En,Fr,De,Es,It)" - rom ( name "Resident Evil Gaiden (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc F85C3F2C md5 8A7F483857E251D56A16594CA84D1A7E sha1 2116120A930BD93D5E32CC588ACADB559B0D65E8 flags verified ) + rom ( name "Resident Evil Gaiden (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc f85c3f2c sha1 2116120A930BD93D5E32CC588ACADB559B0D65E8 flags verified ) ) game ( name "Resident Evil Gaiden (USA)" description "Resident Evil Gaiden (USA)" - rom ( name "Resident Evil Gaiden (USA).gbc" size 2097152 crc F8C5021B md5 3C0C5FCEEBFF4D9730875A9362D26AA1 sha1 A302CDDC085D65CA778153E2A591BD648CE963C9 ) + rom ( name "Resident Evil Gaiden (USA).gbc" size 2097152 crc f8c5021b sha1 A302CDDC085D65CA778153E2A591BD648CE963C9 ) ) game ( name "Return of the Ninja (Europe)" description "Return of the Ninja (Europe)" - rom ( name "Return of the Ninja (Europe).gbc" size 1048576 crc 8E04849A md5 9C1CB86CCCB4FA2BBC6137A81D92A3B1 sha1 E49CE291A1DA791955A5DE8C894ACA28FFC97F9B flags verified ) + rom ( name "Return of the Ninja (Europe).gbc" size 1048576 crc 8e04849a sha1 E49CE291A1DA791955A5DE8C894ACA28FFC97F9B flags verified ) ) game ( name "Return of the Ninja (USA)" description "Return of the Ninja (USA)" - rom ( name "Return of the Ninja (USA).gbc" size 1048576 crc A07DA702 md5 178EA5A9EBA6E7F35E894BAD1EC34F77 sha1 E33352F0AC19D28983EBED0758D022861473EC0E ) + rom ( name "Return of the Ninja (USA).gbc" size 1048576 crc a07da702 sha1 E33352F0AC19D28983EBED0758D022861473EC0E ) ) game ( - name "Revelations - The Demon Slayer (USA) (SGB Enhanced)" - description "Revelations - The Demon Slayer (USA) (SGB Enhanced)" - rom ( name "Revelations - The Demon Slayer (USA) (SGB Enhanced).gbc" size 1048576 crc D1A65D74 md5 86ED74283FE0071F8D3F05923051EFAB sha1 BD684074944CCC02B5F997E7AB95D0B03327773D flags verified ) + name "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" + description "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d1a65d74 sha1 BD684074944CCC02B5F997E7AB95D0B03327773D flags verified ) ) game ( name "Rhino Rumble (USA, Europe)" description "Rhino Rumble (USA, Europe)" - rom ( name "Rhino Rumble (USA, Europe).gbc" size 1048576 crc 73160E05 md5 CED299D2952AE83C7BBFBB64767E4634 sha1 2CAF47C20D8632E47C4426DD3564E76415139973 flags verified ) + rom ( name "Rhino Rumble (USA, Europe).gbc" size 1048576 crc 73160e05 sha1 2CAF47C20D8632E47C4426DD3564E76415139973 flags verified ) ) game ( - name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It)" - description "Rip-Tide Racer (Europe) (En,Fr,De,Es,It)" - rom ( name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc AB8C3A31 md5 5CFEB93B86FBFE59D7C59E904DE3BB88 sha1 3354D6E79B8094BBAA4EF48EB8BD2B0774C46E1A flags verified ) + name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Rip-Tide Racer (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc ab8c3a31 sha1 3354D6E79B8094BBAA4EF48EB8BD2B0774C46E1A flags verified ) ) game ( name "Road Champs - BXS Stunt Biking (USA, Europe)" description "Road Champs - BXS Stunt Biking (USA, Europe)" - rom ( name "Road Champs - BXS Stunt Biking (USA, Europe).gbc" size 1048576 crc 98C59706 md5 618BE0636A482B1C5E5898E7CB5F1BB3 sha1 15134178346C5209197F4847D7DE5EF86BE36B85 flags verified ) + rom ( name "Road Champs - BXS Stunt Biking (USA, Europe).gbc" size 1048576 crc 98c59706 sha1 15134178346C5209197F4847D7DE5EF86BE36B85 flags verified ) ) game ( name "Road Rash (USA, Europe)" description "Road Rash (USA, Europe)" - rom ( name "Road Rash (USA, Europe).gbc" size 1048576 crc 11025EEB md5 F5767F97F44365B703EAE78AFB7562E6 sha1 B3329C0F92C1A6A6CFA894F487F68A7FCCEB5844 flags verified ) + rom ( name "Road Rash (USA, Europe).gbc" size 1048576 crc 11025eeb sha1 B3329C0F92C1A6A6CFA894F487F68A7FCCEB5844 flags verified ) ) game ( - name "Roadsters '98 (USA) (Proto) (SGB Enhanced)" - description "Roadsters '98 (USA) (Proto) (SGB Enhanced)" - rom ( name "Roadsters '98 (USA) (Proto) (SGB Enhanced).gbc" size 131072 crc FE2995A1 md5 DF12FD885C09702EF5F02BFD2A5E1EC3 sha1 30A28CD5E020E98B0E7016B5CCDA5BC0972A0AC9 ) + name "Roadsters (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Roadsters (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Roadsters (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 717b3525 sha1 3C0A54FBA91A6DF88C152A824D192E05C0A68250 ) ) game ( - name "Roadsters Trophy (Europe) (En,Fr,De,Es,It,Nl)" - description "Roadsters Trophy (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Roadsters Trophy (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 717B3525 md5 EC6D8099AA51ACC791E3846558C81EBB sha1 3C0A54FBA91A6DF88C152A824D192E05C0A68250 ) + name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 38b022be sha1 EDE737E99108BE29DAF94FEE8E10F5DD770731BB ) ) game ( - name "Roadsters Trophy (USA) (En,Fr,De,Es,It,Nl)" - description "Roadsters Trophy (USA) (En,Fr,De,Es,It,Nl)" - rom ( name "Roadsters Trophy (USA) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 38B022BE md5 79B84A54581CA90B245619522C09E523 sha1 EDE737E99108BE29DAF94FEE8E10F5DD770731BB ) + name "Roadsters '98 (USA) (Proto) (SGB Enhanced) (GB Compatible)" + description "Roadsters '98 (USA) (Proto) (SGB Enhanced) (GB Compatible)" + rom ( name "Roadsters '98 (USA) (Proto) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc fe2995a1 sha1 30A28CD5E020E98B0E7016B5CCDA5BC0972A0AC9 ) ) game ( name "Robin Hood (Europe) (En,Fr,De,Es,It,Nl)" description "Robin Hood (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Robin Hood (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc D4F84329 md5 A94939498326BEAEC405D3947A7CE2DF sha1 FE0C42E949BC41F070B22DD24E643AA42B007667 ) + rom ( name "Robin Hood (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc d4f84329 sha1 FE0C42E949BC41F070B22DD24E643AA42B007667 ) ) game ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" description "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 6C6423E2 md5 B734829913E6D58E678441DE37DBF88A sha1 FBAC3BDC8ED40C0F752EC711C4CC82262358F9BD ) + rom ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 6c6423e2 sha1 FBAC3BDC8ED40C0F752EC711C4CC82262358F9BD ) ) game ( - name "Robopon - Sun Version (USA) (SGB Enhanced)" - description "Robopon - Sun Version (USA) (SGB Enhanced)" - rom ( name "Robopon - Sun Version (USA) (SGB Enhanced).gbc" size 1048576 crc 32CAEF11 md5 398F7B60EA114B90B24503178F47E8D8 sha1 399C928A38A3901B7A1093BD61F5A4D8C05B9771 ) + name "Robopon - Sun Version (USA) (SGB Enhanced) (GB Compatible)" + description "Robopon - Sun Version (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Robopon - Sun Version (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 32caef11 sha1 399C928A38A3901B7A1093BD61F5A4D8C05B9771 flags verified ) ) game ( - name "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced)" - description "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced)" - rom ( name "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced).gbc" size 1048576 crc 4AA209CD md5 52C823C2C7FDDCFD77768DAF42082980 sha1 79D1EDA07E792497506FF1494E5222DB2A52702F flags verified ) + name "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Robot Poncots - Comic Bom Bom Special Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4aa209cd sha1 79D1EDA07E792497506FF1494E5222DB2A52702F flags verified ) ) game ( - name "Robot Poncots - Moon Version (Japan) (SGB Enhanced)" - description "Robot Poncots - Moon Version (Japan) (SGB Enhanced)" - rom ( name "Robot Poncots - Moon Version (Japan) (SGB Enhanced).gbc" size 1048576 crc 87A29030 md5 BA0DEBF5E0CDA9ADFA409DAB91ABB6A9 sha1 7D6424BFECFEB17AEE9F779DCB9BAC47114730CD flags verified ) + name "Robot Poncots - Moon Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Robot Poncots - Moon Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Robot Poncots - Moon Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 87a29030 sha1 7D6424BFECFEB17AEE9F779DCB9BAC47114730CD flags verified ) ) game ( - name "Robot Poncots - Star Version (Japan) (SGB Enhanced)" - description "Robot Poncots - Star Version (Japan) (SGB Enhanced)" - rom ( name "Robot Poncots - Star Version (Japan) (SGB Enhanced).gbc" size 1048576 crc B28F32AC md5 9BDC654FC8ACB425FE4B68269928FBFB sha1 27A96410B38E695D9B80AE861AF3B472F0E84C60 flags verified ) + name "Robot Poncots - Star Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Robot Poncots - Star Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Robot Poncots - Star Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b28f32ac sha1 27A96410B38E695D9B80AE861AF3B472F0E84C60 flags verified ) ) game ( - name "Robot Poncots - Sun Version (Japan) (SGB Enhanced)" - description "Robot Poncots - Sun Version (Japan) (SGB Enhanced)" - rom ( name "Robot Poncots - Sun Version (Japan) (SGB Enhanced).gbc" size 1048576 crc CB0B8003 md5 88EE129F5F61078D8649E2134B2E78A3 sha1 2F82DD4A1537111D14F11EB13C7CE6FC748E83FE flags verified ) + name "Robot Poncots - Sun Version (Japan) (SGB Enhanced) (GB Compatible)" + description "Robot Poncots - Sun Version (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Robot Poncots - Sun Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc cb0b8003 sha1 2F82DD4A1537111D14F11EB13C7CE6FC748E83FE flags verified ) ) game ( name "Robot Wars - Metal Mayhem (Europe) (En,Fr,De,It,Nl,Sv)" description "Robot Wars - Metal Mayhem (Europe) (En,Fr,De,It,Nl,Sv)" - rom ( name "Robot Wars - Metal Mayhem (Europe) (En,Fr,De,It,Nl,Sv).gbc" size 1048576 crc E99BDEE6 md5 AF4565BF1EA33C785FC9E05BE2A9BAD0 sha1 745A6D813BA561B53379A718312E7E8B6730C15F flags verified ) + rom ( name "Robot Wars - Metal Mayhem (Europe) (En,Fr,De,It,Nl,Sv).gbc" size 1048576 crc e99bdee6 sha1 745A6D813BA561B53379A718312E7E8B6730C15F flags verified ) ) game ( name "Rocket Power - Gettin' Air (USA, Europe)" description "Rocket Power - Gettin' Air (USA, Europe)" - rom ( name "Rocket Power - Gettin' Air (USA, Europe).gbc" size 1048576 crc 7025EB63 md5 B3BD4ADC4613FF8F4B9CF8C80FF0A6EF sha1 D9C5C22F1F5A2A922CB2B39D5E8F3DF31C1155D7 flags verified ) + rom ( name "Rocket Power - Gettin' Air (USA, Europe).gbc" size 1048576 crc 7025eb63 sha1 D9C5C22F1F5A2A922CB2B39D5E8F3DF31C1155D7 flags verified ) ) game ( name "Rocket Power - La Glisse de l'Extreme (France)" description "Rocket Power - La Glisse de l'Extreme (France)" - rom ( name "Rocket Power - La Glisse de l'Extreme (France).gbc" size 1048576 crc C9A7AA7B md5 CF9ED892228E2C7DDEE857758EA372A9 sha1 B6B9B7B2FB2FF11D41C6531FE21BFD5AA89F7AB4 ) + rom ( name "Rocket Power - La Glisse de l'Extreme (France).gbc" size 1048576 crc c9a7aa7b sha1 B6B9B7B2FB2FF11D41C6531FE21BFD5AA89F7AB4 ) ) game ( - name "Rockman X - Cyber Mission (Japan)" - description "Rockman X - Cyber Mission (Japan)" - rom ( name "Rockman X - Cyber Mission (Japan).gbc" size 1048576 crc 919077AB md5 EBB19FE17FD6D13D9D52239E8DA9711A sha1 C47D50814489B7426CE110D35D1C059D0C24AF21 ) + name "Rockman X - Cyber Mission (Japan) (GB Compatible)" + description "Rockman X - Cyber Mission (Japan) (GB Compatible)" + rom ( name "Rockman X - Cyber Mission (Japan) (GB Compatible).gbc" size 1048576 crc 919077ab sha1 C47D50814489B7426CE110D35D1C059D0C24AF21 flags verified ) ) game ( name "Rockman X2 - Soul Eraser (Japan)" description "Rockman X2 - Soul Eraser (Japan)" - rom ( name "Rockman X2 - Soul Eraser (Japan).gbc" size 1048576 crc 17913DD0 md5 83F735D3357A32576516F6E20B5B7F19 sha1 B7308301706C5414BB75F33232042124D9A608F1 ) + rom ( name "Rockman X2 - Soul Eraser (Japan).gbc" size 1048576 crc 17913dd0 sha1 B7308301706C5414BB75F33232042124D9A608F1 ) ) game ( name "Rocky Mountain Trophy Hunter (USA)" description "Rocky Mountain Trophy Hunter (USA)" - rom ( name "Rocky Mountain Trophy Hunter (USA).gbc" size 1048576 crc 9AA5B021 md5 B290F995CEC5958D396055C6C0FF8A3B sha1 864BBF4437EA1210E9E3012B290659AF765C87B4 ) + rom ( name "Rocky Mountain Trophy Hunter (USA).gbc" size 1048576 crc 9aa5b021 sha1 864BBF4437EA1210E9E3012B290659AF765C87B4 ) ) game ( name "Rocman X Gold + 4 in 1 (Taiwan) (1B-002, 4B-003, Sachen) (Unl)" description "Rocman X Gold + 4 in 1 (Taiwan) (1B-002, 4B-003, Sachen) (Unl)" - rom ( name "Rocman X Gold + 4 in 1 (Taiwan) (1B-002, 4B-003, Sachen) (Unl).gbc" size 524288 crc 7E1351CF md5 358B42454A4ACB2755834052FE85FC27 sha1 7E62472C13B5A6A933AA93DC5B239F11A664F337 ) + rom ( name "Rocman X Gold + 4 in 1 (Taiwan) (1B-002, 4B-003, Sachen) (Unl).gbc" size 524288 crc 7e1351cf sha1 7E62472C13B5A6A933AA93DC5B239F11A664F337 flags verified ) ) game ( - name "Roi Lion, Le - Les Adventures de Simba (France)" - description "Roi Lion, Le - Les Adventures de Simba (France)" - rom ( name "Roi Lion, Le - Les Adventures de Simba (France).gbc" size 1048576 crc 6467FBA0 md5 FC2629620C6A8B67550DF2773333788D sha1 A0BEF7DF1BA3D75E7958763F0CEC9C76428415DF ) + name "Roi Lion, Le - La Formidable Aventure de Simba (France)" + description "Roi Lion, Le - La Formidable Aventure de Simba (France)" + rom ( name "Roi Lion, Le - La Formidable Aventure de Simba (France).gbc" size 1048576 crc 6467fba0 sha1 A0BEF7DF1BA3D75E7958763F0CEC9C76428415DF ) +) + +game ( + name "Roi Lion, Le - La Formidable Aventure de Simba (France) (Rev 1)" + description "Roi Lion, Le - La Formidable Aventure de Simba (France) (Rev 1)" + rom ( name "Roi Lion, Le - La Formidable Aventure de Simba (France) (Rev 1).gbc" size 1048576 crc c7aae1b3 sha1 B8CC2F1D3A8D40C7588D5C535F28E2F80446A793 flags verified ) ) game ( name "Rokumon Tengai Mon-Colle-Knight GB (Japan)" description "Rokumon Tengai Mon-Colle-Knight GB (Japan)" - rom ( name "Rokumon Tengai Mon-Colle-Knight GB (Japan).gbc" size 2097152 crc E48ADF8D md5 3857F9105094B5423F3D230E630DF8DE sha1 AB0A9630C16407549DA28FF47AC4DA33579975E4 ) + rom ( name "Rokumon Tengai Mon-Colle-Knight GB (Japan).gbc" size 2097152 crc e48adf8d sha1 AB0A9630C16407549DA28FF47AC4DA33579975E4 ) ) game ( name "Roland Garros French Open (Europe) (En,Fr,De,Es,It,Nl)" description "Roland Garros French Open (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Roland Garros French Open (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 10DBDE7C md5 70E3AB7EF2061E7075D81AEDE74EA95C sha1 86AB2D43E62F8A765992BDEBE38B41A8D95EF5CB flags verified ) + rom ( name "Roland Garros French Open (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 10dbde7c sha1 86AB2D43E62F8A765992BDEBE38B41A8D95EF5CB flags verified ) ) game ( - name "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt)" - description "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt)" - rom ( name "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt).gbc" size 1048576 crc A856C066 md5 0EB0F4252FF90CB26EDA0BE680C998BC sha1 33350360394904A03C069261CC53AB1381F326B7 ) + name "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt) (GB Compatible)" + description "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt) (GB Compatible)" + rom ( name "Ronaldo V-Football (Europe) (En,Fr,De,Es,It,Nl,Pt) (GB Compatible).gbc" size 1048576 crc a856c066 sha1 33350360394904A03C069261CC53AB1381F326B7 flags verified ) ) game ( - name "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt)" - description "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt)" - rom ( name "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt).gbc" size 1048576 crc D0204F10 md5 79E619A79BE12B6AC59AE6D4602FFA5E sha1 4558565434FB3527178A183D6C4C4FB1A132E3D2 ) + name "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt) (GB Compatible)" + description "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt) (GB Compatible)" + rom ( name "Ronaldo V-Soccer (USA) (En,Fr,Es,Pt) (GB Compatible).gbc" size 1048576 crc d0204f10 sha1 4558565434FB3527178A183D6C4C4FB1A132E3D2 ) ) game ( name "Roswell Conspiracies - Aliens, Myths & Legends (Europe) (En,Fr,De)" description "Roswell Conspiracies - Aliens, Myths & Legends (Europe) (En,Fr,De)" - rom ( name "Roswell Conspiracies - Aliens, Myths & Legends (Europe) (En,Fr,De).gbc" size 1048576 crc 49101556 md5 79D382D378D49695E9867EDE063EFF17 sha1 9E0A431D3B9D046CC9E2339624631F756E2BC68E flags verified ) + rom ( name "Roswell Conspiracies - Aliens, Myths & Legends (Europe) (En,Fr,De).gbc" size 1048576 crc 49101556 sha1 9E0A431D3B9D046CC9E2339624631F756E2BC68E flags verified ) ) game ( name "Roswell Conspiracies - Aliens, Myths & Legends (USA) (En,Fr,De)" description "Roswell Conspiracies - Aliens, Myths & Legends (USA) (En,Fr,De)" - rom ( name "Roswell Conspiracies - Aliens, Myths & Legends (USA) (En,Fr,De).gbc" size 1048576 crc 1F5EC131 md5 DBD7BC8A47D78E84016F0C240E6AA179 sha1 EC27E608B2787DC18184BE7A5A713A1D88403AFD ) + rom ( name "Roswell Conspiracies - Aliens, Myths & Legends (USA) (En,Fr,De).gbc" size 1048576 crc 1f5ec131 sha1 EC27E608B2787DC18184BE7A5A713A1D88403AFD ) ) game ( - name "Rox (Japan)" - description "Rox (Japan)" - rom ( name "Rox (Japan).gbc" size 262144 crc 4BD73D99 md5 D5CDE4A6F4877A71B06278A4802C7CCE sha1 196EFF1C40B3DC552E6FAC9E16CC0F5F0E293434 ) + name "Rox (Japan) (En) (GB Compatible)" + description "Rox (Japan) (En) (GB Compatible)" + rom ( name "Rox (Japan) (En) (GB Compatible).gbc" size 262144 crc 4bd73d99 sha1 196EFF1C40B3DC552E6FAC9E16CC0F5F0E293434 ) ) game ( - name "Rox (USA, Europe)" - description "Rox (USA, Europe)" - rom ( name "Rox (USA, Europe).gbc" size 262144 crc 2E944775 md5 C4CD1E337BB76AD0F7307F5CFA1EF6BC sha1 86CB1F29E5D061431978D6DC48D7278B9C290CDA flags verified ) + name "Rox (USA, Europe) (GB Compatible)" + description "Rox (USA, Europe) (GB Compatible)" + rom ( name "Rox (USA, Europe) (GB Compatible).gbc" size 262144 crc 2e944775 sha1 86CB1F29E5D061431978D6DC48D7278B9C290CDA flags verified ) ) game ( name "RPG Tsukuru GB (Japan)" description "RPG Tsukuru GB (Japan)" - rom ( name "RPG Tsukuru GB (Japan).gbc" size 2097152 crc 0B614307 md5 AC3DFC02635524FBB01DCACD2DB3D066 sha1 119A0AB3D82FABBAFF5949DACD6B77E20C7A8FB0 flags verified ) + rom ( name "RPG Tsukuru GB (Japan).gbc" size 2097152 crc 0b614307 sha1 119A0AB3D82FABBAFF5949DACD6B77E20C7A8FB0 flags verified ) ) game ( - name "Rugrats - Time Travelers (USA, Europe)" - description "Rugrats - Time Travelers (USA, Europe)" - rom ( name "Rugrats - Time Travelers (USA, Europe).gbc" size 1048576 crc 9C743F03 md5 069B01643E876EC91A5555450068F4AC sha1 680B38692F9CBD1E9E37CCFE45C5F65817164EC2 flags verified ) + name "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" + description "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" + rom ( name "Rugrats - Time Travelers (USA, Europe) (GB Compatible).gbc" size 1048576 crc 9c743f03 sha1 680B38692F9CBD1E9E37CCFE45C5F65817164EC2 flags verified ) ) game ( name "Rugrats - Totally Angelica (USA, Europe)" description "Rugrats - Totally Angelica (USA, Europe)" - rom ( name "Rugrats - Totally Angelica (USA, Europe).gbc" size 1048576 crc FC6195EF md5 80CF4B05B2A0388A804E54F433CDD126 sha1 D4396A974AEE16F74A5A80F4845C24DDE5A083D6 flags verified ) + rom ( name "Rugrats - Totally Angelica (USA, Europe).gbc" size 1048576 crc fc6195ef sha1 D4396A974AEE16F74A5A80F4845C24DDE5A083D6 flags verified ) ) game ( name "Rugrats - Typisch Angelica (Germany)" description "Rugrats - Typisch Angelica (Germany)" - rom ( name "Rugrats - Typisch Angelica (Germany).gbc" size 1048576 crc 026C4794 md5 B7D7A761D1666D4CF9832435C49EB14A sha1 A00F5EAC5E6D50CF38BC3114A9D0D30A02D93E7C flags verified ) + rom ( name "Rugrats - Typisch Angelica (Germany).gbc" size 1048576 crc 026c4794 sha1 A00F5EAC5E6D50CF38BC3114A9D0D30A02D93E7C flags verified ) ) game ( - name "Rugrats in Paris - The Movie (Europe) (En,Es)" - description "Rugrats in Paris - The Movie (Europe) (En,Es)" - rom ( name "Rugrats in Paris - The Movie (Europe) (En,Es).gbc" size 1048576 crc 35323432 md5 54DD12EF93FAD931DF26CDF67AD4677A sha1 5AA140068F3460F027F155566534B19500AD30E9 ) + name "Rugrats en Paris - La pelicula (Spain) (En,Es)" + description "Rugrats en Paris - La pelicula (Spain) (En,Es)" + rom ( name "Rugrats en Paris - La pelicula (Spain) (En,Es).gbc" size 1048576 crc 35323432 sha1 5AA140068F3460F027F155566534B19500AD30E9 flags verified ) ) game ( name "Rugrats in Paris - The Movie (USA, Europe)" description "Rugrats in Paris - The Movie (USA, Europe)" - rom ( name "Rugrats in Paris - The Movie (USA, Europe).gbc" size 1048576 crc 8B195237 md5 C1DEE0A8036D61D1483A793126DA3B45 sha1 F4CDC771299E9E6539443A9C9D62D3842877E618 flags verified ) + rom ( name "Rugrats in Paris - The Movie (USA, Europe).gbc" size 1048576 crc 8b195237 sha1 F4CDC771299E9E6539443A9C9D62D3842877E618 flags verified ) ) game ( - name "Rugrats Movie, The (Europe) (SGB Enhanced)" - description "Rugrats Movie, The (Europe) (SGB Enhanced)" - rom ( name "Rugrats Movie, The (Europe) (SGB Enhanced).gbc" size 1048576 crc B4091600 md5 BF5C2F39B42212B8AF8776B12F31D466 sha1 29953D2D41FCB6BA4A78853A328DD01A6918EF8F flags verified ) + name "Rugrats Movie, The (Europe) (SGB Enhanced) (GB Compatible)" + description "Rugrats Movie, The (Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Rugrats Movie, The (Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b4091600 sha1 29953D2D41FCB6BA4A78853A328DD01A6918EF8F flags verified ) ) game ( - name "Rugrats Movie, The (USA) (SGB Enhanced)" - description "Rugrats Movie, The (USA) (SGB Enhanced)" - serial "DMG-ARQE-USA" - rom ( name "Rugrats Movie, The (USA) (SGB Enhanced).gbc" size 1048576 crc FEBE2606 md5 1383DA42B08BF94B6FAD381CADA66FAD sha1 C64DDF11C12D34F13D86E4A468B1EEDACB698081 ) + name "Rugrats Movie, The (USA) (SGB Enhanced) (GB Compatible)" + description "Rugrats Movie, The (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Rugrats Movie, The (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc febe2606 sha1 C64DDF11C12D34F13D86E4A468B1EEDACB698081 flags verified ) +) + +game ( + name "Rumble & Tumble (USA) (Demo) (E3 2001)" + description "Rumble & Tumble (USA) (Demo) (E3 2001)" + rom ( name "Rumble & Tumble (USA) (Demo) (E3 2001).gbc" size 131072 crc 4400496d sha1 2429581D154AC04A12C99A24C2FD2C1B45A90807 flags verified ) +) + +game ( + name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" + description "Saban's Power Rangers - Lightspeed Rescue (USA, Europe)" + rom ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe).gbc" size 1048576 crc 99869172 sha1 E7D0F2F21CDCDA49516F682092D0B2017E82D379 flags verified ) +) + +game ( + name "Saban's Power Rangers - Time Force (USA, Europe)" + description "Saban's Power Rangers - Time Force (USA, Europe)" + rom ( name "Saban's Power Rangers - Time Force (USA, Europe).gbc" size 1048576 crc 17e51443 sha1 9C383013C5EC0E1F2C33B95D66CD93A3D0743928 flags verified ) ) game ( name "Sabrina - The Animated Series - Spooked! (USA, Europe)" description "Sabrina - The Animated Series - Spooked! (USA, Europe)" - rom ( name "Sabrina - The Animated Series - Spooked! (USA, Europe).gbc" size 1048576 crc 2CF48188 md5 3073432455A395835DE6147399B36CFC sha1 7A219159EF46C5EF88EB6B478667C2EC80194EDC flags verified ) + rom ( name "Sabrina - The Animated Series - Spooked! (USA, Europe).gbc" size 1048576 crc 2cf48188 sha1 7A219159EF46C5EF88EB6B478667C2EC80194EDC flags verified ) ) game ( name "Sabrina - The Animated Series - Zapped! (Europe) (En,Fr,De)" description "Sabrina - The Animated Series - Zapped! (Europe) (En,Fr,De)" - rom ( name "Sabrina - The Animated Series - Zapped! (Europe) (En,Fr,De).gbc" size 2097152 crc 818F3AF6 md5 CB689DC8D4E95FE9D190F6F5AD1D0ED4 sha1 D2E207A07FFA7CD0CC5B168C95AD409CD3DF3FA3 flags verified ) + rom ( name "Sabrina - The Animated Series - Zapped! (Europe) (En,Fr,De).gbc" size 2097152 crc 818f3af6 sha1 D2E207A07FFA7CD0CC5B168C95AD409CD3DF3FA3 flags verified ) ) game ( name "Sabrina - The Animated Series - Zapped! (USA, Europe)" description "Sabrina - The Animated Series - Zapped! (USA, Europe)" - rom ( name "Sabrina - The Animated Series - Zapped! (USA, Europe).gbc" size 2097152 crc 5D39A9B0 md5 EC39462E39E3CBCABE03667FABF12D5A sha1 099E2EC855F47344F5D188CC57F540C88CDB33FD flags verified ) + rom ( name "Sabrina - The Animated Series - Zapped! (USA, Europe).gbc" size 2097152 crc 5d39a9b0 sha1 099E2EC855F47344F5D188CC57F540C88CDB33FD flags verified ) ) game ( - name "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced)" - description "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced)" - rom ( name "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced).gbc" size 1048576 crc B5412C6F md5 EEB8A7311A959035E8A3C3822329EA48 sha1 F2330533B10C22E98C140BB550827618985253CB flags verified ) + name "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible)" + description "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sakata Gorou Kudan no Renju Kyoushitsu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc b5412c6f sha1 F2330533B10C22E98C140BB550827618985253CB flags verified ) ) game ( name "Sakura Taisen GB - Geki Hana Gumi Nyuutai! (Japan)" description "Sakura Taisen GB - Geki Hana Gumi Nyuutai! (Japan)" - rom ( name "Sakura Taisen GB - Geki Hana Gumi Nyuutai! (Japan).gbc" size 4194304 crc EF503D50 md5 70883B45A97984CB033C2B95028BEF65 sha1 4E30A9B06B5048449057376C8F37B3F687FABD18 flags verified ) + rom ( name "Sakura Taisen GB - Geki Hana Gumi Nyuutai! (Japan).gbc" size 4194304 crc ef503d50 sha1 4E30A9B06B5048449057376C8F37B3F687FABD18 flags verified ) ) game ( - name "Sakura Taisen GB2 - Thunderbolt Sakusen (Japan)" - description "Sakura Taisen GB2 - Thunderbolt Sakusen (Japan)" - rom ( name "Sakura Taisen GB2 - Thunderbolt Sakusen (Japan).gbc" size 4194304 crc 47636A2C md5 5B36285C8491BE0E1CB0C2C741D2B793 sha1 13092603EA1D54264BC48F02C2796947BADB462C ) + name "Sakura Taisen GB 2 - Thunderbolt Sakusen (Japan)" + description "Sakura Taisen GB 2 - Thunderbolt Sakusen (Japan)" + rom ( name "Sakura Taisen GB 2 - Thunderbolt Sakusen (Japan).gbc" size 4194304 crc 47636a2c sha1 13092603EA1D54264BC48F02C2796947BADB462C flags verified ) ) game ( name "Samurai Kid (Japan)" description "Samurai Kid (Japan)" - rom ( name "Samurai Kid (Japan).gbc" size 1048576 crc 44A9DDFB md5 7EE095116F1733DC6BA2B2DE3F28F5EF sha1 42834C6A1EA9A0E1D73BB01AC83A4BC504C86C4E flags verified ) + rom ( name "Samurai Kid (Japan).gbc" size 1048576 crc 44a9ddfb sha1 42834C6A1EA9A0E1D73BB01AC83A4BC504C86C4E flags verified ) ) game ( name "San Francisco Rush 2049 (USA, Europe)" description "San Francisco Rush 2049 (USA, Europe)" - rom ( name "San Francisco Rush 2049 (USA, Europe).gbc" size 1048576 crc EF368F16 md5 19601E4FC1F7084076128DCA0182F5A7 sha1 B783B770E6680745DCC0B599199A4429957C874E flags verified ) + rom ( name "San Francisco Rush 2049 (USA, Europe).gbc" size 1048576 crc ef368f16 sha1 B783B770E6680745DCC0B599199A4429957C874E flags verified ) ) game ( - name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced)" - description "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced)" - rom ( name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced).gbc" size 1048576 crc E787B44C md5 73BC46B4EB6E6924DC1B830E884A05F9 sha1 EC6089FF2CFCB17FAF6A8EA9A4171869B3C7289B ) + name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e787b44c sha1 EC6089FF2CFCB17FAF6A8EA9A4171869B3C7289B ) ) game ( - name "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced)" - description "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced)" - rom ( name "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced).gbc" size 1048576 crc 458B579D md5 0146768D48B8317E0C8A2C7DD8D31860 sha1 8421E0D0FC356B25DF62CDE1967E7775A91983C2 flags verified ) + name "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sanrio Timenet - Kako Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 458b579d sha1 8421E0D0FC356B25DF62CDE1967E7775A91983C2 flags verified ) ) game ( - name "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced)" - description "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced)" - rom ( name "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced).gbc" size 1048576 crc EFE51E17 md5 388A603E8B6D0FCF7C553FB00A7C5171 sha1 65C4113401336784BE4C53A51FE8D9B4B3D287DA flags verified ) + name "Sanrio Timenet - Kako Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Sanrio Timenet - Kako Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Sanrio Timenet - Kako Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6555b740 sha1 B3B80B4A48FAEC9CC71D80A6B08B12B3541B4C1B flags verified ) +) + +game ( + name "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sanrio Timenet - Mirai Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc efe51e17 sha1 65C4113401336784BE4C53A51FE8D9B4B3D287DA flags verified ) +) + +game ( + name "Sanrio Timenet - Mirai Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Sanrio Timenet - Mirai Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Sanrio Timenet - Mirai Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 179da7f3 sha1 5CCAF8450862DAB90B45B06AB2DF291D72EA6033 flags verified ) ) game ( name "Santa Claus Junior (Europe)" description "Santa Claus Junior (Europe)" - rom ( name "Santa Claus Junior (Europe).gbc" size 1048576 crc A744DF64 md5 5DF6D1EC0E9241E1ED8A8EE7FF318631 sha1 AB74474CD63A2C74BF9617907270D26B5D183B89 flags verified ) + rom ( name "Santa Claus Junior (Europe).gbc" size 1048576 crc a744df64 sha1 AB74474CD63A2C74BF9617907270D26B5D183B89 flags verified ) ) game ( - name "Saru Puncher (Japan) (SGB Enhanced)" - description "Saru Puncher (Japan) (SGB Enhanced)" - rom ( name "Saru Puncher (Japan) (SGB Enhanced).gbc" size 2097152 crc B02564FC md5 6EBCA05013AF9C103AEA798E0EB924C6 sha1 DB7CC42B4E2A181C31CAA4AE8635EC33B5A09F73 ) + name "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" + description "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b02564fc sha1 DB7CC42B4E2A181C31CAA4AE8635EC33B5A09F73 ) ) game ( name "Scooby-Doo! - Classic Creep Capers (USA, Europe)" description "Scooby-Doo! - Classic Creep Capers (USA, Europe)" - rom ( name "Scooby-Doo! - Classic Creep Capers (USA, Europe).gbc" size 1048576 crc E3704755 md5 117A9BABAE15960DC4DE04AC44066ED2 sha1 F45B42E92E9A570658A2790854578D3766F8C14F flags verified ) + rom ( name "Scooby-Doo! - Classic Creep Capers (USA, Europe).gbc" size 1048576 crc e3704755 sha1 F45B42E92E9A570658A2790854578D3766F8C14F flags verified ) ) game ( name "Scrabble (Europe)" description "Scrabble (Europe)" - rom ( name "Scrabble (Europe).gbc" size 1048576 crc 998657B7 md5 0E31B2DCDE31C590A0835B22F653FD2D sha1 AE24E07E8906BAE07661CF5B8F50CD9B86A5C94D ) + rom ( name "Scrabble (Europe).gbc" size 1048576 crc 998657b7 sha1 AE24E07E8906BAE07661CF5B8F50CD9B86A5C94D ) ) game ( - name "SD Hiryuu no Ken EX (Japan) (SGB Enhanced)" - description "SD Hiryuu no Ken EX (Japan) (SGB Enhanced)" - rom ( name "SD Hiryuu no Ken EX (Japan) (SGB Enhanced).gbc" size 1048576 crc 365BF43F md5 919C330030214DE201278FC6A232A661 sha1 BED7B913A395AE4B62EAC39FF8D6B3093529ED45 ) + name "SD Hiryuu no Ken EX (Japan) (SGB Enhanced) (GB Compatible)" + description "SD Hiryuu no Ken EX (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "SD Hiryuu no Ken EX (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 365bf43f sha1 BED7B913A395AE4B62EAC39FF8D6B3093529ED45 ) ) game ( - name "Sei Hai Densetsu (Japan) (SGB Enhanced)" - description "Sei Hai Densetsu (Japan) (SGB Enhanced)" - rom ( name "Sei Hai Densetsu (Japan) (SGB Enhanced).gbc" size 1048576 crc 612F0529 md5 84749230AB0C2A8881242E67D990FFB1 sha1 1BADA799254B220C1007A1DAC6D13B1BE4A04FF2 ) + name "Sei Hai Densetsu (Japan) (SGB Enhanced) (GB Compatible)" + description "Sei Hai Densetsu (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sei Hai Densetsu (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 612f0529 sha1 1BADA799254B220C1007A1DAC6D13B1BE4A04FF2 ) ) game ( - name "Seme COM Dungeon - Drururuaga (Japan)" - description "Seme COM Dungeon - Drururuaga (Japan)" - rom ( name "Seme COM Dungeon - Drururuaga (Japan).gbc" size 2097152 crc 0B1B928C md5 90DFD51F7A508A4FAC1608FB7A44317F sha1 24B9BEA003A5653FF592D3D63F5AC116C1DE2D60 ) + name "Seme COM Dungeon - Drururuaga (Japan) (GB Compatible)" + description "Seme COM Dungeon - Drururuaga (Japan) (GB Compatible)" + rom ( name "Seme COM Dungeon - Drururuaga (Japan) (GB Compatible).gbc" size 2097152 crc 0b1b928c sha1 24B9BEA003A5653FF592D3D63F5AC116C1DE2D60 flags verified ) ) game ( - name "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced)" - description "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced)" - rom ( name "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced).gbc" size 1048576 crc 23FA5F53 md5 496AFC38447D1DDEC45583F3DF074B35 sha1 C10249EF96A1989C3532A48917862B4DD8BAD12A ) + name "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced) (GB Compatible)" + description "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Senkai Ibunroku Juntei Taisen - TV Animation Senkaiden Houshin Engi Yori (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 23fa5f53 sha1 C10249EF96A1989C3532A48917862B4DD8BAD12A ) +) + +game ( + name "Sesame Street - Elmo's 123s (USA) (GB Compatible)" + description "Sesame Street - Elmo's 123s (USA) (GB Compatible)" + rom ( name "Sesame Street - Elmo's 123s (USA) (GB Compatible).gbc" size 262144 crc 1833fb38 sha1 0ACA4297EC6DC582B668681452F1805AAB991BEC ) +) + +game ( + name "Sesame Street - Elmo's 123s (Europe) (GB Compatible)" + description "Sesame Street - Elmo's 123s (Europe) (GB Compatible)" + rom ( name "Sesame Street - Elmo's 123s (Europe) (GB Compatible).gbc" size 1048576 crc 3bf7fcd4 sha1 841BDA2E2C1542C44B45C98A390BA3320EF735CC flags verified ) +) + +game ( + name "Sesame Street - Elmo's ABCs (USA) (GB Compatible)" + description "Sesame Street - Elmo's ABCs (USA) (GB Compatible)" + rom ( name "Sesame Street - Elmo's ABCs (USA) (GB Compatible).gbc" size 262144 crc cc1fb2a9 sha1 C63EA7FF94250F1F7514A01250BBD5F04A5D2037 ) +) + +game ( + name "Sesame Street - Elmo's ABCs (Europe) (GB Compatible)" + description "Sesame Street - Elmo's ABCs (Europe) (GB Compatible)" + rom ( name "Sesame Street - Elmo's ABCs (Europe) (GB Compatible).gbc" size 1048576 crc 20158fbc sha1 E98D4D4179CA13C22D0205F118470ECC795928B1 flags verified ) +) + +game ( + name "Sesame Street - The Adventures of Elmo in Grouchland (Europe) (GB Compatible)" + description "Sesame Street - The Adventures of Elmo in Grouchland (Europe) (GB Compatible)" + rom ( name "Sesame Street - The Adventures of Elmo in Grouchland (Europe) (GB Compatible).gbc" size 1048576 crc 41228ee7 sha1 AF1C3912DA946D858F9EEB10A3B9D95CBB6A00D8 flags verified ) +) + +game ( + name "Sesame Street - The Adventures of Elmo in Grouchland (USA) (GB Compatible)" + description "Sesame Street - The Adventures of Elmo in Grouchland (USA) (GB Compatible)" + rom ( name "Sesame Street - The Adventures of Elmo in Grouchland (USA) (GB Compatible).gbc" size 262144 crc 2c4c2a5f sha1 60F240476D2FAC81B1EFB83E1128E6223C766F15 ) ) game ( name "Sesame Street Sports (USA)" description "Sesame Street Sports (USA)" - rom ( name "Sesame Street Sports (USA).gbc" size 1048576 crc 4ED4AAFA md5 6814576EE449D4119027DC4A85B92555 sha1 C5F4D432F37A261DA5D11426A36893718EF94B86 ) + rom ( name "Sesame Street Sports (USA).gbc" size 1048576 crc 4ed4aafa sha1 C5F4D432F37A261DA5D11426A36893718EF94B86 ) ) game ( name "Sesame Street Sports (Europe)" description "Sesame Street Sports (Europe)" - rom ( name "Sesame Street Sports (Europe).gbc" size 1048576 crc 55BE1A6E md5 821F70DB4753F0B59A798B9DE91CECFC sha1 2CF168DBAA51C1A0D49E6AB776872A0D2D5CED42 ) + rom ( name "Sesame Street Sports (Europe).gbc" size 1048576 crc 55be1a6e sha1 2CF168DBAA51C1A0D49E6AB776872A0D2D5CED42 flags verified ) ) game ( - name "Sewing Machine Operation Software (USA) (En,Fr,Es)" - description "Sewing Machine Operation Software (USA) (En,Fr,Es)" - serial "DMG-BRAE-USA" - rom ( name "Sewing Machine Operation Software (USA) (En,Fr,Es).gbc" size 1048576 crc E42FD7C4 md5 52F46E74689516225055B8576079EE24 sha1 A05A67F2D29BF29C56C9533C172DA02EE0AD26B1 ) + name "Sewing Machine Operation Software (USA) (En,Fr,Es) (GB Compatible)" + description "Sewing Machine Operation Software (USA) (En,Fr,Es) (GB Compatible)" + rom ( name "Sewing Machine Operation Software (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc e42fd7c4 sha1 A05A67F2D29BF29C56C9533C172DA02EE0AD26B1 ) ) game ( name "Sgt. Rock - On the Frontline (USA)" description "Sgt. Rock - On the Frontline (USA)" - rom ( name "Sgt. Rock - On the Frontline (USA).gbc" size 1048576 crc 521A2F77 md5 A2623ACF15EC36AB072EE5B92B88B613 sha1 53D7FA6FDAC65519F8A78F4A42E79E56162589AD ) + rom ( name "Sgt. Rock - On the Frontline (USA).gbc" size 1048576 crc 521a2f77 sha1 53D7FA6FDAC65519F8A78F4A42E79E56162589AD ) ) game ( - name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv)" - description "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv)" - rom ( name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv).gbc" size 1048576 crc F6A876A5 md5 9D79034C9B026F448F84F9898C6CCFD6 sha1 4E0C0E15BEAC73913320F8AB68001F90F52BEB92 flags verified ) + name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (GB Compatible)" + description "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (GB Compatible)" + rom ( name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (GB Compatible).gbc" size 1048576 crc f6a876a5 sha1 4E0C0E15BEAC73913320F8AB68001F90F52BEB92 flags verified ) ) game ( - name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev A)" - description "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev A)" - rom ( name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev A).gbc" size 1048576 crc D337F450 md5 90280833C156E2CA8E4EAA29ADF369B2 sha1 B7343C9CE3343FA618A6C208969446B964DDE5F5 flags verified ) + name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev 1) (GB Compatible)" + description "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev 1) (GB Compatible)" + rom ( name "Shadowgate Classic (USA, Europe) (En,Fr,De,Es,Sv) (Rev 1) (GB Compatible).gbc" size 1048576 crc d337f450 sha1 B7343C9CE3343FA618A6C208969446B964DDE5F5 flags verified ) ) game ( - name "Shadowgate Return (Japan)" - description "Shadowgate Return (Japan)" - rom ( name "Shadowgate Return (Japan).gbc" size 1048576 crc 1BCD7D70 md5 4C18B5D470B105344EC55D195A05D2DE sha1 15C4A88E7FBBEED6F529B86601285794E92CCF0C flags verified ) + name "Shadowgate Return (Japan) (GB Compatible)" + description "Shadowgate Return (Japan) (GB Compatible)" + rom ( name "Shadowgate Return (Japan) (GB Compatible).gbc" size 1048576 crc 1bcd7d70 sha1 15C4A88E7FBBEED6F529B86601285794E92CCF0C flags verified ) ) game ( name "Shaman King Card Game - Chou Senjiryakketsu - Funbari Hen (Japan)" description "Shaman King Card Game - Chou Senjiryakketsu - Funbari Hen (Japan)" - rom ( name "Shaman King Card Game - Chou Senjiryakketsu - Funbari Hen (Japan).gbc" size 4194304 crc EF10272E md5 43F61059772E7CEF92E32F05DD89205B sha1 7B5AABC533784634CA210A2ED2B44BA136DC7276 flags verified ) + rom ( name "Shaman King Card Game - Chou Senjiryakketsu - Funbari Hen (Japan).gbc" size 4194304 crc ef10272e sha1 7B5AABC533784634CA210A2ED2B44BA136DC7276 flags verified ) ) game ( name "Shaman King Card Game - Chou Senjiryakketsu - Meramera Hen (Japan)" description "Shaman King Card Game - Chou Senjiryakketsu - Meramera Hen (Japan)" - rom ( name "Shaman King Card Game - Chou Senjiryakketsu - Meramera Hen (Japan).gbc" size 4194304 crc 5730393D md5 B3550A7C733B9392477F5B2E4502D7A8 sha1 03901428FE3A791A0078C9295AA4E41994282013 flags verified ) + rom ( name "Shaman King Card Game - Chou Senjiryakketsu - Meramera Hen (Japan).gbc" size 4194304 crc 5730393d sha1 03901428FE3A791A0078C9295AA4E41994282013 flags verified ) ) game ( - name "Shamus (USA, Europe)" - description "Shamus (USA, Europe)" - rom ( name "Shamus (USA, Europe).gbc" size 1048576 crc EFB9196D md5 C0E42B4B7BA5605C3AB7B83B1E2FAB6D sha1 66349ABF080E85738875F22A86E0453E5B68F425 flags verified ) + name "Shamus (USA, Europe) (GB Compatible)" + description "Shamus (USA, Europe) (GB Compatible)" + rom ( name "Shamus (USA, Europe) (GB Compatible).gbc" size 1048576 crc efb9196d sha1 66349ABF080E85738875F22A86E0453E5B68F425 flags verified ) ) game ( - name "Shanghai Pocket (USA) (SGB Enhanced)" - description "Shanghai Pocket (USA) (SGB Enhanced)" - rom ( name "Shanghai Pocket (USA) (SGB Enhanced).gbc" size 1048576 crc 9401BA47 md5 08680AEDC945591F81461C1BF459124E sha1 6436B152924A8612D7CD28FEF09F10A81EC91AD7 ) + name "Shanghai Pocket (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Shanghai Pocket (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Shanghai Pocket (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 9401ba47 sha1 6436B152924A8612D7CD28FEF09F10A81EC91AD7 flags verified ) ) game ( - name "Shanghai Pocket (USA, Europe) (Rev A) (SGB Enhanced)" - description "Shanghai Pocket (USA, Europe) (Rev A) (SGB Enhanced)" - rom ( name "Shanghai Pocket (USA, Europe) (Rev A) (SGB Enhanced).gbc" size 1048576 crc D8FAC36C md5 F7E13DE010DECF104EFA3DB865971F34 sha1 ADBF1A18DEA69E46C3DBCCEC03E09668912F12A7 flags verified ) + name "Shanghai Pocket (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Shanghai Pocket (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Shanghai Pocket (USA, Europe) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d8fac36c sha1 ADBF1A18DEA69E46C3DBCCEC03E09668912F12A7 flags verified ) ) game ( name "Shantae (USA)" description "Shantae (USA)" - rom ( name "Shantae (USA).gbc" size 4194304 crc E994B59B md5 028C4262DBB49F4FC462A6EB3E514D72 sha1 520E48C50F6E997FCD841CA368FC9ABC1DBDDEC1 flags verified ) + rom ( name "Shantae (USA).gbc" size 4194304 crc e994b59b sha1 520E48C50F6E997FCD841CA368FC9ABC1DBDDEC1 flags verified ) ) game ( - name "Shaun Palmer's Pro Snowboarder (USA, Australia)" - description "Shaun Palmer's Pro Snowboarder (USA, Australia)" - rom ( name "Shaun Palmer's Pro Snowboarder (USA, Australia).gbc" size 2097152 crc 709CDA93 md5 3BCB284142A35A8D86550C2F34549DCC sha1 3563D3085198BF40BA92C4DE40093E5FA2D422D5 flags verified ) + name "Shaun Palmer's Pro Snowboarder (USA)" + description "Shaun Palmer's Pro Snowboarder (USA)" + rom ( name "Shaun Palmer's Pro Snowboarder (USA).gbc" size 2097152 crc 709cda93 sha1 3563D3085198BF40BA92C4DE40093E5FA2D422D5 ) ) game ( - name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced)" - description "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced)" - rom ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced).gbc" size 2097152 crc F90C4977 md5 3D04E5C70919118EF6E7CB69DAE14B10 sha1 B15CBD01A21048D0FD022F0E023AB5D91FAAF442 flags verified ) + name "Shelly Club (Europe) (En,Fr,De,Es,It)" + description "Shelly Club (Europe) (En,Fr,De,Es,It)" + rom ( name "Shelly Club (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 767caa42 sha1 F81FE7427484D9C2AF043819690FAE9B81B29813 flags verified ) ) game ( - name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced)" - description "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced)" - rom ( name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced).gbc" size 2097152 crc 55B9AF51 md5 158691457CB7365CAFBD0B7BB230FADF sha1 B6177175AB34B8301CE146306DC95C3702B38CA6 flags verified ) + name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible)" + description "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc f90c4977 sha1 B15CBD01A21048D0FD022F0E023AB5D91FAAF442 flags verified ) +) + +game ( + name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Shin Megami Tensei Devil Children - Aka no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc c1e27556 sha1 E9A3EDD28503EE94DB8EC4EA48832DC2BA0264D9 flags verified ) +) + +game ( + name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced) (GB Compatible)" + description "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 55b9af51 sha1 B6177175AB34B8301CE146306DC95C3702B38CA6 flags verified ) +) + +game ( + name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Shin Megami Tensei Devil Children - Kuro no Sho (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 3d4ae536 sha1 421D20BF556E28D07801D808ECFEF45DAF86A974 flags verified ) ) game ( name "Shin Megami Tensei Devil Children - Shiro no Sho (Japan)" description "Shin Megami Tensei Devil Children - Shiro no Sho (Japan)" - rom ( name "Shin Megami Tensei Devil Children - Shiro no Sho (Japan).gbc" size 2097152 crc 39A10855 md5 9354CC341AA23DA3E29829DA76B8888E sha1 0AD803E30CD4653855A0C878E4C7A63F1183E369 flags verified ) + rom ( name "Shin Megami Tensei Devil Children - Shiro no Sho (Japan).gbc" size 2097152 crc 39a10855 sha1 0AD803E30CD4653855A0C878E4C7A63F1183E369 flags verified ) ) game ( name "Shin Megami Tensei Trading Card - Card Summoner (Japan)" description "Shin Megami Tensei Trading Card - Card Summoner (Japan)" - rom ( name "Shin Megami Tensei Trading Card - Card Summoner (Japan).gbc" size 2097152 crc 85264877 md5 4EF95A30C72008DEE31AB836742C9ACF sha1 67DAAF5AAD65D91109B122E61C1EB3A864437FD4 flags verified ) + rom ( name "Shin Megami Tensei Trading Card - Card Summoner (Japan).gbc" size 2097152 crc 85264877 sha1 67DAAF5AAD65D91109B122E61C1EB3A864437FD4 flags verified ) ) game ( name "Shinseiki Evangelion - Mahjong Hokan Keikaku (Japan)" description "Shinseiki Evangelion - Mahjong Hokan Keikaku (Japan)" - rom ( name "Shinseiki Evangelion - Mahjong Hokan Keikaku (Japan).gbc" size 2097152 crc 5337FF55 md5 211031BE4F99F69BFD8DFACC2B148D7C sha1 F9B048C7C18148197AD82EC9DEC65CE124D663E1 ) + rom ( name "Shinseiki Evangelion - Mahjong Hokan Keikaku (Japan).gbc" size 2097152 crc 5337ff55 sha1 F9B048C7C18148197AD82EC9DEC65CE124D663E1 flags verified ) ) game ( - name "Shougi 2 (Japan)" - description "Shougi 2 (Japan)" - rom ( name "Shougi 2 (Japan).gbc" size 262144 crc A7748D2B md5 C8B51BECB4EDACC3B115A81329AA12C0 sha1 7C89CEBC4DFCF8713C94B0553E4F4D4F8945052F ) + name "Shougi 2 (Japan) (GB Compatible)" + description "Shougi 2 (Japan) (GB Compatible)" + rom ( name "Shougi 2 (Japan) (GB Compatible).gbc" size 262144 crc a7748d2b sha1 7C89CEBC4DFCF8713C94B0553E4F4D4F8945052F flags verified ) ) game ( - name "Shougi 3 (Japan)" - description "Shougi 3 (Japan)" - rom ( name "Shougi 3 (Japan).gbc" size 262144 crc 64B479FA md5 30F78CB1AF3772826AB1D0F6D989BB52 sha1 6927C466F838A913850A7EECB86FE75840F1CF09 ) + name "Shougi 3 (Japan) (GB Compatible)" + description "Shougi 3 (Japan) (GB Compatible)" + rom ( name "Shougi 3 (Japan) (GB Compatible).gbc" size 262144 crc 64b479fa sha1 6927C466F838A913850A7EECB86FE75840F1CF09 flags verified ) ) game ( name "Shrek - Fairy Tale Freakdown (USA, Europe) (En,Fr,De,Es,It)" description "Shrek - Fairy Tale Freakdown (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Shrek - Fairy Tale Freakdown (USA, Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 387E6459 md5 69C68B13BB0DA057ACBAFE24E389E855 sha1 E6A728CAFD14A4DF952467F2A7434FF14E53E268 flags verified ) + rom ( name "Shrek - Fairy Tale Freakdown (USA, Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 387e6459 sha1 E6A728CAFD14A4DF952467F2A7434FF14E53E268 flags verified ) ) game ( - name "Shutokou Racing, The (Japan) (SGB Enhanced)" - description "Shutokou Racing, The (Japan) (SGB Enhanced)" - rom ( name "Shutokou Racing, The (Japan) (SGB Enhanced).gbc" size 131072 crc 36E781CD md5 43202194489C664523243AE75EE041AF sha1 0F29818190EA9CE8C242B648BA64D50CC5408E5A ) + name "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible)" + description "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc 36e781cd sha1 0F29818190EA9CE8C242B648BA64D50CC5408E5A ) ) game ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" description "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe)" - rom ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe).gbc" size 1048576 crc EBAF4888 md5 2A4F3309FE05B47A98D8C5B4C81B91E5 sha1 A5BE079336E48552E53706F0380F35829D91B3C0 flags verified ) + rom ( name "Simpsons, The - Night of the Living Treehouse of Horror (USA, Europe).gbc" size 1048576 crc ebaf4888 sha1 A5BE079336E48552E53706F0380F35829D91B3C0 flags verified ) ) game ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" description "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" - rom ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6F97B043 md5 5DA63FE252B4CB3E17DD4986FB276690 sha1 FE9F70D6FF58174F533A08B556358D916EDA8A1E flags verified ) + rom ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6f97b043 sha1 FE9F70D6FF58174F533A08B556358D916EDA8A1E flags verified ) ) game ( name "Smurfs Nightmare, The (USA)" description "Smurfs Nightmare, The (USA)" - rom ( name "Smurfs Nightmare, The (USA).gbc" size 1048576 crc B50CAFE4 md5 20052C527795A4F332BE14AFF49D4D4B sha1 1D0D3512F32176B7035F9C2A77D4636B1D08B349 ) + rom ( name "Smurfs Nightmare, The (USA).gbc" size 1048576 crc b50cafe4 sha1 1D0D3512F32176B7035F9C2A77D4636B1D08B349 flags verified ) ) game ( name "Snobow Champion (Japan)" description "Snobow Champion (Japan)" - rom ( name "Snobow Champion (Japan).gbc" size 1048576 crc 846FEA2B md5 78F920F4E9174CD3382294129D30F373 sha1 E99284640D67643102E68ACA25BF56D78A1A0D39 ) + rom ( name "Snobow Champion (Japan).gbc" size 1048576 crc 846fea2b sha1 E99284640D67643102E68ACA25BF56D78A1A0D39 ) ) game ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl)" description "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8C2D9B43 md5 D3C6C44A4F6021B4D5A6454A87AF9A6C sha1 E51347BB82E44A2ECEFEB3F220A0B3DEF6DAF514 ) + rom ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 8c2d9b43 sha1 E51347BB82E44A2ECEFEB3F220A0B3DEF6DAF514 flags verified ) ) game ( name "Snoopy Tennis (Japan)" description "Snoopy Tennis (Japan)" - rom ( name "Snoopy Tennis (Japan).gbc" size 1048576 crc D088EEFD md5 6DEF7D77E305997838C4B64B5163E3C2 sha1 66B78EC7DE2D407B3B4FAC0323AD6C6DF223C744 ) + rom ( name "Snoopy Tennis (Japan).gbc" size 1048576 crc d088eefd sha1 66B78EC7DE2D407B3B4FAC0323AD6C6DF223C744 ) ) game ( name "Snoopy Tennis (USA) (En,Fr,Es)" description "Snoopy Tennis (USA) (En,Fr,Es)" - rom ( name "Snoopy Tennis (USA) (En,Fr,Es).gbc" size 1048576 crc D882ECCC md5 56CBF668AF5095A073E205A07987C82A sha1 A07B8FE92B4FEE98586A09FDD5A8DD4C8345BF16 ) + rom ( name "Snoopy Tennis (USA) (En,Fr,Es).gbc" size 1048576 crc d882eccc sha1 A07B8FE92B4FEE98586A09FDD5A8DD4C8345BF16 ) ) game ( name "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" description "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da)" - rom ( name "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da).gbc" size 1048576 crc C9C68471 md5 6156E8789CE8126C299892F34D2C9805 sha1 BCB5F2141BDFA0BD055E7E94301CF0AFF00971A0 ) + rom ( name "Snow White and the Seven Dwarfs (Europe) (En,Fr,De,Es,It,Nl,Sv,No,Da).gbc" size 1048576 crc c9c68471 sha1 BCB5F2141BDFA0BD055E7E94301CF0AFF00971A0 ) ) game ( name "Snow White and the Seven Dwarfs (USA)" description "Snow White and the Seven Dwarfs (USA)" - rom ( name "Snow White and the Seven Dwarfs (USA).gbc" size 1048576 crc 8DD38534 md5 0C1C350CE431ACE4328C0E935FA2F41B sha1 865E5BD17E336B4696FB891BC21C966EF2E186C9 ) + rom ( name "Snow White and the Seven Dwarfs (USA).gbc" size 1048576 crc 8dd38534 sha1 865E5BD17E336B4696FB891BC21C966EF2E186C9 flags verified ) ) game ( name "SnowCross (Europe) (En,Fr,De,Es,It,Pt)" description "SnowCross (Europe) (En,Fr,De,Es,It,Pt)" - rom ( name "SnowCross (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 4BA47DBC md5 523FAC00115280EDE5AC1647552B2024 sha1 436BED2117772F4632A37D54A83E2310DDDF1121 ) + rom ( name "SnowCross (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 4ba47dbc sha1 436BED2117772F4632A37D54A83E2310DDDF1121 ) ) game ( name "Soccer Manager (Europe) (En,Fr,De,Es)" description "Soccer Manager (Europe) (En,Fr,De,Es)" - rom ( name "Soccer Manager (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 237ECEF9 md5 BA0AEEDAE367F82A1FD2760CFCDA2BD9 sha1 353EB6AAF40A78EBF1BCA9298726D068A5986EFA ) + rom ( name "Soccer Manager (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 237ecef9 sha1 353EB6AAF40A78EBF1BCA9298726D068A5986EFA ) ) game ( name "Solomon (Japan)" description "Solomon (Japan)" - rom ( name "Solomon (Japan).gbc" size 1048576 crc 6AEE0958 md5 DC15BF4D545A2C537F46598CB9204DAF sha1 0C8DA92984888A2C4EEA29A3CB05DC75F35EFAAA flags verified ) + rom ( name "Solomon (Japan).gbc" size 1048576 crc 6aee0958 sha1 0C8DA92984888A2C4EEA29A3CB05DC75F35EFAAA flags verified ) ) game ( name "Soreike! Anpanman - 5-tsu no Tou no Ousama (Japan)" description "Soreike! Anpanman - 5-tsu no Tou no Ousama (Japan)" - rom ( name "Soreike! Anpanman - 5-tsu no Tou no Ousama (Japan).gbc" size 1048576 crc C9A25B0C md5 F09214D17150911AF6AACBE5D89BC00F sha1 E3E4D1E2D1FE6D0683DB9D17356080542E1A6905 ) + rom ( name "Soreike! Anpanman - 5-tsu no Tou no Ousama (Japan).gbc" size 1048576 crc c9a25b0c sha1 E3E4D1E2D1FE6D0683DB9D17356080542E1A6905 flags verified ) ) game ( - name "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced)" - description "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced)" - rom ( name "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced).gbc" size 1048576 crc A80EEEAD md5 28B5114313B8ABC43A31EA40AA91CF52 sha1 FE75B7B7A904CE76130D65B67D24E291BA3C2693 flags verified ) + name "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced) (GB Compatible)" + description "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Soreike! Anpanman - Fushigi na Nikoniko Album (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc a80eeead sha1 FE75B7B7A904CE76130D65B67D24E291BA3C2693 flags verified ) ) game ( - name "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced)" - description "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced)" - rom ( name "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced).gbc" size 1048576 crc 081D7FCB md5 47E8DCB47A5E87F74441BB735F255ABA sha1 CB249BD50DC8C7D503544383AF6FB5DF0E874AE5 ) + name "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced) (GB Compatible)" + description "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Soukoban Densetsu - Hikari to Yami no Kuni (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 081d7fcb sha1 CB249BD50DC8C7D503544383AF6FB5DF0E874AE5 ) ) game ( - name "Soul Getter - Houkago Bouken RPG (Japan)" - description "Soul Getter - Houkago Bouken RPG (Japan)" - rom ( name "Soul Getter - Houkago Bouken RPG (Japan).gbc" size 2097152 crc 3FFCD45B md5 053D55B23C41C5E0E3227239F4844FEA sha1 DED83FDE342A5DC9E56CDBB91ACAD2CD5F4AC754 flags verified ) + name "Soul Getter - Houkago Bouken RPG (Japan) (GB Compatible)" + description "Soul Getter - Houkago Bouken RPG (Japan) (GB Compatible)" + rom ( name "Soul Getter - Houkago Bouken RPG (Japan) (GB Compatible).gbc" size 2097152 crc 3ffcd45b sha1 DED83FDE342A5DC9E56CDBB91ACAD2CD5F4AC754 flags verified ) ) game ( - name "Space Invaders (USA, Europe)" - description "Space Invaders (USA, Europe)" - rom ( name "Space Invaders (USA, Europe).gbc" size 1048576 crc DAB7460C md5 46E0E199F58AEBBB75B4ED16DA5AAE60 sha1 392A8087633969ED0BE05E7DA628D6E92BEFB711 flags verified ) + name "South Park (USA) (Proto)" + description "South Park (USA) (Proto)" + rom ( name "South Park (USA) (Proto).gbc" size 524288 crc e79d411a sha1 AD9240B30E381CD7B260F5FC78AAAEED00C6B43D flags verified ) ) game ( - name "Space Invaders X (Japan)" - description "Space Invaders X (Japan)" - rom ( name "Space Invaders X (Japan).gbc" size 1048576 crc C016BC79 md5 A1304BDEFA239600BD6116081BAE2E23 sha1 40D16062BF170647CDF060359FC65FF02350F40A ) + name "Space Invaders (USA, Europe) (GB Compatible)" + description "Space Invaders (USA, Europe) (GB Compatible)" + rom ( name "Space Invaders (USA, Europe) (GB Compatible).gbc" size 1048576 crc dab7460c sha1 392A8087633969ED0BE05E7DA628D6E92BEFB711 flags verified ) +) + +game ( + name "Space Invaders X (Japan) (En) (GB Compatible)" + description "Space Invaders X (Japan) (En) (GB Compatible)" + rom ( name "Space Invaders X (Japan) (En) (GB Compatible).gbc" size 1048576 crc c016bc79 sha1 40D16062BF170647CDF060359FC65FF02350F40A ) ) game ( name "Space Invasion (Europe) (Unl)" description "Space Invasion (Europe) (Unl)" - rom ( name "Space Invasion (Europe) (Unl).gbc" size 131072 crc 2B2D9868 md5 3606F20C43C009075AF22991766B2CC7 sha1 BCF0940375A23BCA6957EEC2AB8E49AF695AEB32 flags verified ) + rom ( name "Space Invasion (Europe) (Unl).gbc" size 131072 crc 2b2d9868 sha1 BCF0940375A23BCA6957EEC2AB8E49AF695AEB32 flags verified ) ) game ( name "Space Invasion & Karate Joe (Europe) (Unl)" description "Space Invasion & Karate Joe (Europe) (Unl)" - rom ( name "Space Invasion & Karate Joe (Europe) (Unl).gbc" size 524288 crc 6A184C55 md5 866994B67B78C02B70573076B27D18FB sha1 96918CBD3648B227EB43E5A9711D1A9939541BEA flags verified ) + rom ( name "Space Invasion & Karate Joe (Europe) (Unl).gbc" size 524288 crc 6a184c55 sha1 96918CBD3648B227EB43E5A9711D1A9939541BEA flags verified ) ) game ( name "Space Invasion & Painter (Europe) (Unl)" description "Space Invasion & Painter (Europe) (Unl)" - rom ( name "Space Invasion & Painter (Europe) (Unl).gbc" size 524288 crc BD4C1065 md5 D6E59AD9058F410A56356ACCCE0CB488 sha1 A5BF26ED894576DADA84F6925CC659980CF150A0 ) + rom ( name "Space Invasion & Painter (Europe) (Unl).gbc" size 524288 crc bd4c1065 sha1 A5BF26ED894576DADA84F6925CC659980CF150A0 ) ) game ( name "Space Marauder (USA)" description "Space Marauder (USA)" - rom ( name "Space Marauder (USA).gbc" size 1048576 crc 4F83B35E md5 5EE49EAF9A2C19623478215788C0BFDC sha1 E6738767434F53AF8221FB06513C0758AB228A94 ) + rom ( name "Space Marauder (USA).gbc" size 1048576 crc 4f83b35e sha1 E6738767434F53AF8221FB06513C0758AB228A94 ) ) game ( name "Space-Net - Cosmo Blue (Japan)" description "Space-Net - Cosmo Blue (Japan)" - rom ( name "Space-Net - Cosmo Blue (Japan).gbc" size 2097152 crc F606D369 md5 062BFA5E5B52B5A4ACE5B59C364FE2FF sha1 9D662A4B95F8B562406EB89FAD8CADE1EDACA954 flags verified ) + rom ( name "Space-Net - Cosmo Blue (Japan).gbc" size 2097152 crc f606d369 sha1 9D662A4B95F8B562406EB89FAD8CADE1EDACA954 flags verified ) ) game ( name "Space-Net - Cosmo Red (Japan)" description "Space-Net - Cosmo Red (Japan)" - rom ( name "Space-Net - Cosmo Red (Japan).gbc" size 2097152 crc 01F96353 md5 8EB8951D69263571392192BF3D928099 sha1 AA4669D5A6D1C3A53DE889543D8477ADAE6F3ED4 ) + rom ( name "Space-Net - Cosmo Red (Japan).gbc" size 2097152 crc 01f96353 sha1 AA4669D5A6D1C3A53DE889543D8477ADAE6F3ED4 flags verified ) ) game ( - name "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 2097152 crc 63353C0F md5 488611AF773CEC5B7ECC5BD3EFB754BB sha1 1DBFA27EBC11C63B86CB36075B807B24426DCFD5 flags verified ) + name "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Spacestation Silicon Valley (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 2097152 crc 63353c0f sha1 1DBFA27EBC11C63B86CB36075B807B24426DCFD5 flags verified ) ) game ( name "Spawn (USA)" description "Spawn (USA)" - rom ( name "Spawn (USA).gbc" size 2097152 crc 72FCB0AD md5 FEBD6CDB9F12B6003D7EF33045EF7079 sha1 4F816EEC1B5DC79928ADE9F3A3C687B8AA5B2F87 ) + rom ( name "Spawn (USA).gbc" size 2097152 crc 72fcb0ad sha1 4F816EEC1B5DC79928ADE9F3A3C687B8AA5B2F87 ) ) game ( - name "Speedy Gonzales - Aztec Adventure (USA, Europe)" - description "Speedy Gonzales - Aztec Adventure (USA, Europe)" - rom ( name "Speedy Gonzales - Aztec Adventure (USA, Europe).gbc" size 1048576 crc AE82AFA4 md5 49B834AC7CD50DA9B424E17C112C577A sha1 95F868358979C5BBDFA70920FB35B7D4E00BF8CC flags verified ) + name "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" + description "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" + rom ( name "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible).gbc" size 1048576 crc ae82afa4 sha1 95F868358979C5BBDFA70920FB35B7D4E00BF8CC flags verified ) ) game ( name "Spider-Man (France)" description "Spider-Man (France)" - rom ( name "Spider-Man (France).gbc" size 1048576 crc F6334DC5 md5 402DF05FC7CEE731E564B48366BC779D sha1 4BFF8A1324C6530B719E99F91BF6D46B2483C9E9 ) + rom ( name "Spider-Man (France).gbc" size 1048576 crc f6334dc5 sha1 4BFF8A1324C6530B719E99F91BF6D46B2483C9E9 ) ) game ( name "Spider-Man (Japan)" description "Spider-Man (Japan)" - rom ( name "Spider-Man (Japan).gbc" size 1048576 crc 5A83DFC4 md5 B74E388091F84C552EA4E2C1BE3FBA95 sha1 EF05291A6197E5F1D9790422466E2663E76F64D4 ) + rom ( name "Spider-Man (Japan).gbc" size 1048576 crc 5a83dfc4 sha1 EF05291A6197E5F1D9790422466E2663E76F64D4 ) ) game ( name "Spider-Man (USA, Europe)" description "Spider-Man (USA, Europe)" - rom ( name "Spider-Man (USA, Europe).gbc" size 1048576 crc 34E2B3BA md5 9FDE547BCB70B108895E259DA4C4E100 sha1 EA432C3F2B0D92B4CF03D762E273ABC68F45F072 flags verified ) + rom ( name "Spider-Man (USA, Europe).gbc" size 1048576 crc 34e2b3ba sha1 EA432C3F2B0D92B4CF03D762E273ABC68F45F072 flags verified ) ) game ( name "Spider-Man 2 - The Sinister Six (USA, Europe)" description "Spider-Man 2 - The Sinister Six (USA, Europe)" - rom ( name "Spider-Man 2 - The Sinister Six (USA, Europe).gbc" size 1048576 crc A7FAACCF md5 85BBAD46380DFFA631F8CE732E9C5D89 sha1 22C63FA198DF68EDB9CBE22E35CBD307174C9EB9 flags verified ) + rom ( name "Spider-Man 2 - The Sinister Six (USA, Europe).gbc" size 1048576 crc a7faaccf sha1 22C63FA198DF68EDB9CBE22E35CBD307174C9EB9 flags verified ) ) game ( - name "Spirou Robbedoes - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" - description "Spirou Robbedoes - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Spirou Robbedoes - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 1048576 crc 3E9BC90B md5 144FC4636FCEFBD56D906505F5308DA1 sha1 AE46EBE1D5A8BD13E9D7533B1FE3B04392630E41 ) + name "Spirou - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" + description "Spirou - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da)" + rom ( name "Spirou - The Robot Invasion (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 1048576 crc 3e9bc90b sha1 AE46EBE1D5A8BD13E9D7533B1FE3B04392630E41 ) ) game ( name "SpongeBob SquarePants - Legend of the Lost Spatula (USA, Europe)" description "SpongeBob SquarePants - Legend of the Lost Spatula (USA, Europe)" - rom ( name "SpongeBob SquarePants - Legend of the Lost Spatula (USA, Europe).gbc" size 1048576 crc 81230564 md5 4272D192CF2B14DB93F1E2D1BC07AA74 sha1 D3BEA58987C9904056587242BF3AD26F91B4EF34 flags verified ) + rom ( name "SpongeBob SquarePants - Legend of the Lost Spatula (USA, Europe).gbc" size 1048576 crc 81230564 sha1 D3BEA58987C9904056587242BF3AD26F91B4EF34 flags verified ) ) game ( - name "Spy vs. Spy (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Spy vs. Spy (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Spy vs. Spy (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 713C6C17 md5 FE002EE7D615BF7B728BF6031645B168 sha1 574C90CC4EF318D76A76392E5165351DBC9A1AB0 flags verified ) + name "Spy vs Spy (Europe) (En,Fr,De,Es,It,Nl,Sv)" + description "Spy vs Spy (Europe) (En,Fr,De,Es,It,Nl,Sv)" + rom ( name "Spy vs Spy (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 713c6c17 sha1 574C90CC4EF318D76A76392E5165351DBC9A1AB0 flags verified ) ) game ( - name "Spy vs. Spy (Japan)" - description "Spy vs. Spy (Japan)" - rom ( name "Spy vs. Spy (Japan).gbc" size 1048576 crc 0E783117 md5 A5BFA8B98969CA67811ED2D7BFBF5535 sha1 0167B0D74004AA9ACE10069C5D4BF51ADFE7297B ) + name "Spy vs Spy (Japan)" + description "Spy vs Spy (Japan)" + rom ( name "Spy vs Spy (Japan).gbc" size 1048576 crc 0e783117 sha1 0167B0D74004AA9ACE10069C5D4BF51ADFE7297B ) ) game ( - name "Spy vs. Spy (USA)" - description "Spy vs. Spy (USA)" - rom ( name "Spy vs. Spy (USA).gbc" size 1048576 crc F0463D51 md5 D5F373B287D29E882A1F1182542D5B68 sha1 7249CDAF769F959F527A6E01435420BB8102DF7A ) + name "Spy vs Spy (USA)" + description "Spy vs Spy (USA)" + rom ( name "Spy vs Spy (USA).gbc" size 1048576 crc f0463d51 sha1 7249CDAF769F959F527A6E01435420BB8102DF7A ) ) game ( - name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced)" - description "Star Ocean - Blue Sphere (Japan) (SGB Enhanced)" - rom ( name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced).gbc" size 4194304 crc 8C7DDBDA md5 820E0A19275FABC03FE619C42DB47179 sha1 3D07AE53BA21EDA4923BF4DA6C938E2A407C990C flags verified ) + name "Spy vs Spy (Japan) (Rev 1) (NP)" + description "Spy vs Spy (Japan) (Rev 1) (NP)" + rom ( name "Spy vs Spy (Japan) (Rev 1) (NP).gbc" size 1048576 crc eb47d63b sha1 9E203F04857CD84EC49B0E6C6D4917B1A5CC199E flags verified ) +) + +game ( + name "Star Heritage (Europe) (Proto) (SRAM Version)" + description "Star Heritage (Europe) (Proto) (SRAM Version)" + rom ( name "Star Heritage (Europe) (Proto) (SRAM Version).gbc" size 1048576 crc c72e6dfe sha1 4EB7AD40520E21F1B371B06AC2ADB6F2E1B507A9 flags verified ) +) + +game ( + name "Star Heritage (Europe) (Proto) (Password Version)" + description "Star Heritage (Europe) (Proto) (Password Version)" + rom ( name "Star Heritage (Europe) (Proto) (Password Version).gbc" size 1048576 crc b39b4532 sha1 6EB2C27E2EEDB22B4055DED87FCE0621D460FE5B flags verified ) +) + +game ( + name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" + description "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 8c7ddbda sha1 3D07AE53BA21EDA4923BF4DA6C938E2A407C990C flags verified ) +) + +game ( + name "Star Wars - Yoda Stories (USA, Europe) (GB Compatible)" + description "Star Wars - Yoda Stories (USA, Europe) (GB Compatible)" + rom ( name "Star Wars - Yoda Stories (USA, Europe) (GB Compatible).gbc" size 1048576 crc 6314da32 sha1 F0DD388373E863F91A05CF6F2DF00A56E26D3B18 flags verified ) ) game ( name "Star Wars Episode I - Obi-Wan's Adventures (Europe) (En,Fr,De,Es,It)" description "Star Wars Episode I - Obi-Wan's Adventures (Europe) (En,Fr,De,Es,It)" - rom ( name "Star Wars Episode I - Obi-Wan's Adventures (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc E584DFC2 md5 B9CF2CC6FF8CBE94CB58FFA958475AB8 sha1 F6A4F115E553F67512373FC5FCBF295C1D6D9FCD ) + rom ( name "Star Wars Episode I - Obi-Wan's Adventures (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc e584dfc2 sha1 F6A4F115E553F67512373FC5FCBF295C1D6D9FCD ) ) game ( name "Star Wars Episode I - Obi-Wan's Adventures (USA)" description "Star Wars Episode I - Obi-Wan's Adventures (USA)" - rom ( name "Star Wars Episode I - Obi-Wan's Adventures (USA).gbc" size 1048576 crc 0E697582 md5 484EEB83AD00353272767485ECA59EA5 sha1 FB15A0AE700A11F0925113E5F5C9CB5C655ACDB5 ) + rom ( name "Star Wars Episode I - Obi-Wan's Adventures (USA).gbc" size 1048576 crc 0e697582 sha1 FB15A0AE700A11F0925113E5F5C9CB5C655ACDB5 ) ) game ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version)" description "Star Wars Episode I - Racer (USA, Europe) (Rumble Version)" - rom ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version).gbc" size 2097152 crc 0EBC5758 md5 D1E875CB7DAC0092E83B9E7799B06653 sha1 C0613D654A4382F0C50FD4D389D3A6AEEF4D5207 flags verified ) + rom ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version).gbc" size 2097152 crc 0ebc5758 sha1 C0613D654A4382F0C50FD4D389D3A6AEEF4D5207 flags verified ) ) game ( - name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced)" - description "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced)" - rom ( name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced).gbc" size 1048576 crc 816A4D94 md5 326F861A8FB3E21F1E9379E62CFB6BEA sha1 5C1D738F23A68CCE8D2561F91F06C9998E0FE5A9 flags verified ) + name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + description "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" + rom ( name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 816a4d94 sha1 5C1D738F23A68CCE8D2561F91F06C9998E0FE5A9 flags verified ) ) game ( name "Street Fighter Alpha - Warriors' Dreams (Europe)" description "Street Fighter Alpha - Warriors' Dreams (Europe)" - rom ( name "Street Fighter Alpha - Warriors' Dreams (Europe).gbc" size 1048576 crc 28A3AB3A md5 2FFA53B90351C9A3390CA1F848435239 sha1 8BAAD8F1FE999D1EE352D534B1DBE6E10C0281FE ) + rom ( name "Street Fighter Alpha - Warriors' Dreams (Europe).gbc" size 1048576 crc 28a3ab3a sha1 8BAAD8F1FE999D1EE352D534B1DBE6E10C0281FE ) ) game ( name "Street Fighter Alpha - Warriors' Dreams (Japan)" description "Street Fighter Alpha - Warriors' Dreams (Japan)" - rom ( name "Street Fighter Alpha - Warriors' Dreams (Japan).gbc" size 1048576 crc 32739B34 md5 6ACD649D8AB0EC4F26B8CA3930434264 sha1 C0086C92381B1561153FBE97FA455FC8C6573C1D ) + rom ( name "Street Fighter Alpha - Warriors' Dreams (Japan).gbc" size 1048576 crc 32739b34 sha1 C0086C92381B1561153FBE97FA455FC8C6573C1D ) ) game ( name "Street Fighter Alpha - Warriors' Dreams (USA)" description "Street Fighter Alpha - Warriors' Dreams (USA)" - rom ( name "Street Fighter Alpha - Warriors' Dreams (USA).gbc" size 1048576 crc AA5F14D2 md5 DB1AEAA7135BD5707DBBCCC427808CD7 sha1 CA26852EE2C0E691CD0FC30A44DE84FD1465B4DE ) + rom ( name "Street Fighter Alpha - Warriors' Dreams (USA).gbc" size 1048576 crc aa5f14d2 sha1 CA26852EE2C0E691CD0FC30A44DE84FD1465B4DE ) ) game ( name "Street Hero (Taiwan) (En) (1B-004, EB-004, Sachen) (Unl)" description "Street Hero (Taiwan) (En) (1B-004, EB-004, Sachen) (Unl)" - rom ( name "Street Hero (Taiwan) (En) (1B-004, EB-004, Sachen) (Unl).gbc" size 393216 crc B580CB1F md5 102A290E0711214484555DE2176E565C sha1 F80FFCAF0757F16CE0E6940A2EC786EBD7549458 flags verified ) + rom ( name "Street Hero (Taiwan) (En) (1B-004, EB-004, Sachen) (Unl).gbc" size 393216 crc b580cb1f sha1 F80FFCAF0757F16CE0E6940A2EC786EBD7549458 flags verified ) ) game ( name "Stuart Little - The Journey Home (Europe) (Fr,De)" description "Stuart Little - The Journey Home (Europe) (Fr,De)" - rom ( name "Stuart Little - The Journey Home (Europe) (Fr,De).gbc" size 1048576 crc ACB08666 md5 6B2118817985DBB1BB36A804A8240641 sha1 153F8FFAB32E78DD4A6C2EEC4560B2CF6509774D ) + rom ( name "Stuart Little - The Journey Home (Europe) (Fr,De).gbc" size 1048576 crc acb08666 sha1 153F8FFAB32E78DD4A6C2EEC4560B2CF6509774D flags verified ) ) game ( name "Stuart Little - The Journey Home (USA, Europe)" description "Stuart Little - The Journey Home (USA, Europe)" - rom ( name "Stuart Little - The Journey Home (USA, Europe).gbc" size 1048576 crc EB273887 md5 AC38DFD19646CA6E143024D699145C70 sha1 D3C31E41709C54AF328787036DB1B98997F508EA flags verified ) + rom ( name "Stuart Little - The Journey Home (USA, Europe).gbc" size 1048576 crc eb273887 sha1 D3C31E41709C54AF328787036DB1B98997F508EA flags verified ) +) + +game ( + name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" + description "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" + rom ( name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl).gbc" size 2097152 crc 6a99a079 sha1 BCB683600278094E4D40A7DA0226B83EC1F92C81 flags verified ) +) + +game ( + name "Super 6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" + description "Super 6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl)" + rom ( name "Super 6 in 1 (Taiwan) (En,Zh) (6B-001, Sachen) (Unl).gbc" size 2097152 crc fb60d1c5 sha1 8670282E7EA22235E374D5DCD1BEB5AC54B35FE6 flags verified ) ) game ( name "Super Black Bass - Real Fight (Japan) (Rumble Version)" description "Super Black Bass - Real Fight (Japan) (Rumble Version)" - rom ( name "Super Black Bass - Real Fight (Japan) (Rumble Version).gbc" size 4194304 crc B7F77B6A md5 34FDA0252963CC5A24C7382AA12B72C6 sha1 8C587086F3DEC061027322DA305081E3AA06FF60 flags verified ) + rom ( name "Super Black Bass - Real Fight (Japan) (Rumble Version).gbc" size 4194304 crc b7f77b6a sha1 8C587086F3DEC061027322DA305081E3AA06FF60 flags verified ) ) game ( - name "Super Black Bass Pocket 3 (Japan) (SGB Enhanced)" - description "Super Black Bass Pocket 3 (Japan) (SGB Enhanced)" - rom ( name "Super Black Bass Pocket 3 (Japan) (SGB Enhanced).gbc" size 1048576 crc AE466545 md5 CF45B5414EC4515F7A1021C139EDD71E sha1 B416F8FE1D229BD4E90259F2E6A7D78DD1F7BF3E ) + name "Super Black Bass Pocket 3 (Japan) (SGB Enhanced) (GB Compatible)" + description "Super Black Bass Pocket 3 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Super Black Bass Pocket 3 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ae466545 sha1 B416F8FE1D229BD4E90259F2E6A7D78DD1F7BF3E flags verified ) ) game ( - name "Super Bombliss DX (Japan) (SGB Enhanced)" - description "Super Bombliss DX (Japan) (SGB Enhanced)" - rom ( name "Super Bombliss DX (Japan) (SGB Enhanced).gbc" size 262144 crc 34C8A4A5 md5 6DBC891774265F4BC8CCBA65F9383AEC sha1 44070E77EB2B56B67F979E444D404E56B67EDBB0 ) + name "Super Bombliss DX (Japan) (En) (SGB Enhanced) (GB Compatible)" + description "Super Bombliss DX (Japan) (En) (SGB Enhanced) (GB Compatible)" + rom ( name "Super Bombliss DX (Japan) (En) (SGB Enhanced) (GB Compatible).gbc" size 262144 crc 34c8a4a5 sha1 44070E77EB2B56B67F979E444D404E56B67EDBB0 ) ) game ( - name "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl)" - description "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl).gbc" size 524288 crc 6833923D md5 3383C2754015C4DA7B5295A28AC09739 sha1 5BD06600B35CD2B2E8D51EDE6F79DB76BA97E78E flags verified ) + name "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Super Breakout! (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 524288 crc 6833923d sha1 5BD06600B35CD2B2E8D51EDE6F79DB76BA97E78E flags verified ) ) game ( - name "Super Breakout! (USA)" - description "Super Breakout! (USA)" - rom ( name "Super Breakout! (USA).gbc" size 1048576 crc 52F51CB5 md5 9B8869FA36562A32EDEC76717632875E sha1 8C795B6D8EBC3A796821A6B2879F3E5CEBF9215C ) + name "Super Breakout! (USA) (GB Compatible)" + description "Super Breakout! (USA) (GB Compatible)" + rom ( name "Super Breakout! (USA) (GB Compatible).gbc" size 1048576 crc 52f51cb5 sha1 8C795B6D8EBC3A796821A6B2879F3E5CEBF9215C ) ) game ( name "Super Chinese Fighter EX (Japan)" description "Super Chinese Fighter EX (Japan)" - rom ( name "Super Chinese Fighter EX (Japan).gbc" size 1048576 crc DCDAA333 md5 A601E9009C88C7DCFAC8AAEA41DD45D8 sha1 0296D0A60933C798B21399195789D10EB319872F ) + rom ( name "Super Chinese Fighter EX (Japan).gbc" size 1048576 crc dcdaa333 sha1 0296D0A60933C798B21399195789D10EB319872F ) ) game ( name "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" description "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" - rom ( name "Super Doll Licca-chan - Kisekae Daisakusen (Japan).gbc" size 1048576 crc DF50473F md5 1E90FA6DAB5D51A09F0F6134C96EFA08 sha1 8BECF5A8834285F2AFF42812C8E44D864EE46D02 flags verified ) + rom ( name "Super Doll Licca-chan - Kisekae Daisakusen (Japan).gbc" size 1048576 crc df50473f sha1 8BECF5A8834285F2AFF42812C8E44D864EE46D02 flags verified ) ) game ( name "Super Gals! Kotobuki Ran (Japan)" description "Super Gals! Kotobuki Ran (Japan)" - rom ( name "Super Gals! Kotobuki Ran (Japan).gbc" size 4194304 crc 90379C16 md5 8B437E964CA98E785010160160CF380A sha1 FC18F5137D6063CA1AFE20F5D3ED544E527E6BCF flags verified ) + rom ( name "Super Gals! Kotobuki Ran (Japan).gbc" size 4194304 crc 90379c16 sha1 FC18F5137D6063CA1AFE20F5D3ED544E527E6BCF flags verified ) ) game ( name "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan)" description "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan)" - rom ( name "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan).gbc" size 4194304 crc E77FA0F2 md5 B2FE715038778210C0C2C8DD06B2A11F sha1 A724C6DD33B84AE9120D041FC49D66692C798DD0 ) + rom ( name "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan).gbc" size 4194304 crc e77fa0f2 sha1 A724C6DD33B84AE9120D041FC49D66692C798DD0 flags verified ) ) game ( name "Super Mario Bros. Deluxe (Japan) (NP)" description "Super Mario Bros. Deluxe (Japan) (NP)" - rom ( name "Super Mario Bros. Deluxe (Japan) (NP).gbc" size 1048576 crc 866B1212 md5 8040970140B2E728A0078504C2BCD908 sha1 94466F48D8B4F811608CE8641DE5F82315CD60B5 flags verified ) + rom ( name "Super Mario Bros. Deluxe (Japan) (NP).gbc" size 1048576 crc 866b1212 sha1 94466F48D8B4F811608CE8641DE5F82315CD60B5 flags verified ) ) game ( name "Super Mario Bros. Deluxe (USA, Europe)" description "Super Mario Bros. Deluxe (USA, Europe)" - rom ( name "Super Mario Bros. Deluxe (USA, Europe).gbc" size 1048576 crc A4CD26FF md5 EC764E03228D212CA794AC0B9DF62857 sha1 F84F26F22751B58ED57BD332274E18131660729A flags verified ) + rom ( name "Super Mario Bros. Deluxe (USA, Europe).gbc" size 1048576 crc a4cd26ff sha1 F84F26F22751B58ED57BD332274E18131660729A flags verified ) ) game ( - name "Super Mario Bros. Deluxe (USA, Europe) (Rev A)" - description "Super Mario Bros. Deluxe (USA, Europe) (Rev A)" - rom ( name "Super Mario Bros. Deluxe (USA, Europe) (Rev A).gbc" size 1048576 crc 90AB047B md5 1FD75C2B798C04ACD4B99AD2F1006280 sha1 07295CD60AE44183EBECB013930727E0404169D5 flags verified ) + name "Super Mario Bros. Deluxe (USA, Europe) (Rev 1)" + description "Super Mario Bros. Deluxe (USA, Europe) (Rev 1)" + rom ( name "Super Mario Bros. Deluxe (USA, Europe) (Rev 1).gbc" size 1048576 crc 90ab047b sha1 07295CD60AE44183EBECB013930727E0404169D5 flags verified ) ) game ( - name "Super Mario Bros. Deluxe (USA, Europe) (Rev B)" - description "Super Mario Bros. Deluxe (USA, Europe) (Rev B)" - rom ( name "Super Mario Bros. Deluxe (USA, Europe) (Rev B).gbc" size 1048576 crc 62BBAE83 md5 B5A71128227F5BC953FD55CB0025807F sha1 254F2254E9D54E2501E3E4EBE09491E03573A6A4 flags verified ) + name "Super Mario Bros. Deluxe (USA, Europe) (Rev 2)" + description "Super Mario Bros. Deluxe (USA, Europe) (Rev 2)" + rom ( name "Super Mario Bros. Deluxe (USA, Europe) (Rev 2).gbc" size 1048576 crc 62bbae83 sha1 254F2254E9D54E2501E3E4EBE09491E03573A6A4 flags verified ) +) + +game ( + name "Super Mario Bros. Deluxe (Japan) (En) (Rev 1) (NP)" + description "Super Mario Bros. Deluxe (Japan) (En) (Rev 1) (NP)" + rom ( name "Super Mario Bros. Deluxe (Japan) (En) (Rev 1) (NP).gbc" size 1048576 crc f4e91f63 sha1 E61D564E1FF19EB4B7C62A6CD96214F2BCA4B01D flags verified ) ) game ( name "Super Me-Mail GB - Me-Mail Bear no Happy Mail Town (Japan)" description "Super Me-Mail GB - Me-Mail Bear no Happy Mail Town (Japan)" - rom ( name "Super Me-Mail GB - Me-Mail Bear no Happy Mail Town (Japan).gbc" size 1048576 crc 315CAA18 md5 5D4CDBF3B54B6857C29CB24EBFAF2470 sha1 4B96D2447B763F08D079EB07B95B6627D3FC120B ) + rom ( name "Super Me-Mail GB - Me-Mail Bear no Happy Mail Town (Japan).gbc" size 1048576 crc 315caa18 sha1 4B96D2447B763F08D079EB07B95B6627D3FC120B flags verified ) ) game ( name "Super Nenas, Las - El Malvado Mojo Jojo (Spain)" description "Super Nenas, Las - El Malvado Mojo Jojo (Spain)" - rom ( name "Super Nenas, Las - El Malvado Mojo Jojo (Spain).gbc" size 2097152 crc EFE652BF md5 2AD76236E7EA4F655D7D36F3C504EC5E sha1 286CABC9EA92D1866E59748A788658C5E3D32A35 ) + rom ( name "Super Nenas, Las - El Malvado Mojo Jojo (Spain).gbc" size 2097152 crc efe652bf sha1 286CABC9EA92D1866E59748A788658C5E3D32A35 flags verified ) ) game ( name "Super Nenas, Las - Lucha Con Ese (Spain)" description "Super Nenas, Las - Lucha Con Ese (Spain)" - rom ( name "Super Nenas, Las - Lucha Con Ese (Spain).gbc" size 2097152 crc 7BA87C11 md5 6A38F9F550A6858F7CED15BA03D2A8CD sha1 06B0835C40D4F27AD45833D54F606A0964E09DE0 ) + rom ( name "Super Nenas, Las - Lucha Con Ese (Spain).gbc" size 2097152 crc 7ba87c11 sha1 06B0835C40D4F27AD45833D54F606A0964E09DE0 flags verified ) ) game ( name "Super Nenas, Las - Panico en Townsville (Spain)" description "Super Nenas, Las - Panico en Townsville (Spain)" - rom ( name "Super Nenas, Las - Panico en Townsville (Spain).gbc" size 2097152 crc 03EDB574 md5 5B36C3DA8BCFEE8A5F14A6DB12F533A3 sha1 34463C99193E4CF99AA1833242FA2B30DB9FE522 ) + rom ( name "Super Nenas, Las - Panico en Townsville (Spain).gbc" size 2097152 crc 03edb574 sha1 34463C99193E4CF99AA1833242FA2B30DB9FE522 flags verified ) ) game ( name "Super Real Fishing (Japan) (Rumble Version)" description "Super Real Fishing (Japan) (Rumble Version)" - rom ( name "Super Real Fishing (Japan) (Rumble Version).gbc" size 1048576 crc 00865161 md5 C259CF18B489D1DDECB4B7A04FEDFD2E sha1 CBD6CA89332EE11F89B580E53B53285760DD025A ) + rom ( name "Super Real Fishing (Japan) (Rumble Version).gbc" size 1048576 crc 00865161 sha1 CBD6CA89332EE11F89B580E53B53285760DD025A ) ) game ( name "Super Robot Pinball (Japan)" description "Super Robot Pinball (Japan)" - rom ( name "Super Robot Pinball (Japan).gbc" size 2097152 crc 6E330FCD md5 6C7DC7CE74088A9E42A6FB8D98A67714 sha1 2DBE45E3D5912B270B8BFACC5D9FFC836FE74284 flags verified ) + rom ( name "Super Robot Pinball (Japan).gbc" size 2097152 crc 6e330fcd sha1 2DBE45E3D5912B270B8BFACC5D9FFC836FE74284 flags verified ) ) game ( - name "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced)" - description "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced)" - rom ( name "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced).gbc" size 1048576 crc D24E592D md5 D710CD23E7E38023297D04E935DBEBAE sha1 E6C715042ADC4C1B52A7295E082953ADA79CF95E flags verified ) + name "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced) (GB Compatible)" + description "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Super Robot Taisen - Link Battler (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d24e592d sha1 E6C715042ADC4C1B52A7295E082953ADA79CF95E flags verified ) ) game ( name "Supercross Freestyle (Europe) (En,Fr,De,Es,It)" description "Supercross Freestyle (Europe) (En,Fr,De,Es,It)" - rom ( name "Supercross Freestyle (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 4D3E0F51 md5 DC640627128579EE52C3FB0FF38A96F0 sha1 4F4AA8353D230E3A65A7E68DBB3312AD871894DF flags verified ) + rom ( name "Supercross Freestyle (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 4d3e0f51 sha1 4F4AA8353D230E3A65A7E68DBB3312AD871894DF flags verified ) ) game ( name "Supreme Snowboarding (Europe) (En,Fr,De)" description "Supreme Snowboarding (Europe) (En,Fr,De)" - rom ( name "Supreme Snowboarding (Europe) (En,Fr,De).gbc" size 2097152 crc 53B1E661 md5 B9BC4621F069F59E22EEE05EEB6503CD sha1 4F745FFA0146E21BB26408CF7431376887499919 flags verified ) + rom ( name "Supreme Snowboarding (Europe) (En,Fr,De).gbc" size 2097152 crc 53b1e661 sha1 4F745FFA0146E21BB26408CF7431376887499919 flags verified ) ) game ( - name "Survival Kids (USA) (SGB Enhanced)" - description "Survival Kids (USA) (SGB Enhanced)" - rom ( name "Survival Kids (USA) (SGB Enhanced).gbc" size 1048576 crc C46ABA56 md5 07D4DF7A1C93F5BEF617E5A90B9EDEE2 sha1 0E3D3821710B07F68628EDDA071B928DF0C6A2F2 ) + name "Survival Kids (USA) (SGB Enhanced) (GB Compatible)" + description "Survival Kids (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "Survival Kids (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c46aba56 sha1 0E3D3821710B07F68628EDDA071B928DF0C6A2F2 ) ) game ( - name "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced)" - description "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced)" - rom ( name "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced).gbc" size 1048576 crc 19C2BD07 md5 41530A4366254265021EB0668AE9884D sha1 091AFC2743425E1846CFE356CF8CB0F3C4E14ED7 ) + name "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced) (GB Compatible)" + description "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Survival Kids - Kotou no Boukensha (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 61fa675c sha1 F80ABBEAA2CF0631C1CDF812C13F13F1FEA41F18 flags verified ) ) game ( - name "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced)" - description "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced)" - rom ( name "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced).gbc" size 1048576 crc AB8B25D8 md5 9D2F7E1AC30A46456A841C264963E5EA sha1 8FD720D5B035939B553910A3EC45C1BD052484EB flags verified ) + name "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced) (GB Compatible)" + description "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Survival Kids 2 - Dasshutsu!! Futago-Jima! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ab8b25d8 sha1 8FD720D5B035939B553910A3EC45C1BD052484EB flags verified ) ) game ( name "Suske en Wiske - De Tijdtemmers ~ Bob et Bobette - Les Dompteurs du Temps (Europe) (Fr,Nl)" description "Suske en Wiske - De Tijdtemmers ~ Bob et Bobette - Les Dompteurs du Temps (Europe) (Fr,Nl)" - rom ( name "Suske en Wiske - De Tijdtemmers ~ Bob et Bobette - Les Dompteurs du Temps (Europe) (Fr,Nl).gbc" size 524288 crc A4C6523D md5 AB3245958E1DDEA3209841C62CA8448E sha1 2B4B8C3A4A74FDF7ACC4138125FEA5D8F5A9A093 ) + rom ( name "Suske en Wiske - De Tijdtemmers ~ Bob et Bobette - Les Dompteurs du Temps (Europe) (Fr,Nl).gbc" size 524288 crc a4c6523d sha1 2B4B8C3A4A74FDF7ACC4138125FEA5D8F5A9A093 flags verified ) ) game ( name "Suzuki Alstare Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" description "Suzuki Alstare Extreme Racing (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Suzuki Alstare Extreme Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 524288 crc 0F7264BA md5 54051BC19CE1C0301710D7845717DBAD sha1 2489B5C2572246EDF3F28F9D62ABCDA9D63B62BF ) + rom ( name "Suzuki Alstare Extreme Racing (Europe) (En,Fr,De,Es,It,Nl).gbc" size 524288 crc 0f7264ba sha1 2489B5C2572246EDF3F28F9D62ABCDA9D63B62BF ) ) game ( - name "Sweet Ange (Japan) (SGB Enhanced)" - description "Sweet Ange (Japan) (SGB Enhanced)" - rom ( name "Sweet Ange (Japan) (SGB Enhanced).gbc" size 1048576 crc 4BE9B159 md5 8DC38A2906306949576E60B8D4BABC5F sha1 5B6F268D945BCDB070195459582F01B434C01495 flags verified ) + name "Sweet Ange (Japan) (SGB Enhanced) (GB Compatible)" + description "Sweet Ange (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sweet Ange (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 4be9b159 sha1 5B6F268D945BCDB070195459582F01B434C01495 flags verified ) ) game ( name "Swing (Germany)" description "Swing (Germany)" - rom ( name "Swing (Germany).gbc" size 1048576 crc 7041929D md5 C53D2F538F6A5F421C87F935A42AA912 sha1 C681530A49A5287EF59B4BAE02CB1F9E82C72386 flags verified ) + rom ( name "Swing (Germany).gbc" size 1048576 crc 7041929d sha1 C681530A49A5287EF59B4BAE02CB1F9E82C72386 flags verified ) ) game ( name "SWIV (Europe) (En,Fr,De,Es,It)" description "SWIV (Europe) (En,Fr,De,Es,It)" - rom ( name "SWIV (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 44D30B7A md5 3A00468EA1520A57F23F88D43CF8C067 sha1 7E037008EABF01FA647CDFB0D5C88766A6F77423 flags verified ) + rom ( name "SWIV (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 44d30b7a sha1 7E037008EABF01FA647CDFB0D5C88766A6F77423 flags verified ) ) game ( - name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced)" - description "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced)" - rom ( name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced).gbc" size 2097152 crc C6FE4497 md5 5B250AB006A50301F29E74551531BD7F sha1 440D0010386F3F2D658740CC6584558F546482A6 flags verified ) + name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" + description "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sylvanian Families - Otogi no Kuni no Pendant (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc c6fe4497 sha1 440D0010386F3F2D658740CC6584558F546482A6 flags verified ) ) game ( name "Sylvanian Families 2 - Irozuku Mori no Fantasy (Japan)" description "Sylvanian Families 2 - Irozuku Mori no Fantasy (Japan)" - rom ( name "Sylvanian Families 2 - Irozuku Mori no Fantasy (Japan).gbc" size 2097152 crc F82D391F md5 F16C1E8B98E0DBE969214FE3DF4562D1 sha1 16F5D02E0272FBB2B0A3C219487484C7013BA4FB ) + rom ( name "Sylvanian Families 2 - Irozuku Mori no Fantasy (Japan).gbc" size 2097152 crc f82d391f sha1 16F5D02E0272FBB2B0A3C219487484C7013BA4FB flags verified ) ) game ( name "Sylvanian Families 3 - Hoshi Furu Yoru no Sunadokei (Japan)" description "Sylvanian Families 3 - Hoshi Furu Yoru no Sunadokei (Japan)" - rom ( name "Sylvanian Families 3 - Hoshi Furu Yoru no Sunadokei (Japan).gbc" size 2097152 crc ABF32B8B md5 816CE6275D9D5C78B8497E8D0B6A9ECE sha1 AB279C72758CD2CA41A5F41CE3C9CAD9490AACA3 ) + rom ( name "Sylvanian Families 3 - Hoshi Furu Yoru no Sunadokei (Japan).gbc" size 2097152 crc abf32b8b sha1 AB279C72758CD2CA41A5F41CE3C9CAD9490AACA3 flags verified ) ) game ( - name "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced)" - description "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced)" - rom ( name "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced).gbc" size 1048576 crc 6DD8AC91 md5 08130CB33FE270321D04D056B85D2037 sha1 55230E865958F7301076A4354B6B8B083A494BAE ) + name "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced) (GB Compatible)" + description "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Sylvanian Melodies - Mori no Nakama to Odori Masho! (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6dd8ac91 sha1 55230E865958F7301076A4354B6B8B083A494BAE flags verified ) ) game ( - name "Sylvester and Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl)" - description "Sylvester and Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Sylvester and Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 6BB3B0DC md5 88E01DB4AEE70B3C48324F991D149A2A sha1 8999A54B27B51A078FB3776EC7842C56287F05DF ) + name "Sylvester & Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Sylvester & Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Sylvester & Tweety - Breakfast on the Run (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 6bb3b0dc sha1 8999A54B27B51A078FB3776EC7842C56287F05DF ) ) game ( - name "Tabaluga (Germany)" - description "Tabaluga (Germany)" - rom ( name "Tabaluga (Germany).gbc" size 1048576 crc F09F92D7 md5 89F251B40B2420AE1DDE4D22CA01ED72 sha1 D23FE68A0D95A8EFB5D4536B03C0A3FC250E8258 flags verified ) + name "Tabaluga (Germany) (GB Compatible)" + description "Tabaluga (Germany) (GB Compatible)" + rom ( name "Tabaluga (Germany) (GB Compatible).gbc" size 1048576 crc f09f92d7 sha1 D23FE68A0D95A8EFB5D4536B03C0A3FC250E8258 flags verified ) ) game ( - name "Taisen Tsumeshougi (Japan) (NP)" - description "Taisen Tsumeshougi (Japan) (NP)" - rom ( name "Taisen Tsumeshougi (Japan) (NP).gbc" size 1048576 crc 95310C8B md5 E49185B5B5268F17A923A459E84BED0D sha1 813B97785076D2A17B19FA48EE2E0047C54259E0 ) + name "Taisen Tsumeshougi (Japan) (NP) (GB Compatible)" + description "Taisen Tsumeshougi (Japan) (NP) (GB Compatible)" + rom ( name "Taisen Tsumeshougi (Japan) (NP) (GB Compatible).gbc" size 1048576 crc 95310c8b sha1 813B97785076D2A17B19FA48EE2E0047C54259E0 ) ) game ( - name "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced)" - description "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced)" - rom ( name "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced).gbc" size 1048576 crc 388C6760 md5 B59FA772B15A07F44110D5B7AA24B424 sha1 6A30D328417E085DCD10588D0A5AF90FF4BFA40D ) + name "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced) (GB Compatible)" + description "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Taito Memorial - Bubble Bobble (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 388c6760 sha1 6A30D328417E085DCD10588D0A5AF90FF4BFA40D ) ) game ( - name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced)" - description "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced)" - rom ( name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced).gbc" size 1048576 crc 6A0C272D md5 A11802247B7F38F508F71CB257FF76AB sha1 D6D90667EBF295016F01B4604AB03AB5B1876D00 ) + name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced) (GB Compatible)" + description "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Taito Memorial - Chase H.Q. - Secret Police (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6a0c272d sha1 D6D90667EBF295016F01B4604AB03AB5B1876D00 ) ) game ( - name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced)" - description "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced)" - rom ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced).gbc" size 2097152 crc 725CF31C md5 A3C65D746E0E171843E9013E8D8E1021 sha1 EF322F4160CEEBD8DA67758EBD73225190AF6D23 flags verified ) + name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" + description "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Tales of Phantasia - Narikiri Dungeon (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 725cf31c sha1 EF322F4160CEEBD8DA67758EBD73225190AF6D23 flags verified ) ) game ( - name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced)" - description "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced)" - rom ( name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced).gbc" size 2097152 crc CE8AE58C md5 E3EDBFE8ABA5DD198A9E2E0F0141785B sha1 F752E96602274A29006425A06086D8AB45E1075C ) + name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible)" + description "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Tanimura Hitoshi Ryuu Pachinko Kouryaku Daisakusen - Don Quijote ga Iku (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc ce8ae58c sha1 F752E96602274A29006425A06086D8AB45E1075C flags verified ) ) game ( name "Tarzan (France)" description "Tarzan (France)" - rom ( name "Tarzan (France).gbc" size 2097152 crc C503AFBB md5 410652F95C575FFDE3312E24C754DD2A sha1 9A4821570F565F7A1B3C7ABA3C7CD2E1C1A0B570 ) + rom ( name "Tarzan (France).gbc" size 2097152 crc c503afbb sha1 9A4821570F565F7A1B3C7ABA3C7CD2E1C1A0B570 flags verified ) ) game ( name "Tarzan (Germany)" description "Tarzan (Germany)" - rom ( name "Tarzan (Germany).gbc" size 2097152 crc 39D04581 md5 9D3E582F7A50CD50F37C848BA24EE382 sha1 AC8FC45CDDB749B471A9B3F234B72731363C3B14 flags verified ) + rom ( name "Tarzan (Germany).gbc" size 2097152 crc 39d04581 sha1 AC8FC45CDDB749B471A9B3F234B72731363C3B14 flags verified ) ) game ( name "Tarzan (Japan)" description "Tarzan (Japan)" - rom ( name "Tarzan (Japan).gbc" size 2097152 crc F2005973 md5 1473FA5D4A50760DBDB45CC1232C8B4B sha1 920C9AA99A6DD0CA53694E2553DE6388B2D22EAC ) + rom ( name "Tarzan (Japan).gbc" size 2097152 crc f2005973 sha1 920C9AA99A6DD0CA53694E2553DE6388B2D22EAC ) ) game ( name "Tarzan (USA, Europe)" description "Tarzan (USA, Europe)" - rom ( name "Tarzan (USA, Europe).gbc" size 2097152 crc 4224F930 md5 55FEA8E7BE17975374AB24518BD83171 sha1 CE23EAA9AEF5909883252D1340CF94E3483652B3 flags verified ) + rom ( name "Tarzan (USA, Europe).gbc" size 2097152 crc 4224f930 sha1 CE23EAA9AEF5909883252D1340CF94E3483652B3 flags verified ) +) + +game ( + name "Tasmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Tasmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Tasmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 683752a0 sha1 E96CE1658BB9063042C64A161130F95F925F215B flags verified ) +) + +game ( + name "Tasmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It) (GB Compatible)" + description "Tasmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Tasmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 3611d0d8 sha1 E8C2465D0503FD02BCC50B81CB1040FFF63BF513 ) ) game ( name "Taxi 2 (France)" description "Taxi 2 (France)" - rom ( name "Taxi 2 (France).gbc" size 1048576 crc 0FD9FFF0 md5 400D3090F58E68E3FC7D186C370C74BE sha1 76927FBF52A4C53DCD58208439EB3F285EC568FB ) + rom ( name "Taxi 2 (France).gbc" size 1048576 crc 0fd9fff0 sha1 76927FBF52A4C53DCD58208439EB3F285EC568FB ) ) game ( name "Taxi 3 (France)" description "Taxi 3 (France)" - rom ( name "Taxi 3 (France).gbc" size 1048576 crc 2838996F md5 72B6216FE3094D7798A359B9A4CDF7ED sha1 E43817C673D47B7587F542DCC9F74190C63629FF ) -) - -game ( - name "Tazmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It)" - description "Tazmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It)" - rom ( name "Tazmanian Devil - Munching Madness (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 683752A0 md5 6902207E70E62FB38A07F49FCEE77929 sha1 E96CE1658BB9063042C64A161130F95F925F215B flags verified ) -) - -game ( - name "Tazmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It)" - description "Tazmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It)" - rom ( name "Tazmanian Devil - Munching Madness (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 3611D0D8 md5 7B671745F13BCC3ABAA2D9351FC22F8F sha1 E8C2465D0503FD02BCC50B81CB1040FFF63BF513 ) + rom ( name "Taxi 3 (France).gbc" size 1048576 crc 2838996f sha1 E43817C673D47B7587F542DCC9F74190C63629FF flags verified ) ) game ( name "Tech Deck Skateboarding (USA, Europe)" description "Tech Deck Skateboarding (USA, Europe)" - rom ( name "Tech Deck Skateboarding (USA, Europe).gbc" size 1048576 crc C07EBE70 md5 5130D3EC4A93ACB84E3F2C3590A0E5A6 sha1 CD8D7F3EEA5DF5DCC257D07932C453303D0C64E1 flags verified ) + rom ( name "Tech Deck Skateboarding (USA, Europe).gbc" size 1048576 crc c07ebe70 sha1 CD8D7F3EEA5DF5DCC257D07932C453303D0C64E1 flags verified ) ) game ( name "Test Drive 2001 (USA)" description "Test Drive 2001 (USA)" - rom ( name "Test Drive 2001 (USA).gbc" size 2097152 crc BB894EC7 md5 4A1EEFB91466FD1A2368617D4E697C30 sha1 8B34597B90D048C3D483ACBA60EBB49F86BD93CC ) + rom ( name "Test Drive 2001 (USA).gbc" size 2097152 crc bb894ec7 sha1 8B34597B90D048C3D483ACBA60EBB49F86BD93CC ) ) game ( - name "Test Drive 6 (Europe) (En,Fr,De,Es,It)" - description "Test Drive 6 (Europe) (En,Fr,De,Es,It)" - rom ( name "Test Drive 6 (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 13691CEB md5 CFA42DE596FAAEB161BEA96D3F6B9E6A sha1 92E5B9911032E0B810FCB0B76A94BB117BCF107E ) + name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + description "Test Drive 6 (Europe) (En,Fr,De,Es,It) (GB Compatible)" + rom ( name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (GB Compatible).gbc" size 1048576 crc 13691ceb sha1 92E5B9911032E0B810FCB0B76A94BB117BCF107E flags verified ) ) game ( - name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample)" - description "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample)" - rom ( name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample).gbc" size 1048576 crc 2F179045 md5 87599B7F88AE1680B490251CFD417792 sha1 F50415339A36ECEA8A1207B6C197086372E29AB7 ) + name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample) (GB Compatible)" + description "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample) (GB Compatible)" + rom ( name "Test Drive 6 (Europe) (En,Fr,De,Es,It) (Sample) (GB Compatible).gbc" size 1048576 crc 2f179045 sha1 F50415339A36ECEA8A1207B6C197086372E29AB7 ) ) game ( - name "Test Drive 6 (USA)" - description "Test Drive 6 (USA)" - rom ( name "Test Drive 6 (USA).gbc" size 1048576 crc 5CE00547 md5 4A07F33107D47D904F80C53D0E857605 sha1 43EA5758FC6747014F024B567F5768EF43D5C841 ) + name "Test Drive 6 (USA) (GB Compatible)" + description "Test Drive 6 (USA) (GB Compatible)" + rom ( name "Test Drive 6 (USA) (GB Compatible).gbc" size 1048576 crc 5ce00547 sha1 43EA5758FC6747014F024B567F5768EF43D5C841 ) ) game ( name "Test Drive Cycles (USA)" description "Test Drive Cycles (USA)" - rom ( name "Test Drive Cycles (USA).gbc" size 1048576 crc E32BB06F md5 4DF8D03BB1853F949CF4A99DFFD21362 sha1 E9242949661FB34CE6D6FD521B04EB1926EAD070 ) + rom ( name "Test Drive Cycles (USA).gbc" size 1048576 crc e32bb06f sha1 E9242949661FB34CE6D6FD521B04EB1926EAD070 ) ) game ( name "Test Drive Le Mans (USA) (En,Fr,Es)" description "Test Drive Le Mans (USA) (En,Fr,Es)" - rom ( name "Test Drive Le Mans (USA) (En,Fr,Es).gbc" size 1048576 crc E6D6AC8F md5 ADB95251CFD973F8245E6A869925D6DA sha1 BF007BF9C22633D67B7B46AEF656D136DD2D9B25 ) + rom ( name "Test Drive Le Mans (USA) (En,Fr,Es).gbc" size 1048576 crc e6d6ac8f sha1 BF007BF9C22633D67B7B46AEF656D136DD2D9B25 ) ) game ( - name "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced)" - description "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced)" - rom ( name "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced).gbc" size 1048576 crc 0FDD5B9E md5 9F88BDC053B035240FF1478CA11E7C23 sha1 71B425CBC02FA20B1F28A7612E7AC259BD1338B0 ) + name "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced) (GB Compatible)" + description "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced) (GB Compatible)" + rom ( name "Test Drive Off-Road 3 (USA) (Rumble Version) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0fdd5b9e sha1 71B425CBC02FA20B1F28A7612E7AC259BD1338B0 ) ) game ( name "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan)" description "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan)" - rom ( name "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan).gbc" size 1048576 crc EAF6E4F2 md5 8339E84709EA33723FD11ED2F3E1ABEE sha1 AA7DD2044A7E1535DA67D7B9439E9771F736086A flags verified ) + rom ( name "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan).gbc" size 1048576 crc eaf6e4f2 sha1 AA7DD2044A7E1535DA67D7B9439E9771F736086A flags verified ) ) game ( - name "Tetris DX (World) (SGB Enhanced)" - description "Tetris DX (World) (SGB Enhanced)" - rom ( name "Tetris DX (World) (SGB Enhanced).gbc" size 524288 crc 69989152 md5 65973D7A1446346294F8CA9D2D1B7E66 sha1 7183BCB54DD35F3A07D8FE63339B768F13B8168D flags verified ) + name "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan) (Rev 1)" + description "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan) (Rev 1)" + rom ( name "Tetris Adventure - Susume Mickey to Nakama-tachi (Japan) (Rev 1).gbc" size 1048576 crc b7c0831f sha1 A8842E85F2C6DE4DB40B47C9640DAD59AE9D1C51 flags verified ) +) + +game ( + name "Tetris DX (World) (SGB Enhanced) (GB Compatible)" + description "Tetris DX (World) (SGB Enhanced) (GB Compatible)" + rom ( name "Tetris DX (World) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 69989152 sha1 7183BCB54DD35F3A07D8FE63339B768F13B8168D flags verified ) ) game ( name "Tezhong Budui 2 - Jidi (China) (Li Cheng) (Unl)" description "Tezhong Budui 2 - Jidi (China) (Li Cheng) (Unl)" - rom ( name "Tezhong Budui 2 - Jidi (China) (Li Cheng) (Unl).gbc" size 2097152 crc 0D17E940 md5 A6051D0058BE5B2F3BE03C87E51EFCF1 sha1 D1FDD5B289165126091F5FBA3DA05903198A8620 ) + rom ( name "Tezhong Budui 2 - Jidi (China) (Li Cheng) (Unl).gbc" size 2097152 crc a2c4f7b3 sha1 5B516C6CE57EED1791A9C20184357C583FEBDCB8 flags verified ) ) game ( name "TG Rally 2 (Europe)" description "TG Rally 2 (Europe)" - rom ( name "TG Rally 2 (Europe).gbc" size 1048576 crc 795A9992 md5 AB38E871B66EE8AD1BB8EA7D92934FD1 sha1 906F886C19C4800A7AC2612951E03A092665B22C ) + rom ( name "TG Rally 2 (Europe).gbc" size 1048576 crc 795a9992 sha1 906F886C19C4800A7AC2612951E03A092665B22C flags verified ) ) game ( - name "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 1CBEA1AA md5 BD34182264A2F503D4E6982718D3BB6D sha1 D6D4EB47595B72C9C3AD77B5F9FA85B76F0ACF4C flags verified ) + name "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + description "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible)" + rom ( name "Three Lions (Europe) (En,Fr,De,Es,It,Nl,Sv) (GB Compatible).gbc" size 1048576 crc 1cbea1aa sha1 D6D4EB47595B72C9C3AD77B5F9FA85B76F0ACF4C flags verified ) ) game ( name "Thunder Blast Man (Europe) (1B-003, Sachen) (Unl)" description "Thunder Blast Man (Europe) (1B-003, Sachen) (Unl)" - rom ( name "Thunder Blast Man (Europe) (1B-003, Sachen) (Unl).gbc" size 262144 crc 1A719EAD md5 A9EE7C9FCFE647A75D9F0CE4DDE1B64D sha1 676B5F0A304FB83BC04921BC617B7485AF529B38 flags verified ) + rom ( name "Thunder Blast Man (Europe) (1B-003, Sachen) (Unl).gbc" size 262144 crc 1a719ead sha1 676B5F0A304FB83BC04921BC617B7485AF529B38 flags verified ) ) game ( name "Thunderbirds (Europe)" description "Thunderbirds (Europe)" - rom ( name "Thunderbirds (Europe).gbc" size 2097152 crc B5BECECF md5 5164521245F41B0F3A51CFFE0704D21D sha1 4DF8353CBB74D368CC139899EABE5288E59ADAEB ) + rom ( name "Thunderbirds (Europe).gbc" size 2097152 crc b5bececf sha1 4DF8353CBB74D368CC139899EABE5288E59ADAEB ) ) game ( name "Thunderbirds (Europe) (En,Fr,De,Es,It)" description "Thunderbirds (Europe) (En,Fr,De,Es,It)" - rom ( name "Thunderbirds (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 36536324 md5 543FE119633338174899829B6D4C571F sha1 8C7585E41B8E38F4BC76BA315DC5E7A768C0C516 ) + rom ( name "Thunderbirds (Europe) (En,Fr,De,Es,It).gbc" size 2097152 crc 36536324 sha1 8C7585E41B8E38F4BC76BA315DC5E7A768C0C516 flags verified ) ) game ( - name "Tiger Woods PGA Tour 2000 (USA, Europe)" - description "Tiger Woods PGA Tour 2000 (USA, Europe)" - rom ( name "Tiger Woods PGA Tour 2000 (USA, Europe).gbc" size 1048576 crc A6DFB1D9 md5 C58361B88496E7AD0179B59122AFD687 sha1 46E81D5E7D4F41B3B0A0AB8B55A3592ABE6911F3 flags verified ) + name "Tiger Woods PGA Tour 2000 (USA, Europe) (GB Compatible)" + description "Tiger Woods PGA Tour 2000 (USA, Europe) (GB Compatible)" + rom ( name "Tiger Woods PGA Tour 2000 (USA, Europe) (GB Compatible).gbc" size 1048576 crc a6dfb1d9 sha1 46E81D5E7D4F41B3B0A0AB8B55A3592ABE6911F3 flags verified ) ) game ( - name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" - description "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" - rom ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De).gbc" size 1048576 crc B2205D49 md5 46ED332D95C5DA9A2007945FED9F8118 sha1 34AB01951490A9510A3E0D3493D25A2547761AEA ) + name "Tintin - Le Temple Du Soleil (Europe) (En,Fr,De)" + description "Tintin - Le Temple Du Soleil (Europe) (En,Fr,De)" + rom ( name "Tintin - Le Temple Du Soleil (Europe) (En,Fr,De).gbc" size 1048576 crc b2205d49 sha1 34AB01951490A9510A3E0D3493D25A2547761AEA ) ) game ( - name "Tintin in Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv)" - description "Tintin in Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv)" - rom ( name "Tintin in Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 6832F38A md5 8150A3978211939D367F48FFCD49F979 sha1 EEF17D4A827EFAB90C03083EDB0BEE534CD64188 ) + name "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv)" + description "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv)" + rom ( name "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 6832f38a sha1 EEF17D4A827EFAB90C03083EDB0BEE534CD64188 ) ) game ( name "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" description "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It)" - rom ( name "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 7AA371ED md5 8187BB1E84F676F110BDF2166B4498D2 sha1 3A30DC722739FBAA9924C855C83BE311BEFC8FF2 ) + rom ( name "Tiny Toon Adventures - Buster Saves the Day (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 7aa371ed sha1 3A30DC722739FBAA9924C855C83BE311BEFC8FF2 ) ) game ( name "Tiny Toon Adventures - Buster Saves the Day (USA)" description "Tiny Toon Adventures - Buster Saves the Day (USA)" - rom ( name "Tiny Toon Adventures - Buster Saves the Day (USA).gbc" size 1048576 crc 800EFB3D md5 5A93ECB5781A3338C99E35BD06CC6127 sha1 A3953E9ADE5367558F7D430D2DFB83D06C361170 ) + rom ( name "Tiny Toon Adventures - Buster Saves the Day (USA).gbc" size 1048576 crc 800efb3d sha1 A3953E9ADE5367558F7D430D2DFB83D06C361170 ) ) game ( name "Tiny Toon Adventures - Dizzy's Candy Quest (Europe) (En,Fr,De,Es,It,Nl)" description "Tiny Toon Adventures - Dizzy's Candy Quest (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tiny Toon Adventures - Dizzy's Candy Quest (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 5A0D41AA md5 F2F1E41F5843C54C35E731445D6A2BEB sha1 CF8948C148AF76C00E7B6B557C5451D9BE364F55 ) + rom ( name "Tiny Toon Adventures - Dizzy's Candy Quest (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 5a0d41aa sha1 CF8948C148AF76C00E7B6B557C5451D9BE364F55 ) ) game ( name "Titi - Le Tour du Monde en 80 Chats (France)" description "Titi - Le Tour du Monde en 80 Chats (France)" - rom ( name "Titi - Le Tour du Monde en 80 Chats (France).gbc" size 1048576 crc CE55ED18 md5 D8595AF2C6A3DBB2659ACADBC9440515 sha1 1B3E161DCDE3709CC4B26D6D753CB879AB75C8C0 ) + rom ( name "Titi - Le Tour du Monde en 80 Chats (France).gbc" size 1048576 crc ce55ed18 sha1 1B3E161DCDE3709CC4B26D6D753CB879AB75C8C0 ) ) game ( - name "Titus the Fox to Marrakech and Back (Europe)" - description "Titus the Fox to Marrakech and Back (Europe)" - rom ( name "Titus the Fox to Marrakech and Back (Europe).gbc" size 1048576 crc 2F9F19DE md5 3B2F918967698C3EEF1F04EF7CD5601A sha1 B595C2E0A11BF843E91E9128E38252222133659B ) + name "Titus the Fox (Europe) (GB Compatible)" + description "Titus the Fox (Europe) (GB Compatible)" + rom ( name "Titus the Fox (Europe) (GB Compatible).gbc" size 1048576 crc 2f9f19de sha1 B595C2E0A11BF843E91E9128E38252222133659B ) ) game ( - name "Titus the Fox to Marrakech and Back (USA)" - description "Titus the Fox to Marrakech and Back (USA)" - rom ( name "Titus the Fox to Marrakech and Back (USA).gbc" size 1048576 crc BA70D28F md5 3F45AAEB406C50D03FC6984908FCBFA5 sha1 3EC16A3CE1CFDC03B6F3B04A455C8B5C54A37EEE ) + name "Titus the Fox (USA) (GB Compatible)" + description "Titus the Fox (USA) (GB Compatible)" + rom ( name "Titus the Fox (USA) (GB Compatible).gbc" size 1048576 crc ba70d28f sha1 3EC16A3CE1CFDC03B6F3B04A455C8B5C54A37EEE ) ) game ( - name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced)" - description "TNN Outdoors Fishing Champ (USA) (SGB Enhanced)" - rom ( name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced).gbc" size 1048576 crc 00A14D18 md5 6B7D527D4B2062AC2BE2CAB73AEEBFE5 sha1 ACFE7C9EDD20F7D6B155DEEBC9428703EDF28978 ) + name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced) (GB Compatible)" + description "TNN Outdoors Fishing Champ (USA) (SGB Enhanced) (GB Compatible)" + rom ( name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 00a14d18 sha1 ACFE7C9EDD20F7D6B155DEEBC9428703EDF28978 ) ) game ( name "TOCA Touring Car Championship (USA, Europe)" description "TOCA Touring Car Championship (USA, Europe)" - rom ( name "TOCA Touring Car Championship (USA, Europe).gbc" size 1048576 crc B509892B md5 2348EA9E0C1041610115443165CF8F4F sha1 8A759A627B436C2B3941C3AA480E38488AD16197 flags verified ) + rom ( name "TOCA Touring Car Championship (USA, Europe).gbc" size 1048576 crc b509892b sha1 8A759A627B436C2B3941C3AA480E38488AD16197 flags verified ) ) game ( name "Toki Tori (USA, Europe) (En,Ja,Fr,De,Es)" description "Toki Tori (USA, Europe) (En,Ja,Fr,De,Es)" - rom ( name "Toki Tori (USA, Europe) (En,Ja,Fr,De,Es).gbc" size 1048576 crc 0A0F9289 md5 E1BF59102BCD5E3601F4B24B3E873FD2 sha1 2025275BB55710594E990AB61CDE622947A2FA8D flags verified ) + rom ( name "Toki Tori (USA, Europe) (En,Ja,Fr,De,Es).gbc" size 1048576 crc 0a0f9289 sha1 2025275BB55710594E990AB61CDE622947A2FA8D flags verified ) ) game ( - name "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced)" - description "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced)" - rom ( name "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced).gbc" size 4194304 crc 4BE4A8ED md5 25AD12B8D2436D520057F12253F2D37D sha1 0F64C4AFE74B6CFD693B6C65F0168DCB26224443 ) + name "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced) (GB Compatible)" + description "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Tokimeki Memorial Pocket - Culture Hen - Komorebi no Melody (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 4be4a8ed sha1 0F64C4AFE74B6CFD693B6C65F0168DCB26224443 ) ) game ( - name "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced)" - description "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced)" - rom ( name "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced).gbc" size 4194304 crc 78E14FA9 md5 20B1ED1AE966B173C3A0F7F7F267E408 sha1 CE39FCF903BB3B0529205CAB4A412BFA0E8A2EBF ) + name "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced) (GB Compatible)" + description "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Tokimeki Memorial Pocket - Sport Hen - Koutei no Photograph (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 78e14fa9 sha1 CE39FCF903BB3B0529205CAB4A412BFA0E8A2EBF flags verified ) ) game ( - name "Tokoro-san no Setagaya C.C. (Japan)" - description "Tokoro-san no Setagaya C.C. (Japan)" - rom ( name "Tokoro-san no Setagaya C.C. (Japan).gbc" size 1048576 crc 9139E307 md5 2B77458EF761618D869EB1713D567AA4 sha1 F38D776FF74D02C2EDCE0DCBC84EDD5601EE315A ) + name "Tokoro-san no Setagaya C.C. (Japan) (GB Compatible)" + description "Tokoro-san no Setagaya C.C. (Japan) (GB Compatible)" + rom ( name "Tokoro-san no Setagaya C.C. (Japan) (GB Compatible).gbc" size 1048576 crc 9139e307 sha1 F38D776FF74D02C2EDCE0DCBC84EDD5601EE315A ) ) game ( - name "Tom & Jerry (USA, Europe)" - description "Tom & Jerry (USA, Europe)" - rom ( name "Tom & Jerry (USA, Europe).gbc" size 1048576 crc B97C0BD9 md5 FAC13870841C0F570FFF95B0C53A6E24 sha1 86D841E84C68E4D15F4BBF72F1AA0FDDC86DCD34 flags verified ) + name "Tom and Jerry (USA, Europe)" + description "Tom and Jerry (USA, Europe)" + rom ( name "Tom and Jerry (USA, Europe).gbc" size 1048576 crc b97c0bd9 sha1 86D841E84C68E4D15F4BBF72F1AA0FDDC86DCD34 flags verified ) ) game ( - name "Tom and Jerry - Mousehunt (Europe) (En,Fr,De,Es,It)" - description "Tom and Jerry - Mousehunt (Europe) (En,Fr,De,Es,It)" - rom ( name "Tom and Jerry - Mousehunt (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 3E17D04A md5 57B59BC623B05385AB27A0D7E18295A1 sha1 6F837075D7493ADCBD5B18BA1E27386B6FC31E62 ) + name "Tom and Jerry - Mouse Hunt (Europe) (En,Fr,De,Es,It)" + description "Tom and Jerry - Mouse Hunt (Europe) (En,Fr,De,Es,It)" + rom ( name "Tom and Jerry - Mouse Hunt (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 3e17d04a sha1 6F837075D7493ADCBD5B18BA1E27386B6FC31E62 ) ) game ( - name "Tom and Jerry - Mousehunt (USA) (En,Fr,Es)" - description "Tom and Jerry - Mousehunt (USA) (En,Fr,Es)" - rom ( name "Tom and Jerry - Mousehunt (USA) (En,Fr,Es).gbc" size 1048576 crc 5FC6BEC0 md5 9B2D3DFD0F545B1AC8B10B25F9FBE56B sha1 99C71A51921D802A0FCAEA1F67B54EF4EC653900 ) + name "Tom and Jerry - Mouse Hunt (USA) (En,Fr,Es)" + description "Tom and Jerry - Mouse Hunt (USA) (En,Fr,Es)" + rom ( name "Tom and Jerry - Mouse Hunt (USA) (En,Fr,Es).gbc" size 1048576 crc 5fc6bec0 sha1 99C71A51921D802A0FCAEA1F67B54EF4EC653900 ) ) game ( - name "Tom and Jerry in Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da)" - description "Tom and Jerry in Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Tom and Jerry in Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 2097152 crc 9D9C84F4 md5 E43684F551FD471B7DD2D694748CDDE1 sha1 FF3A39CCDF4E9802B38C3095D4A2AE056DEFC476 ) + name "Tom and Jerry in - Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da)" + description "Tom and Jerry in - Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da)" + rom ( name "Tom and Jerry in - Mouse Attacks! (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 2097152 crc 9d9c84f4 sha1 FF3A39CCDF4E9802B38C3095D4A2AE056DEFC476 ) ) game ( - name "Tom and Jerry in Mouse Attacks! (USA)" - description "Tom and Jerry in Mouse Attacks! (USA)" - rom ( name "Tom and Jerry in Mouse Attacks! (USA).gbc" size 2097152 crc 38CE3F76 md5 7A826122CCC3818DCE9A8E8DB6D77EDB sha1 A58215E2C6240B42779665D85484F02B79A0F9D8 ) + name "Tom and Jerry in - Mouse Attacks! (USA)" + description "Tom and Jerry in - Mouse Attacks! (USA)" + rom ( name "Tom and Jerry in - Mouse Attacks! (USA).gbc" size 2097152 crc 38ce3f76 sha1 A58215E2C6240B42779665D85484F02B79A0F9D8 ) +) + +game ( + name "Tom and Jerry in - Mouse Attacks! (USA) (Rev 1)" + description "Tom and Jerry in - Mouse Attacks! (USA) (Rev 1)" + rom ( name "Tom and Jerry in - Mouse Attacks! (USA) (Rev 1).gbc" size 2097152 crc ce4ca7b1 sha1 89374D81045A3BEDF24E42B58CE403B0A5FBCDDB flags verified ) ) game ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De)" description "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De)" - rom ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De).gbc" size 1048576 crc E72F2683 md5 6E863B582BDDB6126BB63633F41BEFD8 sha1 7E9E21DB84D1BFDAB3C604C9E3328F624F86A9B1 flags verified ) + rom ( name "Tom Clancy's Rainbow Six (USA, Europe) (En,Fr,De).gbc" size 1048576 crc e72f2683 sha1 7E9E21DB84D1BFDAB3C604C9E3328F624F86A9B1 flags verified ) ) game ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It)" description "Tomb Raider (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 2988FC78 md5 74B9B221C2B32147422144B327BD5F30 sha1 208B054CA63C43F32BEFA989C75E8DE96847F4FE flags verified ) + rom ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It).gbc" size 4194304 crc 2988fc78 sha1 208B054CA63C43F32BEFA989C75E8DE96847F4FE flags verified ) ) game ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It) (Beta)" description "Tomb Raider (USA, Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It) (Beta).gbc" size 4194304 crc 58590868 md5 545B4875C01233EDBDC6C2CD001AEC25 sha1 3F7259E9DEF8BE46E9B1F2956182084276F105ED ) + rom ( name "Tomb Raider (USA, Europe) (En,Fr,De,Es,It) (Beta).gbc" size 4194304 crc 58590868 sha1 3F7259E9DEF8BE46E9B1F2956182084276F105ED ) ) game ( name "Tomb Raider - Curse of the Sword (USA, Europe)" description "Tomb Raider - Curse of the Sword (USA, Europe)" - rom ( name "Tomb Raider - Curse of the Sword (USA, Europe).gbc" size 4194304 crc 02C1035A md5 A0B4538F687FC61BC88F7EE111170355 sha1 C84DB1EAF7403BA292BE020D410AB453342AB737 flags verified ) + rom ( name "Tomb Raider - Curse of the Sword (USA, Europe).gbc" size 4194304 crc 02c1035a sha1 C84DB1EAF7403BA292BE020D410AB453342AB737 flags verified ) ) game ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" description "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc A8628F7A md5 B5F00D021A370663458B346FAD6903CC sha1 D9ED647746CF23F2F9C7448D682AC34BB7F2EC1C ) + rom ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc a8628f7a sha1 D9ED647746CF23F2F9C7448D682AC34BB7F2EC1C ) ) game ( name "Tonka Construction Site (USA)" description "Tonka Construction Site (USA)" - rom ( name "Tonka Construction Site (USA).gbc" size 1048576 crc 8142A3E8 md5 87422721DD67B96736861358C71D5A8B sha1 19E6FB8B61EC20025061B2703079DB926BE93C96 ) + rom ( name "Tonka Construction Site (USA).gbc" size 1048576 crc 8142a3e8 sha1 19E6FB8B61EC20025061B2703079DB926BE93C96 ) ) game ( name "Tonka Raceway (Europe)" description "Tonka Raceway (Europe)" - rom ( name "Tonka Raceway (Europe).gbc" size 1048576 crc E108B2C2 md5 618E8914445053D1BD0901AD5297F927 sha1 EC52838E58D33A3ED36CD0F80F287EF72A578624 flags verified ) + rom ( name "Tonka Raceway (Europe).gbc" size 1048576 crc e108b2c2 sha1 EC52838E58D33A3ED36CD0F80F287EF72A578624 flags verified ) ) game ( name "Tonka Raceway (USA)" description "Tonka Raceway (USA)" - rom ( name "Tonka Raceway (USA).gbc" size 1048576 crc BC07F4FB md5 476902451BD5DA0F854A5C1681495B94 sha1 9159B2FFE1ECF2A1A8F6AF976E2737C0B22CEA6D ) + rom ( name "Tonka Raceway (USA).gbc" size 1048576 crc bc07f4fb sha1 9159B2FFE1ECF2A1A8F6AF976E2737C0B22CEA6D flags verified ) ) game ( name "Tonka Raceway (USA) (Rumble Version)" description "Tonka Raceway (USA) (Rumble Version)" - rom ( name "Tonka Raceway (USA) (Rumble Version).gbc" size 1048576 crc A5AF4B28 md5 E4E5488D10D69C4C12EB2A9A522FFC7B sha1 6A86B7172C53A8E67F3D72F953116991640F6E71 ) -) - -game ( - name "Tony Hawk's Pro Skater (USA, Europe)" - description "Tony Hawk's Pro Skater (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater (USA, Europe).gbc" size 1048576 crc 8D8BB5C4 md5 75BE6E3561908E705D9E790B34EDDB4D sha1 44236627939371A6DB564852F0536F969B21595E flags verified ) + rom ( name "Tonka Raceway (USA) (Rumble Version).gbc" size 1048576 crc a5af4b28 sha1 6A86B7172C53A8E67F3D72F953116991640F6E71 ) ) game ( name "Tony Hawk's Pro Skater 2 (USA, Europe)" description "Tony Hawk's Pro Skater 2 (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater 2 (USA, Europe).gbc" size 2097152 crc 2C27C61F md5 0454B25266D645990B63B5B406672DC2 sha1 300FE89F98711853BEE86CCD81481D55B5097B2D flags verified ) + rom ( name "Tony Hawk's Pro Skater 2 (USA, Europe).gbc" size 2097152 crc 2c27c61f sha1 300FE89F98711853BEE86CCD81481D55B5097B2D flags verified ) ) game ( name "Tony Hawk's Pro Skater 3 (USA, Europe)" description "Tony Hawk's Pro Skater 3 (USA, Europe)" - rom ( name "Tony Hawk's Pro Skater 3 (USA, Europe).gbc" size 1048576 crc FD5290A1 md5 365F913D6F2B0F44D87B7A347DAEA528 sha1 BD210707DF413D97EAA1D5B050F3A1B859C30C5E flags verified ) + rom ( name "Tony Hawk's Pro Skater 3 (USA, Europe).gbc" size 1048576 crc fd5290a1 sha1 BD210707DF413D97EAA1D5B050F3A1B859C30C5E flags verified ) +) + +game ( + name "Tony Hawk's Skateboarding ~ Tony Hawk's Pro Skater (USA, Europe)" + description "Tony Hawk's Skateboarding ~ Tony Hawk's Pro Skater (USA, Europe)" + rom ( name "Tony Hawk's Skateboarding ~ Tony Hawk's Pro Skater (USA, Europe).gbc" size 1048576 crc 8d8bb5c4 sha1 44236627939371A6DB564852F0536F969B21595E flags verified ) ) game ( name "Toobin' (USA)" description "Toobin' (USA)" - rom ( name "Toobin' (USA).gbc" size 1048576 crc 3D6B598C md5 D9575286A0DA1DA5F6036F649024298C sha1 BA5A1889F63AC13A1081885F0FCBE4C351C63FEA ) + rom ( name "Toobin' (USA).gbc" size 1048576 crc 3d6b598c sha1 BA5A1889F63AC13A1081885F0FCBE4C351C63FEA ) ) game ( name "Toonsylvania (Europe) (En,Fr,De,Es,It,Nl)" description "Toonsylvania (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Toonsylvania (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 6573B88F md5 91FD1E446EF8AF51080409B7940391E9 sha1 48943F0F5D47444889F78DA7EE0472D9B42DBC89 flags verified ) + rom ( name "Toonsylvania (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 6573b88f sha1 48943F0F5D47444889F78DA7EE0472D9B42DBC89 flags verified ) ) game ( name "Toonsylvania (USA)" description "Toonsylvania (USA)" - rom ( name "Toonsylvania (USA).gbc" size 1048576 crc 096D0C27 md5 F70756D7502B1374E05C7FCE48A4D283 sha1 5665F54D1CE0B1E0EF72D8F71A14594920ADF81D ) + rom ( name "Toonsylvania (USA).gbc" size 1048576 crc 096d0c27 sha1 5665F54D1CE0B1E0EF72D8F71A14594920ADF81D ) ) game ( name "Tootuff (Europe) (En,Fr,De,Es,It,Nl)" description "Tootuff (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Tootuff (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 1972CBF7 md5 4639D79E2E02A687A44D19D9C9C3C28A sha1 E38C16213C6BB0C1511ADE138E3E8EEABD7B8898 ) + rom ( name "Tootuff (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 1972cbf7 sha1 E38C16213C6BB0C1511ADE138E3E8EEABD7B8898 ) ) game ( - name "Top Gear Pocket (Japan) (Rumble Version)" - description "Top Gear Pocket (Japan) (Rumble Version)" - rom ( name "Top Gear Pocket (Japan) (Rumble Version).gbc" size 1048576 crc EBCCA3DA md5 B3F1A058F5702384AF5E5D79EE855824 sha1 19C861E8CE24C18F8C625C8B920AAD8A0ACFCE64 flags verified ) + name "Top Gear Pocket (Japan) (En) (Rumble Version)" + description "Top Gear Pocket (Japan) (En) (Rumble Version)" + rom ( name "Top Gear Pocket (Japan) (En) (Rumble Version).gbc" size 1048576 crc ebcca3da sha1 19C861E8CE24C18F8C625C8B920AAD8A0ACFCE64 flags verified ) ) game ( name "Top Gear Pocket (USA) (Rumble Version)" description "Top Gear Pocket (USA) (Rumble Version)" - rom ( name "Top Gear Pocket (USA) (Rumble Version).gbc" size 1048576 crc 84499FC1 md5 809251D6205BC712211FBCAB55190A3A sha1 F875F5A637FB861A0845B1753B90FE053D0A5A95 ) + rom ( name "Top Gear Pocket (USA) (Rumble Version).gbc" size 1048576 crc 84499fc1 sha1 F875F5A637FB861A0845B1753B90FE053D0A5A95 ) ) game ( name "Top Gear Pocket 2 (Japan) (Rumble Version)" description "Top Gear Pocket 2 (Japan) (Rumble Version)" - rom ( name "Top Gear Pocket 2 (Japan) (Rumble Version).gbc" size 1048576 crc 1845F25A md5 84EE1AC070C9695B6D422ADB5525DB85 sha1 26A357B6DF4484D8F98F9C89A0B1B0357DF5CF88 flags verified ) + rom ( name "Top Gear Pocket 2 (Japan) (Rumble Version).gbc" size 1048576 crc 1845f25a sha1 26A357B6DF4484D8F98F9C89A0B1B0357DF5CF88 flags verified ) ) game ( name "Top Gear Pocket 2 (USA)" description "Top Gear Pocket 2 (USA)" - rom ( name "Top Gear Pocket 2 (USA).gbc" size 1048576 crc EFB87F80 md5 7D9585C947A7637703FB8CCD6A691ED7 sha1 BDBB64D13C3C40992D923829A92D7A15A15AABEA ) + rom ( name "Top Gear Pocket 2 (USA).gbc" size 1048576 crc efb87f80 sha1 BDBB64D13C3C40992D923829A92D7A15A15AABEA ) ) game ( name "Top Gear Rally (Europe) (Rumble Version)" description "Top Gear Rally (Europe) (Rumble Version)" - rom ( name "Top Gear Rally (Europe) (Rumble Version).gbc" size 1048576 crc 337E5DD3 md5 B173870C83682E97FCC43B6D3EE9AC7F sha1 B880F5CFDE3724DA3FF932BF766CEE470C4F664C flags verified ) + rom ( name "Top Gear Rally (Europe) (Rumble Version).gbc" size 1048576 crc 337e5dd3 sha1 B880F5CFDE3724DA3FF932BF766CEE470C4F664C flags verified ) ) game ( name "Top Gear Rally 2 (Europe)" description "Top Gear Rally 2 (Europe)" - rom ( name "Top Gear Rally 2 (Europe).gbc" size 1048576 crc 017773CD md5 0A1CF1904C87B60308C404D93BAB2702 sha1 5A0AC4ACE1D5C2B6DFC0BDD20D6F88F319493558 ) + rom ( name "Top Gear Rally 2 (Europe).gbc" size 1048576 crc 017773cd sha1 5A0AC4ACE1D5C2B6DFC0BDD20D6F88F319493558 ) ) game ( name "Top Gun - Fire Storm (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Top Gun - Fire Storm (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Top Gun - Fire Storm (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc E2AD5A0F md5 E8B4A4231325ADC851229BBDE40D2284 sha1 BAD3F0770E7595AD7B4FD68D8212A902974FE1E1 flags verified ) + rom ( name "Top Gun - Fire Storm (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc e2ad5a0f sha1 BAD3F0770E7595AD7B4FD68D8212A902974FE1E1 flags verified ) ) game ( - name "Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" - description "Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Total Soccer 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc C25EE35A md5 4B497DFA757C4C54C67089507A71A715 sha1 BE0703EE2667DDC53CFF9D6C7D22B30D272C0738 flags verified ) -) - -game ( - name "Totsugeki! Papparatai (Japan) (SGB Enhanced)" - description "Totsugeki! Papparatai (Japan) (SGB Enhanced)" - rom ( name "Totsugeki! Papparatai (Japan) (SGB Enhanced).gbc" size 4194304 crc 0AEAE8FB md5 D952041D1970551EE4BEDBE341556E6F sha1 4C98BEAB325CD058445102C85D30B3724325F2CE ) + name "Totsugeki! Papparatai (Japan) (SGB Enhanced) (GB Compatible)" + description "Totsugeki! Papparatai (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Totsugeki! Papparatai (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc 0aeae8fb sha1 4C98BEAB325CD058445102C85D30B3724325F2CE ) ) game ( name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan)" description "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan)" - rom ( name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan).gbc" size 1048576 crc 19EB4516 md5 30F38B2BE2450F14838A98C5711E303B sha1 FED38C5131A00F0BBF00FF2A974A8E457373ABA6 flags verified ) + rom ( name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan).gbc" size 1048576 crc 19eb4516 sha1 FED38C5131A00F0BBF00FF2A974A8E457373ABA6 flags verified ) ) game ( - name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev A)" - description "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev A)" - rom ( name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev A).gbc" size 1048576 crc D549E074 md5 5563E6E09898599A781750D9CE9F0259 sha1 369F53D1A8BC7E6F2D1CCD101E648C2744C39FC5 ) + name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev 1)" + description "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev 1)" + rom ( name "Tottoko Hamutarou - Tomodachi Daisakusen Dechu (Japan) (Rev 1).gbc" size 1048576 crc d549e074 sha1 369F53D1A8BC7E6F2D1CCD101E648C2744C39FC5 flags verified ) ) game ( name "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan)" description "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan)" - rom ( name "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan).gbc" size 2097152 crc F1FBCF84 md5 32F31220DD01F329BE0279E6F5CD6BFF sha1 ADB1D5242A62D41C6E435B31082685EA4EEC651A ) + rom ( name "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan).gbc" size 2097152 crc f1fbcf84 sha1 ADB1D5242A62D41C6E435B31082685EA4EEC651A flags verified ) ) game ( name "Towers - Lord Baniff's Deceit (USA, Europe)" description "Towers - Lord Baniff's Deceit (USA, Europe)" - rom ( name "Towers - Lord Baniff's Deceit (USA, Europe).gbc" size 1048576 crc 7B9B2468 md5 0D7BCA4E08D522493491484896F7F3CC sha1 E1324E5D7F61225366BD8DCF6079C171D23E89CA flags verified ) + rom ( name "Towers - Lord Baniff's Deceit (USA, Europe).gbc" size 1048576 crc 7b9b2468 sha1 E1324E5D7F61225366BD8DCF6079C171D23E89CA flags verified ) ) game ( - name "Toy Story 2 (USA, Europe) (SGB Enhanced)" - description "Toy Story 2 (USA, Europe) (SGB Enhanced)" - rom ( name "Toy Story 2 (USA, Europe) (SGB Enhanced).gbc" size 1048576 crc 47AECB95 md5 EF032B6F603B3A290A91D40CB9C4B3E6 sha1 0C8506DE2349ECF5241692DA2AFF239A0C40D862 flags verified ) + name "Toy Story 2 (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Toy Story 2 (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Toy Story 2 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 47aecb95 sha1 0C8506DE2349ECF5241692DA2AFF239A0C40D862 flags verified ) ) game ( name "Toy Story Racer (Europe) (En,Fr,De)" description "Toy Story Racer (Europe) (En,Fr,De)" - rom ( name "Toy Story Racer (Europe) (En,Fr,De).gbc" size 2097152 crc F660ED94 md5 3E3C0FF63A8F5DE3C13A60B82CEA89D9 sha1 1D06B1B563EC34014A8EABFD557E20EE03154FF9 ) + rom ( name "Toy Story Racer (Europe) (En,Fr,De).gbc" size 2097152 crc f660ed94 sha1 1D06B1B563EC34014A8EABFD557E20EE03154FF9 ) ) game ( name "Toy Story Racer (USA, Europe)" description "Toy Story Racer (USA, Europe)" - rom ( name "Toy Story Racer (USA, Europe).gbc" size 2097152 crc D911DD97 md5 01A67ED2DC935044BA69EDA42BDDEBF3 sha1 5DEB31321A86B260AA84CAB5E45A3FA36CE5EFBD flags verified ) + rom ( name "Toy Story Racer (USA, Europe).gbc" size 2097152 crc d911dd97 sha1 5DEB31321A86B260AA84CAB5E45A3FA36CE5EFBD flags verified ) ) game ( - name "Trade & Battle Card Hero (Japan) (SGB Enhanced)" - description "Trade & Battle Card Hero (Japan) (SGB Enhanced)" - rom ( name "Trade & Battle Card Hero (Japan) (SGB Enhanced).gbc" size 2097152 crc B18CBA2A md5 92D36245A65305A209700608971B0597 sha1 9787A4583899720FF80A9E478CA096BA5DF38FB3 flags verified ) + name "Trade & Battle Card Hero (Japan) (SGB Enhanced) (GB Compatible)" + description "Trade & Battle Card Hero (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Trade & Battle Card Hero (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b18cba2a sha1 9787A4583899720FF80A9E478CA096BA5DF38FB3 flags verified ) +) + +game ( + name "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible)" + description "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible)" + rom ( name "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d98a877d sha1 C6C1E0365166B53D25A1F84BC380948A9661DF30 flags verified ) ) game ( name "Trick Boarder (Europe)" description "Trick Boarder (Europe)" - rom ( name "Trick Boarder (Europe).gbc" size 1048576 crc EFE3FC64 md5 2400E6B73383221778C0D83EB0A1EBD4 sha1 74573EBE3196E600FB180BC4AEDAFDDEA4060A2C flags verified ) + rom ( name "Trick Boarder (Europe).gbc" size 1048576 crc efe3fc64 sha1 74573EBE3196E600FB180BC4AEDAFDDEA4060A2C flags verified ) ) game ( name "Trick Boarder (USA)" description "Trick Boarder (USA)" - rom ( name "Trick Boarder (USA).gbc" size 1048576 crc E856DC3D md5 FB3C040F2CC720EE26F9744E55371D07 sha1 A5BA3E762A56801E997335EAF1F0B614EC54400C ) + rom ( name "Trick Boarder (USA).gbc" size 1048576 crc e856dc3d sha1 A5BA3E762A56801E997335EAF1F0B614EC54400C ) ) game ( name "Trickboarder GP (Japan)" description "Trickboarder GP (Japan)" - rom ( name "Trickboarder GP (Japan).gbc" size 1048576 crc 31740097 md5 E6A4EF193F15C78FA2463A693BFB0928 sha1 263D8612ECDF651115DF6F896737B8C498C970C0 ) + rom ( name "Trickboarder GP (Japan).gbc" size 1048576 crc 31740097 sha1 263D8612ECDF651115DF6F896737B8C498C970C0 ) ) game ( name "Triple Play 2001 (USA, Europe)" description "Triple Play 2001 (USA, Europe)" - rom ( name "Triple Play 2001 (USA, Europe).gbc" size 1048576 crc 74E04C07 md5 96D2F46187D1EEE4A7E0253E1F51C7AA sha1 326841285C54476C1FC231886A8CBD9C00E0195C flags verified ) + rom ( name "Triple Play 2001 (USA, Europe).gbc" size 1048576 crc 74e04c07 sha1 326841285C54476C1FC231886A8CBD9C00E0195C flags verified ) ) game ( name "Trouballs (USA)" description "Trouballs (USA)" - rom ( name "Trouballs (USA).gbc" size 524288 crc 260EED04 md5 1B5E155AC68D2C7B89E49C5E1024B45C sha1 DC4D0F608354E7CC32DF7501DBACF8C50D70E728 ) + rom ( name "Trouballs (USA).gbc" size 524288 crc 260eed04 sha1 DC4D0F608354E7CC32DF7501DBACF8C50D70E728 ) ) game ( - name "Tsuri Sensei 2 (Japan) (SGB Enhanced)" - description "Tsuri Sensei 2 (Japan) (SGB Enhanced)" - rom ( name "Tsuri Sensei 2 (Japan) (SGB Enhanced).gbc" size 2097152 crc 1BE00A6E md5 8C188939044778F311BDAF2BC9ACA076 sha1 ECC0B306501F1A2371A83DB808BDA38AF8BC28CE ) + name "Tsuri Sensei 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Tsuri Sensei 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Tsuri Sensei 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 1be00a6e sha1 ECC0B306501F1A2371A83DB808BDA38AF8BC28CE flags verified ) ) game ( name "Tsuriiko!! (Japan)" description "Tsuriiko!! (Japan)" - rom ( name "Tsuriiko!! (Japan).gbc" size 2097152 crc 6F2CBD1D md5 AA1BF5FF55E7106B496850E3C6CF7C14 sha1 B14CC1E8ACA284517D964A909736DA6B4540DE85 flags verified ) + rom ( name "Tsuriiko!! (Japan).gbc" size 2097152 crc 6f2cbd1d sha1 B14CC1E8ACA284517D964A909736DA6B4540DE85 flags verified ) +) + +game ( + name "Turbo RC Racing (USA) (Proto)" + description "Turbo RC Racing (USA) (Proto)" + rom ( name "Turbo RC Racing (USA) (Proto).gbc" size 262144 crc e1983dfd sha1 494466CFED8E082C61B9E56A7275014C38705694 flags verified ) ) game ( name "Turok - Rage Wars (USA, Europe) (En,Fr,De,Es)" description "Turok - Rage Wars (USA, Europe) (En,Fr,De,Es)" - rom ( name "Turok - Rage Wars (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 786B5AB4 md5 2D7D0ADCEC6F72CA0755862C5FDDF353 sha1 CE95E00B6E9D7DFB952E8CDF590A4C6948A6340E flags verified ) + rom ( name "Turok - Rage Wars (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 786b5ab4 sha1 CE95E00B6E9D7DFB952E8CDF590A4C6948A6340E flags verified ) ) game ( - name "Turok 2 - Seeds of Evil (Japan)" - description "Turok 2 - Seeds of Evil (Japan)" - rom ( name "Turok 2 - Seeds of Evil (Japan).gbc" size 1048576 crc F095B446 md5 9253AAE0D9257D82F52D879813CF3C19 sha1 08A112F0C3FDC4CD4C14CFB98683D25D5D8475DE ) + name "Turok 2 - Jikku Senshi (Japan) (GB Compatible)" + description "Turok 2 - Jikku Senshi (Japan) (GB Compatible)" + rom ( name "Turok 2 - Jikku Senshi (Japan) (GB Compatible).gbc" size 1048576 crc f095b446 sha1 08A112F0C3FDC4CD4C14CFB98683D25D5D8475DE ) ) game ( - name "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es)" - description "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es)" - rom ( name "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6EDA6A3A md5 28D6C613FDF608FE241FB3CE183AAAE5 sha1 FB7856AF0205CC749174CDA9EB51AE137984558C flags verified ) + name "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es) (GB Compatible)" + description "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es) (GB Compatible)" + rom ( name "Turok 2 - Seeds of Evil (USA, Europe) (En,Fr,De,Es) (GB Compatible).gbc" size 1048576 crc 6eda6a3a sha1 FB7856AF0205CC749174CDA9EB51AE137984558C flags verified ) ) game ( name "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es)" description "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es)" - rom ( name "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6D48765E md5 A9D2F36D6C2A334E0B2261C57C20F0D4 sha1 4B240F6B8E3648F2CBAFA2FD6EE4E5B508950122 flags verified ) + rom ( name "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6d48765e sha1 4B240F6B8E3648F2CBAFA2FD6EE4E5B508950122 flags verified ) +) + +game ( + name "Tutty (Europe) (Demo)" + description "Tutty (Europe) (Demo)" + rom ( name "Tutty (Europe) (Demo).gbc" size 131072 crc c4655f0a sha1 51883C4CC1469987483F993E3904DA22690FAEB9 flags verified ) ) game ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" description "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" - rom ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It).gbc" size 1048576 crc 9306EDD0 md5 1BA7A470A32664D5F68F4310680D8426 sha1 D1FF6FD8772DBC2038AF7220845E817396664AE3 ) + rom ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It).gbc" size 1048576 crc 9306edd0 sha1 D1FF6FD8772DBC2038AF7220845E817396664AE3 ) ) game ( name "Tweenies - Doodles' Bones (Europe) (En,Nl,Sv,No,Da)" description "Tweenies - Doodles' Bones (Europe) (En,Nl,Sv,No,Da)" - rom ( name "Tweenies - Doodles' Bones (Europe) (En,Nl,Sv,No,Da).gbc" size 1048576 crc C7B61220 md5 6C34052AE5E516F8737982CB93A0845C sha1 1E39A4EA0A8C7322A2E0653E522E0E486AA1AC36 ) + rom ( name "Tweenies - Doodles' Bones (Europe) (En,Nl,Sv,No,Da).gbc" size 1048576 crc c7b61220 sha1 1E39A4EA0A8C7322A2E0653E522E0E486AA1AC36 flags verified ) ) game ( name "Tweety Sekaiisshuu - 80 Hiki no Neko o Sagase! (Japan)" description "Tweety Sekaiisshuu - 80 Hiki no Neko o Sagase! (Japan)" - rom ( name "Tweety Sekaiisshuu - 80 Hiki no Neko o Sagase! (Japan).gbc" size 1048576 crc 147F427A md5 867971B1E3B751A6B736D03793241176 sha1 CF04DAC11119C9BE4CA6E247E33B935BD0CDC62D ) + rom ( name "Tweety Sekaiisshuu - 80 Hiki no Neko o Sagase! (Japan).gbc" size 1048576 crc 147f427a sha1 CF04DAC11119C9BE4CA6E247E33B935BD0CDC62D ) ) game ( name "Tweety's High-Flying Adventure (Europe) (En,Es,It)" description "Tweety's High-Flying Adventure (Europe) (En,Es,It)" - rom ( name "Tweety's High-Flying Adventure (Europe) (En,Es,It).gbc" size 1048576 crc CA9E5385 md5 ACFA3540921A88CAE136DA1040CA2302 sha1 E0C3AB341A825B297F9970B00F1D911E48492A72 ) + rom ( name "Tweety's High-Flying Adventure (Europe) (En,Es,It).gbc" size 1048576 crc ca9e5385 sha1 E0C3AB341A825B297F9970B00F1D911E48492A72 flags verified ) ) game ( name "Tweety's High-Flying Adventure (Europe) (En,Fr,De)" description "Tweety's High-Flying Adventure (Europe) (En,Fr,De)" - rom ( name "Tweety's High-Flying Adventure (Europe) (En,Fr,De).gbc" size 1048576 crc 7361D6BC md5 304C2FE8EF1D9AE537004E3465814B4A sha1 94B4E1953B230D862E8F6173E82C822ACB7FF02E ) + rom ( name "Tweety's High-Flying Adventure (Europe) (En,Fr,De).gbc" size 1048576 crc 7361d6bc sha1 94B4E1953B230D862E8F6173E82C822ACB7FF02E ) ) game ( name "Tweety's High-Flying Adventure (USA)" description "Tweety's High-Flying Adventure (USA)" - rom ( name "Tweety's High-Flying Adventure (USA).gbc" size 1048576 crc 4E226396 md5 57DB65568F3C4A523960CD5B35096481 sha1 9702AEEA4A92625D2C19AA7F606B589CB7531613 ) -) - -game ( - name "Tyco RC - Racin' Ratz (USA)" - description "Tyco RC - Racin' Ratz (USA)" - rom ( name "Tyco RC - Racin' Ratz (USA).gbc" size 1048576 crc D6881014 md5 9DECE7202BD00A2806B36B5848CA985E sha1 32C63BE36093DB84FB5FEC110AD5AF49BE78C4AF ) + rom ( name "Tweety's High-Flying Adventure (USA).gbc" size 1048576 crc 4e226396 sha1 9702AEEA4A92625D2C19AA7F606B589CB7531613 flags verified ) ) game ( name "Tyrannosaurus Tex (USA) (Proto)" description "Tyrannosaurus Tex (USA) (Proto)" - rom ( name "Tyrannosaurus Tex (USA) (Proto).gbc" size 2097152 crc 1BD4E588 md5 4B355F96EA75826AD0E48055482BADEA sha1 E2FCC7FCC643F9D7FC61ACCE6C5ED1F8ABC13FA0 ) + rom ( name "Tyrannosaurus Tex (USA) (Proto).gbc" size 2097152 crc 1bd4e588 sha1 E2FCC7FCC643F9D7FC61ACCE6C5ED1F8ABC13FA0 flags verified ) ) game ( - name "Tyrian 2000 (USA) (Proto)" - description "Tyrian 2000 (USA) (Proto)" - rom ( name "Tyrian 2000 (USA) (Proto).gbc" size 524288 crc 1FB6B290 md5 E56E69BC23281C85A8A17A48A6F2ABDB sha1 1CFE1C97C50155844A349B7CA4EF8C77985ADAC2 ) + name "Tyrian 2000 (USA) (Proto) (GB Compatible)" + description "Tyrian 2000 (USA) (Proto) (GB Compatible)" + rom ( name "Tyrian 2000 (USA) (Proto) (GB Compatible).gbc" size 524288 crc 1fb6b290 sha1 1CFE1C97C50155844A349B7CA4EF8C77985ADAC2 flags verified ) ) game ( - name "Uchuujin Tanaka Tarou de RPG Tsuku-ru GB 2 (Japan)" - description "Uchuujin Tanaka Tarou de RPG Tsuku-ru GB 2 (Japan)" - rom ( name "Uchuujin Tanaka Tarou de RPG Tsuku-ru GB 2 (Japan).gbc" size 4194304 crc 219E42E3 md5 26508069768CB23F6FC03A33F8D4CF43 sha1 AA090449E93E4DCFA0437E7CDBA695E90CFA9509 flags verified ) + name "Uchuujin Tanaka Tarou de - RPG Tsukuru GB 2 (Japan)" + description "Uchuujin Tanaka Tarou de - RPG Tsukuru GB 2 (Japan)" + rom ( name "Uchuujin Tanaka Tarou de - RPG Tsukuru GB 2 (Japan).gbc" size 4194304 crc 219e42e3 sha1 AA090449E93E4DCFA0437E7CDBA695E90CFA9509 flags verified ) ) game ( name "UEFA 2000 (Europe) (En,Fr,De,Es,It,Nl)" description "UEFA 2000 (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "UEFA 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 4B314D4B md5 CA00C843A575EFD01814FCBF7D84A8DC sha1 56E5F0E62B65A265C85E1A88882B18139F26B94D ) + rom ( name "UEFA 2000 (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 4b314d4b sha1 56E5F0E62B65A265C85E1A88882B18139F26B94D ) ) game ( name "Ultimate Fighting Championship (Europe)" description "Ultimate Fighting Championship (Europe)" - rom ( name "Ultimate Fighting Championship (Europe).gbc" size 1048576 crc 92A5A1AD md5 65BD155F47EADE36F7BD446CF58B9BDB sha1 5036626B97238E17B8FC203C44453E79B108CD2E flags verified ) + rom ( name "Ultimate Fighting Championship (Europe).gbc" size 1048576 crc 92a5a1ad sha1 5036626B97238E17B8FC203C44453E79B108CD2E flags verified ) ) game ( name "Ultimate Fighting Championship (USA)" description "Ultimate Fighting Championship (USA)" - rom ( name "Ultimate Fighting Championship (USA).gbc" size 1048576 crc D5F036CE md5 8268AE026F73E834F52EE8291BB125B8 sha1 8A02015E399A0311C15F0A8CA31744AA0BE0F5E6 ) + rom ( name "Ultimate Fighting Championship (USA).gbc" size 1048576 crc d5f036ce sha1 8A02015E399A0311C15F0A8CA31744AA0BE0F5E6 ) ) game ( - name "Ultimate Paint Ball (USA, Europe)" - description "Ultimate Paint Ball (USA, Europe)" - rom ( name "Ultimate Paint Ball (USA, Europe).gbc" size 1048576 crc 6DCFDFE2 md5 9AF23C3CDF945B6A78F13DBAEBBAEFC0 sha1 7765398DB980C145062F2C0AC92B1F8F4BA40236 flags verified ) + name "Ultimate Paintball (USA, Europe)" + description "Ultimate Paintball (USA, Europe)" + rom ( name "Ultimate Paintball (USA, Europe).gbc" size 1048576 crc 6dcfdfe2 sha1 7765398DB980C145062F2C0AC92B1F8F4BA40236 flags verified ) ) game ( name "Ultimate Surfing (Europe)" description "Ultimate Surfing (Europe)" - rom ( name "Ultimate Surfing (Europe).gbc" size 1048576 crc B3398A9B md5 BA7297329E355C7C52A3AE457F0E6069 sha1 15426E79CF1C0CAFBF8972501B8478951023C21A ) + rom ( name "Ultimate Surfing (Europe).gbc" size 1048576 crc b3398a9b sha1 15426E79CF1C0CAFBF8972501B8478951023C21A flags verified ) ) game ( name "Ultimate Surfing (USA)" description "Ultimate Surfing (USA)" - rom ( name "Ultimate Surfing (USA).gbc" size 1048576 crc E84DF1F0 md5 59E3AE1C56F9F22A7DA70168757F640A sha1 264C19AB212D938839306F7E8230D5CAEE3CF3E7 ) + rom ( name "Ultimate Surfing (USA).gbc" size 1048576 crc e84df1f0 sha1 264C19AB212D938839306F7E8230D5CAEE3CF3E7 ) ) game ( - name "Uno (Europe) (En,Fr,De,Es,It,Nl)" - description "Uno (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Uno (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 70760CCE md5 F1E27AD24BB3BF71D1D7B048AE21F0B5 sha1 B33214A4CD05F58DD019A77B1260BF557293C826 ) + name "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + description "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" + rom ( name "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 70760cce sha1 B33214A4CD05F58DD019A77B1260BF557293C826 ) ) game ( - name "Uno (USA)" - description "Uno (USA)" - rom ( name "Uno (USA).gbc" size 1048576 crc F026D509 md5 C720B196E885FE116D8B0C2154438C0E sha1 20868148461618D1195570775B183A065781CE35 ) + name "Uno (USA) (GB Compatible)" + description "Uno (USA) (GB Compatible)" + rom ( name "Uno (USA) (GB Compatible).gbc" size 1048576 crc f026d509 sha1 20868148461618D1195570775B183A065781CE35 ) ) game ( name "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" description "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" - rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 1312B3F7 md5 EC1A1E432CBA04E33C408A7DAD314997 sha1 5447F2C317DEEE8CA6DA8F098A7D78F52B87E0CB ) + rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 1312b3f7 sha1 5447F2C317DEEE8CA6DA8F098A7D78F52B87E0CB ) ) game ( name "V-Rally - Championship Edition (Japan)" description "V-Rally - Championship Edition (Japan)" - rom ( name "V-Rally - Championship Edition (Japan).gbc" size 1048576 crc FAB9D941 md5 09FBEBC41DF99D534290D3033B09814E sha1 C05473DCF45FD4E185F9F3AEC3F4E429E4F12BBD ) + rom ( name "V-Rally - Championship Edition (Japan).gbc" size 1048576 crc fab9d941 sha1 C05473DCF45FD4E185F9F3AEC3F4E429E4F12BBD ) ) game ( - name "V-Rally - Championship Edition (USA) (En,Fr,Es)" - description "V-Rally - Championship Edition (USA) (En,Fr,Es)" - rom ( name "V-Rally - Championship Edition (USA) (En,Fr,Es).gbc" size 1048576 crc DA300C6C md5 84A0FE6C3FB014CF43C119C344F99965 sha1 638266C9D2D16486C2ED00510176112071B05E2C ) + name "V-Rally - Edition 99 (USA) (En,Fr,Es)" + description "V-Rally - Edition 99 (USA) (En,Fr,Es)" + rom ( name "V-Rally - Edition 99 (USA) (En,Fr,Es).gbc" size 1048576 crc da300c6c sha1 638266C9D2D16486C2ED00510176112071B05E2C ) ) game ( name "Vegas Games (Europe) (En,Fr,De)" description "Vegas Games (Europe) (En,Fr,De)" - rom ( name "Vegas Games (Europe) (En,Fr,De).gbc" size 1048576 crc 81B2BB8D md5 CFDD9DF7434C0A8D0E0AD3FDB04EA9B7 sha1 9B110D6EE12241AA5C061A1BB5F66E9CAB93842F flags verified ) + rom ( name "Vegas Games (Europe) (En,Fr,De).gbc" size 1048576 crc 81b2bb8d sha1 9B110D6EE12241AA5C061A1BB5F66E9CAB93842F flags verified ) ) game ( name "Vegas Games (USA)" description "Vegas Games (USA)" - rom ( name "Vegas Games (USA).gbc" size 1048576 crc 40B5EA96 md5 F7A5DC02B67118F6B7B8211F75625AC4 sha1 C73423444CC5900518FBD163EC7421DC3E5A7CA2 ) + rom ( name "Vegas Games (USA).gbc" size 1048576 crc 40b5ea96 sha1 C73423444CC5900518FBD163EC7421DC3E5A7CA2 ) ) game ( name "Vigilante 8 (USA) (Rumble Version)" description "Vigilante 8 (USA) (Rumble Version)" - rom ( name "Vigilante 8 (USA) (Rumble Version).gbc" size 1048576 crc D1A188DC md5 CB5348C1B469D698ECCDDCE99A16D384 sha1 4E4CE54C06E8F71BA6E0D8FC8550C177DCF660FD flags verified ) + rom ( name "Vigilante 8 (USA) (Rumble Version).gbc" size 1048576 crc d1a188dc sha1 4E4CE54C06E8F71BA6E0D8FC8550C177DCF660FD flags verified ) ) game ( - name "VIP (USA, Europe) (En,Fr,De,Es,It)" - description "VIP (USA, Europe) (En,Fr,De,Es,It)" - rom ( name "VIP (USA, Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc DBDD6D85 md5 0E11915BAB69CC3B5AAA3473784F03EE sha1 4DA103B9A5C9E9649B26876FCBD70555BD8FD042 flags verified ) + name "VIP (Europe) (En,Fr,De,Es,It)" + description "VIP (Europe) (En,Fr,De,Es,It)" + rom ( name "VIP (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc dbdd6d85 sha1 4DA103B9A5C9E9649B26876FCBD70555BD8FD042 flags verified ) ) game ( name "VIP (USA) (En,Fr,Es)" description "VIP (USA) (En,Fr,Es)" - serial "CGB-BVIE-USA" - rom ( name "VIP (USA) (En,Fr,Es).gbc" size 1048576 crc 436C87D4 md5 435D9FA03B3F891648F9C56D39299807 sha1 3ECFF5C68E457EE34C42AF6349F9AB2A6845B5DE ) + rom ( name "VIP (USA) (En,Fr,Es).gbc" size 1048576 crc 436c87d4 sha1 3ECFF5C68E457EE34C42AF6349F9AB2A6845B5DE flags verified ) ) game ( - name "Visiteurs, Les (France)" - description "Visiteurs, Les (France)" - rom ( name "Visiteurs, Les (France).gbc" size 1048576 crc D843F898 md5 5962E70172BBE5A77AE507A409D12AA9 sha1 307B5D80FD7DEF049D446BF3406EC8D57DFEE93D ) -) - -game ( - name "VS Lemmings (Japan)" - description "VS Lemmings (Japan)" - rom ( name "VS Lemmings (Japan).gbc" size 4194304 crc 947D45AE md5 DFC1C1FA9731807AA8BB5AA7D4849984 sha1 2EBB428A53ACBCBC215F37BB263E44D94F547473 ) + name "Visiteurs, Les (France) (GB Compatible)" + description "Visiteurs, Les (France) (GB Compatible)" + rom ( name "Visiteurs, Les (France) (GB Compatible).gbc" size 1048576 crc d843f898 sha1 307B5D80FD7DEF049D446BF3406EC8D57DFEE93D ) ) game ( name "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" description "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Wacky Races (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 37EA6093 md5 51356C19A22FCB871CBDD721E42FE201 sha1 DBA18064C886CEBE4C4BE80F941622F377ADAB98 ) + rom ( name "Wacky Races (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 37ea6093 sha1 DBA18064C886CEBE4C4BE80F941622F377ADAB98 ) ) game ( name "Wacky Races (USA) (En,Fr,Es)" description "Wacky Races (USA) (En,Fr,Es)" - rom ( name "Wacky Races (USA) (En,Fr,Es).gbc" size 1048576 crc 543ABB1B md5 716DE1A7F4178FD941EDF22D1A907624 sha1 3EC148027D0E5A075D7A4597232E64215C060FA7 ) + rom ( name "Wacky Races (USA) (En,Fr,Es).gbc" size 1048576 crc 543abb1b sha1 3EC148027D0E5A075D7A4597232E64215C060FA7 ) ) game ( name "Walt Disney World Quest - Magical Racing Tour (Europe) (Fr,De,Es)" description "Walt Disney World Quest - Magical Racing Tour (Europe) (Fr,De,Es)" - rom ( name "Walt Disney World Quest - Magical Racing Tour (Europe) (Fr,De,Es).gbc" size 2097152 crc E54B22B9 md5 3CCF696DDC0E2ED66C26C2FF2CB9E12A sha1 95DBEF19504368E73B97CD785E2B19E3C71710F4 flags verified ) + rom ( name "Walt Disney World Quest - Magical Racing Tour (Europe) (Fr,De,Es).gbc" size 2097152 crc e54b22b9 sha1 95DBEF19504368E73B97CD785E2B19E3C71710F4 flags verified ) ) game ( name "Walt Disney World Quest - Magical Racing Tour (USA, Europe)" description "Walt Disney World Quest - Magical Racing Tour (USA, Europe)" - rom ( name "Walt Disney World Quest - Magical Racing Tour (USA, Europe).gbc" size 2097152 crc 56BEB694 md5 31E1AF241F91CA3B9C165431258A4312 sha1 529289CCFD21397405D08305409C5D9B2119505E flags verified ) + rom ( name "Walt Disney World Quest - Magical Racing Tour (USA, Europe).gbc" size 2097152 crc 56beb694 sha1 529289CCFD21397405D08305409C5D9B2119505E flags verified ) ) game ( name "Warau Inu no Bouken - Silly Go Lucky! (Japan)" description "Warau Inu no Bouken - Silly Go Lucky! (Japan)" - rom ( name "Warau Inu no Bouken - Silly Go Lucky! (Japan).gbc" size 1048576 crc E93F1582 md5 C275DE8ABC3DD903038737A2139B0C18 sha1 3C337B71AEBA3B937CAADA4C84F2B29ADD517D03 flags verified ) + rom ( name "Warau Inu no Bouken - Silly Go Lucky! (Japan).gbc" size 1048576 crc e93f1582 sha1 3C337B71AEBA3B937CAADA4C84F2B29ADD517D03 flags verified ) ) game ( - name "Wario Land 2 (Japan) (SGB Enhanced)" - description "Wario Land 2 (Japan) (SGB Enhanced)" - rom ( name "Wario Land 2 (Japan) (SGB Enhanced).gbc" size 2097152 crc B30FDBF5 md5 A5BE435543968412CAAC1FE7C914472E sha1 CD6266E48DF816219FB38D223B0EC6760259616D flags verified ) + name "Wario Land 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "Wario Land 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Wario Land 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc b30fdbf5 sha1 CD6266E48DF816219FB38D223B0EC6760259616D flags verified ) ) game ( name "Wario Land 3 (World) (En,Ja)" description "Wario Land 3 (World) (En,Ja)" - rom ( name "Wario Land 3 (World) (En,Ja).gbc" size 2097152 crc 480D0259 md5 16BB3FB83E8CBBF2C4C510B9F50CF4EE sha1 BB7877309834441FD03ADB7FA65738E5D5B2D7BA flags verified ) + rom ( name "Wario Land 3 (World) (En,Ja).gbc" size 2097152 crc 480d0259 sha1 BB7877309834441FD03ADB7FA65738E5D5B2D7BA flags verified ) ) game ( - name "Wario Land II (USA, Europe) (SGB Enhanced)" - description "Wario Land II (USA, Europe) (SGB Enhanced)" - rom ( name "Wario Land II (USA, Europe) (SGB Enhanced).gbc" size 2097152 crc 047BDF80 md5 B7598A51E0ACC0D74CA8F464826371ED sha1 AE37915058035DF4CEEDD72D709F91EFB4878EFF flags verified ) + name "Wario Land II (USA, Europe) (SGB Enhanced) (GB Compatible)" + description "Wario Land II (USA, Europe) (SGB Enhanced) (GB Compatible)" + rom ( name "Wario Land II (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 047bdf80 sha1 AE37915058035DF4CEEDD72D709F91EFB4878EFF flags verified ) ) game ( name "Warlocked (USA)" description "Warlocked (USA)" - rom ( name "Warlocked (USA).gbc" size 2097152 crc CFA0DF0F md5 B5EB859E6EA60A0BD83100A10206D9C9 sha1 2F9C05F74476368BD6DBBA7D675E7870CF8CA27C ) + rom ( name "Warlocked (USA).gbc" size 2097152 crc cfa0df0f sha1 2F9C05F74476368BD6DBBA7D675E7870CF8CA27C flags verified ) ) game ( name "Warriors of Might and Magic (USA) (En,Fr,De)" description "Warriors of Might and Magic (USA) (En,Fr,De)" - rom ( name "Warriors of Might and Magic (USA) (En,Fr,De).gbc" size 1048576 crc EF9F5BEA md5 F0656CF3AA3D6B539FB1B7DA0FD27617 sha1 06163ACAD95D6AB87FFCD56F18B37C8C9E37A6EC ) + rom ( name "Warriors of Might and Magic (USA) (En,Fr,De).gbc" size 1048576 crc ef9f5bea sha1 06163ACAD95D6AB87FFCD56F18B37C8C9E37A6EC ) ) game ( name "Watashi no Kitchen (Japan)" description "Watashi no Kitchen (Japan)" - rom ( name "Watashi no Kitchen (Japan).gbc" size 1048576 crc BC767B25 md5 341597629F04D5EA6716A7CA9EB24DC1 sha1 7AA55D3CDD7AB505C62F4E3654256391F3590BF6 ) + rom ( name "Watashi no Kitchen (Japan).gbc" size 1048576 crc bc767b25 sha1 7AA55D3CDD7AB505C62F4E3654256391F3590BF6 flags verified ) ) game ( - name "Watashi no Kitchen (Japan) (Rev A)" - description "Watashi no Kitchen (Japan) (Rev A)" - rom ( name "Watashi no Kitchen (Japan) (Rev A).gbc" size 1048576 crc 584669E4 md5 C2A2490640EF568E6FA326AB149BFACC sha1 EFFD0D198BAC35ABEE1A8A6481382A1F2B14EAD3 ) + name "Watashi no Kitchen (Japan) (Rev 1)" + description "Watashi no Kitchen (Japan) (Rev 1)" + rom ( name "Watashi no Kitchen (Japan) (Rev 1).gbc" size 1048576 crc 584669e4 sha1 EFFD0D198BAC35ABEE1A8A6481382A1F2B14EAD3 flags verified ) ) game ( name "Watashi no Restaurant (Japan)" description "Watashi no Restaurant (Japan)" - rom ( name "Watashi no Restaurant (Japan).gbc" size 1048576 crc 395003EF md5 C9156B49032E63498DF93E132B0307B3 sha1 D66F728006AAA37C2776B6ADE7D1C8CDC2101A57 ) + rom ( name "Watashi no Restaurant (Japan).gbc" size 1048576 crc 395003ef sha1 D66F728006AAA37C2776B6ADE7D1C8CDC2101A57 ) ) game ( name "WCW Mayhem (USA, Europe)" description "WCW Mayhem (USA, Europe)" - rom ( name "WCW Mayhem (USA, Europe).gbc" size 1048576 crc 9F8620D1 md5 8940BA032D30F87E6956FBD8009420E3 sha1 EC4E5AB0B78B3A72778700907CCCAB6306BFD0EA flags verified ) + rom ( name "WCW Mayhem (USA, Europe).gbc" size 1048576 crc 9f8620d1 sha1 EC4E5AB0B78B3A72778700907CCCAB6306BFD0EA flags verified ) +) + +game ( + name "WDL - World Destruction League - Thunder Tanks (USA) (En,Fr,De)" + description "WDL - World Destruction League - Thunder Tanks (USA) (En,Fr,De)" + rom ( name "WDL - World Destruction League - Thunder Tanks (USA) (En,Fr,De).gbc" size 1048576 crc 1a0bf4d7 sha1 665D34621B4D51D4F1CEE882A453F5E278E2B5DA ) ) game ( name "Wendy - Der Traum von Arizona (Germany)" description "Wendy - Der Traum von Arizona (Germany)" - rom ( name "Wendy - Der Traum von Arizona (Germany).gbc" size 2097152 crc DF7C18BC md5 B8E7F2F760DC0E7010AC5A83A793FBD3 sha1 21141E9E0302EAD50456AF7B55A1391679455662 flags verified ) + rom ( name "Wendy - Der Traum von Arizona (Germany).gbc" size 2097152 crc df7c18bc sha1 21141E9E0302EAD50456AF7B55A1391679455662 flags verified ) ) game ( name "Wendy - Every Witch Way (USA, Europe)" description "Wendy - Every Witch Way (USA, Europe)" - rom ( name "Wendy - Every Witch Way (USA, Europe).gbc" size 1048576 crc 4AC6907B md5 4E1A5F02CCE49842D4717A8B0CE501F5 sha1 8CA45ED882C23DF714BDA46B227A857DEDDC899F flags verified ) + rom ( name "Wendy - Every Witch Way (USA, Europe).gbc" size 1048576 crc 4ac6907b sha1 8CA45ED882C23DF714BDA46B227A857DEDDC899F flags verified ) ) game ( - name "Wetrix GB (Europe) (En,Fr,De)" - description "Wetrix GB (Europe) (En,Fr,De)" - rom ( name "Wetrix GB (Europe) (En,Fr,De).gbc" size 1048576 crc 9CBFAA3D md5 916D740FC366ECBF9E5626218E56562D sha1 6DE683DC99FEAF7FB0440046668D36A229513AB5 ) + name "Wetrix (Europe) (En,Fr,De)" + description "Wetrix (Europe) (En,Fr,De)" + rom ( name "Wetrix (Europe) (En,Fr,De).gbc" size 1048576 crc 9cbfaa3d sha1 6DE683DC99FEAF7FB0440046668D36A229513AB5 ) ) game ( - name "Wetrix GB (Japan) (SGB Enhanced)" - description "Wetrix GB (Japan) (SGB Enhanced)" - rom ( name "Wetrix GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 6215C5B3 md5 F36CD3E0A8A8EACF4A9C5A2A755F237E sha1 92944052B6E4448ABF0103F085998662E0140825 ) + name "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6215c5b3 sha1 92944052B6E4448ABF0103F085998662E0140825 ) ) game ( name "Who Wants to Be a Millionaire - 2nd Edition (USA)" description "Who Wants to Be a Millionaire - 2nd Edition (USA)" - rom ( name "Who Wants to Be a Millionaire - 2nd Edition (USA).gbc" size 1048576 crc 6830B7AF md5 866DCA02365FD72F9AD396DCA758D8B5 sha1 1FD2C608231E6F919FEE05DA91418E05C502EF61 ) + rom ( name "Who Wants to Be a Millionaire - 2nd Edition (USA).gbc" size 1048576 crc 6830b7af sha1 1FD2C608231E6F919FEE05DA91418E05C502EF61 ) ) game ( name "Wild Thornberrys, The - Rambler (USA)" description "Wild Thornberrys, The - Rambler (USA)" - rom ( name "Wild Thornberrys, The - Rambler (USA).gbc" size 1048576 crc 0E1465CB md5 F32210EEDC7A619A09339764887E2B93 sha1 0E806F0E6C1A41E764683850A3C15A80AC7FC9A5 ) + rom ( name "Wild Thornberrys, The - Rambler (USA).gbc" size 1048576 crc 0e1465cb sha1 0E806F0E6C1A41E764683850A3C15A80AC7FC9A5 ) ) game ( - name "Wings of Fury (Europe) (En,Fr,De)" - description "Wings of Fury (Europe) (En,Fr,De)" - rom ( name "Wings of Fury (Europe) (En,Fr,De).gbc" size 1048576 crc 6D59104F md5 B80371A8C851A4C0B9C944FD14B44D6E sha1 D3F21EA1A1D83546DFFCD63EC089CFAC04212A03 ) + name "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" + description "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" + rom ( name "Wings of Fury (Europe) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc 6d59104f sha1 D3F21EA1A1D83546DFFCD63EC089CFAC04212A03 ) ) game ( - name "Wings of Fury (USA)" - description "Wings of Fury (USA)" - rom ( name "Wings of Fury (USA).gbc" size 1048576 crc C94A413A md5 8B01ED48B1F51F57CFBA2F3024FA60D8 sha1 AE217BD12F42CE6297282227B7E2D21E6337420C ) + name "Wings of Fury (USA) (GB Compatible)" + description "Wings of Fury (USA) (GB Compatible)" + rom ( name "Wings of Fury (USA) (GB Compatible).gbc" size 1048576 crc c94a413a sha1 AE217BD12F42CE6297282227B7E2D21E6337420C ) ) game ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (Europe) (En,Fr,De,Es,It,Nl,Da)" description "Winnie the Pooh - Adventures in the 100 Acre Wood (Europe) (En,Fr,De,Es,It,Nl,Da)" - rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 2097152 crc 1DB0840C md5 D05A3C8E6AF26686166B5049F1438DFF sha1 B97B33E7423A712B3F77A2BF9A419F78EC5D30BE flags verified ) + rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (Europe) (En,Fr,De,Es,It,Nl,Da).gbc" size 2097152 crc 1db0840c sha1 B97B33E7423A712B3F77A2BF9A419F78EC5D30BE flags verified ) ) game ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA)" description "Winnie the Pooh - Adventures in the 100 Acre Wood (USA)" - rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA).gbc" size 2097152 crc 066A2196 md5 C721161C0EE8B4731D71448B481C93AE sha1 5FF68BC5EC735D090B24AAB79A787F77F26AFB08 ) + rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA).gbc" size 2097152 crc 066a2196 sha1 5FF68BC5EC735D090B24AAB79A787F77F26AFB08 ) ) game ( name "Wizardry Empire (Japan)" description "Wizardry Empire (Japan)" - rom ( name "Wizardry Empire (Japan).gbc" size 1048576 crc 7ADC90E1 md5 CCB604CA00F176AE6CA40F4FC33D8C1A sha1 041C125115C83C6FEF1B888761BA0B2B1F9BD291 ) + rom ( name "Wizardry Empire (Japan).gbc" size 1048576 crc 7adc90e1 sha1 041C125115C83C6FEF1B888761BA0B2B1F9BD291 flags verified ) ) game ( - name "Wizardry Empire (Japan) (Rev A)" - description "Wizardry Empire (Japan) (Rev A)" - rom ( name "Wizardry Empire (Japan) (Rev A).gbc" size 1048576 crc FA82620F md5 FCF910E4D2F27BAB40244EB7BF4AA2D3 sha1 F5F4E8BEAD0FE45075141133A530A0EB116EA78C ) + name "Wizardry Empire (Japan) (Rev 1)" + description "Wizardry Empire (Japan) (Rev 1)" + rom ( name "Wizardry Empire (Japan) (Rev 1).gbc" size 1048576 crc fa82620f sha1 F5F4E8BEAD0FE45075141133A530A0EB116EA78C ) ) game ( name "Wizardry Empire - Fukkatsu no Tsue (Japan)" description "Wizardry Empire - Fukkatsu no Tsue (Japan)" - rom ( name "Wizardry Empire - Fukkatsu no Tsue (Japan).gbc" size 1048576 crc 1A10552B md5 FA8360094CAE37A838FABCFD333AE300 sha1 07A197F0B5E2AB6379FAA95EB1E7A519E1306E09 ) + rom ( name "Wizardry Empire - Fukkatsu no Tsue (Japan).gbc" size 1048576 crc 1a10552b sha1 07A197F0B5E2AB6379FAA95EB1E7A519E1306E09 ) ) game ( name "Wizardry I - Proving Grounds of the Mad Overlord (Japan)" description "Wizardry I - Proving Grounds of the Mad Overlord (Japan)" - rom ( name "Wizardry I - Proving Grounds of the Mad Overlord (Japan).gbc" size 1048576 crc A99A33DC md5 6B94C050291C68D6FB13C642C46873AB sha1 ECC073882D09A90FA1F02448C9AE44D43C8B81DC ) + rom ( name "Wizardry I - Proving Grounds of the Mad Overlord (Japan).gbc" size 1048576 crc a99a33dc sha1 ECC073882D09A90FA1F02448C9AE44D43C8B81DC ) ) game ( name "Wizardry II - Llylgamyn no Isan (Japan)" description "Wizardry II - Llylgamyn no Isan (Japan)" - rom ( name "Wizardry II - Llylgamyn no Isan (Japan).gbc" size 1048576 crc DD727F1A md5 8D0A97CC2C5235656E722B0FB9627504 sha1 2EBFCF6DE50F1DEA2B96730967B2351E5AA58BE9 ) + rom ( name "Wizardry II - Llylgamyn no Isan (Japan).gbc" size 1048576 crc dd727f1a sha1 2EBFCF6DE50F1DEA2B96730967B2351E5AA58BE9 ) ) game ( name "Wizardry III - Diamond no Kishi (Japan)" description "Wizardry III - Diamond no Kishi (Japan)" - rom ( name "Wizardry III - Diamond no Kishi (Japan).gbc" size 1048576 crc D44D3596 md5 E81E4977A1380A6A0BAC49BFD9E04671 sha1 F850DDBBFC8A77D53948DE805819B4457380B390 flags verified ) + rom ( name "Wizardry III - Diamond no Kishi (Japan).gbc" size 1048576 crc d44d3596 sha1 F850DDBBFC8A77D53948DE805819B4457380B390 flags verified ) ) game ( name "Woody Woodpecker (Europe) (En,Fr,De,Es,It)" description "Woody Woodpecker (Europe) (En,Fr,De,Es,It)" - rom ( name "Woody Woodpecker (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2612F8C4 md5 F66B21AF086612F0F26448E63AA7A9FD sha1 363111C56BD301A4A4F3B921B5D1DDC65B856699 ) + rom ( name "Woody Woodpecker (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2612f8c4 sha1 363111C56BD301A4A4F3B921B5D1DDC65B856699 ) ) game ( name "Woody Woodpecker (USA)" description "Woody Woodpecker (USA)" - rom ( name "Woody Woodpecker (USA).gbc" size 1048576 crc BD2D1F8B md5 2A26B9D248BF62788E23AA897E8E355C sha1 09A6363D98F441B57ADB725CABDE7FEFF74466E3 ) + rom ( name "Woody Woodpecker (USA).gbc" size 1048576 crc bd2d1f8b sha1 09A6363D98F441B57ADB725CABDE7FEFF74466E3 ) ) game ( name "Woody Woodpecker no Go! Go! Racing (Japan)" description "Woody Woodpecker no Go! Go! Racing (Japan)" - rom ( name "Woody Woodpecker no Go! Go! Racing (Japan).gbc" size 1048576 crc F59DAA99 md5 59E6B58B2F788C5E72BFA93E3052869D sha1 42D841BDEAD319AA43D6BC09D88B4C32B4304CED ) + rom ( name "Woody Woodpecker no Go! Go! Racing (Japan).gbc" size 1048576 crc f59daa99 sha1 42D841BDEAD319AA43D6BC09D88B4C32B4304CED ) ) game ( name "Woody Woodpecker Racing (Europe)" description "Woody Woodpecker Racing (Europe)" - rom ( name "Woody Woodpecker Racing (Europe).gbc" size 1048576 crc B0F43498 md5 890CC599A9EC49D5ADF1CD225EBD233C sha1 47FBFBFB8AF15AE388E8DBE2AC521960C2F835AE flags verified ) + rom ( name "Woody Woodpecker Racing (Europe).gbc" size 1048576 crc b0f43498 sha1 47FBFBFB8AF15AE388E8DBE2AC521960C2F835AE flags verified ) ) game ( name "Woody Woodpecker Racing (USA)" description "Woody Woodpecker Racing (USA)" - rom ( name "Woody Woodpecker Racing (USA).gbc" size 1048576 crc 0424CF43 md5 21D38C37D8E01A27F8635BB9F5F315CD sha1 BE98D0A54AEDCF59CDDC111C72DB66105AEA1375 ) + rom ( name "Woody Woodpecker Racing (USA).gbc" size 1048576 crc 0424cf43 sha1 BE98D0A54AEDCF59CDDC111C72DB66105AEA1375 ) ) game ( - name "World Destruction League - Thunder Tanks (USA) (En,Fr,De)" - description "World Destruction League - Thunder Tanks (USA) (En,Fr,De)" - rom ( name "World Destruction League - Thunder Tanks (USA) (En,Fr,De).gbc" size 1048576 crc 1A0BF4D7 md5 EC648C50E1BC337C399AB40B58B40509 sha1 665D34621B4D51D4F1CEE882A453F5E278E2B5DA ) + name "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" + description "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc dd18db5f sha1 B58C969510AAB4930A1846D857F58D57ED342592 flags verified ) ) game ( name "World Soccer GB 2000 (Japan)" description "World Soccer GB 2000 (Japan)" - rom ( name "World Soccer GB 2000 (Japan).gbc" size 2097152 crc 6775B29E md5 4D48457F7138C58BE1589A4DDCE1F02D sha1 22433FAE69D7DD5B1FF351DB579A1EE9E883F06F ) -) - -game ( - name "World Soccer GB2 (Japan) (SGB Enhanced)" - description "World Soccer GB2 (Japan) (SGB Enhanced)" - rom ( name "World Soccer GB2 (Japan) (SGB Enhanced).gbc" size 1048576 crc DD18DB5F md5 AC812A2C6EAF743EFD64972D8FA5A3C4 sha1 B58C969510AAB4930A1846D857F58D57ED342592 ) + rom ( name "World Soccer GB 2000 (Japan).gbc" size 2097152 crc 6775b29e sha1 22433FAE69D7DD5B1FF351DB579A1EE9E883F06F flags verified ) ) game ( name "Worms Armageddon (Europe) (En,Fr,De,Es,It,Nl)" description "Worms Armageddon (Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Worms Armageddon (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc CB04F34D md5 B6B81D98A27596443792F47812F15B67 sha1 0BFF9F46F2C455E98A5F0D9C0D560EDA88D939DE flags verified ) + rom ( name "Worms Armageddon (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc cb04f34d sha1 0BFF9F46F2C455E98A5F0D9C0D560EDA88D939DE flags verified ) ) game ( name "Worms Armageddon (USA) (En,Fr,Es)" description "Worms Armageddon (USA) (En,Fr,Es)" - rom ( name "Worms Armageddon (USA) (En,Fr,Es).gbc" size 1048576 crc E241EDDE md5 7E0DF312CCD8F3E25BF3074E17D5AEDF sha1 EC587A3660298F95BF85F4471A626727B5FE6D7C ) + rom ( name "Worms Armageddon (USA) (En,Fr,Es).gbc" size 1048576 crc e241edde sha1 EC587A3660298F95BF85F4471A626727B5FE6D7C ) ) game ( name "WWF Attitude (USA, Europe)" description "WWF Attitude (USA, Europe)" - rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc D5FDF68A md5 87C5862EDCE9EAE3D6AFE964BFED5204 sha1 D5C37EABE3311666123B22F44A973C06D96BFCE0 flags verified ) + rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc d5fdf68a sha1 D5C37EABE3311666123B22F44A973C06D96BFCE0 flags verified ) ) game ( name "WWF Betrayal (USA, Europe)" description "WWF Betrayal (USA, Europe)" - rom ( name "WWF Betrayal (USA, Europe).gbc" size 1048576 crc 6C28BCB5 md5 F270519E6357BC32FD07FC6386E14DEC sha1 27773B6396CCB55051227CE7CE81D01C33EA75D1 flags verified ) + rom ( name "WWF Betrayal (USA, Europe).gbc" size 1048576 crc 6c28bcb5 sha1 27773B6396CCB55051227CE7CE81D01C33EA75D1 flags verified ) ) game ( - name "WWF WrestleMania 2000 (USA, Europe)" - description "WWF WrestleMania 2000 (USA, Europe)" - rom ( name "WWF WrestleMania 2000 (USA, Europe).gbc" size 1048576 crc FCBA12AE md5 7FA5A6DDE384652120B46475B193DFF9 sha1 EE9A375A16CA77883B7E30C92FC6BEB8F772DF5F flags verified ) + name "WWF WrestleMania 2000 (USA, Europe) (GB Compatible)" + description "WWF WrestleMania 2000 (USA, Europe) (GB Compatible)" + rom ( name "WWF WrestleMania 2000 (USA, Europe) (GB Compatible).gbc" size 1048576 crc fcba12ae sha1 EE9A375A16CA77883B7E30C92FC6BEB8F772DF5F flags verified ) ) game ( name "X-Men - Mutant Academy (Japan)" description "X-Men - Mutant Academy (Japan)" - rom ( name "X-Men - Mutant Academy (Japan).gbc" size 1048576 crc 8162ADC1 md5 814042BFBC1EC31E5F992BDE98ED613E sha1 3DE082556A1DDD99149FA10CE4E219D64CAF98F3 ) + rom ( name "X-Men - Mutant Academy (Japan).gbc" size 1048576 crc 8162adc1 sha1 3DE082556A1DDD99149FA10CE4E219D64CAF98F3 ) ) game ( name "X-Men - Mutant Academy (USA, Europe)" description "X-Men - Mutant Academy (USA, Europe)" - rom ( name "X-Men - Mutant Academy (USA, Europe).gbc" size 1048576 crc EC6278A3 md5 CC17F52E5140C0D1AD892D1856D05212 sha1 6509F46A2F32DF697D966BCAFD72EC3D631A3AC5 flags verified ) + rom ( name "X-Men - Mutant Academy (USA, Europe).gbc" size 1048576 crc ec6278a3 sha1 6509F46A2F32DF697D966BCAFD72EC3D631A3AC5 flags verified ) ) game ( - name "X-Men - Mutant Academy (USA, Europe) (Rev A)" - description "X-Men - Mutant Academy (USA, Europe) (Rev A)" - rom ( name "X-Men - Mutant Academy (USA, Europe) (Rev A).gbc" size 1048576 crc 234E1E9C md5 6774580DB542B838EFF5A155128B7413 sha1 167770BEFB087C0F95CFE3C3EFA3540C5F55A799 ) + name "X-Men - Mutant Academy (USA, Europe) (Rev 1)" + description "X-Men - Mutant Academy (USA, Europe) (Rev 1)" + rom ( name "X-Men - Mutant Academy (USA, Europe) (Rev 1).gbc" size 1048576 crc 234e1e9c sha1 167770BEFB087C0F95CFE3C3EFA3540C5F55A799 flags verified ) ) game ( name "X-Men - Mutant Wars (USA, Europe)" description "X-Men - Mutant Wars (USA, Europe)" - rom ( name "X-Men - Mutant Wars (USA, Europe).gbc" size 1048576 crc 921999E2 md5 2C74082758017E30990E30B145C2F841 sha1 0ADAEEF76DB5A6DF2786A45231E0934840F6EB44 flags verified ) + rom ( name "X-Men - Mutant Wars (USA, Europe).gbc" size 1048576 crc 921999e2 sha1 0ADAEEF76DB5A6DF2786A45231E0934840F6EB44 flags verified ) ) game ( name "X-Men - Wolverine's Rage (Europe)" description "X-Men - Wolverine's Rage (Europe)" - rom ( name "X-Men - Wolverine's Rage (Europe).gbc" size 1048576 crc 83AD5B99 md5 2ACF3B5FB6A9CF4C8194BBADCE34AEE7 sha1 6EEEF0A72A453C26FA8C772C4036004986DC68F2 ) + rom ( name "X-Men - Wolverine's Rage (Europe).gbc" size 1048576 crc 83ad5b99 sha1 6EEEF0A72A453C26FA8C772C4036004986DC68F2 flags verified ) ) game ( name "X-Men - Wolverine's Rage (USA)" description "X-Men - Wolverine's Rage (USA)" - rom ( name "X-Men - Wolverine's Rage (USA).gbc" size 1048576 crc 12FC1A6E md5 B1729716BAAEA01D4BAA795DB31800B0 sha1 B7143367D71932AD525C5DB94F5295686E6C58E5 ) + rom ( name "X-Men - Wolverine's Rage (USA).gbc" size 1048576 crc 12fc1a6e sha1 B7143367D71932AD525C5DB94F5295686E6C58E5 ) ) game ( name "Xena - Warrior Princess (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Xena - Warrior Princess (USA, Europe) (En,Fr,De,Es,It,Nl)" - rom ( name "Xena - Warrior Princess (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc F0DE3CE7 md5 ACB82A5584F830D6D7BC33F4827571B9 sha1 1DE53D445D898AA25B0472C604D5CFB052812070 flags verified ) + rom ( name "Xena - Warrior Princess (USA, Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f0de3ce7 sha1 1DE53D445D898AA25B0472C604D5CFB052812070 flags verified ) ) game ( name "Xtreme Sports (USA)" description "Xtreme Sports (USA)" - rom ( name "Xtreme Sports (USA).gbc" size 4194304 crc 19828751 md5 AF1D1E17A5C568DF796F4004BE872649 sha1 FFCA13207E6284A3CC16F7F130B68FCA87663D08 ) + rom ( name "Xtreme Sports (USA).gbc" size 4194304 crc 19828751 sha1 FFCA13207E6284A3CC16F7F130B68FCA87663D08 ) ) game ( name "Xtreme Wheels (Europe)" description "Xtreme Wheels (Europe)" - rom ( name "Xtreme Wheels (Europe).gbc" size 1048576 crc E101246F md5 90D9DDB15CC652FCD3A158A54ECE8808 sha1 7C1B43AC8F1E136B159F957613C1D4CDA8A9360A ) + rom ( name "Xtreme Wheels (Europe).gbc" size 1048576 crc e101246f sha1 7C1B43AC8F1E136B159F957613C1D4CDA8A9360A ) ) game ( name "Xtreme Wheels (USA)" description "Xtreme Wheels (USA)" - rom ( name "Xtreme Wheels (USA).gbc" size 1048576 crc 129465DB md5 9F28E403EB338A7457F54DEE7A6F443E sha1 07C1DC116C369B3FF73588251E0D09D50D040474 ) + rom ( name "Xtreme Wheels (USA).gbc" size 1048576 crc 129465db sha1 07C1DC116C369B3FF73588251E0D09D50D040474 ) ) game ( name "Yakouchuu GB (Japan)" description "Yakouchuu GB (Japan)" - rom ( name "Yakouchuu GB (Japan).gbc" size 2097152 crc AA05DAF1 md5 D8E39DF6EB57D397A328FE7F552D59D9 sha1 F40A651C7D21E37D4F9FA0CBE8460EC674C4A6D0 ) + rom ( name "Yakouchuu GB (Japan).gbc" size 2097152 crc aa05daf1 sha1 F40A651C7D21E37D4F9FA0CBE8460EC674C4A6D0 ) ) game ( - name "Yars' Revenge (USA, Europe)" - description "Yars' Revenge (USA, Europe)" - rom ( name "Yars' Revenge (USA, Europe).gbc" size 1048576 crc D6A26444 md5 1405C2C436255D0D5C901BF6D64F68A1 sha1 45FB176D539AE4A65AF1F6340A9BD398DD7956D2 flags verified ) -) - -game ( - name "Yoda Stories (USA, Europe)" - description "Yoda Stories (USA, Europe)" - rom ( name "Yoda Stories (USA, Europe).gbc" size 1048576 crc 6314DA32 md5 544EB3962EF54F89718C8DFA668EC4BE sha1 F0DD388373E863F91A05CF6F2DF00A56E26D3B18 flags verified ) + name "Yars' Revenge (USA, Europe) (GB Compatible)" + description "Yars' Revenge (USA, Europe) (GB Compatible)" + rom ( name "Yars' Revenge (USA, Europe) (GB Compatible).gbc" size 1048576 crc d6a26444 sha1 45FB176D539AE4A65AF1F6340A9BD398DD7956D2 flags verified ) ) game ( name "Yogi Bear - Great Balloon Blast (USA)" description "Yogi Bear - Great Balloon Blast (USA)" - rom ( name "Yogi Bear - Great Balloon Blast (USA).gbc" size 1048576 crc F817E978 md5 CD5C8BE982147D4BA99376C2B60BDBCF sha1 EF3583E3B4092726D1875C4613F65C65FCBD26E6 ) + rom ( name "Yogi Bear - Great Balloon Blast (USA).gbc" size 1048576 crc f817e978 sha1 EF3583E3B4092726D1875C4613F65C65FCBD26E6 ) ) game ( name "Yu-Gi-Oh! - Dark Duel Stories (Europe)" description "Yu-Gi-Oh! - Dark Duel Stories (Europe)" - rom ( name "Yu-Gi-Oh! - Dark Duel Stories (Europe).gbc" size 4194304 crc 338E2CDA md5 036B4944895082F5895A475F4CED3BFB sha1 86D3DFC1B852C34DF1BE90A24A41B5D4D5C4CA54 ) + rom ( name "Yu-Gi-Oh! - Dark Duel Stories (Europe).gbc" size 4194304 crc 338e2cda sha1 86D3DFC1B852C34DF1BE90A24A41B5D4D5C4CA54 flags verified ) ) game ( name "Yu-Gi-Oh! - Dark Duel Stories (USA)" description "Yu-Gi-Oh! - Dark Duel Stories (USA)" - rom ( name "Yu-Gi-Oh! - Dark Duel Stories (USA).gbc" size 4194304 crc 803A56AE md5 C30ADD585D87114288FF8E3726C5381B sha1 1952D343BDFB5625BD23A8569CDE6FD61A911502 ) + rom ( name "Yu-Gi-Oh! - Dark Duel Stories (USA).gbc" size 4194304 crc 803a56ae sha1 1952D343BDFB5625BD23A8569CDE6FD61A911502 ) ) game ( name "Yu-Gi-Oh! - Das Dunkle Duell (Germany)" description "Yu-Gi-Oh! - Das Dunkle Duell (Germany)" - rom ( name "Yu-Gi-Oh! - Das Dunkle Duell (Germany).gbc" size 4194304 crc 6CA75BA0 md5 B928699D63702E21A3599B887B947041 sha1 55391AE4C27EFC4EFE0A43BDA8E791BBBB888DD8 flags verified ) + rom ( name "Yu-Gi-Oh! - Das Dunkle Duell (Germany).gbc" size 4194304 crc 6ca75ba0 sha1 55391AE4C27EFC4EFE0A43BDA8E791BBBB888DD8 flags verified ) ) game ( name "Yu-Gi-Oh! - Duel des Tenebres (France)" description "Yu-Gi-Oh! - Duel des Tenebres (France)" - rom ( name "Yu-Gi-Oh! - Duel des Tenebres (France).gbc" size 4194304 crc 5B72BAB5 md5 CA9D65EBA8AF25068242C946C50B6753 sha1 566E9C4A02EFD2E15C8758D0A6AAB4519B6AF102 flags verified ) + rom ( name "Yu-Gi-Oh! - Duel des Tenebres (France).gbc" size 4194304 crc 5b72bab5 sha1 566E9C4A02EFD2E15C8758D0A6AAB4519B6AF102 flags verified ) ) game ( name "Yu-Gi-Oh! - Duelo en las Tinieblas (Spain)" description "Yu-Gi-Oh! - Duelo en las Tinieblas (Spain)" - rom ( name "Yu-Gi-Oh! - Duelo en las Tinieblas (Spain).gbc" size 4194304 crc DC160F10 md5 CDB21E5E2502DC8B9D0CC0ACDE7841FC sha1 73BC0B9CE57AC806BFEFCD830C44EEC42A3E7ADF ) + rom ( name "Yu-Gi-Oh! - Duelo en las Tinieblas (Spain).gbc" size 4194304 crc dc160f10 sha1 73BC0B9CE57AC806BFEFCD830C44EEC42A3E7ADF flags verified ) ) game ( - name "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced)" - description "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced)" - rom ( name "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced).gbc" size 1048576 crc 1371E872 md5 B980DA92693762BD3A7A4791FE08766E sha1 4ED5607DD83EBE7975C492B08D36870F8DD6E302 flags verified ) + name "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced) (GB Compatible)" + description "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Yu-Gi-Oh! - Monster Capsule GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1371e872 sha1 4ED5607DD83EBE7975C492B08D36870F8DD6E302 flags verified ) ) game ( name "Yu-Gi-Oh! - Racconti Oscuri (Italy)" description "Yu-Gi-Oh! - Racconti Oscuri (Italy)" - rom ( name "Yu-Gi-Oh! - Racconti Oscuri (Italy).gbc" size 4194304 crc 8A6B0948 md5 DD34A89C4839949F4A983786EC63A993 sha1 BF4D4E4450FBBC97EFFACE042684341947E626A9 ) + rom ( name "Yu-Gi-Oh! - Racconti Oscuri (Italy).gbc" size 4194304 crc 8a6b0948 sha1 BF4D4E4450FBBC97EFFACE042684341947E626A9 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Jounouchi Deck (Japan)" description "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Jounouchi Deck (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Jounouchi Deck (Japan).gbc" size 4194304 crc 298BD054 md5 F84F21FD860D1D9CFB8CA6EA62A0DA8F sha1 2FDF56C2B52BA83FEE778F3C2961A90AB69EA899 flags verified ) + rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Jounouchi Deck (Japan).gbc" size 4194304 crc 298bd054 sha1 2FDF56C2B52BA83FEE778F3C2961A90AB69EA899 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Kaiba Deck (Japan)" description "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Kaiba Deck (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Kaiba Deck (Japan).gbc" size 4194304 crc A4D06001 md5 19B1085C7C17A8123A7EC59F4033E92C sha1 EE769A23750E48C5BA4949F83236B18814316DE2 ) + rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Kaiba Deck (Japan).gbc" size 4194304 crc a4d06001 sha1 EE769A23750E48C5BA4949F83236B18814316DE2 flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Yuugi Deck (Japan)" description "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Yuugi Deck (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Yuugi Deck (Japan).gbc" size 4194304 crc 4D6105F6 md5 E3809354341CFB1F2EBB3E4DD1BC8828 sha1 3199283039089FDF1E1B3CBB5B95FE7B26C6765F ) + rom ( name "Yu-Gi-Oh! Duel Monsters 4 - Battle of Great Duelist - Yuugi Deck (Japan).gbc" size 4194304 crc 4d6105f6 sha1 3199283039089FDF1E1B3CBB5B95FE7B26C6765F flags verified ) ) game ( - name "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced)" - description "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced)" - rom ( name "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced).gbc" size 4194304 crc BA7182C3 md5 782B88B1BF9768A2B1B139177A0C1C33 sha1 6A96C30C1F9ECC207F962EC156F6D22A652AE41D flags verified ) + name "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced) (GB Compatible)" + description "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Yu-Gi-Oh! Duel Monsters II - Dark Duel Stories (Japan) (SGB Enhanced) (GB Compatible).gbc" size 4194304 crc ba7182c3 sha1 6A96C30C1F9ECC207F962EC156F6D22A652AE41D flags verified ) ) game ( name "Yu-Gi-Oh! Duel Monsters III - Tri Holy God Advant (Japan)" description "Yu-Gi-Oh! Duel Monsters III - Tri Holy God Advant (Japan)" - rom ( name "Yu-Gi-Oh! Duel Monsters III - Tri Holy God Advant (Japan).gbc" size 4194304 crc 9F9DBAB4 md5 560256BD5D95F16DEAD694D680E1C2E8 sha1 DC4753A2F12360D921A147287673B4448394A9D3 flags verified ) + rom ( name "Yu-Gi-Oh! Duel Monsters III - Tri Holy God Advant (Japan).gbc" size 4194304 crc 9f9dbab4 sha1 DC4753A2F12360D921A147287673B4448394A9D3 flags verified ) ) game ( name "Zebco Fishing! (USA) (Rumble Version)" description "Zebco Fishing! (USA) (Rumble Version)" - rom ( name "Zebco Fishing! (USA) (Rumble Version).gbc" size 1048576 crc 3CC6B1F9 md5 C4583C9127D08F9A7DEC2056A8C21C1F sha1 9B6C536B403C62AF102E3800658C9DEC258BE249 ) + rom ( name "Zebco Fishing! (USA) (Rumble Version).gbc" size 1048576 crc 3cc6b1f9 sha1 9B6C536B403C62AF102E3800658C9DEC258BE249 ) ) game ( name "Zelda no Densetsu - Fushigi no Kinomi - Daichi no Shou (Japan)" description "Zelda no Densetsu - Fushigi no Kinomi - Daichi no Shou (Japan)" - rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Daichi no Shou (Japan).gbc" size 1048576 crc E42538F0 md5 D3C08C1EB4F93B64C30FCB0BB7FF8924 sha1 08BF49D7E225C695F64D38131CB720DECB84B663 flags verified ) + rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Daichi no Shou (Japan).gbc" size 1048576 crc e42538f0 sha1 08BF49D7E225C695F64D38131CB720DECB84B663 flags verified ) ) game ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan)" description "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan)" - rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan).gbc" size 1048576 crc 3272E6F9 md5 484020D0BF01D29F2A74322E0D4ACC3A sha1 596AA066CCEE9FAE71643576F7526BAA22D26D6D flags verified ) + rom ( name "Zelda no Densetsu - Fushigi no Kinomi - Jikuu no Shou (Japan).gbc" size 1048576 crc 3272e6f9 sha1 596AA066CCEE9FAE71643576F7526BAA22D26D6D flags verified ) ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced).gbc" size 1048576 crc D974ABEA md5 F75874E3654360094FC2B09BD1FED7E8 sha1 B810925BF9D9F4F6CD97C5E46C94C1A9DD61A113 ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc d974abea sha1 B810925BF9D9F4F6CD97C5E46C94C1A9DD61A113 ) ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev A) (SGB Enhanced)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev A) (SGB Enhanced).gbc" size 1048576 crc BD8A1041 md5 6D8F9CD72201CAABDFD0455A819AF9CE sha1 D3DE302D44BDB240BCF55A5DC70F491F5456D721 flags verified ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc bd8a1041 sha1 D3DE302D44BDB240BCF55A5DC70F491F5456D721 flags verified ) ) game ( - name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev B) (SGB Enhanced)" - description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev B) (SGB Enhanced)" - rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev B) (SGB Enhanced).gbc" size 1048576 crc E998E595 md5 2E2596C008D47DF901394D28F5BD66EC sha1 5FDFFAE3CAEF63A9FB295BCBD38F923190254E01 flags verified ) + name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (SGB Enhanced) (GB Compatible)" + description "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (SGB Enhanced) (GB Compatible)" + rom ( name "Zelda no Densetsu - Yume o Miru Shima DX (Japan) (Rev 2) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e998e595 sha1 5FDFFAE3CAEF63A9FB295BCBD38F923190254E01 flags verified ) ) game ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan)" description "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan)" - rom ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan).gbc" size 2097152 crc EFAD8B34 md5 2CDD3D78009AFDAD0A49DED398FF17C9 sha1 BFFE5FDB803F0872D1C0DE9D152EB626C5B36147 ) + rom ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan).gbc" size 2097152 crc efad8b34 sha1 BFFE5FDB803F0872D1C0DE9D152EB626C5B36147 flags verified ) ) game ( name "Zidane Football Generation (Europe) (En,Fr,De,Es,It)" description "Zidane Football Generation (Europe) (En,Fr,De,Es,It)" - rom ( name "Zidane Football Generation (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc E96DBFB5 md5 0044C80FB6C6C7C49466DAFE6637D61A sha1 06385470BB0B4EF6C743AB6A5E7F8D7A97F6100B flags verified ) + rom ( name "Zidane Football Generation (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc e96dbfb5 sha1 06385470BB0B4EF6C743AB6A5E7F8D7A97F6100B flags verified ) ) game ( name "Zoboomafoo - Playtime in Zobooland (USA)" description "Zoboomafoo - Playtime in Zobooland (USA)" - rom ( name "Zoboomafoo - Playtime in Zobooland (USA).gbc" size 1048576 crc 38D91885 md5 63F1430338D4F8053A34587429FB6B96 sha1 A85A113BC266325F807F110DAAF30FEEEA4B2738 ) + rom ( name "Zoboomafoo - Playtime in Zobooland (USA).gbc" size 1048576 crc 38d91885 sha1 A85A113BC266325F807F110DAAF30FEEEA4B2738 ) ) game ( - name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced)" - description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced)" - rom ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced).gbc" size 2097152 crc F36C874D md5 E2F33AAF29750F1142B2B6017B454BD4 sha1 4DDB1D66D909D453374BD195A4A7DBE328ED41BE flags verified ) + name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" + description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" + rom ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc f36c874d sha1 4DDB1D66D909D453374BD195A4A7DBE328ED41BE flags verified ) ) game ( - name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev A) (SGB Enhanced)" - description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev A) (SGB Enhanced)" - rom ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev A) (SGB Enhanced).gbc" size 2097152 crc 96461918 md5 ACD26C013FFA1C3A7905BE69DD79C67C sha1 BFE8CDB8A8DA37D5C8D9DB57E8A5EEEDEE24D4CC flags verified ) + name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible)" + rom ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (Rev 1) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 96461918 sha1 BFE8CDB8A8DA37D5C8D9DB57E8A5EEEDEE24D4CC flags verified ) ) game ( name "Zoids - Shirogane no Juukishin Liger Zero (Japan)" description "Zoids - Shirogane no Juukishin Liger Zero (Japan)" - rom ( name "Zoids - Shirogane no Juukishin Liger Zero (Japan).gbc" size 2097152 crc 530705A1 md5 77836DF2B2CE5284E4DDA233E118B914 sha1 A5623AB4E026AA546B345F2BD5638CFDFED68C04 ) + rom ( name "Zoids - Shirogane no Juukishin Liger Zero (Japan).gbc" size 2097152 crc 530705a1 sha1 A5623AB4E026AA546B345F2BD5638CFDFED68C04 flags verified ) ) game ( name "Zok Zok Heroes (Japan)" description "Zok Zok Heroes (Japan)" - rom ( name "Zok Zok Heroes (Japan).gbc" size 2097152 crc C09F9E1B md5 E4874674056451F1DF22C2CBF7A25F93 sha1 91AB908FDDEBD926E7DB8D61295A40955B2ADC39 flags verified ) + rom ( name "Zok Zok Heroes (Japan).gbc" size 2097152 crc c09f9e1b sha1 91AB908FDDEBD926E7DB8D61295A40955B2ADC39 flags verified ) ) From 30e0624751a01f1d93e13ecbab66ab4a62af33db Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 May 2019 16:34:18 -0700 Subject: [PATCH 329/429] GBA Video: Fix backdrop color trick in GL --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 94e8228f9..6d2011904 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1389,7 +1389,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { } glEnable(GL_SCISSOR_TEST); - uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->d.palette[0]); + uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->shadowPalette[0]); glViewport(0, 0, 1, GBA_VIDEO_VERTICAL_PIXELS); glScissor(0, glRenderer->firstY, 1, y - glRenderer->firstY + 1); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); From 33d13b3757da9ec8ebecfa3a684e6ddd3d4b53e1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 May 2019 17:20:54 -0700 Subject: [PATCH 330/429] GBA Video: Optimize mode 0 offset changes in GL --- include/mgba/internal/gba/renderers/gl.h | 7 +- src/gba/renderers/gl.c | 178 ++++++++++------------- 2 files changed, 76 insertions(+), 109 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 13502686b..0d804bc6f 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -45,7 +45,6 @@ struct GBAVideoGLBackground { GLuint fbo; GLuint tex; GLuint flags; - GLuint scanlineTex; unsigned index; int enabled; @@ -64,6 +63,9 @@ struct GBAVideoGLBackground { int32_t refy; struct GBAVideoGLAffine affine; + + GLint scanlineAffine[GBA_VIDEO_VERTICAL_PIXELS * 4]; + GLint scanlineOffset[GBA_VIDEO_VERTICAL_PIXELS]; }; enum { @@ -81,8 +83,6 @@ enum { GBA_GL_TEX_BACKDROP_COLOR, GBA_GL_TEX_BACKDROP_FLAGS, GBA_GL_TEX_WINDOW, - GBA_GL_TEX_AFFINE_2, - GBA_GL_TEX_AFFINE_3, GBA_GL_TEX_MAX }; @@ -140,7 +140,6 @@ struct GBAVideoGLRenderer { uint32_t* temporaryBuffer; struct GBAVideoGLBackground bg[4]; - struct GBAVideoGLAffine affine[2][GBA_VIDEO_VERTICAL_PIXELS]; int oamMax; bool oamDirty; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 6d2011904..56984b3bc 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -129,7 +129,7 @@ static const char* const _renderMode0 = "uniform int screenBase;\n" "uniform int charBase;\n" "uniform int size;\n" - "uniform ivec2 offset;\n" + "uniform int offset[160];\n" "uniform ivec4 inflags;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" @@ -145,11 +145,17 @@ static const char* const _renderMode0 = " if (mosaic.y > 1) {\n" " coord.y -= coord.y % mosaic.y;\n" " }\n" - " coord += offset;\n" + " coord += (ivec2(0x3FF, 0x3FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n" + " if (size == 3) {\n" + " coord.y += (coord.y & 256) << 1;\n" + " }\n" + " if (size != 2) {\n" + " coord.y &= ~256;\n" + " }\n" " if ((size & 1) == 1) {\n" " coord.y += coord.x & 256;\n" " }\n" - " coord.x &= 255;\n" + " coord &= ivec2(255, 511);\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int tileFlags = int(map.g * 15.9);\n" @@ -208,22 +214,15 @@ static const char* const _interpolate = "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]) {\n" " int start = max(range.x, y - 3);\n" - " ivec4 splitOffset[4];\n" - " mat[0] = texelFetch(transform, ivec2(0, start), 0).xz;\n" - " mat[1] = texelFetch(transform, ivec2(0, start + 1), 0).xz;\n" - " mat[2] = texelFetch(transform, ivec2(0, start + 2), 0).xz;\n" - " mat[3] = texelFetch(transform, ivec2(0, start + 3), 0).xz;\n" - - " splitOffset[0] = texelFetch(transform, ivec2(1, start + 0), 0);\n" - " splitOffset[1] = texelFetch(transform, ivec2(1, start + 1), 0);\n" - " splitOffset[2] = texelFetch(transform, ivec2(1, start + 2), 0);\n" - " splitOffset[3] = texelFetch(transform, ivec2(1, start + 3), 0);\n" - - " aff[0] = (splitOffset[0].xz & 0xFFFF) + (splitOffset[0].yw << 16);\n" - " aff[1] = (splitOffset[1].xz & 0xFFFF) + (splitOffset[1].yw << 16);\n" - " aff[2] = (splitOffset[2].xz & 0xFFFF) + (splitOffset[2].yw << 16);\n" - " aff[3] = (splitOffset[3].xz & 0xFFFF) + (splitOffset[3].yw << 16);\n" + " mat[0] = transform[start + 0].xy;\n" + " aff[0] = transform[start + 0].zw;\n" + " mat[1] = transform[start + 1].xy;\n" + " aff[1] = transform[start + 1].zw;\n" + " mat[2] = transform[start + 2].xy;\n" + " aff[2] = transform[start + 2].zw;\n" + " mat[3] = transform[start + 3].xy;\n" + " aff[3] = transform[start + 3].zw;\n" " if (y - 3 < range.x) {\n" " ivec2 tempMat[3];\n" @@ -273,7 +272,7 @@ static const char* const _renderMode2 = "uniform int charBase;\n" "uniform int size;\n" "uniform ivec4 inflags;\n" - "uniform isampler2D transform;\n" + "uniform ivec4 transform[160];\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" @@ -339,7 +338,7 @@ static const char* const _renderMode35 = "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" - "uniform isampler2D transform;\n" + "uniform ivec4 transform[160];\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" @@ -399,7 +398,7 @@ static const char* const _renderMode4 = "uniform int charBase;\n" "uniform ivec2 size;\n" "uniform ivec4 inflags;\n" - "uniform isampler2D transform;\n" + "uniform ivec4 transform[160];\n" "uniform ivec2 range;\n" "uniform ivec2 mosaic;\n" "OUT(0) out vec4 color;\n" @@ -749,19 +748,6 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 256, 192, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 0); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_2]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, NULL); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_3]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, NULL); - glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); @@ -814,8 +800,8 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFramebuffer(GL_FRAMEBUFFER, bg->fbo); _initFramebufferTexture(bg->tex, GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTextureEx(bg->flags, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); - glBindFramebuffer(GL_FRAMEBUFFER, 0); } + glBindFramebuffer(GL_FRAMEBUFFER, 0); char log[2048]; const GLchar* shaderBuffer[4]; @@ -965,15 +951,44 @@ uint16_t GBAVideoGLRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, dirty = true; break; case REG_BG0HOFS: + value &= 0x01FF; + glRenderer->bg[0].x = value; + dirty = false; + break; case REG_BG0VOFS: + value &= 0x01FF; + glRenderer->bg[0].y = value; + dirty = false; + break; case REG_BG1HOFS: + value &= 0x01FF; + glRenderer->bg[1].x = value; + dirty = false; + break; case REG_BG1VOFS: + value &= 0x01FF; + glRenderer->bg[1].y = value; + dirty = false; + break; case REG_BG2HOFS: + value &= 0x01FF; + glRenderer->bg[2].x = value; + dirty = false; + break; case REG_BG2VOFS: + value &= 0x01FF; + glRenderer->bg[2].y = value; + dirty = false; + break; case REG_BG3HOFS: + value &= 0x01FF; + glRenderer->bg[3].x = value; + dirty = false; + break; case REG_BG3VOFS: value &= 0x01FF; - dirty = true; + glRenderer->bg[3].y = value; + dirty = false; break; case REG_BG2PA: glRenderer->bg[2].affine.dx = value; @@ -1124,30 +1139,6 @@ void _cleanRegister(struct GBAVideoGLRenderer* glRenderer, int address, uint16_t case REG_BG3CNT: GBAVideoGLRendererWriteBGCNT(&glRenderer->bg[3], value); break; - case REG_BG0HOFS: - glRenderer->bg[0].x = value; - break; - case REG_BG0VOFS: - glRenderer->bg[0].y = value; - break; - case REG_BG1HOFS: - glRenderer->bg[1].x = value; - break; - case REG_BG1VOFS: - glRenderer->bg[1].y = value; - break; - case REG_BG2HOFS: - glRenderer->bg[2].x = value; - break; - case REG_BG2VOFS: - glRenderer->bg[2].y = value; - break; - case REG_BG3HOFS: - glRenderer->bg[3].x = value; - break; - case REG_BG3VOFS: - glRenderer->bg[3].y = value; - break; case REG_BLDCNT: GBAVideoGLRendererWriteBLDCNT(glRenderer, value); value &= 0x3FFF; @@ -1314,8 +1305,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } glRenderer->regsDirty = 0; - memcpy(&glRenderer->affine[0][y], &glRenderer->bg[2].affine, sizeof(struct GBAVideoGLAffine)); - memcpy(&glRenderer->affine[1][y], &glRenderer->bg[3].affine, sizeof(struct GBAVideoGLAffine)); glRenderer->winNHistory[0][y * 4 + 0] = glRenderer->winN[0].h.start; glRenderer->winNHistory[0][y * 4 + 1] = glRenderer->winN[0].h.end; glRenderer->winNHistory[0][y * 4 + 2] = glRenderer->winN[0].v.start; @@ -1325,6 +1314,23 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { glRenderer->winNHistory[1][y * 4 + 2] = glRenderer->winN[1].v.start; glRenderer->winNHistory[1][y * 4 + 3] = glRenderer->winN[1].v.end; + glRenderer->bg[0].scanlineOffset[y] = glRenderer->bg[0].x; + glRenderer->bg[0].scanlineOffset[y] |= glRenderer->bg[0].y << 12; + glRenderer->bg[1].scanlineOffset[y] = glRenderer->bg[1].x; + glRenderer->bg[1].scanlineOffset[y] |= glRenderer->bg[1].y << 12; + glRenderer->bg[2].scanlineOffset[y] = glRenderer->bg[2].x; + glRenderer->bg[2].scanlineOffset[y] |= glRenderer->bg[2].y << 12; + glRenderer->bg[2].scanlineAffine[y * 4] = glRenderer->bg[2].affine.dx; + glRenderer->bg[2].scanlineAffine[y * 4 + 1] = glRenderer->bg[2].affine.dy; + glRenderer->bg[2].scanlineAffine[y * 4 + 2] = glRenderer->bg[2].affine.sx; + glRenderer->bg[2].scanlineAffine[y * 4 + 3] = glRenderer->bg[2].affine.sy; + glRenderer->bg[3].scanlineOffset[y] = glRenderer->bg[3].x; + glRenderer->bg[3].scanlineOffset[y] |= glRenderer->bg[3].y << 12; + glRenderer->bg[3].scanlineAffine[y * 4] = glRenderer->bg[3].affine.dx; + glRenderer->bg[3].scanlineAffine[y * 4 + 1] = glRenderer->bg[3].affine.dy; + glRenderer->bg[3].scanlineAffine[y * 4 + 2] = glRenderer->bg[3].affine.sx; + glRenderer->bg[3].scanlineAffine[y * 4 + 3] = glRenderer->bg[3].affine.sy; + if (glRenderer->paletteDirty) { for (i = 0; i < 512; ++i) { glRenderer->shadowPalette[i] = glRenderer->d.palette[i]; @@ -1381,12 +1387,6 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { } void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { - if (glRenderer->firstAffine >= 0) { - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, glRenderer->affine[0]); - glBindTexture(GL_TEXTURE_2D, glRenderer->layers[GBA_GL_TEX_AFFINE_3]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16I, 2, GBA_VIDEO_VERTICAL_PIXELS, 0, GL_RGBA_INTEGER, GL_SHORT, glRenderer->affine[1]); - } glEnable(GL_SCISSOR_TEST); uint32_t backdrop = M_RGB5_TO_RGB8(glRenderer->shadowPalette[0]); @@ -1712,19 +1712,6 @@ void _prepareBackground(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBa } void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBackground* background, int y) { - int inY0 = renderer->firstY + background->y; - int yDiv = (((y + background->y) & ~0xFF) - background->y) & 0xFF; - int inY1 = yDiv + background->y; - int yBase0 = inY0 & 0xFF; - int yBase1 = inY1 & 0xFF; - if (background->size == 2) { - yBase0 += inY0 & 0x100; - yBase1 += inY1 & 0x100; - } else if (background->size == 3) { - yBase0 += (inY0 & 0x100) << 1; - yBase1 += (inY1 & 0x100) << 1; - } - const struct GBAVideoGLShader* shader = &renderer->bgShader[background->multipalette ? 1 : 0]; const GLuint* uniforms = shader->uniforms; glUseProgram(shader->program); @@ -1733,28 +1720,11 @@ void GBAVideoGLRendererDrawBackgroundMode0(struct GBAVideoGLRenderer* renderer, glUniform1i(uniforms[GBA_GL_BG_SCREENBASE], background->screenBase); glUniform1i(uniforms[GBA_GL_BG_CHARBASE], background->charBase); glUniform1i(uniforms[GBA_GL_BG_SIZE], background->size); + glUniform1iv(uniforms[GBA_GL_BG_OFFSET], GBA_VIDEO_VERTICAL_PIXELS, background->scanlineOffset); - if (yDiv > renderer->firstY) { - int end = yDiv - 1; - if (end > y) { - end = y; - } - glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, (end - renderer->firstY + 1) * renderer->scale); - glUniform2i(uniforms[GBA_GL_VS_LOC], end - renderer->firstY + 1, renderer->firstY); - glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase0 - renderer->firstY); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - if (y >= yDiv) { - int start = yDiv; - if (yDiv < renderer->firstY) { - start = renderer->firstY; - } - glScissor(0, start * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, (y - start + 1) * renderer->scale); - glUniform2i(uniforms[GBA_GL_VS_LOC], y - start + 1, start); - glUniform2i(uniforms[GBA_GL_BG_OFFSET], background->x, yBase1 - yDiv); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } + glScissor(0, renderer->firstY * renderer->scale, GBA_VIDEO_HORIZONTAL_PIXELS * renderer->scale, (y - renderer->firstY + 1) * renderer->scale); + glUniform2i(uniforms[GBA_GL_VS_LOC], y - renderer->firstY + 1, renderer->firstY); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } @@ -1764,9 +1734,7 @@ void _prepareTransform(struct GBAVideoGLRenderer* renderer, struct GBAVideoGLBac glUniform2i(uniforms[GBA_GL_VS_LOC], y - renderer->firstY + 1, renderer->firstY); glUniform2i(uniforms[GBA_GL_BG_RANGE], renderer->firstAffine, y); - glActiveTexture(GL_TEXTURE0 + 2); - glBindTexture(GL_TEXTURE_2D, renderer->layers[GBA_GL_TEX_AFFINE_2 + background->index - 2]); - glUniform1i(uniforms[GBA_GL_BG_TRANSFORM], 2); + glUniform4iv(uniforms[GBA_GL_BG_TRANSFORM], GBA_VIDEO_VERTICAL_PIXELS, background->scanlineAffine); _prepareBackground(renderer, background, uniforms); } From fcb5a4168fed46dffb4572d193182d6b25d71b39 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 May 2019 21:52:15 -0700 Subject: [PATCH 331/429] Qt: Fix VideoProxy lifetime --- src/platform/qt/Display.h | 5 ++++- src/platform/qt/DisplayGL.cpp | 26 +++++++++++++++++--------- src/platform/qt/DisplayGL.h | 9 +++++---- src/platform/qt/Window.cpp | 11 +++++++---- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index a5c1d227a..52db65a41 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -49,9 +49,11 @@ public: virtual bool isDrawing() const = 0; virtual bool supportsShaders() const = 0; virtual VideoShader* shaders() = 0; - virtual VideoProxy* videoProxy() { return nullptr; } virtual int framebufferHandle() { return -1; } + virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = proxy; } + std::shared_ptr videoProxy() { return m_videoProxy; } + signals: void showCursor(); void hideCursor(); @@ -88,6 +90,7 @@ private: bool m_interframeBlending = false; bool m_filter = false; QTimer m_mouseTimer; + std::shared_ptr m_videoProxy; }; } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index ddf4c211c..86460606e 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -57,7 +57,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) m_gl->create(); } - m_painter = new PainterGL(&m_videoProxy, windowHandle(), m_gl); + m_painter = new PainterGL(windowHandle(), m_gl); setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions } @@ -95,7 +95,9 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { m_gl->doneCurrent(); m_gl->moveToThread(m_drawThread); m_painter->moveToThread(m_drawThread); - m_videoProxy.moveToThread(m_drawThread); + if (videoProxy()) { + videoProxy()->moveToThread(m_drawThread); + } connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start); m_drawThread->start(); @@ -217,21 +219,21 @@ void DisplayGL::resizePainter() { } } -VideoProxy* DisplayGL::videoProxy() { - if (supportsShaders()) { - return &m_videoProxy; +void DisplayGL::setVideoProxy(std::shared_ptr proxy) { + Display::setVideoProxy(proxy); + if (m_drawThread && proxy) { + proxy->moveToThread(m_drawThread); } - return nullptr; + m_painter->setVideoProxy(proxy); } int DisplayGL::framebufferHandle() { return m_painter->glTex(); } -PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent) +PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent) : m_gl(parent) , m_surface(surface) - , m_videoProxy(proxy) { #ifdef BUILD_GL mGLContext* glBackend; @@ -425,7 +427,9 @@ void PainterGL::stop() { m_gl->moveToThread(m_surface->thread()); m_context.reset(); moveToThread(m_gl->thread()); - m_videoProxy->moveToThread(m_gl->thread()); + if (m_videoProxy) { + m_videoProxy->moveToThread(m_gl->thread()); + } } void PainterGL::pause() { @@ -516,6 +520,10 @@ void PainterGL::dequeueAll() { m_mutex.unlock(); } +void PainterGL::setVideoProxy(std::shared_ptr proxy) { + m_videoProxy = proxy; +} + void PainterGL::setShaders(struct VDir* dir) { if (!supportsShaders()) { return; diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index ff6d647b0..0256b32cc 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -42,7 +42,7 @@ public: bool isDrawing() const override { return m_isDrawing; } bool supportsShaders() const override; VideoShader* shaders() override; - VideoProxy* videoProxy() override; + void setVideoProxy(std::shared_ptr) override; int framebufferHandle() override; public slots: @@ -71,14 +71,13 @@ private: PainterGL* m_painter; QThread* m_drawThread = nullptr; std::shared_ptr m_context; - VideoProxy m_videoProxy; }; class PainterGL : public QObject { Q_OBJECT public: - PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent); + PainterGL(QWindow* surface, QOpenGLContext* parent); ~PainterGL(); void setContext(std::shared_ptr); @@ -87,6 +86,8 @@ public: bool supportsShaders() const { return m_supportsShaders; } + void setVideoProxy(std::shared_ptr); + public slots: void forceDraw(); void draw(); @@ -133,7 +134,7 @@ private: QTimer m_swapTimer{this}; bool m_needsUnlock = false; bool m_frameReady = false; - VideoProxy* m_videoProxy; + std::shared_ptr m_videoProxy; }; } diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ded67df94..ddb89f737 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -780,7 +780,6 @@ void Window::gameStarted() { } void Window::gameStopped() { - m_controller.reset(); #ifdef M_CORE_GBA for (Action* action : m_platformActions) { action->setEnabled(true); @@ -816,6 +815,10 @@ void Window::gameStopped() { m_audioProcessor.reset(); } m_display->stopDrawing(); + + m_controller.reset(); + + m_display->setVideoProxy({}); if (m_pendingClose) { m_display.reset(); close(); @@ -1739,9 +1742,9 @@ void Window::setController(CoreController* controller, const QString& fname) { } if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && controller->supportsFeature(CoreController::Feature::OPENGL)) { - if (m_display->videoProxy()) { - m_display->videoProxy()->attach(controller); - } + std::shared_ptr proxy = std::make_shared(); + m_display->setVideoProxy(proxy); + proxy->attach(controller); int fb = m_display->framebufferHandle(); if (fb >= 0) { From baeba633ee6a61b45e99ddc35599317eb6609b32 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 May 2019 22:29:51 -0700 Subject: [PATCH 332/429] Qt: Minor cleanup --- src/platform/qt/DisplayQt.cpp | 1 - src/platform/qt/Window.cpp | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index e3c227c1b..be6403dd6 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -109,7 +109,6 @@ void DisplayQt::paintEvent(QPaintEvent*) { ds.setWidth(ds.width() - ds.width() % m_width); ds.setHeight(ds.height() - ds.height() % m_height); } -#warning TODO: Add interframeBlending QPoint origin = QPoint((s.width() - ds.width()) / 2, (s.height() - ds.height()) / 2); QRect full(origin, ds); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ddb89f737..3ef192255 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -773,18 +773,15 @@ void Window::gameStarted() { } m_actions.rebuildMenu(menuBar(), this, *m_shortcutController); - #ifdef USE_DISCORD_RPC DiscordCoordinator::gameStarted(m_controller); #endif } void Window::gameStopped() { -#ifdef M_CORE_GBA for (Action* action : m_platformActions) { action->setEnabled(true); } -#endif for (Action* action : m_gameActions) { action->setEnabled(false); } From 6b41d91e69463ceab0293e8272413884be961eae Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 May 2019 23:15:15 -0700 Subject: [PATCH 333/429] Qt: Fix excess wakeups in VideoProxy --- src/platform/qt/VideoProxy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/VideoProxy.cpp b/src/platform/qt/VideoProxy.cpp index 1eb8fa933..431de4d26 100644 --- a/src/platform/qt/VideoProxy.cpp +++ b/src/platform/qt/VideoProxy.cpp @@ -62,7 +62,6 @@ bool VideoProxy::writeData(const void* data, size_t length) { m_fromThreadCond.wait(&m_mutex); m_mutex.unlock(); } - emit dataAvailable(); return true; } @@ -109,6 +108,7 @@ void VideoProxy::wait() { void VideoProxy::wake(int y) { if ((y & 15) == 15) { + emit dataAvailable(); m_toThreadCond.wakeAll(); } } From e8383209c52406356e43b41c4c5080318879c22e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 09:33:15 -0700 Subject: [PATCH 334/429] Qt: Make mute menu option also toggle fast-forward mute (fixes #1424) --- CHANGES | 1 + src/platform/qt/Window.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index b4180940d..be5d78206 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,7 @@ Misc: - Qt: Add native FPS button to settings view - Qt: Improve sync code - Switch: Dynamic display resizing + - Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424) 0.7.2: (2019-05-25) Emulation fixes: diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 3ef192255..00a7f5b00 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1375,6 +1375,7 @@ void Window::setupMenu(QMenuBar* menubar) { ConfigOption* mute = m_config->addOption("mute"); mute->addBoolean(tr("Mute"), &m_actions, "av"); mute->connect([this](const QVariant& value) { + m_config->setOption("fastForwardMute", static_cast(value.toInt())); reloadConfig(); }, this); m_config->updateOption("mute"); From 422d2cb7552c3b029d6e211e3a69ac76e0dbb06b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 09:52:27 -0700 Subject: [PATCH 335/429] Wii: Fix typos (fixes #1428) --- src/platform/wii/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 5ab370bbf..c7f524713 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -479,7 +479,7 @@ int main(int argc, char* argv[]) { .submenu = 0, .state = 7, .validStates = (const char*[]) { - "1/2x", "0.6x", "1/3x", "0.7x", "1/4x", "0.8x", "0.9x", "1.0x" + "1/2x", "0.6x", "2/3x", "0.7x", "3/4x", "0.8x", "0.9x", "1.0x" }, .stateMappings = (const struct GUIVariant[]) { GUI_V_F(0.5f), From cabbffad416193029e3e4fac56d2ee99119f56bb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 09:57:26 -0700 Subject: [PATCH 336/429] Wii: 2/3, not 1/3 scaling is useful --- src/platform/wii/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index c7f524713..540b797d0 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -484,7 +484,7 @@ int main(int argc, char* argv[]) { .stateMappings = (const struct GUIVariant[]) { GUI_V_F(0.5f), GUI_V_F(0.6f), - GUI_V_F(1.f / 3.f), + GUI_V_F(2.f / 3.f), GUI_V_F(0.7f), GUI_V_F(0.75f), GUI_V_F(0.8f), From b6f8ff7569ef485c4f3b49427b7c798a419fe146 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 09:58:00 -0700 Subject: [PATCH 337/429] Wii: Other half of last two commits --- src/platform/wii/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 540b797d0..634aa52f9 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -499,12 +499,12 @@ int main(int argc, char* argv[]) { .submenu = 0, .state = 6, .validStates = (const char*[]) { - "1/2x", "0.6x", "1/3x", "0.7x", "1/4x", "0.8x", "0.9x", "1.0x" + "1/2x", "0.6x", "2/3x", "0.7x", "3/4x", "0.8x", "0.9x", "1.0x" }, .stateMappings = (const struct GUIVariant[]) { GUI_V_F(0.5f), GUI_V_F(0.6f), - GUI_V_F(1.f / 3.f), + GUI_V_F(2.f / 3.f), GUI_V_F(0.7f), GUI_V_F(0.75f), GUI_V_F(0.8f), From 14b3bdf414536b166e50405c829d4047817f840b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 12:08:00 -0700 Subject: [PATCH 338/429] Wii: Interframe blending --- src/platform/wii/main.c | 45 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 634aa52f9..1c2ab5ada 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -87,6 +87,7 @@ static void _setup(struct mGUIRunner* runner); static void _gameLoaded(struct mGUIRunner* runner); static void _gameUnloaded(struct mGUIRunner* runner); static void _unpaused(struct mGUIRunner* runner); +static void _prepareForFrame(struct mGUIRunner* runner); static void _drawFrame(struct mGUIRunner* runner, bool faded); static uint16_t _pollGameInput(struct mGUIRunner* runner); static void _setFrameLimiter(struct mGUIRunner* runner, bool limit); @@ -110,6 +111,8 @@ static uint16_t* texmem; static GXTexObj tex; static uint16_t* rescaleTexmem; static GXTexObj rescaleTex; +static uint16_t* interframeTexmem; +static GXTexObj interframeTex; static int32_t tiltX; static int32_t tiltY; static int32_t gyroZ; @@ -118,6 +121,7 @@ static uint32_t referenceRetraceCount; static bool frameLimiter = true; static int scaleFactor; static unsigned corew, coreh; +static bool interframeBlending = true; uint32_t* romBuffer; size_t romBufferSize; @@ -277,10 +281,16 @@ int main(int argc, char* argv[]) { GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S16, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GX_SetNumTevStages(1); GX_SetNumChans(1); GX_SetNumTexGens(1); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR0A0); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); + GX_SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_DIVIDE_2, GX_TRUE, GX_TEVPREV); + GX_SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV); + GX_SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_InvVtxCache(); @@ -298,6 +308,8 @@ int main(int argc, char* argv[]) { texmem = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL); GX_InitTexObj(&tex, texmem, TEX_W, TEX_H, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); + interframeTexmem = memalign(32, TEX_W * TEX_H * BYTES_PER_PIXEL); + GX_InitTexObj(&interframeTex, interframeTexmem, TEX_W, TEX_H, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); rescaleTexmem = memalign(32, TEX_W * TEX_H * 4 * BYTES_PER_PIXEL); GX_InitTexObj(&rescaleTex, rescaleTexmem, TEX_W * 2, TEX_H * 2, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObjFilterMode(&rescaleTex, GX_LINEAR, GX_LINEAR); @@ -519,7 +531,7 @@ int main(int argc, char* argv[]) { .teardown = 0, .gameLoaded = _gameLoaded, .gameUnloaded = _gameUnloaded, - .prepareForFrame = 0, + .prepareForFrame = _prepareForFrame, .drawFrame = _drawFrame, .paused = _gameUnloaded, .unpaused = _unpaused, @@ -584,6 +596,7 @@ int main(int argc, char* argv[]) { free(fifo); free(texmem); free(rescaleTexmem); + free(interframeTexmem); free(outputBuffer); GUIFontDestroy(font); @@ -728,6 +741,7 @@ void _reproj2(int w, int h) { } void _guiPrepare(void) { + GX_SetNumTevStages(1); _reproj2(vmode->fbWidth * guiScale * wAdjust, vmode->efbHeight * guiScale * hAdjust); } @@ -811,6 +825,7 @@ void _gameLoaded(struct mGUIRunner* runner) { } } memset(texmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL); + memset(interframeTexmem, 0, TEX_W * TEX_H * BYTES_PER_PIXEL); _unpaused(runner); } @@ -843,6 +858,10 @@ void _unpaused(struct mGUIRunner* runner) { break; } } + int fakeBool; + mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); + interframeBlending = fakeBool; + float stretch; if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) { wStretch = fminf(1.0f, fmaxf(0.5f, stretch)); @@ -852,6 +871,12 @@ void _unpaused(struct mGUIRunner* runner) { } } +void _prepareForFrame(struct mGUIRunner* runner) { + if (interframeBlending) { + memcpy(interframeTexmem, texmem, TEX_W * TEX_H * BYTES_PER_PIXEL); + } +} + void _drawFrame(struct mGUIRunner* runner, bool faded) { runner->core->desiredVideoDimensions(runner->core, &corew, &coreh); uint32_t color = 0xFFFFFF3F; @@ -870,14 +895,24 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) { } } DCFlushRange(texdest, TEX_W * TEX_H * BYTES_PER_PIXEL); + if (interframeBlending) { + DCFlushRange(interframeTexmem, TEX_W * TEX_H * BYTES_PER_PIXEL); + } - if (faded) { + if (faded || interframeBlending) { GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); } else { GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP); } GX_InvalidateTexAll(); - GX_LoadTexObj(&tex, GX_TEXMAP0); + if (interframeBlending) { + GX_LoadTexObj(&interframeTex, GX_TEXMAP0); + GX_LoadTexObj(&tex, GX_TEXMAP1); + GX_SetNumTevStages(2); + } else { + GX_LoadTexObj(&tex, GX_TEXMAP0); + GX_SetNumTevStages(1); + } GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); s16 vertWidth = corew; @@ -910,6 +945,10 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) { GX_SetTexCopyDst(TEX_W * 2, TEX_H * 2, GX_TF_RGB565, GX_FALSE); GX_CopyTex(rescaleTexmem, GX_TRUE); GX_LoadTexObj(&rescaleTex, GX_TEXMAP0); + GX_SetNumTevStages(1); + if (!faded) { + GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_NOOP); + } } int hfactor = (vmode->fbWidth * wStretch) / (corew * wAdjust); From cc71f7f9647ecec22926c3c0e848e0ee838e0308 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 12:58:59 -0700 Subject: [PATCH 339/429] GBA Video: Use interpolation not extrapolation for first few scanlines (fixes #1431) --- src/gba/renderers/gl.c | 61 +++++++++++++----------------------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 56984b3bc..97acc8e02 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -214,7 +214,6 @@ static const char* const _interpolate = "void loadAffine(int y, out ivec2 mat[4], out ivec2 aff[4]) {\n" " int start = max(range.x, y - 3);\n" - " mat[0] = transform[start + 0].xy;\n" " aff[0] = transform[start + 0].zw;\n" " mat[1] = transform[start + 1].xy;\n" @@ -223,45 +222,6 @@ static const char* const _interpolate = " aff[2] = transform[start + 2].zw;\n" " mat[3] = transform[start + 3].xy;\n" " aff[3] = transform[start + 3].zw;\n" - - " if (y - 3 < range.x) {\n" - " ivec2 tempMat[3];\n" - " ivec2 tempAff[3];\n" - " tempMat[0] = ivec2(interpolate(mat, -0.75));\n" - " tempMat[1] = ivec2(interpolate(mat, -0.5));\n" - " tempMat[2] = ivec2(interpolate(mat, -0.25));\n" - " tempAff[0] = ivec2(interpolate(aff, -0.75));\n" - " tempAff[1] = ivec2(interpolate(aff, -0.5));\n" - " tempAff[2] = ivec2(interpolate(aff, -0.25));\n" - " if (range.x == y) {\n" - " mat[3] = mat[0];\n" - " mat[2] = tempMat[2];\n" - " mat[1] = tempMat[1];\n" - " mat[0] = tempMat[0];\n" - " aff[3] = aff[0];\n" - " aff[2] = tempAff[2];\n" - " aff[1] = tempAff[1];\n" - " aff[0] = tempAff[0];\n" - " } else if (range.x == y - 1) {\n" - " mat[3] = mat[1];\n" - " mat[2] = mat[0];\n" - " mat[1] = tempMat[2];\n" - " mat[0] = tempMat[1];\n" - " aff[3] = aff[1];\n" - " aff[2] = aff[0];\n" - " aff[1] = tempAff[2];\n" - " aff[0] = tempAff[1];\n" - " } else if (range.x == y - 2) {\n" - " mat[3] = mat[2];\n" - " mat[2] = mat[1];\n" - " mat[1] = mat[0];\n" - " mat[0] = tempMat[0];\n" - " aff[3] = aff[2];\n" - " aff[2] = aff[1];\n" - " aff[1] = aff[0];\n" - " aff[0] = tempAff[0];\n" - " }\n" - " }\n" "}\n"; static const char* const _renderMode2 = @@ -311,7 +271,12 @@ static const char* const _renderMode2 = " }\n" " loadAffine(int(incoord.y), mat, offset);\n" " float y = fract(incoord.y);\n" - " float lin = 0.75 + y * 0.25;\n" + " float start = 0.75;\n" + " if (int(incoord.y) - range.x < 4) {\n" + " y = incoord.y - float(range.x);\n" + " start = 0.;\n" + " }\n" + " float lin = start + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " color = fetchTile(ivec2(mixedTransform * incoord.x + mixedOffset));\n" @@ -359,7 +324,12 @@ static const char* const _renderMode35 = " }\n" " loadAffine(int(incoord.y), mat, offset);\n" " float y = fract(incoord.y);\n" - " float lin = 0.75 + y * 0.25;\n" + " float start = 0.75;\n" + " if (int(incoord.y) - range.x < 4) {\n" + " y = incoord.y - float(range.x);\n" + " start = 0.;\n" + " }\n" + " float lin = start + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" @@ -419,7 +389,12 @@ static const char* const _renderMode4 = " }\n" " loadAffine(int(incoord.y), mat, offset);\n" " float y = fract(incoord.y);\n" - " float lin = 0.75 + y * 0.25;\n" + " float start = 0.75;\n" + " if (int(incoord.y) - range.x < 4) {\n" + " y = incoord.y - float(range.x);\n" + " start = 0.;\n" + " }\n" + " float lin = start + y * 0.25;\n" " vec2 mixedTransform = interpolate(mat, lin);\n" " vec2 mixedOffset = interpolate(offset, lin);\n" " ivec2 coord = ivec2(mixedTransform * incoord.x + mixedOffset);\n" From 252b9409b66ba0e5fe8d86d530d0b19587c16586 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 13:50:59 -0700 Subject: [PATCH 340/429] Vita: Interframe blending --- src/platform/psp2/psp2-context.c | 38 +++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 6df9181a5..b933dab4f 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -52,8 +52,10 @@ static enum ScreenMode { static void* outputBuffer; static vita2d_texture* tex; +static vita2d_texture* oldTex; static vita2d_texture* screenshot; static Thread audioThread; +static bool interframeBlending = false; static struct mSceRotationSource { struct mRotationSource d; @@ -322,6 +324,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); tex = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); + oldTex = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); screenshot = vita2d_create_empty_texture_format(256, toPow2(height), SCE_GXM_TEXTURE_FORMAT_X8U8U8U8_1BGR); outputBuffer = anonymousMemoryMap(256 * toPow2(height) * 4); @@ -390,6 +393,10 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { break; } + int fakeBool; + mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); + interframeBlending = fakeBool; + MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); memset(audioContext.buffer, 0, sizeof(audioContext.buffer)); @@ -451,18 +458,23 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { } } } + + int fakeBool; + mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); + interframeBlending = fakeBool; } void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); CircleBufferDeinit(&rumble.history); vita2d_free_texture(tex); + vita2d_free_texture(oldTex); vita2d_free_texture(screenshot); mappedMemoryFree(outputBuffer, 256 * 256 * 4); frameLimiter = true; } -void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded) { +void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded, bool interframe) { unsigned w = width; unsigned h = height; // Get greatest common divisor @@ -477,10 +489,21 @@ void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded) { float scalex; float scaley; + unsigned tint = 0x1FFFFFFF; + if (!faded) { + if (interframe) { + tint |= 0x60000000; + } else { + tint |= 0xE0000000; + } + } else if (!interframe) { + tint |= 0x20000000; + } + switch (screenMode) { case SM_BACKDROP: default: - vita2d_draw_texture_tint(backdrop, 0, 0, (faded ? 0 : 0xC0000000) | 0x3FFFFFFF); + vita2d_draw_texture_tint(backdrop, 0, 0, tint); // Fall through case SM_PLAIN: w = 960 / width; @@ -520,15 +543,20 @@ void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded) { (960.0f - w) / 2.0f, (544.0f - h) / 2.0f, 0, 0, width, height, scalex, scaley, - (faded ? 0 : 0xC0000000) | 0x3FFFFFFF); + tint); } void mPSP2Draw(struct mGUIRunner* runner, bool faded) { unsigned width, height; runner->core->desiredVideoDimensions(runner->core, &width, &height); void* texpixels = vita2d_texture_get_datap(tex); + if (interframeBlending) { + void* oldTexpixels = vita2d_texture_get_datap(oldTex); + memcpy(oldTexpixels, texpixels, 256 * height * 4); + _drawTex(oldTex, width, height, faded, false); + } memcpy(texpixels, outputBuffer, 256 * height * 4); - _drawTex(tex, width, height, faded); + _drawTex(tex, width, height, faded, interframeBlending); } void mPSP2DrawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsigned width, unsigned height, bool faded) { @@ -538,7 +566,7 @@ void mPSP2DrawScreenshot(struct mGUIRunner* runner, const uint32_t* pixels, unsi for (y = 0; y < height; ++y) { memcpy(&texpixels[256 * y], &pixels[width * y], width * 4); } - _drawTex(screenshot, width, height, faded); + _drawTex(screenshot, width, height, faded, false); } void mPSP2IncrementScreenMode(struct mGUIRunner* runner) { From 456dbc482f9ee76e8b632e296ff4162ac38f18a1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 15:13:30 -0700 Subject: [PATCH 341/429] 3DS: Interframe blending --- src/platform/3ds/main.c | 65 +++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index ea2bc6d45..9bd228a72 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -89,7 +89,8 @@ static color_t* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; -static C3D_Tex outputTexture; +static C3D_Tex outputTexture[2]; +static int activeOutputTexture = 0; static ndspWaveBuf dspBuffer[DSP_BUFFERS]; static int bufferId = 0; static bool frameLimiter = true; @@ -102,6 +103,7 @@ static bool frameStarted = false; static C3D_RenderTarget* upscaleBuffer; static C3D_Tex upscaleBufferTex; +static bool interframeBlending = false; static aptHookCookie cookie; static bool core2; @@ -150,7 +152,8 @@ static void _cleanup(void) { C3D_RenderTargetDelete(bottomScreen[1]); C3D_RenderTargetDelete(upscaleBuffer); C3D_TexDelete(&upscaleBufferTex); - C3D_TexDelete(&outputTexture); + C3D_TexDelete(&outputTexture[0]); + C3D_TexDelete(&outputTexture[1]); C3D_Fini(); gfxExit(); @@ -374,6 +377,11 @@ static void _gameLoaded(struct mGUIRunner* runner) { } } } + + int fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { + interframeBlending = fakeBool; + } } static void _gameUnloaded(struct mGUIRunner* runner) { @@ -404,7 +412,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) { } } -static void _drawTex(struct mCore* core, bool faded) { +static void _drawTex(struct mCore* core, bool faded, bool both) { unsigned screen_w, screen_h; switch (screenMode) { case SM_PA_BOTTOM: @@ -466,7 +474,6 @@ static void _drawTex(struct mCore* core, bool faded) { break; } - ctrActivateTexture(&outputTexture); u32 color; if (!faded) { color = 0xFFFFFFFF; @@ -502,7 +509,12 @@ static void _drawTex(struct mCore* core, bool faded) { } } + ctrActivateTexture(&outputTexture[activeOutputTexture]); ctrAddRectEx(color, x, y, w, h, 0, 0, corew, coreh, 0); + if (both) { + ctrActivateTexture(&outputTexture[activeOutputTexture ^ 1]); + ctrAddRectEx(color & 0x7FFFFFFF, x, y, w, h, 0, 0, corew, coreh, 0); + } ctrFlushBatch(); corew = w; @@ -546,9 +558,14 @@ static void _drawTex(struct mCore* core, bool faded) { ctrFlushBatch(); } +static void _prepareForFrame(struct mGUIRunner* runner) { + UNUSED(runner); + activeOutputTexture ^= 1; +} + static void _drawFrame(struct mGUIRunner* runner, bool faded) { UNUSED(runner); - C3D_Tex* tex = &outputTexture; + C3D_Tex* tex = &outputTexture[activeOutputTexture]; GSPGPU_FlushDataCache(outputBuffer, 256 * GBA_VIDEO_VERTICAL_PIXELS * 2); C3D_SyncDisplayTransfer( @@ -563,11 +580,11 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { blip_clear(runner->core->getAudioChannel(runner->core, 1)); } - _drawTex(runner->core, faded); + _drawTex(runner->core, faded, interframeBlending); } static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { - C3D_Tex* tex = &outputTexture; + C3D_Tex* tex = &outputTexture[activeOutputTexture]; if (!screenshotBuffer) { screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); @@ -586,7 +603,7 @@ static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, un GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB565) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1)); - _drawTex(runner->core, faded); + _drawTex(runner->core, faded, false); } static uint16_t _pollGameInput(struct mGUIRunner* runner) { @@ -804,25 +821,29 @@ int main() { gfxInit(GSP_BGR8_OES, GSP_BGR8_OES, true); if (!_initGpu()) { - outputTexture.data = 0; + outputTexture[0].data = 0; _cleanup(); return 1; } - if (!C3D_TexInitVRAM(&outputTexture, 256, 256, GPU_RGB565)) { - _cleanup(); - return 1; - } - C3D_TexSetWrap(&outputTexture, GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE); - C3D_TexSetFilter(&outputTexture, GPU_NEAREST, GPU_NEAREST); C3D_TexSetFilter(&upscaleBufferTex, GPU_LINEAR, GPU_LINEAR); - void* outputTextureEnd = (u8*)outputTexture.data + 256 * 256 * 2; - // Zero texture data to make sure no garbage around the border interferes with filtering - GX_MemoryFill( - outputTexture.data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER, - NULL, 0, NULL, 0); - gspWaitForPSC0(); + int i; + for (i = 0; i < 2; ++i) { + if (!C3D_TexInitVRAM(&outputTexture[i], 256, 256, GPU_RGB565)) { + _cleanup(); + return 1; + } + C3D_TexSetWrap(&outputTexture[i], GPU_CLAMP_TO_EDGE, GPU_CLAMP_TO_EDGE); + C3D_TexSetFilter(&outputTexture[i], GPU_NEAREST, GPU_NEAREST); + void* outputTextureEnd = (u8*)outputTexture[i].data + 256 * 256 * 2; + + // Zero texture data to make sure no garbage around the border interferes with filtering + GX_MemoryFill( + outputTexture[i].data, 0x0000, outputTextureEnd, GX_FILL_16BIT_DEPTH | GX_FILL_TRIGGER, + NULL, 0, NULL, 0); + gspWaitForPSC0(); + } struct GUIFont* font = GUIFontCreate(); @@ -937,7 +958,7 @@ int main() { .teardown = 0, .gameLoaded = _gameLoaded, .gameUnloaded = _gameUnloaded, - .prepareForFrame = 0, + .prepareForFrame = _prepareForFrame, .drawFrame = _drawFrame, .drawScreenshot = _drawScreenshot, .paused = _gameUnloaded, From dd1514cb8aa41d0071c1f756c86a0acbbbfa3a0e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 29 May 2019 15:13:55 -0700 Subject: [PATCH 342/429] Ports: Interframe blending menu option --- src/feature/gui/gui-config.c | 10 ++++++++++ src/platform/psp2/psp2-context.c | 5 +++-- src/platform/switch/main.c | 5 +++-- src/platform/wii/main.c | 5 +++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index 7aa397833..484465b43 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -108,6 +108,16 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t .title = "Select SGB BIOS path", .data = "sgb.bios", }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Interframe blending", + .data = "interframeBlending", + .submenu = 0, + .state = false, + .validStates = (const char*[]) { + "Off", "On" + }, + .nStates = 2 + }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Enable SGB borders", .data = "sgb.borders", diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index b933dab4f..f33738e65 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -394,8 +394,9 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { } int fakeBool; - mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); - interframeBlending = fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { + interframeBlending = fakeBool; + } MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 33e2b9298..86d6abdfb 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -289,8 +289,9 @@ static void _gameLoaded(struct mGUIRunner* runner) { } int fakeBool; - mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); - interframeBlending = fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { + interframeBlending = fakeBool; + } rumble.up = 0; rumble.down = 0; diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 1c2ab5ada..eea6b17d6 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -859,8 +859,9 @@ void _unpaused(struct mGUIRunner* runner) { } } int fakeBool; - mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); - interframeBlending = fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { + interframeBlending = fakeBool; + } float stretch; if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) { From 9ce234daaca53093448c1b133c9e291385ee229e Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Thu, 30 May 2019 09:44:16 +0200 Subject: [PATCH 343/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 442 +++++++++++++++++----------------- 1 file changed, 226 insertions(+), 216 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index b4a54aa7a..28f090df8 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -1289,22 +1289,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -3381,12 +3381,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3395,428 +3395,433 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + Undo save state Speichern des Savestate rückgängig machen - - + + State &%1 Savestate &%1 - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + &Next frame &Nächstes Bild - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + Step backwards Schrittweiser Rücklauf - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Solar-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + + Interframe blending + Interframe-Überblendung + + + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Record GIF... GIF aufzeichen... - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + Game &Pak sensors... Game &Pak-Sensoren... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... @@ -3826,142 +3831,142 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + About... Über... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video aufzeichnen... - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Record debug video log... Video-Protokoll aufzeichnen... - + Stop debug video log Aufzeichnen des Video-Protokolls beenden - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links @@ -4274,7 +4279,7 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + frames Bild(er) @@ -4320,253 +4325,258 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Nativ (59.7275) - + + Interframe blending + Interframe-Überblendung + + + Language Sprache - + English Englisch - + List view Listenansicht - + Tree view Baumansicht - + Show FPS in title bar Bildwiederholrate in der Titelleiste anzeigen - + Automatically save cheats Cheats automatisch speichern - + Automatically load cheats Cheats automatisch laden - + Automatically save state Zustand (Savestate) automatisch speichern - + Automatically load state Zustand (Savestate) automatisch laden - + Enable Discord Rich Presence Discord-Integration aktivieren - + Video renderer: Video-Renderer: - + Software Software - + OpenGL OpenGL - + OpenGL enhancements OpenGL-Verbesserungen - + High-resolution scale: Hochauflösende Skalierung: - + XQ GBA audio (experimental) XQ GBA-Audio (experimentell) - + Cheats Cheats - + Log to file In Datei protokollieren - + Log to console Auf die Konsole protokollieren - + Select Log File Protokoll-Datei auswählen - + Camera: Kamera: - - - + + + Autodetect Automatisch erkennen - - - + + + Game Boy (DMG) Game Boy (DMG) - - - + + + Super Game Boy (SGB) Super Game Boy (SGB) - - - + + + Game Boy Color (CGB) Game Boy Color (CGB) - - - + + + Game Boy Advance (AGB) Game Boy Advance (AGB) - + Default BG colors: Standard-Hintergrundfarben: - + Default sprite colors 1: Standard-Sprite-Farben 1: - + Default sprite colors 2: Standard-Sprite-Farben 2: - + Use GBC colors in GB games Verwende GBC-Farben in GB-Spielen - + Super Game Boy borders Super Game Boy-Rahmen - + Game Boy model: Game Boy-Modell: - + Super Game Boy model: Super Game Boy-Modell: - + Game Boy Color model: Game Boy Color-Modell: - + Camera driver: Kamera-Treiber: - + Library: Bibliothek: - + Show when no game open Anzeigen, wenn kein Spiel geöffnet ist - + Clear cache Cache leeren - + Fast forward speed: Vorlauf-Geschwindigkeit: - + Preload entire ROM into memory ROM-Datei vollständig in Arbeitsspeicher vorladen - - - - - - - - - + + + + + + + + + Browse Durchsuchen - + Use BIOS file if found BIOS-Datei verwenden, wenn vorhanden - + Skip BIOS intro BIOS-Intro überspringen - - + + × × - + Unbounded unbegrenzt - + Suspend screensaver Bildschirmschoner deaktivieren @@ -4576,50 +4586,50 @@ wenn vorhanden BIOS - + Pause when inactive Pause, wenn inaktiv - + Run all Alle ausführen - + Remove known Bekannte entfernen - + Detect and remove Erkennen und entfernen - + Allow opposing input directions Gegensätzliche Eingaberichtungen erlauben - - + + Screenshot Screenshot - - + + Save data Speicherdaten - - + + Cheat codes Cheat-Codes - + Enable rewind Rücklauf aktivieren @@ -4629,76 +4639,76 @@ wenn vorhanden Bilineare Filterung - + Rewind history: Rücklauf-Verlauf: - + Idle loops: Leerlaufprozesse: - + Savestate extra data: Zusätzliche Savestate-Daten: - + Load extra data: Lade zusätzliche Daten: - + Autofire interval: Autofeuer-Intervall: - + GB BIOS file: Datei mit GB-BIOS: - + GBA BIOS file: Datei mit GBA-BIOS: - + GBC BIOS file: Datei mit GBC-BIOS: - + SGB BIOS file: Datei mit SGB-BIOS: - + Save games Spielstände - - - - - + + + + + Same directory as the ROM Verzeichnis der ROM-Datei - + Save states Savestates - + Screenshots Screenshots - + Patches Patches From 0cace151e1148cfd12d4175f816a044871d8e113 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 30 May 2019 11:59:07 -0700 Subject: [PATCH 344/429] GBA Video: Fix wrapped sprite mosaic clamping (fixes #1432) --- CHANGES | 1 + .../gba/obj/sma2-mosaic-clamp/baseline_0000.png | Bin 0 -> 5996 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0001.png | Bin 0 -> 5950 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0002.png | Bin 0 -> 6056 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0003.png | Bin 0 -> 6061 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0004.png | Bin 0 -> 5954 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0005.png | Bin 0 -> 6010 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0006.png | Bin 0 -> 6015 bytes .../gba/obj/sma2-mosaic-clamp/baseline_0007.png | Bin 0 -> 5987 bytes cinema/gba/obj/sma2-mosaic-clamp/test.mvl | Bin 0 -> 37919 bytes src/gba/renderers/video-software.c | 6 +++--- 11 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0000.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0001.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0002.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0003.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0004.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0005.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0006.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/baseline_0007.png create mode 100644 cinema/gba/obj/sma2-mosaic-clamp/test.mvl diff --git a/CHANGES b/CHANGES index be5d78206..84dbb27fa 100644 --- a/CHANGES +++ b/CHANGES @@ -18,6 +18,7 @@ Emulation fixes: - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) + - GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0000.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..d05b02e1689c81e153cfde56dc2beab12674eb92 GIT binary patch literal 5996 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 aP)mA|y4Dp*9dX4iGIi8}%O@U8 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 g)~om`Ud{Ob0|JX›SzyJUM07*qoM6N<$g7RX=z5oCK literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0002.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..92763de4a81591cf97032c56d590a25b383b6afa GIT binary patch literal 6056 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 literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0004.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0004.png new file mode 100644 index 0000000000000000000000000000000000000000..11cb7a1f44e5d845d47b293caf38510083014b4d GIT binary patch literal 5954 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 literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0005.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0005.png new file mode 100644 index 0000000000000000000000000000000000000000..0796c9e35bee034acab52075ef8530bd580b2ab1 GIT binary patch literal 6010 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 literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0006.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0006.png new file mode 100644 index 0000000000000000000000000000000000000000..8172f46705f9d734c6498423cc8b264406c231dd GIT binary patch literal 6015 zcmV-_7l7!AP)xyI@b*(FsI^q_$Nb10W%O`Fa zLjHedk_pXucvu*2l4R8Nh0_(ll+gTCw<++5oVrEw3*G{uLkl{kKYmJ+t=3YSq-V#cBnh zzP$kOmE%!6Ek$xF6Dr@@0QMi#-TD$hRaNrkv{VRSGXP?VLldkpzAUO`m4K=K3D>{Yi@_n*k7;o0?`1{zCtxp*2yt zSZpTPIZd?Aw?8r_6gnBFi_T_3-ggMj9!Ft`drye_{^Nn*F*ckPoZ(@Iskle^POG0wL zL{Mnr?WVT;;u*pE>fZHPvYAkF8pTm)KiBak%E*!7jM+>mIb9SF?dLkaL>V~}1hIMB znQS`~dG_PLXXA8^3cacLzKx;K_Gm{0^CcpBPhb>G$wglKflH)68w#(`j%XI-(CJP~ zp~?qwNX$hM!feN<66t(BG*e}VS|?O!x09wgK_cxYVghP%*@*+6S)_AU=uO4RW~5PQ zPbdA~j~}AtnIRS(MQby|=Mm|mXE~IArirk6(^j>*TVL|ktza(JCY=oS5DZo}O{l8x zT&hgxYa`&(+-sxb)(VbW4YY%vt@iui$b9ReseZ#vYfpuCxCwgw)ic^1#}`rP7{KY2n`Z{b z;{a+hdrG8Xzvipeijg}dvo+hVvsS4Db2_d}0?$~4=? zMPk=MR8B@jhh{VOB&M~U(1;+?0SXNlr}yoR&nPHx<xbph&XhXOL%#53kOaMJyxhflPloi{R?kwBq&@fZh%cCZ^6QRv#_19ECuDYSQcH*QMvLM<|aO;#S-76+S=K#jCc1 zV1&dCl>D>w`?TA+o4Ve@=7N><0)Loe*141j{ z{6soB+-wf0(smS4jh>H{-yF#uU7>@j?d*BzG_&6k2^zPmEGI8EhyqU*Vn(V9;ldcNDyeWG%NgQ?jNH$a|c^BaCM;c+Kf zI8vD*pq@J}r-dkVf?r`S^K*>ET-coZoMlRcUhS7)pXn1Leh8@NjwRLSHd9!ebTTs) z(z<6ts6xl(v^X{sg6p{>a$1y!7WALZg{+^%MhDDGBfjep&1ORIcP|R3rBG;Tf7}B) zCb>K#+8P59ca;sB5uu(tl+(q_a>xMr*^D>}9gNJ_3?B8|0u{Ot|LX}*l)sCMLTAZl zLTGP;MVgyJXOOw$=zT@o=-hL5;GxjjvzZV&iVfhjSPvaV%%nBY1V{IZBF~7a&_b7_ zNr1$e8Q~tfKnw^)vHq5n3Z0ic6GHp!C(>DDIf8j0c@m9vuUKqGv@1&T?O^}{zK6jZ zW|ZX!<+Oyfw)aXLo3%=X9^CgF_nJRD@|9;ove6+=g$^DUhH@g9*4!B%d@TE?aoHSw zMCe$LIo44^A<4QKiIHrMGt)fu{$rYw)}rA)df}V~Lt=%NL7ovUC+!yL9A*lmP$YX= zdmd3Jo86MkSESELp`&NeqbqdKHH9axBf_#^M3m5LTZmzz^Ll)FEJFsG5cjHV*^sQ~ z!TgMRO(EOeVzo+eXE%8k;Y}~e$qY0@^i>2x;iu4s&kFlwGbHgFh>%BTukDv?MN#OG z75p6@B|+C^@TpP!eX)=x%OL}j&D(SK(2Lb7*&KL|eByX$dHe>>&O=Acbwu~jL05gJ zcO4F7U_wNEe_|0@wBVFJr z+wJN_o@bG8CdIF=x+pV+eET1}9y&eV3R{IIA)5nGDztD9T|y8%>#7Unp*i+H#!Ml{ zKcI+nhmwy4-4)fvnknSf|Jc_QmSC8#rOwzC#Y6ici)uS~)vYE&u||i?J=;m_C~lGV zt`3DzXg9J@XwSOUPXeNHfhrA4g^r}q98r`~Y1tOsh=@|5LloMxZZ*9~7c_+@KT3tp zTA=~F?RHny>e~gHjT|x_3nP3~ceO+jQ>xvP3MD3Y}XX z`bw^R*O{R7&^dT$FdMzw(cjQ-)`yFY`x^kFs<65e(=kBzW&?!B4%zSN7N{)5L z@w#v*6*^}R%^Z>^n}wct#^!TE>7jG3hh_|R_Z|`MiJKT_$!3(*cA?dF?v%5L^^B3N zLZ2&}Q7ZH&ROmBiGfIVyQV*TMdd7&R(2`fW$$(O!BPq1#^^B2~LZ7!hqg3eJuUPR^ zX!|!(bO+81r9#W-q3z#DaMfu^yYmbbTEhOz zQpFq{AJd<(dRES0Q91DqYLQ1bSP&EbDJro*>6D#tvo-?UuO8Pg8wS> zmznbX)UNfSY$$r(+izWDUJ$L&a`wMy9(vGakI)^if2;Gs%+!94IxqOW$M5~9^D>;O zy~zy#qbu(Kp9{(?M;0q51;9_CjpZI)%Ov!M1L#}KY5+#}P4&_DUYG0NYOjBT1_1OX zH>1uAyo{>`YXHO7+u;HHP4!Wm_?9p9Cc{NSt5UA;FP^o9cfP+tK+zsBnJOUkS8=p$iqY^vlYuKI}q}&>Sv()Kq z6uRARdbSTIbNkzVr{!)8hG>P(A0{|LN z07k=?v-BGf?4kReR=eF~4}QHq;!Hd=a~-|e7&TQUJ$3y{Z4Bzom`_1;1wGH5A9B~Jw8!o(&JhT)6Av+k}7mhTg}D~Cm+{T zNBrI8$G5pRaVbf6!2A4#zQ^PF%MAEwkL*ou&NU$|Jj<~hU^$p?4FH4b#A@8OPN>Xm z#ufRGlI`upV75b`LbvOR1cYf7704z>-Psf5OEJxuzG)^;jSIs5>bF&~-CXv4CzoP$ox{TI^wpM;Nqb|M_XTxeF=a288}*|QwO#Rhh>VS4MaCz~z&SHZZV z>*}mC#=|`x?lHZ``1SZHfb+G{B0TilZbv^{ilU&VDvE-`ujsFOXHfGhV@xX2qQ?MP z5ZW=fLYzL@jDuj)<862y!sc2RwJxUj`t1S$273Vd?E=$#0H}2tr_T~1JhV4#QOc+YjGh-?~}N zUo<=%Nj#f9>IkpeD=37_6h5}~-WZ1;Opnodgn><-{kI_pg+9)HU+bgU3_zo!>b)0w zEFOcB&CP|0?HGeS277GBc&J!xrbb})+|>Ve@%cP7eVUvNjI!G`%@WYFPjEtchIoZm zM34Hfs#RLmjxr1un{^%6mNQeXZrB7NVK%yP>vX+p4HIk2pZ0>gBN|YYvAO7?;bb#Q zZY0QZJijg_xlWNGK;huUiQxXTEC-op`|w6lRBD`!AN1a}wLuCtC+Pp+I$jnw2Zgp; z11m)Xu)TN!06YOerk769ivB7^{iJB|qJO~+uJvH6N}P}^3sJr==cjtZT1mcv-? z=gk2*4aVu&=x8%M<=M4I06^nu^{2J^(}MByz-f?ppR3=1uq?sbZud64HqA9X+yO*o z#4Hxgtp5yI=b;-Hl{qkP4lsM5vO56AWDQuH)_X78u<3|dXRJ?v#*=n8r-C~MnjSw_ zHbZE&-TibnYU|yBmEYK|agb+@zEoiU0c7K$h3-EtN)H`^$2QI8f>NvZQ%=1;La2w% zLZMA_DEbilkMQ$e`PNpHzUZEahERojXio+@SOHmozQ#QEH7PmvADP`6ISS!QM1i-!2L)(&9Yy&9M89E)JaT&)1j_0aW()Irje}W=(lUgF=EQo73#Uz4^j09F5)w zT^cx8d^fX2x2J*VEW!Kr3xKt;Z?&zK#bgq+!D(hT^pB0({|j5ubG@p-tF+kO&Y95m z>qG5|>qli0*MF1C@16I5lgoPN9Y7Rm_uTw@=N-Ts3>FZu)m62sFLbzWVF*B6dwPgd z=(Vv|8`giH+Ni9JNYZ#L1(`MgD5u|H#s_xsPO|^ z=x%>(H$B_^;{DorL7YMpUi#ykVZ3T`#^z&-X)22H&vbf&(EdNRn>fe~fX8O@5%4^p z#AbIpH$r=^BCOrD0qk_FU8QxZj>@+-Tyrj!Z*A=kjMjdj%{}L9h}OIHrSCyI@2YG0 z1Uft7+Ic~!hj!SEi1O?SH>XLY1Nz@@*6oT5+Yf2<^PI(?kT@FfshgLo?YtmVp=td0(jT*yP_y*5+bPwmt)l(7-jb(I2eX+eE(Nc(wf!w3oaaol z9CD(fRrG~!KRd%!qpulSLvysJiRYE^5U0@ZuRq_0*H``5x8XHwym}4T!iHztx?#5D zshiVo9#gxg;(Gqj1)u+t&`@hCDFI=)YQT1mc*XO|cnDJHt7_FWCyLTB&B<&OlBaXP zCDOpMi3@9;HwULZJqCPyg(rf~zgR-=Kc-}qC4paO*r}wm1E8-3O*$rsryoQn)kvz= z;uKm@I_xKx ze*+20*bLYC7rwS#Regsv_0Xa6EDlVE=oYOwwI9(D(L;0Wc`Sr-+A$VnARfnMvm4w9 z?OvGB(X#)TMxk}|uvp#83(VvJP-|-X{ItvpO(0GmX?@@{^BXi4bf-1avl$s!4kpqB zH(%M?-TIP62GH8^QFH@cRo^p~XEp%mxKGIynm|hzO>$xhAGE=0((3UNUU|Mr8)i1c-fTm~2oey4sE-?ByJaqL_ah%AsaU++-@}w4K{{ z^qX~7X5^r?8zj;Z6&KOuxvIXi4%C%#W+L6!jJOGtC=gxC!554Vl&j9SGbKtC56boC zIy|aGiGtv)t|=^0;_G_WP<0QVx1L$PlYQ!LDdWp{+2X$%?O&Mw&;5bX{$*`C{U817 zXer~%cnRZ`>C<)l=PQ85=?Bv%%Ujc@?v^sXjF&K83D{9E%J?!~!g$4844)UyYn5)B z$BRAKr>wDzFXN?+SIk9F#ir8i2M3h#WxQ1JL1{as**8s7Y4!o&VvmcEg&NBEGCucs z+tfF0zpPLw0Mj%_E9(*(0OoFRvcEFEjF&IoSJoQyn<8M zLjm;EU!%2^F6n7to0aipyrl7tdjzsj0KM&KRO`|6vGKIjwu~?1rHWUE|4s<)8SU7n tj4$J*jdx}_dfSm_G;1&8%XpdN{|_q~OA^-RgSh|z002ovPDHLkV1hiT=4}7~ literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/baseline_0007.png b/cinema/gba/obj/sma2-mosaic-clamp/baseline_0007.png new file mode 100644 index 0000000000000000000000000000000000000000..3ccd126c3f591781080ee40cb5ddaabb8ff754f0 GIT binary patch literal 5987 zcmV-p7o6ycP)i}7Es{EL#N`tg zhBUvEWF|i}=iy<~;U*cfCx??eHxp&Lupt!PwgSMmM`AZC7S{WW7HZlX0O1FLAB&Co zqdT62HZ}Wqngs_RiXu>vc=lm+Liv z#_j^ZSFtanaE>6pai_MJFPBt@q+16Lv z`YQciyKSW`Y-S)@1K4jassH)*rw9mAX!LCO<9ISomrj^nV4TKLs&nj2?nt1}vJEu+ zTnDu~6`I(4Q0T;*E<2kE>bH)|e&pMq9Fe0!yHwfvC%^0X!j=+n`aIa|#b@Sp?jG6~ zK?)6z>-ggOj23t}eXeXKd|FQD>!E`Xq|o^2Iskm}@|_mKIenIFcA9B?R!+xN=nM=r zI24+AyREOj_(rh4`fmL!*-WT7T^5B7avfiIt{j~>V>S~$Ij76wp@Uq<7oICe21#t* zb*H=Tv^d*w;Zt!sM}^+1fq%wOXlJx5g832|y=Pz)Ovy!2+kr=!GQB!%J&lg?70KTIN#dcCAK)7O2pibPVEj%GEjH zQfR~!X~tt7YPy*1WK2qC>*@!BgmXGyg=TPZI-Wu!s+x(GbGc6P)#=Q%S^d`Wa+(K3 zMN`Yxr^+4qA)dU7-{@mWQV0K!uj-I?e{!OcUel zJ(yC8<#cfrdaHu5R)9j&wpa$b0s|WZ&ur2ouTnx9rwgLcTNMopjI{+-=p1tt!grnJ z6kfjE!jaQb_Z6wot0m=iY&o2zMP2WIPfmv?w0qsL(Dpqf+Q|MI@(v;gsaa;-n-qCkb*I z0NyRjS4{a8IK>XUo%%KBxafN@<6HYP%d2Iu@s;5;R$weF_9f1f@O~z>< zwSG<>r>y5r&uo5$J`g%+9U+8HEVr@lu#zF_1tc^=In9>SaN1m1X-f80YlR%CfbK&=J)G?qeV z!)9>Qb4PNzlv$1+P#8hahQ_>_r;>=7I9=a?H z;6aJLOG<^#OP&dleGU@ojItczJScb)jdia?YzE&QCHeL+1R>{P_=?$OIU+e-Kw3L{ zC5g?ts?tmNmgC;@=S05pOh|ThC|IF?{rMAeT^PxUa9RszeE7bcpT=b~=M|xo$HF;X zka;r_BiR_IV13qac0*9C>uM?7U@*ho2EM_y?T3>Mi<6(oUZF#99xA)GtXNNOjf+a51!p<_+IH>} z8)S(>$urI|%fVAEC?(4w<@=o@V$H`K7jd&3rMn_@o{ek_T>MBOI|JS=s|d5tWP_Ua zb~jrlSaEGx^b+2sN}dfA@%ey`nwd@num_;f9#RM zG&mYPHu3 zw3<0&JeFqkh27N(g_>}K6P1Uq>Y>jHCCWqlqGWk!FL=bV0zWE+&NB~vRjicPIiT{; z`FLnB8@=CCkDbfxjHK`I&}q>GMQtt2aCh5EQdI_G+5XOCUI2gkFi6XPt|j4BTuS#9S{IZK+)7#S+`xw09RLVrSqK4Uhc zQfQuf=xpXQ28Tiyywa@*s1%w@p);7z7+ERw8Ot*&h0gts6<>vRosqKpa89Tcx`-ay zbw-NX7pG&%APKFjD!qhnIU9v8TK_ABb|cG?6jyz@*o|kP&;{&&foeHqDD|3g?~CkrQUuM5 zEDEv}x|sbhlZQsn0H6CX%B%Z-74+NhFtJ|!0ia)eXJP%p&3N=I<@@A~Y!tfFY5BH~rVHnvgKpc~ z7>;vOX!MM}VT7|e2;~vbo$pirE zC%(2iZD$w-w7PA6PRmwkxmk|a{eIADI2GCzU~iWIY}>ZCOWU?>`=H8!ccwHkpKnNv z+c&?_?4j9f-~0xk-+l*x<|Bad==m)D1~SZY%x240ujgblfaR>`e7QcA*Z%@#IoNjq zV6LqGe1f{BC>oAz2B0X4ZEqAsv28o#CM#z)BN#bP1`;$cvM5MZXtEGeQEr8Heg^=3 zeLbJtfB3Afxq@#m-@h&ViAzbkBiP$Wa?b_I-B7Ny=Ip9#}19ltwS7{usJnZcfyNzvcfcNlCDNm1A`ZHYx z;)&*i?BVGVIJjr!>C&6O%Q#h+O?|nnT8`BatKnj20w7KU4jz-oV4U8yTfJVai^9^6 z6vCm>P`HP_s@1%W|24V*{@qTGobE1X zj;e(EA~B)k_P=q|ga%Ytp7$dz^ut{pnJRSiLLDu)aGDL&d`vrjf*N$mqWdnR;mIJ#qSE zGme5yuh-Fa1e@zU)O(oS89$Z)Fth*|KbDx?0YJUSIDM9o;h|smd!n_XD5z_SqTpx? z|7&!Ib;D)!UO~{6aj-l>=cXEI}=_ZaV zbxz1u=&U{TY4jTaKm~V3|D?*1oJP+ACcp$e3!Mj;6LcPqjWDL?%x1{*pp3G+4GnwI zdq8kPdB$0K=tC>38jXqF#UlXV5dfNxhZk!Bkax~bDugTCRjqb4cu^WH%9+yjx}s)-A5?>5Yz zM@}EAqAP{w-{9$ru+eg5pXj=9KDoc5r0TBS>P*tGSw{a|$T|<*yigawqBX?)p33e3 zn9~h#;Iz?y-bD>Z%)1j~3N#<}+XWTeG0^b%xw0A3YB^r_dpvZEz9%<#M5{9)QeJdm2l zz3)ti23SSpV6nj>_B|ywAmIHJgp!rf)F+>LJfWbgfcqPRmnhCz}Bn z{pb1k#_9{Ui?S8^te#W&86F`gDUW;KnfkUJxY@h*$dapf5Ry~hPxo&OPX zuNQ^Oz3@X`9`}C!!!;ltz-qn|;>1y=f>B_{> z;(P6f?DjN}=b>*#y*Ko5q<6J_amHfpDvKfLWC3GHO_U)%mi zQHVO*+oo4a85aR)1_0={oxk*vAFW+m@UE^Ihd+td+h*WeI35C3S816z$0+V>znd+6 z+k@gm+G8J3Kgd()jcIAk!~dYxR5xaf`^SjQ0BqaFQ%kAUUiW*~Jk!K!p8gM74O)vH z$J(eVuH#AE^=+4HIf!9IP~VTVkG13aZO3|_g{&36I{g{B(|@{ebO^M%wmDXr5evQT z51p28dr*8(yC_If=;5q;-&CBU@IO_(l2RPV#YO!raQU2O)ZxGr4hfWJe zxdHIdYCQnH$CKFXZ5Kvp-&ut9+YW%efsLoMPBWl>>%cSSqJHb>w_vmm0lUPH9r zZ!QCO+I`bJ(HnbBa4IewKcxJ}Ig5)z;%LaH zUS5W;!U>mt`^VI^HP-MPHR0`|Ak{;=YzB`!zwY-+t!AHydzuu_SEs|-%oO*~AARHe z6CB4m(=10Zq3Wu!G@M6gv~CV`Q*Y|7_B8RLG9FSDny&wz2dA1lUibgxnB37(3gzXr zm&erZtGK>Dbm7OpA~dwRMoK^!t($NhBT@09G9L02`t9ZC>*)Gw@bWskW{p=bA!{7q z5ouu6!o^{pHy5XUJq7}Ng)hR7zub|+qSYjkYxja3N;*0K271^iPvUrzYIf@Giy(w-f5(L?7te;+vG=`!3}pG@k!HBWZ%LlhcG z>!CwVF#b+n1?x14v@>(Z(m^M79@#ulKisqt4%hL|!g5&evq(TZu_lT5dd0;w3zpyykkGR{B zSIZ#;k>0~~EyzGTj>~2*gb~_1F`=u)dY|#onm;U7_woWWc>uJ!mOei%$wLbSar#8- zBd3|)pld;IS|dH1k-=TxOr!~3zOp~}n@biMLTlGY{06$Fy=5%V>;hciHVdxM1iF)4 zVfb#^f131j$C@p9gQyj7K{&+tIoGG6)Kbu%Jud-I;uj2lHjcFDXdW8>t^263?HAjnIC*7`_$V~#aHn~ zi~nkN{=@8F?+0e*zr(7tf9YRWOBG+m7cgF#JzjTyz5r-`{9yKY@YeLHx21}&;tLqB zgls4rReTj+z<9-8j-Hn8dzF5)PB(k7Pg!FXU&R+TUa^;f6`M+H5b|jiU&R+NJ}_;k zv<9|qE3M-^ix(Cy!s;HY_$s~#@s6QyT7RWdkZs%J_2K>*0QP?9-eeVD#TPIBLoJ6= zyQfe9<2C4={yePqQQ@ojD!yp(igN{LD1iQMJg)Z-%R1Ot;;Zz_tJY literal 0 HcmV?d00001 diff --git a/cinema/gba/obj/sma2-mosaic-clamp/test.mvl b/cinema/gba/obj/sma2-mosaic-clamp/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..9fece4fdb3267c352bcc7e0767841aaef1fe9a92 GIT binary patch literal 37919 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%0D3Q)vAOh3I)f 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 literal 0 HcmV?d00001 diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 4c83844ad..86c3bc409 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -808,12 +808,12 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { if ((y < sprite->y && (sprite->endY - 256 < 0 || y >= sprite->endY - 256)) || y >= sprite->endY) { continue; } - if (GBAObjAttributesAIsMosaic(sprite->obj.a)) { + if (GBAObjAttributesAIsMosaic(sprite->obj.a) && mosaicV > 1) { localY = mosaicY; - if (localY < sprite->y) { + if (localY < sprite->y && sprite->y < GBA_VIDEO_VERTICAL_PIXELS) { localY = sprite->y; } - if (localY >= sprite->endY) { + if (localY >= (sprite->endY & 0xFF)) { localY = sprite->endY - 1; } } From ba00cdfc024e495dc377f07d9ed6e5c57958de9c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 30 May 2019 12:26:49 -0700 Subject: [PATCH 345/429] GBA Memory: Fix STM to VRAM (fixes #1430) --- CHANGES | 1 + src/gba/memory.c | 52 ++++++++++++++++++++++++++++++------------------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 84dbb27fa..3366a9ea9 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Emulation fixes: - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432) + - GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gba/memory.c b/src/gba/memory.c index 3f037567c..62fa6fda9 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -396,9 +396,10 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) { value = 0; \ break; \ } \ - address &= 0x00017FFC; \ + LOAD_32(value, address & 0x00017FFC, gba->video.vram); \ + } else { \ + LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ } \ - LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ wait += waitstatesRegion[REGION_VRAM]; #define LOAD_OAM LOAD_32(value, address & (SIZE_OAM - 4), gba->video.oam.raw); @@ -530,9 +531,10 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { value = 0; break; } - address &= 0x00017FFE; + LOAD_16(value, address & 0x00017FFE, gba->video.vram); + } else { + LOAD_16(value, address & 0x0001FFFE, gba->video.vram); } - LOAD_16(value, address & 0x0001FFFE, gba->video.vram); break; case REGION_OAM: LOAD_16(value, address & (SIZE_OAM - 2), gba->video.oam.raw); @@ -645,9 +647,10 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { value = 0; break; } - address &= 0x00017FFF; + value = ((uint8_t*) gba->video.vram)[address & 0x00017FFF]; + } else { + value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; } - value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; break; case REGION_OAM: value = ((uint8_t*) gba->video.oam.raw)[address & (SIZE_OAM - 1)]; @@ -734,13 +737,19 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store32: 0x%08X", address); \ break; \ } \ - address &= 0x00017FFC; \ - } \ - LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram); \ - if (oldValue != value) { \ - STORE_32(value, address & 0x0001FFFC, gba->video.vram); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \ - gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \ + LOAD_32(oldValue, address & 0x00017FFC, gba->video.vram); \ + if (oldValue != value) { \ + STORE_32(value, address & 0x00017FFC, gba->video.vram); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC) + 2); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x00017FFC)); \ + } \ + } else { \ + LOAD_32(oldValue, address & 0x0001FFFC, gba->video.vram); \ + if (oldValue != value) { \ + STORE_32(value, address & 0x0001FFFC, gba->video.vram); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC) + 2); \ + gba->video.renderer->writeVRAM(gba->video.renderer, (address & 0x0001FFFC)); \ + } \ } \ wait += waitstatesRegion[REGION_VRAM]; @@ -855,12 +864,17 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle mLOG(GBA_MEM, GAME_ERROR, "Bad VRAM Store16: 0x%08X", address); break; } - address &= 0x00017FFE; - } - LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram); - if (value != oldValue) { - STORE_16(value, address & 0x0001FFFE, gba->video.vram); - gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); + LOAD_16(oldValue, address & 0x00017FFE, gba->video.vram); + if (value != oldValue) { + STORE_16(value, address & 0x00017FFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE); + } + } else { + LOAD_16(oldValue, address & 0x0001FFFE, gba->video.vram); + if (value != oldValue) { + STORE_16(value, address & 0x0001FFFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); + } } break; case REGION_OAM: From 06657d9fde5a2e579ef55b72cfa7ed8269135b83 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 30 May 2019 17:45:34 -0700 Subject: [PATCH 346/429] Qt: Add additional info to map view --- CHANGES | 2 +- src/platform/qt/AssetInfo.cpp | 40 ++++++++++ src/platform/qt/AssetInfo.h | 34 ++++++++ src/platform/qt/AssetTile.cpp | 22 +----- src/platform/qt/AssetTile.h | 7 +- src/platform/qt/AssetTile.ui | 12 ++- src/platform/qt/CMakeLists.txt | 1 + src/platform/qt/MapView.cpp | 64 ++++++++++++++- src/platform/qt/MapView.ui | 137 ++++++++++++++++++--------------- 9 files changed, 231 insertions(+), 88 deletions(-) create mode 100644 src/platform/qt/AssetInfo.cpp create mode 100644 src/platform/qt/AssetInfo.h diff --git a/CHANGES b/CHANGES index 3366a9ea9..b6a6143fe 100644 --- a/CHANGES +++ b/CHANGES @@ -7,7 +7,7 @@ Features: - GB: Expose platform information to CLI debugger - Support Discord Rich Presence - Debugger: Add tracing to file - - Map viewer supports bitmapped GBA modes + - Enhanced map viewer, supporting bitmapped GBA modes and more displayed info - OpenGL renderer with high-resolution upscaling support - Experimental high level "XQ" audio for most GBA games - Interframe blending for games that use flicker effects diff --git a/src/platform/qt/AssetInfo.cpp b/src/platform/qt/AssetInfo.cpp new file mode 100644 index 000000000..f70d8ea0d --- /dev/null +++ b/src/platform/qt/AssetInfo.cpp @@ -0,0 +1,40 @@ +/* Copyright (c) 2013-2019 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 "AssetInfo.h" + +#include +#include + +using namespace QGBA; + +AssetInfo::AssetInfo(QWidget* parent) + : QGroupBox(parent) +{ +} + +void AssetInfo::addCustomProperty(const QString& id, const QString& visibleName) { + QHBoxLayout* newLayout = new QHBoxLayout; + newLayout->addWidget(new QLabel(visibleName)); + QLabel* value = new QLabel; + value->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + value->setAlignment(Qt::AlignRight); + newLayout->addWidget(value); + m_customProperties[id] = value; + int index = customLocation(); + static_cast(layout())->insertLayout(index, newLayout); +} + +void AssetInfo::setCustomProperty(const QString& id, const QVariant& value) { + QLabel* label = m_customProperties[id]; + if (!label) { + return; + } + label->setText(value.toString()); +} + +int AssetInfo::customLocation(const QString&) { + return layout()->count(); +} \ No newline at end of file diff --git a/src/platform/qt/AssetInfo.h b/src/platform/qt/AssetInfo.h new file mode 100644 index 000000000..c30a4f4c5 --- /dev/null +++ b/src/platform/qt/AssetInfo.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include +#include +#include +#include + +namespace QGBA { + +class CoreController; + +class AssetInfo : public QGroupBox { +Q_OBJECT + +public: + AssetInfo(QWidget* parent = nullptr); + void addCustomProperty(const QString& id, const QString& visibleName); + +public slots: + void setCustomProperty(const QString& id, const QVariant& value); + +protected: + virtual int customLocation(const QString& id = {}); + +private: + QHash m_customProperties; +}; + +} diff --git a/src/platform/qt/AssetTile.cpp b/src/platform/qt/AssetTile.cpp index ad16d47a3..ea3bcb28c 100644 --- a/src/platform/qt/AssetTile.cpp +++ b/src/platform/qt/AssetTile.cpp @@ -22,7 +22,7 @@ using namespace QGBA; AssetTile::AssetTile(QWidget* parent) - : QGroupBox(parent) + : AssetInfo(parent) { m_ui.setupUi(this); @@ -42,16 +42,8 @@ AssetTile::AssetTile(QWidget* parent) m_ui.b->setFont(font); } -void AssetTile::addCustomProperty(const QString& id, const QString& visibleName) { - QHBoxLayout* newLayout = new QHBoxLayout; - newLayout->addWidget(new QLabel(visibleName)); - QLabel* value = new QLabel; - value->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - value->setAlignment(Qt::AlignRight); - newLayout->addWidget(value); - m_customProperties[id] = value; - int index = layout()->indexOf(m_ui.line); - static_cast(layout())->insertLayout(index, newLayout); +int AssetTile::customLocation(const QString&) { + return layout()->indexOf(m_ui.line); } void AssetTile::setController(std::shared_ptr controller) { @@ -149,11 +141,3 @@ void AssetTile::selectColor(int index) { m_ui.g->setText(tr("0x%0 (%1)").arg(g, 2, 16, QChar('0')).arg(g, 2, 10, QChar('0'))); m_ui.b->setText(tr("0x%0 (%1)").arg(b, 2, 16, QChar('0')).arg(b, 2, 10, QChar('0'))); } - -void AssetTile::setCustomProperty(const QString& id, const QVariant& value) { - QLabel* label = m_customProperties[id]; - if (!label) { - return; - } - label->setText(value.toString()); -} diff --git a/src/platform/qt/AssetTile.h b/src/platform/qt/AssetTile.h index 35dd14e5b..676582387 100644 --- a/src/platform/qt/AssetTile.h +++ b/src/platform/qt/AssetTile.h @@ -15,13 +15,12 @@ namespace QGBA { class CoreController; -class AssetTile : public QGroupBox { +class AssetTile : public AssetInfo { Q_OBJECT public: AssetTile(QWidget* parent = nullptr); void setController(std::shared_ptr); - void addCustomProperty(const QString& id, const QString& visibleName); public slots: void setPalette(int); @@ -29,7 +28,9 @@ public slots: void selectIndex(int); void setFlip(bool h, bool v); void selectColor(int); - void setCustomProperty(const QString& id, const QVariant& value); + +protected: + int customLocation(const QString& id = {}) override; private: Ui::AssetTile m_ui; diff --git a/src/platform/qt/AssetTile.ui b/src/platform/qt/AssetTile.ui index e5557506b..403e26d60 100644 --- a/src/platform/qt/AssetTile.ui +++ b/src/platform/qt/AssetTile.ui @@ -1,13 +1,13 @@ AssetTile - + 0 0 - 171 - 355 + 241 + 406 @@ -185,6 +185,12 @@ + + QGBA::AssetInfo + QGroupBox +

AssetInfo.h
+ 1 + QGBA::Swatch QWidget diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index e5ae84e58..0dbb75efa 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -59,6 +59,7 @@ set(SOURCE_FILES AbstractUpdater.cpp Action.cpp ActionMapper.cpp + AssetInfo.cpp AssetTile.cpp AssetView.cpp AudioProcessor.cpp diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index a0232c50b..91a283121 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -18,6 +18,7 @@ #include #endif #ifdef M_CORE_GB +#include #include #endif @@ -42,6 +43,12 @@ MapView::MapView(std::shared_ptr controller, QWidget* parent) m_boundary = 2048; m_addressBase = BASE_VRAM; m_addressWidth = 8; + m_ui.bgInfo->addCustomProperty("priority", tr("Priority")); + m_ui.bgInfo->addCustomProperty("screenBase", tr("Map base")); + m_ui.bgInfo->addCustomProperty("charBase", tr("Tile base")); + m_ui.bgInfo->addCustomProperty("size", tr("Size")); + m_ui.bgInfo->addCustomProperty("offset", tr("Offset")); + m_ui.bgInfo->addCustomProperty("transform", tr("Xform")); break; #endif #ifdef M_CORE_GB @@ -49,6 +56,9 @@ MapView::MapView(std::shared_ptr controller, QWidget* parent) m_boundary = 1024; m_addressBase = GB_BASE_VRAM; m_addressWidth = 4; + m_ui.bgInfo->addCustomProperty("screenBase", tr("Map base")); + m_ui.bgInfo->addCustomProperty("charBase", tr("Tile base")); + m_ui.bgInfo->addCustomProperty("offset", tr("Offset")); break; #endif default: @@ -143,16 +153,58 @@ void MapView::updateTilesGBA(bool force) { { CoreController::Interrupter interrupter(m_controller); int bitmap = -1; + int priority = -1; + int frame = 0; + QString offset(tr("N/A")); + QString transform(tr("N/A")); if (m_controller->platform() == PLATFORM_GBA) { - int mode = GBARegisterDISPCNTGetMode(static_cast(m_controller->thread()->core->board)->memory.io[REG_DISPCNT]); + uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); if (m_map == 2 && mode > 2) { bitmap = mode == 4 ? 1 : 0; + if (mode != 3) { + frame = GBARegisterDISPCNTGetFrameSelect(io[REG_DISPCNT >> 1]); + } } + priority = GBARegisterBGCNTGetPriority(io[(REG_BG0CNT >> 1) + m_map]); + if (mode == 0 || (mode == 1 && m_map != 2)) { + offset = QString("%1, %2") + .arg(io[(REG_BG0HOFS >> 1) + (m_map << 1)]) + .arg(io[(REG_BG0VOFS >> 1) + (m_map << 1)]); + } else if ((mode > 0 && m_map == 2) || (mode == 2 && m_map == 3)) { + int32_t refX = io[(REG_BG2X_LO >> 1) + ((m_map - 2) << 2)]; + refX |= io[(REG_BG2X_HI >> 1) + ((m_map - 2) << 2)] << 16; + int32_t refY = io[(REG_BG2Y_LO >> 1) + ((m_map - 2) << 2)]; + refY |= io[(REG_BG2Y_HI >> 1) + ((m_map - 2) << 2)] << 16; + refX <<= 4; + refY <<= 4; + refX >>= 4; + refY >>= 4; + offset = QString("%1\n%2").arg(refX / 65536., 0, 'f', 3).arg(refY / 65536., 0, 'f', 3); + transform = QString("%1 %2\n%3 %4") + .arg(io[(REG_BG2PA >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2) + .arg(io[(REG_BG2PB >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2) + .arg(io[(REG_BG2PC >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2) + .arg(io[(REG_BG2PD >> 1) + ((m_map - 2) << 2)] / 256., 3, 'f', 2); + + } + } + if (m_controller->platform() == PLATFORM_GB) { + uint8_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + int x = io[m_map == 0 ? 0x42 : 0x4A]; + int y = io[m_map == 0 ? 0x43 : 0x4B]; + offset = QString("%1, %2").arg(x).arg(y); } if (bitmap >= 0) { mBitmapCache* bitmapCache = mBitmapCacheSetGetPointer(&m_cacheSet->bitmaps, bitmap); int width = mBitmapCacheSystemInfoGetWidth(bitmapCache->sysConfig); int height = mBitmapCacheSystemInfoGetHeight(bitmapCache->sysConfig); + m_ui.bgInfo->setCustomProperty("screenBase", QString("0x%1").arg(m_addressBase + bitmapCache->bitsStart[frame], 8, 16, QChar('0'))); + m_ui.bgInfo->setCustomProperty("charBase", tr("N/A")); + m_ui.bgInfo->setCustomProperty("size", QString("%1×%2").arg(width).arg(height)); + m_ui.bgInfo->setCustomProperty("priority", priority); + m_ui.bgInfo->setCustomProperty("offset", offset); + m_ui.bgInfo->setCustomProperty("transform", transform); m_rawMap = QImage(QSize(width, height), QImage::Format_ARGB32); uchar* bgBits = m_rawMap.bits(); for (int j = 0; j < height; ++j) { @@ -163,6 +215,16 @@ void MapView::updateTilesGBA(bool force) { mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig); int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig); + m_ui.bgInfo->setCustomProperty("screenBase", QString("%0%1") + .arg(m_addressWidth == 8 ? "0x" : "") + .arg(m_addressBase + mapCache->mapStart, m_addressWidth, 16, QChar('0'))); + m_ui.bgInfo->setCustomProperty("charBase", QString("%0%1") + .arg(m_addressWidth == 8 ? "0x" : "") + .arg(m_addressBase + mapCache->tileCache->tileBase, m_addressWidth, 16, QChar('0'))); + m_ui.bgInfo->setCustomProperty("size", QString("%1×%2").arg(tilesW * 8).arg(tilesH * 8)); + m_ui.bgInfo->setCustomProperty("priority", priority); + m_ui.bgInfo->setCustomProperty("offset", offset); + m_ui.bgInfo->setCustomProperty("transform", transform); m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32); uchar* bgBits = m_rawMap.bits(); for (int j = 0; j < tilesH; ++j) { diff --git a/src/platform/qt/MapView.ui b/src/platform/qt/MapView.ui index d07a832b5..b9d5418f3 100644 --- a/src/platform/qt/MapView.ui +++ b/src/platform/qt/MapView.ui @@ -6,18 +6,80 @@ 0 0 - 641 - 489 + 1273 + 736 Maps - - - + + + - + + + + + + + + + + + + Export + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + × + + + 1 + + + 8 + + + + + + + Magnification + + + + + + + + true @@ -30,8 +92,8 @@ 0 0 - 457 - 463 + 835 + 720 @@ -71,62 +133,15 @@
- - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - - - - 0 - 0 - - - - × - - - 1 - - - 8 - - - - - - - Magnification - - - - - - - - - Export - - - + + QGBA::AssetInfo + QGroupBox +
AssetInfo.h
+ 1 +
QGBA::AssetTile QGroupBox From db2b56f418359e03f0505bac5e894cf821989cc3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 30 May 2019 20:56:19 -0700 Subject: [PATCH 347/429] Qt: Add getPixels call for a finished context --- src/platform/qt/CoreController.cpp | 20 ++++++++++++++++++++ src/platform/qt/CoreController.h | 1 + src/platform/qt/Window.cpp | 5 +---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 579f75d04..e1d4bc7ea 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -210,6 +210,26 @@ const color_t* CoreController::drawContext() { return reinterpret_cast(m_completeBuffer.constData()); } +QImage CoreController::getPixels() { + QByteArray buffer; + QSize size = screenDimensions(); + size_t stride = size.width() * BYTES_PER_PIXEL; + + if (!m_hwaccel) { + buffer = m_completeBuffer; + } else { + Interrupter interrupter(this); + const void* pixels; + m_threadContext.core->getPixels(m_threadContext.core, &pixels, &stride); + stride *= BYTES_PER_PIXEL; + buffer.resize(stride * size.height()); + memcpy(buffer.data(), pixels, buffer.size()); + } + + return QImage(reinterpret_cast(buffer.constData()), + size.width(), size.height(), stride, QImage::Format_RGBX8888); +} + bool CoreController::isPaused() { return mCoreThreadIsPaused(&m_threadContext); } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 978421249..ac1e327ba 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -67,6 +67,7 @@ public: mCoreThread* thread() { return &m_threadContext; } const color_t* drawContext(); + QImage getPixels(); bool isPaused(); bool hasStarted(); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 00a7f5b00..d87674d55 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1706,11 +1706,8 @@ void Window::focusCheck() { } void Window::updateFrame() { - QSize size = m_controller->screenDimensions(); - QImage currentImage(reinterpret_cast(m_controller->drawContext()), size.width(), size.height(), - size.width() * BYTES_PER_PIXEL, QImage::Format_RGBX8888); QPixmap pixmap; - pixmap.convertFromImage(currentImage); + pixmap.convertFromImage(m_controller->getPixels()); m_screenWidget->setPixmap(pixmap); emit paused(true); } From 86efc6cc9f138ef54e4478b76cc91c0bb173362d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 31 May 2019 15:32:22 -0700 Subject: [PATCH 348/429] Qt: Add frame inspector for GBA games --- CHANGES | 1 + src/platform/qt/AssetView.cpp | 175 ++++++++++++++++++- src/platform/qt/AssetView.h | 39 ++++- src/platform/qt/CMakeLists.txt | 2 + src/platform/qt/FrameView.cpp | 309 +++++++++++++++++++++++++++++++++ src/platform/qt/FrameView.h | 85 +++++++++ src/platform/qt/FrameView.ui | 156 +++++++++++++++++ src/platform/qt/MapView.cpp | 13 +- src/platform/qt/MapView.ui | 8 +- src/platform/qt/ObjView.cpp | 194 ++++++--------------- src/platform/qt/ObjView.h | 14 +- src/platform/qt/Window.cpp | 9 +- 12 files changed, 829 insertions(+), 176 deletions(-) create mode 100644 src/platform/qt/FrameView.cpp create mode 100644 src/platform/qt/FrameView.h create mode 100644 src/platform/qt/FrameView.ui diff --git a/CHANGES b/CHANGES index b6a6143fe..8b449be32 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,7 @@ Features: - OpenGL renderer with high-resolution upscaling support - Experimental high level "XQ" audio for most GBA games - Interframe blending for games that use flicker effects + - Frame inspector for dissecting and debugging rendering Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index 2f48cce32..eef257025 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016 Jeffrey Pfau +/* Copyright (c) 2013-2019 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 @@ -9,6 +9,16 @@ #include +#ifdef M_CORE_GBA +#include +#endif +#ifdef M_CORE_GB +#include +#include +#endif + +#include + using namespace QGBA; AssetView::AssetView(std::shared_ptr controller, QWidget* parent) @@ -98,3 +108,166 @@ void AssetView::compositeTile(const void* tBuffer, void* buffer, size_t stride, break; } } + +QImage AssetView::compositeMap(int map, mMapCacheEntry* mapStatus) { + mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, map); + int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig); + int tilesH = 1 << mMapCacheSystemInfoGetTilesHigh(mapCache->sysConfig); + QImage rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32); + uchar* bgBits = rawMap.bits(); + for (int j = 0; j < tilesH; ++j) { + for (int i = 0; i < tilesW; ++i) { + mMapCacheCleanTile(mapCache, mapStatus, i, j); + } + for (int i = 0; i < 8; ++i) { + memcpy(static_cast(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32); + } + } + return rawMap.rgbSwapped(); +} + +QImage AssetView::compositeObj(const ObjInfo& objInfo) { + mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, objInfo.paletteSet); + const color_t* rawPalette = mTileCacheGetPalette(tileCache, objInfo.paletteId); + unsigned colors = 1 << objInfo.bits; + QVector palette; + + palette.append(rawPalette[0] & 0xFFFFFF); + for (unsigned c = 1; c < colors && c < 256; ++c) { + palette.append(rawPalette[c] | 0xFF000000); + } + + QImage image = QImage(QSize(objInfo.width * 8, objInfo.height * 8), QImage::Format_Indexed8); + image.setColorTable(palette); + uchar* bits = image.bits(); + unsigned t = objInfo.tile; + for (int y = 0; y < objInfo.height; ++y) { + for (int x = 0; x < objInfo.width; ++x, ++t) { + compositeTile(static_cast(mTileCacheGetVRAM(tileCache, t)), bits, objInfo.width * 8, x * 8, y * 8, objInfo.bits); + } + t += objInfo.stride - objInfo.width; + } + return image.rgbSwapped(); +} + +bool AssetView::lookupObj(int id, struct ObjInfo* info) { + switch (m_controller->platform()) { +#ifdef M_CORE_GBA + case PLATFORM_GBA: + return lookupObjGBA(id, info); +#endif +#ifdef M_CORE_GB + case PLATFORM_GB: + return lookupObjGB(id, info); +#endif + default: + return false; + } +} + +#ifdef M_CORE_GBA +bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { + if (id > 127) { + return false; + } + + const GBA* gba = static_cast(m_controller->thread()->core->board); + const GBAObj* obj = &gba->video.oam.obj[id]; + + unsigned shape = GBAObjAttributesAGetShape(obj->a); + unsigned size = GBAObjAttributesBGetSize(obj->b); + unsigned width = GBAVideoObjSizes[shape * 4 + size][0]; + unsigned height = GBAVideoObjSizes[shape * 4 + size][1]; + unsigned tile = GBAObjAttributesCGetTile(obj->c); + unsigned palette = GBAObjAttributesCGetPalette(obj->c); + unsigned tileBase = tile; + unsigned paletteSet; + unsigned bits; + if (GBAObjAttributesAIs256Color(obj->a)) { + paletteSet = 3; + palette = 0; + tile /= 2; + bits = 8; + } else { + paletteSet = 2; + bits = 4; + } + ObjInfo newInfo{ + tile, + width / 8, + height / 8, + width / 8, + palette, + paletteSet, + bits, + !GBAObjAttributesAIsDisable(obj->a) || GBAObjAttributesAIsTransformed(obj->a), + GBAObjAttributesCGetPriority(obj->c), + GBAObjAttributesBGetX(obj->b), + GBAObjAttributesAGetY(obj->a), + GBAObjAttributesBIsHFlip(obj->b), + GBAObjAttributesBIsVFlip(obj->b), + }; + GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues + if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { + newInfo.stride = 0x20 >> (GBAObjAttributesAGet256Color(obj->a)); + }; + *info = newInfo; + return true; +} +#endif + +#ifdef M_CORE_GB +bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { + if (id > 39) { + return false; + } + + const GB* gb = static_cast(m_controller->thread()->core->board); + const GBObj* obj = &gb->video.oam.obj[id]; + + unsigned width = 8; + unsigned height = 8; + GBRegisterLCDC lcdc = gb->memory.io[REG_LCDC]; + if (GBRegisterLCDCIsObjSize(lcdc)) { + height = 16; + } + unsigned tile = obj->tile; + unsigned palette = 0; + if (gb->model >= GB_MODEL_CGB) { + if (GBObjAttributesIsBank(obj->attr)) { + tile += 512; + } + palette = GBObjAttributesGetCGBPalette(obj->attr); + } else { + palette = GBObjAttributesGetPalette(obj->attr); + } + palette += 8; + + ObjInfo newInfo{ + tile, + 1, + height / 8, + 1, + palette, + 0, + 2, + obj->y != 0 && obj->y < 160, + GBObjAttributesGetPriority(obj->attr), + obj->x, + obj->y, + GBObjAttributesIsXFlip(obj->attr), + GBObjAttributesIsYFlip(obj->attr), + }; + *info = newInfo; + return true; +} +#endif + +bool AssetView::ObjInfo::operator!=(const ObjInfo& other) const { + return other.tile != tile || + other.width != width || + other.height != height || + other.stride != stride || + other.paletteId != paletteId || + other.paletteSet != paletteSet; +} \ No newline at end of file diff --git a/src/platform/qt/AssetView.h b/src/platform/qt/AssetView.h index a95483c5e..779e22890 100644 --- a/src/platform/qt/AssetView.h +++ b/src/platform/qt/AssetView.h @@ -12,6 +12,8 @@ #include +struct mMapCacheEntry; + namespace QGBA { class CoreController; @@ -22,8 +24,6 @@ Q_OBJECT public: AssetView(std::shared_ptr controller, QWidget* parent = nullptr); - static void compositeTile(const void* tile, void* image, size_t stride, size_t x, size_t y, int depth = 8); - protected slots: void updateTiles(); void updateTiles(bool force); @@ -40,9 +40,42 @@ protected: void showEvent(QShowEvent*) override; mCacheSet* const m_cacheSet; + std::shared_ptr m_controller; + +protected: + struct ObjInfo { + unsigned tile; + unsigned width; + unsigned height; + unsigned stride; + unsigned paletteId; + unsigned paletteSet; + unsigned bits; + + bool enabled : 1; + unsigned priority : 2; + unsigned x : 9; + unsigned y : 9; + bool hflip : 1; + bool vflip : 1; + + bool operator!=(const ObjInfo&) const; + }; + + static void compositeTile(const void* tile, void* image, size_t stride, size_t x, size_t y, int depth = 8); + QImage compositeMap(int map, mMapCacheEntry*); + QImage compositeObj(const ObjInfo&); + + bool lookupObj(int id, struct ObjInfo*); private: - std::shared_ptr m_controller; +#ifdef M_CORE_GBA + bool lookupObjGBA(int id, struct ObjInfo*); +#endif +#ifdef M_CORE_GB + bool lookupObjGB(int id, struct ObjInfo*); +#endif + QTimer m_updateTimer; }; diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 0dbb75efa..49be1cda7 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -72,6 +72,7 @@ set(SOURCE_FILES Display.cpp DisplayGL.cpp DisplayQt.cpp + FrameView.cpp GBAApp.cpp GBAKeyEditor.cpp GIFView.cpp @@ -122,6 +123,7 @@ set(UI_FILES BattleChipView.ui CheatsView.ui DebuggerConsole.ui + FrameView.ui GIFView.ui IOViewer.ui LoadSaveState.ui diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp new file mode 100644 index 000000000..121bd9171 --- /dev/null +++ b/src/platform/qt/FrameView.cpp @@ -0,0 +1,309 @@ +/* Copyright (c) 2013-2019 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 "FrameView.h" + +#include +#include +#include + +#include + +#include "CoreController.h" + +#ifdef M_CORE_GBA +#include +#include +#include +#include +#endif +#ifdef M_CORE_GB +#include +#include +#endif + +using namespace QGBA; + +FrameView::FrameView(std::shared_ptr controller, QWidget* parent) + : AssetView(controller, parent) +{ + m_ui.setupUi(this); + + m_glowTimer.setInterval(33); + connect(&m_glowTimer, &QTimer::timeout, this, [this]() { + ++m_glowFrame; + invalidateQueue(); + }); + m_glowTimer.start(); + + m_ui.compositedView->installEventFilter(this); + + connect(m_ui.queue, &QListWidget::itemChanged, this, [this](QListWidgetItem* item) { + Layer& layer = m_queue[item->data(Qt::UserRole).toInt()]; + layer.enabled = item->checkState() == Qt::Checked; + if (layer.enabled) { + m_disabled.remove(layer.id); + } else { + m_disabled.insert(layer.id); + } + invalidateQueue(); + }); + connect(m_ui.queue, &QListWidget::currentItemChanged, this, [this](QListWidgetItem* item) { + if (item) { + m_active = m_queue[item->data(Qt::UserRole).toInt()].id; + } else { + m_active = {}; + } + invalidateQueue(); + }); +} + +void FrameView::selectLayer(const QPointF& coord) { + for (const Layer& layer : m_queue) { + QPointF location = layer.location; + QSizeF layerDims(layer.image.width(), layer.image.height()); + QRegion region; + if (layer.repeats) { + if (location.x() + layerDims.width() < 0) { + location.setX(std::fmod(location.x(), layerDims.width())); + } + if (location.y() + layerDims.height() < 0) { + location.setY(std::fmod(location.y(), layerDims.height())); + } + + region += layer.mask.translated(location.x(), location.y()); + region += layer.mask.translated(location.x() + layerDims.width(), location.y()); + region += layer.mask.translated(location.x(), location.y() + layerDims.height()); + region += layer.mask.translated(location.x() + layerDims.width(), location.y() + layerDims.height()); + } else { + region = layer.mask.translated(location.x(), location.y()); + } + + if (region.contains(QPoint(coord.x(), coord.y()))) { + m_active = layer.id; + m_glowFrame = 0; + break; + } + } +} + +void FrameView::updateTilesGBA(bool force) { + if (m_ui.freeze->checkState() == Qt::Checked) { + return; + } + m_queue.clear(); + { + CoreController::Interrupter interrupter(m_controller); + updateRendered(); + + uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); + + std::array enabled{ + GBARegisterDISPCNTIsBg0Enable(io[REG_DISPCNT >> 1]), + GBARegisterDISPCNTIsBg1Enable(io[REG_DISPCNT >> 1]), + GBARegisterDISPCNTIsBg2Enable(io[REG_DISPCNT >> 1]), + GBARegisterDISPCNTIsBg3Enable(io[REG_DISPCNT >> 1]), + }; + + for (int priority = 0; priority < 4; ++priority) { + for (int sprite = 0; sprite < 128; ++sprite) { + ObjInfo info; + lookupObj(sprite, &info); + + if (!info.enabled || info.priority != priority) { + continue; + } + + QPointF offset(info.x, info.y); + QImage obj(compositeObj(info)); + if (info.hflip || info.vflip) { + obj = obj.mirrored(info.hflip, info.vflip); + } + m_queue.append({ + { LayerId::SPRITE, sprite }, + !m_disabled.contains({ LayerId::SPRITE, sprite}), + QPixmap::fromImage(obj), + {}, offset, false + }); + if (m_queue.back().image.hasAlpha()) { + m_queue.back().mask = QRegion(m_queue.back().image.mask()); + } else { + m_queue.back().mask = QRegion(0, 0, m_queue.back().image.width(), m_queue.back().image.height()); + } + } + + for (int bg = 0; bg < 4; ++bg) { + if (!enabled[bg]) { + continue; + } + if (GBARegisterBGCNTGetPriority(io[(REG_BG0CNT >> 1) + bg]) != priority) { + continue; + } + + QPointF offset; + if (mode == 0) { + offset.setX(-(io[(REG_BG0HOFS >> 1) + (bg << 1)] & 0x1FF)); + offset.setY(-(io[(REG_BG0VOFS >> 1) + (bg << 1)] & 0x1FF)); + }; + m_queue.append({ + { LayerId::BACKGROUND, bg }, + !m_disabled.contains({ LayerId::BACKGROUND, bg}), + QPixmap::fromImage(compositeMap(bg, m_mapStatus[bg])), + {}, offset, true + }); + if (m_queue.back().image.hasAlpha()) { + m_queue.back().mask = QRegion(m_queue.back().image.mask()); + } else { + m_queue.back().mask = QRegion(0, 0, m_queue.back().image.width(), m_queue.back().image.height()); + } + } + } + } + invalidateQueue(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS)); +} + +void FrameView::updateTilesGB(bool force) { + if (m_ui.freeze->checkState() == Qt::Checked) { + return; + } + m_queue.clear(); + { + CoreController::Interrupter interrupter(m_controller); + updateRendered(); + } + invalidateQueue(m_controller->screenDimensions()); +} + +void FrameView::invalidateQueue(const QSize& dims) { + QSize realDims = dims; + if (!dims.isValid()) { + realDims = m_composited.size() / m_ui.magnification->value(); + } + bool blockSignals = m_ui.queue->blockSignals(true); + QPixmap composited(realDims); + + QPainter painter(&composited); + QPalette palette; + QColor activeColor = palette.color(QPalette::HighlightedText); + activeColor.setAlpha(sin(m_glowFrame * M_PI / 60) * 16 + 96); + + QRectF rect(0, 0, realDims.width(), realDims.height()); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(rect, QColor(0, 0, 0, 0)); + + painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); + for (int i = 0; i < m_queue.count(); ++i) { + const Layer& layer = m_queue[i]; + QListWidgetItem* item; + if (i >= m_ui.queue->count()) { + item = new QListWidgetItem; + m_ui.queue->addItem(item); + } else { + item = m_ui.queue->item(i); + } + item->setText(layer.id.readable()); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + item->setCheckState(layer.enabled ? Qt::Checked : Qt::Unchecked); + item->setData(Qt::UserRole, i); + item->setSelected(layer.id == m_active); + + if (!layer.enabled) { + continue; + } + + QPointF location = layer.location; + QSizeF layerDims(layer.image.width(), layer.image.height()); + QRegion region; + if (layer.repeats) { + if (location.x() + layerDims.width() < 0) { + location.setX(std::fmod(location.x(), layerDims.width())); + } + if (location.y() + layerDims.height() < 0) { + location.setY(std::fmod(location.y(), layerDims.height())); + } + + if (layer.id == m_active) { + region = layer.mask.translated(location.x(), location.y()); + region += layer.mask.translated(location.x() + layerDims.width(), location.y()); + region += layer.mask.translated(location.x(), location.y() + layerDims.height()); + region += layer.mask.translated(location.x() + layerDims.width(), location.y() + layerDims.height()); + } + } else { + QRectF layerRect(location, layerDims); + if (!rect.intersects(layerRect)) { + continue; + } + if (layer.id == m_active) { + region = layer.mask.translated(location.x(), location.y()); + } + } + + if (layer.id == m_active) { + painter.setClipping(true); + painter.setClipRegion(region); + painter.fillRect(rect, activeColor); + painter.setClipping(false); + } + + if (layer.repeats) { + painter.drawPixmap(location, layer.image); + painter.drawPixmap(location + QPointF(layerDims.width(), 0), layer.image); + painter.drawPixmap(location + QPointF(0, layerDims.height()), layer.image); + painter.drawPixmap(location + QPointF(layerDims.width(), layerDims.height()), layer.image); + } else { + painter.drawPixmap(location, layer.image); + } + } + painter.end(); + + while (m_ui.queue->count() > m_queue.count()) { + delete m_ui.queue->takeItem(m_queue.count()); + } + m_ui.queue->blockSignals(blockSignals); + + m_composited = composited.scaled(realDims * m_ui.magnification->value()); + m_ui.compositedView->setPixmap(m_composited); +} + +void FrameView::updateRendered() { + if (m_ui.freeze->checkState() == Qt::Checked) { + return; + } + m_rendered.convertFromImage(m_controller->getPixels()); + m_rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); + m_ui.renderedView->setPixmap(m_rendered); +} + +bool FrameView::eventFilter(QObject* obj, QEvent* event) { + if (event->type() != QEvent::MouseButtonPress) { + return false; + } + QPointF pos = static_cast(event)->localPos(); + pos /= m_ui.magnification->value(); + selectLayer(pos); + return true; +} + +QString FrameView::LayerId::readable() const { + QString typeStr; + switch (type) { + case NONE: + return tr("None"); + case BACKGROUND: + typeStr = tr("Background"); + break; + case WINDOW: + typeStr = tr("Window"); + break; + case SPRITE: + typeStr = tr("Sprite"); + break; + } + if (index < 0) { + return typeStr; + } + return tr("%1 %2").arg(typeStr).arg(index); +} \ No newline at end of file diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h new file mode 100644 index 000000000..626dfbd62 --- /dev/null +++ b/src/platform/qt/FrameView.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2013-2019 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/. */ +#pragma once + +#include "ui_FrameView.h" + +#include +#include +#include +#include +#include +#include + +#include "AssetView.h" + +#include + +namespace QGBA { + +class CoreController; + +class FrameView : public AssetView { +Q_OBJECT + +public: + FrameView(std::shared_ptr controller, QWidget* parent = nullptr); + +public slots: + void selectLayer(const QPointF& coord); + +protected: +#ifdef M_CORE_GBA + void updateTilesGBA(bool force) override; +#endif +#ifdef M_CORE_GB + void updateTilesGB(bool force) override; +#endif + + bool eventFilter(QObject* obj, QEvent* event) override; + +private: + struct LayerId { + enum { + NONE = 0, + BACKGROUND, + WINDOW, + SPRITE + } type = NONE; + int index = -1; + + bool operator==(const LayerId& other) const { return other.type == type && other.index == index; } + operator uint() const { return (type << 8) | index; } + QString readable() const; + }; + + struct Layer { + LayerId id; + bool enabled; + QPixmap image; + QRegion mask; + QPointF location; + bool repeats; + }; + + void invalidateQueue(const QSize& dims = QSize()); + void updateRendered(); + + Ui::FrameView m_ui; + + LayerId m_active{}; + + int m_glowFrame; + QTimer m_glowTimer; + + QList m_queue; + QSet m_disabled; + QPixmap m_composited; + QPixmap m_rendered; + mMapCacheEntry m_mapStatus[4][128 * 128] = {}; // TODO: Correct size +}; + +} \ No newline at end of file diff --git a/src/platform/qt/FrameView.ui b/src/platform/qt/FrameView.ui new file mode 100644 index 000000000..2e61e09c8 --- /dev/null +++ b/src/platform/qt/FrameView.ui @@ -0,0 +1,156 @@ + + + FrameView + + + + 0 + 0 + 869 + 875 + + + + Inspect frame + + + + + + + + + 0 + 0 + + + + × + + + 1 + + + 8 + + + + + + + Magnification + + + + + + + + + Freeze frame + + + + + + + true + + + + + 0 + 0 + 591 + 403 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + true + + + + + 0 + 0 + 591 + 446 + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + false + + + Export + + + + + + + + 0 + 0 + + + + + + + + + diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index 91a283121..0fe80c2c3 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -211,6 +211,7 @@ void MapView::updateTilesGBA(bool force) { mBitmapCacheCleanRow(bitmapCache, m_bitmapStatus, j); memcpy(static_cast(&bgBits[width * j * 4]), mBitmapCacheGetRow(bitmapCache, j), width * 4); } + m_rawMap = m_rawMap.rgbSwapped(); } else { mMapCache* mapCache = mMapCacheSetGetPointer(&m_cacheSet->maps, m_map); int tilesW = 1 << mMapCacheSystemInfoGetTilesWide(mapCache->sysConfig); @@ -225,19 +226,9 @@ void MapView::updateTilesGBA(bool force) { m_ui.bgInfo->setCustomProperty("priority", priority); m_ui.bgInfo->setCustomProperty("offset", offset); m_ui.bgInfo->setCustomProperty("transform", transform); - m_rawMap = QImage(QSize(tilesW * 8, tilesH * 8), QImage::Format_ARGB32); - uchar* bgBits = m_rawMap.bits(); - for (int j = 0; j < tilesH; ++j) { - for (int i = 0; i < tilesW; ++i) { - mMapCacheCleanTile(mapCache, m_mapStatus, i, j); - } - for (int i = 0; i < 8; ++i) { - memcpy(static_cast(&bgBits[tilesW * 32 * (i + j * 8)]), mMapCacheGetRow(mapCache, i + j * 8), tilesW * 32); - } - } + m_rawMap = compositeMap(m_map, m_mapStatus); } } - m_rawMap = m_rawMap.rgbSwapped(); QPixmap map = QPixmap::fromImage(m_rawMap.convertToFormat(QImage::Format_RGB32)); if (m_ui.magnification->value() > 1) { map = map.scaled(map.size() * m_ui.magnification->value()); diff --git a/src/platform/qt/MapView.ui b/src/platform/qt/MapView.ui index b9d5418f3..d21cce841 100644 --- a/src/platform/qt/MapView.ui +++ b/src/platform/qt/MapView.ui @@ -6,8 +6,8 @@ 0 0 - 1273 - 736 + 941 + 617 @@ -92,8 +92,8 @@ 0 0 - 835 - 720 + 613 + 601 diff --git a/src/platform/qt/ObjView.cpp b/src/platform/qt/ObjView.cpp index 64b689640..e482f023b 100644 --- a/src/platform/qt/ObjView.cpp +++ b/src/platform/qt/ObjView.cpp @@ -19,9 +19,7 @@ #endif #ifdef M_CORE_GB #include -#include #endif -#include #include using namespace QGBA; @@ -53,11 +51,7 @@ ObjView::ObjView(std::shared_ptr controller, QWidget* parent) connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), [this]() { updateTiles(true); }); -#ifdef USE_PNG connect(m_ui.exportButton, &QAbstractButton::clicked, this, &ObjView::exportObj); -#else - m_ui.exportButton->setVisible(false); -#endif } void ObjView::selectObj(int obj) { @@ -77,79 +71,56 @@ void ObjView::updateTilesGBA(bool force) { const GBA* gba = static_cast(m_controller->thread()->core->board); const GBAObj* obj = &gba->video.oam.obj[m_objId]; - unsigned shape = GBAObjAttributesAGetShape(obj->a); - unsigned size = GBAObjAttributesBGetSize(obj->b); - unsigned width = GBAVideoObjSizes[shape * 4 + size][0]; - unsigned height = GBAVideoObjSizes[shape * 4 + size][1]; - unsigned tile = GBAObjAttributesCGetTile(obj->c); - m_ui.tiles->setTileCount(width * height / 64); - m_ui.tiles->setMinimumSize(QSize(width, height) * m_ui.magnification->value()); - m_ui.tiles->resize(QSize(width, height) * m_ui.magnification->value()); - unsigned palette = GBAObjAttributesCGetPalette(obj->c); - unsigned tileBase = tile; - unsigned paletteSet; - unsigned bits; + ObjInfo newInfo; + lookupObj(m_objId, &newInfo); + + m_ui.tiles->setTileCount(newInfo.width * newInfo.height); + m_ui.tiles->setMinimumSize(QSize(newInfo.width * 8, newInfo.height * 8) * m_ui.magnification->value()); + m_ui.tiles->resize(QSize(newInfo.width * 8, newInfo.height * 8) * m_ui.magnification->value()); + unsigned tileBase = newInfo.tile; + unsigned tile = newInfo.tile; if (GBAObjAttributesAIs256Color(obj->a)) { m_ui.palette->setText("256-color"); - paletteSet = 3; m_ui.tile->setBoundary(1024, 1, 3); m_ui.tile->setPalette(0); m_boundary = 1024; - palette = 0; - tile /= 2; - bits = 8; + tileBase *= 2; } else { - m_ui.palette->setText(QString::number(palette)); - paletteSet = 2; + m_ui.palette->setText(QString::number(newInfo.paletteId)); m_ui.tile->setBoundary(2048, 0, 2); - m_ui.tile->setPalette(palette); - m_boundary = 2048; - bits = 4; + m_ui.tile->setPalette(newInfo.paletteId); } - ObjInfo newInfo{ - tile, - width / 8, - height / 8, - width / 8, - palette, - paletteSet, - bits - }; if (newInfo != m_objInfo) { force = true; } - GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues - if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { - newInfo.stride = 0x20 >> (GBAObjAttributesAGet256Color(obj->a)); - }; m_objInfo = newInfo; - m_tileOffset = tile; - mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, paletteSet); + m_tileOffset = newInfo.tile; + mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, newInfo.paletteSet); int i = 0; - for (int y = 0; y < height / 8; ++y) { - for (int x = 0; x < width / 8; ++x, ++i, ++tile, ++tileBase) { - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, palette); + for (int y = 0; y < newInfo.height; ++y) { + for (int x = 0; x < newInfo.width; ++x, ++i, ++tile, ++tileBase) { + const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { - m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, tile, palette)); + m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, tile, newInfo.paletteId)); } } - tile += newInfo.stride - width / 8; - tileBase += newInfo.stride - width / 8; + tile += newInfo.stride - newInfo.width; + tileBase += newInfo.stride - newInfo.width; } - m_ui.x->setText(QString::number(GBAObjAttributesBGetX(obj->b))); - m_ui.y->setText(QString::number(GBAObjAttributesAGetY(obj->a))); - m_ui.w->setText(QString::number(width)); - m_ui.h->setText(QString::number(height)); + m_ui.x->setText(QString::number(newInfo.x)); + m_ui.y->setText(QString::number(newInfo.y)); + m_ui.w->setText(QString::number(newInfo.width * 8)); + m_ui.h->setText(QString::number(newInfo.height * 8)); m_ui.address->setText(tr("0x%0").arg(BASE_OAM + m_objId * sizeof(*obj), 8, 16, QChar('0'))); - m_ui.priority->setText(QString::number(GBAObjAttributesCGetPriority(obj->c))); - m_ui.flippedH->setChecked(GBAObjAttributesBIsHFlip(obj->b)); - m_ui.flippedV->setChecked(GBAObjAttributesBIsVFlip(obj->b)); - m_ui.enabled->setChecked(!GBAObjAttributesAIsDisable(obj->a) || GBAObjAttributesAIsTransformed(obj->a)); + m_ui.priority->setText(QString::number(newInfo.priority)); + m_ui.flippedH->setChecked(newInfo.hflip); + m_ui.flippedV->setChecked(newInfo.vflip); + m_ui.enabled->setChecked(newInfo.enabled); m_ui.doubleSize->setChecked(GBAObjAttributesAIsDoubleSize(obj->a) && GBAObjAttributesAIsTransformed(obj->a)); m_ui.mosaic->setChecked(GBAObjAttributesAIsMosaic(obj->a)); @@ -182,39 +153,17 @@ void ObjView::updateTilesGB(bool force) { const GB* gb = static_cast(m_controller->thread()->core->board); const GBObj* obj = &gb->video.oam.obj[m_objId]; - mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); - unsigned width = 8; - unsigned height = 8; - GBRegisterLCDC lcdc = gb->memory.io[REG_LCDC]; - if (GBRegisterLCDCIsObjSize(lcdc)) { - height = 16; - } - unsigned tile = obj->tile; - m_ui.tiles->setTileCount(width * height / 64); - m_ui.tile->setBoundary(1024, 0, 0); - m_ui.tiles->setMinimumSize(QSize(width, height) * m_ui.magnification->value()); - m_ui.tiles->resize(QSize(width, height) * m_ui.magnification->value()); - unsigned palette = 0; - if (gb->model >= GB_MODEL_CGB) { - if (GBObjAttributesIsBank(obj->attr)) { - tile += 512; - } - palette = GBObjAttributesGetCGBPalette(obj->attr); - } else { - palette = GBObjAttributesGetPalette(obj->attr); - } - m_ui.palette->setText(QString::number(palette)); - palette += 8; + ObjInfo newInfo; + lookupObj(m_objId, &newInfo); + + mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); + unsigned tile = newInfo.tile; + m_ui.tiles->setTileCount(newInfo.height); + m_ui.tile->setBoundary(1024, 0, 0); + m_ui.tiles->setMinimumSize(QSize(8, newInfo.height * 8) * m_ui.magnification->value()); + m_ui.tiles->resize(QSize(8, newInfo.height * 8) * m_ui.magnification->value()); + m_ui.palette->setText(QString::number(newInfo.paletteId - 8)); - ObjInfo newInfo{ - tile, - 1, - height / 8, - 1, - palette, - 0, - 2 - }; if (newInfo != m_objInfo) { force = true; } @@ -223,27 +172,27 @@ void ObjView::updateTilesGB(bool force) { m_boundary = 1024; int i = 0; - m_ui.tile->setPalette(palette); - for (int y = 0; y < height / 8; ++y, ++i) { + m_ui.tile->setPalette(newInfo.paletteId); + for (int y = 0; y < newInfo.height; ++y, ++i) { unsigned t = tile + i; - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, palette); + const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { - m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, t, palette)); + m_ui.tiles->setTile(i, mTileCacheGetTile(tileCache, t, newInfo.paletteId)); } } - m_ui.x->setText(QString::number(obj->x)); - m_ui.y->setText(QString::number(obj->y)); - m_ui.w->setText(QString::number(width)); - m_ui.h->setText(QString::number(height)); + m_ui.x->setText(QString::number(newInfo.x)); + m_ui.y->setText(QString::number(newInfo.y)); + m_ui.w->setText(QString::number(8)); + m_ui.h->setText(QString::number(newInfo.height * 8)); m_ui.address->setText(tr("0x%0").arg(GB_BASE_OAM + m_objId * sizeof(*obj), 4, 16, QChar('0'))); - m_ui.priority->setText(QString::number(GBObjAttributesGetPriority(obj->attr))); - m_ui.flippedH->setChecked(GBObjAttributesIsXFlip(obj->attr)); - m_ui.flippedV->setChecked(GBObjAttributesIsYFlip(obj->attr)); - m_ui.enabled->setChecked(obj->y != 0 && obj->y < 160); + m_ui.priority->setText(QString::number(newInfo.priority)); + m_ui.flippedH->setChecked(newInfo.hflip); + m_ui.flippedV->setChecked(newInfo.vflip); + m_ui.enabled->setChecked(newInfo.enabled); m_ui.doubleSize->setChecked(false); m_ui.mosaic->setChecked(false); m_ui.transform->setText(tr("N/A")); @@ -251,51 +200,10 @@ void ObjView::updateTilesGB(bool force) { } #endif -#ifdef USE_PNG void ObjView::exportObj() { QString filename = GBAApp::app()->getSaveFileName(this, tr("Export sprite"), tr("Portable Network Graphics (*.png)")); - VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC); - if (!vf) { - LOG(QT, ERROR) << tr("Failed to open output PNG file: %1").arg(filename); - return; - } - CoreController::Interrupter interrupter(m_controller); - png_structp png = PNGWriteOpen(vf); - png_infop info = PNGWriteHeader8(png, m_objInfo.width * 8, m_objInfo.height * 8); - - mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, m_objInfo.paletteSet); - const color_t* rawPalette = mTileCacheGetPalette(tileCache, m_objInfo.paletteId); - unsigned colors = 1 << m_objInfo.bits; - uint32_t palette[256]; - - palette[0] = rawPalette[0]; - for (unsigned c = 1; c < colors && c < 256; ++c) { - palette[c] = rawPalette[c] | 0xFF000000; - } - PNGWritePalette(png, info, palette, colors); - - uint8_t* buffer = new uint8_t[m_objInfo.width * m_objInfo.height * 8 * 8]; - unsigned t = m_objInfo.tile; - for (int y = 0; y < m_objInfo.height; ++y) { - for (int x = 0; x < m_objInfo.width; ++x, ++t) { - compositeTile(static_cast(mTileCacheGetVRAM(tileCache, t)), reinterpret_cast(buffer), m_objInfo.width * 8, x * 8, y * 8, m_objInfo.bits); - } - t += m_objInfo.stride - m_objInfo.width; - } - PNGWritePixels8(png, m_objInfo.width * 8, m_objInfo.height * 8, m_objInfo.width * 8, static_cast(buffer)); - PNGWriteClose(png, info); - delete[] buffer; - vf->close(vf); -} -#endif - -bool ObjView::ObjInfo::operator!=(const ObjInfo& other) { - return other.tile != tile || - other.width != width || - other.height != height || - other.stride != stride || - other.paletteId != paletteId || - other.paletteSet != paletteSet; + QImage obj = compositeObj(m_objInfo); + obj.save(filename, "PNG"); } diff --git a/src/platform/qt/ObjView.h b/src/platform/qt/ObjView.h index 41677ca92..42cd3f65e 100644 --- a/src/platform/qt/ObjView.h +++ b/src/platform/qt/ObjView.h @@ -21,10 +21,8 @@ Q_OBJECT public: ObjView(std::shared_ptr controller, QWidget* parent = nullptr); -#ifdef USE_PNG public slots: void exportObj(); -#endif private slots: void selectObj(int); @@ -43,17 +41,7 @@ private: std::shared_ptr m_controller; mTileCacheEntry m_tileStatus[1024 * 32] = {}; // TODO: Correct size int m_objId = 0; - struct ObjInfo { - unsigned tile; - unsigned width; - unsigned height; - unsigned stride; - unsigned paletteId; - unsigned paletteSet; - unsigned bits; - - bool operator!=(const ObjInfo&); - } m_objInfo = {}; + ObjInfo m_objInfo = {}; int m_tileOffset; int m_boundary; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d87674d55..fc4d9a6e2 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -30,6 +30,7 @@ #include "DebuggerConsoleController.h" #include "Display.h" #include "CoreController.h" +#include "FrameView.h" #include "GBAApp.h" #include "GDBController.h" #include "GDBWindow.h" @@ -1437,7 +1438,7 @@ void Window::setupMenu(QMenuBar* menubar) { m_overrideView->recheck(); }, "tools"); - m_actions.addAction(tr("Game &Pak sensors..."), "sensorWindow", [this]() { + m_actions.addAction(tr("Game Pak sensors..."), "sensorWindow", [this]() { if (!m_sensorView) { m_sensorView = std::move(std::make_unique(&m_inputController)); if (m_controller) { @@ -1467,6 +1468,12 @@ void Window::setupMenu(QMenuBar* menubar) { addGameAction(tr("View &sprites..."), "spriteWindow", openControllerTView(), "tools"); addGameAction(tr("View &tiles..."), "tileWindow", openControllerTView(), "tools"); addGameAction(tr("View &map..."), "mapWindow", openControllerTView(), "tools"); + +#ifdef M_CORE_GBA + Action* frameWindow = addGameAction(tr("&Frame inspector..."), "frameWindow", openControllerTView(), "tools"); + m_platformActions.insert(PLATFORM_GBA, frameWindow); +#endif + addGameAction(tr("View memory..."), "memoryView", openControllerTView(), "tools"); addGameAction(tr("Search memory..."), "memorySearch", openControllerTView(), "tools"); From 306139a73c77131fd7d4d76bc3750ffd49717fd9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 31 May 2019 16:27:02 -0700 Subject: [PATCH 349/429] Qt: Improve FrameView UI --- src/platform/qt/AssetView.cpp | 8 +-- src/platform/qt/FrameView.cpp | 93 +++++++++++++++++++++++++++-------- src/platform/qt/FrameView.h | 12 +++-- 3 files changed, 85 insertions(+), 28 deletions(-) diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index eef257025..c13af9403 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -204,8 +204,8 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { GBAObjAttributesCGetPriority(obj->c), GBAObjAttributesBGetX(obj->b), GBAObjAttributesAGetY(obj->a), - GBAObjAttributesBIsHFlip(obj->b), - GBAObjAttributesBIsVFlip(obj->b), + bool(GBAObjAttributesBIsHFlip(obj->b)), + bool(GBAObjAttributesBIsVFlip(obj->b)), }; GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { @@ -255,8 +255,8 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { GBObjAttributesGetPriority(obj->attr), obj->x, obj->y, - GBObjAttributesIsXFlip(obj->attr), - GBObjAttributesIsYFlip(obj->attr), + bool(GBObjAttributesIsXFlip(obj->attr)), + bool(GBObjAttributesIsYFlip(obj->attr)), }; *info = newInfo; return true; diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 121bd9171..989e0f775 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -38,6 +38,7 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent }); m_glowTimer.start(); + m_ui.renderedView->installEventFilter(this); m_ui.compositedView->installEventFilter(this); connect(m_ui.queue, &QListWidget::itemChanged, this, [this](QListWidgetItem* item) { @@ -58,10 +59,19 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent } invalidateQueue(); }); + connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), this, [this]() { + invalidateQueue(); + + QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); + m_ui.renderedView->setPixmap(rendered); + }); } -void FrameView::selectLayer(const QPointF& coord) { - for (const Layer& layer : m_queue) { +bool FrameView::lookupLayer(const QPointF& coord, Layer*& out) { + for (Layer& layer : m_queue) { + if (!layer.enabled || m_disabled.contains(layer.id)) { + continue; + } QPointF location = layer.location; QSizeF layerDims(layer.image.width(), layer.image.height()); QRegion region; @@ -82,11 +92,33 @@ void FrameView::selectLayer(const QPointF& coord) { } if (region.contains(QPoint(coord.x(), coord.y()))) { - m_active = layer.id; - m_glowFrame = 0; - break; + out = &layer; + return true; } } + return false; +} + +void FrameView::selectLayer(const QPointF& coord) { + Layer* layer; + if (!lookupLayer(coord, layer)) { + return; + } + if (layer->id == m_active) { + m_active = {}; + } else { + m_active = layer->id; + } + m_glowFrame = 0; +} + +void FrameView::disableLayer(const QPointF& coord) { + Layer* layer; + if (!lookupLayer(coord, layer)) { + return; + } + layer->enabled = false; + m_disabled.insert(layer->id); } void FrameView::updateTilesGBA(bool force) { @@ -99,6 +131,7 @@ void FrameView::updateTilesGBA(bool force) { updateRendered(); uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; + QRgb backdrop = M_RGB5_TO_RGB8(static_cast(m_controller->thread()->core->board)->video.palette[0]); int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); std::array enabled{ @@ -124,7 +157,7 @@ void FrameView::updateTilesGBA(bool force) { } m_queue.append({ { LayerId::SPRITE, sprite }, - !m_disabled.contains({ LayerId::SPRITE, sprite}), + !m_disabled.contains({ LayerId::SPRITE, sprite }), QPixmap::fromImage(obj), {}, offset, false }); @@ -150,7 +183,7 @@ void FrameView::updateTilesGBA(bool force) { }; m_queue.append({ { LayerId::BACKGROUND, bg }, - !m_disabled.contains({ LayerId::BACKGROUND, bg}), + !m_disabled.contains({ LayerId::BACKGROUND, bg }), QPixmap::fromImage(compositeMap(bg, m_mapStatus[bg])), {}, offset, true }); @@ -161,6 +194,15 @@ void FrameView::updateTilesGBA(bool force) { } } } + QImage backdropImage(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS), QImage::Format_Mono); + backdropImage.fill(1); + backdropImage.setColorTable({backdrop, backdrop | 0xFF000000 }); + m_queue.append({ + { LayerId::BACKDROP }, + !m_disabled.contains({ LayerId::BACKDROP }), + QPixmap::fromImage(backdropImage), + {}, {0, 0}, false + }); } invalidateQueue(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS)); } @@ -178,19 +220,18 @@ void FrameView::updateTilesGB(bool force) { } void FrameView::invalidateQueue(const QSize& dims) { - QSize realDims = dims; - if (!dims.isValid()) { - realDims = m_composited.size() / m_ui.magnification->value(); + if (dims.isValid()) { + m_dims = dims; } bool blockSignals = m_ui.queue->blockSignals(true); - QPixmap composited(realDims); + QPixmap composited(m_dims); QPainter painter(&composited); QPalette palette; QColor activeColor = palette.color(QPalette::HighlightedText); activeColor.setAlpha(sin(m_glowFrame * M_PI / 60) * 16 + 96); - QRectF rect(0, 0, realDims.width(), realDims.height()); + QRectF rect(0, 0, m_dims.width(), m_dims.height()); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.fillRect(rect, QColor(0, 0, 0, 0)); @@ -264,7 +305,7 @@ void FrameView::invalidateQueue(const QSize& dims) { } m_ui.queue->blockSignals(blockSignals); - m_composited = composited.scaled(realDims * m_ui.magnification->value()); + m_composited = composited.scaled(m_dims * m_ui.magnification->value()); m_ui.compositedView->setPixmap(m_composited); } @@ -273,18 +314,25 @@ void FrameView::updateRendered() { return; } m_rendered.convertFromImage(m_controller->getPixels()); - m_rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); - m_ui.renderedView->setPixmap(m_rendered); + QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); + m_ui.renderedView->setPixmap(rendered); } bool FrameView::eventFilter(QObject* obj, QEvent* event) { - if (event->type() != QEvent::MouseButtonPress) { - return false; + QPointF pos; + switch (event->type()) { + case QEvent::MouseButtonPress: + pos = static_cast(event)->localPos(); + pos /= m_ui.magnification->value(); + selectLayer(pos); + return true; + case QEvent::MouseButtonDblClick: + pos = static_cast(event)->localPos(); + pos /= m_ui.magnification->value(); + disableLayer(pos); + return true; } - QPointF pos = static_cast(event)->localPos(); - pos /= m_ui.magnification->value(); - selectLayer(pos); - return true; + return false; } QString FrameView::LayerId::readable() const { @@ -301,6 +349,9 @@ QString FrameView::LayerId::readable() const { case SPRITE: typeStr = tr("Sprite"); break; + case BACKDROP: + typeStr = tr("Backdrop"); + break; } if (index < 0) { return typeStr; diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 626dfbd62..4fd1bea09 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -30,6 +30,7 @@ public: public slots: void selectLayer(const QPointF& coord); + void disableLayer(const QPointF& coord); protected: #ifdef M_CORE_GBA @@ -41,13 +42,18 @@ protected: bool eventFilter(QObject* obj, QEvent* event) override; +private slots: + void invalidateQueue(const QSize& dims = QSize()); + void updateRendered(); + private: struct LayerId { enum { NONE = 0, BACKGROUND, WINDOW, - SPRITE + SPRITE, + BACKDROP } type = NONE; int index = -1; @@ -65,8 +71,7 @@ private: bool repeats; }; - void invalidateQueue(const QSize& dims = QSize()); - void updateRendered(); + bool lookupLayer(const QPointF& coord, Layer*&); Ui::FrameView m_ui; @@ -75,6 +80,7 @@ private: int m_glowFrame; QTimer m_glowTimer; + QSize m_dims; QList m_queue; QSet m_disabled; QPixmap m_composited; From b230b6e0f64dad1f431a38b7c93f2e6ba89757c3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 31 May 2019 16:30:11 -0700 Subject: [PATCH 350/429] Qt: Clang buildfixes --- src/platform/qt/FrameView.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 989e0f775..22bac7fce 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "CoreController.h" @@ -135,10 +136,10 @@ void FrameView::updateTilesGBA(bool force) { int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); std::array enabled{ - GBARegisterDISPCNTIsBg0Enable(io[REG_DISPCNT >> 1]), - GBARegisterDISPCNTIsBg1Enable(io[REG_DISPCNT >> 1]), - GBARegisterDISPCNTIsBg2Enable(io[REG_DISPCNT >> 1]), - GBARegisterDISPCNTIsBg3Enable(io[REG_DISPCNT >> 1]), + bool(GBARegisterDISPCNTIsBg0Enable(io[REG_DISPCNT >> 1])), + bool(GBARegisterDISPCNTIsBg1Enable(io[REG_DISPCNT >> 1])), + bool(GBARegisterDISPCNTIsBg2Enable(io[REG_DISPCNT >> 1])), + bool(GBARegisterDISPCNTIsBg3Enable(io[REG_DISPCNT >> 1])), }; for (int priority = 0; priority < 4; ++priority) { From 3cce95b287c589bce3b371a1677c01afd3adf0ef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 11:07:49 -0700 Subject: [PATCH 351/429] Core: Video log enhancements --- include/mgba/feature/video-logger.h | 1 + src/feature/video-logger.c | 47 +++++++++++++++++++---------- src/gb/core.c | 8 +++-- src/gba/core.c | 8 +++-- src/platform/qt/CoreController.cpp | 21 ++++++++++--- src/platform/qt/CoreController.h | 5 +-- 6 files changed, 62 insertions(+), 28 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index d33e83155..2acd9c87f 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -104,6 +104,7 @@ void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogCont struct mCore; struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core); +void mVideoLogContextSetCompression(struct mVideoLogContext*, bool enable); void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*); void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core); diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index be1c7b3f7..9e208f9f1 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -94,6 +94,7 @@ struct mVideoLogContext { struct mVideoLogChannel channels[mVL_MAX_CHANNELS]; bool write; + bool compression; uint32_t activeChannel; struct VFile* backing; }; @@ -465,6 +466,12 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { context->initialStateSize = 0; context->initialState = NULL; +#ifdef USE_ZLIB + context->compression = true; +#else + context->compression = false; +#endif + if (core) { context->initialStateSize = core->stateSize(core); context->initialState = anonymousMemoryMap(context->initialStateSize); @@ -482,6 +489,10 @@ void mVideoLogContextSetOutput(struct mVideoLogContext* context, struct VFile* v vf->seek(vf, 0, SEEK_SET); } +void mVideoLogContextSetCompression(struct mVideoLogContext* context, bool compression) { + context->compression = compression; +} + void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* core) { struct mVideoLogHeader header = { { 0 } }; memcpy(header.magic, mVL_MAGIC, sizeof(header.magic)); @@ -499,21 +510,24 @@ void mVideoLogContextWriteHeader(struct mVideoLogContext* context, struct mCore* struct mVLBlockHeader chheader = { 0 }; STORE_32LE(mVL_BLOCK_INITIAL_STATE, 0, &chheader.blockType); #ifdef USE_ZLIB - STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags); + if (context->compression) { + STORE_32LE(mVL_FLAG_BLOCK_COMPRESSED, 0, &chheader.flags); - struct VFile* vfm = VFileMemChunk(NULL, 0); - struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize); - _compress(vfm, src); - src->close(src); - STORE_32LE(vfm->size(vfm), 0, &chheader.length); - context->backing->write(context->backing, &chheader, sizeof(chheader)); - _copyVf(context->backing, vfm); - vfm->close(vfm); -#else - STORE_32LE(context->initialStateSize, 0, &chheader.length); - context->backing->write(context->backing, &chheader, sizeof(chheader)); - context->backing->write(context->backing, context->initialState, context->initialStateSize); + struct VFile* vfm = VFileMemChunk(NULL, 0); + struct VFile* src = VFileFromConstMemory(context->initialState, context->initialStateSize); + _compress(vfm, src); + src->close(src); + STORE_32LE(vfm->size(vfm), 0, &chheader.length); + context->backing->write(context->backing, &chheader, sizeof(chheader)); + _copyVf(context->backing, vfm); + vfm->close(vfm); + } else #endif + { + STORE_32LE(context->initialStateSize, 0, &chheader.length); + context->backing->write(context->backing, &chheader, sizeof(chheader)); + context->backing->write(context->backing, context->initialState, context->initialStateSize); + } } size_t i; @@ -647,9 +661,10 @@ static void _flushBufferCompressed(struct mVideoLogContext* context) { static void _flushBuffer(struct mVideoLogContext* context) { #ifdef USE_ZLIB - // TODO: Make optional - _flushBufferCompressed(context); - return; + if (context->compression) { + _flushBufferCompressed(context); + return; + } #endif struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; diff --git a/src/gb/core.c b/src/gb/core.c index 264f29bf1..9c00519a0 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -879,9 +879,11 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co static void _GBCoreEndVideoLog(struct mCore* core) { struct GBCore* gbcore = (struct GBCore*) core; struct GB* gb = core->board; - GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); - free(gbcore->proxyRenderer.logger); - gbcore->proxyRenderer.logger = NULL; + if (gbcore->proxyRenderer.logger) { + GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); + free(gbcore->proxyRenderer.logger); + gbcore->proxyRenderer.logger = NULL; + } } #endif diff --git a/src/gba/core.c b/src/gba/core.c index 53925cc52..bf3a7ecfd 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -990,9 +990,11 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c static void _GBACoreEndVideoLog(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = core->board; - GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); - free(gbacore->proxyRenderer.logger); - gbacore->proxyRenderer.logger = NULL; + if (gbacore->proxyRenderer.logger) { + GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); + free(gbacore->proxyRenderer.logger); + gbacore->proxyRenderer.logger = NULL; + } } #endif diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index e1d4bc7ea..fb59baf5c 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -809,26 +809,39 @@ void CoreController::clearOverride() { m_override.reset(); } -void CoreController::startVideoLog(const QString& path) { +void CoreController::startVideoLog(const QString& path, bool compression) { if (m_vl) { return; } + VFile* vf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); + if (!vf) { + return; + } + startVideoLog(vf); +} + +void CoreController::startVideoLog(VFile* vf, bool compression) { + if (m_vl || !vf) { + return; + } + Interrupter interrupter(this); m_vl = mVideoLogContextCreate(m_threadContext.core); - m_vlVf = VFileDevice::open(path, O_WRONLY | O_CREAT | O_TRUNC); + m_vlVf = vf; mVideoLogContextSetOutput(m_vl, m_vlVf); + mVideoLogContextSetCompression(m_vl, compression); mVideoLogContextWriteHeader(m_vl, m_threadContext.core); } -void CoreController::endVideoLog() { +void CoreController::endVideoLog(bool closeVf) { if (!m_vl) { return; } Interrupter interrupter(this); mVideoLogContextDestroy(m_threadContext.core, m_vl); - if (m_vlVf) { + if (m_vlVf && closeVf) { m_vlVf->close(m_vlVf); m_vlVf = nullptr; } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index ac1e327ba..b6f9d7ecf 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -161,8 +161,9 @@ public slots: void clearOverride(); - void startVideoLog(const QString& path); - void endVideoLog(); + void startVideoLog(const QString& path, bool compression = true); + void startVideoLog(VFile* vf, bool compression = true); + void endVideoLog(bool closeVf = true); void setFramebufferHandle(int fb); From 5436d2576ffd0dac6254963e4a8d656e445ef078 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 11:08:28 -0700 Subject: [PATCH 352/429] Core: Fix crashes if core directories aren't set --- CHANGES | 1 + src/core/core.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 8b449be32..c49cc0538 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Other fixes: - Core: Improved lockstep driver reliability (Le Hoang Quyen) - Switch: Fix threading-related crash on second launch - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) + - Core: Fix crashes if core directories aren't set Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/core/core.c b/src/core/core.c index 57c2dd811..af3ff68a8 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -157,10 +157,16 @@ bool mCorePreloadFile(struct mCore* core, const char* path) { } bool mCoreAutoloadSave(struct mCore* core) { + if (!core->dirs.save) { + return false; + } return core->loadSave(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.save, ".sav", O_CREAT | O_RDWR)); } bool mCoreAutoloadPatch(struct mCore* core) { + if (!core->dirs.patch) { + return false; + } return core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ups", O_RDONLY)) || core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".ips", O_RDONLY)) || core->loadPatch(core, mDirectorySetOpenSuffix(&core->dirs, core->dirs.patch, ".bps", O_RDONLY)); @@ -217,6 +223,9 @@ bool mCoreLoadState(struct mCore* core, int slot, int flags) { } struct VFile* mCoreGetState(struct mCore* core, int slot, bool write) { + if (!core->dirs.state) { + return NULL; + } char name[PATH_MAX + 14]; // Quash warning snprintf(name, sizeof(name), "%s.ss%i", core->dirs.baseName, slot); return core->dirs.state->openFile(core->dirs.state, name, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); From 4420054c1a3b13e406e28aaa7ab8f44ab3509438 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 11:08:49 -0700 Subject: [PATCH 353/429] Qt: Expose frame actions --- src/platform/qt/CoreController.cpp | 24 +++++++++++++++--------- src/platform/qt/CoreController.h | 5 ++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index fb59baf5c..4608a1b45 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -203,10 +203,10 @@ CoreController::~CoreController() { } const color_t* CoreController::drawContext() { - QMutexLocker locker(&m_mutex); if (m_hwaccel) { return nullptr; } + QMutexLocker locker(&m_bufferMutex); return reinterpret_cast(m_completeBuffer.constData()); } @@ -401,8 +401,7 @@ void CoreController::setPaused(bool paused) { return; } if (paused) { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); } else { @@ -411,13 +410,17 @@ void CoreController::setPaused(bool paused) { } void CoreController::frameAdvance() { - QMutexLocker locker(&m_mutex); - m_frameActions.append([this]() { + addFrameAction([this]() { mCoreThreadPauseFromThread(&m_threadContext); }); setPaused(false); } +void CoreController::addFrameAction(std::function action) { + QMutexLocker locker(&m_actionMutex); + m_frameActions.append(action); +} + void CoreController::setSync(bool sync) { if (sync) { m_threadContext.impl->sync.audioWait = m_audioSync; @@ -880,9 +883,9 @@ int CoreController::updateAutofire() { } void CoreController::finishFrame() { - QMutexLocker locker(&m_mutex); if (!m_hwaccel) { - memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); + QMutexLocker locker(&m_bufferMutex); + memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); // TODO: Generalize this to triple buffering? m_activeBuffer = &m_buffers[0]; @@ -893,10 +896,13 @@ void CoreController::finishFrame() { memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), screenDimensions().width()); } - for (auto& action : m_frameActions) { + + QMutexLocker locker(&m_actionMutex); + QList> frameActions(m_frameActions); + m_frameActions.clear(); + for (auto& action : frameActions) { action(); } - m_frameActions.clear(); updateKeys(); QMetaObject::invokeMethod(this, "frameAvailable"); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index b6f9d7ecf..5463bf76b 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -102,6 +102,8 @@ public: bool audioSync() const { return m_audioSync; } bool videoSync() const { return m_videoSync; } + void addFrameAction(std::function callback); + public slots: void start(); void stop(); @@ -209,7 +211,8 @@ private: QList> m_resetActions; QList> m_frameActions; - QMutex m_mutex; + QMutex m_actionMutex{QMutex::Recursive}; + QMutex m_bufferMutex; int m_activeKeys = 0; bool m_autofire[32] = {}; From 570f2c5f380464ae7f6d468242151d520cb00c15 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 14:28:39 -0700 Subject: [PATCH 354/429] Core: Video packet injection --- include/mgba/feature/video-logger.h | 12 ++++ src/feature/video-logger.c | 104 ++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 15 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index 2acd9c87f..b466e4b6c 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -35,6 +35,11 @@ enum mVideoLoggerEvent { LOGGER_EVENT_GET_PIXELS, }; +enum mVideoLoggerInjectionPoint { + LOGGER_INJECTION_IMMEDIATE = 0, + LOGGER_INJECTION_FIRST_SCANLINE, +}; + struct mVideoLoggerDirtyInfo { enum mVideoLoggerDirtyType type; uint32_t address; @@ -97,6 +102,7 @@ void mVideoLoggerRendererFlush(struct mVideoLogger* logger); void mVideoLoggerRendererFinishFrame(struct mVideoLogger* logger); bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block); +bool mVideoLoggerRendererRunInjected(struct mVideoLogger* logger); struct mVideoLogContext; void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogContext* context, size_t channelId); @@ -116,6 +122,12 @@ void* mVideoLogContextInitialState(struct mVideoLogContext*, size_t* size); int mVideoLoggerAddChannel(struct mVideoLogContext*); +void mVideoLoggerInjectionPoint(struct mVideoLogger* logger, enum mVideoLoggerInjectionPoint); +void mVideoLoggerIgnoreAfterInjection(struct mVideoLogger* logger, uint32_t mask); +void mVideoLoggerInjectVideoRegister(struct mVideoLogger* logger, uint32_t address, uint16_t value); +void mVideoLoggerInjectPalette(struct mVideoLogger* logger, uint32_t address, uint16_t value); +void mVideoLoggerInjectOAM(struct mVideoLogger* logger, uint32_t address, uint16_t value); + struct mCore* mVideoLogCoreFind(struct VFile*); CXX_GUARD_END diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 9e208f9f1..a2884a107 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -84,6 +84,11 @@ struct mVideoLogChannel { z_stream inflateStream; #endif + bool injecting; + enum mVideoLoggerInjectionPoint injectionPoint; + uint32_t ignorePackets; + + struct CircleBuffer injectedBuffer; struct CircleBuffer buffer; }; @@ -286,14 +291,28 @@ void mVideoLoggerWriteBuffer(struct mVideoLogger* logger, uint32_t bufferId, uin } bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block) { + struct mVideoLogChannel* channel = logger->dataContext; + uint32_t ignorePackets = 0; + if (channel->injectionPoint == LOGGER_INJECTION_IMMEDIATE && !channel->injecting) { + mVideoLoggerRendererRunInjected(logger); + ignorePackets = channel->ignorePackets; + } struct mVideoLoggerDirtyInfo item = {0}; while (logger->readData(logger, &item, sizeof(item), block)) { + if (ignorePackets & (1 << item.type)) { + continue; + } switch (item.type) { + case DIRTY_SCANLINE: + if (channel->injectionPoint == LOGGER_INJECTION_FIRST_SCANLINE && !channel->injecting && item.address == 0) { + mVideoLoggerRendererRunInjected(logger); + ignorePackets = channel->ignorePackets; + } + // Fall through case DIRTY_REGISTER: case DIRTY_PALETTE: case DIRTY_OAM: case DIRTY_VRAM: - case DIRTY_SCANLINE: case DIRTY_FLUSH: case DIRTY_FRAME: case DIRTY_RANGE: @@ -309,15 +328,34 @@ bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block) { return !block; } +bool mVideoLoggerRendererRunInjected(struct mVideoLogger* logger) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->injecting = true; + bool res = mVideoLoggerRendererRun(logger, false); + channel->injecting = false; + return res; +} + +void mVideoLoggerInjectionPoint(struct mVideoLogger* logger, enum mVideoLoggerInjectionPoint injectionPoint) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->injectionPoint = injectionPoint; +} + +void mVideoLoggerIgnoreAfterInjection(struct mVideoLogger* logger, uint32_t mask) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->ignorePackets = mask; +} + static bool _writeData(struct mVideoLogger* logger, const void* data, size_t length) { struct mVideoLogChannel* channel = logger->dataContext; return mVideoLoggerWriteChannel(channel, data, length) == (ssize_t) length; } static bool _writeNull(struct mVideoLogger* logger, const void* data, size_t length) { - UNUSED(logger); - UNUSED(data); - UNUSED(length); + struct mVideoLogChannel* channel = logger->dataContext; + if (channel->injecting) { + return mVideoLoggerWriteChannel(channel, data, length) == (ssize_t) length; + } return false; } @@ -623,6 +661,7 @@ bool mVideoLogContextLoad(struct mVideoLogContext* context, struct VFile* vf) { size_t i; for (i = 0; i < context->nChannels; ++i) { + CircleBufferInit(&context->channels[i].injectedBuffer, BUFFER_BASE_SIZE); CircleBufferInit(&context->channels[i].buffer, BUFFER_BASE_SIZE); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; @@ -703,6 +742,7 @@ void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext* contex size_t i; for (i = 0; i < context->nChannels; ++i) { + CircleBufferDeinit(&context->channels[i].injectedBuffer); CircleBufferDeinit(&context->channels[i].buffer); #ifdef USE_ZLIB if (context->channels[i].inflating) { @@ -733,6 +773,7 @@ void mVideoLogContextRewind(struct mVideoLogContext* context, struct mCore* core size_t i; for (i = 0; i < context->nChannels; ++i) { + CircleBufferClear(&context->channels[i].injectedBuffer); CircleBufferClear(&context->channels[i].buffer); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; @@ -759,10 +800,35 @@ int mVideoLoggerAddChannel(struct mVideoLogContext* context) { int chid = context->nChannels; ++context->nChannels; context->channels[chid].p = context; + CircleBufferInit(&context->channels[chid].injectedBuffer, BUFFER_BASE_SIZE); CircleBufferInit(&context->channels[chid].buffer, BUFFER_BASE_SIZE); + context->channels[chid].injecting = false; + context->channels[chid].injectionPoint = LOGGER_INJECTION_IMMEDIATE; + context->channels[chid].ignorePackets = 0; return chid; } +void mVideoLoggerInjectVideoRegister(struct mVideoLogger* logger, uint32_t address, uint16_t value) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->injecting = true; + mVideoLoggerRendererWriteVideoRegister(logger, address, value); + channel->injecting = false; +} + +void mVideoLoggerInjectPalette(struct mVideoLogger* logger, uint32_t address, uint16_t value) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->injecting = true; + mVideoLoggerRendererWritePalette(logger, address, value); + channel->injecting = false; +} + +void mVideoLoggerInjectOAM(struct mVideoLogger* logger, uint32_t address, uint16_t value) { + struct mVideoLogChannel* channel = logger->dataContext; + channel->injecting = true; + mVideoLoggerRendererWriteOAM(logger, address, value); + channel->injecting = false; +} + #ifdef USE_ZLIB static size_t _readBufferCompressed(struct VFile* vf, struct mVideoLogChannel* channel, size_t length) { uint8_t fbuffer[0x400]; @@ -915,12 +981,16 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (channelId >= mVL_MAX_CHANNELS) { return 0; } - if (CircleBufferSize(&channel->buffer) >= length) { - return CircleBufferRead(&channel->buffer, data, length); + struct CircleBuffer* buffer = &channel->buffer; + if (channel->injecting) { + buffer = &channel->injectedBuffer; + } + if (CircleBufferSize(buffer) >= length) { + return CircleBufferRead(buffer, data, length); } ssize_t size = 0; - if (CircleBufferSize(&channel->buffer)) { - size = CircleBufferRead(&channel->buffer, data, CircleBufferSize(&channel->buffer)); + if (CircleBufferSize(buffer)) { + size = CircleBufferRead(buffer, data, CircleBufferSize(buffer)); if (size <= 0) { return size; } @@ -930,7 +1000,7 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (!_fillBuffer(context, channelId, BUFFER_BASE_SIZE)) { return size; } - size += CircleBufferRead(&channel->buffer, data, length); + size += CircleBufferRead(buffer, data, length); return size; } @@ -944,16 +1014,20 @@ static ssize_t mVideoLoggerWriteChannel(struct mVideoLogChannel* channel, const _flushBuffer(context); context->activeChannel = channelId; } - if (CircleBufferCapacity(&channel->buffer) - CircleBufferSize(&channel->buffer) < length) { + struct CircleBuffer* buffer = &channel->buffer; + if (channel->injecting) { + buffer = &channel->injectedBuffer; + } + if (CircleBufferCapacity(buffer) - CircleBufferSize(buffer) < length) { _flushBuffer(context); - if (CircleBufferCapacity(&channel->buffer) < length) { - CircleBufferDeinit(&channel->buffer); - CircleBufferInit(&channel->buffer, toPow2(length << 1)); + if (CircleBufferCapacity(buffer) < length) { + CircleBufferDeinit(buffer); + CircleBufferInit(buffer, toPow2(length << 1)); } } - ssize_t read = CircleBufferWrite(&channel->buffer, data, length); - if (CircleBufferCapacity(&channel->buffer) == CircleBufferSize(&channel->buffer)) { + ssize_t read = CircleBufferWrite(buffer, data, length); + if (CircleBufferCapacity(buffer) == CircleBufferSize(buffer)) { _flushBuffer(context); } return read; From f41f3a847893450843f33e6c45c7025fdd8e1fc9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 14:30:22 -0700 Subject: [PATCH 355/429] GBA Video: Support highlighting layers --- include/mgba/internal/gba/renderers/common.h | 1 + .../internal/gba/renderers/video-software.h | 5 +++ include/mgba/internal/gba/video.h | 6 ++++ src/gba/extra/proxy.c | 6 ++++ src/gba/renderers/common.c | 1 + src/gba/renderers/software-mode0.c | 6 ++++ src/gba/renderers/software-obj.c | 8 ++++- src/gba/renderers/software-private.h | 14 +++++++- src/gba/renderers/video-software.c | 33 ++++++++++++++++++- 9 files changed, 77 insertions(+), 3 deletions(-) diff --git a/include/mgba/internal/gba/renderers/common.h b/include/mgba/internal/gba/renderers/common.h index e90b1f350..ba368edc9 100644 --- a/include/mgba/internal/gba/renderers/common.h +++ b/include/mgba/internal/gba/renderers/common.h @@ -16,6 +16,7 @@ struct GBAVideoRendererSprite { struct GBAObj obj; int16_t y; int16_t endY; + int8_t index; }; int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite* sprites, int offsetY); diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 47b8ddfb6..b15dc47b4 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -42,6 +42,7 @@ struct GBAVideoSoftwareBackground { uint16_t mapCache[64]; int32_t offsetX; int32_t offsetY; + bool highlight; }; enum { @@ -105,6 +106,8 @@ struct GBAVideoSoftwareRenderer { enum GBAVideoBlendEffect blendEffect; color_t normalPalette[512]; color_t variantPalette[512]; + color_t highlightPalette[512]; + color_t highlightVariantPalette[512]; uint16_t blda; uint16_t bldb; @@ -144,6 +147,8 @@ struct GBAVideoSoftwareRenderer { int start; int end; + + uint8_t lastHighlightAmount; }; void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer); diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index ba8048ffd..908954aaf 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -12,6 +12,7 @@ CXX_GUARD_START #include #include +#include mLOG_DECLARE_CATEGORY(GBA_VIDEO); @@ -192,6 +193,11 @@ struct GBAVideoRenderer { bool disableBG[4]; bool disableOBJ; + + bool highlightBG[4]; + bool highlightOBJ[128]; + color_t highlightColor; + uint8_t highlightAmount; }; struct GBAVideo { diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 52a0047b4..6121f4f99 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -191,6 +191,12 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD proxyRenderer->backend->disableBG[2] = proxyRenderer->d.disableBG[2]; proxyRenderer->backend->disableBG[3] = proxyRenderer->d.disableBG[3]; proxyRenderer->backend->disableOBJ = proxyRenderer->d.disableOBJ; + proxyRenderer->backend->highlightBG[0] = proxyRenderer->d.highlightBG[0]; + proxyRenderer->backend->highlightBG[1] = proxyRenderer->d.highlightBG[1]; + proxyRenderer->backend->highlightBG[2] = proxyRenderer->d.highlightBG[2]; + proxyRenderer->backend->highlightBG[3] = proxyRenderer->d.highlightBG[3]; + memcpy(proxyRenderer->backend->highlightOBJ, proxyRenderer->d.highlightOBJ, sizeof(proxyRenderer->backend->highlightOBJ)); + proxyRenderer->backend->highlightAmount = proxyRenderer->d.highlightAmount; if (item->address < GBA_VIDEO_VERTICAL_PIXELS) { proxyRenderer->backend->drawScanline(proxyRenderer->backend, item->address); } diff --git a/src/gba/renderers/common.c b/src/gba/renderers/common.c index 9065a6267..2ec71b3f7 100644 --- a/src/gba/renderers/common.c +++ b/src/gba/renderers/common.c @@ -25,6 +25,7 @@ int GBAVideoRendererCleanOAM(struct GBAObj* oam, struct GBAVideoRendererSprite* sprites[oamMax].y = y; sprites[oamMax].endY = y + height; sprites[oamMax].obj = obj; + sprites[oamMax].index = i; ++oamMax; } } diff --git a/src/gba/renderers/software-mode0.c b/src/gba/renderers/software-mode0.c index df5626c4b..9c5697e6c 100644 --- a/src/gba/renderers/software-mode0.c +++ b/src/gba/renderers/software-mode0.c @@ -482,8 +482,14 @@ void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer uint32_t charBase; int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); color_t* mainPalette = renderer->normalPalette; + if (renderer->d.highlightAmount && background->highlight) { + mainPalette = renderer->highlightPalette; + } if (variant) { mainPalette = renderer->variantPalette; + if (renderer->d.highlightAmount && background->highlight) { + mainPalette = renderer->highlightVariantPalette; + } } color_t* palette = mainPalette; PREPARE_OBJWIN; diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 8e3e677e1..6f0c1bb9e 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -127,7 +127,7 @@ renderer->row[outX] |= FLAG_OBJWIN; \ } -int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y) { +int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int index, int y) { int width = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][0]; int height = GBAVideoObjSizes[GBAObjAttributesAGetShape(sprite->a) * 4 + GBAObjAttributesBGetSize(sprite->b)][1]; int start = renderer->start; @@ -167,10 +167,16 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re } color_t* palette = &renderer->normalPalette[0x100]; + if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) { + palette = &renderer->highlightPalette[0x100]; + } color_t* objwinPalette = palette; if (variant) { palette = &renderer->variantPalette[0x100]; + if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) { + palette = &renderer->highlightVariantPalette[0x100]; + } if (GBAWindowControlIsBlendEnable(renderer->objwin.packed)) { objwinPalette = palette; } diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index 4e4e19166..07e588439 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -26,7 +26,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer void GBAVideoSoftwareRendererDrawBackgroundMode5(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y); -int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int y); +int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* renderer, struct GBAObj* sprite, int index, int y); void GBAVideoSoftwareRendererPostprocessSprite(struct GBAVideoSoftwareRenderer* renderer, unsigned priority); static inline unsigned _brighten(unsigned color, int y); @@ -141,11 +141,17 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re int objwinForceEnable = 0; \ UNUSED(objwinForceEnable); \ color_t* objwinPalette = renderer->normalPalette; \ + if (renderer->d.highlightAmount && background->highlight) { \ + objwinPalette = renderer->highlightPalette; \ + } \ UNUSED(objwinPalette); \ if (objwinSlowPath) { \ if (background->target1 && GBAWindowControlIsBlendEnable(renderer->objwin.packed) && \ (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN)) { \ objwinPalette = renderer->variantPalette; \ + if (renderer->d.highlightAmount && background->highlight) { \ + palette = renderer->highlightVariantPalette; \ + } \ } \ switch (background->index) { \ case 0: \ @@ -200,8 +206,14 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re int variant = background->target1 && GBAWindowControlIsBlendEnable(renderer->currentWindow.packed) && \ (renderer->blendEffect == BLEND_BRIGHTEN || renderer->blendEffect == BLEND_DARKEN); \ color_t* palette = renderer->normalPalette; \ + if (renderer->d.highlightAmount && background->highlight) { \ + palette = renderer->highlightPalette; \ + } \ if (variant) { \ palette = renderer->variantPalette; \ + if (renderer->d.highlightAmount && background->highlight) { \ + palette = renderer->highlightVariantPalette; \ + } \ } \ UNUSED(palette); \ PREPARE_OBJWIN; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 86c3bc409..565b7a452 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -62,6 +62,17 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.highlightBG[0] = false; + renderer->d.highlightBG[1] = false; + renderer->d.highlightBG[2] = false; + renderer->d.highlightBG[3] = false; + int i; + for (i = 0; i < 128; ++i) { + renderer->d.highlightOBJ[i] = false; + } + renderer->d.highlightColor = GBA_COLOR_WHITE; + renderer->d.highlightAmount = 0; + renderer->temporaryBuffer = 0; } @@ -568,6 +579,13 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render softwareRenderer->windows[0].control.packed = 0xFF; } + if (softwareRenderer->lastHighlightAmount != softwareRenderer->d.highlightAmount) { + softwareRenderer->lastHighlightAmount = softwareRenderer->d.highlightAmount; + if (softwareRenderer->lastHighlightAmount) { + softwareRenderer->blendDirty = true; + } + } + if (softwareRenderer->blendDirty) { _updatePalettes(softwareRenderer); softwareRenderer->blendDirty = false; @@ -595,6 +613,11 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render } } + softwareRenderer->bg[0].highlight = softwareRenderer->d.highlightBG[0]; + softwareRenderer->bg[1].highlight = softwareRenderer->d.highlightBG[1]; + softwareRenderer->bg[2].highlight = softwareRenderer->d.highlightBG[2]; + softwareRenderer->bg[3].highlight = softwareRenderer->d.highlightBG[3]; + _drawScanline(softwareRenderer, y); if (softwareRenderer->target2Bd) { @@ -828,7 +851,7 @@ static void _drawScanline(struct GBAVideoSoftwareRenderer* renderer, int y) { continue; } - int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, localY); + int drawn = GBAVideoSoftwareRendererPreprocessSprite(renderer, &sprite->obj, sprite->index, localY); spriteLayers |= drawn << GBAObjAttributesCGetPriority(sprite->obj.c); } if (renderer->spriteCyclesRemaining <= 0) { @@ -925,4 +948,12 @@ static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer) { renderer->variantPalette[i] = renderer->normalPalette[i]; } } + unsigned highlightAmount = renderer->d.highlightAmount >> 4; + + if (highlightAmount) { + for (i = 0; i < 512; ++i) { + renderer->highlightPalette[i] = _mix(0x10 - highlightAmount, renderer->normalPalette[i], highlightAmount, renderer->d.highlightColor); + renderer->highlightVariantPalette[i] = _mix(0x10 - highlightAmount, renderer->variantPalette[i], highlightAmount, renderer->d.highlightColor); + } + } } From 59d2e58bbbd42746d2bc781fe8d8adfe1ff3588f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 14:30:44 -0700 Subject: [PATCH 356/429] GBA Core: VLP fixes --- src/gba/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gba/core.c b/src/gba/core.c index bf3a7ecfd..67864c409 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1094,6 +1094,7 @@ static void _GBAVLPStartFrameCallback(void *context) { GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); mVideoLogContextRewind(gbacore->logContext, core); GBAVideoProxyRendererShim(&gba->video, &gbacore->proxyRenderer); + gba->earlyExit = true; } } @@ -1109,6 +1110,7 @@ static bool _GBAVLPInit(struct mCore* core) { gbacore->logCallbacks.videoFrameStarted = _GBAVLPStartFrameCallback; gbacore->logCallbacks.context = core; core->addCoreCallbacks(core, &gbacore->logCallbacks); + core->videoLogger = gbacore->proxyRenderer.logger; return true; } From ef3cc7bd9f28d73fdff912587fc42260948d5b51 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 14:31:51 -0700 Subject: [PATCH 357/429] Qt: Redo frame inspector using video logs --- src/platform/qt/FrameView.cpp | 203 +++++++++++++++++++++++----------- src/platform/qt/FrameView.h | 28 ++++- src/platform/qt/FrameView.ui | 30 ++--- 3 files changed, 178 insertions(+), 83 deletions(-) diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 22bac7fce..bb5e23e48 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -14,6 +14,8 @@ #include "CoreController.h" +#include +#include #ifdef M_CORE_GBA #include #include @@ -37,7 +39,6 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent ++m_glowFrame; invalidateQueue(); }); - m_glowTimer.start(); m_ui.renderedView->installEventFilter(this); m_ui.compositedView->installEventFilter(this); @@ -66,6 +67,15 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); m_ui.renderedView->setPixmap(rendered); }); + m_controller->addFrameAction(std::bind(&FrameView::frameCallback, this, m_callbackLocker)); +} + +FrameView::~FrameView() { + QMutexLocker locker(&m_mutex); + *m_callbackLocker = false; + if (m_vl) { + m_vl->deinit(m_vl); + } } bool FrameView::lookupLayer(const QPointF& coord, Layer*& out) { @@ -122,24 +132,26 @@ void FrameView::disableLayer(const QPointF& coord) { m_disabled.insert(layer->id); } +#ifdef M_CORE_GBA void FrameView::updateTilesGBA(bool force) { if (m_ui.freeze->checkState() == Qt::Checked) { return; } + QMutexLocker locker(&m_mutex); m_queue.clear(); { CoreController::Interrupter interrupter(m_controller); - updateRendered(); uint16_t* io = static_cast(m_controller->thread()->core->board)->memory.io; QRgb backdrop = M_RGB5_TO_RGB8(static_cast(m_controller->thread()->core->board)->video.palette[0]); - int mode = GBARegisterDISPCNTGetMode(io[REG_DISPCNT >> 1]); + m_gbaDispcnt = io[REG_DISPCNT >> 1]; + int mode = GBARegisterDISPCNTGetMode(m_gbaDispcnt); std::array enabled{ - bool(GBARegisterDISPCNTIsBg0Enable(io[REG_DISPCNT >> 1])), - bool(GBARegisterDISPCNTIsBg1Enable(io[REG_DISPCNT >> 1])), - bool(GBARegisterDISPCNTIsBg2Enable(io[REG_DISPCNT >> 1])), - bool(GBARegisterDISPCNTIsBg3Enable(io[REG_DISPCNT >> 1])), + bool(GBARegisterDISPCNTIsBg0Enable(m_gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg1Enable(m_gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg2Enable(m_gbaDispcnt)), + bool(GBARegisterDISPCNTIsBg3Enable(m_gbaDispcnt)), }; for (int priority = 0; priority < 4; ++priority) { @@ -204,10 +216,53 @@ void FrameView::updateTilesGBA(bool force) { QPixmap::fromImage(backdropImage), {}, {0, 0}, false }); + updateRendered(); } invalidateQueue(QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS)); } +void FrameView::injectGBA() { + mVideoLogger* logger = m_vl->videoLogger; + mVideoLoggerInjectionPoint(logger, LOGGER_INJECTION_FIRST_SCANLINE); + GBA* gba = static_cast(m_vl->board); + gba->video.renderer->highlightBG[0] = false; + gba->video.renderer->highlightBG[1] = false; + gba->video.renderer->highlightBG[2] = false; + gba->video.renderer->highlightBG[3] = false; + for (int i = 0; i < 128; ++i) { + gba->video.renderer->highlightOBJ[i] = false; + } + QPalette palette; + gba->video.renderer->highlightColor = palette.color(QPalette::HighlightedText).rgb(); + gba->video.renderer->highlightAmount = sin(m_glowFrame * M_PI / 30) * 64 + 64; + + for (const Layer& layer : m_queue) { + switch (layer.id.type) { + case LayerId::SPRITE: + if (!layer.enabled) { + mVideoLoggerInjectOAM(logger, layer.id.index << 2, 0x200); + } + if (layer.id == m_active) { + gba->video.renderer->highlightOBJ[layer.id.index] = true; + } + break; + case LayerId::BACKGROUND: + m_vl->enableVideoLayer(m_vl, layer.id.index, layer.enabled); + if (layer.id == m_active) { + gba->video.renderer->highlightBG[layer.id.index] = true; + } + break; + } + } + if (m_ui.disableScanline->checkState() == Qt::Checked) { + mVideoLoggerIgnoreAfterInjection(logger, (1 << DIRTY_PALETTE) | (1 << DIRTY_OAM) | (1 << DIRTY_REGISTER)); + } else { + mVideoLoggerIgnoreAfterInjection(logger, 0); + } +} +#endif + +#ifdef M_CORE_GB void FrameView::updateTilesGB(bool force) { if (m_ui.freeze->checkState() == Qt::Checked) { return; @@ -220,23 +275,33 @@ void FrameView::updateTilesGB(bool force) { invalidateQueue(m_controller->screenDimensions()); } +void FrameView::injectGB() { + for (const Layer& layer : m_queue) { + } +} +#endif + void FrameView::invalidateQueue(const QSize& dims) { if (dims.isValid()) { m_dims = dims; } bool blockSignals = m_ui.queue->blockSignals(true); - QPixmap composited(m_dims); + QMutexLocker locker(&m_mutex); + if (m_vl) { + m_vl->reset(m_vl); + switch (m_controller->platform()) { +#ifdef M_CORE_GBA + case PLATFORM_GBA: + injectGBA(); +#endif +#ifdef M_CORE_GB + case PLATFORM_GB: + injectGB(); +#endif + } + m_vl->runFrame(m_vl); + } - QPainter painter(&composited); - QPalette palette; - QColor activeColor = palette.color(QPalette::HighlightedText); - activeColor.setAlpha(sin(m_glowFrame * M_PI / 60) * 16 + 96); - - QRectF rect(0, 0, m_dims.width(), m_dims.height()); - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(rect, QColor(0, 0, 0, 0)); - - painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); for (int i = 0; i < m_queue.count(); ++i) { const Layer& layer = m_queue[i]; QListWidgetItem* item; @@ -251,61 +316,20 @@ void FrameView::invalidateQueue(const QSize& dims) { item->setCheckState(layer.enabled ? Qt::Checked : Qt::Unchecked); item->setData(Qt::UserRole, i); item->setSelected(layer.id == m_active); - - if (!layer.enabled) { - continue; - } - - QPointF location = layer.location; - QSizeF layerDims(layer.image.width(), layer.image.height()); - QRegion region; - if (layer.repeats) { - if (location.x() + layerDims.width() < 0) { - location.setX(std::fmod(location.x(), layerDims.width())); - } - if (location.y() + layerDims.height() < 0) { - location.setY(std::fmod(location.y(), layerDims.height())); - } - - if (layer.id == m_active) { - region = layer.mask.translated(location.x(), location.y()); - region += layer.mask.translated(location.x() + layerDims.width(), location.y()); - region += layer.mask.translated(location.x(), location.y() + layerDims.height()); - region += layer.mask.translated(location.x() + layerDims.width(), location.y() + layerDims.height()); - } - } else { - QRectF layerRect(location, layerDims); - if (!rect.intersects(layerRect)) { - continue; - } - if (layer.id == m_active) { - region = layer.mask.translated(location.x(), location.y()); - } - } - - if (layer.id == m_active) { - painter.setClipping(true); - painter.setClipRegion(region); - painter.fillRect(rect, activeColor); - painter.setClipping(false); - } - - if (layer.repeats) { - painter.drawPixmap(location, layer.image); - painter.drawPixmap(location + QPointF(layerDims.width(), 0), layer.image); - painter.drawPixmap(location + QPointF(0, layerDims.height()), layer.image); - painter.drawPixmap(location + QPointF(layerDims.width(), layerDims.height()), layer.image); - } else { - painter.drawPixmap(location, layer.image); - } } - painter.end(); while (m_ui.queue->count() > m_queue.count()) { delete m_ui.queue->takeItem(m_queue.count()); } m_ui.queue->blockSignals(blockSignals); + QPixmap composited; + if (m_framebuffer.isNull()) { + updateRendered(); + composited = m_rendered; + } else { + composited.convertFromImage(m_framebuffer); + } m_composited = composited.scaled(m_dims * m_ui.magnification->value()); m_ui.compositedView->setPixmap(m_composited); } @@ -336,6 +360,53 @@ bool FrameView::eventFilter(QObject* obj, QEvent* event) { return false; } +void FrameView::refreshVl() { + QMutexLocker locker(&m_mutex); + m_currentFrame = m_nextFrame; + m_nextFrame = VFileMemChunk(nullptr, 0); + if (m_currentFrame) { + m_controller->endVideoLog(false); + VFile* currentFrame = VFileMemChunk(nullptr, m_currentFrame->size(m_currentFrame)); + void* buffer = currentFrame->map(currentFrame, m_currentFrame->size(m_currentFrame), MAP_WRITE); + m_currentFrame->seek(m_currentFrame, 0, SEEK_SET); + m_currentFrame->read(m_currentFrame, buffer, m_currentFrame->size(m_currentFrame)); + currentFrame->unmap(currentFrame, buffer, m_currentFrame->size(m_currentFrame)); + m_currentFrame = currentFrame; + QMetaObject::invokeMethod(this, "newVl"); + } + m_controller->endVideoLog(); + m_controller->startVideoLog(m_nextFrame, false); +} + +void FrameView::newVl() { + if (!m_glowTimer.isActive()) { + m_glowTimer.start(); + } + QMutexLocker locker(&m_mutex); + if (m_vl) { + m_vl->deinit(m_vl); + } + m_vl = mCoreFindVF(m_currentFrame); + m_vl->init(m_vl); + m_vl->loadROM(m_vl, m_currentFrame); + mCoreInitConfig(m_vl, nullptr); + unsigned width, height; + m_vl->desiredVideoDimensions(m_vl, &width, &height); + m_framebuffer = QImage(width, height, QImage::Format_RGBX8888); + m_vl->setVideoBuffer(m_vl, reinterpret_cast(m_framebuffer.bits()), width); + m_vl->reset(m_vl); +} + +void FrameView::frameCallback(FrameView* viewer, std::shared_ptr lock) { + if (!*lock) { + return; + } + CoreController::Interrupter interrupter(viewer->m_controller, true); + viewer->refreshVl(); + viewer->m_controller->addFrameAction(std::bind(&FrameView::frameCallback, viewer, lock)); +} + + QString FrameView::LayerId::readable() const { QString typeStr; switch (type) { diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 4fd1bea09..f255b62fc 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -10,14 +10,19 @@ #include #include #include +#include #include #include #include #include "AssetView.h" +#include + #include +struct VFile; + namespace QGBA { class CoreController; @@ -27,6 +32,7 @@ Q_OBJECT public: FrameView(std::shared_ptr controller, QWidget* parent = nullptr); + ~FrameView(); public slots: void selectLayer(const QPointF& coord); @@ -35,16 +41,20 @@ public slots: protected: #ifdef M_CORE_GBA void updateTilesGBA(bool force) override; + void injectGBA(); #endif #ifdef M_CORE_GB void updateTilesGB(bool force) override; + void injectGB(); #endif bool eventFilter(QObject* obj, QEvent* event) override; private slots: - void invalidateQueue(const QSize& dims = QSize()); + void invalidateQueue(const QSize& = {}); void updateRendered(); + void refreshVl(); + void newVl(); private: struct LayerId { @@ -57,7 +67,7 @@ private: } type = NONE; int index = -1; - bool operator==(const LayerId& other) const { return other.type == type && other.index == index; } + bool operator!=(const LayerId& other) const { return other.type != type || other.index != index; } operator uint() const { return (type << 8) | index; } QString readable() const; }; @@ -73,6 +83,8 @@ private: bool lookupLayer(const QPointF& coord, Layer*&); + static void frameCallback(FrameView*, std::shared_ptr); + Ui::FrameView m_ui; LayerId m_active{}; @@ -80,12 +92,24 @@ private: int m_glowFrame; QTimer m_glowTimer; + QMutex m_mutex{QMutex::Recursive}; + VFile* m_currentFrame = nullptr; + VFile* m_nextFrame = nullptr; + mCore* m_vl = nullptr; + QImage m_framebuffer; + QSize m_dims; QList m_queue; QSet m_disabled; QPixmap m_composited; QPixmap m_rendered; mMapCacheEntry m_mapStatus[4][128 * 128] = {}; // TODO: Correct size + +#ifdef M_CORE_GBA + uint16_t m_gbaDispcnt; +#endif + + std::shared_ptr m_callbackLocker{std::make_shared(true)}; }; } \ No newline at end of file diff --git a/src/platform/qt/FrameView.ui b/src/platform/qt/FrameView.ui index 2e61e09c8..c437b14f6 100644 --- a/src/platform/qt/FrameView.ui +++ b/src/platform/qt/FrameView.ui @@ -13,7 +13,7 @@ Inspect frame - + @@ -51,7 +51,7 @@ - + true @@ -61,8 +61,8 @@ 0 0 - 591 - 403 + 567 + 382 @@ -90,7 +90,7 @@ - + true @@ -100,8 +100,8 @@ 0 0 - 591 - 446 + 567 + 467 @@ -129,7 +129,10 @@ - + + + + false @@ -139,13 +142,10 @@ - - - - - 0 - 0 - + + + + Disable scanline effects From c7b6c4412d772011f4e1b9ee63dd830975e30972 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 14:57:35 -0700 Subject: [PATCH 358/429] Qt: Support export button in frame inspector --- src/platform/qt/FrameView.cpp | 9 +++++++++ src/platform/qt/FrameView.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index bb5e23e48..2f1c68a08 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -13,6 +13,7 @@ #include #include "CoreController.h" +#include "GBAApp.h" #include #include @@ -67,6 +68,7 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); m_ui.renderedView->setPixmap(rendered); }); + connect(m_ui.exportButton, &QAbstractButton::pressed, this, &FrameView::exportFrame); m_controller->addFrameAction(std::bind(&FrameView::frameCallback, this, m_callbackLocker)); } @@ -328,6 +330,7 @@ void FrameView::invalidateQueue(const QSize& dims) { updateRendered(); composited = m_rendered; } else { + m_ui.exportButton->setEnabled(true); composited.convertFromImage(m_framebuffer); } m_composited = composited.scaled(m_dims * m_ui.magnification->value()); @@ -406,6 +409,12 @@ void FrameView::frameCallback(FrameView* viewer, std::shared_ptr lock) { viewer->m_controller->addFrameAction(std::bind(&FrameView::frameCallback, viewer, lock)); } +void FrameView::exportFrame() { + QString filename = GBAApp::app()->getSaveFileName(this, tr("Export frame"), + tr("Portable Network Graphics (*.png)")); + CoreController::Interrupter interrupter(m_controller); + m_framebuffer.save(filename, "PNG"); +} QString FrameView::LayerId::readable() const { QString typeStr; diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index f255b62fc..2a2b5f680 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -37,6 +37,7 @@ public: public slots: void selectLayer(const QPointF& coord); void disableLayer(const QPointF& coord); + void exportFrame(); protected: #ifdef M_CORE_GBA From 2743905845e0e3bc7bbb56f34bbc1be06d84ebaa Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 15:52:23 -0700 Subject: [PATCH 359/429] Qt: Add backdrop editor --- src/platform/qt/ColorPicker.cpp | 8 +++ src/platform/qt/ColorPicker.h | 3 + src/platform/qt/FrameView.cpp | 30 +++++--- src/platform/qt/FrameView.h | 3 + src/platform/qt/FrameView.ui | 119 ++++++++++++++++---------------- 5 files changed, 93 insertions(+), 70 deletions(-) diff --git a/src/platform/qt/ColorPicker.cpp b/src/platform/qt/ColorPicker.cpp index 18782a5dc..818a25fd4 100644 --- a/src/platform/qt/ColorPicker.cpp +++ b/src/platform/qt/ColorPicker.cpp @@ -34,6 +34,14 @@ ColorPicker& ColorPicker::operator=(const ColorPicker& other) { return *this; } +void ColorPicker::setColor(const QColor& color) { + m_defaultColor = color; + + QPalette palette = m_parent->palette(); + palette.setColor(m_parent->backgroundRole(), color); + m_parent->setPalette(palette); +} + bool ColorPicker::eventFilter(QObject* obj, QEvent* event) { if (event->type() != QEvent::MouseButtonRelease) { return false; diff --git a/src/platform/qt/ColorPicker.h b/src/platform/qt/ColorPicker.h index 1e94933c8..bf50c5528 100644 --- a/src/platform/qt/ColorPicker.h +++ b/src/platform/qt/ColorPicker.h @@ -24,6 +24,9 @@ public: signals: void colorChanged(const QColor&); +public slots: + void setColor(const QColor&); + protected: bool eventFilter(QObject* obj, QEvent* event) override; diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 2f1c68a08..2dea0f08b 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -41,7 +41,6 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent invalidateQueue(); }); - m_ui.renderedView->installEventFilter(this); m_ui.compositedView->installEventFilter(this); connect(m_ui.queue, &QListWidget::itemChanged, this, [this](QListWidgetItem* item) { @@ -50,7 +49,7 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent if (layer.enabled) { m_disabled.remove(layer.id); } else { - m_disabled.insert(layer.id); + m_disabled.insert(layer.id); } invalidateQueue(); }); @@ -64,12 +63,20 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent }); connect(m_ui.magnification, static_cast(&QSpinBox::valueChanged), this, [this]() { invalidateQueue(); - - QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); - m_ui.renderedView->setPixmap(rendered); }); connect(m_ui.exportButton, &QAbstractButton::pressed, this, &FrameView::exportFrame); + + m_backdropPicker = ColorPicker(m_ui.backdrop, QColor(0, 0, 0, 0)); + connect(&m_backdropPicker, &ColorPicker::colorChanged, this, [this](const QColor& color) { + m_overrideBackdrop = color; + }); m_controller->addFrameAction(std::bind(&FrameView::frameCallback, this, m_callbackLocker)); + + { + CoreController::Interrupter interrupter(m_controller); + refreshVl(); + } + m_controller->frameAdvance(); } FrameView::~FrameView() { @@ -237,7 +244,12 @@ void FrameView::injectGBA() { QPalette palette; gba->video.renderer->highlightColor = palette.color(QPalette::HighlightedText).rgb(); gba->video.renderer->highlightAmount = sin(m_glowFrame * M_PI / 30) * 64 + 64; + if (!m_overrideBackdrop.isValid()) { + QRgb backdrop = M_RGB5_TO_RGB8(gba->video.palette[0]) | 0xFF000000; + m_backdropPicker.setColor(backdrop); + } + m_vl->reset(m_vl); for (const Layer& layer : m_queue) { switch (layer.id.type) { case LayerId::SPRITE: @@ -256,10 +268,13 @@ void FrameView::injectGBA() { break; } } + if (m_overrideBackdrop.isValid()) { + mVideoLoggerInjectPalette(logger, 0, M_RGB8_TO_RGB5(m_overrideBackdrop.rgb())); + } if (m_ui.disableScanline->checkState() == Qt::Checked) { mVideoLoggerIgnoreAfterInjection(logger, (1 << DIRTY_PALETTE) | (1 << DIRTY_OAM) | (1 << DIRTY_REGISTER)); } else { - mVideoLoggerIgnoreAfterInjection(logger, 0); + mVideoLoggerIgnoreAfterInjection(logger, 0); } } #endif @@ -290,7 +305,6 @@ void FrameView::invalidateQueue(const QSize& dims) { bool blockSignals = m_ui.queue->blockSignals(true); QMutexLocker locker(&m_mutex); if (m_vl) { - m_vl->reset(m_vl); switch (m_controller->platform()) { #ifdef M_CORE_GBA case PLATFORM_GBA: @@ -342,8 +356,6 @@ void FrameView::updateRendered() { return; } m_rendered.convertFromImage(m_controller->getPixels()); - QPixmap rendered = m_rendered.scaledToHeight(m_rendered.height() * m_ui.magnification->value()); - m_ui.renderedView->setPixmap(rendered); } bool FrameView::eventFilter(QObject* obj, QEvent* event) { diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index 2a2b5f680..cce09a42c 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -16,6 +16,7 @@ #include #include "AssetView.h" +#include "ColorPicker.h" #include @@ -105,6 +106,8 @@ private: QPixmap m_composited; QPixmap m_rendered; mMapCacheEntry m_mapStatus[4][128 * 128] = {}; // TODO: Correct size + ColorPicker m_backdropPicker; + QColor m_overrideBackdrop; #ifdef M_CORE_GBA uint16_t m_gbaDispcnt; diff --git a/src/platform/qt/FrameView.ui b/src/platform/qt/FrameView.ui index c437b14f6..8cf75ec08 100644 --- a/src/platform/qt/FrameView.ui +++ b/src/platform/qt/FrameView.ui @@ -13,7 +13,7 @@ Inspect frame - + @@ -51,7 +51,63 @@ - + + + + + + + 0 + 0 + + + + + 32 + 32 + + + + true + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + Backdrop color + + + + + + + + + Disable scanline effects + + + + + + + + + + false + + + Export + + + + true @@ -90,65 +146,6 @@ - - - - true - - - - - 0 - 0 - 567 - 467 - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - false - - - Export - - - - - - - Disable scanline effects - - - From b99d8164ddba2e6f8fc16de941d1551674974e4c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2019 23:41:28 -0700 Subject: [PATCH 360/429] Qt: Initial mask support for transformed sprites --- include/mgba/internal/gba/video.h | 24 ++++++++++++------------ src/platform/qt/AssetView.cpp | 13 +++++++++++-- src/platform/qt/AssetView.h | 2 ++ src/platform/qt/FrameView.cpp | 8 ++++++-- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 908954aaf..ea65699aa 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -81,20 +81,20 @@ struct GBAObj { uint16_t d; }; +struct GBAOAMMatrix { + int16_t padding0[3]; + int16_t a; + int16_t padding1[3]; + int16_t b; + int16_t padding2[3]; + int16_t c; + int16_t padding3[3]; + int16_t d; +}; + union GBAOAM { struct GBAObj obj[128]; - - struct GBAOAMMatrix { - int16_t padding0[3]; - int16_t a; - int16_t padding1[3]; - int16_t b; - int16_t padding2[3]; - int16_t c; - int16_t padding3[3]; - int16_t d; - } mat[32]; - + struct GBAOAMMatrix mat[32]; uint16_t raw[512]; }; diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index c13af9403..97d44578d 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -204,9 +204,18 @@ bool AssetView::lookupObjGBA(int id, struct ObjInfo* info) { GBAObjAttributesCGetPriority(obj->c), GBAObjAttributesBGetX(obj->b), GBAObjAttributesAGetY(obj->a), - bool(GBAObjAttributesBIsHFlip(obj->b)), - bool(GBAObjAttributesBIsVFlip(obj->b)), + false, + false, }; + if (GBAObjAttributesAIsTransformed(obj->a)) { + int matIndex = GBAObjAttributesBGetMatIndex(obj->b); + const GBAOAMMatrix* mat = &gba->video.oam.mat[matIndex]; + QTransform invXform(mat->a / 256., mat->c / 256., mat->b / 256., mat->d / 256., 0, 0); + newInfo.xform = invXform.inverted(); + } else { + newInfo.hflip = bool(GBAObjAttributesBIsHFlip(obj->b)); + newInfo.vflip = bool(GBAObjAttributesBIsVFlip(obj->b)); + } GBARegisterDISPCNT dispcnt = gba->memory.io[0]; // FIXME: Register name can't be imported due to namespacing issues if (!GBARegisterDISPCNTIsObjCharacterMapping(dispcnt)) { newInfo.stride = 0x20 >> (GBAObjAttributesAGet256Color(obj->a)); diff --git a/src/platform/qt/AssetView.h b/src/platform/qt/AssetView.h index 779e22890..acc4a1454 100644 --- a/src/platform/qt/AssetView.h +++ b/src/platform/qt/AssetView.h @@ -6,6 +6,7 @@ #pragma once #include +#include #include #include @@ -58,6 +59,7 @@ protected: unsigned y : 9; bool hflip : 1; bool vflip : 1; + QTransform xform; bool operator!=(const ObjInfo&) const; }; diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 2dea0f08b..00cb56d0e 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -6,7 +6,6 @@ #include "FrameView.h" #include -#include #include #include @@ -177,6 +176,11 @@ void FrameView::updateTilesGBA(bool force) { if (info.hflip || info.vflip) { obj = obj.mirrored(info.hflip, info.vflip); } + if (!info.xform.isIdentity()) { + offset += QPointF(obj.width(), obj.height()) / 2; + obj = obj.transformed(info.xform); + offset -= QPointF(obj.width() / 2, obj.height() / 2); + } m_queue.append({ { LayerId::SPRITE, sprite }, !m_disabled.contains({ LayerId::SPRITE, sprite }), @@ -243,7 +247,7 @@ void FrameView::injectGBA() { } QPalette palette; gba->video.renderer->highlightColor = palette.color(QPalette::HighlightedText).rgb(); - gba->video.renderer->highlightAmount = sin(m_glowFrame * M_PI / 30) * 64 + 64; + gba->video.renderer->highlightAmount = sin(m_glowFrame * M_PI / 30) * 48 + 64; if (!m_overrideBackdrop.isValid()) { QRgb backdrop = M_RGB5_TO_RGB8(gba->video.palette[0]) | 0xFF000000; m_backdropPicker.setColor(backdrop); From 427e3a61029a8c49f7dbd4edc4ad4400f6427866 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Sun, 2 Jun 2019 11:35:42 +0200 Subject: [PATCH 361/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 485 +++++++++++++++++++++------------- 1 file changed, 303 insertions(+), 182 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index 28f090df8..fc55841be 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -254,6 +254,44 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Unterbrechen + + FrameView + + + Inspect frame + Bild beobachten + + + + × + × + + + + Magnification + Vergrößerung + + + + Freeze frame + Bild einfrieren + + + + Backdrop color + Hintergrundfarbe + + + + Disable scanline effects + Scanline-Effekte deaktivieren + + + + Export + Exportieren + + GIFView @@ -546,17 +584,17 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Maps - + × × - + Magnification Vergrößerung - + Export Exportieren @@ -1231,14 +1269,14 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::AssetTile - + %0%1%2 %0%1%2 - - - + + + 0x%0 (%1) 0x%0 (%1) @@ -1289,22 +1327,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -1317,6 +1355,49 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Fehler beim Öffnen der Spieldatei: %1 + + QGBA::FrameView + + + Export frame + Bild exportieren + + + + Portable Network Graphics (*.png) + Portable Network Graphics (*.png) + + + + None + Keine + + + + Background + Hintergrund + + + + Window + Fenster + + + + Sprite + Sprite + + + + Backdrop + Hintergrund + + + + %1 %2 + %1 %2 + + QGBA::GBAApp @@ -2909,47 +2990,87 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::MapView - + + Priority + Priorität + + + + + Map base + Map-Basis + + + + + Tile base + Tile-Basis + + + + Size + Größe + + + + + Offset + Versatz + + + + Xform + Xform + + + Map Addr. Map-Addr. - + Mirror Spiegel - + None Keiner - + Both Beidseitig - + Horizontal Horizontal - + Vertical Vertikal - + + + + N/A + N/A + + + Export map Map exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + Failed to open output PNG file: %1 Fehler beim Öffnen der Ausgabe-PNG-Datei: %1 @@ -3043,57 +3164,52 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::ObjView - - + + 0x%0 0x%0 - + Off Aus - + Normal Normal - + Trans Trans - + OBJWIN OBJWIN - + Invalid Ungültig - - + + N/A N/A - + Export sprite Sprite exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - - - Failed to open output PNG file: %1 - Fehler beim Öffnen der Ausgabe-PNG-Datei: %1 - QGBA::PaletteView @@ -3290,103 +3406,103 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::Window - + Game Boy Advance ROMs (%1) Game Boy Advance-ROMs (%1) - + Game Boy ROMs (%1) Game Boy-ROMs (%1) - + All ROMs (%1) Alle ROMs (%1) - + %1 Video Logs (*.mvl) %1 Video-Logs (*.mvl) - + Archives (%1) Archive (%1) - - - + + + Select ROM ROM auswählen - + Game Boy Advance save files (%1) Game Boy Advance-Speicherdateien (%1) - - - + + + Select save Speicherdatei wählen - + mGBA savestate files (%1) mGBA Savestate-Dateien (%1) - - + + Select savestate Savestate auswählen - + Select patch Patch wählen - + Patches (*.ips *.ups *.bps) Patches (*.ips *.ups *.bps) - + Select image Bild auswählen - + Image file (*.png *.gif *.jpg *.jpeg);;All files (*) Bild-Datei (*.png *.gif *.jpg *.jpeg);;Alle Dateien (*) - - + + GameShark saves (*.sps *.xps) GameShark-Speicherdaten (*.sps *.xps) - + Select video log Video-Log auswählen - + Video logs (*.mvl) Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3395,578 +3511,583 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + Undo save state Speichern des Savestate rückgängig machen - - + + State &%1 Savestate &%1 - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + &Next frame &Nächstes Bild - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + Step backwards Schrittweiser Rücklauf - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor - Solar-Sensor + Sonnen-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Interframe blending Interframe-Überblendung - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Record GIF... GIF aufzeichen... - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - - Game &Pak sensors... - Game &Pak-Sensoren... - - - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... - + Select folder Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + About... Über... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video aufzeichnen... - + + Game Pak sensors... + Spielmodul-Sensoren... + + + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + + &Frame inspector... + &Bildbetrachter... + + + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Record debug video log... Video-Protokoll aufzeichnen... - + Stop debug video log Aufzeichnen des Video-Protokolls beenden - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links From 00e8b9877f76420e1e85c34cc2a156d1a52b8a30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2019 15:56:21 -0700 Subject: [PATCH 362/429] Qt: Add reset button to frame inspector --- src/platform/qt/FrameView.cpp | 10 +++++++ src/platform/qt/FrameView.h | 1 + src/platform/qt/FrameView.ui | 51 ++++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 00cb56d0e..5c13f2b77 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -64,6 +64,7 @@ FrameView::FrameView(std::shared_ptr controller, QWidget* parent invalidateQueue(); }); connect(m_ui.exportButton, &QAbstractButton::pressed, this, &FrameView::exportFrame); + connect(m_ui.reset, &QAbstractButton::pressed, this, &FrameView::reset); m_backdropPicker = ColorPicker(m_ui.backdrop, QColor(0, 0, 0, 0)); connect(&m_backdropPicker, &ColorPicker::colorChanged, this, [this](const QColor& color) { @@ -432,6 +433,15 @@ void FrameView::exportFrame() { m_framebuffer.save(filename, "PNG"); } +void FrameView::reset() { + m_disabled.clear(); + for (Layer& layer : m_queue) { + layer.enabled = true; + } + m_overrideBackdrop = QColor(); + invalidateQueue(); +} + QString FrameView::LayerId::readable() const { QString typeStr; switch (type) { diff --git a/src/platform/qt/FrameView.h b/src/platform/qt/FrameView.h index cce09a42c..e47e82054 100644 --- a/src/platform/qt/FrameView.h +++ b/src/platform/qt/FrameView.h @@ -39,6 +39,7 @@ public slots: void selectLayer(const QPointF& coord); void disableLayer(const QPointF& coord); void exportFrame(); + void reset(); protected: #ifdef M_CORE_GBA diff --git a/src/platform/qt/FrameView.ui b/src/platform/qt/FrameView.ui index 8cf75ec08..80b184561 100644 --- a/src/platform/qt/FrameView.ui +++ b/src/platform/qt/FrameView.ui @@ -13,7 +13,7 @@ Inspect frame - + @@ -87,27 +87,7 @@ - - - - Disable scanline effects - - - - - - - - - - false - - - Export - - - - + true @@ -146,6 +126,33 @@ + + + + Disable scanline effects + + + + + + + + + + false + + + Export + + + + + + + Reset + + + From ff735e35b77c2ee4246ed0413605a45ed6158847 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2019 17:21:44 -0700 Subject: [PATCH 363/429] GB: mVL-related fixes --- src/gb/core.c | 2 ++ src/gb/video.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gb/core.c b/src/gb/core.c index 9c00519a0..87eedfd40 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -984,6 +984,7 @@ static void _GBVLPStartFrameCallback(void *context) { GBVideoProxyRendererUnshim(&gb->video, &gbcore->proxyRenderer); mVideoLogContextRewind(gbcore->logContext, core); GBVideoProxyRendererShim(&gb->video, &gbcore->proxyRenderer); + gb->earlyExit = true; } } @@ -999,6 +1000,7 @@ static bool _GBVLPInit(struct mCore* core) { gbcore->logCallbacks.videoFrameStarted = _GBVLPStartFrameCallback; gbcore->logCallbacks.context = core; core->addCoreCallbacks(core, &gbcore->logCallbacks); + core->videoLogger = gbcore->proxyRenderer.logger; return true; } diff --git a/src/gb/video.c b/src/gb/video.c index 8aa978292..cfe80f913 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -343,19 +343,19 @@ void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLat mTimingSchedule(timing, &video->frameEvent, 4 - ((video->p->cpu->executionState + 1) & 3)); return; } + if (!GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC])) { + mTimingSchedule(timing, &video->frameEvent, GB_VIDEO_TOTAL_LENGTH); + } - GBFrameEnded(video->p); - mCoreSyncPostFrame(video->p->sync); --video->frameskipCounter; if (video->frameskipCounter < 0) { video->renderer->finishFrame(video->renderer); video->frameskipCounter = video->frameskip; } + GBFrameEnded(video->p); + mCoreSyncPostFrame(video->p->sync); ++video->frameCounter; - if (!GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC])) { - mTimingSchedule(timing, &video->frameEvent, GB_VIDEO_TOTAL_LENGTH); - } GBFrameStarted(video->p); } From cffff67c4989c391ea30f6cc6647fa46bd17cb9a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2019 22:57:23 -0700 Subject: [PATCH 364/429] Qt: Better handling of GB sprite coords --- src/platform/qt/AssetView.cpp | 6 +++--- src/platform/qt/AssetView.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index 97d44578d..f77b779bb 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -260,10 +260,10 @@ bool AssetView::lookupObjGB(int id, struct ObjInfo* info) { palette, 0, 2, - obj->y != 0 && obj->y < 160, + obj->y != 0 && obj->y < 160 && obj->x != 0 && obj->x < 168, GBObjAttributesGetPriority(obj->attr), - obj->x, - obj->y, + obj->x - 8, + obj->y - 16, bool(GBObjAttributesIsXFlip(obj->attr)), bool(GBObjAttributesIsYFlip(obj->attr)), }; diff --git a/src/platform/qt/AssetView.h b/src/platform/qt/AssetView.h index acc4a1454..c3d3a92b2 100644 --- a/src/platform/qt/AssetView.h +++ b/src/platform/qt/AssetView.h @@ -55,8 +55,8 @@ protected: bool enabled : 1; unsigned priority : 2; - unsigned x : 9; - unsigned y : 9; + int x : 10; + int y : 10; bool hflip : 1; bool vflip : 1; QTransform xform; From c6b61d512382169d771fc3a0e8202352289a7f3b Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Mon, 3 Jun 2019 18:32:13 +0200 Subject: [PATCH 365/429] Qt: Update German GUI translation Add translation for the "Reset" string in FrameView --- src/platform/qt/ts/mgba-de.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index fc55841be..baba6f57c 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -282,15 +282,20 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Hintergrundfarbe - + Disable scanline effects Scanline-Effekte deaktivieren - + Export Exportieren + + + Reset + Zurücksetzen + GIFView @@ -1358,42 +1363,42 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::FrameView - + Export frame Bild exportieren - + Portable Network Graphics (*.png) Portable Network Graphics (*.png) - + None Keine - + Background Hintergrund - + Window Fenster - + Sprite Sprite - + Backdrop Hintergrund - + %1 %2 %1 %2 From 982bc486b0dac7ae7fb91e58b28d8f5dc5364c03 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2019 09:49:54 -0700 Subject: [PATCH 366/429] Feature: Fix video logger with no channel backing --- src/feature/video-logger.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index a2884a107..a240d2c33 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -293,7 +293,7 @@ void mVideoLoggerWriteBuffer(struct mVideoLogger* logger, uint32_t bufferId, uin bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block) { struct mVideoLogChannel* channel = logger->dataContext; uint32_t ignorePackets = 0; - if (channel->injectionPoint == LOGGER_INJECTION_IMMEDIATE && !channel->injecting) { + if (channel && channel->injectionPoint == LOGGER_INJECTION_IMMEDIATE && !channel->injecting) { mVideoLoggerRendererRunInjected(logger); ignorePackets = channel->ignorePackets; } @@ -304,7 +304,7 @@ bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block) { } switch (item.type) { case DIRTY_SCANLINE: - if (channel->injectionPoint == LOGGER_INJECTION_FIRST_SCANLINE && !channel->injecting && item.address == 0) { + if (channel && channel->injectionPoint == LOGGER_INJECTION_FIRST_SCANLINE && !channel->injecting && item.address == 0) { mVideoLoggerRendererRunInjected(logger); ignorePackets = channel->ignorePackets; } From 2ef05b9aad15e43a9898bd427b7160d51f313ab0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2019 11:16:48 -0700 Subject: [PATCH 367/429] Python: cffi 1.12.3 is broken --- src/platform/python/setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/python/setup.py b/src/platform/python/setup.py index c9030313c..e610f551f 100644 --- a/src/platform/python/setup.py +++ b/src/platform/python/setup.py @@ -21,8 +21,8 @@ setup( author_email="jeffrey@endrift.com", url="http://github.com/mgba-emu/mgba/", packages=["mgba"], - setup_requires=['cffi>=1.6', 'pytest-runner'], - install_requires=['cffi>=1.6', 'cached-property'], + setup_requires=['cffi>=1.6,!=1.12.3', 'pytest-runner'], + install_requires=['cffi>=1.6,!=1.12.3', 'cached-property'], extras_require={'pil': ['Pillow>=2.3'], 'cinema': ['pyyaml', 'pytest']}, tests_require=['pytest'], cffi_modules=["_builder.py:ffi"], From a1cdd65e19e73e4ddfbd828582f83d6fb0c48fe0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2019 11:46:57 -0700 Subject: [PATCH 368/429] GBA Video: Add missing initializers --- src/gba/extra/proxy.c | 11 +++++++++++ src/gba/renderers/gl.c | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 6121f4f99..196329036 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -44,6 +44,17 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.highlightBG[0] = false; + renderer->d.highlightBG[1] = false; + renderer->d.highlightBG[2] = false; + renderer->d.highlightBG[3] = false; + int i; + for (i = 0; i < 128; ++i) { + renderer->d.highlightOBJ[i] = false; + } + renderer->d.highlightColor = 0xFFFFFF; + renderer->d.highlightAmount = 0; + renderer->logger->context = renderer; renderer->logger->parsePacket = _parsePacket; renderer->logger->handleEvent = _handleEvent; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 97acc8e02..952467eea 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -651,6 +651,17 @@ void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { renderer->d.disableBG[3] = false; renderer->d.disableOBJ = false; + renderer->d.highlightBG[0] = false; + renderer->d.highlightBG[1] = false; + renderer->d.highlightBG[2] = false; + renderer->d.highlightBG[3] = false; + int i; + for (i = 0; i < 128; ++i) { + renderer->d.highlightOBJ[i] = false; + } + renderer->d.highlightColor = 0xFFFFFF; + renderer->d.highlightAmount = 0; + renderer->scale = 1; } From 4a2d8d078b14485772909ec157414282043189af Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2019 15:40:41 -0700 Subject: [PATCH 369/429] GBA Video: Fix color normalization in GL --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 952467eea..1153d2d3c 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -1380,7 +1380,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { glScissor(0, glRenderer->firstY, 1, y - glRenderer->firstY + 1); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); - glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xFF) / 256., ((backdrop >> 8) & 0xFF) / 256., (backdrop & 0xFF) / 256., 1.f }); + glClearBufferfv(GL_COLOR, 0, (GLfloat[]) { ((backdrop >> 16) & 0xF8) / 248., ((backdrop >> 8) & 0xF8) / 248., (backdrop & 0xF8) / 248., 1.f }); glClearBufferiv(GL_COLOR, 1, (GLint[]) { 32, glRenderer->target1Bd | (glRenderer->target2Bd * 2) | (glRenderer->blendEffect * 4), glRenderer->blda, 0 }); glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); From 42818c764da9400a8dc9aef368711c786cff5884 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 12:53:04 -0700 Subject: [PATCH 370/429] GBA Core: Separate mVL proxy from generic proxy --- src/gba/core.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 67864c409..98d4d036a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -133,6 +133,7 @@ struct GBACore { #if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBAVideoGLRenderer glRenderer; #endif + struct GBAVideoProxyRenderer vlProxy; struct GBAVideoProxyRenderer proxyRenderer; struct mVideoLogContext* logContext; struct mCoreCallbacks logCallbacks; @@ -188,6 +189,7 @@ static bool _GBACoreInit(struct mCore* core) { #ifndef DISABLE_THREADING mVideoThreadProxyCreate(&gbacore->threadProxy); #endif + gbacore->vlProxy.logger = NULL; gbacore->proxyRenderer.logger = NULL; gbacore->keys = 0; @@ -978,22 +980,22 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c state->cpu.gprs[ARM_PC] = BASE_WORKING_RAM; int channelId = mVideoLoggerAddChannel(context); - gbacore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->proxyRenderer.logger, false); - mVideoLoggerAttachChannel(gbacore->proxyRenderer.logger, context, channelId); - gbacore->proxyRenderer.logger->block = false; + gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); + mVideoLoggerRendererCreate(gbacore->vlProxy.logger, false); + mVideoLoggerAttachChannel(gbacore->vlProxy.logger, context, channelId); + gbacore->vlProxy.logger->block = false; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, &gbacore->renderer.d); - GBAVideoProxyRendererShim(&gba->video, &gbacore->proxyRenderer); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, gba->video.renderer); + GBAVideoProxyRendererShim(&gba->video, &gbacore->vlProxy); } static void _GBACoreEndVideoLog(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = core->board; - if (gbacore->proxyRenderer.logger) { - GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); - free(gbacore->proxyRenderer.logger); - gbacore->proxyRenderer.logger = NULL; + if (gbacore->vlProxy.logger) { + GBAVideoProxyRendererUnshim(&gba->video, &gbacore->vlProxy); + free(gbacore->vlProxy.logger); + gbacore->vlProxy.logger = NULL; } } #endif @@ -1090,10 +1092,10 @@ static void _GBAVLPStartFrameCallback(void *context) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = core->board; - if (!mVideoLoggerRendererRun(gbacore->proxyRenderer.logger, true)) { - GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); + if (!mVideoLoggerRendererRun(gbacore->vlProxy.logger, true)) { + GBAVideoProxyRendererUnshim(&gba->video, &gbacore->vlProxy); mVideoLogContextRewind(gbacore->logContext, core); - GBAVideoProxyRendererShim(&gba->video, &gbacore->proxyRenderer); + GBAVideoProxyRendererShim(&gba->video, &gbacore->vlProxy); gba->earlyExit = true; } } @@ -1103,14 +1105,14 @@ static bool _GBAVLPInit(struct mCore* core) { if (!_GBACoreInit(core)) { return false; } - gbacore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->proxyRenderer.logger, true); - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, NULL); + gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); + mVideoLoggerRendererCreate(gbacore->vlProxy.logger, true); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, NULL); memset(&gbacore->logCallbacks, 0, sizeof(gbacore->logCallbacks)); gbacore->logCallbacks.videoFrameStarted = _GBAVLPStartFrameCallback; gbacore->logCallbacks.context = core; core->addCoreCallbacks(core, &gbacore->logCallbacks); - core->videoLogger = gbacore->proxyRenderer.logger; + core->videoLogger = gbacore->vlProxy.logger; return true; } @@ -1125,8 +1127,8 @@ static void _GBAVLPDeinit(struct mCore* core) { static void _GBAVLPReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; - if (gba->video.renderer == &gbacore->proxyRenderer.d) { - GBAVideoProxyRendererUnshim(&gba->video, &gbacore->proxyRenderer); + if (gba->video.renderer == &gbacore->vlProxy.d) { + GBAVideoProxyRendererUnshim(&gba->video, &gbacore->vlProxy); } else if (gbacore->renderer.outputBuffer) { struct GBAVideoRenderer* renderer = &gbacore->renderer.d; GBAVideoAssociateRenderer(&gba->video, renderer); @@ -1134,7 +1136,7 @@ static void _GBAVLPReset(struct mCore* core) { ARMReset(core->cpu); mVideoLogContextRewind(gbacore->logContext, core); - GBAVideoProxyRendererShim(&gba->video, &gbacore->proxyRenderer); + GBAVideoProxyRendererShim(&gba->video, &gbacore->vlProxy); // Make sure CPU loop never spins GBAHalt(gba); @@ -1150,7 +1152,7 @@ static bool _GBAVLPLoadROM(struct mCore* core, struct VFile* vf) { gbacore->logContext = NULL; return false; } - mVideoLoggerAttachChannel(gbacore->proxyRenderer.logger, gbacore->logContext, 0); + mVideoLoggerAttachChannel(gbacore->vlProxy.logger, gbacore->logContext, 0); return true; } From f2134e6b62dd18fe7245bda5674e0a1555c6a3ef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 12:56:50 -0700 Subject: [PATCH 371/429] Qt: Only allow one Frame Inspector to be open --- src/platform/qt/Window.cpp | 16 +++++++++++++++- src/platform/qt/Window.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index fc4d9a6e2..980506472 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1470,7 +1470,21 @@ void Window::setupMenu(QMenuBar* menubar) { addGameAction(tr("View &map..."), "mapWindow", openControllerTView(), "tools"); #ifdef M_CORE_GBA - Action* frameWindow = addGameAction(tr("&Frame inspector..."), "frameWindow", openControllerTView(), "tools"); + Action* frameWindow = addGameAction(tr("&Frame inspector..."), "frameWindow", [this]() { + if (!m_frameView) { + m_frameView = new FrameView(m_controller); + connect(this, &Window::shutdown, this, [this]() { + if (m_frameView) { + m_frameView->close(); + } + }); + connect(m_frameView, &QObject::destroyed, this, [this]() { + m_frameView = nullptr; + }); + m_frameView->setAttribute(Qt::WA_DeleteOnClose); + } + m_frameView->show(); + }, "tools"); m_platformActions.insert(PLATFORM_GBA, frameWindow); #endif diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 526a10496..b41944fa0 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -32,6 +32,7 @@ class CoreController; class CoreManager; class DebuggerConsoleController; class Display; +class FrameView; class GDBController; class GIFView; class LibraryController; @@ -215,6 +216,7 @@ private: std::unique_ptr m_overrideView; std::unique_ptr m_sensorView; + FrameView* m_frameView = nullptr; #ifdef USE_FFMPEG VideoView* m_videoView = nullptr; From d048917b72d008f0c0776cfc9f3defd9f6c72ef7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 14:20:10 -0700 Subject: [PATCH 372/429] Qt: Cap audio buffer size to 8192 --- CHANGES | 1 + src/platform/qt/SettingsView.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c49cc0538..ae38339f6 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Other fixes: - Switch: Fix threading-related crash on second launch - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) - Core: Fix crashes if core directories aren't set + - Qt: Cap audio buffer size to 8192 (fixes mgba.io/i/1433) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 75a639b8a..62a1d43f0 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -369,7 +369,6 @@ void SettingsView::updateConfig() { saveSetting("useCgbColors", m_ui.useCgbColors); saveSetting("useBios", m_ui.useBios); saveSetting("skipBios", m_ui.skipBios); - saveSetting("audioBuffers", m_ui.audioBufferSize); saveSetting("sampleRate", m_ui.sampleRate); saveSetting("videoSync", m_ui.videoSync); saveSetting("audioSync", m_ui.audioSync); @@ -407,6 +406,11 @@ void SettingsView::updateConfig() { saveSetting("useDiscordPresence", m_ui.useDiscordPresence); saveSetting("gba.audioHle", m_ui.audioHle); + if (m_ui.audioBufferSize->currentText().toInt() > 8192) { + m_ui.audioBufferSize->setCurrentText("8192"); + } + saveSetting("audioBuffers", m_ui.audioBufferSize); + if (m_ui.fastForwardUnbounded->isChecked()) { saveSetting("fastForwardRatio", "-1"); } else { From 4787eb29c5d953bac921281edae17920e149cb62 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 16:21:53 -0700 Subject: [PATCH 373/429] GBA SIO: Stop using bitfield structs --- include/mgba/internal/gba/sio.h | 48 +++++++++++++-------------------- src/gba/extra/battlechip.c | 12 ++++----- src/gba/hardware.c | 4 +-- src/gba/sio/lockstep.c | 38 +++++++++++++------------- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/include/mgba/internal/gba/sio.h b/include/mgba/internal/gba/sio.h index 07ede7009..df4cd2f7a 100644 --- a/include/mgba/internal/gba/sio.h +++ b/include/mgba/internal/gba/sio.h @@ -33,6 +33,23 @@ enum { JOYSTAT_RECV_BIT = 2, }; +DECL_BITFIELD(GBASIONormal, uint16_t); +DECL_BIT(GBASIONormal, Sc, 0); +DECL_BIT(GBASIONormal, InternalSc, 1); +DECL_BIT(GBASIONormal, Si, 2); +DECL_BIT(GBASIONormal, IdleSo, 3); +DECL_BIT(GBASIONormal, Start, 7); +DECL_BIT(GBASIONormal, Length, 12); +DECL_BIT(GBASIONormal, Irq, 14); +DECL_BITFIELD(GBASIOMultiplayer, uint16_t); +DECL_BITS(GBASIOMultiplayer, Baud, 0, 2); +DECL_BIT(GBASIOMultiplayer, Slave, 2); +DECL_BIT(GBASIOMultiplayer, Ready, 3); +DECL_BITS(GBASIOMultiplayer, Id, 4, 2); +DECL_BIT(GBASIOMultiplayer, Error, 6); +DECL_BIT(GBASIOMultiplayer, Busy, 8); +DECL_BIT(GBASIOMultiplayer, Irq, 14); + struct GBASIODriverSet { struct GBASIODriver* normal; struct GBASIODriver* multiplayer; @@ -47,36 +64,7 @@ struct GBASIO { struct GBASIODriver* activeDriver; uint16_t rcnt; - // TODO: Convert to bitfields - union { - struct { - unsigned sc : 1; - unsigned internalSc : 1; - unsigned si : 1; - unsigned idleSo : 1; - unsigned : 3; - unsigned start : 1; - unsigned : 4; - unsigned length : 1; - unsigned : 1; - unsigned irq : 1; - unsigned : 1; - } normalControl; - - struct { - unsigned baud : 2; - unsigned slave : 1; - unsigned ready : 1; - unsigned id : 2; - unsigned error : 1; - unsigned busy : 1; - unsigned : 6; - unsigned irq : 1; - unsigned : 1; - } multiplayerControl; - - uint16_t siocnt; - }; + uint16_t siocnt; }; void GBASIOInit(struct GBASIO* sio); diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index fb411eef5..ae8aedff0 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -87,7 +87,7 @@ void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { if (gate->d.p->mode == SIO_NORMAL_32) { cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; } else { - cycles = GBASIOCyclesPerTransfer[gate->d.p->multiplayerControl.baud][1]; + cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1]; } mTimingDeschedule(&gate->d.p->p->timing, &gate->event); mTimingSchedule(&gate->d.p->p->timing, &gate->event, cycles); @@ -100,8 +100,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle if (gate->d.p->mode == SIO_NORMAL_32) { gate->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = 0; gate->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0; - gate->d.p->normalControl.start = 0; - if (gate->d.p->normalControl.irq) { + gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt); + if (GBASIONormalIsIrq(gate->d.p->siocnt)) { GBARaiseIRQ(gate->d.p->p, IRQ_SIO, cyclesLate); } return; @@ -112,8 +112,8 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->p->memory.io[REG_SIOMULTI0 >> 1] = cmd; gate->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF; gate->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF; - gate->d.p->multiplayerControl.busy = 0; - gate->d.p->multiplayerControl.id = 0; + gate->d.p->siocnt = GBASIOMultiplayerClearBusy(gate->d.p->siocnt); + gate->d.p->siocnt = GBASIOMultiplayerSetId(gate->d.p->siocnt, 0); mLOG(GBA_BATTLECHIP, DEBUG, "Game: %04X (%i)", cmd, gate->state); @@ -193,7 +193,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle gate->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = reply; - if (gate->d.p->multiplayerControl.irq) { + if (GBASIOMultiplayerIsIrq(gate->d.p->siocnt)) { GBARaiseIRQ(gate->d.p->p, IRQ_SIO, cyclesLate); } } diff --git a/src/gba/hardware.c b/src/gba/hardware.c index c2c19d50e..dedbd9af3 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -584,10 +584,10 @@ void _gbpSioProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLat ++gbp->p->gbpTxPosition; gbp->p->p->memory.io[REG_SIODATA32_LO >> 1] = tx; gbp->p->p->memory.io[REG_SIODATA32_HI >> 1] = tx >> 16; - if (gbp->d.p->normalControl.irq) { + if (GBASIONormalIsIrq(gbp->d.p->siocnt)) { GBARaiseIRQ(gbp->p->p, IRQ_SIO, cyclesLate); } - gbp->d.p->normalControl.start = 0; + gbp->d.p->siocnt = GBASIONormalClearStart(gbp->d.p->siocnt); gbp->p->p->memory.io[REG_SIOCNT >> 1] = gbp->d.p->siocnt & ~0x0080; } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 356fa130a..506854a7e 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -71,7 +71,7 @@ void GBASIOLockstepDetachNode(struct GBASIOLockstep* lockstep, struct GBASIOLock bool GBASIOLockstepNodeInit(struct GBASIODriver* driver) { struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver; - node->d.p->multiplayerControl.slave = node->id > 0; + node->d.p->siocnt = GBASIOMultiplayerSetSlave(node->d.p->siocnt, node->id > 0); mLOG(GBA_SIO, DEBUG, "Lockstep %i: Node init", node->id); node->event.context = node; node->event.name = "GBA SIO Lockstep"; @@ -99,10 +99,10 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; node->d.p->rcnt |= 3; ATOMIC_ADD(node->p->attachedMulti, 1); - node->d.p->multiplayerControl.ready = node->p->attachedMulti == node->p->d.attached; + node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); if (node->id) { node->d.p->rcnt |= 4; - node->d.p->multiplayerControl.slave = 1; + node->d.p->siocnt = GBASIOMultiplayerFillSlave(node->d.p->siocnt); } break; case SIO_NORMAL_32: @@ -178,10 +178,10 @@ static uint16_t GBASIOLockstepNodeMultiWriteRegister(struct GBASIODriver* driver ATOMIC_LOAD(transferActive, node->p->d.transferActive); if (value & 0x0080 && transferActive == TRANSFER_IDLE) { - if (!node->id && node->d.p->multiplayerControl.ready) { + if (!node->id && GBASIOMultiplayerIsReady(node->d.p->siocnt)) { mLOG(GBA_SIO, DEBUG, "Lockstep %i: Transfer initiated", node->id); ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); - ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[node->d.p->multiplayerControl.baud][node->p->d.attached - 1]); + ATOMIC_STORE(node->p->d.transferCycles, GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][node->p->d.attached - 1]); bool scheduled = mTimingIsScheduled(&driver->p->p->timing, &node->event); int oldWhen = node->event.when; @@ -220,37 +220,37 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { sio->p->memory.io[REG_SIOMULTI2 >> 1] = node->p->multiRecv[2]; sio->p->memory.io[REG_SIOMULTI3 >> 1] = node->p->multiRecv[3]; sio->rcnt |= 1; - sio->multiplayerControl.busy = 0; - sio->multiplayerControl.id = node->id; - if (sio->multiplayerControl.irq) { + sio->siocnt = GBASIOMultiplayerClearBusy(sio->siocnt); + sio->siocnt = GBASIOMultiplayerSetId(sio->siocnt, node->id); + if (GBASIOMultiplayerIsIrq(sio->siocnt)) { GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; case SIO_NORMAL_8: // TODO - sio->normalControl.start = 0; + sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { - sio->normalControl.si = node->p->players[node->id - 1]->d.p->normalControl.idleSo; + sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); node->d.p->p->memory.io[REG_SIODATA8 >> 1] = node->p->normalRecv[node->id - 1] & 0xFF; } else { node->d.p->p->memory.io[REG_SIODATA8 >> 1] = 0xFFFF; } - if (sio->multiplayerControl.irq) { + if (GBASIONormalIsIrq(sio->siocnt)) { GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; case SIO_NORMAL_32: // TODO - sio->normalControl.start = 0; + sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { - sio->normalControl.si = node->p->players[node->id - 1]->d.p->normalControl.idleSo; + sio->siocnt = GBASIONormalSetSi(sio->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); node->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = node->p->normalRecv[node->id - 1]; node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] |= node->p->normalRecv[node->id - 1] >> 16; } else { node->d.p->p->memory.io[REG_SIODATA32_LO >> 1] = 0xFFFF; node->d.p->p->memory.io[REG_SIODATA32_HI >> 1] = 0xFFFF; } - if (sio->multiplayerControl.irq) { + if (GBASIONormalIsIrq(sio->siocnt)) { GBARaiseIRQ(sio->p, IRQ_SIO, 0); } break; @@ -278,7 +278,7 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { case TRANSFER_IDLE: // If the master hasn't initiated a transfer, it can keep going. node->nextEvent += LOCKSTEP_INCREMENT; - node->d.p->multiplayerControl.ready = attachedMulti == attached; + node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); break; case TRANSFER_STARTING: // Start the transfer, but wait for the other GBAs to catch up @@ -352,11 +352,11 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { ATOMIC_LOAD(attachedMulti, node->p->attachedMulti); ATOMIC_LOAD(attached, node->p->d.attached); - node->d.p->multiplayerControl.ready = attachedMulti == attached; + node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); bool signal = false; switch (transferActive) { case TRANSFER_IDLE: - if (!node->d.p->multiplayerControl.ready) { + if (!GBASIOMultiplayerIsReady(node->d.p->siocnt)) { node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT); } break; @@ -376,7 +376,7 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { node->d.p->p->memory.io[REG_SIOMULTI1 >> 1] = 0xFFFF; node->d.p->p->memory.io[REG_SIOMULTI2 >> 1] = 0xFFFF; node->d.p->p->memory.io[REG_SIOMULTI3 >> 1] = 0xFFFF; - node->d.p->multiplayerControl.busy = 1; + node->d.p->siocnt = GBASIOMultiplayerFillBusy(node->d.p->siocnt); break; case SIO_NORMAL_8: node->p->multiRecv[node->id] = 0xFFFF; @@ -455,7 +455,7 @@ static uint16_t GBASIOLockstepNodeNormalWriteRegister(struct GBASIODriver* drive mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIOCNT <- %04x", node->id, value); value &= 0xFF8B; if (!node->id) { - driver->p->normalControl.si = 1; + driver->p->siocnt = GBASIONormalFillSi(driver->p->siocnt); } if (value & 0x0080 && !node->id) { // Internal shift clock From 5c11ea8c27810c7d9f556595d4b737fdcfe6a198 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 16:26:11 -0700 Subject: [PATCH 374/429] GBA: Work around CFFI regression --- include/mgba/internal/gba/hardware.h | 4 ++++ src/platform/python/_builder.py | 12 ++++++++++++ src/platform/python/setup.py | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/mgba/internal/gba/hardware.h b/include/mgba/internal/gba/hardware.h index 540a9fdf4..fab175538 100644 --- a/include/mgba/internal/gba/hardware.h +++ b/include/mgba/internal/gba/hardware.h @@ -66,6 +66,7 @@ DECL_BITS(RTCCommandData, Magic, 0, 4); DECL_BITS(RTCCommandData, Command, 4, 3); DECL_BIT(RTCCommandData, Reading, 7); +#ifndef PYCPARSE #pragma pack(push, 1) struct GBARTC { int32_t bytesRemaining; @@ -78,6 +79,9 @@ struct GBARTC { uint8_t time[7]; }; #pragma pack(pop) +#else +struct GBATRC; +#endif struct GBAGBPKeyCallback { struct mKeyCallback d; diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 43bcddc19..6b76ee698 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -65,6 +65,18 @@ for line in preprocessed.splitlines(): lines.append(line) ffi.cdef('\n'.join(lines)) +ffi.cdef(""" +struct GBARTC { + int32_t bytesRemaining; + int32_t transferStep; + int32_t bitsRead; + int32_t bits; + int32_t commandActive; + RTCCommandData command; + RTCControl control; + uint8_t time[7]; +};""", packed=True) + preprocessed = subprocess.check_output(cpp + ["-fno-inline", "-P"] + cppflags + [os.path.join(pydir, "lib.h")], universal_newlines=True) lines = [] diff --git a/src/platform/python/setup.py b/src/platform/python/setup.py index e610f551f..c9030313c 100644 --- a/src/platform/python/setup.py +++ b/src/platform/python/setup.py @@ -21,8 +21,8 @@ setup( author_email="jeffrey@endrift.com", url="http://github.com/mgba-emu/mgba/", packages=["mgba"], - setup_requires=['cffi>=1.6,!=1.12.3', 'pytest-runner'], - install_requires=['cffi>=1.6,!=1.12.3', 'cached-property'], + setup_requires=['cffi>=1.6', 'pytest-runner'], + install_requires=['cffi>=1.6', 'cached-property'], extras_require={'pil': ['Pillow>=2.3'], 'cinema': ['pyyaml', 'pytest']}, tests_require=['pytest'], cffi_modules=["_builder.py:ffi"], From 9b0e4af7b430ee1cd4bbc9b7a37768a820c2b236 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 20:38:44 -0700 Subject: [PATCH 375/429] GBA Video: Fix GL output ivec rank --- src/gba/renderers/gl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 1153d2d3c..01d9f118d 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -442,7 +442,7 @@ static const char* const _renderObj = "uniform ivec4 mosaic;\n" "OUT(0) out vec4 color;\n" "OUT(1) out ivec4 flags;\n" - "OUT(2) out ivec3 window;\n" + "OUT(2) out ivec4 window;\n" "vec4 renderTile(int tile, int paletteId, ivec2 localCoord);\n" @@ -467,7 +467,7 @@ static const char* const _renderObj = " color = pix;\n" " flags = inflags;\n" " gl_FragDepth = float(flags.x) / 16.;\n" - " window = objwin.yzw;\n" + " window = ivec4(objwin.yzw, 0);\n" "}"; static const struct GBAVideoGLUniform _uniformsWindow[] = { @@ -488,7 +488,7 @@ static const char* const _renderWindow = "uniform ivec3 flags;\n" "uniform ivec4 win0[160];\n" "uniform ivec4 win1[160];\n" - "OUT(0) out ivec3 window;\n" + "OUT(0) out ivec4 window;\n" "void crop(vec4 windowParams, int flags, inout ivec3 windowFlags) {\n" " bvec4 compare = lessThan(texCoord.xxyy, windowParams);\n" @@ -526,7 +526,7 @@ static const char* const _renderWindow = "void main() {\n" " int dispflags = (dispcnt & 0x1F) | 0x20;\n" " if ((dispcnt & 0xE0) == 0) {\n" - " window = ivec3(dispflags, blend);\n" + " window = ivec4(dispflags, blend, 0);\n" " } else {\n" " ivec3 windowFlags = ivec3(flags.z, blend);\n" " if ((dispcnt & 0x40) != 0) { \n" @@ -535,7 +535,7 @@ static const char* const _renderWindow = " if ((dispcnt & 0x20) != 0) { \n" " crop(interpolate(win0), flags.x, windowFlags);\n" " }\n" - " window = windowFlags;\n" + " window = ivec4(windowFlags, 0);\n" " }\n" "}\n"; From 9ac838d14df205480010d9aa6464ef2c6aa389f2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 4 Jun 2019 22:32:09 -0700 Subject: [PATCH 376/429] Switch: Option to use built-in brightness sensor for Boktai --- CHANGES | 1 + src/platform/switch/main.c | 50 +++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index ae38339f6..a96f51dcb 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Features: - Experimental high level "XQ" audio for most GBA games - Interframe blending for games that use flicker effects - Frame inspector for dissecting and debugging rendering + - Switch: Option to use built-in brightness sensor for Boktai Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 86d6abdfb..3b5124e83 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -99,6 +99,8 @@ static u8 vmode; static u32 vwidth; static u32 vheight; static bool interframeBlending = false; +static bool useLightSensor = true; +static struct mGUIRunnerLux lightSensor; static enum ScreenMode { SM_PA, @@ -268,6 +270,10 @@ static void _setup(struct mGUIRunner* runner) { runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); + if (runner->core->platform(runner->core) == PLATFORM_GBA && useLightSensor) { + runner->core->setPeripheral(runner->core, mPERIPH_GBA_LUMINANCE, &lightSensor.d); + } + unsigned mode; if (mCoreConfigGetUIntValue(&runner->config, "screenMode", &mode) && mode < SM_MAX) { screenMode = mode; @@ -292,6 +298,19 @@ static void _gameLoaded(struct mGUIRunner* runner) { if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { interframeBlending = fakeBool; } + if (mCoreConfigGetIntValue(&runner->config, "useLightSensor", &fakeBool)) { + if (useLightSensor != fakeBool) { + useLightSensor = fakeBool; + + if (runner->core->platform(runner->core) == PLATFORM_GBA) { + if (useLightSensor) { + runner->core->setPeripheral(runner->core, mPERIPH_GBA_LUMINANCE, &lightSensor.d); + } else { + runner->core->setPeripheral(runner->core, mPERIPH_GBA_LUMINANCE, &runner->luminanceSource.d); + } + } + } + } rumble.up = 0; rumble.down = 0; @@ -543,6 +562,18 @@ int32_t _readGyroZ(struct mRotationSource* source) { return sixaxis.gyroscope.z * -1.1e9f; } +static void _lightSensorSample(struct GBALuminanceSource* lux) { + struct mGUIRunnerLux* runnerLux = (struct mGUIRunnerLux*) lux; + float luxLevel = 0; + appletGetCurrentIlluminance(&luxLevel); + runnerLux->luxLevel = cbrtf(luxLevel) * 8; +} + +static uint8_t _lightSensorRead(struct GBALuminanceSource* lux) { + struct mGUIRunnerLux* runnerLux = (struct mGUIRunnerLux*) lux; + return 0xFF - runnerLux->luxLevel; +} + static int _batteryState(void) { u32 charge; int state = 0; @@ -690,6 +721,9 @@ int main(int argc, char* argv[]) { rotation.readTiltY = _readTiltY; rotation.readGyroZ = _readGyroZ; + lightSensor.d.readLuminance = _lightSensorRead; + lightSensor.d.sample = _lightSensorSample; + stream.videoDimensionsChanged = NULL; stream.postVideoFrame = NULL; stream.postAudioFrame = NULL; @@ -707,6 +741,9 @@ int main(int argc, char* argv[]) { audoutBuffer[i].data_offset = 0; } + bool illuminanceAvailable = false; + appletIsIlluminanceAvailable(&illuminanceAvailable); + struct mGUIRunner runner = { .params = { 1280, 720, @@ -829,8 +866,19 @@ int main(int argc, char* argv[]) { }, .nStates = 6 }, + { + .title = "Use built-in brightness sensor for Boktai", + .data = "useLightSensor", + .submenu = 0, + .state = illuminanceAvailable, + .validStates = (const char*[]) { + "Off", + "On", + }, + .nStates = 2 + }, }, - .nConfigExtra = 4, + .nConfigExtra = 5, .setup = _setup, .teardown = NULL, .gameLoaded = _gameLoaded, From c5fc0f0492e0c94128b2286b65ec5e2ab8d1211a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 5 Jun 2019 10:06:41 -0700 Subject: [PATCH 377/429] Qt: Remove excess memcpying (fixes #1437) --- src/platform/qt/CoreController.cpp | 30 ++++++++++-------------------- src/platform/qt/CoreController.h | 3 +-- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 4608a1b45..cd4195420 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -82,8 +82,7 @@ CoreController::CoreController(mCore* core, QObject* parent) controller->m_resetActions.clear(); if (!controller->m_hwaccel) { - controller->m_activeBuffer = &controller->m_buffers[0]; - context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer->data()), controller->screenDimensions().width()); + context->core->setVideoBuffer(context->core, reinterpret_cast(controller->m_activeBuffer.data()), controller->screenDimensions().width()); } QMetaObject::invokeMethod(controller, "didReset"); @@ -357,15 +356,12 @@ void CoreController::setLogger(LogController* logger) { void CoreController::start() { if (!m_hwaccel) { - QSize size(1024, 2048); - m_buffers[0].resize(size.width() * size.height() * sizeof(color_t)); - m_buffers[1].resize(size.width() * size.height() * sizeof(color_t)); - m_buffers[0].fill(0xFF); - m_buffers[1].fill(0xFF); - m_activeBuffer = &m_buffers[0]; - m_completeBuffer = m_buffers[0]; + QSize size(256, 224); + m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t)); + m_activeBuffer.fill(0xFF); + m_completeBuffer = m_activeBuffer; - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), size.width()); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), size.width()); } if (!m_patched) { @@ -884,17 +880,11 @@ int CoreController::updateAutofire() { void CoreController::finishFrame() { if (!m_hwaccel) { - QMutexLocker locker(&m_bufferMutex); - memcpy(m_completeBuffer.data(), m_activeBuffer->constData(), m_activeBuffer->size()); + unsigned width, height; + m_threadContext.core->desiredVideoDimensions(m_threadContext.core, &width, &height); - // TODO: Generalize this to triple buffering? - m_activeBuffer = &m_buffers[0]; - if (m_activeBuffer == m_completeBuffer) { - m_activeBuffer = &m_buffers[1]; - } - // Copy contents to avoid issues when doing frameskip - memcpy(m_activeBuffer->data(), m_completeBuffer.constData(), m_activeBuffer->size()); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer->data()), screenDimensions().width()); + QMutexLocker locker(&m_bufferMutex); + memcpy(m_completeBuffer.data(), m_activeBuffer.constData(), 256 * height * BYTES_PER_PIXEL); } QMutexLocker locker(&m_actionMutex); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 5463bf76b..e0ba677f7 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -201,8 +201,7 @@ private: bool m_patched = false; - QByteArray m_buffers[2]; - QByteArray* m_activeBuffer; + QByteArray m_activeBuffer; QByteArray m_completeBuffer; bool m_hwaccel = false; From e34c529f7edda021bcf6121b503eaf2f62eb9481 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 5 Jun 2019 12:55:30 -0700 Subject: [PATCH 378/429] Ports: Ability to enable or disable all SGB features (closes #1205) --- CHANGES | 1 + src/feature/gui/gui-config.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index a96f51dcb..1dbc740ea 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Features: - Interframe blending for games that use flicker effects - Frame inspector for dissecting and debugging rendering - Switch: Option to use built-in brightness sensor for Boktai + - Ports: Ability to enable or disable all SGB features (closes mgba.io/i/1205) Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index 484465b43..4695115a3 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -118,6 +118,20 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }, .nStates = 2 }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Enable SGB features", + .data = "sgb.model", + .submenu = 0, + .state = true, + .validStates = (const char*[]) { + "Off", "On" + }, + .stateMappings = (const struct GUIVariant[]) { + GUI_V_S("DMG"), + GUI_V_S("SGB"), + }, + .nStates = 2 + }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Enable SGB borders", .data = "sgb.borders", @@ -173,8 +187,6 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t continue; } if (item->stateMappings) { - item->state = 0; - size_t j; for (j = 0; j < item->nStates; ++j) { const struct GUIVariant* v = &item->stateMappings[j]; From 1a6b422b4c4ade66c97d589e8be7306f849fdb05 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 5 Jun 2019 22:04:55 -0700 Subject: [PATCH 379/429] CMake: Fix libretro version-info dep (fixes #1438) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccebef30..50ec9fc3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -998,7 +998,7 @@ endif() if(BUILD_LIBRETRO) file(GLOB RETRO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/libretro/*.c) add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC}) - add_dependencies(${BINARY_NAME} version-info) + add_dependencies(${BINARY_NAME}_libretro version-info) set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) if(MSVC) From 9b9aeb0c2bd76a1f8bb8d6d0fc6b20c7432bbaed Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 14:14:14 -0700 Subject: [PATCH 380/429] GBA Core: Fix libretro build (fixes #1439) --- src/gba/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gba/core.c b/src/gba/core.c index 98d4d036a..20c08779e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -133,9 +133,11 @@ struct GBACore { #if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBAVideoGLRenderer glRenderer; #endif +#ifndef MINIMAL_CORE struct GBAVideoProxyRenderer vlProxy; struct GBAVideoProxyRenderer proxyRenderer; struct mVideoLogContext* logContext; +#endif struct mCoreCallbacks logCallbacks; #ifndef DISABLE_THREADING struct mVideoThreadProxy threadProxy; @@ -167,7 +169,9 @@ static bool _GBACoreInit(struct mCore* core) { gbacore->overrides = NULL; gbacore->debuggerPlatform = NULL; gbacore->cheatDevice = NULL; +#ifndef MINIMAL_CORE gbacore->logContext = NULL; +#endif gbacore->audioMixer = NULL; GBACreate(gba); @@ -189,8 +193,10 @@ static bool _GBACoreInit(struct mCore* core) { #ifndef DISABLE_THREADING mVideoThreadProxyCreate(&gbacore->threadProxy); #endif +#ifndef MINIMAL_CORE gbacore->vlProxy.logger = NULL; gbacore->proxyRenderer.logger = NULL; +#endif gbacore->keys = 0; gba->keySource = &gbacore->keys; @@ -466,11 +472,13 @@ static void _GBACoreReset(struct mCore* core) { } } #endif +#ifndef MINIMAL_CORE if (core->videoLogger) { gbacore->proxyRenderer.logger = core->videoLogger; GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); renderer = &gbacore->proxyRenderer.d; } +#endif GBAVideoAssociateRenderer(&gba->video, renderer); } From 7b12516df45ac2bfc0597d6a584e80f8b4721255 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 15:54:35 -0700 Subject: [PATCH 381/429] Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes #1292) --- CHANGES | 1 + src/platform/psp2/main.c | 14 +++++++------- src/platform/psp2/psp2-context.c | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index 1dbc740ea..c3ed94cd7 100644 --- a/CHANGES +++ b/CHANGES @@ -51,6 +51,7 @@ Misc: - Qt: Improve sync code - Switch: Dynamic display resizing - Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424) + - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) 0.7.2: (2019-05-25) Emulation fixes: diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index 4dad587d8..594d9942f 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -41,7 +41,7 @@ static void _drawEnd(void) { static uint32_t _pollInput(const struct mInputMap* map) { SceCtrlData pad; - sceCtrlPeekBufferPositive(0, &pad, 1); + sceCtrlPeekBufferPositiveExt2(0, &pad, 1); int input = mInputMapKeyBits(map, PSP2_INPUT, pad.buttons, 0); if (pad.buttons & SCE_CTRL_UP || pad.ly < 64) { @@ -127,17 +127,17 @@ int main() { .id = PSP2_INPUT, .keyNames = (const char*[]) { "Select", - 0, - 0, + "L3", + "R3", "Start", "Up", "Right", "Down", "Left", - "L", - "R", - 0, // L2? - 0, // R2? + "L2", + "R2", + "L1", + "R1", "\1\xC", "\1\xA", "\1\xB", diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index f33738e65..8b5c6301d 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -267,7 +267,7 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig uint16_t mPSP2PollInput(struct mGUIRunner* runner) { SceCtrlData pad; - sceCtrlPeekBufferPositive(0, &pad, 1); + sceCtrlPeekBufferPositiveExt2(0, &pad, 1); int activeKeys = mInputMapKeyBits(&runner->core->inputMap, PSP2_INPUT, pad.buttons, 0); int angles = mInputMapAxis(&runner->core->inputMap, PSP2_INPUT, 0, pad.ly); @@ -313,8 +313,8 @@ void mPSP2Setup(struct mGUIRunner* runner) { mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_DOWN, GBA_KEY_DOWN); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_LEFT, GBA_KEY_LEFT); mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_RIGHT, GBA_KEY_RIGHT); - mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_LTRIGGER, GBA_KEY_L); - mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_RTRIGGER, GBA_KEY_R); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_L1, GBA_KEY_L); + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_R1, GBA_KEY_R); struct mInputAxis desc = { GBA_KEY_DOWN, GBA_KEY_UP, 192, 64 }; mInputBindAxis(&runner->core->inputMap, PSP2_INPUT, 0, &desc); @@ -398,6 +398,18 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { interframeBlending = fakeBool; } + // Backcompat: Old versions of mGBA use an older binding system that has different mappings for L/R + if (!sceKernelIsPSVitaTV()) { + int key = mInputMapKey(&runner->core->inputMap, PSP2_INPUT, __builtin_ctz(SCE_CTRL_L2)); + if (key >= 0) { + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_L1, key); + } + key = mInputMapKey(&runner->core->inputMap, PSP2_INPUT, __builtin_ctz(SCE_CTRL_R2)); + if (key >= 0) { + mPSP2MapKey(&runner->core->inputMap, SCE_CTRL_R1, key); + } + } + MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); memset(audioContext.buffer, 0, sizeof(audioContext.buffer)); From 81476720e2f0fc450ae2be62f7c888e774626715 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 16:15:07 -0700 Subject: [PATCH 382/429] GB Serialize: Fix loading non-BIOS state from BIOS (fixes #1280) --- CHANGES | 1 + include/mgba/internal/gb/gb.h | 1 + src/gb/gb.c | 19 +++++++++++-------- src/gb/io.c | 2 ++ src/gb/serialize.c | 16 ++++++++++++++++ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index c3ed94cd7..76d22caf6 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Other fixes: - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) - Core: Fix crashes if core directories aren't set - Qt: Cap audio buffer size to 8192 (fixes mgba.io/i/1433) + - GB Serialize: Fix loading non-BIOS state from BIOS (fixes mgba.io/i/1280) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/include/mgba/internal/gb/gb.h b/include/mgba/internal/gb/gb.h index ac9d6230d..7d007296a 100644 --- a/include/mgba/internal/gb/gb.h +++ b/include/mgba/internal/gb/gb.h @@ -150,6 +150,7 @@ void GBDestroy(struct GB* gb); void GBReset(struct LR35902Core* cpu); void GBSkipBIOS(struct GB* gb); +void GBMapBIOS(struct GB* gb); void GBUnmapBIOS(struct GB* gb); void GBDetectModel(struct GB* gb); diff --git a/src/gb/gb.c b/src/gb/gb.c index 5f5178a90..a03eb36ff 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -419,14 +419,7 @@ void GBReset(struct LR35902Core* cpu) { gb->biosVf->close(gb->biosVf); gb->biosVf = NULL; } else { - gb->biosVf->seek(gb->biosVf, 0, SEEK_SET); - gb->memory.romBase = malloc(GB_SIZE_CART_BANK0); - ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0); - memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size); - if (size > 0x100) { - memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge)); - } - + GBMapBIOS(gb); cpu->a = 0; cpu->f.packed = 0; cpu->c = 0; @@ -563,6 +556,16 @@ void GBSkipBIOS(struct GB* gb) { } } +void GBMapBIOS(struct GB* gb) { + gb->biosVf->seek(gb->biosVf, 0, SEEK_SET); + gb->memory.romBase = malloc(GB_SIZE_CART_BANK0); + ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0); + memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size); + if (size > 0x100) { + memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge)); + } +} + void GBUnmapBIOS(struct GB* gb) { if (gb->memory.romBase < gb->memory.rom || gb->memory.romBase > &gb->memory.rom[gb->memory.romSize - 1]) { free(gb->memory.romBase); diff --git a/src/gb/io.c b/src/gb/io.c index beecce12a..c7b08dd03 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -185,8 +185,10 @@ void GBIOReset(struct GB* gb) { GBIOWrite(gb, REG_NR51, 0xF3); if (!gb->biosVf) { GBIOWrite(gb, REG_LCDC, 0x91); + gb->memory.io[0x50] = 1; } else { GBIOWrite(gb, REG_LCDC, 0x00); + gb->memory.io[0x50] = 0xFF; } GBIOWrite(gb, REG_SCY, 0x00); GBIOWrite(gb, REG_SCX, 0x00); diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 7a4f5de4b..dfeced1ba 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -135,6 +135,16 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { if (ucheck16 >= 0x40) { mLOG(GB_STATE, WARN, "Savestate is corrupted: OCPS is out of range"); } + bool differentBios = !gb->biosVf || gb->model != state->model; + if (state->io[0x50] == 0xFF) { + if (differentBios) { + mLOG(GB_STATE, WARN, "Incompatible savestate, please restart with correct BIOS in %s mode", GBModelToName(state->model)); + error = true; + } else { + // TODO: Make it work correctly + mLOG(GB_STATE, WARN, "ILoading savestate in BIOS. This may not work correctly"); + } + } if (error) { return false; } @@ -187,6 +197,12 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { GBTimerDeserialize(&gb->timer, state); GBAudioDeserialize(&gb->audio, state); + if (gb->memory.io[0x50] == 0xFF) { + GBMapBIOS(gb); + } else { + GBUnmapBIOS(gb); + } + if (gb->model & GB_MODEL_SGB && canSgb) { GBSGBDeserialize(gb, state); } From 8c55de4b5f55c45182b78d815f741e597610021c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 16:27:52 -0700 Subject: [PATCH 383/429] README: Mention disco docker container --- README.md | 1 + README_DE.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 9042c0ead..803e1de0f 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,7 @@ This will produce a `build-win32` directory with the build products. Replace `mg - mgba/ubuntu:xenial - mgba/ubuntu:bionic - mgba/ubuntu:cosmic +- mgba/ubuntu:disco - mgba/vita - mgba/wii - mgba/windows:w32 diff --git a/README_DE.md b/README_DE.md index 172b5f826..8a1fae9ed 100644 --- a/README_DE.md +++ b/README_DE.md @@ -124,6 +124,7 @@ Dieser Befehl erzeugt ein Verzeichnis `build-win32` mit den erzeugten Programmda - mgba/ubuntu:xenial - mgba/ubuntu:bionic - mgba/ubuntu:cosmic +- mgba/ubuntu:disco - mgba/vita - mgba/wii - mgba/windows:w32 From ace3bd57f7274db5544a8714b136287622d4ade9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 18:38:25 -0700 Subject: [PATCH 384/429] GB Serialize: Fix typo --- src/gb/serialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gb/serialize.c b/src/gb/serialize.c index dfeced1ba..78d455300 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -142,7 +142,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { error = true; } else { // TODO: Make it work correctly - mLOG(GB_STATE, WARN, "ILoading savestate in BIOS. This may not work correctly"); + mLOG(GB_STATE, WARN, "Loading savestate in BIOS. This may not work correctly"); } } if (error) { From ff8f03ab74c20ce387dbbd20a57c317dfd225ab5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 23:36:35 -0700 Subject: [PATCH 385/429] GBA Video: Fix 512x512 backgrounds in GL --- src/gba/renderers/gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 01d9f118d..72ddd1d8c 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -155,7 +155,7 @@ static const char* const _renderMode0 = " if ((size & 1) == 1) {\n" " coord.y += coord.x & 256;\n" " }\n" - " coord &= ivec2(255, 511);\n" + " coord &= ivec2(255, 1023);\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int tileFlags = int(map.g * 15.9);\n" From e9aff885a267c228999958ea590441064951c289 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 6 Jun 2019 19:26:54 -0700 Subject: [PATCH 386/429] Vita: Add SGB cropping --- src/platform/psp2/psp2-context.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 8b5c6301d..7e96f24fb 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -56,6 +56,7 @@ static vita2d_texture* oldTex; static vita2d_texture* screenshot; static Thread audioThread; static bool interframeBlending = false; +static bool sgbCrop = false; static struct mSceRotationSource { struct mRotationSource d; @@ -365,6 +366,10 @@ void mPSP2Setup(struct mGUIRunner* runner) { if (mCoreConfigGetUIntValue(&runner->config, "camera", &mode)) { camera.cam = mode; } + int fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "sgb.borderCrop", &fakeBool)) { + sgbCrop = fakeBool; + } } void mPSP2LoadROM(struct mGUIRunner* runner) { @@ -473,8 +478,13 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { } int fakeBool; - mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool); - interframeBlending = fakeBool; + if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { + interframeBlending = fakeBool; + } + + if (mCoreConfigGetIntValue(&runner->config, "sgb.borderCrop", &fakeBool)) { + sgbCrop = fakeBool; + } } void mPSP2Teardown(struct mGUIRunner* runner) { @@ -519,6 +529,13 @@ void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded, bo vita2d_draw_texture_tint(backdrop, 0, 0, tint); // Fall through case SM_PLAIN: + if (sgbCrop && width == 256 && height == 224) { + w = 768; + h = 672; + scalex = 3; + scaley = 3; + break; + } w = 960 / width; h = 544 / height; if (w * height > 544) { @@ -533,6 +550,13 @@ void _drawTex(vita2d_texture* t, unsigned width, unsigned height, bool faded, bo scaley = scalex; break; case SM_ASPECT: + if (sgbCrop && width == 256 && height == 224) { + w = 967; + h = 846; + scalex = 34.0f / 9.0f; + scaley = scalex; + break; + } w = 960 / aspectw; h = 544 / aspecth; if (w * aspecth > 544) { From aab47e52f5261e714785c31c953f1a28ad8ad9ff Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 00:15:27 -0700 Subject: [PATCH 387/429] Qt: Fix Software display driver frame sizing --- src/platform/qt/DisplayGL.cpp | 1 - src/platform/qt/Window.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 86460606e..ad8f7ba4f 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -111,7 +111,6 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatio()); #endif resizePainter(); - connect(m_context.get(), &CoreController::didReset, this, &DisplayGL::resizeContext); } void DisplayGL::stopDrawing() { diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 980506472..8b7762a8b 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -906,6 +906,7 @@ void Window::reloadDisplayDriver() { connect(m_controller.get(), &CoreController::unpaused, m_display.get(), &Display::unpauseDrawing); connect(m_controller.get(), &CoreController::frameAvailable, m_display.get(), &Display::framePosted); connect(m_controller.get(), &CoreController::statusPosted, m_display.get(), &Display::showMessage); + connect(m_controller.get(), &CoreController::didReset, m_display.get(), &Display::resizeContext); attachWidget(m_display.get()); m_display->startDrawing(m_controller); @@ -1814,6 +1815,7 @@ void Window::setController(CoreController* controller, const QString& fname) { connect(m_controller.get(), &CoreController::unpaused, m_display.get(), &Display::unpauseDrawing); connect(m_controller.get(), &CoreController::frameAvailable, m_display.get(), &Display::framePosted); connect(m_controller.get(), &CoreController::statusPosted, m_display.get(), &Display::showMessage); + connect(m_controller.get(), &CoreController::didReset, m_display.get(), &Display::resizeContext); connect(m_controller.get(), &CoreController::unpaused, &m_inputController, &InputController::suspendScreensaver); connect(m_controller.get(), &CoreController::frameAvailable, this, &Window::recordFrame); From 101d80dca32cf2cab879600db2c6c959ea57c442 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 11:20:34 -0700 Subject: [PATCH 388/429] Switch: Add SGB cropping --- src/platform/switch/main.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 3b5124e83..c0624423d 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -6,6 +6,7 @@ #include "feature/gui/gui-runner.h" #include #include +#include #include #include #include @@ -99,6 +100,7 @@ static u8 vmode; static u32 vwidth; static u32 vheight; static bool interframeBlending = false; +static bool sgbCrop = false; static bool useLightSensor = true; static struct mGUIRunnerLux lightSensor; @@ -298,6 +300,9 @@ static void _gameLoaded(struct mGUIRunner* runner) { if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { interframeBlending = fakeBool; } + if (mCoreConfigGetIntValue(&runner->config, "sgb.borderCrop", &fakeBool)) { + sgbCrop = fakeBool; + } if (mCoreConfigGetIntValue(&runner->config, "useLightSensor", &fakeBool)) { if (useLightSensor != fakeBool) { useLightSensor = fakeBool; @@ -332,8 +337,14 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, glUseProgram(program); glBindVertexArray(vao); - float aspectX = width / (float) vwidth; - float aspectY = height / (float) vheight; + float inwidth = width; + float inheight = height; + if (sgbCrop && width == 256 && height == 224) { + inwidth = GB_VIDEO_HORIZONTAL_PIXELS; + inheight = GB_VIDEO_VERTICAL_PIXELS; + } + float aspectX = inwidth / vwidth; + float aspectY = inheight / vheight; float max = 1.f; switch (screenMode) { case SM_PA: @@ -359,6 +370,11 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, break; } + if (screenMode != SM_SF) { + aspectX = width / (float) vwidth; + aspectY = height / (float) vheight; + } + aspectX *= max; aspectY *= max; From ea4c16042422a2b0a3848fd990fe5f4e26e44530 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 11:32:52 -0700 Subject: [PATCH 389/429] Wii: Add SGB cropping --- src/platform/wii/main.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index eea6b17d6..20cd2445b 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -17,6 +17,7 @@ #include #include #include "feature/gui/gui-runner.h" +#include #include #include #include @@ -113,6 +114,7 @@ static uint16_t* rescaleTexmem; static GXTexObj rescaleTex; static uint16_t* interframeTexmem; static GXTexObj interframeTex; +static bool sgbCrop = false; static int32_t tiltX; static int32_t tiltY; static int32_t gyroZ; @@ -862,6 +864,9 @@ void _unpaused(struct mGUIRunner* runner) { if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { interframeBlending = fakeBool; } + if (mCoreConfigGetIntValue(&runner->config, "sgb.borderCrop", &fakeBool)) { + sgbCrop = fakeBool; + } float stretch; if (mCoreConfigGetFloatValue(&runner->config, "stretchWidth", &stretch)) { @@ -952,20 +957,25 @@ void _drawFrame(struct mGUIRunner* runner, bool faded) { } } - int hfactor = (vmode->fbWidth * wStretch) / (corew * wAdjust); - int vfactor = (vmode->efbHeight * hStretch) / (coreh * hAdjust); - if (hfactor > vfactor) { - scaleFactor = vfactor; - } else { - scaleFactor = hfactor; - } - if (screenMode == SM_PA) { + unsigned factorWidth = corew; + unsigned factorHeight = coreh; + if (sgbCrop && factorWidth == 256 && factorHeight == 224) { + factorWidth = GB_VIDEO_HORIZONTAL_PIXELS; + factorHeight = GB_VIDEO_VERTICAL_PIXELS; + } + + int hfactor = (vmode->fbWidth * wStretch) / (factorWidth * wAdjust); + int vfactor = (vmode->efbHeight * hStretch) / (factorHeight * hAdjust); + if (hfactor > vfactor) { + scaleFactor = vfactor; + } else { + scaleFactor = hfactor; + } + vertWidth *= scaleFactor; vertHeight *= scaleFactor; - } - if (screenMode == SM_PA) { _reproj(corew * scaleFactor, coreh * scaleFactor); } else { _reproj2(corew, coreh); From 62e39558485d896d794e912663915349f25ae390 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 12:11:57 -0700 Subject: [PATCH 390/429] 3DS: Add SGB cropping --- src/platform/3ds/main.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 9bd228a72..f5af6d50b 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -104,6 +104,7 @@ static bool frameStarted = false; static C3D_RenderTarget* upscaleBuffer; static C3D_Tex upscaleBufferTex; static bool interframeBlending = false; +static bool sgbCrop = false; static aptHookCookie cookie; static bool core2; @@ -382,6 +383,10 @@ static void _gameLoaded(struct mGUIRunner* runner) { if (mCoreConfigGetIntValue(&runner->config, "interframeBlending", &fakeBool)) { interframeBlending = fakeBool; } + + if (mCoreConfigGetIntValue(&runner->config, "sgb.borderCrop", &fakeBool)) { + sgbCrop = fakeBool; + } } static void _gameUnloaded(struct mGUIRunner* runner) { @@ -437,6 +442,12 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { int w = corew; int h = coreh; + if (sgbCrop && w == 256 && h == 224) { + w = GB_VIDEO_HORIZONTAL_PIXELS; + h = GB_VIDEO_VERTICAL_PIXELS; + } + int innerw = w; + int innerh = h; // Get greatest common divisor while (w != 0) { int temp = h % w; @@ -444,8 +455,8 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { w = temp; } int gcd = h; - unsigned aspectw = corew / gcd; - unsigned aspecth = coreh / gcd; + unsigned aspectw = innerw / gcd; + unsigned aspecth = innerh / gcd; int x = 0; int y = 0; @@ -517,6 +528,8 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { } ctrFlushBatch(); + innerw = corew; + innerh = coreh; corew = w; coreh = h; screen_h = 240; @@ -529,19 +542,20 @@ static void _drawTex(struct mCore* core, bool faded, bool both) { } ctrSetViewportSize(screen_w, screen_h, true); + float afw, afh; switch (screenMode) { default: return; case SM_AF_TOP: case SM_AF_BOTTOM: - w = screen_w / aspectw; - h = screen_h / aspecth; - if (w * aspecth > screen_h) { - w = aspectw * h; - h = aspecth * h; + afw = screen_w / (float) aspectw; + afh = screen_h / (float) aspecth; + if (afw * aspecth > screen_h) { + w = innerw * afh / gcd; + h = innerh * afh / gcd; } else { - h = aspecth * w; - w = aspectw * w; + h = innerh * afw / gcd; + w = innerw * afw / gcd; } break; case SM_SF_TOP: From 1928d2b5fc234df201165c6e2e137264822ffd74 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 12:13:20 -0700 Subject: [PATCH 391/429] Ports: Ability to crop SGB borders off screen (closes #1204) --- CHANGES | 1 + src/feature/gui/gui-config.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/CHANGES b/CHANGES index 76d22caf6..c2d7397ec 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Features: - Frame inspector for dissecting and debugging rendering - Switch: Option to use built-in brightness sensor for Boktai - Ports: Ability to enable or disable all SGB features (closes mgba.io/i/1205) + - Ports: Ability to crop SGB borders off screen (closes mgba.io/i/1204) Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index 4695115a3..37b239ba3 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -142,6 +142,16 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }, .nStates = 2 }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Crop SGB borders", + .data = "sgb.borderCrop", + .submenu = 0, + .state = false, + .validStates = (const char*[]) { + "Off", "On" + }, + .nStates = 2 + }; #endif size_t i; const char* mapNames[GUI_MAX_INPUTS + 1]; From 7d821d4f117d974cf0921b5526a5e92270f04f2c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 12:26:40 -0700 Subject: [PATCH 392/429] mGUI: Remmeber name and position of last loaded game --- CHANGES | 1 + include/mgba-util/gui/file-select.h | 2 +- src/feature/gui/gui-config.c | 8 ++++---- src/feature/gui/gui-runner.c | 10 +++++++++- src/util/gui/file-select.c | 17 ++++++++++------- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index c2d7397ec..bb3eb9e80 100644 --- a/CHANGES +++ b/CHANGES @@ -54,6 +54,7 @@ Misc: - Switch: Dynamic display resizing - Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424) - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) + - mGUI: Remember name and position of last loaded game 0.7.2: (2019-05-25) Emulation fixes: diff --git a/include/mgba-util/gui/file-select.h b/include/mgba-util/gui/file-select.h index 2b679b05a..fcbb7b789 100644 --- a/include/mgba-util/gui/file-select.h +++ b/include/mgba-util/gui/file-select.h @@ -14,7 +14,7 @@ CXX_GUARD_START struct VFile; -bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)); +bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*), const char* preselect); CXX_GUARD_END diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index 37b239ba3..ee14a019c 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -303,7 +303,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t } if (!strcmp(item->data, "gba.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), _biosNamed, GBAIsBIOS)) { + if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), _biosNamed, GBAIsBIOS, NULL)) { gbaBiosPath[0] = '\0'; } continue; @@ -311,21 +311,21 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t #ifdef M_CORE_GB if (!strcmp(item->data, "gb.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), _biosNamed, GBIsBIOS)) { + if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), _biosNamed, GBIsBIOS, NULL)) { gbBiosPath[0] = '\0'; } continue; } if (!strcmp(item->data, "gbc.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), _biosNamed, GBIsBIOS)) { + if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), _biosNamed, GBIsBIOS, NULL)) { gbcBiosPath[0] = '\0'; } continue; } if (!strcmp(item->data, "sgb.bios")) { // TODO: show box if failed - if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), _biosNamed, GBIsBIOS)) { + if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), _biosNamed, GBIsBIOS, NULL)) { sgbBiosPath[0] = '\0'; } continue; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 60a34d79e..038d30a3c 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -628,10 +628,18 @@ void mGUIRunloop(struct mGUIRunner* runner) { } while (true) { char path[PATH_MAX]; - if (!GUISelectFile(&runner->params, path, sizeof(path), _testExtensions, NULL)) { + const char* preselect = mCoreConfigGetValue(&runner->config, "lastGame"); + if (preselect) { + preselect = strrchr(preselect, '/'); + } + if (preselect) { + ++preselect; + } + if (!GUISelectFile(&runner->params, path, sizeof(path), _testExtensions, NULL, preselect)) { break; } mCoreConfigSetValue(&runner->config, "lastDirectory", runner->params.currentPath); + mCoreConfigSetValue(&runner->config, "lastGame", path); mCoreConfigSave(&runner->config); mGUIRun(runner, path); } diff --git a/src/util/gui/file-select.c b/src/util/gui/file-select.c index 5043a860c..2e6abaed5 100644 --- a/src/util/gui/file-select.c +++ b/src/util/gui/file-select.c @@ -47,7 +47,7 @@ static int _strpcmp(const void* a, const void* b) { return strcasecmp(((const struct GUIMenuItem*) a)->title, ((const struct GUIMenuItem*) b)->title); } -static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, struct GUIMenuItemList* currentFiles, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)) { +static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, struct GUIMenuItemList* currentFiles, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*), const char* preselect) { _cleanFiles(currentFiles); struct VDir* dir = VDirOpen(currentPath); @@ -144,6 +144,9 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, free((char*) testItem->title); GUIMenuItemListShift(currentFiles, item, 1); } else { + if (preselect && strncmp(testItem->title, preselect, PATH_MAX) == 0) { + params->fileIndex = item; + } ++item; } } @@ -152,14 +155,14 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, return true; } -bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*)) { +bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*), const char* preselect) { struct GUIMenu menu = { .title = "Select file", .subtitle = params->currentPath, - .index = params->fileIndex, }; GUIMenuItemListInit(&menu.items, 0); - _refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents); + _refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents, preselect); + menu.index = params->fileIndex; while (true) { struct GUIMenuItem* item; @@ -174,7 +177,7 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool continue; } _upDirectory(params->currentPath); - if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents)) { + if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents, NULL)) { break; } } else { @@ -187,7 +190,7 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool struct GUIMenuItemList newFiles; GUIMenuItemListInit(&newFiles, 0); - if (!_refreshDirectory(params, outPath, &newFiles, filterName, filterContents)) { + if (!_refreshDirectory(params, outPath, &newFiles, filterName, filterContents, NULL)) { _cleanFiles(&newFiles); GUIMenuItemListDeinit(&newFiles); _cleanFiles(&menu.items); @@ -208,7 +211,7 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool break; } _upDirectory(params->currentPath); - if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents)) { + if (!_refreshDirectory(params, params->currentPath, &menu.items, filterName, filterContents, NULL)) { break; } params->fileIndex = 0; From 5321ffd2277a277a3aafda23a5956c8c06b4d94f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 7 Jun 2019 12:46:38 -0700 Subject: [PATCH 393/429] Tools: Attempt to make perf.py work with Py3 --- tools/perf.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf.py b/tools/perf.py index 67453ddeb..b6fa04bcb 100755 --- a/tools/perf.py +++ b/tools/perf.py @@ -96,12 +96,15 @@ class PerfServer(object): subprocess.check_call(server_command) time.sleep(4) self.socket = socket.create_connection(self.address, timeout=1000) - self.reader = csv.DictReader(self.socket.makefile()) + kwargs = {} + if sys.version_info[0] >= 3: + kwargs["encoding"] = "utf-8" + self.reader = csv.DictReader(self.socket.makefile(**kwargs)) def run(self, test): if not self.socket: self._start(test) - self.socket.send(os.path.join("/perfroms", test.rom)) + self.socket.send(os.path.join("/perfroms", test.rom).encode("utf-8")) self.results.append(next(self.reader)) self.iterations -= 1 if self.iterations == 0: @@ -109,7 +112,7 @@ class PerfServer(object): self.iterations = self.ITERATIONS_PER_INSTANCE def finish(self): - self.socket.send("\n"); + self.socket.send(b"\n"); self.reader = None self.socket.close() time.sleep(5) From 763eccd69a740c62ae283c7f7adfa0f532dfb34a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 8 Jun 2019 16:12:09 -0700 Subject: [PATCH 394/429] Qt: Fix menu bar staying hidden in full screen (fixes #317) --- CHANGES | 3 +-- src/platform/qt/Window.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index bb3eb9e80..83a608c58 100644 --- a/CHANGES +++ b/CHANGES @@ -30,8 +30,7 @@ Other fixes: - Switch: Fix threading-related crash on second launch - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) - Core: Fix crashes if core directories aren't set - - Qt: Cap audio buffer size to 8192 (fixes mgba.io/i/1433) - - GB Serialize: Fix loading non-BIOS state from BIOS (fixes mgba.io/i/1280) + - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 8b7762a8b..6b174a35d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -821,6 +821,9 @@ void Window::gameStopped() { m_display.reset(); close(); } +#ifndef Q_OS_MAC + menuBar()->show(); +#endif #ifdef USE_DISCORD_RPC DiscordCoordinator::gameStopped(); @@ -1042,6 +1045,9 @@ void Window::openStateWindow(LoadSave ls) { m_stateWindow->setAttribute(Qt::WA_DeleteOnClose); m_stateWindow->setMode(ls); updateFrame(); +#ifndef Q_OS_MAC + menuBar()->show(); +#endif attachWidget(m_stateWindow); } From f33c5f55131a2ec4a4d8be7a729ee63d5adb0636 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 8 Jun 2019 16:21:46 -0700 Subject: [PATCH 395/429] Qt: Add cancel button to savestate view --- src/platform/qt/LoadSaveState.cpp | 1 + src/platform/qt/LoadSaveState.ui | 241 ++++++++++++++++-------------- 2 files changed, 128 insertions(+), 114 deletions(-) diff --git a/src/platform/qt/LoadSaveState.cpp b/src/platform/qt/LoadSaveState.cpp index 93cbfee66..78c58c2d4 100644 --- a/src/platform/qt/LoadSaveState.cpp +++ b/src/platform/qt/LoadSaveState.cpp @@ -65,6 +65,7 @@ LoadSaveState::LoadSaveState(std::shared_ptr controller, QWidget escape->setShortcutContext(Qt::WidgetWithChildrenShortcut); addAction(escape); + connect(m_ui.cancel, &QAbstractButton::clicked, this, &QWidget::close); connect(m_controller.get(), &CoreController::stopping, this, &QWidget::close); } diff --git a/src/platform/qt/LoadSaveState.ui b/src/platform/qt/LoadSaveState.ui index 46e90fc03..81e2001bb 100644 --- a/src/platform/qt/LoadSaveState.ui +++ b/src/platform/qt/LoadSaveState.ui @@ -13,7 +13,7 @@ %1 State - + 6 @@ -29,8 +29,8 @@ 2 - - + + 0 @@ -47,29 +47,7 @@ - 1 - - - - - - - - 0 - 0 - - - - No Save - - - - 240 - 160 - - - - 2 + 5 @@ -95,72 +73,6 @@ - - - - - 0 - 0 - - - - No Save - - - - 240 - 160 - - - - 3 - - - - - - - - 0 - 0 - - - - No Save - - - - 240 - 160 - - - - 4 - - - - - - - - 0 - 0 - - - - No Save - - - - 240 - 160 - - - - 5 - - - @@ -183,28 +95,6 @@ - - - - - 0 - 0 - - - - No Save - - - - 240 - 160 - - - - 7 - - - @@ -227,6 +117,94 @@ + + + + + 0 + 0 + + + + No Save + + + + 240 + 160 + + + + 4 + + + + + + + + 0 + 0 + + + + No Save + + + + 240 + 160 + + + + 1 + + + + + + + + 0 + 0 + + + + No Save + + + + 240 + 160 + + + + 3 + + + + + + + + 0 + 0 + + + + No Save + + + + 240 + 160 + + + + 7 + + + @@ -249,6 +227,41 @@ + + + + + 0 + 0 + + + + No Save + + + + 240 + 160 + + + + 2 + + + + + + + + 0 + 0 + + + + Cancel + + + From faef25b0d8772c78e8a5e25380576c30117789b7 Mon Sep 17 00:00:00 2001 From: Lothar Serra Mari Date: Sun, 9 Jun 2019 17:58:40 +0200 Subject: [PATCH 396/429] Qt: Update German GUI translation --- src/platform/qt/ts/mgba-de.ts | 277 +++++++++++++++++----------------- 1 file changed, 141 insertions(+), 136 deletions(-) diff --git a/src/platform/qt/ts/mgba-de.ts b/src/platform/qt/ts/mgba-de.ts index baba6f57c..fcbc84ca3 100644 --- a/src/platform/qt/ts/mgba-de.ts +++ b/src/platform/qt/ts/mgba-de.ts @@ -460,13 +460,13 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.LoadSaveState - + %1 State Savestate %1 - + @@ -478,17 +478,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Kein Savestate - + 1 1 - + 2 2 - + + Cancel + Abbrechen + + + 3 3 @@ -498,12 +503,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.4 - + 5 5 - + 6 6 @@ -513,12 +518,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.7 - + 8 8 - + 9 9 @@ -1332,22 +1337,22 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::CoreController - + Failed to open save file: %1 Fehler beim Öffnen der Speicherdatei: %1 - + Failed to open game file: %1 Fehler beim Öffnen der Spieldatei: %1 - + Failed to open snapshot file for reading: %1 Konnte Snapshot-Datei %1 nicht zum Lesen öffnen - + Failed to open snapshot file for writing: %1 Konnte Snapshot-Datei %1 nicht zum Schreiben öffnen @@ -2875,27 +2880,27 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. QGBA::LoadSaveState - + Load State Savestate laden - + Save State Savestate speichern - + Empty Leer - + Corrupted Defekt - + Slot %1 Speicherplatz %1 @@ -3502,12 +3507,12 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Video-Logs (*.mvl) - + Crash Absturz - + The game has crashed with the following error: %1 @@ -3516,428 +3521,428 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd. - + Couldn't Load Konnte nicht geladen werden - + Could not load game. Are you sure it's in the correct format? Konnte das Spiel nicht laden. Sind Sie sicher, dass es im korrekten Format vorliegt? - + Unimplemented BIOS call Nicht implementierter BIOS-Aufruf - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. Dieses Spiel verwendet einen BIOS-Aufruf, der nicht implementiert ist. Bitte verwenden Sie für die beste Spielerfahrung das offizielle BIOS. - + Really make portable? Portablen Modus wirklich aktivieren? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? Diese Einstellung wird den Emulator so konfigurieren, dass er seine Konfiguration aus dem gleichen Verzeichnis wie die Programmdatei lädt. Möchten Sie fortfahren? - + Restart needed Neustart benötigt - + Some changes will not take effect until the emulator is restarted. Einige Änderungen werden erst übernommen, wenn der Emulator neu gestartet wurde. - + - Player %1 of %2 - Spieler %1 von %2 - + %1 - %2 %1 - %2 - + %1 - %2 - %3 %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 %1 - %2 (%3 Bilder/Sekunde) - %4 - + &File &Datei - + Load &ROM... &ROM laden... - + Load ROM in archive... ROM aus Archiv laden... - + Load alternate save... Alternative Speicherdatei laden... - + Load temporary save... Temporäre Speicherdatei laden... - + Load &patch... &Patch laden... - + Boot BIOS BIOS booten - + Replace ROM... ROM ersetzen... - + ROM &info... ROM-&Informationen... - + Recent Zuletzt verwendet - + Make portable Portablen Modus aktivieren - + &Load state Savestate (aktueller Zustand) &laden - + Load state file... Ssavestate-Datei laden... - + &Save state Savestate (aktueller Zustand) &speichern - + Save state file... Savestate-Datei speichern... - + Quick load Schnell laden - + Quick save Schnell speichern - + Load recent Lade zuletzt gespeicherten Savestate - + Save recent Speichere aktuellen Zustand - + Undo load state Laden des Savestate rückgängig machen - + Undo save state Speichern des Savestate rückgängig machen - - + + State &%1 Savestate &%1 - + Load camera image... Lade Kamerabild... - + Import GameShark Save Importiere GameShark-Speicherstand - + Export GameShark Save Exportiere GameShark-Speicherstand - + New multiplayer window Neues Multiplayer-Fenster - + E&xit &Beenden - + &Emulation &Emulation - + &Reset Zu&rücksetzen - + Sh&utdown Schli&eßen - + Yank game pak Spielmodul herausziehen - + &Pause &Pause - + &Next frame &Nächstes Bild - + Fast forward (held) Schneller Vorlauf (gehalten) - + &Fast forward Schneller &Vorlauf - + Fast forward speed Vorlauf-Geschwindigkeit - + Unbounded Unbegrenzt - + %0x %0x - + Rewind (held) Zurückspulen (gehalten) - + Re&wind Zur&ückspulen - + Step backwards Schrittweiser Rücklauf - + Sync to &video Mit &Video synchronisieren - + Sync to &audio Mit &Audio synchronisieren - + Solar sensor Sonnen-Sensor - + Increase solar level Sonnen-Level erhöhen - + Decrease solar level Sonnen-Level verringern - + Brightest solar level Hellster Sonnen-Level - + Darkest solar level Dunkelster Sonnen-Level - + Brightness %1 Helligkeit %1 - + BattleChip Gate... BattleChip Gate... - + Audio/&Video Audio/&Video - + Frame size Bildgröße - + Toggle fullscreen Vollbildmodus umschalten - + Lock aspect ratio Seitenverhältnis korrigieren - + Force integer scaling Pixelgenaue Skalierung (Integer scaling) - + Interframe blending Interframe-Überblendung - + Frame&skip Frame&skip - + Mute Stummschalten - + FPS target Bildwiederholrate - + Take &screenshot &Screenshot erstellen - + F12 F12 - + Record GIF... GIF aufzeichen... - + Game Boy Printer... Game Boy Printer... - + Video layers Video-Ebenen - + Audio channels Audio-Kanäle - + Adjust layer placement... Lage der Bildebenen anpassen... - + &Tools &Werkzeuge - + View &logs... &Logs ansehen... - + Game &overrides... Spiel-&Überschreibungen... - + &Cheats... &Cheats... - + Open debugger console... Debugger-Konsole öffnen... - + Start &GDB server... &GDB-Server starten... - + Settings... Einstellungen... @@ -3947,152 +3952,152 @@ Game Boy Advance ist ein eingetragenes Warenzeichen von Nintendo Co., Ltd.Ordner auswählen - + Add folder to library... Ordner zur Bibliothek hinzufügen... - + About... Über... - + %1× %1x - + Bilinear filtering Bilineare Filterung - + Native (59.7275) Nativ (59.7275) - + Record A/V... Audio/Video aufzeichnen... - + Game Pak sensors... Spielmodul-Sensoren... - + View &palette... &Palette betrachten... - + View &sprites... &Sprites betrachten... - + View &tiles... &Tiles betrachten... - + View &map... &Map betrachten... - + &Frame inspector... &Bildbetrachter... - + View memory... Speicher betrachten... - + Search memory... Speicher durchsuchen... - + View &I/O registers... &I/O-Register betrachten... - + Record debug video log... Video-Protokoll aufzeichnen... - + Stop debug video log Aufzeichnen des Video-Protokolls beenden - + Exit fullscreen Vollbildmodus beenden - + GameShark Button (held) GameShark-Taste (gehalten) - + Autofire Autofeuer - + Autofire A Autofeuer A - + Autofire B Autofeuer B - + Autofire L Autofeuer L - + Autofire R Autofeuer R - + Autofire Start Autofeuer Start - + Autofire Select Autofeuer Select - + Autofire Up Autofeuer nach oben - + Autofire Right Autofeuer rechts - + Autofire Down Autofeuer nach unten - + Autofire Left Autofeuer links From c5c742dbfd76a5a6ac6083bee395a07e270c7dbd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2019 10:44:57 -0700 Subject: [PATCH 397/429] Revert "GBA Video: Clean up dead code in sprite rendering loop" This reverts commit 459eaefcfcf75a177ddecab65e7896279109f7c5. --- CHANGES | 1 - src/gba/renderers/software-obj.c | 36 +++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 83a608c58..72ccd171d 100644 --- a/CHANGES +++ b/CHANGES @@ -45,7 +45,6 @@ Misc: - Debugger: Make tracing compatible with breakpoints/watchpoints - Debugger: Print breakpoint/watchpoint number when inserting - Qt: Open a message box for Qt frontend errors - - GBA Video: Clean up dead code in sprite rendering loop - FFmpeg: Support audio-only recording - Qt: Increase maximum magnifications and scaling - Qt: Add native FPS button to settings view diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 6f0c1bb9e..d638dd332 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -80,17 +80,25 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_16_NORMAL_OBJWIN(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 3) << 2)) & 0xF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ - unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ - renderer->spriteLayer[outX] = color | flags; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_16_OBJWIN(localX) \ @@ -107,17 +115,25 @@ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ - renderer->spriteLayer[outX] = palette[tileData] | flags; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + renderer->spriteLayer[outX] = palette[tileData] | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_256_NORMAL_OBJWIN(localX) \ LOAD_16(tileData, ((yBase + charBase + xBase) & 0x7FFE), vramBase); \ tileData = (tileData >> ((localX & 1) << 3)) & 0xFF; \ current = renderer->spriteLayer[outX]; \ - if ((current & FLAG_ORDER_MASK) > flags && tileData) { \ - unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ - renderer->spriteLayer[outX] = color | flags; \ + if ((current & FLAG_ORDER_MASK) > flags) { \ + if (tileData) { \ + unsigned color = (renderer->row[outX] & FLAG_OBJWIN) ? objwinPalette[tileData] : palette[tileData]; \ + renderer->spriteLayer[outX] = color | flags; \ + } else if (current != FLAG_UNWRITTEN) { \ + renderer->spriteLayer[outX] = (current & ~FLAG_ORDER_MASK) | GBAObjAttributesCGetPriority(sprite->c) << OFFSET_PRIORITY; \ + } \ } #define SPRITE_DRAW_PIXEL_256_OBJWIN(localX) \ From 09ccf5403eb0a0d85fa119c612b9070fe8807818 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2019 10:50:14 -0700 Subject: [PATCH 398/429] GBA Video: Fix GL mode 0 y wrapping --- src/gba/renderers/gl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index 72ddd1d8c..a54e0b028 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -146,8 +146,12 @@ static const char* const _renderMode0 = " coord.y -= coord.y % mosaic.y;\n" " }\n" " coord += (ivec2(0x3FF, 0x3FF000) & offset[int(texCoord.y)]) >> ivec2(0, 12);\n" + " ivec2 wrap = ivec2(255, 511);\n" " if (size == 3) {\n" " coord.y += (coord.y & 256) << 1;\n" + " wrap.y = 1023;\n" + " } else if (size == 0) {\n" + " wrap.y = 255;\n" " }\n" " if (size != 2) {\n" " coord.y &= ~256;\n" @@ -155,7 +159,7 @@ static const char* const _renderMode0 = " if ((size & 1) == 1) {\n" " coord.y += coord.x & 256;\n" " }\n" - " coord &= ivec2(255, 1023);\n" + " coord &= wrap;\n" " int mapAddress = screenBase + (coord.x >> 3) + (coord.y >> 3) * 32;\n" " vec4 map = texelFetch(vram, ivec2(mapAddress & 255, mapAddress >> 8), 0);\n" " int tileFlags = int(map.g * 15.9);\n" From a39741056ece1da3db99710ac7c079ce81306952 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 11 Jun 2019 12:23:21 -0700 Subject: [PATCH 399/429] Cinema: Rebaseline F-Zero Climax test --- .../obj/fzc-obj-priority/baseline_0000.png | Bin 29698 -> 29741 bytes .../obj/fzc-obj-priority/baseline_0001.png | Bin 29919 -> 29963 bytes .../obj/fzc-obj-priority/baseline_0002.png | Bin 29919 -> 29963 bytes .../obj/fzc-obj-priority/baseline_0003.png | Bin 29919 -> 29963 bytes .../obj/fzc-obj-priority/baseline_0004.png | Bin 29919 -> 29963 bytes .../obj/fzc-obj-priority/baseline_0005.png | Bin 29919 -> 29963 bytes .../obj/fzc-obj-priority/baseline_0006.png | Bin 30051 -> 30095 bytes 7 files changed, 0 insertions(+), 0 deletions(-) diff --git a/cinema/gba/obj/fzc-obj-priority/baseline_0000.png b/cinema/gba/obj/fzc-obj-priority/baseline_0000.png index 1542506183adc4dc00eec892ddfd48ae6d7ce66f..9515678bdaa2959251957eb7ae5b89dcb6c35ea6 100644 GIT binary patch delta 26922 zcmW(+1yCJLvt8U>KHQVw!R_KM!5tDLxCaOxSS+{)F7EE`8rv?7_+s_j9ki+`dY4O3`5wTxiDvRA-V0NY`mYNTforW=Lpz=R>@JGEHT+f> z9_H}KoopX#I#)VCp4AX795QEz==^Evh1y~*49tkqM$YljgFLbtA+hgUgq9+0QgX@Rcs@o^)zL3{R6@5btK znZcXc^ujx5+K)24wVcTwVIKQ)Jx-6K>KnqbPLK=)QH*gj((~E-D=}G& z&3ldQ$N@sMv`|!1@Q3jg!OItxtN#xB;5U5NIpe}u4dS6Vxp%liM_q(@9)=p zX1v>2TpUy~+GB{yh^F9lJG#jFjWJ5CcIH$gbPg`Wr`@;~)da*iK~5FbDq1x%JbImK z6#Miy357b;j@u8uEr?>Dz6~pSZ_mVoS)p*Iv!7o~f57nRlhb^((5|23O^Wr!3k_fS zlE6SKvs0coQ7tF4*EdU<5-#-9&}?=3LYWyBN` zP}348D(;3&<_Lo>vUGGcl8KTE1aT-Fq$al4AzuM z|4yzs5fuA@6F8o}wRi)L(HJ8O|0wd6+ZnM&cdD_iAP1eX^&FbLaRT?$$#g6T1wT%xXVRBmG$~#N@S#m8 zEq1P~wxN5JQGFX(MF(_TXRy}trWGd@jpGL*pN2Bf>jpopIPdxWvjNEaE8R!(Y5Tb> z&z3O!?H1EDFIHO~S6hx*5^a0d3BT%xjF;%VtHD^|u?@gx3D-98*nPM;o&sz5raIR5 z1P(HrgjQtEJ8L?@wPVw0Pctx6;3%P zeA-T9Mx`Eg@NwRUg;(RuZBDK+R#KN+R}(JdC`3f%XgA6ob-~$V;oY)7eenOO&Z6XE zqlzwRa4Q%=Z9RKCpfAYZ$_QSB(#5pR)XimRFgX>QRA-&sBdm8%1~X z#}Ct9@I!sH_|lZk{#iJH%x0e{yxs{)arDF{c7Z3yJleThC+rF^}~3PWzl39 z-ClU7j15mxvQtUuA)GUgN3!qWqasZHDWG3medBEht|UBy?^*e{K9HQ0dt zJw81H6SBp=R0ywj zV2{B6qn&;=jsgg4WIujm*h|44ZNI8F!*==E(!yvNf5FXAS}GJGUi$-pkX8 zp|g0b*fk*ey|!?JI_BzpiQ&resY^hU11Znzb-O4U^#!@-Qy@p4b+@7}F(R9*(lj0o zWk3JvcU6NUGUI=#{45wNGE{fvQ`Z6#0d-P5UUxP%gM_v7@3t*Isd90<-{QZ`K5OP_ zNne<03RRliVAZfE_>MZ5YZ`_G)NE6lJFGuCr&eHjxEg+xeL5TM+4d*Tj4IV%vW~&& zahhLTlh>GdS95e61-&dLZK2CRAT>IyflKR9`PA0xkJ(+ig@AJNA?~?9pIzq?Ee@{Z zcY65TBs|3GGH<$tAAWpL>nB&_RNT0_rXXAbeprnx3UHCF`F)9fKTE5=p67J^he3+a zDBv1QnIhN>{4I-f#e2sqs

HDP(3oszqmJ%ku8`b^R5eqfK0Rr)38!W! zFTUCnEhusI(Zd z=RhVY<}i9GKQ+BUW44CDy#Zh4{ST8lA(8Qq|5~Q;qzp{xVURhkTj8nHvUNCl!}RTK z<~EjHMsWd*Iet%!=BKDM0q#&DJdh(uMcOJC%_5zJae(u>T7C52yJ*NKes^YpOZ($fu2gGltW_<#8_y}gY?Cv%cfqtbf|MzVs{?)k zsAc9*4p*boY#E;As5|R{Jba05rME|?IiLJiGGaf5%dPO;bfiWJW>Ac~0Q{aMvoYN& zb47EkB>CKw&KXD5-0`v1u9x;^Jb397Hp|3S9Ax=Hh~kfqpH-X)Ax=G9zNcdt zIAf~c&Gb<2pVZ9NE9)D@AxI}nU>SrT9vgvUUSTiL5iaKy{dd9N3Wc+KmNSd8ylk?Q zq3lHbms<@vS?QRX3ek|UCAb1*i<};IYU%n$YQb~D-B`bDiB-}^!lB|l`&_u&EV9Ne z5UXMuA+YyZuGl^OGqY~Zyb>IqaT=t3soX_>;P7Y;X7BGA4s5^Rev?#^OTnSno}ZsQ zw^q-jFjv}1C#5f2?j;$&`#K$Q5X+I5)CRY?n^sud=-M|7TT~klD=>&B_dhve{f2h{ zUp$CNhAU|I(o%zNfJ;@2JU%q}$zaN@Z1#b?Sgns9rx^Kw?7pB`a&6PRu|Hf2W6s%1 zP04%CQVfBz;ChBxjJt^)BQxClPv zq`Vt0U`*X+xCm2u1<#XJ>ja|BBAAVo(dhVzSd&Z!)6UXbV-n03p_Y|;O9P^e)`9ra zaee4Q@iuv!42zo>neO9}F?D@jRLkRjQ)g{Sh zU|ICPdvF59}c9{(5^KhyH?Lyn+vjM#75;?YPjxFhFNzS+BoLEg)g9i-ocyZy*KX;N)lyQ!R2Uhm9TjQjOmUWQf{$FInLB@tI$uwV#I`)sx7Mxl*=|9 zbmxoD8QRxRnLjBM{3rRy8}BA5yR~?|CQJsanYQZq11z9oZ*Ss1^c~Ragv&SmgcR&7 zag-R>RSg@??4U%~se#wv$YOW*75FB#$e(n;Ou$yN4)ZPK2LgcLF9%>ta|DtMhseU< z!?ec+cI{n=7MD?BX5rxKw=o5=j1Jb9Wk&$WYEE<#E70IF&0j*DQ;U1pw zU5GzvLCy{}Qz0WwDZ4k8pI_#;`A6;s+gxh!uBXY>h)(9N*`(?=TA`6?PKiiodv;uU-ioX@W#Pd2mfF!f<}xIcuAHM7K6`4I`Y zKM!wP?kxOQ!4HvrC|fWoGLWt0m1`UVA3p5vRl}IVczc-S{~+-_PU-;CZuAHFYMZQ+ zt;FnwUAqn)iH6KsQER{2xT+?J64P#o(r7knuEZXn!8;#oaO3)?OEA|gZP1r;j{E2M zY;*QlQx=!41tP&uhV5_@GxWVw6fHCG9t{`~EgMh?Ao@rohIbAb%DucTRv&HH%PXfw2lczE+IvMSvZwu4#o3D-L z0AK!gU0t`5a|093eFqZ4lc&JZhL&fUP$^aMEMyF~m0s2_CvQ zFF2oBqk?%i{Do{_=IUVnE2;wN7jv`DhQ=v}jP9Ca)&#S(WxbjqiZ27#wj~X;b0WDD zjeHWy&d!7lScd$j_QL9iFjW{{RCg|jugSU8aR1uqcb)?zRvOId&+os0KdAB>6NeL* zuoF&vOGp(dGxGOa2z>e|NyafU=fCWp57}@`Co-UKqVPtT<~{jaRcrsEdc)c<#}BLh zig4L_)b7NFGpwxhX?x3ys+2(LqlU}d9Fq@L8j9Ruu2UB<%^-{o+!r{_m93TTUQZ!% z1US+6mxOuYscSX#Zf2EW_v?J0Rd(MNzJ&UPC&OosscVxV^fw@Yi+JYCnz5CL`}fuaq z$f4>ki)K}ilhBqo@Kq6A!po&pG|xS7tpUk*fVfVGv~HvL@(0L6zHL6#q|0Hzp!~xg z8lgDgo;B^#Hh4i({oYm~guB{YMzBY0g$dhLAJg}g@E=NBP$~YYTM5ov7u^vJmAd}; znF^G<3SN&X@2K0%jekgCBv!VI9wr2xX0>putc6(c2?=FncT_wpaR&~s=Rezro&!J! z9ON{PE%#Yz4&uJ!7TN)q(Ti&D&#`Xp;2Pk#dSt& z3vES`Y~tD*ZJ$ga8)KOCt+48O*GFR$z)N)kiQ~{t>TQ0i$y(56E-F z8a4mS2kHLAT13$j)Vo>BPx&-T5}?t}7ZY2u<~E}vcB;4Ud=i;5grSPcS`&17tZehw zHb}lWz8-ITNhXxu-QyU){-xe73EHs+>vFXNc%{9sHmgPZwL|Rc?Vyv1Bnr0EmXl*pdc0tvfnyoiS=2czQR=?VD`5iPLTn2wgut| zxrDQOLi|e6?2&3jAC6~%TW3MqoWw@_l7wQz73ZlN{QnzWJ?!njM@AO4UTJg2;=(`JyjpE%K_3 zx-~*b>U>`~)ok}B+>d@cT;9d)T-Zzg%NzN=F*CuwH%Z2?cey-{5f)E3;vL_UF)(Pl&p5gEfBO@Jk&pX zc<*cJ7O`>YYB5#v9#uXquXo*6zC!&%AkD=vZ@F2$o1W5!rZC{o{B-c%K=QQHn?lCS zP-K6nayx@^j{~?j-ZOw)IhtwWtbN8&;&DPvguE~7s5r=K2{!f)FEx=7Lr~xQ0YB{-t zl(TqC427NYYe7QVq!&wcbN*B3kqBXvtetfggjfdaKhLgHyyxWjT5z|YpndyWoKgTWVi{##xg#XP!%;dZQP^w!ubYUEb|})bBJr)~H;lL|xkIy-N@T zme2p;2ma`)_JtM6gL(dY4VhUh^ps@F?e?BuD*WCiZS1t0Q_(bJ$<7|mvTjr7t%e7Sq0uUx*kJF^+sS=B(Au@8IEGfSn9!06|Pz9DHaZ; zUm-8Q>*Hk?Ks`7r&P3oukaE+As`y*f(>~b zW|GA;()%EOP)=W;cXSuo55AE}fJXBx@9aaBV&0K! zIZnfU)KV5$=9#xCwJzYKR!;%lynPG97hZEnj8`L=p4GL zIVrJP;Rsq=fml??O^Hq3LbvuNFNs9LdXE;ZU8C5K{8i`E7G#=5l@u6Pjr5A1ei8 zyCgdf4S)kXz*smGi0tt-6G{$nJtbSQexhf7YI>>gNwQo_$p-QKnbf zY=IKumF%ty>Gh<3RPREb=rE}M;u%Fn@`N{?YQ7~Rj4d1UClW`I$2jV&;(sjdu^+p# zM3`ooYQex7jVx8$7%W=b6q%3E_+c9Iw~+@5hY?Om$S7UeFZ>qrzyEjUiWRUAuJQ?^ zr?@bZI4$PnOl`R2?&nyMnT?KrRhul6k?Yh|NckFw-L z?V1CdJ}o~!SBb>TeY*1M2ggG}4V@JyqUcb36YIjMzrU{aj=lu5FH%q6v3MnNZG{Et z$ip^T&)LltYqN`6c1|7i?P!(j>(2A`AWx)jHAl@_$FT{XJ?TgcLF#DG|G zIV2PB8E=JFIi1+KX`qzjFp^cjZ|4p?yBU}wtS?}%%rOI=94k7}7>0h!JFIm;UjGC+G$of?+ zN}-RMxr5E~K5ZLCi|;SR*Q=l3u`CPfq}92_B`x=KZ#d}L~mnbkV2l04MM+reF-r(K@zpg?R9P# zd|$W}&S1&KuNJ;fdCrT4q-h*-GI!CSseFf_($HS38LmOZm2&Er+HT$1q0W<_UyV?l zHKh?&bLW?4-gp8cMwnX?J9}JFR2vZ*r{wtdR)HDd}!v+*aj>KNCe$}G8EfR2KH@z0vuON zS1@qycWRs%p+*n9=EkCbp|ZticKB#rskd%0OYa_8rO7Uz4!6Pm2Q}KvQmo_@SEhG1 z_*9yD%@{0dkXG#n;%Q{Kc(ucO0)F2*b9ZX5{SDG95f)}S{V~=rIYI_nDvA^1=|#b9 zGlDgmF8@ubWrj$GN`_whtQ~8mO0OMbTFb9l!c_6JA>TgSxOSwHbwav|^s^n;kiy_M&ZqJW*29WQH(vju(|26kD1U9Sfy^t9}gkCnYNQAU;B_k^NN43Jh zd(65cMPq3(+OneZ1*sE-sq2_UcuNcGm-Vbm1*nD?IXSq$>k#aQHes>phKo9GN6H@ z`%=9g{h&eJ}=QVOf?DpTN3P9eKQBws8`#1O*aUVHgC`EAwJZvFoGAtsy@Ln4*?cVssF zlAX*YmB4nVYq*J18BgilBWtA41v=Yv7+qBCrhK;&D5aHs2H!n%AU6n`_+rlbJhH zVbY?{&1kUi+ud4n@eM=MhGbo!O*Qu1{XZJpk&Z1Eh0$0PM$KP2Y&JJ}^ng*WwV(A3 zBB1GFi)+7DOD%9io+>%iXI!Uw2evSW2bbSw8Hi}qk881bvZ9iVwXC3%jHSgV)7sE+ z5)~{dJ`gxKGoXwn)JQ#(J;1VQ4|miNXG8S4iS>2qwx4PH?{+Ha4AgLD5M|RJ8}s z8<#`fW}4A;W$?OVTAi^{t6=7F{q*mpdcJhp^BGe0aniH&r|;WQBa?aq=w06;)1YvJ zY@Y2{Mnj>-Q0zOT^ag~mEImeBJu_)bK=>zj4T}m3F@*{WKwUSQLdhM%b0h^PYTSI_ z?n;M#djH$N>rr)kRodAC96)-@U43tF=#DEIPn`-cwk_d?h)V~V-|!5SSh|Ur(m6o0 zEuzkO2bv`b5SbE5o*#Ba*^!YP8mNpa%B)MG^bo*6K} zgl8dAZEaTU4_=bDSF!dA?_>wedD`W8WMwY_xhhTJiN|q_7dh1$#cXS^A8~ectcG2~ z&wR^>NyMXcwIVv65}-x@>?~{LZ1G*AK+ysVx;(2u094n`KHa8>w0wRpYV{aj8`@63 zM1G>I9Q~iprx$zhFeQRirNO#fHb*P2+N>geWtvxexI5xujl*|bE7HsoP@l;1tnP3f_cUa{jZ8ijT;`8?KTR=8MPvEO4oUJnmD_+`0m&-f1Kj3$tAkciEI%2x z1&+xl-gF#bszA3rsDn}>^5}8;vd!|+1DS=?Wd2YVPjurP-YNWMvd?+~me~d=3EMy4 z0)}4qUF{A)^nDuCEHa(5kxW;DH}lhz)8T=qtuq_Cb+O(6e6<#sl2{xx3ALdsK8Err zzGB_%3ZOVLu+lm|h3pMafLvjgUrixRA=x}Jh1?zwzbf)U0uFD>N-2nSF}w4FzAB>x zCFJ!mgg{Ht7WFtKLMH-olHPrp%MvEzi%BdAtrwliZ9&zlX11B7wB;va_(ioQtwXal zg@&|r50!EYVZ7Q8B>RsN$D)ff%V%RL7;hQ$Vz9hAd$mmKAwZtTqD2u+igKvGOH>k2`3Up3 zh1Iv{ECt@dxls3~`t8=26Rs1g<=|S#qR2Pi=S%DSHn}mi)+Ks0>QzOSC{K=OyU_|*#+mi&w z?4a5Ek;-}Zi%QO^7Qz~bqp4$dfDPm)2%G)+BR;)dCHM4;TI?w?&g9w>o!SqUAFdY8 z-no=6Zai=7Pk1(CWzQtlHj%q4%V2%4ukZa4Z7z)yS6y%asamFzHep0ldlCBe-bvK~ z@?675V=mSxlbW00r#tMr=5m;bXKah5N&~06A#f#kSd;D*JPuD{kl(VPlNxc$I+}RV8(mN|UG-OL zJupj5sLMKpagDc`hicIs)5?N-8G1qe$l1@ht1mi{?F`H_^lwRQU0y5}2@7z#u%dO0 zS%VhOprZ*IkdGpf-{olZdF~70Wy8$sX!Jr`?YL$1;{&Z*7=Y<^2Q=kg?{U}IM2Wng$r4_=C81%w?+slxY2g#fEs z7+p#|h}gWT<`V_OQA@R(C({|ewP?PKkY+1u`z8Z@n8}r6HM2sO`fax(AG?Y3*?&b3 zf6NP;$%X!V^Ajn8L!*8_az0VA>l+35seYNrrx}dIdh>rotBd{x-nz4DdMnqhCK>GxWzomnN!vz?gK z?%j`6V8H#LvX(w(OtzG<8Kz8BBiEmiYXz6h6I#WUJ@$S{ zc;Mb?F}Fog@4D=flv7DqPIdb|U!z1}h8<-Q%ffP^qb2Bvs!HWWp!uPOMN&!!4v@pX zXZ$|I(<}Y4tl3n5jxnKRO4{>+5jrpZVY%3e7n;}13CIi;iZH(=*frC}x^IB?7QyCw~mC`F)&G6=LS zB~gIIi{O+JEkE%xyZmTD`0ymec_7m#xXPc{_qG9U68S9{*>DVtb9gP*_YmHlw`!0q znbj``(qi)K%Mzx#Fi&T^idu~!nR_j>X-bv1=_RAgr6}!;{EoY}T40}<&?>K+GW*HJ zpiNIZFy_>`@wf3h**v0%R7O2*YCs1L`%Ss{3KB!Bc6w__irKFzi^OQ z7%2cwGqBj)fKk;dtP!seFk3T(pUpeTQor}!H@yJBKIa0+T&>$g7DfKH>IXar^eEXe zkR&rsS=jR(INTv2o}$#RVBtWY)0;J9cUbOkA!Kd_e#fCtOflBSCmo6%`^z<=Uzv$gl`$lF0 z7gwHyoChV0uFLrnwp{btI&+z&jJ0EsJAbeu_KY&o#=35z(`mxIc1J%3wrafJ64?mLv%hKp5^RlO}Qe->$i} zZj$st9E*(u4!txA;}=syVT04!CURx|R)T+_T6Cs^Izimf4cL_8(6L_N#bnQeCNAHnQD5 zGiW`S1Kc%T0_2Kmm|sI$$`=(qGSE+TPS+;C7Q59l#RM+2UH`Q`$g}Y^vuyu`*1gbG zncK0Qw-H9iv@X=zZ|`O+xx)qpnFI6y>HigAJ=@F0w|c$6ox%OS<{r;0DMF#H)5VdY zvl||qlrK*_dY`IT^F^r^x1~0Wi>GvL$kEwi(i)L8JYGhGN50Gy4VXtBlxntV?CpYv zJl2rFgpgqVHcu;nmUj=H+Zz*#%U}e5!fAx}t%6T|i^(e`#qI9z#jilESrhxi$El2& zS#Kzf+KS@(bcU!ip6{|fVdbx7d)TbuD7^&h)@DYgT|2I}Wlzqp_=##9PU>bB$De!7 z?Z1@PJ^0Kzcxo&a|AUN~GlUs9HjKEmHmtCqsjVGzi-oDOBxI-NFRL&%PC{QiM=Ygk z=F5x&mxfvXz6^5+KvKb|xwFS9?&zBPHDiWuY&0|YQK>bSAtP>>0k`ox1`VO2bnJb6s6FSh-dEM;i6RaYT1`MrOkUOxIg zvAbA?`N&tzS+K^|?iaCj5YPAx5?kqEBkBU&Fgi0sbK%OeU2uu1I{rMnJTpE_cR4IJ z01F&EGNka7G7LJ@57dN<{hGsx-Zqcfsa_~)FHi-jKCP7TNUlZ;kONxvBrXC$+e!5T z05n^Z8E&r9GqQ=YNGFb=DHbB5V#DV6hthc5^s?6+)Hj%U{JF?nvW)Z0ZMJKx$h5v` z^lGHHmr+0}yL*#1hU>czjnHeEu>Qq%(ku6x60yiQfvhK>Im!_}WwvZw(g4+dMQnuhp-fjHnZg>@&mvxvyh~K4nmUi#1yhFOMV552+3BD?`O1=H8&;{h$EW zW-lj|O!J1H!F2u0DJ(u`Y83^ZvJkr1BcDT@`^)1$=VE20U$B!9++x4Wp}|>5Vbz>7 zXxlJ=#qPJ`eG5nA@xbq|(WN-WZ1Vnq?l<7D9zv$o zN>vZt=taBvwQcSPo_5RCxZU&QKi(jG`LMk8o?iC@Zg-QAWdEkALJ;j=R_6ak7Hm?@ zF?>nrlprUkE?Ag7&%N4Vda>WXUj7P^ZSI#`;!~8r;1mVK)s_;kQ^?DEweq^yf2RB= z^F;owX*hcm@MFt0+pMFp3eb|3#D~SRjf}`RBQ!lAvnnE_F|#q){%N}FY3>d3pBdXj ze~oZP&Zpgn>MnH+`>7&KMz2{<9S`7TWD0i;8BS`UpQiNIe8jqByikz?pfut1{$W|z z!N#x)S?{PV=OowDkT`yZ^}M5A+}I$IBWK>!p>iue=|NfyWz^lNU?@udA>w?x0$o^c zg4!8VH7YtV)InG8Ox|23kz zdz36jg83zZZxpnQNjq*6xPyY#Wp4??7I`g-_NU}4vy)1Z4nA=Z4>o*kFtR)X)gn|h zZh|zL0cIOn=$a;8{HBIUOWp)UQVP{IkcQJy$u5x<^=If_%Wp`6Rt^X@pv}4z<7(hw z_*+sU0`!*wmIPd=0-tUX_|*`)O7>OfS_=@lfn_M7DD&gyL9%K!dTa-+9Wu}^DV@hG z#RF5d?bGF~VcdI(xRe|`%?y)nKx3o6Da1jcD=_!lZf%gC>(n+z{^REw6FPb;Rzu5C zxlOOm_PQ{3_wa-Yc3H6I56jqe6~~@K>z-XpeR^yo3hBCkthin+p90A;ajrd67G*K+ z2x$h4^cFHve{4l>9}SXG?O=BJ4<{bc=RivjS}$t;oeuINvU~9%W(_=XKb5SYVyYf5 zph#@%g9))`ngz-ttY9kQ3y?dg3*@cl=#$;^sX)l0hEI`-w7?SI>YUqotGU@`Br zmfM|tgNj`LKP41jetlmDAqLXkNz%K`(kgfu(bGQ0h{1-z2KpqUuQe?rh)zx}FNP8e!U>@@KdtL}wnF1ddWQIyu0IE$R;?NfhhX)_8aXQhY`W zjRiDkTs({2$m{tv3X2g*o&b#SlasHih*1Rduy1vK%UrsNZdkrY6yJ6_OAZKO?tfF% zt#Dm6%D*0Sv@(u5v51xyEQco-s>66nMhqMK%fe;iW{ZQe)H!S#^ecn}7<1=EIw{>S zUE;T^BT?Q(aL>`L2}#K2U&}{Dl#FYzi{SvZ8=wvkIXA)`y}E({Ap5<$ES_w3hVDLK z(sxRs!xyVob5S#o0Ti_-^(9fAVd0_pdb5=+@@nkpL9Oy+ndw5rYa^&>q8y_P;cEOh#?wV znSO_yN zUAi8LG(9ZsMjzhAHP<5vQ`hh)a-D~xqj+Uanqu)3LnK1auZ zPYWAiP4XF{go!B&Qr6N##>s?_T_s;hy3nFXRX%)G9kinP4f<*Ib1+KM41!l3Z+c`( z>TA!hSN7**I*XMmYTw1eDlvpoJt1`Plj|fJH4N8LK#!P$P1!H1suCMj=gd#l*{D8s z$9gs$Y3FroPe<&W6|cO-*@Jw+rkR$s`fk_AjNDs3&-d8%CfnZ98;PNp+Q$DoY2uD1 zI(IJe@Oh%%M{prd{=IowVgk`W2!OoRVFHyOLv#u534j5bH?ZPorNvx-n`DAkvyAAaQ9Od=YF_%LRURJ@Qs3(p^dQj3*i10;A8n1 zEOz-~0g`ofzDx*bbsxO8K7(+kVXyy$40nZ1!$e+#LDWCa6E7@);mZ!>=GHmWN2X#I z&cSQ#3}V>$IKJS$?H4-n*1q#=Y{!gzMIr%%`ZHnfFF74jcrpDhX^}X`xz{cal{;O` zGe7!Vp5oD#27DBLewXjsaeti%{CL27RR&&rIF(`eET6JUHY$(6yQ`m{45d7&yO=0_ z+*#~jmv&!ENKQL1H-k&3UX))KG8+}oUq%eS7+QmuhYQ-_^~%D}p1_^qi#7J0$iM63 zfTq{X=YIk1?PnXFJI-puGL5g@8_UmY7VElhsT0DFn8EN9R~@g9Xg^rwr~VW9=bC@u zmg!Nb_WfMpu#~$LylzsoyRM$)|GRWkq*taGLiT25lIX(2Z*G;8^1wU&zo-r@wu6#2 zKZyl8YjWbMhIB?S`}}2Ai+@!^2gyZLBPI>KFE`>bvTr6=lLWS>Xy=bKr!{TABqIXeETJrH#9 zHbja2*8X)iGWry|u!$iO_?Y2^Qp*b8<@EgOc5N9|k1P2I9MvV_V*poO`jE_cZ6=`R z4+ggpvM`jCaPoPj(y;D2x_pV#s#%m5bcT8K6&&kI>9S9(J}PWJ5zU=> zo#of>8%`Ul+rJ!98u9gNzZ$hwiY!U5?^l8|j}M~HGuM92#)Wzv)d@M5!RLL;S0C5z zRuvwOgU=BRF*)y8ecolayKXc3DhqmfljwYzd0I>|#(RFv|NajT%+jPb#^QXc|#7Qi(FLU*led!qQn2b!~ z;Eg1j5Ub70KS}_*-CBg%oqtC*%3{alj?rV}s_@yx-EbNr{58w_pSymw6JVS0BY9no z%LY|Qr(-7PSn%IuZR*{mp{J|oSGP8RX3y~8ST`vLGE&ffeNA zmMaEaVmzV)5T%=fc-{%xZNJg$_IBqJXgTz#xox$R(^1$=EGov&6l6nh1q1RF*)Ian zv?kN=Fx3*)Ru_ChDNGb)RsHyppXE-*HtKK6+t{k@TY1ki{eKPe-C9HTu77p>a2_r> zS$*}^ej{g3h-^!$z?C9pt$zc4SggQf+p)mV^M;kvJ!NhP&3fm#iRL^sTWH1fY%8|_ zEsDXStCu3r=@hZt7T zE1Pgi%Z{!ni=6K3315uPeID7*;72lQbYxu#c5Khql3H^pnltneSW@Ikbz#zijJ4z& zZM<$$`jN*CH!fE4HZD89t(ii@_; z7}Xwf1?ErAvs3`Vh*h9DvA|Xgw-k>gsYEpTtxv@ussErRPpL3bc5^LSi9Lo+P(`Ut zdyz^*kdT#ehcGp%%C_w@+GubKO5nH}VL%~u8tDDzMi0*25i;?s@isUMSBleBUK<#; zjH~%)AW(Hr+!zgf2}t4+bkGbR8>d?EVRMQdJL4@i|5Hk}Y?wm`h$H`TdtrN8c0Pa9 zE>9?1aWifn^t;BT3DYMcIB(hh?l}~inC5O}cXJS}YnL?FKfP?t>h=k$QIiU1RM4~5 z-lTqh<4qiFS{BRDJ>@l~7FcdZx)obUPMV_y^7=ZN5YU376gsUyO5`2PTi6)YpYl%meHRyPY3r=vxQ<_&vhuB%QK{0O=ASbkvkfA5V8`Q3$T(6rR9 z%hi)D9l!y&g4O5YPzo`O7 zaf$C|d6J|?11IH5Pm%4M6X5Tw&dCF*;E@<6t-%<XYJ|R(2{ygg zWv^!PuGf)e1UC2QM3`RXHngr+3mby2GdHlOXruFSZNq3(fj@`<=abCfjP4r3j7eum zDzAkLg2BVMDiTLJKWDA(#3|>!i|yL~K9;QvhyIiQM^d{2PXB0R>mAPrU)A5;oaMio zh3a)KTfVPb=(v;v+MYF~x0o{FtGsr5kg(sL_qR^6jKr)4gS*fPF6*`l?*;+(bGSDf z0dFwzYPU}HDROO>H%jgBPmlCFMb~>W{`-akk~Z?GHiV%^jk;#%q!!8mJIV*9U(k#j zOkc^f**NMe_Ta>75JQfrTg9pG8w`GY4;2g6Dw{nPgD9?TSX`JH6N)o3Mi)=knBU2v zD(#BvX98(`)o28pAUpa^b>uEh9$9Fanqg3bAI7`D!!to`eST-uD=P}|RwOHam(Y^q z*{7@<8M$Y7mH`}5$oT^Q0i>FfMYHpoeD(E@w`WV^IZD$BxEI$;4L6Y#pHVCOxdB?D zn5!09APo;lAM}HrK7eWi6yRe;=s1!JHnRyO_9o`Y7D9uIpgXskE=IbyIpXjnbI&|$ z_~k<{v4n2Md4}XDG8op)xO9_CAfkt2rrw`S(^R07ET7T48Z)XFOuh+YYxu7k`%;Ev z#F#^R1N#!perSbZ6JKD>N4CQ~Q8*uN2t>U+F@){H6M3)s_w79USKQ13M;i)p&M@AO z&xQi0W5KJcXE%?Oy$T!2f6Rf8-WCxxo}i~i%S9>Zo7nN|=*0XsQ|_0Aa;42RtH750 z{{Pi<)?rmVUjx4&C6dzd1(cBP5+tNcN*W}jL%Ic)?vS`hNL&%=mX1qEcS(15cieaR zJyD&=%xEJWe#04h|d z$Eh+gz~tOwZk}gCEY#w}#h{Q6TRCZ99%~sQQQ%epc6iBZilYA_3dwJ}xKW+5;?u>( zmqk9#idGAeIk$YSyNejcd*L5q3Q>h2=^=fIe5rr8Ys1LX2E!U_a+5O-9)XZ%UJ+#B zes`Kyq@(2(cK*YKLK8l%LmK}X2tlLe^)Gthe^##oD^e#*tEQ}wSSbG*fii-I5&DI9LD8Xmv{f0+-;zA~tC0LN_L`2U<;WLq|7F&7R_DjKFRgjYLtMH&&dXfk$Fsf}_)MMG(_ejk;+)@1lv@@-Oj(>l?Vle@!!Cj(LsNDCytbW|dT~e?*$}+qyG4FX2I1q)8HawT<)j@FYFgcG!bF5iH zUQRcDpmS2nq@ckzl>D97le#cXO7o}CLRg#rS}jX<+uelAYs@ztpQ?Uo2=KB(;!oM6 z%_T9$Exc~^ew0%uqggCUgv6?~W57D<7Su2PWKu_`a=Vhef_z~x<4R*Os7MYfiH0;_ zROffZg#j9Uv_T!+vxxx}Rruc5onYy6AnZnuShYU)Yt-u*2K^tmsOpa9U-b8026#hK zlM2&xP#ieC{8+2^dV0I2Fw%&^UEIX#GLm69KL;}q2V01t5^x=cq|SZo{D0g|mn{7w z6o?0YfBWuTJ9^0MRIf^Y71R~2-{xD2ZG|Wu5Pliw_ngz>*;;$5Q0EkHhE`Ff*^9@z ze}3+JdUy0D4ryJ#ttWac?1!j+tXa@Nm0ZJI*#!IiKC2AQg$laturaLAey6G-6%t`t+}YYV+|jAck&pn5jjHERPVH5GSCil*~)D2x#6KkT%+G~80G0h zfOFAnG~bCuk1XW!s}4kDZRJO?>*YJ7;*5u@Ap1s-jr~J!$JLXI;)%Auk6E z&lbIVDx-eP4Ek;WD8+Dlv(ekFVM7Tt*w;~5GAxyOGW>0e?=yo@hu#ET`$Mec+Ctfl z3A4Tea>+{4Cbp{N#3mK#m~`EAYM_zTl8C(F(@|mtai0b4^N!w&tYiUF82C7TW-Ny! z3@N8wHect(d4{Xq@66$$Cpx+o#buNypm_J2M0bSB6|L*J}U&tq1==6bU6 z^~g5}t>&quSBnBP&)nuuC6{j6eG$tZ$)l+<+n|duOk{fh3}05hqTkdpXU-dbv%7z1JLq7|riIqZ+6j|5 z*G(DLmuv1OvlbRyy~UJBG;=9qew<_qp&w&8AVUVMGQWm0%Jd@tv1`3nwh%8;cvRS+yvAHLS|bQMR}F&4@MTfw4tg z9P>QCV;xk8!*E8KVd6t|6x5=;;`C!j4*Ecx*xO+;eYbCiMh0h?(|2vcoPLM)19N_t zt7>pVVTZzBerrtzKedilHGfhxM`-JThZ&2Vw)Rax>tKTrr(V>OT5JLrdI%8vVSlUE_O zarb!e)9`EODmIzQEywUN4%nd&9aIT>Gar9pEZ~|Oh2FXl5~J7r1J@MB{hq4*29C<)>x3QQO3&G(^9tNWs@|6WP0?87-&NwocJbPP+1MG}sG#7j%*DKEVQecQkP zYI&COcWMVnPPBJ0DE*9Man>7QkGEj#_(kgjXnO;Djr;HF&t5`Quo#zn-B3Gsv^@7{ zw6eKN0_xVtmDkTX71CgQ&uP*>CJS=@Q4kCpfv{FqCAa@9td6nyc3!0yTTCUyB550p zRvuW7QDSaoZ$g%aKU>;YGGrCO*&XSQ9PGC~;7bkMMuEKUC_Tl&=se+`V5^>AiAnH5H#qZ=FKp)5{J5_DW`=LRZ@x}IZ3S`<8Z8$d z%?ZGS^~x=+00Yub@$uJqb49Xgnq9bnp(7+I(^K&EML@R*M8)u!Q({}puk879+Y8O; z8m@NIkeM8&Yd$YF)wz&1sJ2a{=LFTf`{<|Hm7h z!D5*ndUErEC_iY}D4+MoZTcedZdI1?qsw8dYk$T_jzp>V8j1|y#rV9f zqd=rxY#58UqUiYZynwyMF{h4{wnW<@Qq}5T>CKdPgbsRdTeHdjQ)leyMI}sD;G(1v zU#f+lKubvAw8UdCd*TqgvIyNk_HH<3)CjD-(p>ajxVp0&m|BCQXCvp>g{y8D73<3* zXRrL;y1)#-Yx4lA>aMTLxB!V^I=_SbX9Iy>qA8_?^dl~BN&81^K6$XzGn6sBi5z>D zr~7Phg^u1NPsrM2k9e_w%pJ7``!hXShYK^d`HB~@^6>aq&gS!cg7`wi;x0^F!~8C0 z>Frr*T-xAG;sza*-p>~;~Po-v$1E_SJVw2>f0c6w)joaK#F>m z8m`mJ3>$wXb1RGk@a)9e?KPeDx4YPwAaRa?J?1bU?J6r`M6YcCw9GnNasI<7d4Q4i z#K)h`oX~1bf3*3Ho5teaQ+oSeu^_|2$9xYQAbo*s4dpWU?@fty3D+m*QN2AgG7@BC zdauV_jwPOAzs4CiVi4^A>e8}B!^r18%kNwff*D-HSVaXyphtWdk6tUGoB4zb!NNt$ z)CV0@hI}?y20`(a;N98|Hy;J*!+}6k283<&{O#VVx0RVGCZE98K2t%wId{kpv;|fH zNz+UD?U=={5DgA3B%f?=HHZ3*xCJ=&vi#9&8H_===ypao25f1&`Hhz6SR;nsVtpOj z@>zAiH<14N&ozqw@Ygu&;70I$c`Q3@*03>EgrHCGrLsJ0dcGW#EB5R-4|+C&aqtNT z>Qit^m5!28_QUFasW7JOJh$&Fq^ZJNl>fsXz5xFR(Idr8IOLckXPD*?=xg-(c~a$J ze4A;ef4F~%v1%3MlhJRGJoU>jn@Ug>m+sH^5n%DDJow(3WYQmvLO%sRPXZlOE6Y#? zWg_@Sbc6ZDH49znXS^^5!}}rchSl>MkqR0bkkgI+`)X5TZHo*8&hkj$!f}Sz1fM1X z@n`u$JOp3;XU|Z`)(6o^zX=8IO{3xvrQJZ>c!EF)AuK327!V3ytx<5FdZrw>Qcn;3 z^=+&^fiC%2otzl?20zZ{EuGY4-QGrkOLMKx2BV9TVP~u~>GRYzNeOBksG1XqXIY45 zZdwra&!e|u_5`Q}95BxXn9yoU>zm~XSJ7D{cCmD_HXr1*_#vvqGNrA$J}v&{{&QDb z-l)KlE1F67? ziN~7681*XfH4?v*y+j->Uf>1%eh^pe!9CIOai$j8^E|Z{a=p%TgyMKJ;{mxo1FrL! zqcim2mgn)$G8V{N^Q7f(aCOD@UzKi<;J=VM*xy1E|pGWM+g{fxwY-T)9YGJ21Zyau_62D%3vt$_1rhO|g zwbUx>ME%0^Hnlb^ri>w`%zhHlSwa8Y6r3Oi-s+_Z<%!4*SR~dI5RrS@w*3*kKc6GW z_nIU)(uhhF*Jeh^%e-euwAU79wjt)Yj}arK(ob-#eyoBhA)E3*WcCc{`jcC&tQjXI zdUNd)Te$wdFltO3*XAYmpi?zKEt+veGVr_n&j70WKO0k8;(t1%lpdtP${nDqN2!pHw%0^%K=}XoxKLu-^oHp6b+Fh#=a}jkoYQ%Svi3!cFOfob9qCJgUNUl4YhsEXEs{`Tlb(WJn3`t0#hUMEKJ&_kr9p1~ zqUTkn`ux@m7?#tfR3a3;lGkQh^$w24&S|JP`Zw3lBmviF+T~p&DLCFk9D`QxHpd55 zg;K2^=nF|pglZqs$5hmo@BL}Ptg5<|Z(K5-vQkcYmN`kv*~pS;|t?a)M#n5M6e za@|=*ka(>Bp0op(*n;NVF{S;$wbS7@LEp$Y{qtIVcx$4(feWy}0Q1^-1<7E+O$`Pn zJhRky%D}L$oW3jHo7Weqn|CM$hh@!E4Ev9>l0{Nk)-7cU6ZNNf4kFx-YHPlb2Kc4n z>)heo%hk3$xKH&G&eEd;%W2n{VG|VVK=G)MLDK7z<5{lgxKEb42K;nUykOzzG4vB0 z!E=2PaU1d$&@1n|YO>L;Dtx&+{-xG$1>Aq|k3$e~F!ya1Z|+;<%nt7URAa)t7SeCsKS1 zxTS|ua^MY1SsAnXDZQ9UJOHOX#6XG_|Cx1F$ZW&N!!WkJoCW+ACRy9GB>Br)g!Ez? zgGcItden9?%y-8N6A&7zuejr4^7V* zm1XW@f6XU>kn^qn-g64|&%^U0YPL%SKqB-Z z`;cG4#XPxDO3xcDyGM+(w6Lw-kCr&uL2Kh*%-^b=iI(OezTcH@HK~<)IOu4!pKlWr zNZC@!dNwfb?eIv1mE=ejJ}1*=@||v6cN*Pq>R4lYnoZN`F`FGYv&VcIEXVHdZD_R& zF@7+RR`o_>=Wx4US$$UGkiZE`j*M#mVM8In*8d55sP=;V zgA$3l{@k&++r>=65$NZ#gCGdb*zdfu_OgID+={;ApZk|q*3-52)yDtsm&UTZ{R8-K9y zdW|yLrFr|CE!pe(%uYMBeT~q6?J_v9Dx(?nXJkNU6>-`{Y(~7RuGP5BK9TAS9z^hQ zUZn^Kx?8efAWJ`*YMlVWHG z7VE?4u?I=nSss4cNhUZHtv74z&6K2rt{Nfn#sqR694+dAV_6Qwy~Am>!}q4o2=XNn zWnjD`8D9MSTbys*Rc~iE{22E!HJ0f-2jgrUvGCrT&um-i6Oj@z_q&XZO;#sUjOPks zvq*YXBrgVMGVltce!&vh6T}Pf6qpktUosB+bAB&UWq%^uL{<;se$kC#un`WC>$|KR`=*ot3~thhx5m9J_kVwegqP_n&T*8xYvU`uLyYo5}l_#edg zZX`sPr@bCykT8C%jkSOmtAjSjetHVaMipi;&DUYC3VRLElmzZ+}=JFeAr;AIevsxKh-^-s{ zdjAeIS^zztui8xggAj0W6~B3YA9)z2&z(jhrmn6oII3Yk99*@wAF*D-D)9*y%FyG+ zg8iXn4QJ&e_W3U`8OA5Ehq;LK^6eP*3v$K$G*WNWcxC6`)uYARsu-pikRPwBbKAw4 z4$!Wl1e5p!G`vM!^Bt^vqBicfQZy6#eRF;;VBG-6NeVSRNC zab|QY0@=(jcOdP(Y?FHVyYYQlER{Dyz2ZhZl{c~69A5jM@8C=^trD9_N6H5-#i0be z+h@zFeRb4-A0Xl(J?);FZ=jKKGjx=JitdLe%d^2DibuHLK#oXC%lpO9YZ?MFEI#pQ zz_41;5_`mw!#i+${-#ioU*yE^yIohm!^6Bf3X#w8hx7>Vn~GH}?k8EW5jms&wR4-0 z-l0#Gwkoabyt5qAej+c^zy5^2USrg56B@n7!OC0#X;+J3i#kM`!`r7B;&+PgVNRw9 z9MNGsB;5DP&Id`RFCs|3>|}Yx0ifriN1^hHZTN`nH(B#xBU-s?z_VE$nws}eB}WSXtecMD2Us;cCDyOMZ{$ZiTA~-~w5AY6Zqdq8*ciqZ zo>KrT`&pms|Bw}^xlqXvj6YYqapl1$Zymm0L6l!#Q#T*eM-#tsCIlwNrB|bW(v^|@ zNzEtvrq78~thWKbK3Z(PzBVwo{kgldFwA>K{+ieIZ=X&c(lnajZ#@4<^Oq>{c)ijfzBEtTAO||kY z?kg-Ix){8|_+01S{f-l-F1=b-l>T|~cEnYdl@C=tm>%Q01lKEY8$@0d8s4ibLilkv z>!=PNll+$R6xB$9gYJolF2qDg8Y*wuyLry-TG92J{_{fMACnIoBdB(gCN2jG0xFmd zy}`|RiD||bBX)jd6dD3{CbJLuOPUJZFTBkJiXOW>zOiBHO;B7_E!Dn6eXc;qT8d?hJh9|}FPx-#+&0;nhEU zZ&3$d2Y`y`BTo)Of2q1&n>uF+!Q}hD|xrG@Pnu6MHAP|V~1YrjurnXlxdXYCFl#d{sgVtV7~zoD!W zmK{^hyd1zQUYS0P*xRn29c0>IzrBxF*US^PQp$WN(MA~K@rzAa)pPY`c{?h37U^eS z(HwsY0db;_Uq`L*4$NVbU8wDRLCC0=n`>_Ez-`=8_4PI4K8FLs8KeH={6h|*%uDfX zx-FF|**%muF4`)*k414K9xciy$;4C6RvAvo&i4Qeq!~g!-)dRk46JWjO}tO3Ij9TO z9orCFy!>c{*zA5>18eqcL{c1)KJ$bdCT+I+D37>-@3H*RXXH+d!8_`F!z2ahkanZO zLm3o46?coU-8i~!Hzii{~#c|=>EO45hPy6p?>HSmTrwqqvG zNLThi;ahf#x!*CK6*+BbvEVG8^?@TGX$Z$G9%8kROek?@JdYtts|i#Ug6#y zN4S>J7rwVF${vcH0U>xogSdk~(!@g)BBSYt`TeD&2v_CuhzINH=O6S0pMR6GNh#?e zVn!*lMi&0CRQB<@S!RjW4RcEqH|_UV=ZGlhzbm2jN{zB_R?7j4iwFoKQS5+SQ;c|) z_i6g9a61Ejp~&H|`p%zZ)67Ll^ojE5V5Nd%+sZOpt-_>CxiSJzuRiD(B)ME2Y)Z!R zE9x!eNo#gj96Up3EF#P#W*1iHc$EHRFGnkvPcpuy)u*B?*l-(OReebw`+nQ9w)!JH zHv8qKt?+%rhEPD2TQ^U%`<4gjtK?%r!B&-uoN}D+M)hGo!eRJQU3?>=!B~ zWM2|B9))hsmzmR$00)gzRi7efbz0n4edl&6^{`Fu5*27$UCpbY`?$R>Z`ZO(1WW0( z5n30VOEKHM+=+Z|ktRt?H@)9j%p(%^oP+?=txwDMDoqDe z*rlSY{pb=QCDs?x`8m=)c7=w%Xiq^yxc~+h?D}m4CugCm{P&b>DMm^wl z^uRZKNQgloy|1C7THoI=;%K$WIXX@P6LnR7yF}?!?F?vK=!&V=VR9-r_KjK@l1kQg zbX5^xe6lCF_pva8F4c7v%Bpj!RmMG@Nk(LtZ1C+%w9ld7sQ1fVO+x*4Bwh`SY&(n& zC&p-2CR+7Gs)1edDPK(>;qd(*OGb`hz_*qyqQCj(p z0a|jWW6x>r7~=1tsf1+X7x%;_;ifkh1A}Mi1I}l>kxS&Zi>Du*R2sU3PA5}~*wUfD z@-D2#o%y-F?JXXB8R;sCQ9^mxjlU4|nVl6Xceip|ct9)HM##wmM4qK}yff_zrjSor zvv8;9V=6gAZdHE$6BA+*{qZifjD5`}4M+%8VI&(aQ}!BgdT|^Rn5I4C*6`*-OsX%P zA*w<(W!jkfoa#(=vE9Z2C43W4Phd#ngIVK&Jfj;cXiklJlJOlMpwg@YlT=&Z{2vChGCt-dEFGE^Yl+J*LxYOo9G& z{SSfTJN1lM?;uAx);Hc}dGuPS+ysCN_0%kSD|BkYD&~rLT>Q%y*88JZ8x6|X{?va6 zZw7v+=@xh{xGBMB#t;tb>_6Q21O*;Q2SiYDU;Z`C%rrYm4O6kUxpM9mb1o-wBN zj@;4S2zof~o{Dt?w2E3Xg1rqPj>r7nJw1Z!7nETQj=!GUF7Zls#kwZ00M5>351xdJWA1*=X zPzZB6imk>UZBaO-;4-LkLVyTdB3ieZvm7Fbx@I`Dx#Tn&zPsH857qs3hyM~hR z!V+H&wBSIVA6)oOUP0OGv*j5jM~E%&mAQx@*)B6YZ0eI7Yz=G0wgzS1Q$m@jmcEBv zZ87s+ByXfeM`Ii#uu=D9hrbEa*1_^>F*fk^<^-pI1*$1I6Khqo0$c>q@g`Oewx}{Q zc(4R)=r-61+zBoX`z*x9!uDp1@tL%9yUy%3N~efJYay&?kx}0oH9(V+K(=bA#s{>W z;^nrahbxv-%NC@r3`=ElatMu&T-E58sncld$Bb4@vWIT zDkr=pPkPIWxXNY;xGA21Rgcd1Bw+El*370sbvbtbe(o`QHSScP$5fhn{ncE=qv+4| z?w7P+?$?A1CA|I|Ea-b}7mpPV?!-I{$tks5wbJ29`cI#hNlQ*krMODo(fC)rM7n`7 zdDB)ocBW+f51E&3zBMMa_lNP@(0@s6Z;SD@)8nhF=s8Odz6n>j zTlZxOq@RYSUh{1lTV_ai(H>rma-1h#DplDc3&y4goQ!>A%IoQnBS5DKCwLJ=i^lrJ sRV3YJa#;synHnb{S!ArtBQOtvFjK@OFuzD;gn&PJX=SNW3FE;31M3$fVE_OC delta 26906 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

5o2(}R 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 E1E&Uo00000 delta 27520 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 E1E&Uo00000 delta 27520 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 E1E&Uo00000 delta 27520 zcmV*8Kykl|>H**B0gxnrrb$FWRCt{2{eO@n*>xU>e%%_aPOVIBW{?V3E@{iRm)ggy zM~VZ8lvNpwF`1(g$!v2q3wU;R3TkTRWiQojlxCW&VylCV?GZI-iS(f59kXDQj0Pnt z7A^8wsL=YcAjXQFqPg?3WO4)Gh|iVOI^365Xq2@!_hp7=Lv_g{=h%6FoWw;U0aT&- z#|)+52}D-n;^xhpStq|d_xwD8Wf%8`k;rdj}!$&H}qG} z^hquH@Z`CfK$?9O6t^&!7f6_~Fk_4QdujGm=%eyuHmhFT@9FJwd`q`4$G3Dla;&WT z>vQG5=J)d>bK|~ydO6sMm*n)RXU<2TSC5eItmj#{)eGL(nMCF5L73D!@hi;Dp6QQ& zzupaQ25>Tr_mEy+oYjs+%+t$|6>DiTrbT$Vz^R&*i4;-B+%pmS5YnAv0D$lNgTY{H zYilqV_`cuibTDe~bUNI=wY9a=ysSsyo`b=X`kOITtfghhyT#1_PVO65VVqTJ4e9mUo7v$P zuPE3zu7>g6j)Cp?K&iFE`!n-twjS>&(hxh7o3|6%i7c5|%R;Oeu0^&D(jct|0nq7m z%H{IDb?S8EYNylDypnHUUtcem%NT*B@B5Zl&A0G@44k?%fO5Iq>2yvvuI^iZr=~fN zPhojgJ~bc3hjU|oC_Ohljy|>S0|4O-%pp?la(a2*uNgUOok-;eA?0>E8>C!!sWS73 z<@7R@Z--m-_)4v9#|JwG!gz1rxOzA@AIW2RI+^`7&I;N*`r>Djvv%Yu_l>L9RGaq~ z!D-Fb1>R+mBkRMMonzVk13OlK-Y~K!hRSsiq%aAnd7dk@>;1Uj<35AIK)>txKxViC zLT_zt@qYeknI2XjH4p5!wze`pwoYj{-)Uan+S;iC|_;RaH!p;lAco%w6lr+nRY z%pgqiM|C?JwN9)k2oAPq4x75iScgm>t|g6Ys(rYSlkt_ac1WKBoz#zinxynLL?}f8 z!W(ebj)Yzh$+%)FS40-|`Kv=BC6Vtyqy!Nr0hMu)_qm-V z*8*~Dq+DNL*NqIualf~|zOFmx`^-dW#&tf5r@=$%Mmfwo&I zbO0RDIj`jyi_tm$F0AvIcu`ogBmQbAX^}l%8Y)T@Fo}qH%FDi6TU-0qDc#O|ndfrd ztssaOo&=57`Y0`?vlufy)bx1)G-~KDbRXUh27|(Xf%+$I&-c;$FYoPL_q+L{ zUf$c|&mnV|**-Ccy}j%H@wBeT(hl7@-R092*mBnAvP~DK*M6GwJ^GU^PE7YnSuWD5{XB8t2U+FN@EF`FliK*L3Uy z4~6G{yG-eIrPg4a-8ZhDQ~^`~IBVW|Z-RG?v&_~dvpsVVZM5UBT4y|y+cG(17LU%P zycs1sWd7qZlPt1JQ@!+SuYdClGQf%&6m+VhTVTx1S+(Nb8T!o5w^ zZ9-|mq;>CTIlU}slX(@u2~f6{j~g)RV#$(!`nPOm%2jD&{B=?|o_CsQkD~1Gkv?wP z#GNDu?3^@j(j1E45a!l0j&fi;zJ?{xrzHYKIwLnco)X49iqgaymU zvFNaufTFyXqhhL+c=Ww^^-ktgt6<80YnKM~%Zs~1ZfwqmS z05Hzp$E}i5AOHn<7uAy4mIrfRXY*Js)6?bP6GzD>GX|e8T@+8J*p8|I2s1_+muy5a z#VP`5dYsK}O&`L-N1Pjk9}YY7&|BF2~hy!taiGnEOigD{LP$}hV4U;`}SyhouNV6BAdPY zHCbefS?iMVGo~n>8a#iBK-xopH5O@NzyN8FD3Q~{C`CbvK-vJdV=0x2pkyld_TgBa zX|0P=6pe13Fk|lHOnRQMQIkk%j-C%XOV3inXL6!f~^;_ z%aAdnUAb)d6RjKl!Gu@m5&$}@mLSy(Hm9N5HtgdHc&`e79SMI53Ti*!B9xJ- zoPmOS6DgNXgoiOSQ+{1Ib3%oe^~`nQU7_iRVPzRL+j2=b76ubP3z?}1sJc_*(5Mu5v3?pN((s*#unN981U(W6j~Iqk#Rp? zS9YS!-r0ge=yCi!C#Q9D#>JIU~Gnrut><)B>>Gna-K3D9wlhXkn-&5&X-k};y( z)lJ8DF=_9A5&l{-En&u(dIt2Pl^6Oqgq2@t@=m^kV|7>xiefp8Y}*p1;jJuZ3k*jSzscJvnMxt^1jsFd3oXxXOs$!0(#4AGmzh_3#>O7V)@_;=pkQ89J zWR4+ox^v+|R+eE~qO)q{9|NhV8Br8V7Blovu93~8WJfmw;yE`X(&D&YK^A0a_OBYx z(2g9dV_U)^ThFJq?fjM2>uH+F^m*qZMrB2RfnMpIToKivzT2xCGIqW7* zU5}~d$R9X!QK&?e(fV1Zif($;;6C>N*3r@Gh#D6MFIQS-sw!oSKw> zTUqMrki?mBTqh-^r-R0dsIHecsiSTqJUzdLyITg7MZ}UL7lqRnjl7bW$(rJC{WXww zUK-BJ810hitXecF6Yn3`0Jetl-abmE#RJwYAs}NlF%ve#gi6_#kcqVuS$q44V%f0O zw1;4xahKANWoTDK4C;A_MT_-%V$EQG)3Q!{PwDmUWMS%=ei-lFQ2rqyiDT1u=U@ob zaD2z{nS#Xh;^w#m9%=m!m68eVAIuG@UrIyA3N5nyIg$KQP1we@w7s1GfGeWz{zPY~ zfRXhMfI}2004Nbm0)Qx%5!6t|L<*o7*d9p;Y#tAl$_wHEnh~+ZyK30Nj9trr8p;@e zASFjKv~BswTQ%A98=WxrOLoTD+X+vP0N9{tWX4yDtOu={sBaBgt$L?mEx+qdAotX( zWSG?Vjr8z7x39K4oaS-)f|kMp9kQA{d{KDh*{9{;m1Q_2*s!A24uu25*q4c=bdbdAyKeKGuaS-)`l26vMNQPl71-k10Y8F?89Yf0D5((Nn7mo`==LQ zGtH&)%JQ^c@9xs#OTF8mc_xuOoxGC-28Yu$zG{2#aSxxVFj;U>n5V*`ut3`hH6z;F zhiwTSL<{IjQHdsw4di$cmS?h(X;mySZ4qR}U*5Ng2d|i_u!zjY9~oJH=E=}``y!8{ z#g)7rUX47fh?HooXuTerV1yy21M2Q6-D}6dlbpbyb-K4;4uji+*!zIK6oVDA?IJ3BFnQ1|8K61e6aTv*FE(-HvYkpCfLK!39KqA$! zRmYKQ?gVq|R5cQUokJ|L+21IyGtPsee&aL4Y9Fb*-Gm1O(2nJQH5n_#{;sIm88_<3 zU>MncD7yPWGivL14qquok1>y?&uffUhg!nPUp|1^wzF=Zo?a|wmvbn~z5?dP*-mdq z>C1cVosC}o1bJBqR+beC2*N}KScY7pb|$steR=0ZRTZE&uL7G%Jj<8scVCSAKE1kh zqCF!>S<^g`L$@D))?s<}0%IFx4~{7|4uOV(A?+<9R*5Pxq8kxl)o{9L3Y~==Nd?z4acma!}u0@3&51 z*>#sHGRbT$`DBl-WBNALIbO!&Kqag?R zyeQ=T{R7*!W+?CYUA!-)znjUI`4E--fU0-IGjOw4AC6-%rvBan9Cx``ccFB(1n#KEn0L+!jFtY8cPo#K+Zet4oj}tVu zY*5&2@q9KM#dN{)SQ%Hd`@Jt^2}^>+7B%#plvT1=6msdlI5r_s3V{Z}7F3D7(_A6V^5dsu%MN zr>Dn%Gt}1=Hd_%?{w{^B2Hybyd*>a8SEcLo+noHKoU~ACgYYAHo+pzh+ zlWkkg@qTlQK!p|n@${>8L2kJ%(OeDAZXeV-2ScsVJF!rWl^nVlbo=J(JTXG+=Qxkh zN6Oz!x~NJZZQBxB9eZFntaM|9Uhl{ALhb~ADPt7dr}2-OgXvnB0(iM%NQHJf`dT$_ z?~-qWPV^F@VTiC7s@bPQc=_cSzfSMW>z`|3RBkQfR6jkjo$9ZxW$-+CK09#> zBZTg4Z4fEGQhg^QsQex1Hfkk1vVCKJJE3}WLl~kvIuTp=>O56 z)g%z_>lVGA-xg>=waHyjQK#3BjnMN_z+fs8WLou+r$Z3BFrXsCwHh0%Wft!=+=@{> zD~?z}PEW@O&6q6{t3H(4zQBw#ZCxi)7THlJtTQ0C3_2fbo8RcoVDc zxN$dt^WgZ`>7AMVlNiQw);L1w!>2@5i*H4&B8|s7SiNwiywh2=gc*miZ&815AEr?Z zJLkL6>7-WH?gWn`GKzp)X2t7>UugDkV&+uCqMtGBhW++KjW!~HzzL4UODXR zG#%RiL@(KlU*gLRl&spmV|BvVZ$|C9CAJgFX9y97 zXn7sSx5G}f+0X3lQ94&K_j28iO5V!ZYx6oF2hYb7GnQQdLKz2ts=g0F?u7A#cTUDA z&&w}5Jp-P^Z3{Xx&DZ=)X9(T20rald0Ss8?yIu!CNh1uDS84?@>Xjz9STc>H7L^US zJyk6YY+3euma|%OZM#kY>^ha~sMoA0MLbS-YeOm0BS%n;End-I2H;$-2s2i0snu-k z#jR^$%6!9!sI>|QiSe zpw-rRtlj*Xo3Wq_jXBo4JRKLg3ka=8h;L?yC{CM)n9U2PvkXs|t}75ogmM!=v*c?_ zVSSh>MmPYL(F;I{kV5IeZ(gIYf|f~pv}wRTFdX+ra11R6kby44^O5~05qib2JC0=Y zp)iC)La#A))|}HfLVrO@5Cv%#KoF$B92;#OaXYKlvJk__?#O^InGu?0Xw&cl+2Ju8 zc0Gz^sAOIN0$|hGvg>}-?r5lH%OZge>f%li`Y>8V4;?$LdtC?j5aQ>%*E`s|zL6vc zJG}~(jX_$cvJq}=#5dz<9A(VTW71Bq5~uykt*{lYZ(WuOYJaC!iDHTB@{NEPp?lpm z#+wLAV?Thc5%v(Ntxl=q$WkK#;MEBLs>{R3E;W*2WE++Gf#EQIBi$bZs@``VM7p18 zk< zCBL$ihNVW*uz%H7r-Ttg_quD_36&a2qB2}BH4@tr+=uTQqxEV%Y}L%lnhZ8~_}86Y z#Ww6<=k_af&BMfFVddD{?ywSCBUCtKO?rC>9Yo_iWA&CXuQN-=07PTOGQ2qL<4}h_ z1!WK%qLOLxntjFuZZ(lcrqj`)XS*agwu(cWG$a?)CVv~l*(D8%bgP9lLivtT?XMWN zLqY?jcJ|m1R`X_^=Z{&|u7Xns8v^r+3ji{efd`pbvGTN*gEOx-h8-TKS8<1t?N}YR zkHCW$6cyVwQE&S7PSDp-y;s9+BXohmiu|?+LK}hP{03Z6<%r6e_rMp{srdb%>r{L- zNQYsSw|{A~Jq)V=cpE7{Srf9f+3h9WE@X2r*zr;<_j?sZ2BSi-;}I#|4|gglmK$Af zn8cl~UHDa_$l3N@ve!De)jSx~lp@h60YKdYuv9bjzSE3LcH}f;$LcuE_*$vHyHi;) z?A@Kp5@>g)a(3C<-Khj?Zhp(-<5ml|S{V2yp?}by$8m^ucPjkru1C7PA;j)Z1%Tfn zp0hfUxj!H&m~T0H+`uXQk}2}9(sjkQodRrh<9im9At zEJy`Ao>G**52$;+iW}^BB|^Vf;rrQ@ZCTnZEtfl8yH>9A-DX-O9pg;b=e$a7X17CV zLVwGlQ*&^E=rLg5RT;YJ#{f3SVT2BY>>;VO3|1|NHP-@>Dabgz`_$wc}pi z?pOe9{^|!A>{Sh~;OF;zf|sG3XjMCqmc|d)|TK;a_Ecwl-T{XP!e&8B#h0ijyAk}e+ zBVroEPP3HlFjQNkC}RLhkt13gtL5ST;IiG8Zt1i?)Kc})X=&$cHYQr;_(N+F%72*9 za_k#d`IE1zyNH(hSR_0W9_jtft$M9xY;M&Db(Ka{0A@$TP-#o0a!b0wfs|%PP~EYp z*6UisuqtbgMKu6U#jjU8-7Xq#E9^PKbb}pFkQ44yNTvN=B?daZic*wEtbQ-cezvt0 zT)paFz3NMNXRr3ow)d|0Ex#25aDSTdFtV3w#xSy-W()vz@4#>vv3T3*Rd_VN9B35h zElVlWVIR2RC6n+ zZ9DG982c6v?m9B*{~~ZHlo6wRg1lQt7ofdM2;J=^+Tf=VS~E9By5zLk25=z9f^Qmz zG1PV{L!>>i){py8B7zK&`edkbGmtP)bzA}lE4L3YQHJc!QtuifI99IL}>^}b81y}9$Z9?ZPtv{Q$+6k;TB*OuMxejp4XQ`s!} zov1Ap2~shj_0Rwql}mPX`bHRdI4~UE31fe{ECIg;6W^9@=|AAI+d?;K;b>rc({hDw+w#`{zzGw?7%Wk%f906aPS}i>1~r&+piDJdSkyn z1faT07RcWz14y^_Z4%CoX+v~&T$_Y@dHW#V+`L}v2VG~a8nrv&&dPzRcY0QQGY)P# z4Yw8Cbc7*-n+^cp7JtYZ$qa^R_R{|8>tZPlmwZ^%cUn=&j`SA5l8->zogEiIr)SB; z!iEEYf93r{#t)>u<@|^pNxi-Hru{ zq1q~HSrtZT00BjHvMo?O9qy9{fDl<`J&2n`>y5GjptM|ed^;9~cKl$ky}h`3cD=Q= z6#!tIW4c~nVSh#!&XPvZZK@&<3{JwMa?T zT>{YUr8|S(PTTR^TDY@fVc=fg?he}a>CWcaW-1?SU+qSymRFW9H`Cr=Z+d#Xz+&3# z)~?C;^nZ16O~##`)sE$IttJy|$wx;9OFo1d4>~@8PS5ho0V7#uQw^gGeGea>G0$m5 z4O{JXYdj7g3*hoK>za%kJqO5ek=vJiG;G!1asBcPh|%LGYK)geYOh-(Qo&7!NOAk1 z;|D1^JuA*(Hg9Q!%E3)XDZ+-+7I@R>u`iVgh~Y0va(nYqX?qh=Wv8xN<;2n zkfDJI@w6aAm+UCmmF+l_p^u#Zbi@j)CN_k1O~x!n18A0fZ5p%y->$PrjgdW)F?&N; z?yAr-G$S;o3<7K^T&Zs7-Agu|t$9$bXMa8uvnLwo`$OwM*pu4s&6*80I9sisW<$AI ztM&)ge9m;67K%QS%{~3ew+oN_HHf&8cZm*q-XLDT-W;ar)he}i&v&TWNL8g>_2o9) zK1{FNu`G~%tqcHeA3(Wd0l3_$0~TfzFeyT0yjZ3WC3Oi6OE*RA!|0=eS~L&zN$0OKg{Z};45 zGTv&}00dpJ6Ir6}-Uz6&sg}}krI!6`=Z$|OAW?URkzH%by?v~%yD<=S1prZZ0bIUj zZ3v6cRcp$U9o3o=z)Fp_6N-8s%YV@G#wSvIY}E63=0lauJm`4<{H9wXG&?9!*52u6 z{iUK>Q^tVYafuXP3!i;`%Uos0pIf+3)bo@g-j_Qwcupy52Ai9GKM&QMGZIr; z=i;%4uOpSqRae-SVgzzgZ#(_6I3#94x5pb>S(7-6(n}?R6^FQfRH{4bps*wvXUtG(<(uAQ_`Rl%MRd-p)+fH*cKVI|BI-@=5 z>yO+j131{(1>la-o7c(ibltX5y4>~Zh8^`h3y6AN6~?XJnhg>i2Y-OoF##BDVUs{< z9YC|^#87tIwm@bpwG_3td;osC4j}9*0HRkjw{5$+Wp3N$T9bA~xz+?=SGNk&)ZB2r zz5-x-w`W(k+E=@2csi)>rr~Kmsxi0~^}P6IEO*>y$=~Z$FhZ#e#e0kf96Xhe|Ov2R)BS4Z3R@ ziFxa{R+XZt=P};vo>9*eq-ss6uZYhp>KPKJP;$o|CULDPT@mSPXN2Z4^{i%wEHP9I zA-HG;a>>{WG;JW%CJ~k0_S$)TV3g z$t1EsrD{49HR|kR{(YCckzH1+O*rC^vxVfbS;rzpCC^#EhB=-#Of^xjtX5}2 zwWeeFanD?Gx`{(0mP$OszjnD zmz)H(SVghXwg4DyYspC}9nWx_11A7LO$C6O0B~S$0;qIc0Cw9ZQ(&{FTUxCR05>}T zu-x?lEO+a?KiJ!kgX&;!f4N&`}qR!x0j@TP~VM%T2S9jQr~T_u5OkFa&NC!i5j;C-AZkA>-G3c<*t-$ z#$WSy<7MAl@5hx!ytj|l&D9vV+$I3az6aoP+t?7+Ue5ziX~ZQvsx)E%qH1g>H0V~? z5}qHwQ4OR_h}584DG~VC(Y7KL4Z0PjsN3}btbcB<3Nzm6*r)AyvZtpMRT{DGzwCQz zw9mhC&z+7PNL#mXA0o9kLg?unECuSywuWk*3bkNaJlbZiTn;Ow@^yE!?mA{s4-Ehz zWSHsgH86JvZ5H(oIfvFS%8eGcOe3^si%7Pj6dS%8idx+2m1{ms?_khYQLGZF5D{!^ zy?;B{s@jfgby{kW77#k=HdHc(Ps4GxgAM>k$sGfmU6iXc5V}CCdmW_Fu9Hpmz#3nd zT9ve0jNjCayP~%UcvEr>Y1D7|QPkzQMiyA7qlvRY4AHO^yD86;p&hHU6Im?vZuA7w z=$fA$o)4XL4X_NYcM3uH8u)e8carwov43R6yKmRo?T(Fz9LADoPz%5ap$k_Lwi+eb zjY?kmYU0a-+#R%A;rb%w z(T|K0^K1dY8UcApcCF3offFF9< z5!!Fp)owBqp?NDB3Ae~$xa+iZpQV^YE8Ehp5UmXWqE#*{W{ax9`zy;BbSsY4k;CwsPkHYsLv3Nq;LTEy@^D zc4g7`cM*NK)^ZdOdRepqsC1_6Xg18`H0aBZ)1Gd8h^usbp;W zpj)16b~j*MO8{gBlkf&co}ogG7}{SdX}bde24;)`F!Qt!L(f?h<{8>H&`hItbD{$o zQ}WLweLu74D@-am0(7P`zJF?y%Jh115t^1j#&Ng{sF?5TwRbv^@@$Hu21bd6VnDbx z00KY=0R13iwN@{_GIGD-l1X`8hsqJG@%0&1!6D{MCSPoHa^*p{&EPs9+k_jYF_jMu#z;lUrvioZjM$Vj7qzK`;BVlEf=cR=t(Er46 zVo>s+`bSug0hk2n-1><;7_^s!U<1l{sIs93X|`_)J5lUb%G^8}$OF0nknRD1v4Z`5 z0`c9Sex+z`2GEu54iwNRXozMqy4H;_F@NuMmIw=F09r$)BY#>mH+f|#rNluLDk-HD z+Ud%b;Ry^0}1L%x7z#YAs zghx~+;#$*QP3hzQlTTSbuf|PihDSg7oiNQmtC>qjU^BjE7&p0%)|w?T~>Hgm}spTyi;wb z`hRD;L_L?PVGZ#hjQ3ywfTAFbS3#qo!*oxOBUK2j`aaeCYidvjplxXY#Bvago*9+M z2-!Q*h5)dg%9xa;$R+@G(hqr#DvDX&AUpR^njX;IPGx;6yhkP@OQ+huqZ>JgrkxEk z>4i&nj07dk;8sY-x_(Fu;DEnDWo-v zv!tP&F&ef4`myp@-tY}D634(WiFG9|7C8W$MGjr$ld}QpCq&B|`3or^_nlC8KM+dh zp_&j0L;`h8g;LxHKn>C$9m~+;JWIeP;M+6^1{g)o0wCp<-SQy7zS`n&RBqo#t$$hr zj1{%JMysaIJ+O3o^q*%lhTf!)Kt&z|0JWQ_C??w?+oEuS ziOIH9I2O2t=}Hv}WgM+DUxcO>mkYY^PH;IgO{yRVfNP4yc^$y2til9evnUH=kPeY( z@J3EJky2Jxs~b048)#WF4Li|re}B*&w4owoEI7eid;2gA=4`|&V^*a|k^sP993wa| z99_hADGf_DC{oU-t{3JcCN8KraL1f2Q`rjFEwb~AMHxC)R1a+rK)hkHF7G}7wO!!Q ze^uEn0|>%hXt!zRZxtE;;Q2Y8HcRMi=%*0xmf0V*xAyWGQq}m41Ng<31k}<@(rT}mV zmum}Up1E`2os2bHyI|o&O3B8{dM^Z^b`ut3!lXY;B>?upu#&(~v1?hTks-05tdOY& zW8Q|b53a;)L@JlHYMOB|C4W8NwhUdo4~nEJE*9gYEy8w0R=H{@N|9d_szJ&^f?A!B z768<1A@eid;aIAcC}&07-jv z6Aok%aLE)Eo!)n9X&9pnjC>c5#naR5Ypeh(Gb7OE#Su-XV=MHL>3=qXIOzg_ZeoJh zzoRvYg+YvR%}kif=P3m9{LN~Uyl@gGkft}>7i^^$LU^ra%V^}88^BOuC}W@_q!?+i zfDss5QMOo|6gk3BDR+vSXX)>b&U=3w#8<~q&0lR5J7%eKFa&VoAbEM_VPpOtY0aQB zF|RDsstLe9tG44(_J5nP;+1>-z=p9BuV3d5nwtS2=^un9fK+a^)5wMhDEhTOyce?W z_vzK7cdi1HqR8E4Xid{5m^x}F;^r;gL+kbnqiF!k3XtkTvI@v%5swsK~s>-Jh z66R)1GPH(gmF`@VeH-Fuc84!~_3g7K``yD2*_M;ScxzSctnnw$T_Q~xphnIvc1upxjXpr}bDt5!P*O?J?WAOSQRgM&d^ zYpl~Sv}&j0)_)$EVqKMjc*nI)2XemCcIzug%((I2WQHQ+EYdxq^?cpYL&$3;{l?KD zYDdQVjJ_`u6|cfjt10dB7JzCzaQL}ywtu|Pl1V0JqL-Bz`8xmzlfGkmUaLvH;c$Nd zK<@QJCACqIUGUgvT1STGW$5Rgd;42|>T93+)LWi<>VIpvXMC(_TCX<|v7))Tu&=4t zx*_|)!Om{d=pXFt#z~t$QQ|U4tIli#A+4I6)C(iC2-D|(`5X5?`@;Z!^tt<>#Qo3y zunoa2kAD0u0RHvg`5b^By8Oc+`M`5O4&Yz^XYW^0{QtfD17wQ-<=tQ5K4gkN|A&7H z;Iq&DEq?%C`ouf*_OqXQd!gn1Z+*?qJ6^N%j@Nws!HLh#J6`ktx4s6=|0kM%hUT9E z_|mg)oHq`EiX(?J&NbcgsZYISW}h#7;%yTntNkxL^F^h$zVOT!0etG?{}X`!@!6*V z>^FZ46w^gr>;Yr~}fpZ)nm+q=EL_2_4%l#gBhi(qr-cb|Pn!)-nH z+}j-zJkR_8A20B=C`DiR#M_jj-+lHSO3~|H%3iH`rN{YV1vY{4tM(@|5Vk}b^8`IQxU!Y1Q%ekc|^l5T^H)2ZAFQpE`Um8bqq z#SmH#&7E117eUqyn-O|@*a85Ok-~=XIOc^+!RABukOr`>oFH!Yx^mO6$#i?}4H$tm z|JRv*`-PVPeEq@Ky!ah_{-x|IfUj>Jfq#OpB;B8z`J=DF>wgIM-+T$PE(E}GRi5cOrWJ!}oOs!6xO$1ccSUw;C3J2QGbOd$)&j zqdRDqylt`KUHbTw@HrL%Et3a2JOuuizfqG%IzxZu5Ad4Tp;W?fh?l;N2Oa`|;Sc~y zBMlFK)h+p7^?rWmg|FiAUp(wU-Dj%h{@fa1-pmWw%wjhVrG1EHNZuBHYK#nO*D!EN zY48T%nBFva|NU$0FMRdwAN%G1Q%l~j7*C@R^*zna07}YPFFkN}H9^=7#Xr+SX7wFWfqdUL#r)D0-6JtS{=RA$g z7$GrlKlMydX!-cFR|_qlefBJXo#xqmAI9~jS{03;saAjGnRF-JXf>=vZM7Pfg8jgU zh5%X(D@^(*H@0_sB`^E`w!F@!v(<20Rck{S;x3dVT#QcKT0Pp&696+}may6MkW+ud z9Z4)qbJQRJmB?v?W*Iu>kTpd%LYujLw66Pk9WUhH(D%rElZbt&A@V2+ce54xHI}v~&Ng1;BXD zn-2gGMuiK7E%*;&((t@lE4R9XLi>OI$VE24->R8mpu%`>iP``N5rE(M!|1Cw-}|rH zD|xr?(sG#t=_N#*%#IzoD|B+nNtT>s>GbO1AG6jpYt5z8tA*S#c~a?40f3nfc6O6) zW4j;7BqHN9nIam!*DOWYT(%(|ea5jN>Wy~+s5DnG!t8;y1EAG>FMuC?)=YmC;!Pt; zvp$bL<3tJrssoUIlA`z7XIE16c3STR&}+R5BZS^*y_Z1T&IrvT@8H+N)_?WeFTBJI z!BD5w1pvk}##jDeHt6Odys$rwvWpy8kY^@It2KD40J6z%KJeKe`W3!XnQr$Q|L=YE zV5iwyqV~t1y_(W)r`ZC)+Yx_4PqZvU^1f}aaf@TEbeb)0UxxhbvuAamon{@tkKSM1 zjt@G`mQ<~+#zCZZT8+QM^VG(UFzHJvw|9HpK|4(P0-NIgqFMk^bl2vDz2}hm}O`iqKBv;qeqae_YkJdS`L<>3#REjTF(o4 zWVA*O{66$hj;rR$(DTsrg|Fh&sf<$(1>M8s?5UrA;}0^ido1f8rHA1qgk^X!%E%=g zDv(C#0#r|9^C5t}*-d}GzI*EV&-=mWo7?fhGUSRCF(i-g^GNarpwrFVE%44{Xm+~b z4<|ax>o<}{pVbuEXT;4N40}jJC3SV-2r5L%%8)4O$bFYThs?mf@?!x0ZgUkt<;pv4 z2yS_z`7WD8^tOKspmF6r0Dh#otov84ypvmO2zll&w^J$4{H1?^>Zh9}06V|-u!7?4 zrx~q(?LFKM;QwXq02sXXO8}B5-wELVv$+aj=exgQG#=Rb?r$*WWgNqb2&O~i>AdcO z>G5C0ty{CY0xy00umhP+otoLK=k{s*IyN8J`R;FI*G0>GrF@O~?LTR~OBiD7;{T=6 zM(^VPx+U;EV1OVRtDkJfgPXO4t@}Yf*Uv0LM9q5*2NbbYGa?7Wib>8Pb zo85%>0c^(y032(jcfDqtL8Ny4YG|8*f}M|n?GD=fVeqb%>l(Zr(Yg)E`$W94b&$Cq zgKZ!BE0dO<^$vhkZq?Hv^D&2)u?Z~>H*!ytbx_uVMz3@Jn!ZU|2$vYkc+ zga%+6(B?q)^r(|q-dI-MU#{IduZ_X&yqm z`&l`4iJI%wgRuQaY2#=u$00yF@7Fo#JFzn@RloFYJn+!{db)S+3ApSQlEfhg&zO{+ z^GIB=mTG@3qgtCCu*?YE{2$i#Au84q0LP^;P}}iA#ad!UUxrL+*TMiJ$$Oe~>H+?m zxr`nK-Y0vVv>(Yxwj$X|`eD)!^P;dycY=5&h*u)nl1Z)zt|?Zgk|!}Yq_fsxhj;+n zSAHyl{E_Bzl#bCif_%8~E&zDv?B4B(}2k5N|dPwz}Oe&rAF(zi36-OTW-mU&R?YmGb@Tbp`~5#|ai)NZwdA-YJjx?_t7g_)#*#Gy zZWjk{0F2)(d^32TTrphDz5r%&bF89x5_;qOz8Zg@bvlUyb8|24M^N#sN9xqYHv_nO z@eF{|7vBfq?30h^?bqM@?{)jBi*HU;)?fEbp}zBhH`@^0vVHNPAZ~77d#r>(-Sse{*B2u>F#s=sw39UmuliX}P$c zZ#n+_$5%aPJ8@@#Yft{LN*gzx{F5bW|I>@VmD27%z4%+pklPoZ<}F4TJa2pI^-uD@ zRdX|dFi`bc$dXL2Yb86T@TgXvEiY;CK2U#kiJC-hx(|c5#&1_ZgZGJ>B911*UGt<= zFET6uu?j3j6+;NqW_kKrlCmF`24>zuMULTNgwRpaX{$z7&kx2-8M=oEfHo7d7#*E; zSX)0A$BQ$Z0mI#G$Y3yh=x}$3;XYh1!(q6~fZ-0qhs$suZo_58-P^wXz5OFk+UDlD z$w_k4&-dhXlBia1yiZ3KBr0t%zdbC)wx80sZJ9gTyS#!f`qD2a{)7+8cpI2)D0Wwm zd!bUW4{pTW0D!yj{hO<9KfJb+57~Oi=Nyk8>6(v6E{B%Tvx%cHJ;i_JrWf4p#?`WU zH#5#?TPb(PAzP(V8@v)CUfZ0p*}j;^e1bi<%pE5LtV~QkhGMQ`eNK)(ORPbWTTwl! z@Lj_zd)vLj5b&@=pH3&MzhTnl!=ynf`Hs!OanUE>Zd4BWPX+TPampB;P^5rBtw@Nz zpvT?G9K3Z;mekK6;NjQ`D0yU;Qqvv zfzJtWd0RaX9e@tP{kaUCdma+Sp8sp3Vcg2|QQzq|Rf4}GMYq%WZBZ1GF2iUB5!RK9 z76%Vg*sd}?jEVOxoiu#cwf*PSr8)%u z)RJvSs9Xzc>g+?u{!vT;lEPR)2&TL&#Rm*92XvL3r`8ej5js5l)@DByKwGI8FLll z?HY3?_N<|=QtSuluvtvMV7#Gsr3UrXd->y(&9) zA4h$>62zj1ph{c9NuTb>5gZH5PIC-bJY-aBp0 z^WI2a_gIqpQ7JzIqqY;!B5_A}AOqQTlcnsk-aPq8nx+n|S2!(6Ce!(JQvZS&o_Ti? zl<2agKUVtK_%9!gmuJa3rSVrv52>ZoVQzH>Tk>R|gi!f?GLLzM)*mnsgY9-CNg6zy z9p~Omcy!W67Q8wrmndZmVqEkzVman)4LH2yyC&@(|JNFMhJ9w}O2C&wa%lk)BSZd_Hd2Ya9RI&X z*R0fWGei0SltZeeJ(R#uHf71l-wtFp=$aHk!ZdS}$Q#BaY3IeqALSB}v#F)w6In3?N&!=01r&pSQY z*@)JRmd0}NULCYz#(*kWj39$wtn!Ws$;{U>#-m+e@rzOl_GQF14(NPT&O+lH=tsMl z_XViw!=StOnII}5)8FU`zOaJp=1juY&YMhvk76F(Ei27%BO!0OA69|H?)!vfZ3mt^ ztr&Z6kEuCrUtw^`rj|SEJx)j!p3u)}&m)@KNelcpR&RtWP z!1I!x6&W>H25h)F-Q3am!yIqybZ#9Wc?z5bG=upz9u`04LrAXk-O)-7&(6FCoGq2q z?JP}2(LEJ@dx?LlY);MkMa_V6o4+wl-=yL2w42qf;V=#kGb>^lq0>n{iW98MhE+!M zW8tTwxY|Z*VMvHv?Qc21IBaBu-p=rtAxv?E9SEk1vb@P9E!LIr<&5NNRSp5F92ccj z9X?#8OMXT2LY?$P9pt=WqoXauhQrQa>*wyfhMu#seQ-7tn`WjR)*`AAL)J zO)&@IN)X8o;w7j}&eO3Y189cLuo{62?T`(9p}T7~7wzpSc1XQHf;e2DQ7&^*26 zNiSH)K09b*s$*h~nMGpON16n-8S;L<%WeAUiFrPc-GQ-&TK_t9`$I~^)rAOV*&$do z)5LEgT7Kc}{Oj<@sioIxv>uR<1bj(%Ok)-#pML>ymn0HkNq%)7Fb^92-bTBtLFO4U znei1uCk$qbZ2k;4T-Ky7&yx$4^BBVj-V<6R3(d{0HVAGcB%j{|{6LPG=n<8}i)vn7 z8Ab`_f>v?tVrPl_t^k(hHTfo4-wpIZ^q_uddh;vT|I0MKA5%qO+&Wpy^+*>bwXJil zo}zEq)c8K3n{_F9I|<5tR+Qc-dqE?u?2|CgJ8+!iap%?eZ+B~R1nyZWhp@9sru+Qp z8H2tFKZ(UJw(!NR27nZhjwGdAtz6QpFKgSE;%2kAjMSo-8&=fR0lwEo)Xz>Jn`vvN z;NvCnG2!s^GHTIV(|mDORv8`MpNJBf&euPpW{kpuY42>hm-PZ(@`FykffT~x%YRZu zqsc4HDJ4(x{nf`rz`954K1TSNQ`Y^mzqqs8V}K4>$T^4f0te^RyP2afGWu3%`!6c8 z$4tq|Nfdtt>(5zAv}GR!rYC1I11bDMVa}jtOn%ULo$-vJ^P}ax3zE-RPcXjZbsg^G zAsmYcJe;c#=3Q|Gr?dR|yv!}d0_++`m+p!I`$Q_qVUuvqaqgvO+Ep5t~J=^iK-NX0G zBbCuKl@*m{O-(PbX{bXHj2I^SCn8DygN*-I@(CakW<6j9%Clje{~N4iY#csW7jMkJ z*2MpHrsr|)+h*?Y6fF9!eINR1cE5OLB94H@0zMI_dNKea4y_*?1`Y{&hV4cTbs}cA zHO9nGhvnhW&w-Y?@4^^Ye$%-Qcod*E33$<^DiD9JXoW+bZZAi;E8#D-nIH*SO&h^; zU;+Cr7e2N&v&JLx40BdOS(`p%!v(@m#4l!A<{e{RX3Ha5f8MODOmRf76kjUvsJcKZ z>O?Qr6AtmS-7;FUuuh>)&aYV5jLYdFchc#cec_f$;U&zElqD+wZs}nskHjX=1qm+` z0{Ot4CH}B~XzFun8gv1SZw5e>r}Kfe{|ZEkUA>#`xmf*g4K8yKFZ*$Y z4oSQZ4a$bv-G0w64IQou$`;!r45DdFWB7P4k)9%c=XTqQ7vd4~4=hd%RX%>Lq472%}S z&ZI9I*KYiuheg~Rn&E+>Y;dNUn{VGM*i3(=yh*&?pLr%Lu+-R86@6Mt#?f@6$iQGP zG}3S7P<YbVOmq$}5s<@)ia*pw}2FqOw{aWQMu=c`F?Kc9EDh}bL-ENvoo(16zE$yr; z`HZ`NA`;;$_*C+bav*2bsr897}wTA1@z*(kcyhqhRJR+%Oyw#CTG$Oh*1^E&UmW@#X zS$f~1%xngO{u@_a079x-ewbPi(tANskh{C17~X*ww+(e z5_GWAYOY0m4FB>w%bwwX#X%z1z{#3d|0JA8%OqTMOm~M$OpD%oAwtf|QF@ES?;Am4 zR|V7jSkLw2K)pE`ZorNBR{2wS&g7xai+kDk{HoivX_4m^l84oBK=aJ>xnNw}NHG$C z;=-EJae6NQz?RinO$Tv}q1#lmXnD_<=tuCoq7R>4vI-5lU-3>wHwEC@Mtwz65+r4;86~m9@8d=dITF7%nKX*9|~+X-YZ#jGw1u}hUp zfzCT~_+{B7PjQWbGyxELVTeY;$EYMjHmhKrYN6n+Uz2wq;>Moh`o_Lj=Q%G+oG~`8 zz2vt|C*5M2j_!o_T%!G^SA1RjKIl!byqP0vuWc9Qcnl-A0hvOx+LsF9;yT>Re%Iz{QerwaMCV{Eb1h+}hqh)f({{V{lZc3&q26+MMOm8H}7> z9E-rkY9~Ouo{M0#WDyuECG&g~@CAE5#ZT7!^~o^s@lO~*FUFknR1&1=IjFfW4+#9w zr8Ks%6=-48Hh?O*HiBb0$+y;fP4;R+-g*jt5}3R8#c{vES1b0FX?V}Wd0p4VLMw1m zQAbKIuYO3-D2vV+m90gm$t`)9pD$8KT%C!^f(uNqm*0PI|5WrE6!l~xSMn4K(viru zuAjx2TYm~y>bYg@ye&Im`giEDA1-CB^H#dv7B8bKTY$9VGMHxPA8lk5zCqo2bL6W{ zIwX%eE8BI=u=m-M_QpPh&B6tSNQnvBJc#kFty31mF+?%ctp4ScO4 zu(VoDDfvgyr`RGnTmHYFwr3likq19bXe;~fnT-EI4?NQ!zH~|@Ct7mh|J$qAbyK~D zpC&ukcJlabk&7eIdbnR~E@=?QW?}p(PMidQ4pC#_vdaHjeOS?%TW~3p%XbSAtQGi9 zsL)fyu?4RiV=(ZlnY^s(!-g;B5^0BAG0XCLh0bwVPU!rr_HJc#7m|-mI>ohcFBN9g z@v4uNQI+4ng}P;b$RW+{s|ybC6*6)=k5y~giXB6T%xkW=i)i+Zum{E_GUeRc3e*AJ zBmO~qNZk67c&cNPM}KhyC*Z%XhvEyze}B(&PO+j)*#wYj{=305cIf;_9nSB zh9+`cGmmRdLMH*)vu^!1V3VC*YI8EPUqrd`RPUaGi4{2YdT*cmz>wAdekjX|PenBa z;k7gl7FvX=>^MtvY_h5>QG`^{mLve84=0pm=ick|U+FFpeWMZXeBDK&&FIL#NuE&o z+Qe^BJBDo1`;=`kFwY;J_ZaNc+HTBuO{1%o8(HSAB!7O})s;$n(~(*Tzpy^0`wsVh z!TB}L5>D}+eYjB@_m?}IVhT0Uh^G@=NX%cKt)K8w^?Uo55A9M7n^qkgKxo5C5%Rn8 z^%T4OuTWD{re#5|CkxA z?%Hr`P+wn*5~2)(u)L;A)Wr~d`QePx#i&Rw4GeKYUz6xFCk~FWNE?xm;fS?R_@hn< zPF{h@%J5K+qeC!z9{3S~R~oS_tLwIhduAwUrdAD^wGMc1j(m`^@bZah^R=G7OlucH zRjQwiWvzmSKEHOGh~hq-^y$cF3+3G$4=O5$Jj_UykfMuHSi1@vU*>=_d2c-A`^QgB z&GO6g#%?5qGSVFMpWPZ9vp_Ao9BgzUvu8yh2Id| zBmM{xd$Rn&Ef=fktBFr9C9F)%XoGHyoq8PTxSiCj11Spss+Z}1qAg^olSR0-l81j) zDrCW`y%TOHU&`}?OA0A7?N{8vXK9hj{o?lBx)mo&@I2>d&h~7Aq$iK#t`M#Br4360 zub|Uy?LyVo4MTwb$iz3ZRg4r?{%8W~GWEwznmyF$7~N_%ZC^c?c6n~q_TBXrUr~y@ z8}weBEr9dr0*!p`6+MUx3kEF-OH0Sq#uz}Z{Odfxk_LA)h+mKE3iHH za0~AWS7=8oQ|YK@uh?<`*JhTF*6`)|d)-L+lNWCn0Ap<)eGAtfZ3$uTXif-mx_z45V`onsaZu8Ju($BF+bcenM zGMD@-=d`)9niItFJ)M|wGmMgHBc&Xpl(H*w&Ho(ZzH2#=DSmx#rB3zuY2&3Tlrp^P zDuQBV4`^aI#bd)_HNgX=<5{hMv+a_fF>_`rdRJJ^GyTunz#iXIf7nB z^{CS8xEU#a9Q>KL~Y!;Xw&&V_Z|2X z{b%14wws_+QH4M75g?#d3741Nm)|>_SM)zH*LWlRi&x{^vb=cryNauw%$Y;AMl87>3@|cNl?wy@hOQHi0?;=zWqHOKR{bV1eQt%LCpi341 zl{x#oAHBwRt?TL{=)1_e&r*ZcB3Czac>5CiWSagNz8#n}xX^6#S0$>=^Q5%iSN)V6 z0gcU40{=U*rOdIV73(pF4-^1NY}AUXf<@D3YnlxDi^h*eC)|wYEYbS$K8qt6yTrgH zxn&9eR*HFwZB znpO{`fmTpE83{=Ow4kGIC^N}-RNhoE8?WI1>A50C>rS#Ym`Dx9ji{x_BE{@Aa+1_% z`e!XUBt*PoG55<@lz@XBQY4R~(R&$%yuhm@l81{yx!2)vor0K7^m&ioUv2ZLm%KF; zNB76h|22!&&?y0G;PGqFI&2YbgQWbQA+-;E0%+?uF*SZ^;M2}CQza2q*%Y;|>co=r z3%oMWfAT|an4#{Ji0m)V{R!Vfc((JGQM>0p7PS2KPb9EYgbN$^X8P|kvPY$L3zK?Y z4)V!LDq(2N`?XlWWfI}h(crshx2qJJjlMPEtR95+Yxw@-o8vhVsg3z}xSIPbop$!v zcfz_CE^Tr;65^v{<+$Y+GVuNg8y(8fXt-ZfQ$LeDTw1D}D1eIO-Q zv5(0oeR${BUH(vUgtp@Bildwh7L_|;lG(7@TEz`E-ieaSX1_U(1Ih zglpJVJ~*?VCZ0zevT0nbD;Y7hpxyVG_IHY}^Av%AY~qiTBFZ29{`E88H=}>}eac}w zrNxHF5G;B%S&;%iB9#Pds*ICDG%^bzyr>+yzY{*%|-Lm(n1M7%*I+)sL@VuZ^X~; zIg*&KpKHW%BC`_DCT-Wio5u=~nx`o=Vj-r#(an1jz}nNMi%g^;_|a@1&baillbd8B z$Hyk^r*|i_m}K@{))v=Zm-W>A3fTW^InT;5GNbf%gsDCY$Fn1SiF0Ojv!@eIL7yHs zm6S9)`X4_dt5pZ}p%?ga!l#nuq$#_Q;MqkT0{m#Gs|so9mB?c?p9Gs=yuvQ7(G4iF6dvI&hlMU_nVfEw_@w{ zIvr!r?Za68kho_p*}x^R;?7@@DyEBko3-vM9#DX~#Z2vad#88ZDk~Rw5OQv?n5)%o z5a6%MIz0($!L^4JTOudZ5ux5ize&4lXc)2v8Lj6G&h`J8>n1gL#PjaB^&t6Z_dyR& z-=5<^2$>U3)fS05rHa24lfU6hSL5fo!Jy0CQ*tQM|5Jd+hz9}$W$X=Q3N%)+FUE%} z=`*Elb>eJLMqg2;9jtv-N(+i*(`&m#KxTdLlPbCDCiNxtvm%Av15eR|!?44i8-LJ* zy7?wcdM+fILFqokgjDoK=}QJ1z32@`Vhe4U9hY#oc9ni}_O{@YrQcLC-V@T6#8@#k z69i8pZKU5vn;A%pkzZk;2vPLfzT8?3EBSVgnUvS9#xHBT+I|&Qwd?8(wEz!p)d3|h|A@$l2&+1D`5|Q6<@*mI@0F;1gO)eh&5MK6*&c=Atp&M>+ zec&-Aq5T={eb+gc5U=2^^TJ=;Go9RiUHk&vf-SR-s2Qb+O{1FbEnQ^76u|~zw6ZJo zA0)kWC^)v3Uzbs}-TRzCK?k^+cae)w3!x`YE-7~ma-{9e6(w{_GiCKDoZc^G7Bz_$U+l4PfdoRR12H!{2)l_jS-o+$$TF=N< z>PR?`BLB44hVJwLOFO&nX*JQ6W%pup6ID?&Gx+S5xo{VStxQP}Taq0~sX0mbNAa_3 z8}SoYOR|V(^D^pta{FIdIKpgJm%WTRA2`&3toUgLX|{I*%M4BJ%6NfS0e@*LO-1I4 zUoWxlwQEd%vk9(#yZD@cp;-KiEug3==W@FMh# zr268%-LHkSN7hZf2`Et5L&vRi&eS`8x3Le#A#Q!P@6+Z!Z zglh~^KH?X1CKQaO5FWU3;8i#y)UYS;VL#R2KK1c-6?$TrVvpfv^9(WkqM6!E`RXiW z&NWcXlu62$Z#sm^k7bzYC4P3FI(r!+MvBA!V1`7a8E`)oN8J5%w4U0lZ|HvcqOLNsrQ`Hb8R9S1x;0&Vvhz7ck)?@SlcyFyc@H{QZ*&ei^ zD>UM)EP9+lCxi*@xiVma(%IfGhlX{S4a;FfcZE!Nj+2v*=9?GNoEjv6h)G-lTw8$) z2!ZfsPhyh3CjU`3y@ZXoWbS*^=@OhLbk59HbvW!Zx`5FZE@u{YJ+;8ye*iC%pnaGi zx78{QmRu-y!%X;YQTXHp?!P>uf$K5{z2&ACn&EJ2ABh1+`H>iKG?`22;!~KOd7ya+ zNw({Pz1k##8d3pw@%%yEd35LEH<`UvhGiF2bFcETreuc=Q1Y>+ua;Gn6^A(R4sqws z#@iXE9tZXny&92?nAZ^P6sctW{;7)HVpB=S?imk3K?>xD2Qp*-SR}l7d1wjHbJ4^# zlJg5A$Rg}ds35|_71!`MNyh6s<7a;1KP>60xIr(o83}-T*##VC3KPsKYU=c(k2%YX zHr?Smg2ol`&p}&CDLvOR09-8L3=6WN)3Kf%?MiA&^v;_|QSOgmLG~%5rAF=RVmZUX$lgmgHS)9mj?!7C0dUs6J;{ zY(bhanF>4#$POzRhJw9o-yo?z5?gGgKua>Us0xTlVQ?%@5OsjE$@HQF39$Jo!p+`yoW9yzNou~8T;MW+u0ur5dE(&g|@{Z!{*xlLYZta~N)eiyt_)lj`tP^uP1~@hErZm5bYfWWHMdDti?}ufrQzQtX&$Uo4 zaf=#5cWcCNn_b{cu)Dy^Svc+L@{6HNyNWs1Jl6wiR2429gnud^De#5CdrX7%+^D8( z9;O5Fhx~%|Xu~$V*uX}fxG})xa|)D^SgS)#GbX4i=p*Y>F#xV-4m$sj%O_o%&M!bs zUbcGX7LeQa6%Tt};K&>T9`1f<0!C>qwB8z*d&Ox}eK0+~!)|uRi7kUD;+S9fq#aXU z-NEPby!NZMFSM;M*9n~$lZTr(C2*&kR-Xh^H>Go(wfcb2>uhe|R9p)Z9aE7_{L*bM zvTtgO*Hz$!LmvQ{J8FA*kaLEE^=@WQj0Ab+OyXwbYJ8#b&xv#)6Th#OV&po7x!g5~ zWdHtT##OI_LAGP-yH$Zfut|mBPdrJR$AT7ReG%68|`$2kvES~vBtg6lsM?d~t6DHf~6ct9nE zNm+5NJpWQu1Eu`smKo@p$07P`xr<*W=KTK!lcgsmvJ(X<-+2xw#5E9rJrTK7+Zs4Q z6@*n^rBLpmyGB2RCc~!?`W52~B%^t);$_~>x~}lv<2nMhb5Mtyn$>N`XN%Ri>W%70N+A!%w z6toAJtgQZgT2AGB%O0_XVW5P8L6dPpqQK?*0sE}Ulaf?b5e@Ztb(bSl@(x;IXkkTq zITL)E*dzha28)(+rw4!TP$e3w>hA-=?;%i&g4|Y#%@`&$7f3SNO`~V@!k6?JBUdDP za;cM!uu)GrlH!nj&gie0G0(`v7h7rMoWKmv(nFSg3&|uEey2FpEY#-!km6#bRxyLD zDhehfDVZ)NgOh-FAKHx&K7u@QlUX)bT-VjAD*?yx<-IBkAUYWyR^zL2CUnVBLTg7g zjksNt&wBpqXdptRG1&(b^PR`02lAIXid-{Dgvs@Xq6Nc5w!LIhGd6`hc{x30fuR&3 zvB_}995Wqj)w>B#`Dm)b0BI+x*tpTp9V2#^O?DAAb3#&a4nI`hcPP1$xcpQi$x6N5 z^#De~C`rcC+o+lK*F(+gOF|hjI5`4cTrWh+bdPyR^1YK}%%P@wy^?qRjSGSfyGk_| zO3ryyt`lz+!1S3`9~8JUjl7TGt|jb0+Rca6oTN!cQ5}29iv)3nD>(^M5X)=m6q8UC zKy*ZG{UcbUNNOw$db5YkgjPxcW_={uU4XLGJ0hlVqTlcJQ+)^ZA6-erk`JA8SQ`_m zZ`m$x>Zb%dFy8dUUyGHj$|uV+n~a7sy4PF-XBF-85%i^C#We)GLflgq>#{* z0kK7JQ$!XnC-X85;z$v_#{Vp5)ewiU!=wD^y;p2Na)X^=QFCefNi?B*qoq$h1_;pG zTeZU)j8-r!tIr*x87=iBkzh)u=1RKDosn>IE}dK#_e5oIc+XiZonsxo+h8enyei^6 zmH*GV;K3;&g~wxKq>RAGwhorX7=ASxb`yVK7waSB;i#Azrc6vE%`Ce4g8A*byJc~ zE1e9YHF7!WjY)Iv?~czu(x%;V^L=+iaL7@k&C&G~LQUuCC`-+iUK~L`AqQqC4#?jz ztt%BF3N*4;$m{14gS^NHv=PuPzpqXQSdr?^rSb(Rjrs(6j?u>(2D=c>cYdjz6ScFS zc%i?~d z>X*iziWknPyVlikrY)HfDZKIop}Twr+om07%4Qb3c?@nrgAP%$VCiHMHwyuOvF=EZkD( zODVXQy>i>$n%D>8VSsF2^>^1~Z_Mp2r}(5K`GMmPIG)>|2o}5TB2;LWZG^s&aHBB& zRdGbOwm2|@@2czGpjq-Ty=BNYGf?3gUq*3lU(ZuNW9>TQR{}w5DxKN2L=D4mJ8!8# z5VOQDA8?_f`{3~iUw-AN_^tW1U2saIUgvdjo3FvJ?!{&=2f!}07Njc?{<}m2VIGbU z$D@$S9bZ?g|1o)d`LY$9ajF&Z38@@8Yup5{4wP7_pjAWC|9)#mCCk8W_HY{hw?#yLVSRcjqfJ9yOz|^%9Kh%T9!F z-eP;6PlqVDr7u0E>fG1Z+-D++eqgvV0OcR%vtC5p69MvD(Pl?RsWPw|Q*hqki~qdn z5>=Pb(E(i_`x|(~+wfG~dQ|mqjTyPJFi37uu!f}v@f2*Db+&oYY_=BS0DmYr8w{iiYM)fuc)y;u~U#6oI= z*pCJsTy_Cpn04#5OZoJTQ)O2G>EjahjsFfyUDGF5h)*rU+P8e?=svNY$2o6PCjb?y z6He-$2c!{IKl{hhI2yYjM$VsJM7~-QdW9zpIfE(DUs#3N!&xO6SQOWF1b>RC<6*5& zn~2UbG#~UQ{jq|zz131(>oYW_G8^oRW;;4BUe+jx8;x78@^$SgZ5_K{Tkj^@oH-q? zZ#b)+N_oxPoQfNdc{)4XGi5MNoGr~2q6{z=mF#ZJwcgU^@HV%`NvTCNQ$PM$%Prtn zA_l(rGPDu*j&N>B`3AUZLkPH3IHa_ziYL+uwhm!S?X>CDrHQ{xNgqhbdBws2-RGDH z!PV8(KTLl=1(weKD1*)(x;!l`EGSswP^K~9EK1Ts>wI(LNYjBK5uoXoL zQZChCPrIwuC?(Z_&#gej{X;s>t4WT6~ zT|G$3_ATsx*`vtxCcPvf1W_){nqaC>dGU!W!vdr8p=XLaVl;$DqbWr0 zetaxnd;6%nE0wY9y2mmf)1Kz$l#6-~h5iTStILIj)IF`CI|~efcsKOs%$c)slg1Bw z$2H~%W{F}ItIK5`pFc{t)QNssniCxqws>@5vo+K>?GMe4uFY@3Iylg7q?PN zGNE8?1T}iTzqU(Q`H)Ww34ZWEsb<)<{WvT?h_BI3(@-{LLXN}qpFbiET?8j`S#(s_ z)G2E_LA(L&-s5A3lLcq&6ZGcBV_j&|nqHEp=1NTjokBt2sNnMHvDdAAeCO)hjf;Zq zoy*@ZSc8$GM&&gB8k?m)jw1l%j$cHNLt zv+UC%xZe?zK5Rp}(UTWmW;sJYqxurbFLb2jqfRbnRMiTDweO~>)VSAJKZ=56jjkq`G`~niUUP>u@K0 z2VL}NTY}g_(pQ3qUB5|@I&bv+;9W~_8DgOnyq~*HwG_5)gfFnTmStblbFv&3pcgSF z>8>-toZz_BVn!O`t%rsXe7smYG)7}gz|r%sVPmRQx8D+9N0{VAcZmm3=% zJy~K$dr;9AGVbtNPPi1{5;GR?lT(;~^| z1)}jePCWPCR2|3b$5fs9fa};jtt-iPZBCA%R+LBcacpq&kFC(<7gN1#!fy{Bys|JJ zKxm)!4#o$4(*Yk}(dfH|k7l`EK8FaYuCvFI#8>p1($n8Qy+>S~U1_D=Pn#Xui(@+y z#W2EC&Q|-ST0pKC9UoU;m#>vBqY%?DuGH}=qB{{czOwg^HS-*{TSQ|Y?9Hz*mNl))97l@~JTa+*| z2EOw!Im?V-WW0KhzmGbZ(c};3A=MA11o0H}~f-Wx6t`O*U_vQC67Qqz7?OkDqBC!m|2Fo;~Q;XFhr%iztNG zs{`yx`}iXbNobks+_#|3>?D9=>7U~C zu?bjdhYI_RVIwc~VjlG#z&S1uVc=vc<5Woc^4`POl>!EmP5Ct4WI=?ZvGg z@GJZ^u)TtQn5_y5Uje*bBTYps1B&s0oC))0C6%;b6*9WKaU%b2cQuim&yWgOs&OJ) z!v^dDyh^0}Ls$Mzz5patN>?YWKsnZifGz#GO_D)unHT^Nve%X#rLI`kraIj#wgJF z8gA}U(#)=)#@pf17u_DmbLi72^ND7FyhWt4<%GLa$GOe2e*6A*A%Ff-7zm+8gEjW( z969~9z2?8PSG3qak@_do&V|3{h=tqTQvt;^8(Q#>b7RcUj54s>oM{K6Gy^O-_wmJy zasa+IS$-xbiaqPCk;6SoU~*O$^8K4kgIXuyJ8=+c(`Q-~@sRaIO2u+Vbdbv}Uv$0!l|incLK(hqjh$-^@S18+^z+N?pQA zm3kMn6%!!)hUiKkAgugKHf;=u$&oaSVW)}Y$UIhK+wRs@PHdHe(jJO!G?{1GlnN6K z7?vlx-k2d5MBFE9>RDb+@9+k@yUS$cfrBdjZ<;(y*R2q<~zL5Uo7+bGn2Fs7H@`QfLT1CKswQvF&ma8CYDI_m-ln+o=7N z8GQCPTK?~Ik5DoYLJWEt!eUj*W%DnNWjXorEv>mKVFraA!9v3f17($SGNhxCiKQ6( z4bFe)nMaNOLJQc%Lk%3+!O*~8_~H|McU|LKQ|$@w-GOz1Z~o77w}KYX=@fZiZ4fjW5Xk)-`g zVw~A44F;{!>o`WsEmgPxifRlK`N3A}_1Ukk;SO^(u|vG*_j0x8BgTj$a**((iIinC zeq8CXtFB#)*1$MKL3Pv2-MEj^r>f z_M4;;!t&Af%&855Kcu;fS1PNXTroqpg$@wZ^hY4W5pjI!Xh1W@p=w29AD&hU6mqE= zea&{EjbUc8h6$g(>W^@yXI{k_xms&uQgN|ER<*3< z=l8%Aoihmak`ph`CR1*Urg*L9QW5+ir{T(4VNm$FB2p+9rxxkvHJA8f<(2N>Fx+jE zxO&i5qEOiQ;bbVPo?e*af0Gp{AX-tOm9!eG-uSdsy9|F)BKbN}#Gkcjxu_jqc)j?7 zX7W_T_v0z`v7<)gZyMGwNyodPH@MC(<qS;wFtexeLztfiZZwFbmA=#RVo9O^cOhSVbAw3>;F&mB(mneVt{Wl@A7btZ#g4 zcjv&OwNZ7Q@b{C^JHkv%qU5~V(jL$*d2$cZt-}YtwH)qzR+?0@cE;=$o86S3N(*@4 zaqZWps~H#LL7Oyb>-j?Y4DZ)ogu1sXzl=I+dd<<65T&Y|;gwZc zys@zA647^8(VfX*tWupcpH-(6S@o+HaqU5btW=L}KZV*m1%i^?!|;m@^gT+PL_z)l zFN`p8^dT>@JSI6M4yRbi?}UYORi=#Tmmh2KkHx(1Rns(MdAK7S^C6CgimR*0KpV}` znTmTV3X$G9ASnG6HVEg(dm!R7u>`uMQV|gO^)w-*cmG1Qyo(AWpBUSqt1^sjd zDu{+bQg?eVwVE2&rIjSw^9$L$$HF=rn)CM>DF{7M#>&5V*tfUhzsEO}ukb=yxP+X& zbJKw;gvkeN%3+>=d9v&5x1~tquwi1Irmh_6Ck&O%4baCh)(eyRhR&jYsw&7C9gv}` zzv01FX`x@0YrZT{noHV)ivw@Zn*^epIY!jeR;uGMABIbc0iTPeJ{X1}b?b!v7D|HRzV^oucglwi#y0dXu zcjq!0LoG14Os+UuWa}9=k2g^XPzwFN7L2ywAq@4Y=j&lqDu_;S zrb@6|s@NIk^ZM5AQ9*+IW0IO+`NTPSk@$~S#zA`hEpFLtPMDHnHin(8Pu6O zi6*@<=Ztm`!&`sOCvLuhgxBJIA4-><{lh0yDaE$6%RwpbxT@ExqQXJYI3|>AX#)Rc z$Dy?K`}H35c2cG`@LLz_JC-pN_;+T7u&h$-YLF!T%kHi(g%v2%Svp@Q-skR(-9R`7 z1M-Xwgn#8?7ggEj4i|u{n8$S@eqWoijoAf8p&c;4Lt8p&Pz&dO~IA zHFpLKbtfH)_!$;0ss0VJi(CO&b~(B?Du-8WlhdjlR0Z+2mKlY8ZnazpaG5-jKK=FCVHgVf>Wru_<29pj|> zZY47$lQuP0bNpnbC}`%p@<=-ERBX9U7bEEkBb={I9v~2q=1CJ3KK~x=S6xaEDW#D7 zcdH7url?p<#(yBHF6jYD*)qW<0sX@9AtMpMozhBegr+}{c!KdU=CwL%Rx)aUDXiqu zgF~PD7Yfb@nm>-XOC8&IRb`<#`s5{pO><@Q1s~iy!ot_)mpY)tJ6Z(X#(610QMCuiIzR*8Pr82TkGM2 zhLA}N_!%8qyg!h}x{mQU`3#Pw{5Qomwd4|wSRpzTM=r*%!`wnQo-%3+*(XMbsm3Yj z)I(I=bpM8@1xhiYWK|QDEd-bi-gv0QZ+|)b4r{x(D2l9B{j|e!DR94{m~3P_hisn( zHy`B_HVe+~5FZ`CJ%hvyruAtDp94TQ+=Pr&y6cidyNqY5?>g@UoxNoppUp*cNOhRw z(!b4-mg;@)p7xLVlBhx6kMkW=t!t?^H3-(Nn07hA1q%l`x@Ch37)EFv0aqTmLt!{y0}%ptLy(o3lG zPBRBh#1$~owoPpvF?1sX*ur9$*w%VMI&o&Y8L=0GecfZ>(~}F9(O4Zbj4%f+?B*fU zAha4C%GT6mZmaVwzT&UB?Fdk{!t~yv1EYFI3Q`n4`-19f-vL40?bK+$$jMRhL)Gl-T1{%R*lK6(w69-n zrtNSd?mVJ4rkqim@>g~-%F1Sshhz?Xm`pkGk-4iMhi9pgjEGbdw)A6S=DDN1NSp@B za`9!Ws7g!CL#)PA|I?yWa5OO;%xI~>Wr{i}!@XP-L7_nmF%1cPuml8MVS7Puv9ABL zyw=)Cdwop*9bZq5zsRGR3)z!VUvFs?Rt&V#XeSJslUEtHsc#%s>GwtVFSVBSv|`RO zhUHwX+jt_>6s+iUu1oCyZb8!Ih?wSqyN%5k>QWeW)IN?8{IQKBI@@WY@#Cn#dGw@! ze)S>ajE{wg+TA%y?TVXwd}$M0iqL9qs+UOBJ9l&xESz6mS-Pw;ZdB*Or?h+;ye3Z3Kph0402o%>#6RKD491>4G31$+Lv)VoVBpymP?!|v_mxwAeyjn^H2<2~rWvVbw|p;*Ogt{3r^-s7@Axg<-UB5v!BV3Vd%$q>e8ArCKK zuzdF|%IxZ=l0wSTnIm?#$hu~^o8aX>He04`+L99!DQG)x)(e}R2z>Wk$5}<*;|W2M zYU+yJSv6x=IkCRIWz4Be_iJ~OrE}gpY4#zH5B{_BAMqGFPyj~5X>Ep6dG&esK^V-F z|LhUw>c79$40Ge^O5&R#p2hN86dEpZMLXv+o(Y7aQzT-bF&h*?_a?D%iD z7n(UOyUnEMko7|^=3@4uvrLj=iGpDuNjStWFs4b^B%&}tk_rh3zAD%Vk8^CQR}V;3 zR$u6LKJW;bOAwQMsq*p>W_KgR(vQR19LG}2=Evm9B2=~}&gC@Hp^8V^qYttgSxoJF zn)bXB75__DO~2I?~LGY-C@` z3@JRs*!-kQsMI+G{FY3GGQ%1~CHGZ`e??^5Q@h%dIxJy50mg)zmUnErWDCBb-<@<+U6 z36}_kk^%c$V%)ZQX_5?O*{Iyp#NSKI7>+aXhN@Yh1DbUjFXK!#!3@%#PO=?1P)CkK zLe<lgy@H?3PK|x(GEjLZ2|8n zy7J4GYX0+`t@ZlW9d-mIaUv~1MbqAG{fM=K^!|^)??`4@&B-p*?mFdxb3~)k?Mew@ zw8}26mfw%qw9oCEm5kg(_}|FmF8rw8|B+vU_n!GN7Pr)o+{c>lHu-LtjKyyg1gi9UuN^+3|FeOTOtd z7&)22sM2vTPqCxZpTrRABrs^*i7YVXt1av7gsR#JB9tTs59t_SI1fBEA@8W3DmJ(u zze`z|H2ZxB5~cL z6wgl?La)Vcgc{x=FO)GB2RLR>i-%5E>-kHs9jg&%nbV3bk2|=B&uqXaq&{77tpHP39X;HQw1p%i!u!)99LZh z2A5jBT^1AMUkSe|7DN;6;qI;rcL1m4k_S#4zYxS?rZd~QX6Q;M_=Dht2>fR`qYGLz zh-ps$YYtos$HBIUm}8Ji$@&`dwPFVc*ivhzeuL$xR2o$gZ+G(P|JJ!zp|sF7Ko{?`nUMb;lYT2oO4#!N??G^0_oEYH85|~ zApW9EEZ))VoaExEL|WLmv+{mzY!&fhfB!~b>_FIlzHA-YOB+KII@`FNKRYUtlkm6XZeuXO$XB~2;_@y@cArhdvROE1vRG=+Grk1PB@CK9*Q}ukW0U4ixV-?5x&vHtit#ot_R%G#&+3d|D z3aD5p>^$fxiLa5}E0Nt=?FD<9;1qg4t?ecMmDycn3*=PQ_{; zR|Ou=$?TA^8*uoy%RA~~8?8bu{*uG0bQ#vMEd zr%mKj)u9j;0)(@@)3bcXyfcSf$CAshxARURc0QI5Zak;xwx0d{ozc#h2yoJbJ5CtWWkXY`3khSQE$W!nbYdfWkBAvCz@2b^H_9MsM^)f2R5>%qMK)W6b*?5|TQ>b?jb@oKNX4)jr~D)B39p z7+Zm*4>3J707S-kL=k)Qvz{wy=wv->QiyJ#`~nfHIputWm&@2POq9MLi@aic)UUJVMH6py6&C{=H2 zU&@i^2GnA9ITLZ-7uz+RkfYR$7c)Lz1csK-y{01>pQc>Luxof)?8sYV=rGkr=avZ)t>0$)A*1Cx}&q0 zAm%JPCUhOUAV!FSKKn3UG+a%36dDT1FEj*Xzs~fxaez9Y=0D27P!JsRzW0?ie@qjN_JLJ}Jw2 zYdhq=NqS(YwcNqwPhftT0GgNmtg9dVcF++tfY*89PmI_>5z(PaEQ^#tOFvSDo%f=Y z*9LgsY?o(w;Dd6Ao-mNH$o4DN()``Xn#S1lTNV5J$7$UB5@{bdI!Eo^aHo$AvG8ls z2akToy#kW{5EpNOe5YLc30R1+I4Z&Z~GWFI5qOPds zH-`AT^%&@@fu-{0`?A_nX|Ug7RKsVhlWhM9@bswU{4{~Sc+3K{c=^4x0-CeJO5Zeo zlHC38B*6x1Q&G-?ZbOc#|DeY3w8^8YT{_6>ZRnlxk@=h-f>KDh&iEY$cHS9rfzb{! zKgS$*GNXz4h#T7jie--JSdM()i90w0%ka#=o|Tgb^Nf!EM3_?0x*sd{j9~`P1DrY{<`b(8Xf9f0hg;m%9ZNf& zZF-H6E?YLQgwSFL8OTv&d9bQ$US{9er|;PIYvSIF+Ii4x+6$+0AS%u<7!8eo$ntQ8 z4x!kp*Qm;T&Dt~WA$B<80Vjym1Y%1BzsI?fh>K(vE4;UJ8Kfj}ULx z1;;eZD>!#@VgpuU8T@<|)QYi>U&gviWuE@A+^rohy~(?%chu^Bv>~~Z zKh*PU9PG;$%2iQQ2fjP*kM7k;GMjh_y!o*RZl(b&$*_zKW4JF~(^hKd@n3A73)gI1 z$9N_ES|Ti16zaDs3(5wnjobJ8uQ3oD@!z~VDA+$*7QoKn>Wb4g?b2cdTbP0*Cn-Af zdtNeY$N}Jzyv9|x{IOjat^l>EV^Ma#9Ih*#=`AqfNO=Q1i(F*Og%TMyIni@?~lZz)zt?N<}o z00!G0a!^sb>&Y``{cI^>*o@T&p&58nFJ17>D%BF#%XU+yT1snO>F1@5kP0Ru1>f6h zD2Hj=P1vV9@Q-*2jVK(PF*ht#DYy1ctV?v_*Knv)JP$K+O%VW9*zsu=iz`(Wf-s36 z?6`pMj@S-^ww;cZjIqJYR@6oQ+gik%+|sLmngEZPG!YA zy-4|{2DVd_Un>BW{>`NaPPH)5*-@-rY%{N8`4&9<&yRcB*HU5?QwIk4* z$gHJ|q^qYPTB3DZms|*~_91!bT%r}$wDu1?leYzhS*=dJgwOkp!{qxiE9t<>cfHOj z6=AKj)kOIUv@LHh{8WTOd)2MkG+W;qc418a-Fj(!4J~Lqol#NI&!X=wX1owj+f{RT z0&GOW8u$6$$X)_wB6?p@vsLzV0@#!|Qy5KcsY4I|68;K*W05cgX&*_06ucg}VMk&z z`F4Jv&ziU9eeFoUT_P|@5HS*k)2I_R+ zI&r9mkA&^}JMr`uJ$ss?p>=kkQah^CsNZ$m_YD)KnG*u==l@yFU~18f;H?ekn3v6R z)>D#wp0v0ekdZZ>eJTcjvQ|D)KlAPFIecPy`SC_d^!Ia1NQZZCzD?i+o%_m&u39(C z<9Q@Cfu9B)QY=KNj^k1a(al_oVNRtAZhp02eFWprb)B%w+ zZ-&kuezV?qz-q$sd#+i`&W^CRN#;TAYxhCWWd^dKGccaw*rio&%|M3zJ=M)f45&p!o9jP zw*Ie96(OI`LKrOM`;w%Ss;)pLU681*z}1~qcO1BG1V0VTw4A&PNN5ro=s_oe1ya)r zJz0+x^*W3Ls?_n~HZCPlESCTAVC?jhw%}MXL_bHCx8U{-kJ92hGVGG-`H)17F`~Rl zwnT-EcBiM6_HUNCXgAM&!YCg(8Rd!A;fWDk$k#b(QIO;7(x7Hax1KvDFi9x-=~;Z4 z4i+oK5s0-t8OY{w8u$|PA!srkZtYj4ytlL^O%31a{G3z6q8=<39l5}|Su=Su@Z)n_ zC3ZQZaz9qkmY_KWIrg$PNf`Zm-DREMw)E!kPv#EBe=}OpAqwANH|=Gn1Rg*4#|^Rh zyyPNpgoD!+RaRCtbX9EB3c^ymWXk-Oys+mpZtZT+ZnFiLGKnMi!qfGQ7m21c1O+un zs02Deib4pEWsFbn44Yt(guWN9g1Fmsf zwQrwBr0=Z(mrFu-JgH9lda~i?!fRY6;Y9SyhKKYEt019@2WEyGq1!;ROR2! zpPme8%Y*62PQM&Xij49EV%M|&BH zY0A(5q|12b!@Fp45ePA=vqqxPk|Oml$)XiYVmT;MvF*nUB?q}iQ21hx=KC(=vuxUZQG}K5-U+FP z_Ewy0O!Sl>cmOM@2;!`WzYa3g{)>)>(mEmmtL4%1dXWyWrVP*Vf65Be_s|=@U=|<3 zteZ?(e}j=p zXawZiEn7v9>S|jA$x>GD)WFIG!2IKB&992`FPN-3#-dBhHx30e*;hF@z?T+a(^s88 zqCnt~Ry6?;M*NhXIdY_BxP>v>^m79nek{C`S%-S4B(d!AIAKBgz}`3ZE?mP{r6lHI znBSS7U5ydzm@7GdEV7RF5fw?jC+SMSRW3?SnLiqwSU}KERq9vfT>~lI5gp5rh*6dQ zE^K^I3Kk-*A5GU{N_-D+5)C0?pve-}8!7ZBqDLn4R2+v2{r4X#Ge+0v$<%U(&|`w- zhk-&ga+Zql7DTEIPQ5fQ%%Bx^mxG>)lT?^@TkK7%yjQKGFUQkE%uL!sX#4NJ@j)+l=aEO9UzC^XC=PnSC(5lDBJP%CKbt&vBhO=}1apv+TQQcF}T%b@~C&G9}YL51Rw^V7y`$m1PuH49&=f4M{1y7Vc% zPcHj7H@#)0gNF?hESAKILQs)t2Qp#Z1ref-Cm^VYDNQAPuKc0o!VdJ)pjSjn@VhPmB^cMU9VEl3Ot_RXGF-0 zq@mP2O)H=5avZ4O=J7<~wDvR*k-zZJzgbTj6})Ojy3sFqI{W|h+{P{^J)a$;pmRX4 zrLNddz|PHwsn;aGSHpAvJIL$9zpTFj9Z}c97emfZ<+X74hcmjvRvn~hF$v9NK~~3p zmtt=;{j$vS*3@}36{mOR&|xB=uJJhAnEbbQ@(-SKdr{u}_6ISM2g=4gdAAmHQdl|I z$V|-!yXN3&3q&Xqj(8)NAW>8EpfI{rrKhkHc$&bppv4s7Wq9mP^#|hE+U@%@n)LOP z6(jc~%{s0A)FQcPNSD=&GZ}fIr$yJ)!4tRI1vA>)W(am?n6km=@VsNIry*3f42#e7 zzIy*9^uPsi9zsg~G-u9{V%#ADyT)Rg>ZI_?@Noep9v0rlVS%^HUR|f9-7kkKJvSo^ zU{7r4;814CjV~@XOJ)}8Q>JejD(% z_a|@Xl-{ey)BnKy2Wy)b;vf#Os}i3btTI72!5za{w!D{X1MAy|ZHCPcTn#I)+p{L> zcE?dFAaZZ1*v0F+zhWX+ctOwmm=%N16|Q0?!`E6Cgs@%zw!&2ya>P2XP3FOEXqwnR z7q*S3!`H{Fmcvc(u+m;JN9Duwqkj9#NT~_t?-xZA^rRPtyug6;>(@px(8aIyu9e~; zJNfe07>Mm~_V0}6+@Y=7Ixiqx>f0Zm&DUq2Zi3>2s5ik%{kn6iOM|K7Zs24-Q^&VU z((yXs4X2lG%Cu`#BFGRSoghhE>7l80E2TV;%jO;GC2TjU*$_%B+|xj#vSg7xi8=61 zcE&N@RXD{!qJpTP=W(~EoJjJxpq+>1l4iKWj7QQL^R15HR$s!R80v~=TJj&Jm;n}2 zaDPr1>o`5~WjIYiVQAy`UxjC##a?NGoJIb25E}Op8jp9w-Vg3$gN*lfGXd=xVwb{Q zTj4I76NFsHk^rl~3m6`^ughZAg_tkVX}b(?VsR|I(Kv&-BMJ?V`d^K)+hCuz%FNh|R8n9s?!V!r2Q_)m+Z0q-|u!&-+5VY{>s7Xn9RT1Wky zhpi+8K~Ee39)7LiZr>p`X+eVK+H*K`~jK|9LNujB%+pBl57;LoVdAJ3Suy)H;VaY9&l&r#~XT3@lA ztAC4smpCXq^UrwZ-AtU&Ii2_69jxj}!)HGHiCR>bQK=c43H()Ie% zeDgohi+jC%EucHsi78c!c+7pHx=qC-`DEXAKxmYCN^Fmo9>B~5$>;Z>aliKwsJt+R>jOda8D zc*%jyb_du9fiyrfbI+6HdFq_v=)=q=gWA&?4-4b(3kD+qnkq%*^pN*5$sa`i52eKA zF=5eiX`B-9UWdxA^?{p@*T0_Ng*}cACg0#UL-yjQuIj#!iaC#r-1w@B82KAQT#V04 zj{V6MLNzV*;ol5*g_di7q_wG-H}Mf(mlx1SXHhe#4l6d@eBGiB((Xq|`Y;-Ex^6r& z_R_;v+j!`}x28S6f)&;VM~6)K{f*|v-Cn)xjZUX?;1_)}%eu(opw5!W;$; z>Uekua>%3xMQ|x~HW+XLY4c#&8H1I)n(TtJ_M|vn6R?Nj%)Q!w213-fB+XD?g420L zoEJu`&+@0cK{2<4iSt%FE21*a4TC~{K=R#huNTh8m5ICO%3Fnv)6OQteQ{r8Y=%a2 z*)yaZL$^da20dY@@BQ2GOz3|(ytbqEQp(lr&;U$Jf^*i3R+r8Yx&Ip${8SPlbIzxT z&7bBNA)D*z5aGMC4lqw>MRWR@o&q*}n}}~n&V>txde278R87&UKoa_bj)0=PqJx05 zj1)X*&cYLLt$#j8Pd8S*oB=()^64wqSX;8}QJXsu?+Ds=GG&qQ?Ewk5Uf`9JHLlBQML7T~XE z2sn+)HWuIIylTI;t;>>Q6}6g1Ep|7qw{BgkhxqsVomT5kuyP}vmVKowR(X#0&iP-F z=6YJCNA=OSA@-WaNa_x9@X66{H^#lmEL%)nhxMjZq$`9R=O~R8e4P&VZ=2 zR$=6EC8HJbO4tE4^Y8)o`(x1%+s4#j%Y$#W!f^{%k`%<%32;4_V(B{-KHS$Lya6xv zf*#B}b5as_oI-v_rJMJ`N+%R!kFtkm-pFRe#?jnv$l)kO*d4(9?2#%9xs$G9^%X#_WS<-VlN+Kihf!1eY_=h{esv} zF{3JPWF+_vC82@)y@IgY=H3)FPhIUlqM)8tLwMEpOLo$41{BWStMu5==S^4}Lm!SH zN?Z2hmlT%sZ30rs+=sDK%~2lE7R-OlutM>Q9TF_kJRlIX3a*Xob56^&kL3?JIZC z?tfk|_pc5$uuBhT&O|X!UfoZm(LTgObu`}&v3!JUJ57C02wjgCs%mbEI5PD)K{=f6G$1iRZCKL0(Cl&p3g0Q8Id$6MESLb~XtJ;%JRyCOH3DNn09Msw~ zD(AnK1bEi?dsA+|-LOFHup~}=`dhnpnPHW4*FI$>uoVETUcdlD`iDlf%T`$BElUR} zoG{L0LoUNNK;)DI#{vZ2s&JHqFw#Da{~SuyU%-wUHJMF;fb8mH8&{59m_0J5SJ`2=VHY(f~zM*n>Ra+6%A9F>To_zAa zcvL=7Qk>@qM7$I8&dWVxxqD~mi7LMxA8f6pFy-^UMpv;JOjWC%z|ge{aeBG4f5O7I zM-JLiCn`I=&;QKE^_@eiq{-eaC}CIhlkg1yP8iC>!Ja2Ul~>{{-Ww!1&^>b=hWn`L z7DFVuaDK8RIE=j4dAEqiqA`+`PCBD^Tqh+Gbjl(|An_viMMz=jfK=kcoVNfVbMQET zR`BUtz=hERm?|fc`=AJTZx0orygJ{ID{as6I!#E~$XqN8yehUfUc^J*xcY0b_XPxZ z4ej^9d9<4LxyrecK;YZVwe7{7vp)X9V|#hB>=Co^G2HO5>$Ym|KT0*bO0NrWS)j&l zd_hn&W;xGxfw-V`2ktRR7RJ9s?~loi=hL=^i2P8Jk3 zy8l}my~Y`2Grj#fA$H`r%ZQDNjGNSYi;1Asfghy6jsWT=+6IFTnoc7}P{tZrC1Y;L zhG0+aAZVSVyxqIDruc-dDRP`3>~X;c)EJAv{k|T!gA;uE+3))l)B4YEJ@9DT04L>U zQBr@>qat%VU+eS@ z_+B)t9aEJ{8J)rHj)@I8(pzw4vKZE<23JP|z7b9T*U?pnMfG&y1tfknl7i$S9n#%M zw;&DD0@7W3NkO`$5u}$+X{0-)yQHOiVZZg;KjxYH?94nfd*+;b<~?)XE$N91*B)jJ z=@}4C3aY6i@V)Dc3poA(;xK-|Zt{n1Q}1L;kG!{`{&@-~;BJ46J0~ChvFG zrX%kg71I>{wO*oRgG$-us9n*TwRzns2Xav~cc%;Y>k!L#OLd0V8|PPLB#P^#zKe z8Z&Z_S|C015}owtt3i6gRa!%=*xKBM_m_>dYR3Liig$y3;q33CYunm=&s7SzL#?&v z7Rt}>jtTLw^53hsNid|)y5l-I8u^gbIqx4Y79&s6H~-eyL|%70 zi?U3bOV^Shf0QfXMj#Zr7K>MpJ*HjJH+r5;u@MPTP91e~^Qvys7hx-AcrP_eme9B1 zkbWJ!6F}#j9F8 zimWLK*~2cxi2{U+5kYhNU5|DwyxOHk&66iatK`!c+4lub*qwKXO}pxMO2J#5E%x}k z{k8*1sAM~p`eB^(?<0C=UG!gG>AhL7YN5f0-Hc)D$lwYuW(QSAREsyi zopnCJC@BGP;yN?cY1+YT#5ML(9e^jqJL?$QRorh*l5OHUG&-B+G~Gr-gu^E6Nf z^7gwiI>|WB?a*)tJ7SgK6ZP-fx=Xsus?m8|d=8s|{MRbsjo#0>663QxVIp`uZ@;I4 z(7dc9<=<-^&MEu-H(^kaw@4CVFPgI-XuGOpu39n(T&kyOgQ*m|-3K~equ$I8ZIe~& z+YFct!t7;mWD4I7la!+ZpHK?Er9@8}&sws1MHqZQmHeeOsATnJS=OqXH>3s;-*v_- z6ZY*p+pa;Mef#;t$GX&Qn%Lz`+aDHV?mLs*e?>pan4mqOcWyUpPByXiU_Bk@V=f)3 zVMdqr=yjbQQ(3^|foEl55e5X}>t9rBi&C7LN16d=P0ibzs?UuE`i~_ZdiqsDt$R;A zDts`H)7>$oTa{BbK2jW9!|YxY=3{y|Dj}wZN*#* z8pjeO`7y+?pBGM4l;%t`Dqp^UU(At=beo&!ZHG4>}D3PsZ}Hy#M9U2`2# zj!S8tSTkw!IR6C!zNe^53p4X#)k_cC6T7GRTm8Fl4fi6~7j;ONL?>~j|k6+jTuWDy0vlh5B+8mdaQ9!I; zqIi3mY`@IW2Yy!5-|CuV*+iB`sU93R#2hJGyJ0xuUVJ4@E;Q1-v;b+wz*cV3vjJ>>=)b4>)|ZuXZ2D*;0JvJ@QeE@ zkj8Ei2S~#N&~GGfE{g}7BashC@5`&L-tM1{S%kF8uaj*xbKV_MpYG@gSn^^`H|}M$ zS8B4JIt`%b*lQJBU=phOgyuXq1TGe=B>6c0$rdXSE0GOq`ieY=2Ij)2!(ob~@yIA8 z1C3C;FPLesNwvuM93hb71@cxGeVz2swJjdVIPpjZ&|Xn@&c8U@xF?tM9(}~isp>2E zx!Wh7jdAhovSF;U-Q!#elq+G1dUlUD%Owq7+hb=%sx*b`Nhxc5LOQ#bcL*Q?Uv zEE1NpH7)Nz-mz58{wPg5^02*-f3w3&BP*be%GY2dp@|676%#2e=UW$&^cBh@h3TUI zrieK$dl2ld3UZZOxbFfRNx-0FW;6WL)A`=iALb?Y><21)%km{c`@F9uy$F=y=xNd! zT0jlC6&Q(%gOh`=RJP`0mj>7t`Uf=&TGQ>S;%cxf=G+A)_q{1GW+*c0iz$>DqYf@12Yzpl1^sHv2B=A|-;dUvFjVCNl?`bXnu z8175I>I&Jjj~)Oik(Pb!j*1f|qrIIAo9T9EoZL^u+dzT)fiad5f*boh9yJAAYP@HV z`Z6gYD2tRw4Mp}o^r!5ipsrec0UQzB>TLsu{$e^z#wA5`R`q|_vne{w$THWj8ZnA) z2Tu9o_#n@?D(gwDv6DQCC-ysY)!FiYPwph$-1-cL!R{s;#SuI_tCM|9KPO~+l}!H2 z#^IV?cS%!pvNYUFF{R4k!NLkmpfUiv>+&_jRYK=5t>;i`Q)T`cw-Y>IOfohrc_Nnj zYj>pye-09gpdUXEl2PX~*BW!Z==ESJ`~jw@$XuHkL=5V7 z&qRM0`iJfXc8$bkVgJ@P{OX4(vId>IY}mDesDgQhb>iougK-0lk3S{OjPU|jMXyt; z>Pe{K4buBntN!cg0*HhNvH_Lnd9vo~`M&GP!2u#WM~;Q}+~5&QOd-U{*6~aK@%ALe z(=DjPxCH4=@+25xzo=UQims$*RD>LWfJupP0_n~vKt2Dg06?m5^VsAKoS5f4aQHI0 zMF^iAQ`J1fSGArQ|OK-*9UpnKm5mO6=;@6E5p`2Q2u z6`Q;3)S)&#h?>0xd0U(qnP<#_9nCZR*GR_zqz%*lT&ZbzGH{@`y?5GmB{tNwvUoz< zJB8LK{4I>F%GSbEth$Oy!B(Jf_1|*9SE4+TMIF(;5n4>_G82}jSkBmSe3L$*{E~cj z&TkfdFo3a$5s>JFR!J*TdP@strYU8sU8Ai%avpG5Oxh_Dmjfp>{vAxP#1{sY2pBLKrC@B33=bkVr;8k7PsGNB_cQ!BXm@4GrTwYpoKlI14KN7S9J zl5WqGldkH7(tP&Xx@`TIb&A_5<~eIO?@c@5i_{Zf-fa#io>xmx%PTK6v|BXZ;r6k= zTe*;fi!oR+iQ~oaO2ZH3;frn)ozFegPw7r#w}0d(;6qJ0ewU_@ebxyvIKmc9>UIFv zE19_>@SA@P@PI3u9KYx5Td@Z}^;w9T)Gon;)G7KC@6*hokc29FoX!((z;vf%4_yLQlUY z`$KOd(&^{Gl{xUtV+j;6FL1^Te@X54e9jqg)GPpJ?0m>QJi(%V@LKo%JLX?WeZL1s zMVyZ@#t`Q(wIb3LJVB{CwLy|l#fEH8x&|NcZo!{zyTMqWtvNd{27!s!S@!lv4$0#= zC?fl`dn0+be9{929l5?&Rc|PZwgfqdKgc%MI_l?KXxgS!Iw9@LDjoLbw13dUP$SCA z;23pds@c|zAQJioR?o=O_uhEnnPK949zjpGKEd|DLRjn}7Fxv9vBu??Lys(!k4ht$ zmawDBB$MWtR&YyH*Qt(&g2Y%ip=FJPgjdI}U5Es9EcyhR5)dem(d9RfeD-2C+{-${ z9v%?iRYdshLt$B>8s66f1@$AHMQx`NAc|hv%B;sDFVFKQ;V>XuVV=2-LKH_Ot-~g< zRl9kByxpcaJvYpH)y$fX6KC3X{NB-^^VgAdYMOpuUh_RxCrlNR>Rv6-`lnFi*g?Kg z=Ll%Jw->*Pe+*YZwUX|(Eq+soL=#=r*PMQqx);ylZ6ckZG$j%t&@iHHb2+^!0G;)o zCgit|@DUfQk!$SZmo{56%8ZiHtzQ-hgb~L$e)d#%0EMUTO$Qq zvyZP?ydw=)pRj-aoWEf(_x7uD5ueHyYz#0PHtIiRr~#(;#GhhK@A|6NX9>p&HaHGk!49qR4UYHOLB^qyO87JQ^d_d(%V6fupNCcz1wwy+#NJ! zhPq935O@8UXhZE{%=KXmRG#QS>B@!oNa$$7u6UdVN;u{aU%t^CZ1P7mNAZ3D(wk00 zGjB~F%BVKI5Iur&0&XZ@JgjPB1HA%9M|&aScGMJt^*GT(roskm?$^|LKICFIfqUh_k%Ba*rW)+1K%FZe_7 z8!;;z%)+V>v?oN6gpHsBxEpHHH9Jdr9%~Rd(_9%q&OwZ)c?q?>gl5J7E|!YjvR1ce zJ?fnSX}$jH;`gH>%0<_RxRL>P1)jvy4UwJ6b+5>5{t?j{&hYC*+(JUXn~V?dNVx;9 zt#~Vva^zJQMUjrP9S_))IzEdd~lQY zFsMS$1LWtDdE!Q%a!nDEBBU?2S{<~aY~6G(;gSnJBJIfN!vePPzR0K28#%z(KuKK- z*nv~NBB{j6AM1IO?eccCs^UAidM`~|Sus>iQYF{IO7s7!a2C4sMxtiy@d?KjwG#=x zG+VL?RCq;0feg?a$E%|?6>Fqe3x%~@9gAo&RR+)6wSYLp9&sy`N(`y)dks~GS**@e z30kJv7+H>bFvfK1T2#L&h&>*QU`sb0u)H&-x+es{@k~C;#)T|nt`a(N{#z9?e61XF zqYq(S+N-~$$D~JDgard4o{5BaS}64sog2>UVv3TaYk(v3_Dy=sm?9n(^A1M%ZlT{b zWu{^4Ic~$*4Mzfj0%_4vnzJNi%~aQN{#aeHnV4zf?Y*<{`~ zuSmi4j(n>`htoWc`S?y8*H*nJdpRz2C2})gzZ<9u1pDsT%EwLGwIp;G+N@wiCZs_# zE(Y6Ee-J#Z@F3DanFLrW*X>$@YJ3k~HGx@Tirf}2Nh?hCXvSj00*b&n|L9h1 zP?771tHrqgz)#y|_99&`p(P)2dyb5)3ayl`%#{PT-}cXE>rZH%$e4c)ocr2&q!)vE zSio0F>edtIDyZP9D=z7b&uc$c+kgkU)B6OxE=x*j(XW$YP)mmfq>|@_qY$w-siA=f zeTEGee;A!t9>TDv!&qvt=y;0`r>S%jCmmPfrpB5y>Q~8{AFX$v1FB-N0~jqZFL_HF zEmqyq3SbTY*!Z@REHRhKY*MEL#Z=K0@P*#KCKG?f{^K{dlK3kfGTfM8EC4B*NQXb|}%U&kdqJO^p6NY$9MDNQRnp$LWoc3u<=+(xUHOqdIb8NM>10&2&L_EK$H3MsrN zgr8*=&@gdZLE1!6Su_@NGotsAv4;xZMxO;(BJcI&_Wv1sLO>zjTz2Y@oCqU2YYB`c zsn6Xwq*`NuVlecs9OJ%V`kP>B&hJmT{i1Z@e=Bg@|CIZy zO8qw{+hnj#$DU4WhE9q`?qAnOQt=Se&Xs4>z0Lqb^9&>OW0|qr^X#wk9@p|Iwe(c*M8l{BNS|EN92O#zjPnUe(XACa>xtRQ>xrgbo zge1EnA*oE&f_butZ5T{FlnHoL|8Uk>iw9={S*Zn-`LeX+LVxUktls6jT8mcDP2T51 z6bt3CdU*)Q$)c!dq;D)A<#Eixprb^-bj5rE-;#b>WZ#^X7*j6~NW?h zJMH1J2DFq_P!%1N{_#>S!&Zo{C-QBAndv-&c<-b>jvI)N8llrV4(h!Zj^F;{eU$)2 zUPLLxOiE1at*Tk=4!4%cMhnCVte@a}REb)K80bEQV z-*5&JY@VmDYEQmpi-D$=;T1~sP7=TUbAu0`mi*p_tyQ(_GC#=%4 zoE26x3D^RW_p$!DAMHn#+&)ocRf)%L9+`LBy<_xbM$;-Q-pRm_OpF(&q4m?2-}{o* zm`S7bU5pn;58_bK|;7C~+EJvk&;%LAb`I$|VMoQs_|Bmf8aZ{fbC?DxjBB zwnlRmLYAQD?ZbWl@=IdcZiG#YzYye{v{UGV0gCu5{;!RZdaXtZ7PB`yTv7da?9CAR5{tcA?hI#cB?I}e=P8x zdJ*vp6X4EV{ZzeaBZ_)j{z<_~Ca!jfwl z5W0VCMQkcc_~tjbswW3(=7v61)br17n+sR%xEaYY{cF12 zI$-O&aPdt5>7oYD32;3>pMZw|MHZMLg8i^7z$@Ma=asOoE^1O3w)&rDA@vn9sbHWs z&NFcCxKG**!Weu=>rhr7&ijvwFtQ+@Xjp(o#W0Qk*W8F;xbxxHTanNi()CmQwI-_P zptRozY186c+{{MVloL!FwR`u|XLZ~`GG9<%PouA!2bnx<7-G*n-k`5rrcuq~`X7Wi zAyvbF-8RkagGs4BXc*PSH$~0g10&$q7CcU!2+`|aDbOxh5@ZzO z|C=;u=uWhUoR2G1fys&K#MmC`juhUif$Py5pvgCH?}z_#9TJgPeqtcCOj=M0Z!sP@ zBH7GMW}F74S7{4RBy)z~Z?82;Kliv=k=Tf~A0mqqmPVMw^vS*}k8J|GhZJl3Ruw#mbF$Plpzitfk3F!CV4(Ws31osplD%hu(^YXlbl z2GeF@mM&#>b^1iKNnyxIq7ea+s%JydT>Nj0R9Olqh@}Gfz1HH45Ma}gyivQ@9IRqW zGq-)CHT7DF#gx6H9h$sn4O&KTfJ}2CD<)u~JjzBX`RMCg@PIh}j&0eRP1>$wSNKP? zuKEfi=xFO-vqiA+k@!;vr{?iVA7QT1Y6(r_V38}AWRUryCaAdV5;cc5S*|MomBpY`ZA?DpDd_>siZ z4gz(%G<^^Q{VAz-A{rTgmVH^&DpeIr<;&2l45TDb`I0Cs<9FA8qg*eWEjJi*e*MHH zW}}Glgyc+PHI0`9!T7FZY1USjq|{gN`6ceJH?3#h&JNwveYfEX>ZT>+U|t7fp9N61 zm@bcGw8?dp4fdoB=UwpradU<;zt}kh!AdjY^t7UdO$<3xr6~11sJXBfhTT}OIuN^{ z0=@nozuz6aOPBvt`Lpk_cw7ew0e^qi`XH0wk_`PwY44AYHgVQpNN&n$${YwK_3tnN zN!&-Y)X&pT6oICm4IUTQi@33Am;w}RqScD&_ zWJ&(TmQ2oUGVT$!h$pg=_GJ^Ya4_)nh1{{ICss*c)OpAnS6RDgo9DlTVQemhljle% zn=5SU6@iGi@Rs&^U^Z83Uv9mkfks^i4LlK*c_Qq0B&&JAh6{jK=6?RfZ*^Vu6Ow$} z+k;CGcZO)9peQ$|o?Ufx0w4_Rm0((VV#!1wyYGjq-p4pT@i?Q_J7;XzT)4l~)y91W z&P9&*PpMuDai6ty{53pSJ*oWAJVb@k9)=jgQ1WQFM>Pa;Bm=2dsj|!No)1REVWYYJ z+!zyUX^!tBY&J z&tM8l{c6Wz&0j&X@~`MfYw~+^F3fpdzosu{EnznGoLij9q`fCut7{k;XR`rq(-}sz^I9{x z+yd>LA@ioowPcpWzr-m7SLvKtGUQ1+q&6Z5ahuK$^^(#va&&3}d2nO;NE zR!rRd%NhTRHd6%9BKo(r8#t0#tLdMZf4}pDPEG9XfIwWVgg29ZE$-_sUAyh zhtg2DU}j4J`c1t;xj+4f98&|2EDdQKhI$n6{tvu_L?pD0EKp0@Zm+Z{yrM)MR09|o zERpjrH{_Kr-v8F<(TG|70qhBSJlA7aL@nDb8du@Ft5_1F1)4q#BaDB?Ssq{`?Q1)% zL?*RZ!IVDt9E9`Hhk1(O+4`2L7kx5^_O?+izR{P~5+jBuD&rdl;Y zs7Jp6a=*goL9n~He}&}bOKFP&mE97j=q!%6()&%~9_rue+U0h%WxDRd-clZnJ^Hj} zD|@CsyW2IQcG`dj$}WLh1RhNqhc;zGV&GszXT-y#{n1I>gb`K@zcWU-Hxm*MqM(_x z#Cj)k6C!0$USgKS7*z#f)`~GA41s{{*YAbHd<=|6@;v%|SkA(S?_KxLq}FP)-X>*k zYoePiHExp^6^{V_zhFKV_cS0dH||iZCH}z?iokB8gB}3Xb&$*TFUBV zie)z&dY$}W3I(dDZ{hQY>&t3yvY~&axFEoA=T5L4sh!f4(<~>`yW9&-v4^`;v0K=Y zgzvL*%hLKkSiB{Jrpf;vruz@4mw4L$mUF==gh=ox#G0+F83ym!uXfaUjt8A514Fdf zR8YXRU1lu@q0B8Tw7MKSslfBpUMB+a?}Wvzoqae>pou*YvlB^mayKC@dP0XvXmaUX z2CoZ5BPNWKk64UZXcb@}_Kg}ocmj={^eR-_EmLUFT0dx+C1k;OH4dr&2~%1#WRlSuEgN$|SaVG=VlyQYdRgR}_VhstCd@NSd1 z-r8@{%OZ$#JLq%^@GGtVJLV1ORNK5I4~YBCoTV%FDdR6QJqHVZI0Xs!2~|!+PsS`G z+IMYU?z(e+w1C4QC%aROOxXg@W(noO8G~2^?=+=G5BE#g!tSb}j##}?O;0+YU2S8R zS+^0DCdHi3xuk0i$imVtZk`m9^d92UX3{Jgtr>hr&SCiHIcUt|)pgA5@M9Y8K=`vLiA0>(TsSB}ps$;E8a<3de}@$=_0J?HrN zGL{}l{$!${oQ?dy%-TMyK71oUDoRlbX(y3V=HLxy@vrR0O7OPrLDxrPzbq?_!8M70 zL~URy@@mRN5~df`=*0am<3Hb)c6+M|l66TsRK`VGpu{K^9+}#-po14lUqnUaG9;?x zB{A0AXXu8SlRyvRxBV?Lpv%RqXzBX6F%ci@PHV@nUKbjvFin>hRZIaiGaqyDJ`O#^ zM<(~~mwwEX(9)7UueFjcT3HwPj-L)nr@C~{xN5k)!5n13Bwi>bmn>jnC{%_lzK~){ z?~cY%Dsx$h!nWr;1O)~wE@G^+s)**203q;{AB5%WllI~^^}bkIVMg32D({AP4ltkx z{oYyw#m(^!grmd9LpeY*2lJFna$Lz+NDWu|XHp^d9R9It4+EPL7o6Wi*58w8Qg%zIS;C38c8Hk~6Uvktkjl!|8^af458_8`P zvPy|_hQ?-4Vi(^r2fV0blRrRBI#Q#oME;1XEpSX$7J~s^48#GvEr|BaZJ9{Kbj` zj}^(q4-=Fe@wrzvy1%yOUDk@VMHIOYdRcv{cPdP*ti{||+C-aamdWl{T=K7Zr=d)Z zp(vlqFeLl%ziev&M21@Z1q)^+(saScB`S?vlA=Zb4fV$+sB7^%*w@efP83Tpcl5;O z{D1_CG7^c&6Vya#LE{V={bD^X%AoAU_M2(Q8(xjfOk18?^=zb}3{@=VsUrQ&pT}tv zE&Oqrmy9j%nIOyCme|<>7Y8p$myQ5y#XNs*+V&ql{lcBLWWQFim78{6Q9|diGWLhX#2#K6A*j{As{{T?_81i!hit0yGMZ2GOu2x1L{4^A-#ISK}jJlQ>vYT$JDrgmiG+~^?U9d)9j0gZITTNRKBXL zBX{)-avr!s8)mYt5U*8XW8Q_7{{8SWDukV;-Z85b$Qblm4#CvgjY&*MWImSNy;po! z^W1{WO&iztW|Qd)O)zrAd@K2vuVrs6kt4oSVT0P|BSU`GzKAb`=Y90;>tWWuxDTog z+`DR-e;e{vGo)^NeD?^Jl5D8J%o|tYPYLR#&=)q?6)qxRILPYJ{Ruo5%p{N7X^XNp zpnZJh3atP1?d?s5{w8nUZe~|w{G9RelMQ{FodoUo5}dAb*xt<2r*=$BG52RCc4u9) zBLiEukJT|DVy?o>f>fna;q6j_^r?hmwKFfF$mw63ihjtY`^o*lRn?Z zyBZhc(qJq{B3r*7E7$J$D{MV!cLWz;CLPZp&jPX`*ne_@(f>>0Qdh6N871%9ypYDlO=pX<=#k^4vF8##nGVw81GOj}YS~ zeVh(WB}lP}kRmueO^7T|X~(|rmtOQ&tgj4dsWT(oo=907O*Y90=4(G3LP-Exwv4GW zK>}=|IJKioN{|&8jfVibJ`c5KCaQ$_V8QDf?}r^)l2cJz$DFxyVwk|&k;w7Jbz+T8 z=TdEuhw9BE_ZEmH^M$>3y{>rYYrzdGkrdi#5R25GTGC!tP(j&C9o8?^ID+->i#}vr z-Cwe}T}nC#GaXIP#fu_x>a>W>mFGLdM~k{y!)jB&-JH-LmD_D+I$U26xddX5W1 z-u2?K`8%l-#itN=!5(r*vbXg|%L4W;wZiA*+`!7*qm%b`_8%PEO9-QAzlEs`6xtR3 zwB9;Rxn4P$-hwvSz8sFw^c1KA8F#e3E=Qk#lvB zTv;w6^qGfPB!jj0&_|Rfc!Kn?Cc9n;91+26Ie`ML+{KVAl49MtspIR969U=^MW5j4C&q_G%*(7_K!}gxJ2lx#>5swx E1E&Uo00000 delta 27520 zcmV*8Kykl|>H**B0gxnrrb$FWRCt{2{eO@n*>xU>e%%_aPOVIBW{?V3E@{iRm)ggy zM~VZ8lvNpwF`1(g$!v2q3wU;R3TkTRWiQojlxCW&VylCV?GZI-iS(f59kXDQj0Pnt z7A^8wsL=YcAjXQFqPg?3WO4)Gh|iVOI^365Xq2@!_hp7=Lv_g{=h%6FoWw;U0aT&- z#|)+52}D-n;^xhpStq|d_xwD8Wf%8`k;rdj}!$&H}qG} z^hquH@Z`CfK$?9O6t^&!7f6_~Fk_4QdujGm=%eyuHmhFT@9FJwd`q`4$G3Dla;&WT z>vQG5=J)d>bK|~ydO6sMm*n)RXU<2TSC5eItmj#{)eGL(nMCF5L73D!@hi;Dp6QQ& zzupaQ25>Tr_mEy+oYjs+%+t$|6>DiTrbT$Vz^R&*i4;-B+%pmS5YnAv0D$lNgTY{H zYilqV_`cuibTDe~bUNI=wY9a=ysSsyo`b=X`kOITtfghhyT#1_PVO65VVqTJ4e9mUo7v$P zuPE3zu7>g6j)Cp?K&iFE`!n-twjS>&(hxh7o3|6%i7c5|%R;Oeu0^&D(jct|0nq7m z%H{IDb?S8EYNylDypnHUUtcem%NT*B@B5Zl&A0G@44k?%fO5Iq>2yvvuI^iZr=~fN zPhojgJ~bc3hjU|oC_Ohljy|>S0|4O-%pp?la(a2*uNgUOok-;eA?0>E8>C!!sWS73 z<@7R@Z--m-_)4v9#|JwG!gz1rxOzA@AIW2RI+^`7&I;N*`r>Djvv%Yu_l>L9RGaq~ z!D-Fb1>R+mBkRMMonzVk13OlK-Y~K!hRSsiq%aAnd7dk@>;1Uj<35AIK)>txKxViC zLT_zt@qYeknI2XjH4p5!wze`pwoYj{-)Uan+S;iC|_;RaH!p;lAco%w6lr+nRY z%pgqiM|C?JwN9)k2oAPq4x75iScgm>t|g6Ys(rYSlkt_ac1WKBoz#zinxynLL?}f8 z!W(ebj)Yzh$+%)FS40-|`Kv=BC6Vtyqy!Nr0hMu)_qm-V z*8*~Dq+DNL*NqIualf~|zOFmx`^-dW#&tf5r@=$%Mmfwo&I zbO0RDIj`jyi_tm$F0AvIcu`ogBmQbAX^}l%8Y)T@Fo}qH%FDi6TU-0qDc#O|ndfrd ztssaOo&=57`Y0`?vlufy)bx1)G-~KDbRXUh27|(Xf%+$I&-c;$FYoPL_q+L{ zUf$c|&mnV|**-Ccy}j%H@wBeT(hl7@-R092*mBnAvP~DK*M6GwJ^GU^PE7YnSuWD5{XB8t2U+FN@EF`FliK*L3Uy z4~6G{yG-eIrPg4a-8ZhDQ~^`~IBVW|Z-RG?v&_~dvpsVVZM5UBT4y|y+cG(17LU%P zycs1sWd7qZlPt1JQ@!+SuYdClGQf%&6m+VhTVTx1S+(Nb8T!o5w^ zZ9-|mq;>CTIlU}slX(@u2~f6{j~g)RV#$(!`nPOm%2jD&{B=?|o_CsQkD~1Gkv?wP z#GNDu?3^@j(j1E45a!l0j&fi;zJ?{xrzHYKIwLnco)X49iqgaymU zvFNaufTFyXqhhL+c=Ww^^-ktgt6<80YnKM~%Zs~1ZfwqmS z05Hzp$E}i5AOHn<7uAy4mIrfRXY*Js)6?bP6GzD>GX|e8T@+8J*p8|I2s1_+muy5a z#VP`5dYsK}O&`L-N1Pjk9}YY7&|BF2~hy!taiGnEOigD{LP$}hV4U;`}SyhouNV6BAdPY zHCbefS?iMVGo~n>8a#iBK-xopH5O@NzyN8FD3Q~{C`CbvK-vJdV=0x2pkyld_TgBa zX|0P=6pe13Fk|lHOnRQMQIkk%j-C%XOV3inXL6!f~^;_ z%aAdnUAb)d6RjKl!Gu@m5&$}@mLSy(Hm9N5HtgdHc&`e79SMI53Ti*!B9xJ- zoPmOS6DgNXgoiOSQ+{1Ib3%oe^~`nQU7_iRVPzRL+j2=b76ubP3z?}1sJc_*(5Mu5v3?pN((s*#unN981U(W6j~Iqk#Rp? zS9YS!-r0ge=yCi!C#Q9D#>JIU~Gnrut><)B>>Gna-K3D9wlhXkn-&5&X-k};y( z)lJ8DF=_9A5&l{-En&u(dIt2Pl^6Oqgq2@t@=m^kV|7>xiefp8Y}*p1;jJuZ3k*jSzscJvnMxt^1jsFd3oXxXOs$!0(#4AGmzh_3#>O7V)@_;=pkQ89J zWR4+ox^v+|R+eE~qO)q{9|NhV8Br8V7Blovu93~8WJfmw;yE`X(&D&YK^A0a_OBYx z(2g9dV_U)^ThFJq?fjM2>uH+F^m*qZMrB2RfnMpIToKivzT2xCGIqW7* zU5}~d$R9X!QK&?e(fV1Zif($;;6C>N*3r@Gh#D6MFIQS-sw!oSKw> zTUqMrki?mBTqh-^r-R0dsIHecsiSTqJUzdLyITg7MZ}UL7lqRnjl7bW$(rJC{WXww zUK-BJ810hitXecF6Yn3`0Jetl-abmE#RJwYAs}NlF%ve#gi6_#kcqVuS$q44V%f0O zw1;4xahKANWoTDK4C;A_MT_-%V$EQG)3Q!{PwDmUWMS%=ei-lFQ2rqyiDT1u=U@ob zaD2z{nS#Xh;^w#m9%=m!m68eVAIuG@UrIyA3N5nyIg$KQP1we@w7s1GfGeWz{zPY~ zfRXhMfI}2004Nbm0)Qx%5!6t|L<*o7*d9p;Y#tAl$_wHEnh~+ZyK30Nj9trr8p;@e zASFjKv~BswTQ%A98=WxrOLoTD+X+vP0N9{tWX4yDtOu={sBaBgt$L?mEx+qdAotX( zWSG?Vjr8z7x39K4oaS-)f|kMp9kQA{d{KDh*{9{;m1Q_2*s!A24uu25*q4c=bdbdAyKeKGuaS-)`l26vMNQPl71-k10Y8F?89Yf0D5((Nn7mo`==LQ zGtH&)%JQ^c@9xs#OTF8mc_xuOoxGC-28Yu$zG{2#aSxxVFj;U>n5V*`ut3`hH6z;F zhiwTSL<{IjQHdsw4di$cmS?h(X;mySZ4qR}U*5Ng2d|i_u!zjY9~oJH=E=}``y!8{ z#g)7rUX47fh?HooXuTerV1yy21M2Q6-D}6dlbpbyb-K4;4uji+*!zIK6oVDA?IJ3BFnQ1|8K61e6aTv*FE(-HvYkpCfLK!39KqA$! zRmYKQ?gVq|R5cQUokJ|L+21IyGtPsee&aL4Y9Fb*-Gm1O(2nJQH5n_#{;sIm88_<3 zU>MncD7yPWGivL14qquok1>y?&uffUhg!nPUp|1^wzF=Zo?a|wmvbn~z5?dP*-mdq z>C1cVosC}o1bJBqR+beC2*N}KScY7pb|$steR=0ZRTZE&uL7G%Jj<8scVCSAKE1kh zqCF!>S<^g`L$@D))?s<}0%IFx4~{7|4uOV(A?+<9R*5Pxq8kxl)o{9L3Y~==Nd?z4acma!}u0@3&51 z*>#sHGRbT$`DBl-WBNALIbO!&Kqag?R zyeQ=T{R7*!W+?CYUA!-)znjUI`4E--fU0-IGjOw4AC6-%rvBan9Cx``ccFB(1n#KEn0L+!jFtY8cPo#K+Zet4oj}tVu zY*5&2@q9KM#dN{)SQ%Hd`@Jt^2}^>+7B%#plvT1=6msdlI5r_s3V{Z}7F3D7(_A6V^5dsu%MN zr>Dn%Gt}1=Hd_%?{w{^B2Hybyd*>a8SEcLo+noHKoU~ACgYYAHo+pzh+ zlWkkg@qTlQK!p|n@${>8L2kJ%(OeDAZXeV-2ScsVJF!rWl^nVlbo=J(JTXG+=Qxkh zN6Oz!x~NJZZQBxB9eZFntaM|9Uhl{ALhb~ADPt7dr}2-OgXvnB0(iM%NQHJf`dT$_ z?~-qWPV^F@VTiC7s@bPQc=_cSzfSMW>z`|3RBkQfR6jkjo$9ZxW$-+CK09#> zBZTg4Z4fEGQhg^QsQex1Hfkk1vVCKJJE3}WLl~kvIuTp=>O56 z)g%z_>lVGA-xg>=waHyjQK#3BjnMN_z+fs8WLou+r$Z3BFrXsCwHh0%Wft!=+=@{> zD~?z}PEW@O&6q6{t3H(4zQBw#ZCxi)7THlJtTQ0C3_2fbo8RcoVDc zxN$dt^WgZ`>7AMVlNiQw);L1w!>2@5i*H4&B8|s7SiNwiywh2=gc*miZ&815AEr?Z zJLkL6>7-WH?gWn`GKzp)X2t7>UugDkV&+uCqMtGBhW++KjW!~HzzL4UODXR zG#%RiL@(KlU*gLRl&spmV|BvVZ$|C9CAJgFX9y97 zXn7sSx5G}f+0X3lQ94&K_j28iO5V!ZYx6oF2hYb7GnQQdLKz2ts=g0F?u7A#cTUDA z&&w}5Jp-P^Z3{Xx&DZ=)X9(T20rald0Ss8?yIu!CNh1uDS84?@>Xjz9STc>H7L^US zJyk6YY+3euma|%OZM#kY>^ha~sMoA0MLbS-YeOm0BS%n;End-I2H;$-2s2i0snu-k z#jR^$%6!9!sI>|QiSe zpw-rRtlj*Xo3Wq_jXBo4JRKLg3ka=8h;L?yC{CM)n9U2PvkXs|t}75ogmM!=v*c?_ zVSSh>MmPYL(F;I{kV5IeZ(gIYf|f~pv}wRTFdX+ra11R6kby44^O5~05qib2JC0=Y zp)iC)La#A))|}HfLVrO@5Cv%#KoF$B92;#OaXYKlvJk__?#O^InGu?0Xw&cl+2Ju8 zc0Gz^sAOIN0$|hGvg>}-?r5lH%OZge>f%li`Y>8V4;?$LdtC?j5aQ>%*E`s|zL6vc zJG}~(jX_$cvJq}=#5dz<9A(VTW71Bq5~uykt*{lYZ(WuOYJaC!iDHTB@{NEPp?lpm z#+wLAV?Thc5%v(Ntxl=q$WkK#;MEBLs>{R3E;W*2WE++Gf#EQIBi$bZs@``VM7p18 zk< zCBL$ihNVW*uz%H7r-Ttg_quD_36&a2qB2}BH4@tr+=uTQqxEV%Y}L%lnhZ8~_}86Y z#Ww6<=k_af&BMfFVddD{?ywSCBUCtKO?rC>9Yo_iWA&CXuQN-=07PTOGQ2qL<4}h_ z1!WK%qLOLxntjFuZZ(lcrqj`)XS*agwu(cWG$a?)CVv~l*(D8%bgP9lLivtT?XMWN zLqY?jcJ|m1R`X_^=Z{&|u7Xns8v^r+3ji{efd`pbvGTN*gEOx-h8-TKS8<1t?N}YR zkHCW$6cyVwQE&S7PSDp-y;s9+BXohmiu|?+LK}hP{03Z6<%r6e_rMp{srdb%>r{L- zNQYsSw|{A~Jq)V=cpE7{Srf9f+3h9WE@X2r*zr;<_j?sZ2BSi-;}I#|4|gglmK$Af zn8cl~UHDa_$l3N@ve!De)jSx~lp@h60YKdYuv9bjzSE3LcH}f;$LcuE_*$vHyHi;) z?A@Kp5@>g)a(3C<-Khj?Zhp(-<5ml|S{V2yp?}by$8m^ucPjkru1C7PA;j)Z1%Tfn zp0hfUxj!H&m~T0H+`uXQk}2}9(sjkQodRrh<9im9At zEJy`Ao>G**52$;+iW}^BB|^Vf;rrQ@ZCTnZEtfl8yH>9A-DX-O9pg;b=e$a7X17CV zLVwGlQ*&^E=rLg5RT;YJ#{f3SVT2BY>>;VO3|1|NHP-@>Dabgz`_$wc}pi z?pOe9{^|!A>{Sh~;OF;zf|sG3XjMCqmc|d)|TK;a_Ecwl-T{XP!e&8B#h0ijyAk}e+ zBVroEPP3HlFjQNkC}RLhkt13gtL5ST;IiG8Zt1i?)Kc})X=&$cHYQr;_(N+F%72*9 za_k#d`IE1zyNH(hSR_0W9_jtft$M9xY;M&Db(Ka{0A@$TP-#o0a!b0wfs|%PP~EYp z*6UisuqtbgMKu6U#jjU8-7Xq#E9^PKbb}pFkQ44yNTvN=B?daZic*wEtbQ-cezvt0 zT)paFz3NMNXRr3ow)d|0Ex#25aDSTdFtV3w#xSy-W()vz@4#>vv3T3*Rd_VN9B35h zElVlWVIR2RC6n+ zZ9DG982c6v?m9B*{~~ZHlo6wRg1lQt7ofdM2;J=^+Tf=VS~E9By5zLk25=z9f^Qmz zG1PV{L!>>i){py8B7zK&`edkbGmtP)bzA}lE4L3YQHJc!QtuifI99IL}>^}b81y}9$Z9?ZPtv{Q$+6k;TB*OuMxejp4XQ`s!} zov1Ap2~shj_0Rwql}mPX`bHRdI4~UE31fe{ECIg;6W^9@=|AAI+d?;K;b>rc({hDw+w#`{zzGw?7%Wk%f906aPS}i>1~r&+piDJdSkyn z1faT07RcWz14y^_Z4%CoX+v~&T$_Y@dHW#V+`L}v2VG~a8nrv&&dPzRcY0QQGY)P# z4Yw8Cbc7*-n+^cp7JtYZ$qa^R_R{|8>tZPlmwZ^%cUn=&j`SA5l8->zogEiIr)SB; z!iEEYf93r{#t)>u<@|^pNxi-Hru{ zq1q~HSrtZT00BjHvMo?O9qy9{fDl<`J&2n`>y5GjptM|ed^;9~cKl$ky}h`3cD=Q= z6#!tIW4c~nVSh#!&XPvZZK@&<3{JwMa?T zT>{YUr8|S(PTTR^TDY@fVc=fg?he}a>CWcaW-1?SU+qSymRFW9H`Cr=Z+d#Xz+&3# z)~?C;^nZ16O~##`)sE$IttJy|$wx;9OFo1d4>~@8PS5ho0V7#uQw^gGeGea>G0$m5 z4O{JXYdj7g3*hoK>za%kJqO5ek=vJiG;G!1asBcPh|%LGYK)geYOh-(Qo&7!NOAk1 z;|D1^JuA*(Hg9Q!%E3)XDZ+-+7I@R>u`iVgh~Y0va(nYqX?qh=Wv8xN<;2n zkfDJI@w6aAm+UCmmF+l_p^u#Zbi@j)CN_k1O~x!n18A0fZ5p%y->$PrjgdW)F?&N; z?yAr-G$S;o3<7K^T&Zs7-Agu|t$9$bXMa8uvnLwo`$OwM*pu4s&6*80I9sisW<$AI ztM&)ge9m;67K%QS%{~3ew+oN_HHf&8cZm*q-XLDT-W;ar)he}i&v&TWNL8g>_2o9) zK1{FNu`G~%tqcHeA3(Wd0l3_$0~TfzFeyT0yjZ3WC3Oi6OE*RA!|0=eS~L&zN$0OKg{Z};45 zGTv&}00dpJ6Ir6}-Uz6&sg}}krI!6`=Z$|OAW?URkzH%by?v~%yD<=S1prZZ0bIUj zZ3v6cRcp$U9o3o=z)Fp_6N-8s%YV@G#wSvIY}E63=0lauJm`4<{H9wXG&?9!*52u6 z{iUK>Q^tVYafuXP3!i;`%Uos0pIf+3)bo@g-j_Qwcupy52Ai9GKM&QMGZIr; z=i;%4uOpSqRae-SVgzzgZ#(_6I3#94x5pb>S(7-6(n}?R6^FQfRH{4bps*wvXUtG(<(uAQ_`Rl%MRd-p)+fH*cKVI|BI-@=5 z>yO+j131{(1>la-o7c(ibltX5y4>~Zh8^`h3y6AN6~?XJnhg>i2Y-OoF##BDVUs{< z9YC|^#87tIwm@bpwG_3td;osC4j}9*0HRkjw{5$+Wp3N$T9bA~xz+?=SGNk&)ZB2r zz5-x-w`W(k+E=@2csi)>rr~Kmsxi0~^}P6IEO*>y$=~Z$FhZ#e#e0kf96Xhe|Ov2R)BS4Z3R@ ziFxa{R+XZt=P};vo>9*eq-ss6uZYhp>KPKJP;$o|CULDPT@mSPXN2Z4^{i%wEHP9I zA-HG;a>>{WG;JW%CJ~k0_S$)TV3g z$t1EsrD{49HR|kR{(YCckzH1+O*rC^vxVfbS;rzpCC^#EhB=-#Of^xjtX5}2 zwWeeFanD?Gx`{(0mP$OszjnD zmz)H(SVghXwg4DyYspC}9nWx_11A7LO$C6O0B~S$0;qIc0Cw9ZQ(&{FTUxCR05>}T zu-x?lEO+a?KiJ!kgX&;!f4N&`}qR!x0j@TP~VM%T2S9jQr~T_u5OkFa&NC!i5j;C-AZkA>-G3c<*t-$ z#$WSy<7MAl@5hx!ytj|l&D9vV+$I3az6aoP+t?7+Ue5ziX~ZQvsx)E%qH1g>H0V~? z5}qHwQ4OR_h}584DG~VC(Y7KL4Z0PjsN3}btbcB<3Nzm6*r)AyvZtpMRT{DGzwCQz zw9mhC&z+7PNL#mXA0o9kLg?unECuSywuWk*3bkNaJlbZiTn;Ow@^yE!?mA{s4-Ehz zWSHsgH86JvZ5H(oIfvFS%8eGcOe3^si%7Pj6dS%8idx+2m1{ms?_khYQLGZF5D{!^ zy?;B{s@jfgby{kW77#k=HdHc(Ps4GxgAM>k$sGfmU6iXc5V}CCdmW_Fu9Hpmz#3nd zT9ve0jNjCayP~%UcvEr>Y1D7|QPkzQMiyA7qlvRY4AHO^yD86;p&hHU6Im?vZuA7w z=$fA$o)4XL4X_NYcM3uH8u)e8carwov43R6yKmRo?T(Fz9LADoPz%5ap$k_Lwi+eb zjY?kmYU0a-+#R%A;rb%w z(T|K0^K1dY8UcApcCF3offFF9< z5!!Fp)owBqp?NDB3Ae~$xa+iZpQV^YE8Ehp5UmXWqE#*{W{ax9`zy;BbSsY4k;CwsPkHYsLv3Nq;LTEy@^D zc4g7`cM*NK)^ZdOdRepqsC1_6Xg18`H0aBZ)1Gd8h^usbp;W zpj)16b~j*MO8{gBlkf&co}ogG7}{SdX}bde24;)`F!Qt!L(f?h<{8>H&`hItbD{$o zQ}WLweLu74D@-am0(7P`zJF?y%Jh115t^1j#&Ng{sF?5TwRbv^@@$Hu21bd6VnDbx z00KY=0R13iwN@{_GIGD-l1X`8hsqJG@%0&1!6D{MCSPoHa^*p{&EPs9+k_jYF_jMu#z;lUrvioZjM$Vj7qzK`;BVlEf=cR=t(Er46 zVo>s+`bSug0hk2n-1><;7_^s!U<1l{sIs93X|`_)J5lUb%G^8}$OF0nknRD1v4Z`5 z0`c9Sex+z`2GEu54iwNRXozMqy4H;_F@NuMmIw=F09r$)BY#>mH+f|#rNluLDk-HD z+Ud%b;Ry^0}1L%x7z#YAs zghx~+;#$*QP3hzQlTTSbuf|PihDSg7oiNQmtC>qjU^BjE7&p0%)|w?T~>Hgm}spTyi;wb z`hRD;L_L?PVGZ#hjQ3ywfTAFbS3#qo!*oxOBUK2j`aaeCYidvjplxXY#Bvago*9+M z2-!Q*h5)dg%9xa;$R+@G(hqr#DvDX&AUpR^njX;IPGx;6yhkP@OQ+huqZ>JgrkxEk z>4i&nj07dk;8sY-x_(Fu;DEnDWo-v zv!tP&F&ef4`myp@-tY}D634(WiFG9|7C8W$MGjr$ld}QpCq&B|`3or^_nlC8KM+dh zp_&j0L;`h8g;LxHKn>C$9m~+;JWIeP;M+6^1{g)o0wCp<-SQy7zS`n&RBqo#t$$hr zj1{%JMysaIJ+O3o^q*%lhTf!)Kt&z|0JWQ_C??w?+oEuS ziOIH9I2O2t=}Hv}WgM+DUxcO>mkYY^PH;IgO{yRVfNP4yc^$y2til9evnUH=kPeY( z@J3EJky2Jxs~b048)#WF4Li|re}B*&w4owoEI7eid;2gA=4`|&V^*a|k^sP993wa| z99_hADGf_DC{oU-t{3JcCN8KraL1f2Q`rjFEwb~AMHxC)R1a+rK)hkHF7G}7wO!!Q ze^uEn0|>%hXt!zRZxtE;;Q2Y8HcRMi=%*0xmf0V*xAyWGQq}m41Ng<31k}<@(rT}mV zmum}Up1E`2os2bHyI|o&O3B8{dM^Z^b`ut3!lXY;B>?upu#&(~v1?hTks-05tdOY& zW8Q|b53a;)L@JlHYMOB|C4W8NwhUdo4~nEJE*9gYEy8w0R=H{@N|9d_szJ&^f?A!B z768<1A@eid;aIAcC}&07-jv z6Aok%aLE)Eo!)n9X&9pnjC>c5#naR5Ypeh(Gb7OE#Su-XV=MHL>3=qXIOzg_ZeoJh zzoRvYg+YvR%}kif=P3m9{LN~Uyl@gGkft}>7i^^$LU^ra%V^}88^BOuC}W@_q!?+i zfDss5QMOo|6gk3BDR+vSXX)>b&U=3w#8<~q&0lR5J7%eKFa&VoAbEM_VPpOtY0aQB zF|RDsstLe9tG44(_J5nP;+1>-z=p9BuV3d5nwtS2=^un9fK+a^)5wMhDEhTOyce?W z_vzK7cdi1HqR8E4Xid{5m^x}F;^r;gL+kbnqiF!k3XtkTvI@v%5swsK~s>-Jh z66R)1GPH(gmF`@VeH-Fuc84!~_3g7K``yD2*_M;ScxzSctnnw$T_Q~xphnIvc1upxjXpr}bDt5!P*O?J?WAOSQRgM&d^ zYpl~Sv}&j0)_)$EVqKMjc*nI)2XemCcIzug%((I2WQHQ+EYdxq^?cpYL&$3;{l?KD zYDdQVjJ_`u6|cfjt10dB7JzCzaQL}ywtu|Pl1V0JqL-Bz`8xmzlfGkmUaLvH;c$Nd zK<@QJCACqIUGUgvT1STGW$5Rgd;42|>T93+)LWi<>VIpvXMC(_TCX<|v7))Tu&=4t zx*_|)!Om{d=pXFt#z~t$QQ|U4tIli#A+4I6)C(iC2-D|(`5X5?`@;Z!^tt<>#Qo3y zunoa2kAD0u0RHvg`5b^By8Oc+`M`5O4&Yz^XYW^0{QtfD17wQ-<=tQ5K4gkN|A&7H z;Iq&DEq?%C`ouf*_OqXQd!gn1Z+*?qJ6^N%j@Nws!HLh#J6`ktx4s6=|0kM%hUT9E z_|mg)oHq`EiX(?J&NbcgsZYISW}h#7;%yTntNkxL^F^h$zVOT!0etG?{}X`!@!6*V z>^FZ46w^gr>;Yr~}fpZ)nm+q=EL_2_4%l#gBhi(qr-cb|Pn!)-nH z+}j-zJkR_8A20B=C`DiR#M_jj-+lHSO3~|H%3iH`rN{YV1vY{4tM(@|5Vk}b^8`IQxU!Y1Q%ekc|^l5T^H)2ZAFQpE`Um8bqq z#SmH#&7E117eUqyn-O|@*a85Ok-~=XIOc^+!RABukOr`>oFH!Yx^mO6$#i?}4H$tm z|JRv*`-PVPeEq@Ky!ah_{-x|IfUj>Jfq#OpB;B8z`J=DF>wgIM-+T$PE(E}GRi5cOrWJ!}oOs!6xO$1ccSUw;C3J2QGbOd$)&j zqdRDqylt`KUHbTw@HrL%Et3a2JOuuizfqG%IzxZu5Ad4Tp;W?fh?l;N2Oa`|;Sc~y zBMlFK)h+p7^?rWmg|FiAUp(wU-Dj%h{@fa1-pmWw%wjhVrG1EHNZuBHYK#nO*D!EN zY48T%nBFva|NU$0FMRdwAN%G1Q%l~j7*C@R^*zna07}YPFFkN}H9^=7#Xr+SX7wFWfqdUL#r)D0-6JtS{=RA$g z7$GrlKlMydX!-cFR|_qlefBJXo#xqmAI9~jS{03;saAjGnRF-JXf>=vZM7Pfg8jgU zh5%X(D@^(*H@0_sB`^E`w!F@!v(<20Rck{S;x3dVT#QcKT0Pp&696+}may6MkW+ud z9Z4)qbJQRJmB?v?W*Iu>kTpd%LYujLw66Pk9WUhH(D%rElZbt&A@V2+ce54xHI}v~&Ng1;BXD zn-2gGMuiK7E%*;&((t@lE4R9XLi>OI$VE24->R8mpu%`>iP``N5rE(M!|1Cw-}|rH zD|xr?(sG#t=_N#*%#IzoD|B+nNtT>s>GbO1AG6jpYt5z8tA*S#c~a?40f3nfc6O6) zW4j;7BqHN9nIam!*DOWYT(%(|ea5jN>Wy~+s5DnG!t8;y1EAG>FMuC?)=YmC;!Pt; zvp$bL<3tJrssoUIlA`z7XIE16c3STR&}+R5BZS^*y_Z1T&IrvT@8H+N)_?WeFTBJI z!BD5w1pvk}##jDeHt6Odys$rwvWpy8kY^@It2KD40J6z%KJeKe`W3!XnQr$Q|L=YE zV5iwyqV~t1y_(W)r`ZC)+Yx_4PqZvU^1f}aaf@TEbeb)0UxxhbvuAamon{@tkKSM1 zjt@G`mQ<~+#zCZZT8+QM^VG(UFzHJvw|9HpK|4(P0-NIgqFMk^bl2vDz2}hm}O`iqKBv;qeqae_YkJdS`L<>3#REjTF(o4 zWVA*O{66$hj;rR$(DTsrg|Fh&sf<$(1>M8s?5UrA;}0^ido1f8rHA1qgk^X!%E%=g zDv(C#0#r|9^C5t}*-d}GzI*EV&-=mWo7?fhGUSRCF(i-g^GNarpwrFVE%44{Xm+~b z4<|ax>o<}{pVbuEXT;4N40}jJC3SV-2r5L%%8)4O$bFYThs?mf@?!x0ZgUkt<;pv4 z2yS_z`7WD8^tOKspmF6r0Dh#otov84ypvmO2zll&w^J$4{H1?^>Zh9}06V|-u!7?4 zrx~q(?LFKM;QwXq02sXXO8}B5-wELVv$+aj=exgQG#=Rb?r$*WWgNqb2&O~i>AdcO z>G5C0ty{CY0xy00umhP+otoLK=k{s*IyN8J`R;FI*G0>GrF@O~?LTR~OBiD7;{T=6 zM(^VPx+U;EV1OVRtDkJfgPXO4t@}Yf*Uv0LM9q5*2NbbYGa?7Wib>8Pb zo85%>0c^(y032(jcfDqtL8Ny4YG|8*f}M|n?GD=fVeqb%>l(Zr(Yg)E`$W94b&$Cq zgKZ!BE0dO<^$vhkZq?Hv^D&2)u?Z~>H*!ytbx_uVMz3@Jn!ZU|2$vYkc+ zga%+6(B?q)^r(|q-dI-MU#{IduZ_X&yqm z`&l`4iJI%wgRuQaY2#=u$00yF@7Fo#JFzn@RloFYJn+!{db)S+3ApSQlEfhg&zO{+ z^GIB=mTG@3qgtCCu*?YE{2$i#Au84q0LP^;P}}iA#ad!UUxrL+*TMiJ$$Oe~>H+?m zxr`nK-Y0vVv>(Yxwj$X|`eD)!^P;dycY=5&h*u)nl1Z)zt|?Zgk|!}Yq_fsxhj;+n zSAHyl{E_Bzl#bCif_%8~E&zDv?B4B(}2k5N|dPwz}Oe&rAF(zi36-OTW-mU&R?YmGb@Tbp`~5#|ai)NZwdA-YJjx?_t7g_)#*#Gy zZWjk{0F2)(d^32TTrphDz5r%&bF89x5_;qOz8Zg@bvlUyb8|24M^N#sN9xqYHv_nO z@eF{|7vBfq?30h^?bqM@?{)jBi*HU;)?fEbp}zBhH`@^0vVHNPAZ~77d#r>(-Sse{*B2u>F#s=sw39UmuliX}P$c zZ#n+_$5%aPJ8@@#Yft{LN*gzx{F5bW|I>@VmD27%z4%+pklPoZ<}F4TJa2pI^-uD@ zRdX|dFi`bc$dXL2Yb86T@TgXvEiY;CK2U#kiJC-hx(|c5#&1_ZgZGJ>B911*UGt<= zFET6uu?j3j6+;NqW_kKrlCmF`24>zuMULTNgwRpaX{$z7&kx2-8M=oEfHo7d7#*E; zSX)0A$BQ$Z0mI#G$Y3yh=x}$3;XYh1!(q6~fZ-0qhs$suZo_58-P^wXz5OFk+UDlD z$w_k4&-dhXlBia1yiZ3KBr0t%zdbC)wx80sZJ9gTyS#!f`qD2a{)7+8cpI2)D0Wwm zd!bUW4{pTW0D!yj{hO<9KfJb+57~Oi=Nyk8>6(v6E{B%Tvx%cHJ;i_JrWf4p#?`WU zH#5#?TPb(PAzP(V8@v)CUfZ0p*}j;^e1bi<%pE5LtV~QkhGMQ`eNK)(ORPbWTTwl! z@Lj_zd)vLj5b&@=pH3&MzhTnl!=ynf`Hs!OanUE>Zd4BWPX+TPampB;P^5rBtw@Nz zpvT?G9K3Z;mekK6;NjQ`D0yU;Qqvv zfzJtWd0RaX9e@tP{kaUCdma+Sp8sp3Vcg2|QQzq|Rf4}GMYq%WZBZ1GF2iUB5!RK9 z76%Vg*sd}?jEVOxoiu#cwf*PSr8)%u z)RJvSs9Xzc>g+?u{!vT;lEPR)2&TL&#Rm*92XvL3r`8ej5js5l)@DByKwGI8FLll z?HY3?_N<|=QtSuluvtvMV7#Gsr3UrXd->y(&9) zA4h$>62zj1ph{c9NuTb>5gZH5PIC-bJY-aBp0 z^WI2a_gIqpQ7JzIqqY;!B5_A}AOqQTlcnsk-aPq8nx+n|S2!(6Ce!(JQvZS&o_Ti? zl<2agKUVtK_%9!gmuJa3rSVrv52>ZoVQzH>Tk>R|gi!f?GLLzM)*mnsgY9-CNg6zy z9p~Omcy!W67Q8wrmndZmVqEkzVman)4LH2yyC&@(|JNFMhJ9w}O2C&wa%lk)BSZd_Hd2Ya9RI&X z*R0fWGei0SltZeeJ(R#uHf71l-wtFp=$aHk!ZdS}$Q#BaY3IeqALSB}v#F)w6In3?N&!=01r&pSQY z*@)JRmd0}NULCYz#(*kWj39$wtn!Ws$;{U>#-m+e@rzOl_GQF14(NPT&O+lH=tsMl z_XViw!=StOnII}5)8FU`zOaJp=1juY&YMhvk76F(Ei27%BO!0OA69|H?)!vfZ3mt^ ztr&Z6kEuCrUtw^`rj|SEJx)j!p3u)}&m)@KNelcpR&RtWP z!1I!x6&W>H25h)F-Q3am!yIqybZ#9Wc?z5bG=upz9u`04LrAXk-O)-7&(6FCoGq2q z?JP}2(LEJ@dx?LlY);MkMa_V6o4+wl-=yL2w42qf;V=#kGb>^lq0>n{iW98MhE+!M zW8tTwxY|Z*VMvHv?Qc21IBaBu-p=rtAxv?E9SEk1vb@P9E!LIr<&5NNRSp5F92ccj z9X?#8OMXT2LY?$P9pt=WqoXauhQrQa>*wyfhMu#seQ-7tn`WjR)*`AAL)J zO)&@IN)X8o;w7j}&eO3Y189cLuo{62?T`(9p}T7~7wzpSc1XQHf;e2DQ7&^*26 zNiSH)K09b*s$*h~nMGpON16n-8S;L<%WeAUiFrPc-GQ-&TK_t9`$I~^)rAOV*&$do z)5LEgT7Kc}{Oj<@sioIxv>uR<1bj(%Ok)-#pML>ymn0HkNq%)7Fb^92-bTBtLFO4U znei1uCk$qbZ2k;4T-Ky7&yx$4^BBVj-V<6R3(d{0HVAGcB%j{|{6LPG=n<8}i)vn7 z8Ab`_f>v?tVrPl_t^k(hHTfo4-wpIZ^q_uddh;vT|I0MKA5%qO+&Wpy^+*>bwXJil zo}zEq)c8K3n{_F9I|<5tR+Qc-dqE?u?2|CgJ8+!iap%?eZ+B~R1nyZWhp@9sru+Qp z8H2tFKZ(UJw(!NR27nZhjwGdAtz6QpFKgSE;%2kAjMSo-8&=fR0lwEo)Xz>Jn`vvN z;NvCnG2!s^GHTIV(|mDORv8`MpNJBf&euPpW{kpuY42>hm-PZ(@`FykffT~x%YRZu zqsc4HDJ4(x{nf`rz`954K1TSNQ`Y^mzqqs8V}K4>$T^4f0te^RyP2afGWu3%`!6c8 z$4tq|Nfdtt>(5zAv}GR!rYC1I11bDMVa}jtOn%ULo$-vJ^P}ax3zE-RPcXjZbsg^G zAsmYcJe;c#=3Q|Gr?dR|yv!}d0_++`m+p!I`$Q_qVUuvqaqgvO+Ep5t~J=^iK-NX0G zBbCuKl@*m{O-(PbX{bXHj2I^SCn8DygN*-I@(CakW<6j9%Clje{~N4iY#csW7jMkJ z*2MpHrsr|)+h*?Y6fF9!eINR1cE5OLB94H@0zMI_dNKea4y_*?1`Y{&hV4cTbs}cA zHO9nGhvnhW&w-Y?@4^^Ye$%-Qcod*E33$<^DiD9JXoW+bZZAi;E8#D-nIH*SO&h^; zU;+Cr7e2N&v&JLx40BdOS(`p%!v(@m#4l!A<{e{RX3Ha5f8MODOmRf76kjUvsJcKZ z>O?Qr6AtmS-7;FUuuh>)&aYV5jLYdFchc#cec_f$;U&zElqD+wZs}nskHjX=1qm+` z0{Ot4CH}B~XzFun8gv1SZw5e>r}Kfe{|ZEkUA>#`xmf*g4K8yKFZ*$Y z4oSQZ4a$bv-G0w64IQou$`;!r45DdFWB7P4k)9%c=XTqQ7vd4~4=hd%RX%>Lq472%}S z&ZI9I*KYiuheg~Rn&E+>Y;dNUn{VGM*i3(=yh*&?pLr%Lu+-R86@6Mt#?f@6$iQGP zG}3S7P<YbVOmq$}5s<@)ia*pw}2FqOw{aWQMu=c`F?Kc9EDh}bL-ENvoo(16zE$yr; z`HZ`NA`;;$_*C+bav*2bsr897}wTA1@z*(kcyhqhRJR+%Oyw#CTG$Oh*1^E&UmW@#X zS$f~1%xngO{u@_a079x-ewbPi(tANskh{C17~X*ww+(e z5_GWAYOY0m4FB>w%bwwX#X%z1z{#3d|0JA8%OqTMOm~M$OpD%oAwtf|QF@ES?;Am4 zR|V7jSkLw2K)pE`ZorNBR{2wS&g7xai+kDk{HoivX_4m^l84oBK=aJ>xnNw}NHG$C z;=-EJae6NQz?RinO$Tv}q1#lmXnD_<=tuCoq7R>4vI-5lU-3>wHwEC@Mtwz65+r4;86~m9@8d=dITF7%nKX*9|~+X-YZ#jGw1u}hUp zfzCT~_+{B7PjQWbGyxELVTeY;$EYMjHmhKrYN6n+Uz2wq;>Moh`o_Lj=Q%G+oG~`8 zz2vt|C*5M2j_!o_T%!G^SA1RjKIl!byqP0vuWc9Qcnl-A0hvOx+LsF9;yT>Re%Iz{QerwaMCV{Eb1h+}hqh)f({{V{lZc3&q26+MMOm8H}7> z9E-rkY9~Ouo{M0#WDyuECG&g~@CAE5#ZT7!^~o^s@lO~*FUFknR1&1=IjFfW4+#9w zr8Ks%6=-48Hh?O*HiBb0$+y;fP4;R+-g*jt5}3R8#c{vES1b0FX?V}Wd0p4VLMw1m zQAbKIuYO3-D2vV+m90gm$t`)9pD$8KT%C!^f(uNqm*0PI|5WrE6!l~xSMn4K(viru zuAjx2TYm~y>bYg@ye&Im`giEDA1-CB^H#dv7B8bKTY$9VGMHxPA8lk5zCqo2bL6W{ zIwX%eE8BI=u=m-M_QpPh&B6tSNQnvBJc#kFty31mF+?%ctp4ScO4 zu(VoDDfvgyr`RGnTmHYFwr3likq19bXe;~fnT-EI4?NQ!zH~|@Ct7mh|J$qAbyK~D zpC&ukcJlabk&7eIdbnR~E@=?QW?}p(PMidQ4pC#_vdaHjeOS?%TW~3p%XbSAtQGi9 zsL)fyu?4RiV=(ZlnY^s(!-g;B5^0BAG0XCLh0bwVPU!rr_HJc#7m|-mI>ohcFBN9g z@v4uNQI+4ng}P;b$RW+{s|ybC6*6)=k5y~giXB6T%xkW=i)i+Zum{E_GUeRc3e*AJ zBmO~qNZk67c&cNPM}KhyC*Z%XhvEyze}B(&PO+j)*#wYj{=305cIf;_9nSB zh9+`cGmmRdLMH*)vu^!1V3VC*YI8EPUqrd`RPUaGi4{2YdT*cmz>wAdekjX|PenBa z;k7gl7FvX=>^MtvY_h5>QG`^{mLve84=0pm=ick|U+FFpeWMZXeBDK&&FIL#NuE&o z+Qe^BJBDo1`;=`kFwY;J_ZaNc+HTBuO{1%o8(HSAB!7O})s;$n(~(*Tzpy^0`wsVh z!TB}L5>D}+eYjB@_m?}IVhT0Uh^G@=NX%cKt)K8w^?Uo55A9M7n^qkgKxo5C5%Rn8 z^%T4OuTWD{re#5|CkxA z?%Hr`P+wn*5~2)(u)L;A)Wr~d`QePx#i&Rw4GeKYUz6xFCk~FWNE?xm;fS?R_@hn< zPF{h@%J5K+qeC!z9{3S~R~oS_tLwIhduAwUrdAD^wGMc1j(m`^@bZah^R=G7OlucH zRjQwiWvzmSKEHOGh~hq-^y$cF3+3G$4=O5$Jj_UykfMuHSi1@vU*>=_d2c-A`^QgB z&GO6g#%?5qGSVFMpWPZ9vp_Ao9BgzUvu8yh2Id| zBmM{xd$Rn&Ef=fktBFr9C9F)%XoGHyoq8PTxSiCj11Spss+Z}1qAg^olSR0-l81j) zDrCW`y%TOHU&`}?OA0A7?N{8vXK9hj{o?lBx)mo&@I2>d&h~7Aq$iK#t`M#Br4360 zub|Uy?LyVo4MTwb$iz3ZRg4r?{%8W~GWEwznmyF$7~N_%ZC^c?c6n~q_TBXrUr~y@ z8}weBEr9dr0*!p`6+MUx3kEF-OH0Sq#uz}Z{Odfxk_LA)h+mKE3iHH za0~AWS7=8oQ|YK@uh?<`*JhTF*6`)|d)-L+lNWCn0Ap<)eGAtfZ3$uTXif-mx_z45V`onsaZu8Ju($BF+bcenM zGMD@-=d`)9niItFJ)M|wGmMgHBc&Xpl(H*w&Ho(ZzH2#=DSmx#rB3zuY2&3Tlrp^P zDuQBV4`^aI#bd)_HNgX=<5{hMv+a_fF>_`rdRJJ^GyTunz#iXIf7nB z^{CS8xEU#a9Q>KL~Y!;Xw&&V_Z|2X z{b%14wws_+QH4M75g?#d3741Nm)|>_SM)zH*LWlRi&x{^vb=cryNauw%$Y;AMl87>3@|cNl?wy@hOQHi0?;=zWqHOKR{bV1eQt%LCpi341 zl{x#oAHBwRt?TL{=)1_e&r*ZcB3Czac>5CiWSagNz8#n}xX^6#S0$>=^Q5%iSN)V6 z0gcU40{=U*rOdIV73(pF4-^1NY}AUXf<@D3YnlxDi^h*eC)|wYEYbS$K8qt6yTrgH zxn&9eR*HFwZB znpO{`fmTpE83{=Ow4kGIC^N}-RNhoE8?WI1>A50C>rS#Ym`Dx9ji{x_BE{@Aa+1_% z`e!XUBt*PoG55<@lz@XBQY4R~(R&$%yuhm@l81{yx!2)vor0K7^m&ioUv2ZLm%KF; zNB76h|22!&&?y0G;PGqFI&2YbgQWbQA+-;E0%+?uF*SZ^;M2}CQza2q*%Y;|>co=r z3%oMWfAT|an4#{Ji0m)V{R!Vfc((JGQM>0p7PS2KPb9EYgbN$^X8P|kvPY$L3zK?Y z4)V!LDq(2N`?XlWWfI}h(crshx2qJJjlMPEtR95+Yxw@-o8vhVsg3z}xSIPbop$!v zcfz_CE^Tr;65^v{<+$Y+GVuNg8y(8fXt-ZfQ$LeDTw1D}D1eIO-Q zv5(0oeR${BUH(vUgtp@Bildwh7L_|;lG(7@TEz`E-ieaSX1_U(1Ih zglpJVJ~*?VCZ0zevT0nbD;Y7hpxyVG_IHY}^Av%AY~qiTBFZ29{`E88H=}>}eac}w zrNxHF5G;B%S&;%iB9#Pds*ICDG%^bzyr>+yzY{*%|-Lm(n1M7%*I+)sL@VuZ^X~; zIg*&KpKHW%BC`_DCT-Wio5u=~nx`o=Vj-r#(an1jz}nNMi%g^;_|a@1&baillbd8B z$Hyk^r*|i_m}K@{))v=Zm-W>A3fTW^InT;5GNbf%gsDCY$Fn1SiF0Ojv!@eIL7yHs zm6S9)`X4_dt5pZ}p%?ga!l#nuq$#_Q;MqkT0{m#Gs|so9mB?c?p9Gs=yuvQ7(G4iF6dvI&hlMU_nVfEw_@w{ zIvr!r?Za68kho_p*}x^R;?7@@DyEBko3-vM9#DX~#Z2vad#88ZDk~Rw5OQv?n5)%o z5a6%MIz0($!L^4JTOudZ5ux5ize&4lXc)2v8Lj6G&h`J8>n1gL#PjaB^&t6Z_dyR& z-=5<^2$>U3)fS05rHa24lfU6hSL5fo!Jy0CQ*tQM|5Jd+hz9}$W$X=Q3N%)+FUE%} z=`*Elb>eJLMqg2;9jtv-N(+i*(`&m#KxTdLlPbCDCiNxtvm%Av15eR|!?44i8-LJ* zy7?wcdM+fILFqokgjDoK=}QJ1z32@`Vhe4U9hY#oc9ni}_O{@YrQcLC-V@T6#8@#k z69i8pZKU5vn;A%pkzZk;2vPLfzT8?3EBSVgnUvS9#xHBT+I|&Qwd?8(wEz!p)d3|h|A@$l2&+1D`5|Q6<@*mI@0F;1gO)eh&5MK6*&c=Atp&M>+ zec&-Aq5T={eb+gc5U=2^^TJ=;Go9RiUHk&vf-SR-s2Qb+O{1FbEnQ^76u|~zw6ZJo zA0)kWC^)v3Uzbs}-TRzCK?k^+cae)w3!x`YE-7~ma-{9e6(w{_GiCKDoZc^G7Bz_$U+l4PfdoRR12H!{2)l_jS-o+$$TF=N< z>PR?`BLB44hVJwLOFO&nX*JQ6W%pup6ID?&Gx+S5xo{VStxQP}Taq0~sX0mbNAa_3 z8}SoYOR|V(^D^pta{FIdIKpgJm%WTRA2`&3toUgLX|{I*%M4BJ%6NfS0e@*LO-1I4 zUoWxlwQEd%vk9(#yZD@cp;-KiEug3==W@FMh# zr268%-LHkSN7hZf2`Et5L&vRi&eS`8x3Le#A#Q!P@6+Z!Z zglh~^KH?X1CKQaO5FWU3;8i#y)UYS;VL#R2KK1c-6?$TrVvpfv^9(WkqM6!E`RXiW z&NWcXlu62$Z#sm^k7bzYC4P3FI(r!+MvBA!V1`7a8E`)oN8J5%w4U0lZ|HvcqOLNsrQ`Hb8R9S1x;0&Vvhz7ck)?@SlcyFyc@H{QZ*&ei^ zD>UM)EP9+lCxi*@xiVma(%IfGhlX{S4a;FfcZE!Nj+2v*=9?GNoEjv6h)G-lTw8$) z2!ZfsPhyh3CjU`3y@ZXoWbS*^=@OhLbk59HbvW!Zx`5FZE@u{YJ+;8ye*iC%pnaGi zx78{QmRu-y!%X;YQTXHp?!P>uf$K5{z2&ACn&EJ2ABh1+`H>iKG?`22;!~KOd7ya+ zNw({Pz1k##8d3pw@%%yEd35LEH<`UvhGiF2bFcETreuc=Q1Y>+ua;Gn6^A(R4sqws z#@iXE9tZXny&92?nAZ^P6sctW{;7)HVpB=S?imk3K?>xD2Qp*-SR}l7d1wjHbJ4^# zlJg5A$Rg}ds35|_71!`MNyh6s<7a;1KP>60xIr(o83}-T*##VC3KPsKYU=c(k2%YX zHr?Smg2ol`&p}&CDLvOR09-8L3=6WN)3Kf%?MiA&^v;_|QSOgmLG~%5rAF=RVmZUX$lgmgHS)9mj?!7C0dUs6J;{ zY(bhanF>4#$POzRhJw9o-yo?z5?gGgKua>Us0xTlVQ?%@5OsjE$@HQF39$Jo!p+`yoW9yzNou~8T;MW+u0ur5dE(&g|@{Z!{*xlLYZta~N)eiyt_)lj`tP^uP1~@hErZm5bYfWWHMdDti?}ufrQzQtX&$Uo4 zaf=#5cWcCNn_b{cu)Dy^Svc+L@{6HNyNWs1Jl6wiR2429gnud^De#5CdrX7%+^D8( z9;O5Fhx~%|Xu~$V*uX}fxG})xa|)D^SgS)#GbX4i=p*Y>F#xV-4m$sj%O_o%&M!bs zUbcGX7LeQa6%Tt};K&>T9`1f<0!C>qwB8z*d&Ox}eK0+~!)|uRi7kUD;+S9fq#aXU z-NEPby!NZMFSM;M*9n~$lZTr(C2*&kR-Xh^H>Go(wfcb2>uhe|R9p)Z9aE7_{L*bM zvTtgO*Hz$!LmvQ{J8FA*kaLEE^=@WQj0Ab+OyXwbYJ8#b&xv#)6Th#OV&po7x!g5~ zWdHtT##OI_LAGP-yH$Zfut|mBPdrJR$AT7ReG%68|`$2kvES~vBtg6lsM?d~t6DHf~6ct9nE zNm+5NJpWQu1Eu`smKo@p$07P`xr<*W=KTK!lcgsmvJ(X<-+2xw#5E9rJrTK7+Zs4Q z6@*n^rBLpmyGB2RCc~!?`W52~B%^t);$_~>x~}lv<2nMhb5Mtyn$>N`XN%Ri>W%70N+A!%w z6toAJtgQZgT2AGB%O0_XVW5P8L6dPpqQK?*0sE}Ulaf?b5e@Ztb(bSl@(x;IXkkTq zITL)E*dzha28)(+rw4!TP$e3w>hA-=?;%i&g4|Y#%@`&$7f3SNO`~V@!k6?JBUdDP za;cM!uu)GrlH!nj&gie0G0(`v7h7rMoWKmv(nFSg3&|uEey2FpEY#-!km6#bRxyLD zDhehfDVZ)NgOh-FAKHx&K7u@QlUX)bT-VjAD*?yx<-IBkAUYWyR^zL2CUnVBLTg7g zjksNt&wBpqXdptRG1&(b^PR`02lAIXid-{Dgvs@Xq6Nc5w!LIhGd6`hc{x30fuR&3 zvB_}995Wqj)w>B#`Dm)b0BI+x*tpTp9V2#^O?DAAb3#&a4nI`hcPP1$xcpQi$x6N5 z^#De~C`rcC+o+lK*F(+gOF|hjI5`4cTrWh+bdPyR^1YK}%%P@wy^?qRjSGSfyGk_| zO3ryyt`lz+!1S3`9~8JUjl7TGt|jb0+Rca6oTN!cQ5}29iv)3nD>(^M5X)=m6q8UC zKy*ZG{UcbUNNOw$db5YkgjPxcW_={uU4XLGJ0hlVqTlcJQ+)^ZA6-erk`JA8SQ`_m zZ`m$x>Zb%dFy8dUUyGHj$|uV+n~a7sy4PF-XBF-85%i^C#We)GLflgq>#{* z0kK7JQ$!XnC-X85;z$v_#{Vp5)ewiU!=wD^y;p2Na)X^=QFCefNi?B*qoq$h1_;pG zTeZU)j8-r!tIr*x87=iBkzh)u=1RKDosn>IE}dK#_e5oIc+XiZonsxo+h8enyei^6 zmH*GV;K3;&g~wxKq>RAGwhorX7=ASxb`yVK7waSB;i#Azrc6vE%`Ce4g8A*byJc~ zE1e9YHF7!WjY)Iv?~czu(x%;V^L=+iaL7@k&C&G~LQUuCC`-+iUK~L`AqQqC4#?jz ztt%BF3N*4;$m{14gS^NHv=PuPzpqXQSdr?^rSb(Rjrs(6j?u>(2D=c>cYdjz6ScFS zc%i?~d z>X*iziWknPyVlikrY)HfDZKIop}Twr+om07%4Qb3c?@nrgAP%$VCiHMHwyuOvF=EZkD( zODVXQy>i>$n%D>8VSsF2^>^1~Z_Mp2r}(5K`GMmPIG)>|2o}5TB2;LWZG^s&aHBB& zRdGbOwm2|@@2czGpjq-Ty=BNYGf?3gUq*3lU(ZuNW9>TQR{}w5DxKN2L=D4mJ8!8# z5VOQDA8?_f`{3~iUw-AN_^tW1U2saIUgvdjo3FvJ?!{&=2f!}07Njc?{<}m2VIGbU z$D@$S9bZ?g|1o)d`LY$9ajF&Z38@@8Yup5{4wP7_pjAWC|9)#mCCk8W_HY{hw?#yLVSRcjqfJ9yOz|^%9Kh%T9!F z-eP;6PlqVDr7u0E>fG1Z+-D++eqgvV0OcR%vtC5p69MvD(Pl?RsWPw|Q*hqki~qdn z5>=Pb(E(i_`x|(~+wfG~dQ|mqjTyPJFi37uu!f}v@f2*Db+&oYY_=BS0DmYr8w{iiYM)fuc)y;u~U#6oI= z*pCJsTy_Cpn04#5OZoJTQ)O2G>EjahjsFfyUDGF5h)*rU+P8e?=svNY$2o6PCjb?y z6He-$2c!{IKl{hhI2yYjM$VsJM7~-QdW9zpIfE(DUs#3N!&xO6SQOWF1b>RC<6*5& zn~2UbG#~UQ{jq|zz131(>oYW_G8^oRW;;4BUe+jx8;x78@^$SgZ5_K{Tkj^@oH-q? zZ#b)+N_oxPoQfNdc{)4XGi5MNoGr~2q6{z=mF#ZJwcgU^@HV%`NvTCNQ$PM$%Prtn zA_l(rGPDu*j&N>B`3AUZLkPH3IHa_ziYL+uwhm!S?X>CDrHQ{xNgqhbdBws2-RGDH z!PV8(KTLl=1(weKD1*)(x;!l`EGSswP^K~9EK1Ts>wI(LNYjBK5uoXoL zQZChCPrIwuC?(Z_&#gej{X;s>t4WT6~ zT|G$3_ATsx*`vtxCcPvf1W_){nqaC>dGU!W!vdr8p=XLaVl;$DqbWr0 zetaxnd;6%nE0wY9y2mmf)1Kz$l#6-~h5iTStILIj)IF`CI|~efcsKOs%$c)slg1Bw z$2H~%W{F}ItIK5`pFc{t)QNssniCxqws>@5vo+K>?GMe4uFY@3Iylg7q?PN zGNE8?1T}iTzqU(Q`H)Ww34ZWEsb<)<{WvT?h_BI3(@-{LLXN}qpFbiET?8j`S#(s_ z)G2E_LA(L&-s5A3lLcq&6ZGcBV_j&|nqHEp=1NTjokBt2sNnMHvDdAAeCO)hjf;Zq zoy*@ZSc8$GM&&gB8k?m)jw1l%j$cHNLt zv+UC%xZe?zK5Rp}(UTWmW;sJYqxurbFLb2jqfRbnRMiTDweO~>)VSAJKZ=56jjkq`G`~niUUP>u@K0 z2VL}NTY}g_(pQ3qUB5|@I&bv+;9W~_8DgOnyq~*HwG_5)gfFnTmStblbFv&3pcgSF z>8>-toZz_BVn!O`t%rsXe7smYG)7}gz|r%sVPmRQx8D+9N0{VAcZmm3=% zJy~K$dr;9AGVbtNPPi1{5;GR?lT(;~^| z1)}jePCWPCR2|3b$5fs9fa};jtt-iPZBCA%R+LBcacpq&kFC(<7gN1#!fy{Bys|JJ zKxm)!4#o$4(*Yk}(dfH|k7l`EK8FaYuCvFI#8>p1($n8Qy+>S~U1_D=Pn#Xui(@+y z#W2EC&Q|-ST0pKC9UoU;m#>vBqY%?DuGH}=qB{{czOwg^HS-*{TSQ|Y?9Hz*mNl))97l@~JTa+*| z2EOw!Im?V-WW0KhzmGbZ(c};3A=MA11o0H}~f-Wx6t`O*U_vQC67Qqz7?OkDqBC!m|2Fo;~Q;XFhr%iztNG zs{`yx`}iXbNobks+_#|3>?D9=>7U~C zu?bjdhYI_RVIwc~VjlG#z&S1uVc=vc<5Woc^4`POl>!EmP5Ct4WI=?ZvGg z@GJZ^u)TtQn5_y5Uje*bBTYps1B&s0oC))0C6%;b6*9WKaU%b2cQuim&yWgOs&OJ) z!v^dDyh^0}Ls$Mzz5patN>?YWKsnZifGz#GO_D)unHT^Nve%X#rLI`kraIj#wgJF z8gA}U(#)=)#@pf17u_DmbLi72^ND7FyhWt4<%GLa$GOe2e*6A*A%Ff-7zm+8gEjW( z969~9z2?8PSG3qak@_do&V|3{h=tqTQvt;^8(Q#>b7RcUj54s>oM{K6Gy^O-_wmJy zasa+IS$-xbiaqPCk;6SoU~*O$^8K4kgIXuyJ8=+c(`Q-~@sRaIO2u+Vbdbv}Uv$0!l|incLK(hqjh$-^@S18+^z+N?pQA zm3kMn6%!!)hUiKkAgugKHf;=u$&oaSVW)}Y$UIhK+wRs@PHdHe(jJO!G?{1GlnN6K z7?vlx-k2d5MBFE9>RDb+@9+k@yUS$cfrBdjZ<;(y*R2q<~zL5Uo7+bGn2Fs7H@`QfLT1CKswQvF&ma8CYDI_m-ln+o=7N z8GQCPTK?~Ik5DoYLJWEt!eUj*W%DnNWjXorEv>mKVFraA!9v3f17($SGNhxCiKQ6( z4bFe)nMaNOLJQc%Lk%3+!O*~8_~H|McU|LKQ|$@w-GOz1Z~o77w}KYX=@fZiZ4fjW5Xk)-`g zVw~A44F;{!>o`WsEmgPxifRlK`N3A}_1Ukk;SO^(u|vG*_j0x8BgTj$a**((iIinC zeq8CXtFB#)*1$MKL3Pv2-MEj^r>f z_M4;;!t&Af%&855Kcu;fS1PNXTroqpg$@wZ^hY4W5pjI!Xh1W@p=w29AD&hU6mqE= zea&{EjbUc8h6$g(>W^@yXI{k_xms&uQgN|ER<*3< z=l8%Aoihmak`ph`CR1*Urg*L9QW5+ir{T(4VNm$FB2p+9rxxkvHJA8f<(2N>Fx+jE zxO&i5qEOiQ;bbVPo?e*af0Gp{AX-tOm9!eG-uSdsy9|F)BKbN}#Gkcjxu_jqc)j?7 zX7W_T_v0z`v7<)gZyMGwNyodPH@MC(<qS;wFtexeLztfiZZwFbmA=#RVo9O^cOhSVbAw3>;F&mB(mneVt{Wl@A7btZ#g4 zcjv&OwNZ7Q@b{C^JHkv%qU5~V(jL$*d2$cZt-}YtwH)qzR+?0@cE;=$o86S3N(*@4 zaqZWps~H#LL7Oyb>-j?Y4DZ)ogu1sXzl=I+dd<<65T&Y|;gwZc zys@zA647^8(VfX*tWupcpH-(6S@o+HaqU5btW=L}KZV*m1%i^?!|;m@^gT+PL_z)l zFN`p8^dT>@JSI6M4yRbi?}UYORi=#Tmmh2KkHx(1Rns(MdAK7S^C6CgimR*0KpV}` znTmTV3X$G9ASnG6HVEg(dm!R7u>`uMQV|gO^)w-*cmG1Qyo(AWpBUSqt1^sjd zDu{+bQg?eVwVE2&rIjSw^9$L$$HF=rn)CM>DF{7M#>&5V*tfUhzsEO}ukb=yxP+X& zbJKw;gvkeN%3+>=d9v&5x1~tquwi1Irmh_6Ck&O%4baCh)(eyRhR&jYsw&7C9gv}` zzv01FX`x@0YrZT{noHV)ivw@Zn*^epIY!jeR;uGMABIbc0iTPeJ{X1}b?b!v7D|HRzV^oucglwi#y0dXu zcjq!0LoG14Os+UuWa}9=k2g^XPzwFN7L2ywAq@4Y=j&lqDu_;S zrb@6|s@NIk^ZM5AQ9*+IW0IO+`NTPSk@$~S#zA`hEpFLtPMDHnHin(8Pu6O zi6*@<=Ztm`!&`sOCvLuhgxBJIA4-><{lh0yDaE$6%RwpbxT@ExqQXJYI3|>AX#)Rc z$Dy?K`}H35c2cG`@LLz_JC-pN_;+T7u&h$-YLF!T%kHi(g%v2%Svp@Q-skR(-9R`7 z1M-Xwgn#8?7ggEj4i|u{n8$S@eqWoijoAf8p&c;4Lt8p&Pz&dO~IA zHFpLKbtfH)_!$;0ss0VJi(CO&b~(B?Du-8WlhdjlR0Z+2mKlY8ZnazpaG5-jKK=FCVHgVf>Wru_<29pj|> zZY47$lQuP0bNpnbC}`%p@<=-ERBX9U7bEEkBb={I9v~2q=1CJ3KK~x=S6xaEDW#D7 zcdH7url?p<#(yBHF6jYD*)qW<0sX@9AtMpMozhBegr+}{c!KdU=CwL%Rx)aUDXiqu zgF~PD7Yfb@nm>-XOC8&IRb`<#`s5{pO><@Q1s~iy!ot_)mpY)tJ6Z(X#(610QMCuiIzR*8Pr82TkGM2 zhLA}N_!%8qyg!h}x{mQU`3#Pw{5Qomwd4|wSRpzTM=r*%!`wnQo-%3+*(XMbsm3Yj z)I(I=bpM8@1xhiYWK|QDEd-bi-gv0QZ+|)b4r{x(D2l9B{j|e!DR94{m~3P_hisn( zHy`B_HVe+~5FZ`CJ%hvyruAtDp94TQ+=Pr&y6cidyNqY5?>g@UoxNoppUp*cNOhRw z(!b4-mg;@)p7xLVlBhx6kMkW=t!t?^H3-(Nn07hA1q%l`x@Ch37)EFv0aqTmLt!{y0}%ptLy(o3lG zPBRBh#1$~owoPpvF?1sX*ur9$*w%VMI&o&Y8L=0GecfZ>(~}F9(O4Zbj4%f+?B*fU zAha4C%GT6mZmaVwzT&UB?Fdk{!t~yv1EYFI3Q`n4`-19f-vL40?bK+$$jMRhL)Gl-T1{%R*lK6(w69-n zrtNSd?mVJ4rkqim@>g~-%F1Sshhz?Xm`pkGk-4iMhi9pgjEGbdw)A6S=DDN1NSp@B za`9!Ws7g!CL#)PA|I?yWa5OO;%xI~>Wr{i}!@XP-L7_nmF%1cPuml8MVS7Puv9ABL zyw=)Cdwop*9bZq5zsRGR3)z!VUvFs?Rt&V#XeSJslUEtHsc#%s>GwtVFSVBSv|`RO zhUHwX+jt_>6s+iUu1oCyZb8!Ih?wSqyN%5k>QWeW)IN?8{IQKBI@@WY@#Cn#dGw@! ze)S>ajE{wg+TA%y?TVXwd}$M0iqL9qs+UOBJ9l&xESz6mS-Pw;ZdB*Or?h+;ye3Z3Kph0402o%>#6RKD491>4G31$+Lv)VoVBpymP?!|v_mxwAeyjn^H2<2~rWvVbw|p;*Ogt{3r^-s7@Axg<-UB5v!BV3Vd%$q>e8ArCKK zuzdF|%IxZ=l0wSTnIm?#$hu~^o8aX>He04`+L99!DQG)x)(e}R2z>Wk$5}<*;|W2M zYU+yJSv6x=IkCRIWz4Be_iJ~OrE}gpY4#zH5B{_BAMqGFPyj~5X>Ep6dG&esK^V-F z|LhUw>c79$40Ge^O5&R#p2hN86dEpZMLXv+o(Y7aQzT-bF&h*?_a?D%iD z7n(UOyUnEMko7|^=3@4uvrLj=iGpDuNjStWFs4b^B%&}tk_rh3zAD%Vk8^CQR}V;3 zR$u6LKJW;bOAwQMsq*p>W_KgR(vQR19LG}2=Evm9B2=~}&gC@Hp^8V^qYttgSxoJF zn)bXB75__DO~2I?~LGY-C@` z3@JRs*!-kQsMI+G{FY3GGQ%1~CHGZ`e??^5Q@h%dIxJy50mg)zmUnErWDCBb-<@<+U6 z36}_kk^%c$V%)ZQX_5?O*{Iyp#NSKI7>+aXhN@Yh1DbUjFXK!#!3@%#PO=?1P)CkK zLe<lgy@H?3PK|x(GEjLZ2|8n zy7J4GYX0+`t@ZlW9d-mIaUv~1MbqAG{fM=K^!|^)??`4@&B-p*?mFdxb3~)k?Mew@ zw8}26mfw%qw9oCEm5kg(_}|FmF8rw8|B+vU_n!GN7Pr)o+{c>lHu-LtjKyyg1gi9UuN^+3|FeOTOtd z7&)22sM2vTPqCxZpTrRABrs^*i7YVXt1av7gsR#JB9tTs59t_SI1fBEA@8W3DmJ(u zze`z|H2ZxB5~cL z6wgl?La)Vcgc{x=FO)GB2RLR>i-%5E>-kHs9jg&%nbV3bk2|=B&uqXaq&{77tpHP39X;HQw1p%i!u!)99LZh z2A5jBT^1AMUkSe|7DN;6;qI;rcL1m4k_S#4zYxS?rZd~QX6Q;M_=Dht2>fR`qYGLz zh-ps$YYtos$HBIUm}8Ji$@&`dwPFVc*ivhzeuL$xR2o$gZ+G(P|JJ!zp|sF7Ko{?`nUMb;lYT2oO4#!N??G^0_oEYH85|~ zApW9EEZ))VoaExEL|WLmv+{mzY!&fhfB!~b>_FIlzHA-YOB+KII@`FNKRYUtlkm6XZeuXO$XB~2;_@y@cArhdvROE1vRG=+Grk1PB@CK9*Q}ukW0U4ixV-?5x&vHtit#ot_R%G#&+3d|D z3aD5p>^$fxiLa5}E0Nt=?FD<9;1qg4t?ecMmDycn3*=PQ_{; zR|Ou=$?TA^8*uoy%RA~~8?8bu{*uG0bQ#vMEd zr%mKj)u9j;0)(@@)3bcXyfcSf$CAshxARURc0QI5Zak;xwx0d{ozc#h2yoJbJ5CtWWkXY`3khSQE$W!nbYdfWkBAvCz@2b^H_9MsM^)f2R5>%qMK)W6b*?5|TQ>b?jb@oKNX4)jr~D)B39p z7+Zm*4>3J707S-kL=k)Qvz{wy=wv->QiyJ#`~nfHIputWm&@2POq9MLi@aic)UUJVMH6py6&C{=H2 zU&@i^2GnA9ITLZ-7uz+RkfYR$7c)Lz1csK-y{01>pQc>Luxof)?8sYV=rGkr=avZ)t>0$)A*1Cx}&q0 zAm%JPCUhOUAV!FSKKn3UG+a%36dDT1FEj*Xzs~fxaez9Y=0D27P!JsRzW0?ie@qjN_JLJ}Jw2 zYdhq=NqS(YwcNqwPhftT0GgNmtg9dVcF++tfY*89PmI_>5z(PaEQ^#tOFvSDo%f=Y z*9LgsY?o(w;Dd6Ao-mNH$o4DN()``Xn#S1lTNV5J$7$UB5@{bdI!Eo^aHo$AvG8ls z2akToy#kW{5EpNOe5YLc30R1+I4Z&Z~GWFI5qOPds zH-`AT^%&@@fu-{0`?A_nX|Ug7RKsVhlWhM9@bswU{4{~Sc+3K{c=^4x0-CeJO5Zeo zlHC38B*6x1Q&G-?ZbOc#|DeY3w8^8YT{_6>ZRnlxk@=h-f>KDh&iEY$cHS9rfzb{! zKgS$*GNXz4h#T7jie--JSdM()i90w0%ka#=o|Tgb^Nf!EM3_?0x*sd{j9~`P1DrY{<`b(8Xf9f0hg;m%9ZNf& zZF-H6E?YLQgwSFL8OTv&d9bQ$US{9er|;PIYvSIF+Ii4x+6$+0AS%u<7!8eo$ntQ8 z4x!kp*Qm;T&Dt~WA$B<80Vjym1Y%1BzsI?fh>K(vE4;UJ8Kfj}ULx z1;;eZD>!#@VgpuU8T@<|)QYi>U&gviWuE@A+^rohy~(?%chu^Bv>~~Z zKh*PU9PG;$%2iQQ2fjP*kM7k;GMjh_y!o*RZl(b&$*_zKW4JF~(^hKd@n3A73)gI1 z$9N_ES|Ti16zaDs3(5wnjobJ8uQ3oD@!z~VDA+$*7QoKn>Wb4g?b2cdTbP0*Cn-Af zdtNeY$N}Jzyv9|x{IOjat^l>EV^Ma#9Ih*#=`AqfNO=Q1i(F*Og%TMyIni@?~lZz)zt?N<}o z00!G0a!^sb>&Y``{cI^>*o@T&p&58nFJ17>D%BF#%XU+yT1snO>F1@5kP0Ru1>f6h zD2Hj=P1vV9@Q-*2jVK(PF*ht#DYy1ctV?v_*Knv)JP$K+O%VW9*zsu=iz`(Wf-s36 z?6`pMj@S-^ww;cZjIqJYR@6oQ+gik%+|sLmngEZPG!YA zy-4|{2DVd_Un>BW{>`NaPPH)5*-@-rY%{N8`4&9<&yRcB*HU5?QwIk4* z$gHJ|q^qYPTB3DZms|*~_91!bT%r}$wDu1?leYzhS*=dJgwOkp!{qxiE9t<>cfHOj z6=AKj)kOIUv@LHh{8WTOd)2MkG+W;qc418a-Fj(!4J~Lqol#NI&!X=wX1owj+f{RT z0&GOW8u$6$$X)_wB6?p@vsLzV0@#!|Qy5KcsY4I|68;K*W05cgX&*_06ucg}VMk&z z`F4Jv&ziU9eeFoUT_P|@5HS*k)2I_R+ zI&r9mkA&^}JMr`uJ$ss?p>=kkQah^CsNZ$m_YD)KnG*u==l@yFU~18f;H?ekn3v6R z)>D#wp0v0ekdZZ>eJTcjvQ|D)KlAPFIecPy`SC_d^!Ia1NQZZCzD?i+o%_m&u39(C z<9Q@Cfu9B)QY=KNj^k1a(al_oVNRtAZhp02eFWprb)B%w+ zZ-&kuezV?qz-q$sd#+i`&W^CRN#;TAYxhCWWd^dKGccaw*rio&%|M3zJ=M)f45&p!o9jP zw*Ie96(OI`LKrOM`;w%Ss;)pLU681*z}1~qcO1BG1V0VTw4A&PNN5ro=s_oe1ya)r zJz0+x^*W3Ls?_n~HZCPlESCTAVC?jhw%}MXL_bHCx8U{-kJ92hGVGG-`H)17F`~Rl zwnT-EcBiM6_HUNCXgAM&!YCg(8Rd!A;fWDk$k#b(QIO;7(x7Hax1KvDFi9x-=~;Z4 z4i+oK5s0-t8OY{w8u$|PA!srkZtYj4ytlL^O%31a{G3z6q8=<39l5}|Su=Su@Z)n_ zC3ZQZaz9qkmY_KWIrg$PNf`Zm-DREMw)E!kPv#EBe=}OpAqwANH|=Gn1Rg*4#|^Rh zyyPNpgoD!+RaRCtbX9EB3c^ymWXk-Oys+mpZtZT+ZnFiLGKnMi!qfGQ7m21c1O+un zs02Deib4pEWsFbn44Yt(guWN9g1Fmsf zwQrwBr0=Z(mrFu-JgH9lda~i?!fRY6;Y9SyhKKYEt019@2WEyGq1!;ROR2! zpPme8%Y*62PQM&Xij49EV%M|&BH zY0A(5q|12b!@Fp45ePA=vqqxPk|Oml$)XiYVmT;MvF*nUB?q}iQ21hx=KC(=vuxUZQG}K5-U+FP z_Ewy0O!Sl>cmOM@2;!`WzYa3g{)>)>(mEmmtL4%1dXWyWrVP*Vf65Be_s|=@U=|<3 zteZ?(e}j=p zXawZiEn7v9>S|jA$x>GD)WFIG!2IKB&992`FPN-3#-dBhHx30e*;hF@z?T+a(^s88 zqCnt~Ry6?;M*NhXIdY_BxP>v>^m79nek{C`S%-S4B(d!AIAKBgz}`3ZE?mP{r6lHI znBSS7U5ydzm@7GdEV7RF5fw?jC+SMSRW3?SnLiqwSU}KERq9vfT>~lI5gp5rh*6dQ zE^K^I3Kk-*A5GU{N_-D+5)C0?pve-}8!7ZBqDLn4R2+v2{r4X#Ge+0v$<%U(&|`w- zhk-&ga+Zql7DTEIPQ5fQ%%Bx^mxG>)lT?^@TkK7%yjQKGFUQkE%uL!sX#4NJ@j)+l=aEO9UzC^XC=PnSC(5lDBJP%CKbt&vBhO=}1apv+TQQcF}T%b@~C&G9}YL51Rw^V7y`$m1PuH49&=f4M{1y7Vc% zPcHj7H@#)0gNF?hESAKILQs)t2Qp#Z1ref-Cm^VYDNQAPuKc0o!VdJ)pjSjn@VhPmB^cMU9VEl3Ot_RXGF-0 zq@mP2O)H=5avZ4O=J7<~wDvR*k-zZJzgbTj6})Ojy3sFqI{W|h+{P{^J)a$;pmRX4 zrLNddz|PHwsn;aGSHpAvJIL$9zpTFj9Z}c97emfZ<+X74hcmjvRvn~hF$v9NK~~3p zmtt=;{j$vS*3@}36{mOR&|xB=uJJhAnEbbQ@(-SKdr{u}_6ISM2g=4gdAAmHQdl|I z$V|-!yXN3&3q&Xqj(8)NAW>8EpfI{rrKhkHc$&bppv4s7Wq9mP^#|hE+U@%@n)LOP z6(jc~%{s0A)FQcPNSD=&GZ}fIr$yJ)!4tRI1vA>)W(am?n6km=@VsNIry*3f42#e7 zzIy*9^uPsi9zsg~G-u9{V%#ADyT)Rg>ZI_?@Noep9v0rlVS%^HUR|f9-7kkKJvSo^ zU{7r4;814CjV~@XOJ)}8Q>JejD(% z_a|@Xl-{ey)BnKy2Wy)b;vf#Os}i3btTI72!5za{w!D{X1MAy|ZHCPcTn#I)+p{L> zcE?dFAaZZ1*v0F+zhWX+ctOwmm=%N16|Q0?!`E6Cgs@%zw!&2ya>P2XP3FOEXqwnR z7q*S3!`H{Fmcvc(u+m;JN9Duwqkj9#NT~_t?-xZA^rRPtyug6;>(@px(8aIyu9e~; zJNfe07>Mm~_V0}6+@Y=7Ixiqx>f0Zm&DUq2Zi3>2s5ik%{kn6iOM|K7Zs24-Q^&VU z((yXs4X2lG%Cu`#BFGRSoghhE>7l80E2TV;%jO;GC2TjU*$_%B+|xj#vSg7xi8=61 zcE&N@RXD{!qJpTP=W(~EoJjJxpq+>1l4iKWj7QQL^R15HR$s!R80v~=TJj&Jm;n}2 zaDPr1>o`5~WjIYiVQAy`UxjC##a?NGoJIb25E}Op8jp9w-Vg3$gN*lfGXd=xVwb{Q zTj4I76NFsHk^rl~3m6`^ughZAg_tkVX}b(?VsR|I(Kv&-BMJ?V`d^K)+hCuz%FNh|R8n9s?!V!r2Q_)m+Z0q-|u!&-+5VY{>s7Xn9RT1Wky zhpi+8K~Ee39)7LiZr>p`X+eVK+H*K`~jK|9LNujB%+pBl57;LoVdAJ3Suy)H;VaY9&l&r#~XT3@lA ztAC4smpCXq^UrwZ-AtU&Ii2_69jxj}!)HGHiCR>bQK=c43H()Ie% zeDgohi+jC%EucHsi78c!c+7pHx=qC-`DEXAKxmYCN^Fmo9>B~5$>;Z>aliKwsJt+R>jOda8D zc*%jyb_du9fiyrfbI+6HdFq_v=)=q=gWA&?4-4b(3kD+qnkq%*^pN*5$sa`i52eKA zF=5eiX`B-9UWdxA^?{p@*T0_Ng*}cACg0#UL-yjQuIj#!iaC#r-1w@B82KAQT#V04 zj{V6MLNzV*;ol5*g_di7q_wG-H}Mf(mlx1SXHhe#4l6d@eBGiB((Xq|`Y;-Ex^6r& z_R_;v+j!`}x28S6f)&;VM~6)K{f*|v-Cn)xjZUX?;1_)}%eu(opw5!W;$; z>Uekua>%3xMQ|x~HW+XLY4c#&8H1I)n(TtJ_M|vn6R?Nj%)Q!w213-fB+XD?g420L zoEJu`&+@0cK{2<4iSt%FE21*a4TC~{K=R#huNTh8m5ICO%3Fnv)6OQteQ{r8Y=%a2 z*)yaZL$^da20dY@@BQ2GOz3|(ytbqEQp(lr&;U$Jf^*i3R+r8Yx&Ip${8SPlbIzxT z&7bBNA)D*z5aGMC4lqw>MRWR@o&q*}n}}~n&V>txde278R87&UKoa_bj)0=PqJx05 zj1)X*&cYLLt$#j8Pd8S*oB=()^64wqSX;8}QJXsu?+Ds=GG&qQ?Ewk5Uf`9JHLlBQML7T~XE z2sn+)HWuIIylTI;t;>>Q6}6g1Ep|7qw{BgkhxqsVomT5kuyP}vmVKowR(X#0&iP-F z=6YJCNA=OSA@-WaNa_x9@X66{H^#lmEL%)nhxMjZq$`9R=O~R8e4P&VZ=2 zR$=6EC8HJbO4tE4^Y8)o`(x1%+s4#j%Y$#W!f^{%k`%<%32;4_V(B{-KHS$Lya6xv zf*#B}b5as_oI-v_rJMJ`N+%R!kFtkm-pFRe#?jnv$l)kO*d4(9?2#%9xs$G9^%X#_WS<-VlN+Kihf!1eY_=h{esv} zF{3JPWF+_vC82@)y@IgY=H3)FPhIUlqM)8tLwMEpOLo$41{BWStMu5==S^4}Lm!SH zN?Z2hmlT%sZ30rs+=sDK%~2lE7R-OlutM>Q9TF_kJRlIX3a*Xob56^&kL3?JIZC z?tfk|_pc5$uuBhT&O|X!UfoZm(LTgObu`}&v3!JUJ57C02wjgCs%mbEI5PD)K{=f6G$1iRZCKL0(Cl&p3g0Q8Id$6MESLb~XtJ;%JRyCOH3DNn09Msw~ zD(AnK1bEi?dsA+|-LOFHup~}=`dhnpnPHW4*FI$>uoVETUcdlD`iDlf%T`$BElUR} zoG{L0LoUNNK;)DI#{vZ2s&JHqFw#Da{~SuyU%-wUHJMF;fb8mH8&{59m_0J5SJ`2=VHY(f~zM*n>Ra+6%A9F>To_zAa zcvL=7Qk>@qM7$I8&dWVxxqD~mi7LMxA8f6pFy-^UMpv;JOjWC%z|ge{aeBG4f5O7I zM-JLiCn`I=&;QKE^_@eiq{-eaC}CIhlkg1yP8iC>!Ja2Ul~>{{-Ww!1&^>b=hWn`L z7DFVuaDK8RIE=j4dAEqiqA`+`PCBD^Tqh+Gbjl(|An_viMMz=jfK=kcoVNfVbMQET zR`BUtz=hERm?|fc`=AJTZx0orygJ{ID{as6I!#E~$XqN8yehUfUc^J*xcY0b_XPxZ z4ej^9d9<4LxyrecK;YZVwe7{7vp)X9V|#hB>=Co^G2HO5>$Ym|KT0*bO0NrWS)j&l zd_hn&W;xGxfw-V`2ktRR7RJ9s?~loi=hL=^i2P8Jk3 zy8l}my~Y`2Grj#fA$H`r%ZQDNjGNSYi;1Asfghy6jsWT=+6IFTnoc7}P{tZrC1Y;L zhG0+aAZVSVyxqIDruc-dDRP`3>~X;c)EJAv{k|T!gA;uE+3))l)B4YEJ@9DT04L>U zQBr@>qat%VU+eS@ z_+B)t9aEJ{8J)rHj)@I8(pzw4vKZE<23JP|z7b9T*U?pnMfG&y1tfknl7i$S9n#%M zw;&DD0@7W3NkO`$5u}$+X{0-)yQHOiVZZg;KjxYH?94nfd*+;b<~?)XE$N91*B)jJ z=@}4C3aY6i@V)Dc3poA(;xK-|Zt{n1Q}1L;kG!{`{&@-~;BJ46J0~ChvFG zrX%kg71I>{wO*oRgG$-us9n*TwRzns2Xav~cc%;Y>k!L#OLd0V8|PPLB#P^#zKe z8Z&Z_S|C015}owtt3i6gRa!%=*xKBM_m_>dYR3Liig$y3;q33CYunm=&s7SzL#?&v z7Rt}>jtTLw^53hsNid|)y5l-I8u^gbIqx4Y79&s6H~-eyL|%70 zi?U3bOV^Shf0QfXMj#Zr7K>MpJ*HjJH+r5;u@MPTP91e~^Qvys7hx-AcrP_eme9B1 zkbWJ!6F}#j9F8 zimWLK*~2cxi2{U+5kYhNU5|DwyxOHk&66iatK`!c+4lub*qwKXO}pxMO2J#5E%x}k z{k8*1sAM~p`eB^(?<0C=UG!gG>AhL7YN5f0-Hc)D$lwYuW(QSAREsyi zopnCJC@BGP;yN?cY1+YT#5ML(9e^jqJL?$QRorh*l5OHUG&-B+G~Gr-gu^E6Nf z^7gwiI>|WB?a*)tJ7SgK6ZP-fx=Xsus?m8|d=8s|{MRbsjo#0>663QxVIp`uZ@;I4 z(7dc9<=<-^&MEu-H(^kaw@4CVFPgI-XuGOpu39n(T&kyOgQ*m|-3K~equ$I8ZIe~& z+YFct!t7;mWD4I7la!+ZpHK?Er9@8}&sws1MHqZQmHeeOsATnJS=OqXH>3s;-*v_- z6ZY*p+pa;Mef#;t$GX&Qn%Lz`+aDHV?mLs*e?>pan4mqOcWyUpPByXiU_Bk@V=f)3 zVMdqr=yjbQQ(3^|foEl55e5X}>t9rBi&C7LN16d=P0ibzs?UuE`i~_ZdiqsDt$R;A zDts`H)7>$oTa{BbK2jW9!|YxY=3{y|Dj}wZN*#* z8pjeO`7y+?pBGM4l;%t`Dqp^UU(At=beo&!ZHG4>}D3PsZ}Hy#M9U2`2# zj!S8tSTkw!IR6C!zNe^53p4X#)k_cC6T7GRTm8Fl4fi6~7j;ONL?>~j|k6+jTuWDy0vlh5B+8mdaQ9!I; zqIi3mY`@IW2Yy!5-|CuV*+iB`sU93R#2hJGyJ0xuUVJ4@E;Q1-v;b+wz*cV3vjJ>>=)b4>)|ZuXZ2D*;0JvJ@QeE@ zkj8Ei2S~#N&~GGfE{g}7BashC@5`&L-tM1{S%kF8uaj*xbKV_MpYG@gSn^^`H|}M$ zS8B4JIt`%b*lQJBU=phOgyuXq1TGe=B>6c0$rdXSE0GOq`ieY=2Ij)2!(ob~@yIA8 z1C3C;FPLesNwvuM93hb71@cxGeVz2swJjdVIPpjZ&|Xn@&c8U@xF?tM9(}~isp>2E zx!Wh7jdAhovSF;U-Q!#elq+G1dUlUD%Owq7+hb=%sx*b`Nhxc5LOQ#bcL*Q?Uv zEE1NpH7)Nz-mz58{wPg5^02*-f3w3&BP*be%GY2dp@|676%#2e=UW$&^cBh@h3TUI zrieK$dl2ld3UZZOxbFfRNx-0FW;6WL)A`=iALb?Y><21)%km{c`@F9uy$F=y=xNd! zT0jlC6&Q(%gOh`=RJP`0mj>7t`Uf=&TGQ>S;%cxf=G+A)_q{1GW+*c0iz$>DqYf@12Yzpl1^sHv2B=A|-;dUvFjVCNl?`bXnu z8175I>I&Jjj~)Oik(Pb!j*1f|qrIIAo9T9EoZL^u+dzT)fiad5f*boh9yJAAYP@HV z`Z6gYD2tRw4Mp}o^r!5ipsrec0UQzB>TLsu{$e^z#wA5`R`q|_vne{w$THWj8ZnA) z2Tu9o_#n@?D(gwDv6DQCC-ysY)!FiYPwph$-1-cL!R{s;#SuI_tCM|9KPO~+l}!H2 z#^IV?cS%!pvNYUFF{R4k!NLkmpfUiv>+&_jRYK=5t>;i`Q)T`cw-Y>IOfohrc_Nnj zYj>pye-09gpdUXEl2PX~*BW!Z==ESJ`~jw@$XuHkL=5V7 z&qRM0`iJfXc8$bkVgJ@P{OX4(vId>IY}mDesDgQhb>iougK-0lk3S{OjPU|jMXyt; z>Pe{K4buBntN!cg0*HhNvH_Lnd9vo~`M&GP!2u#WM~;Q}+~5&QOd-U{*6~aK@%ALe z(=DjPxCH4=@+25xzo=UQims$*RD>LWfJupP0_n~vKt2Dg06?m5^VsAKoS5f4aQHI0 zMF^iAQ`J1fSGArQ|OK-*9UpnKm5mO6=;@6E5p`2Q2u z6`Q;3)S)&#h?>0xd0U(qnP<#_9nCZR*GR_zqz%*lT&ZbzGH{@`y?5GmB{tNwvUoz< zJB8LK{4I>F%GSbEth$Oy!B(Jf_1|*9SE4+TMIF(;5n4>_G82}jSkBmSe3L$*{E~cj z&TkfdFo3a$5s>JFR!J*TdP@strYU8sU8Ai%avpG5Oxh_Dmjfp>{vAxP#1{sY2pBLKrC@B33=bkVr;8k7PsGNB_cQ!BXm@4GrTwYpoKlI14KN7S9J zl5WqGldkH7(tP&Xx@`TIb&A_5<~eIO?@c@5i_{Zf-fa#io>xmx%PTK6v|BXZ;r6k= zTe*;fi!oR+iQ~oaO2ZH3;frn)ozFegPw7r#w}0d(;6qJ0ewU_@ebxyvIKmc9>UIFv zE19_>@SA@P@PI3u9KYx5Td@Z}^;w9T)Gon;)G7KC@6*hokc29FoX!((z;vf%4_yLQlUY z`$KOd(&^{Gl{xUtV+j;6FL1^Te@X54e9jqg)GPpJ?0m>QJi(%V@LKo%JLX?WeZL1s zMVyZ@#t`Q(wIb3LJVB{CwLy|l#fEH8x&|NcZo!{zyTMqWtvNd{27!s!S@!lv4$0#= zC?fl`dn0+be9{929l5?&Rc|PZwgfqdKgc%MI_l?KXxgS!Iw9@LDjoLbw13dUP$SCA z;23pds@c|zAQJioR?o=O_uhEnnPK949zjpGKEd|DLRjn}7Fxv9vBu??Lys(!k4ht$ zmawDBB$MWtR&YyH*Qt(&g2Y%ip=FJPgjdI}U5Es9EcyhR5)dem(d9RfeD-2C+{-${ z9v%?iRYdshLt$B>8s66f1@$AHMQx`NAc|hv%B;sDFVFKQ;V>XuVV=2-LKH_Ot-~g< zRl9kByxpcaJvYpH)y$fX6KC3X{NB-^^VgAdYMOpuUh_RxCrlNR>Rv6-`lnFi*g?Kg z=Ll%Jw->*Pe+*YZwUX|(Eq+soL=#=r*PMQqx);ylZ6ckZG$j%t&@iHHb2+^!0G;)o zCgit|@DUfQk!$SZmo{56%8ZiHtzQ-hgb~L$e)d#%0EMUTO$Qq zvyZP?ydw=)pRj-aoWEf(_x7uD5ueHyYz#0PHtIiRr~#(;#GhhK@A|6NX9>p&HaHGk!49qR4UYHOLB^qyO87JQ^d_d(%V6fupNCcz1wwy+#NJ! zhPq935O@8UXhZE{%=KXmRG#QS>B@!oNa$$7u6UdVN;u{aU%t^CZ1P7mNAZ3D(wk00 zGjB~F%BVKI5Iur&0&XZ@JgjPB1HA%9M|&aScGMJt^*GT(roskm?$^|LKICFIfqUh_k%Ba*rW)+1K%FZe_7 z8!;;z%)+V>v?oN6gpHsBxEpHHH9Jdr9%~Rd(_9%q&OwZ)c?q?>gl5J7E|!YjvR1ce zJ?fnSX}$jH;`gH>%0<_RxRL>P1)jvy4UwJ6b+5>5{t?j{&hYC*+(JUXn~V?dNVx;9 zt#~Vva^zJQMUjrP9S_))IzEdd~lQY zFsMS$1LWtDdE!Q%a!nDEBBU?2S{<~aY~6G(;gSnJBJIfN!vePPzR0K28#%z(KuKK- z*nv~NBB{j6AM1IO?eccCs^UAidM`~|Sus>iQYF{IO7s7!a2C4sMxtiy@d?KjwG#=x zG+VL?RCq;0feg?a$E%|?6>Fqe3x%~@9gAo&RR+)6wSYLp9&sy`N(`y)dks~GS**@e z30kJv7+H>bFvfK1T2#L&h&>*QU`sb0u)H&-x+es{@k~C;#)T|nt`a(N{#z9?e61XF zqYq(S+N-~$$D~JDgard4o{5BaS}64sog2>UVv3TaYk(v3_Dy=sm?9n(^A1M%ZlT{b zWu{^4Ic~$*4Mzfj0%_4vnzJNi%~aQN{#aeHnV4zf?Y*<{`~ zuSmi4j(n>`htoWc`S?y8*H*nJdpRz2C2})gzZ<9u1pDsT%EwLGwIp;G+N@wiCZs_# zE(Y6Ee-J#Z@F3DanFLrW*X>$@YJ3k~HGx@Tirf}2Nh?hCXvSj00*b&n|L9h1 zP?771tHrqgz)#y|_99&`p(P)2dyb5)3ayl`%#{PT-}cXE>rZH%$e4c)ocr2&q!)vE zSio0F>edtIDyZP9D=z7b&uc$c+kgkU)B6OxE=x*j(XW$YP)mmfq>|@_qY$w-siA=f zeTEGee;A!t9>TDv!&qvt=y;0`r>S%jCmmPfrpB5y>Q~8{AFX$v1FB-N0~jqZFL_HF zEmqyq3SbTY*!Z@REHRhKY*MEL#Z=K0@P*#KCKG?f{^K{dlK3kfGTfM8EC4B*NQXb|}%U&kdqJO^p6NY$9MDNQRnp$LWoc3u<=+(xUHOqdIb8NM>10&2&L_EK$H3MsrN zgr8*=&@gdZLE1!6Su_@NGotsAv4;xZMxO;(BJcI&_Wv1sLO>zjTz2Y@oCqU2YYB`c zsn6Xwq*`NuVlecs9OJ%V`kP>B&hJmT{i1Z@e=Bg@|CIZy zO8qw{+hnj#$DU4WhE9q`?qAnOQt=Se&Xs4>z0Lqb^9&>OW0|qr^X#wk9@p|Iwe(c*M8l{BNS|EN92O#zjPnUe(XACa>xtRQ>xrgbo zge1EnA*oE&f_butZ5T{FlnHoL|8Uk>iw9={S*Zn-`LeX+LVxUktls6jT8mcDP2T51 z6bt3CdU*)Q$)c!dq;D)A<#Eixprb^-bj5rE-;#b>WZ#^X7*j6~NW?h zJMH1J2DFq_P!%1N{_#>S!&Zo{C-QBAndv-&c<-b>jvI)N8llrV4(h!Zj^F;{eU$)2 zUPLLxOiE1at*Tk=4!4%cMhnCVte@a}REb)K80bEQV z-*5&JY@VmDYEQmpi-D$=;T1~sP7=TUbAu0`mi*p_tyQ(_GC#=%4 zoE26x3D^RW_p$!DAMHn#+&)ocRf)%L9+`LBy<_xbM$;-Q-pRm_OpF(&q4m?2-}{o* zm`S7bU5pn;58_bK|;7C~+EJvk&;%LAb`I$|VMoQs_|Bmf8aZ{fbC?DxjBB zwnlRmLYAQD?ZbWl@=IdcZiG#YzYye{v{UGV0gCu5{;!RZdaXtZ7PB`yTv7da?9CAR5{tcA?hI#cB?I}e=P8x zdJ*vp6X4EV{ZzeaBZ_)j{z<_~Ca!jfwl z5W0VCMQkcc_~tjbswW3(=7v61)br17n+sR%xEaYY{cF12 zI$-O&aPdt5>7oYD32;3>pMZw|MHZMLg8i^7z$@Ma=asOoE^1O3w)&rDA@vn9sbHWs z&NFcCxKG**!Weu=>rhr7&ijvwFtQ+@Xjp(o#W0Qk*W8F;xbxxHTanNi()CmQwI-_P zptRozY186c+{{MVloL!FwR`u|XLZ~`GG9<%PouA!2bnx<7-G*n-k`5rrcuq~`X7Wi zAyvbF-8RkagGs4BXc*PSH$~0g10&$q7CcU!2+`|aDbOxh5@ZzO z|C=;u=uWhUoR2G1fys&K#MmC`juhUif$Py5pvgCH?}z_#9TJgPeqtcCOj=M0Z!sP@ zBH7GMW}F74S7{4RBy)z~Z?82;Kliv=k=Tf~A0mqqmPVMw^vS*}k8J|GhZJl3Ruw#mbF$Plpzitfk3F!CV4(Ws31osplD%hu(^YXlbl z2GeF@mM&#>b^1iKNnyxIq7ea+s%JydT>Nj0R9Olqh@}Gfz1HH45Ma}gyivQ@9IRqW zGq-)CHT7DF#gx6H9h$sn4O&KTfJ}2CD<)u~JjzBX`RMCg@PIh}j&0eRP1>$wSNKP? zuKEfi=xFO-vqiA+k@!;vr{?iVA7QT1Y6(r_V38}AWRUryCaAdV5;cc5S*|MomBpY`ZA?DpDd_>siZ z4gz(%G<^^Q{VAz-A{rTgmVH^&DpeIr<;&2l45TDb`I0Cs<9FA8qg*eWEjJi*e*MHH zW}}Glgyc+PHI0`9!T7FZY1USjq|{gN`6ceJH?3#h&JNwveYfEX>ZT>+U|t7fp9N61 zm@bcGw8?dp4fdoB=UwpradU<;zt}kh!AdjY^t7UdO$<3xr6~11sJXBfhTT}OIuN^{ z0=@nozuz6aOPBvt`Lpk_cw7ew0e^qi`XH0wk_`PwY44AYHgVQpNN&n$${YwK_3tnN zN!&-Y)X&pT6oICm4IUTQi@33Am;w}RqScD&_ zWJ&(TmQ2oUGVT$!h$pg=_GJ^Ya4_)nh1{{ICss*c)OpAnS6RDgo9DlTVQemhljle% zn=5SU6@iGi@Rs&^U^Z83Uv9mkfks^i4LlK*c_Qq0B&&JAh6{jK=6?RfZ*^Vu6Ow$} z+k;CGcZO)9peQ$|o?Ufx0w4_Rm0((VV#!1wyYGjq-p4pT@i?Q_J7;XzT)4l~)y91W z&P9&*PpMuDai6ty{53pSJ*oWAJVb@k9)=jgQ1WQFM>Pa;Bm=2dsj|!No)1REVWYYJ z+!zyUX^!tBY&J z&tM8l{c6Wz&0j&X@~`MfYw~+^F3fpdzosu{EnznGoLij9q`fCut7{k;XR`rq(-}sz^I9{x z+yd>LA@ioowPcpWzr-m7SLvKtGUQ1+q&6Z5ahuK$^^(#va&&3}d2nO;NE zR!rRd%NhTRHd6%9BKo(r8#t0#tLdMZf4}pDPEG9XfIwWVgg29ZE$-_sUAyh zhtg2DU}j4J`c1t;xj+4f98&|2EDdQKhI$n6{tvu_L?pD0EKp0@Zm+Z{yrM)MR09|o zERpjrH{_Kr-v8F<(TG|70qhBSJlA7aL@nDb8du@Ft5_1F1)4q#BaDB?Ssq{`?Q1)% zL?*RZ!IVDt9E9`Hhk1(O+4`2L7kx5^_O?+izR{P~5+jBuD&rdl;Y zs7Jp6a=*goL9n~He}&}bOKFP&mE97j=q!%6()&%~9_rue+U0h%WxDRd-clZnJ^Hj} zD|@CsyW2IQcG`dj$}WLh1RhNqhc;zGV&GszXT-y#{n1I>gb`K@zcWU-Hxm*MqM(_x z#Cj)k6C!0$USgKS7*z#f)`~GA41s{{*YAbHd<=|6@;v%|SkA(S?_KxLq}FP)-X>*k zYoePiHExp^6^{V_zhFKV_cS0dH||iZCH}z?iokB8gB}3Xb&$*TFUBV zie)z&dY$}W3I(dDZ{hQY>&t3yvY~&axFEoA=T5L4sh!f4(<~>`yW9&-v4^`;v0K=Y zgzvL*%hLKkSiB{Jrpf;vruz@4mw4L$mUF==gh=ox#G0+F83ym!uXfaUjt8A514Fdf zR8YXRU1lu@q0B8Tw7MKSslfBpUMB+a?}Wvzoqae>pou*YvlB^mayKC@dP0XvXmaUX z2CoZ5BPNWKk64UZXcb@}_Kg}ocmj={^eR-_EmLUFT0dx+C1k;OH4dr&2~%1#WRlSuEgN$|SaVG=VlyQYdRgR}_VhstCd@NSd1 z-r8@{%OZ$#JLq%^@GGtVJLV1ORNK5I4~YBCoTV%FDdR6QJqHVZI0Xs!2~|!+PsS`G z+IMYU?z(e+w1C4QC%aROOxXg@W(noO8G~2^?=+=G5BE#g!tSb}j##}?O;0+YU2S8R zS+^0DCdHi3xuk0i$imVtZk`m9^d92UX3{Jgtr>hr&SCiHIcUt|)pgA5@M9Y8K=`vLiA0>(TsSB}ps$;E8a<3de}@$=_0J?HrN zGL{}l{$!${oQ?dy%-TMyK71oUDoRlbX(y3V=HLxy@vrR0O7OPrLDxrPzbq?_!8M70 zL~URy@@mRN5~df`=*0am<3Hb)c6+M|l66TsRK`VGpu{K^9+}#-po14lUqnUaG9;?x zB{A0AXXu8SlRyvRxBV?Lpv%RqXzBX6F%ci@PHV@nUKbjvFin>hRZIaiGaqyDJ`O#^ zM<(~~mwwEX(9)7UueFjcT3HwPj-L)nr@C~{xN5k)!5n13Bwi>bmn>jnC{%_lzK~){ z?~cY%Dsx$h!nWr;1O)~wE@G^+s)**203q;{AB5%WllI~^^}bkIVMg32D({AP4ltkx z{oYyw#m(^!grmd9LpeY*2lJFna$Lz+NDWu|XHp^d9R9It4+EPL7o6Wi*58w8Qg%zIS;C38c8Hk~6Uvktkjl!|8^af458_8`P zvPy|_hQ?-4Vi(^r2fV0blRrRBI#Q#oME;1XEpSX$7J~s^48#GvEr|BaZJ9{Kbj` zj}^(q4-=Fe@wrzvy1%yOUDk@VMHIOYdRcv{cPdP*ti{||+C-aamdWl{T=K7Zr=d)Z zp(vlqFeLl%ziev&M21@Z1q)^+(saScB`S?vlA=Zb4fV$+sB7^%*w@efP83Tpcl5;O z{D1_CG7^c&6Vya#LE{V={bD^X%AoAU_M2(Q8(xjfOk18?^=zb}3{@=VsUrQ&pT}tv zE&Oqrmy9j%nIOyCme|<>7Y8p$myQ5y#XNs*+V&ql{lcBLWWQFim78{6Q9|diGWLhX#2#K6A*j{As{{T?_81i!hit0yGMZ2GOu2x1L{4^A-#ISK}jJlQ>vYT$JDrgmiG+~^?U9d)9j0gZITTNRKBXL zBX{)-avr!s8)mYt5U*8XW8Q_7{{8SWDukV;-Z85b$Qblm4#CvgjY&*MWImSNy;po! z^W1{WO&iztW|Qd)O)zrAd@K2vuVrs6kt4oSVT0P|BSU`GzKAb`=Y90;>tWWuxDTog z+`DR-e;e{vGo)^NeD?^Jl5D8J%o|tYPYLR#&=)q?6)qxRILPYJ{Ruo5%p{N7X^XNp zpnZJh3atP1?d?s5{w8nUZe~|w{G9RelMQ{FodoUo5}dAb*xt<2r*=$BG52RCc4u9) zBLiEukJT|DVy?o>f>fna;q6j_^r?hmwKFfF$mw63ihjtY`^o*lRn?Z zyBZhc(qJq{B3r*7E7$J$D{MV!cLWz;CLPZp&jPX`*ne_@(f>>0Qdh6N871%9ypYDlO=pX<=#k^4vF8##nGVw81GOj}YS~ zeVh(WB}lP}kRmueO^7T|X~(|rmtOQ&tgj4dsWT(oo=907O*Y90=4(G3LP-Exwv4GW zK>}=|IJKioN{|&8jfVibJ`c5KCaQ$_V8QDf?}r^)l2cJz$DFxyVwk|&k;w7Jbz+T8 z=TdEuhw9BE_ZEmH^M$>3y{>rYYrzdGkrdi#5R25GTGC!tP(j&C9o8?^ID+->i#}vr z-Cwe}T}nC#GaXIP#fu_x>a>W>mFGLdM~k{y!)jB&-JH-LmD_D+I$U26xddX5W1 z-u2?K`8%l-#itN=!5(r*vbXg|%L4W;wZiA*+`!7*qm%b`_8%PEO9-QAzlEs`6xtR3 zwB9;Rxn4P$-hwvSz8sFw^c1KA8F#e3E=Qk#lvB zTv;w6^qGfPB!jj0&_|Rfc!Kn?Cc9n;91+26Ie`ML+{KVAl49MtspIR969U=^MW5j4C&q_G%*(7_K!}gxJ2lx#>5swx E1E&Uo00000 delta 27520 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 z

4#O%i@UD^y*K4eh>E{9=gO~o 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 delta 27292 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�agQ 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%0DJv1fMIXl+l>ld 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

T9C^_Z>?`JJMT(wvPR`8^vH&z+50&qtV+vu z)2{QC*h3YG-czKOByXgLL$zmI8WjdBS1jcKW;*fyFTap{bU*6gRNTh;)YkrZSO1?6 zsf&K7Y?H;Lo#a%*)Y8(Q#!pN&6;C~UGDRaeDaqNp$hAbd0W1zPEO&{DaQfnlh1fDC zy|;8mGi8^vq2X3Gc!yuLx+LNV&Ax6wrFKu6-LE%@-SU3-1erpzP)Y_h4mqYe2ewan z-`;28v-ggr*D!?fY}j(uxHX_M)>Ak$&Ak0Ie`%?{!if(ZAU`Ur?epks6NZKOEoIxd zeS*k1adGOte!orNNn*DFL3R3U>e1)_fB&yU&H`Byo2Zd_xK=v5LcEYEqB!7BU2uSa OFF7eC$qI3k!2bb|cla0p From 442a0794be6ebe81568c6579f4b36996c4dcb8e1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 11 Jun 2019 13:44:52 -0700 Subject: [PATCH 400/429] GBA Video: Add transparent sprite priority updating for GL --- include/mgba/internal/gba/renderers/gl.h | 2 +- src/gba/renderers/gl.c | 45 ++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 0d804bc6f..b0fab6e7c 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -161,7 +161,7 @@ struct GBAVideoGLRenderer { uint64_t regsDirty; struct GBAVideoGLShader bgShader[6]; - struct GBAVideoGLShader objShader[2]; + struct GBAVideoGLShader objShader[3]; struct GBAVideoGLShader windowShader; struct GBAVideoGLShader finalizeShader; diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index a54e0b028..0667f2cf5 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -474,6 +474,25 @@ static const char* const _renderObj = " window = ivec4(objwin.yzw, 0);\n" "}"; +static const struct GBAVideoGLUniform _uniformsObjPriority[] = { + { "loc", GBA_GL_VS_LOC, }, + { "maxPos", GBA_GL_VS_MAXPOS, }, + { "inflags", GBA_GL_OBJ_INFLAGS, }, + { 0 } +}; + +static const char* const _renderObjPriority = + "in vec2 texCoord;\n" + "uniform ivec4 inflags;\n" + "OUT(0) out vec4 color;\n" + "OUT(1) out ivec4 flags;\n" + + "void main() {\n" + " flags = inflags;\n" + " gl_FragDepth = float(flags.x) / 16.;\n" + " color = vec4(0., 0., 0., 0.);" + "}"; + static const struct GBAVideoGLUniform _uniformsWindow[] = { { "loc", GBA_GL_VS_LOC, }, { "maxPos", GBA_GL_VS_MAXPOS, }, @@ -742,7 +761,7 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_OBJ_COLOR], GL_RGBA, GL_COLOR_ATTACHMENT0, glRenderer->scale); _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_FLAGS], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT1, glRenderer->scale); _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_WINDOW], GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, GL_COLOR_ATTACHMENT2, glRenderer->scale); - _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_DEPTH], GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_ATTACHMENT, glRenderer->scale); + _initFramebufferTextureEx(glRenderer->layers[GBA_GL_TEX_OBJ_DEPTH], GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH_STENCIL_ATTACHMENT, glRenderer->scale); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_BACKDROP]); _initFramebufferTexture(glRenderer->layers[GBA_GL_TEX_BACKDROP_COLOR], GL_RGB, GL_COLOR_ATTACHMENT0, 0); @@ -850,6 +869,9 @@ void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer) { glBindFragDataLocation(glRenderer->objShader[1].program, 2, "window"); #endif + shaderBuffer[1] = _renderObjPriority; + _compileShader(glRenderer, &glRenderer->objShader[2], shaderBuffer, 2, vs, _uniformsObjPriority, log); + shaderBuffer[1] = _renderWindow; _compileShader(glRenderer, &glRenderer->windowShader, shaderBuffer, 2, vs, _uniformsWindow, log); #ifndef BUILD_GLES3 @@ -1357,9 +1379,10 @@ void GBAVideoGLRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) { #else glClearDepth(1); #endif + glClearStencil(0); glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->fbo[GBA_GL_FBO_OBJ]); glDrawBuffers(2, (GLenum[]) { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); for (i = 0; i < 4; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, glRenderer->bg[i].fbo); @@ -1391,6 +1414,8 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { GBAVideoGLRendererDrawWindow(glRenderer, y); if (GBARegisterDISPCNTIsObjEnable(glRenderer->dispcnt) && !glRenderer->d.disableOBJ) { int i; + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + glEnable(GL_STENCIL_TEST); glDepthFunc(GL_LESS); for (i = 0; i < glRenderer->oamMax; ++i) { struct GBAVideoRendererSprite* sprite = &glRenderer->sprites[i]; @@ -1401,6 +1426,7 @@ void _drawScanlines(struct GBAVideoGLRenderer* glRenderer, int y) { GBAVideoGLRendererDrawSprite(glRenderer, &sprite->obj, y, sprite->y); } glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); } if (TEST_LAYER_ENABLED(0) && GBARegisterDISPCNTGetMode(glRenderer->dispcnt) < 2) { @@ -1678,7 +1704,22 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB } else { glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0); } + glStencilFunc(GL_ALWAYS, 1, 1); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + shader = &renderer->objShader[2]; + uniforms = shader->uniforms; + glStencilFunc(GL_EQUAL, 1, 1); + glUseProgram(shader->program); + glDrawBuffers(2, (GLenum[]) { GL_NONE, GL_COLOR_ATTACHMENT1 }); + glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + glBindVertexArray(shader->vao); + glUniform2i(uniforms[GBA_GL_VS_LOC], totalHeight, 0); + glUniform2i(uniforms[GBA_GL_VS_MAXPOS], totalWidth, totalHeight); + glUniform4i(uniforms[GBA_GL_OBJ_INFLAGS], GBAObjAttributesCGetPriority(sprite->c), 0, 0, 0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } From 34ddae8e4d612badeef7fd2dc07452476cb8558d Mon Sep 17 00:00:00 2001 From: KAMiKAZOW Date: Sat, 8 Jun 2019 20:53:25 +0200 Subject: [PATCH 401/429] HiDPI support for Qt GUI --- src/platform/qt/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index e2659eae3..98f57723d 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -68,6 +68,7 @@ int main(int argc, char* argv[]) { QApplication::setApplicationName(projectName); QApplication::setApplicationVersion(projectVersion); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); #ifdef BUILD_GLES2 QSurfaceFormat format; From 918caf87c476a60685dffab94c3b6f615991c231 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jun 2019 12:57:45 -0700 Subject: [PATCH 402/429] Core: Create game-related paths if they don't exist (fixes #1446) --- CHANGES | 1 + include/mgba-util/vfs.h | 2 ++ src/core/directories.c | 15 +++++++++++++++ src/platform/3ds/3ds-vfs.c | 5 +++++ src/platform/psp2/sce-vfs.c | 6 ++++++ src/platform/windows/vfs-w32.c | 12 ++++++++++++ src/util/vfs/vfs-dirent.c | 5 +++++ 7 files changed, 46 insertions(+) diff --git a/CHANGES b/CHANGES index 72ccd171d..20cf0a4f4 100644 --- a/CHANGES +++ b/CHANGES @@ -53,6 +53,7 @@ Misc: - Qt: Make mute menu option also toggle fast-forward mute (fixes mgba.io/i/1424) - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) - mGUI: Remember name and position of last loaded game + - Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446) 0.7.2: (2019-05-25) Emulation fixes: diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index f10f3c577..0ac676d5f 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -91,6 +91,8 @@ struct VDir* VDirOpen7z(const char* path, int flags); struct VDir* VDeviceList(void); #endif +bool VDirCreate(const char* path); + #ifdef USE_VFS_FILE struct VFile* VFileFOpen(const char* path, const char* mode); struct VFile* VFileFromFILE(FILE* file); diff --git a/src/core/directories.c b/src/core/directories.c index 295614a12..e2e2d2c9f 100644 --- a/src/core/directories.c +++ b/src/core/directories.c @@ -173,6 +173,9 @@ struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, struct VDir* d void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts) { if (opts->savegamePath) { struct VDir* dir = VDirOpen(opts->savegamePath); + if (!dir && VDirCreate(opts->savegamePath)) { + dir = VDirOpen(opts->savegamePath); + } if (dir) { if (dirs->save && dirs->save != dirs->base) { dirs->save->close(dirs->save); @@ -183,6 +186,9 @@ void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptio if (opts->savestatePath) { struct VDir* dir = VDirOpen(opts->savestatePath); + if (!dir && VDirCreate(opts->savestatePath)) { + dir = VDirOpen(opts->savestatePath); + } if (dir) { if (dirs->state && dirs->state != dirs->base) { dirs->state->close(dirs->state); @@ -193,6 +199,9 @@ void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptio if (opts->screenshotPath) { struct VDir* dir = VDirOpen(opts->screenshotPath); + if (!dir && VDirCreate(opts->screenshotPath)) { + dir = VDirOpen(opts->screenshotPath); + } if (dir) { if (dirs->screenshot && dirs->screenshot != dirs->base) { dirs->screenshot->close(dirs->screenshot); @@ -203,6 +212,9 @@ void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptio if (opts->patchPath) { struct VDir* dir = VDirOpen(opts->patchPath); + if (!dir && VDirCreate(opts->patchPath)) { + dir = VDirOpen(opts->patchPath); + } if (dir) { if (dirs->patch && dirs->patch != dirs->base) { dirs->patch->close(dirs->patch); @@ -213,6 +225,9 @@ void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptio if (opts->cheatsPath) { struct VDir* dir = VDirOpen(opts->cheatsPath); + if (!dir && VDirCreate(opts->cheatsPath)) { + dir = VDirOpen(opts->cheatsPath); + } if (dir) { if (dirs->cheats && dirs->cheats != dirs->base) { dirs->cheats->close(dirs->cheats); diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index 975d63fdf..8f5864745 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -310,4 +310,9 @@ static enum VFSType _vd3deType(struct VDirEntry* vde) { } return VFS_FILE; } + +bool VDirCreate(const char* path) { + Result rc = FSUSER_CreateDirectory(sdmcArchive, fsMakePath(PATH_ASCII, path), 0); + return R_SUCCEEDED(rc) || rc == 0xC82044BE; +} #endif diff --git a/src/platform/psp2/sce-vfs.c b/src/platform/psp2/sce-vfs.c index 383847291..c200d8903 100644 --- a/src/platform/psp2/sce-vfs.c +++ b/src/platform/psp2/sce-vfs.c @@ -357,3 +357,9 @@ static enum VFSType _vdlesceType(struct VDirEntry* vde) { UNUSED(vde); return VFS_DIRECTORY; } + +bool VDirCreate(const char* path) { + // TODO: Verify vitasdk explanation of return values + sceIoMkdir(path, 0777); + return true; +} \ No newline at end of file diff --git a/src/platform/windows/vfs-w32.c b/src/platform/windows/vfs-w32.c index 902f937f3..bfa2e30a3 100644 --- a/src/platform/windows/vfs-w32.c +++ b/src/platform/windows/vfs-w32.c @@ -172,3 +172,15 @@ static enum VFSType _vdweType(struct VDirEntry* vde) { } return VFS_FILE; } + +bool VDirCreate(const char* path) { + wchar_t wpath[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH); + if (CreateDirectoryW(wpath, NULL)) { + return true; + } + if (GetLastError() == ERROR_ALREADY_EXISTS) { + return true; + } + return false; +} \ No newline at end of file diff --git a/src/util/vfs/vfs-dirent.c b/src/util/vfs/vfs-dirent.c index c41c5b728..0cb060e2b 100644 --- a/src/util/vfs/vfs-dirent.c +++ b/src/util/vfs/vfs-dirent.c @@ -8,6 +8,7 @@ #include #include +#include #include static bool _vdClose(struct VDir* vd); @@ -166,3 +167,7 @@ static enum VFSType _vdeType(struct VDirEntry* vde) { return VFS_FILE; #endif } + +bool VDirCreate(const char* path) { + return mkdir(path, 0777) == 0 || errno == EEXIST; +} \ No newline at end of file From a9e96c7d00f7816cebf1edf50575e7d9f59219d8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jun 2019 13:28:03 -0700 Subject: [PATCH 403/429] GB SIO: Fix lockstep failing games aren't reloaded --- CHANGES | 1 + src/gb/sio.c | 1 + src/gb/sio/lockstep.c | 35 +++++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 20cf0a4f4..7999a8365 100644 --- a/CHANGES +++ b/CHANGES @@ -31,6 +31,7 @@ Other fixes: - Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) - Core: Fix crashes if core directories aren't set - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) + - GB SIO: Fix lockstep failing games aren't reloaded Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/sio.c b/src/gb/sio.c index 26a326966..f2bb20fe8 100644 --- a/src/gb/sio.c +++ b/src/gb/sio.c @@ -31,6 +31,7 @@ void GBSIOInit(struct GBSIO* sio) { void GBSIOReset(struct GBSIO* sio) { sio->nextEvent = INT_MAX; sio->remainingBits = 0; + GBSIOSetDriver(sio, sio->driver); } void GBSIODeinit(struct GBSIO* sio) { diff --git a/src/gb/sio/lockstep.c b/src/gb/sio/lockstep.c index b1d925ebc..4aba35e01 100644 --- a/src/gb/sio/lockstep.c +++ b/src/gb/sio/lockstep.c @@ -103,9 +103,12 @@ static void _finishTransfer(struct GBSIOLockstepNode* node) { static int32_t _masterUpdate(struct GBSIOLockstepNode* node) { + enum mLockstepPhase transferActive; + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + bool needsToWait = false; int i; - switch (node->p->d.transferActive) { + switch (transferActive) { case TRANSFER_IDLE: // If the master hasn't initiated a transfer, it can keep going. node->nextEvent += LOCKSTEP_INCREMENT; @@ -165,8 +168,12 @@ static int32_t _masterUpdate(struct GBSIOLockstepNode* node) { } static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) { + enum mLockstepPhase transferActive; + + ATOMIC_LOAD(transferActive, node->p->d.transferActive); + bool signal = false; - switch (node->p->d.transferActive) { + switch (transferActive) { case TRANSFER_IDLE: node->p->d.addCycles(&node->p->d, node->id, LOCKSTEP_INCREMENT); break; @@ -174,10 +181,16 @@ static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) { case TRANSFER_FINISHING: break; case TRANSFER_STARTED: + if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { + break; + } node->transferFinished = false; signal = true; break; case TRANSFER_FINISHED: + if (node->p->d.unusedCycles(&node->p->d, node->id) > node->eventDiff) { + break; + } _finishTransfer(node); signal = true; break; @@ -193,7 +206,10 @@ static uint32_t _slaveUpdate(struct GBSIOLockstepNode* node) { static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, uint32_t cyclesLate) { struct GBSIOLockstepNode* node = user; + mLockstepLock(&node->p->d); if (node->p->d.attached < 2) { + mTimingSchedule(timing, &node->event, (GBSIOCyclesPerTransfer[0] >> 1) - cyclesLate); + mLockstepUnlock(&node->p->d); return; } int32_t cycles = 0; @@ -209,6 +225,8 @@ static void _GBSIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, } else { cycles = node->nextEvent; } + mLockstepUnlock(&node->p->d); + if (cycles > 0) { node->nextEvent = 0; node->eventDiff += cycles; @@ -227,17 +245,22 @@ static void GBSIOLockstepNodeWriteSB(struct GBSIODriver* driver, uint8_t value) static uint8_t GBSIOLockstepNodeWriteSC(struct GBSIODriver* driver, uint8_t value) { struct GBSIOLockstepNode* node = (struct GBSIOLockstepNode*) driver; - if ((value & 0x81) == 0x81 && node->p->d.attached > 1) { + int attached; + ATOMIC_LOAD(attached, node->p->d.attached); + + if ((value & 0x81) == 0x81 && attached > 1) { + mLockstepLock(&node->p->d); bool claimed = false; if (ATOMIC_CMPXCHG(node->p->masterClaimed, claimed, true)) { - node->p->d.transferActive = TRANSFER_STARTING; - node->p->d.transferCycles = GBSIOCyclesPerTransfer[(value >> 1) & 1]; + ATOMIC_STORE(node->p->d.transferActive, TRANSFER_STARTING); + ATOMIC_STORE(node->p->d.transferCycles, GBSIOCyclesPerTransfer[(value >> 1) & 1]); mTimingDeschedule(&driver->p->p->timing, &driver->p->event); mTimingDeschedule(&driver->p->p->timing, &node->event); mTimingSchedule(&driver->p->p->timing, &node->event, 0); } else { - mLOG(GB_SIO, FATAL, "GBSIOLockstepNodeWriteSC() failed to write to masterClaimed\n"); + mLOG(GB_SIO, DEBUG, "GBSIOLockstepNodeWriteSC() failed to write to masterClaimed\n"); } + mLockstepUnlock(&node->p->d); } return value; } From ecc6141c67ee8eff2fc74d8a9eaa7fcc4f0b4788 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 18 Jun 2019 11:14:05 -0700 Subject: [PATCH 404/429] Qt: Add option to pause on minimizing window (closes #1379) --- CHANGES | 1 + src/platform/qt/SettingsView.cpp | 2 ++ src/platform/qt/SettingsView.ui | 23 +++++++++++++++-------- src/platform/qt/Window.cpp | 20 ++++++++++++++++++++ src/platform/qt/Window.h | 1 + 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 7999a8365..d28e64d8b 100644 --- a/CHANGES +++ b/CHANGES @@ -55,6 +55,7 @@ Misc: - Vita: L2/R2 and L3/R3 can now be mapped on PSTV (fixes mgba.io/i/1292) - mGUI: Remember name and position of last loaded game - Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446) + - Qt: Add option to pause on minimizing window (closes mgba.io/i/1379) 0.7.2: (2019-05-25) Emulation fixes: diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 62a1d43f0..6f5f94005 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -387,6 +387,7 @@ void SettingsView::updateConfig() { saveSetting("allowOpposingDirections", m_ui.allowOpposingDirections); saveSetting("suspendScreensaver", m_ui.suspendScreensaver); saveSetting("pauseOnFocusLost", m_ui.pauseOnFocusLost); + saveSetting("pauseOnMinimize", m_ui.pauseOnMinimize); saveSetting("savegamePath", m_ui.savegamePath); saveSetting("savestatePath", m_ui.savestatePath); saveSetting("screenshotPath", m_ui.screenshotPath); @@ -550,6 +551,7 @@ void SettingsView::reloadConfig() { loadSetting("allowOpposingDirections", m_ui.allowOpposingDirections); loadSetting("suspendScreensaver", m_ui.suspendScreensaver); loadSetting("pauseOnFocusLost", m_ui.pauseOnFocusLost); + loadSetting("pauseOnMinimize", m_ui.pauseOnMinimize); loadSetting("savegamePath", m_ui.savegamePath); loadSetting("savestatePath", m_ui.savestatePath); loadSetting("screenshotPath", m_ui.screenshotPath); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index d674dd15d..608ab70e1 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -562,7 +562,7 @@ - + Show FPS in title bar @@ -572,21 +572,21 @@ - + Qt::Horizontal - + Qt::Horizontal - + Automatically save cheats @@ -596,7 +596,7 @@ - + Automatically load cheats @@ -606,7 +606,7 @@ - + Automatically save state @@ -616,7 +616,7 @@ - + Automatically load state @@ -626,13 +626,20 @@ - + Enable Discord Rich Presence + + + + Pause when minimized + + + diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 6b174a35d..d8b64b5cb 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -602,6 +602,13 @@ void Window::resizeEvent(QResizeEvent* event) { void Window::showEvent(QShowEvent* event) { if (m_wasOpened) { + if (event->spontaneous() && m_config->getOption("pauseOnMinimize").toInt() && m_controller) { + focusCheck(); + if (m_autoresume) { + m_controller->setPaused(false); + m_autoresume = false; + } + } return; } m_wasOpened = true; @@ -623,6 +630,19 @@ void Window::showEvent(QShowEvent* event) { setFocus(); } +void Window::hideEvent(QHideEvent* event) { + if (!event->spontaneous()) { + return; + } + if (!m_config->getOption("pauseOnMinimize").toInt() || !m_controller) { + return; + } + if (!m_controller->isPaused()) { + m_autoresume = true; + m_controller->setPaused(true); + } +} + void Window::closeEvent(QCloseEvent* event) { emit shutdown(); m_config->setQtOption("windowPos", pos()); diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index b41944fa0..b49185740 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -116,6 +116,7 @@ protected: virtual void keyReleaseEvent(QKeyEvent* event) override; virtual void resizeEvent(QResizeEvent*) override; virtual void showEvent(QShowEvent*) override; + virtual void hideEvent(QHideEvent*) override; virtual void closeEvent(QCloseEvent*) override; virtual void focusInEvent(QFocusEvent*) override; virtual void focusOutEvent(QFocusEvent*) override; From 120e1006d04ed62e011b2342842ac6c54f0673c3 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Tue, 18 Jun 2019 21:42:25 +0200 Subject: [PATCH 405/429] All: Microsoft Visual C++ compatibility code --- CMakeLists.txt | 20 +++- include/mgba/core/version.h | 16 +-- include/mgba/internal/gba/input.h | 3 +- src/core/version.c.in | 14 +-- src/gba/input.c | 2 +- src/platform/cmake/FindSDL2.cmake | 181 +++++++++++++++++++++++++++++ src/platform/cmake/Findepoxy.cmake | 14 +++ src/platform/sdl/CMakeLists.txt | 7 ++ src/platform/sdl/main.c | 2 +- 9 files changed, 236 insertions(+), 23 deletions(-) create mode 100644 src/platform/cmake/FindSDL2.cmake create mode 100644 src/platform/cmake/Findepoxy.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 50ec9fc3e..8b3451987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_minimum_required(VERSION 3.1) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/platform/cmake/") + if(POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif() @@ -245,16 +247,18 @@ endif() if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") add_definitions(-D_WIN32_WINNT=0x0600) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") + if(MSVC) + add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + add_definitions(-D_UNICODE -DUNICODE) + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") + endif() list(APPEND OS_LIB ws2_32 shlwapi) list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/*.c) source_group("Windows-specific code" FILES ${OS_SRC}) - if(MSVC) - add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) - endif() elseif(UNIX) set(USE_PTHREADS ON) @@ -944,6 +948,10 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) + include(GenerateExportHeader) + generate_export_header(${BINARY_NAME} BASE_NAME mgba STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) diff --git a/include/mgba/core/version.h b/include/mgba/core/version.h index 47086618f..b261ab6d3 100644 --- a/include/mgba/core/version.h +++ b/include/mgba/core/version.h @@ -10,13 +10,15 @@ extern "C" { #endif -extern const char* const gitCommit; -extern const char* const gitCommitShort; -extern const char* const gitBranch; -extern const int gitRevision; -extern const char* const binaryName; -extern const char* const projectName; -extern const char* const projectVersion; +#include + +extern MGBA_EXPORT const char* const gitCommit; +extern MGBA_EXPORT const char* const gitCommitShort; +extern MGBA_EXPORT const char* const gitBranch; +extern MGBA_EXPORT const int gitRevision; +extern MGBA_EXPORT const char* const binaryName; +extern MGBA_EXPORT const char* const projectName; +extern MGBA_EXPORT const char* const projectVersion; #ifdef __cplusplus } diff --git a/include/mgba/internal/gba/input.h b/include/mgba/internal/gba/input.h index 03cb8b5e0..179e935f4 100644 --- a/include/mgba/internal/gba/input.h +++ b/include/mgba/internal/gba/input.h @@ -7,12 +7,13 @@ #define GBA_INPUT_H #include +#include CXX_GUARD_START #include -extern const struct mInputPlatformInfo GBAInputInfo; +extern MGBA_EXPORT const struct mInputPlatformInfo GBAInputInfo; enum GBAKey { GBA_KEY_A = 0, diff --git a/src/core/version.c.in b/src/core/version.c.in index b8c87fb70..00028e4c5 100644 --- a/src/core/version.c.in +++ b/src/core/version.c.in @@ -5,10 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -const char* const gitCommit = "${GIT_COMMIT}"; -const char* const gitCommitShort = "${GIT_COMMIT_SHORT}"; -const char* const gitBranch = "${GIT_BRANCH}"; -const int gitRevision = ${GIT_REV}; -const char* const binaryName = "${BINARY_NAME}"; -const char* const projectName = "${PROJECT_NAME}"; -const char* const projectVersion = "${VERSION_STRING}"; +MGBA_EXPORT const char* const gitCommit = "${GIT_COMMIT}"; +MGBA_EXPORT const char* const gitCommitShort = "${GIT_COMMIT_SHORT}"; +MGBA_EXPORT const char* const gitBranch = "${GIT_BRANCH}"; +MGBA_EXPORT const int gitRevision = ${GIT_REV}; +MGBA_EXPORT const char* const binaryName = "${BINARY_NAME}"; +MGBA_EXPORT const char* const projectName = "${PROJECT_NAME}"; +MGBA_EXPORT const char* const projectVersion = "${VERSION_STRING}"; diff --git a/src/gba/input.c b/src/gba/input.c index 8b24dc3f2..4c7d6b09a 100644 --- a/src/gba/input.c +++ b/src/gba/input.c @@ -7,7 +7,7 @@ #include -const struct mInputPlatformInfo GBAInputInfo = { +MGBA_EXPORT const struct mInputPlatformInfo GBAInputInfo = { .platformName = "gba", .keyId = (const char*[]) { "A", diff --git a/src/platform/cmake/FindSDL2.cmake b/src/platform/cmake/FindSDL2.cmake new file mode 100644 index 000000000..091faba16 --- /dev/null +++ b/src/platform/cmake/FindSDL2.cmake @@ -0,0 +1,181 @@ +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDLmain.h and SDLmain.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +#========================================================================= +# +# Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names +# of any contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#========================================================================= +# +SET(SDL2_SEARCH_PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + ${SDL2_PATH} +) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_LIBRARY_TEMP}/../.. +) + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIR}/../.. +) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/src/platform/cmake/Findepoxy.cmake b/src/platform/cmake/Findepoxy.cmake new file mode 100644 index 000000000..1f56add79 --- /dev/null +++ b/src/platform/cmake/Findepoxy.cmake @@ -0,0 +1,14 @@ +find_path(EPOXY_INCLUDE_DIRS NAMES epoxy/gl.h PATH_SUFFIX include) +find_library(EPOXY_LIBRARIES NAMES epoxy_0 PATH_SUFFIX lib) + +if (NOT EPOXY_LIBRARIES) + find_library(EPOXY_LIBRARIES NAMES epoxy PATH_SUFFIX lib) +endif() + +if(EPOXY_LIBRARIES AND EPOXY_INCLUDE_DIRS) + set(epoxy_FOUND TRUE) +endif() + +if (WIN32 AND NOT epoxy_FOUND) + message(FATAL_ERROR "Windows requires epoxy module!") +endif() diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 36e73b686..6f3bdf5ed 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -3,6 +3,10 @@ set(SDL_VERSION "2" CACHE STRING "Version of SDL to use (1.2 or 2)") if (SDL_VERSION EQUAL "2") include(FindPkgConfig) pkg_search_module(SDL2 sdl2) + if (NOT SDL2_FOUND) + find_package(SDL2) + endif() + if (SDL2_FOUND) set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIRS}) set(SDL_LIBRARY ${SDL2_LIBRARIES}) @@ -105,6 +109,9 @@ target_link_libraries(${BINARY_NAME}-sdl ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OP if(NOT WIN32) set_target_properties(${BINARY_NAME}-sdl PROPERTIES OUTPUT_NAME ${BINARY_NAME}) endif() +if (WIN32 AND MSVC) + set_target_properties(${BINARY_NAME}-sdl PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE") +endif() install(TARGETS ${BINARY_NAME}-sdl DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-sdl) if(UNIX) install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-sdl) diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 0bb340c23..deda42506 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -178,7 +178,7 @@ int main(int argc, char** argv) { return ret; } -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UNICODE) #include int wmain(int argc, wchar_t** argv) { From abc5fbeb387e93d9194714eff8ba78669701d5f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2019 14:02:45 -0700 Subject: [PATCH 406/429] Python: Fix build --- CMakeLists.txt | 4 ++++ src/platform/cmake/Findepoxy.cmake | 4 ---- src/platform/python/_builder.h | 1 + src/platform/python/_builder.py | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b3451987..8e61e6953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -785,6 +785,10 @@ elseif(BUILD_GLES2) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgles2") endif() +if (WIN32 AND NOT USE_EPOXY) + message(FATAL_ERROR "Windows requires epoxy module!") +endif() + if(USE_SQLITE3) list(APPEND FEATURES SQLITE3) include_directories(AFTER ${SQLITE3_INCLUDE_DIRS}) diff --git a/src/platform/cmake/Findepoxy.cmake b/src/platform/cmake/Findepoxy.cmake index 1f56add79..0a5ce4091 100644 --- a/src/platform/cmake/Findepoxy.cmake +++ b/src/platform/cmake/Findepoxy.cmake @@ -8,7 +8,3 @@ endif() if(EPOXY_LIBRARIES AND EPOXY_INCLUDE_DIRS) set(epoxy_FOUND TRUE) endif() - -if (WIN32 AND NOT epoxy_FOUND) - message(FATAL_ERROR "Windows requires epoxy module!") -endif() diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index 7c37e4a18..a0a27d5a7 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -5,6 +5,7 @@ #define _SYS_TIME_H_ #define _TIME_H #define _TIME_H_ +#define MGBA_EXPORT #define ATTRIBUTE_FORMAT(X, Y, Z) #define DECL_BITFIELD(newtype, oldtype) typedef oldtype newtype diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 6b76ee698..82c484e64 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -18,6 +18,7 @@ cppflags.extend(["-I" + incdir, "-I" + srcdir, "-I" + bindir]) ffi.set_source("mgba._pylib", """ #define static #define inline +#define MGBA_EXPORT #include #define OPAQUE_THREADING #include From 227121e6761d3bc3a8ad65e8eebaadfa54e7c6ec Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2019 13:46:54 -0700 Subject: [PATCH 407/429] CMake: Begin cleanup --- CMakeLists.txt | 155 ++++------------------- src/arm/CMakeLists.txt | 20 +++ src/core/CMakeLists.txt | 31 +++++ src/debugger/CMakeLists.txt | 16 +++ src/feature/CMakeLists.txt | 16 +++ src/gb/CMakeLists.txt | 45 +++++++ src/gba/CMakeLists.txt | 63 +++++++++ src/lr35902/CMakeLists.txt | 16 +++ src/platform/cmake/ExportDirectory.cmake | 7 + src/platform/cmake/FindFeature.cmake | 47 +++++++ src/util/CMakeLists.txt | 38 ++++++ 11 files changed, 325 insertions(+), 129 deletions(-) create mode 100644 src/arm/CMakeLists.txt create mode 100644 src/core/CMakeLists.txt create mode 100644 src/debugger/CMakeLists.txt create mode 100644 src/feature/CMakeLists.txt create mode 100644 src/gb/CMakeLists.txt create mode 100644 src/gba/CMakeLists.txt create mode 100644 src/lr35902/CMakeLists.txt create mode 100644 src/platform/cmake/ExportDirectory.cmake create mode 100644 src/platform/cmake/FindFeature.cmake create mode 100644 src/util/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e61e6953..b4c617d89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.1) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/platform/cmake/") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/src/platform/cmake/") if(POLICY CMP0025) cmake_policy(SET CMP0025 NEW) @@ -81,38 +81,9 @@ else() endif() endif() -file(GLOB ARM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/*.c) -file(GLOB ARM_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/test/*.c) -file(GLOB LR35902_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/*.c) -file(GLOB LR35902_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/test/*.c) -file(GLOB GBA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/*.c) -file(GLOB GBA_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/test/*.c) -file(GLOB GB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/*.c) -file(GLOB GB_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/test/*.c) -file(GLOB GBA_CHEATS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/cheats/*.c) -file(GLOB GBA_EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/extra/audio-mixer.c) -file(GLOB GBA_RR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/rr/*.c) -file(GLOB CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/*.c) -file(GLOB CORE_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/core/test/*.c) -file(GLOB UTIL_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/*.c) -file(GLOB UTIL_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/test/*.c) -file(GLOB GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/gui/*.c ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/gui/*.c) -file(GLOB GBA_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/renderers/*.c) -file(GLOB GBA_SIO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/sio/*.c) -file(GLOB GBA_EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/extra/*.c) -file(GLOB GB_SIO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/sio/*.c) -file(GLOB GB_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/renderers/*.c) -file(GLOB GB_EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/extra/*.c) file(GLOB THIRD_PARTY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/inih/*.c) -file(GLOB EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/*.c) set(CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-mem.c ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fifo.c) set(VFS_SRC) -source_group("ARM core" FILES ${ARM_SRC}) -source_group("LR35902 core" FILES ${LR35902_SRC}) -source_group("GBA board" FILES ${GBA_SRC} ${GBA_RENDERER_SRC} ${GBA_SIO_SRC}) -source_group("GBA extra" FILES ${GBA_CHEATS_SRC} ${GBA_RR_SRC}) -source_group("GB board" FILES ${GB_SRC} ${GB_SIO_SRC}) -source_group("Utilities" FILES ${UTIL_SRC}) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/include) if(NOT CMAKE_BUILD_TYPE) @@ -154,54 +125,7 @@ if (NOT DEFINED MANDIR) set(MANDIR ${CMAKE_INSTALL_MANDIR}) endif() -# Function definitions -include(FindPkgConfig) -function(find_feature FEATURE_NAME FEATURE_REQUIRES) - if (NOT ${FEATURE_NAME}) - return() - endif() - if (DISABLE_DEPS) - set(${FEATURE_NAME} OFF PARENT_SCOPE) - return() - endif() - foreach(REQUIRE ${FEATURE_REQUIRES}) - if(NOT ${REQUIRE}_FOUND) - find_package(${REQUIRE} QUIET) - if(NOT ${REQUIRE}_FOUND) - pkg_search_module(${REQUIRE} ${REQUIRE}) - if (NOT ${REQUIRE}_FOUND) - message(WARNING "Requested module ${REQUIRE} missing for feature ${FEATURE_NAME}. Feature disabled.") - set(${FEATURE_NAME} OFF PARENT_SCOPE) - return() - endif() - endif() - endif() - string(TOUPPER ${REQUIRE} UREQUIRE) - set(${UREQUIRE}_CFLAGS_OTHER ${${REQUIRE}_CFLAGS_OTHER} PARENT_SCOPE) - set(${UREQUIRE}_FOUND ${${REQUIRE}_FOUND} PARENT_SCOPE) - set(${UREQUIRE}_INCLUDE_DIRS ${${REQUIRE}_INCLUDE_DIRS} PARENT_SCOPE) - set(${UREQUIRE}_VERSION_STRING ${${REQUIRE}_VERSION_STRING} PARENT_SCOPE) - if (APPLE) - set(IS_FRAMEWORK OFF) - set(LIBS) - foreach(LIB IN LISTS ${REQUIRE}_LIBRARIES) - if(LIB STREQUAL "-framework") - set(IS_FRAMEWORK ON) - elseif(IS_FRAMEWORK) - list(APPEND LIBS "-framework ${LIB}") - set(IS_FRAMEWORK OFF) - else() - list(APPEND LIBS ${LIB}) - endif() - endforeach() - set(${UREQUIRE}_LIBRARIES ${LIBS} PARENT_SCOPE) - else() - set(${UREQUIRE}_LIBRARIES ${${REQUIRE}_LIBRARIES} PARENT_SCOPE) - endif() - set(${UREQUIRE}_LIBRARY_DIRS ${${REQUIRE}_LIBRARY_DIRS} PARENT_SCOPE) - set(${UREQUIRE}_LDFLAGS_OTHER ${${REQUIRE}_LDFLAGS_OTHER} PARENT_SCOPE) - endforeach() -endfunction() +include(FindFeature) # Version information add_custom_target(version-info ALL @@ -215,7 +139,6 @@ add_custom_target(version-info ALL include(${CMAKE_CURRENT_SOURCE_DIR}/version.cmake) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/core/version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c) -list(APPEND UTIL_SRC ${CMAKE_CURRENT_BINARY_DIR}/version.c) source_group("Generated sources" FILES ${CMAKE_CURRENT_BINARY_DIR}/version.c) # Advanced settings @@ -559,13 +482,8 @@ if(USE_FFMPEG) endif() # Features -set(DEBUGGER_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/parser.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/symbols.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/cli-debugger.c) - -file(GLOB DEBUGGER_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/test/*.c) +add_subdirectory(src/debugger) +add_subdirectory(src/feature) set(FEATURE_SRC) set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6") @@ -823,43 +741,29 @@ if(ENABLE_SCRIPTING) endif() endif() +add_subdirectory(src/arm) +add_subdirectory(src/core) +add_subdirectory(src/gb) +add_subdirectory(src/gba) +add_subdirectory(src/lr35902) +add_subdirectory(src/util) + +list(APPEND GUI_SRC ${EXTRA_GUI_SRC}) +list(APPEND UTIL_SRC ${CMAKE_CURRENT_BINARY_DIR}/version.c) + set(TEST_SRC ${CORE_TEST_SRC}) if(M_CORE_GB) add_definitions(-DM_CORE_GB) - list(APPEND CORE_SRC - ${LR35902_SRC} - ${GB_SRC} - ${GB_RENDERER_SRC}) - list(APPEND DEBUGGER_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/cli-debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/memory-debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/symbols.c) - list(APPEND TEST_SRC - ${LR35902_TEST_SRC} - ${GB_TEST_SRC}) + list(APPEND CORE_SRC ${LR35902_SRC} ${GB_SRC}) + list(APPEND DEBUGGER_SRC ${LR35902_DEBUGGER_SRC} ${GB_DEBUGGER_SRC}) + list(APPEND TEST_SRC ${LR35902_TEST_SRC} ${GB_TEST_SRC}) endif() if(M_CORE_GBA) add_definitions(-DM_CORE_GBA) - list(APPEND CORE_SRC - ${ARM_SRC} - ${GBA_SRC} - ${GBA_CHEATS_SRC} - ${GBA_RENDERER_SRC}) - list(APPEND DEBUGGER_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/cli-debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/memory-debugger.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/debugger/cli.c) - list(APPEND TEST_SRC - ${ARM_TEST_SRC} - ${GBA_TEST_SRC}) - if(NOT M_CORE_GB) - list(APPEND CORE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/audio.c) - endif() + list(APPEND CORE_SRC ${ARM_SRC} ${GBA_SRC}) + list(APPEND DEBUGGER_SRC ${ARM_DEBUGGER_SRC} ${GBA_DEBUGGER_SRC}) + list(APPEND TEST_SRC ${ARM_TEST_SRC} ${GBA_TEST_SRC}) endif() if(USE_DEBUGGERS) @@ -909,29 +813,22 @@ set(SRC ${CORE_SRC} ${VFS_SRC}) if(NOT MINIMAL_CORE) set(ENABLE_EXTRA ON) if(M_CORE_GBA) - list(APPEND SRC - ${GBA_SIO_SRC}) + list(APPEND SRC ${GBA_SIO_SRC}) endif() if(M_CORE_GB) - list(APPEND SRC - ${GB_SIO_SRC}) + list(APPEND SRC ${GB_SIO_SRC}) endif() - list(APPEND SRC - ${FEATURE_SRC}) + list(APPEND SRC ${FEATURE_SRC}) endif() if(ENABLE_EXTRA) if(M_CORE_GBA) - list(APPEND SRC - ${GBA_RR_SRC} - ${GBA_EXTRA_SRC}) + list(APPEND SRC ${GBA_EXTRA_SRC}) endif() if(M_CORE_GB) - list(APPEND SRC - ${GB_EXTRA_SRC}) + list(APPEND SRC ${GB_EXTRA_SRC}) endif() - list(APPEND SRC - ${EXTRA_SRC}) + list(APPEND SRC ${EXTRA_SRC}) endif() if(NOT SKIP_LIBRARY) diff --git a/src/arm/CMakeLists.txt b/src/arm/CMakeLists.txt new file mode 100644 index 000000000..3eaa2d0d3 --- /dev/null +++ b/src/arm/CMakeLists.txt @@ -0,0 +1,20 @@ +include(ExportDirectory) +set(SOURCE_FILES + arm.c + core.c + decoder-arm.c + decoder.c + decoder-thumb.c + isa-arm.c + isa-thumb.c) + +set(DEBUGGER_FILES + debugger/cli-debugger.c + debugger/debugger.c + debugger/memory-debugger.c) + +source_group("ARM core" FILES ${SOURCE_FILES}) +source_group("ARM debugger" FILES ${DEBUGGER_FILES}) + +export_directory(ARM SOURCE_FILES) +export_directory(ARM_DEBUGGER DEBUGGER_FILES) \ No newline at end of file diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 000000000..6c639e594 --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,31 @@ +include(ExportDirectory) +set(SOURCE_FILES + bitmap-cache.c + cache-set.c + cheats.c + config.c + core.c + directories.c + input.c + interface.c + library.c + lockstep.c + log.c + map-cache.c + mem-search.c + rewind.c + scripting.c + serialize.c + sync.c + thread.c + tile-cache.c + timing.c) + +set(TEST_FILES + test/core.c) + +source_group("mCore" FILES ${SOURCE_FILES}) +source_group("mCore tests" FILES ${TEST_FILES}) + +export_directory(CORE SOURCE_FILES) +export_directory(CORE_TEST TEST_FILES) \ No newline at end of file diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt new file mode 100644 index 000000000..b555caf7d --- /dev/null +++ b/src/debugger/CMakeLists.txt @@ -0,0 +1,16 @@ +include(ExportDirectory) +set(SOURCE_FILES + cli-debugger.c + debugger.c + parser.c + symbols.c) + +set(TEST_FILES + test/lexer.c + test/parser.c) + +source_group("Debugger" FILES ${SOURCE_FILES}) +source_group("Debugger tests" FILES ${TEST_FILES}) + +export_directory(DEBUGGER SOURCE_FILES) +export_directory(DEBUGGER_TEST TEST_FILES) \ No newline at end of file diff --git a/src/feature/CMakeLists.txt b/src/feature/CMakeLists.txt new file mode 100644 index 000000000..e92064d2b --- /dev/null +++ b/src/feature/CMakeLists.txt @@ -0,0 +1,16 @@ +include(ExportDirectory) +set(SOURCE_FILES + commandline.c + thread-proxy.c + video-logger.c) + +set(GUI_FILES + gui/gui-config.c + gui/gui-runner.c + gui/remap.c) + +source_group("Extra features" FILES ${SOURCE_FILES}) +source_group("Extra GUI source" FILES ${GUI_FILES}) + +export_directory(EXTRA SOURCE_FILES) +export_directory(EXTRA_GUI GUI_FILES) diff --git a/src/gb/CMakeLists.txt b/src/gb/CMakeLists.txt new file mode 100644 index 000000000..948cca747 --- /dev/null +++ b/src/gb/CMakeLists.txt @@ -0,0 +1,45 @@ +include(ExportDirectory) +set(SOURCE_FILES + audio.c + cheats.c + core.c + gb.c + io.c + mbc.c + memory.c + overrides.c + serialize.c + renderers/cache-set.c + renderers/software.c + sio.c + timer.c + video.c) + +set(SIO_FILES + sio/lockstep.c + sio/printer.c) + +set(EXTRA_FILES + extra/proxy.c) + +set(DEBUGGER_FILES + debugger/cli.c + debugger/debugger.c + debugger/symbols.c) + +set(TEST_FILES + test/core.c + test/mbc.c + test/memory.c + test/rtc.c) + +source_group("GB board" FILES ${SOURCE_FILES}) +source_group("GB extras" FILES ${EXTRA_FILES} ${SIO_FILES}) +source_group("GB debugger" FILES ${DEBUGGER_FILES}) +source_group("GB tests" FILES ${TEST_FILES}) + +export_directory(GB SOURCE_FILES) +export_directory(GB_SIO SIO_FILES) +export_directory(GB_EXTRA EXTRA_FILES) +export_directory(GB_DEBUGGER DEBUGGER_FILES) +export_directory(GB_TEST TEST_FILES) diff --git a/src/gba/CMakeLists.txt b/src/gba/CMakeLists.txt new file mode 100644 index 000000000..74a79425c --- /dev/null +++ b/src/gba/CMakeLists.txt @@ -0,0 +1,63 @@ +include(ExportDirectory) +set(SOURCE_FILES + ../gb/audio.c + audio.c + bios.c + cheats.c + cheats/codebreaker.c + cheats/gameshark.c + cheats/parv3.c + core.c + dma.c + gba.c + hardware.c + hle-bios.c + input.c + io.c + matrix.c + memory.c + overrides.c + renderers/cache-set.c + renderers/common.c + renderers/gl.c + renderers/software-bg.c + renderers/software-mode0.c + renderers/software-obj.c + renderers/video-software.c + savedata.c + serialize.c + sharkport.c + sio.c + timer.c + vfame.c + video.c) + +set(SIO_FILES + sio/joybus.c + sio/lockstep.c) + +set(EXTRA_FILES + extra/audio-mixer.c + extra/battlechip.c + extra/proxy.c + rr/mgm.c + rr/rr.c + rr/vbm.c) + +set(DEBUGGER_FILES + debugger/cli.c) + +set(TEST_FILES + test/cheats.c + test/core.c) + +source_group("GBA board" FILES ${SOURCE_FILES}) +source_group("GBA extras" FILES ${EXTRA_FILES} ${SIO_FILES}) +source_group("GBA debugger" FILES ${DEBUGGER_FILES}) +source_group("GBA tests" FILES ${TEST_FILES}) + +export_directory(GBA SOURCE_FILES) +export_directory(GBA_SIO SIO_FILES) +export_directory(GBA_EXTRA EXTRA_FILES) +export_directory(GBA_DEBUGGER DEBUGGER_FILES) +export_directory(GBA_TEST TEST_FILES) diff --git a/src/lr35902/CMakeLists.txt b/src/lr35902/CMakeLists.txt new file mode 100644 index 000000000..3b833d418 --- /dev/null +++ b/src/lr35902/CMakeLists.txt @@ -0,0 +1,16 @@ +include(ExportDirectory) +set(SOURCE_FILES + decoder.c + isa-lr35902.c + lr35902.c) + +set(DEBUGGER_FILES + debugger/cli-debugger.c + debugger/debugger.c + debugger/memory-debugger.c) + +source_group("LR35902 core" FILES ${SOURCE_FILES}) +source_group("ARM LR35902" FILES ${DEBUGGER_FILES}) + +export_directory(LR35902 SOURCE_FILES) +export_directory(LR35902_DEBUGGER DEBUGGER_FILES) \ No newline at end of file diff --git a/src/platform/cmake/ExportDirectory.cmake b/src/platform/cmake/ExportDirectory.cmake new file mode 100644 index 000000000..49e5ff929 --- /dev/null +++ b/src/platform/cmake/ExportDirectory.cmake @@ -0,0 +1,7 @@ +macro(export_directory PREFIX FILES) + set(${PREFIX}_SRC) + foreach(SRCFILE IN LISTS ${FILES}) + list(APPEND ${PREFIX}_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${SRCFILE}") + endforeach() + set(${PREFIX}_SRC ${${PREFIX}_SRC} PARENT_SCOPE) +endmacro() \ No newline at end of file diff --git a/src/platform/cmake/FindFeature.cmake b/src/platform/cmake/FindFeature.cmake new file mode 100644 index 000000000..ef23ac32d --- /dev/null +++ b/src/platform/cmake/FindFeature.cmake @@ -0,0 +1,47 @@ +include(FindPkgConfig) +function(find_feature FEATURE_NAME FEATURE_REQUIRES) + if (NOT ${FEATURE_NAME}) + return() + endif() + if (DISABLE_DEPS) + set(${FEATURE_NAME} OFF PARENT_SCOPE) + return() + endif() + foreach(REQUIRE ${FEATURE_REQUIRES}) + if(NOT ${REQUIRE}_FOUND) + find_package(${REQUIRE} QUIET) + if(NOT ${REQUIRE}_FOUND) + pkg_search_module(${REQUIRE} ${REQUIRE}) + if (NOT ${REQUIRE}_FOUND) + message(WARNING "Requested module ${REQUIRE} missing for feature ${FEATURE_NAME}. Feature disabled.") + set(${FEATURE_NAME} OFF PARENT_SCOPE) + return() + endif() + endif() + endif() + string(TOUPPER ${REQUIRE} UREQUIRE) + set(${UREQUIRE}_CFLAGS_OTHER ${${REQUIRE}_CFLAGS_OTHER} PARENT_SCOPE) + set(${UREQUIRE}_FOUND ${${REQUIRE}_FOUND} PARENT_SCOPE) + set(${UREQUIRE}_INCLUDE_DIRS ${${REQUIRE}_INCLUDE_DIRS} PARENT_SCOPE) + set(${UREQUIRE}_VERSION_STRING ${${REQUIRE}_VERSION_STRING} PARENT_SCOPE) + if (APPLE) + set(IS_FRAMEWORK OFF) + set(LIBS) + foreach(LIB IN LISTS ${REQUIRE}_LIBRARIES) + if(LIB STREQUAL "-framework") + set(IS_FRAMEWORK ON) + elseif(IS_FRAMEWORK) + list(APPEND LIBS "-framework ${LIB}") + set(IS_FRAMEWORK OFF) + else() + list(APPEND LIBS ${LIB}) + endif() + endforeach() + set(${UREQUIRE}_LIBRARIES ${LIBS} PARENT_SCOPE) + else() + set(${UREQUIRE}_LIBRARIES ${${REQUIRE}_LIBRARIES} PARENT_SCOPE) + endif() + set(${UREQUIRE}_LIBRARY_DIRS ${${REQUIRE}_LIBRARY_DIRS} PARENT_SCOPE) + set(${UREQUIRE}_LDFLAGS_OTHER ${${REQUIRE}_LDFLAGS_OTHER} PARENT_SCOPE) + endforeach() +endfunction() \ No newline at end of file diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt new file mode 100644 index 000000000..f4265b2ea --- /dev/null +++ b/src/util/CMakeLists.txt @@ -0,0 +1,38 @@ +include(ExportDirectory) +set(SOURCE_FILES + circle-buffer.c + configuration.c + crc32.c + elf-read.c + export.c + formatting.c + hash.c + patch.c + patch-fast.c + patch-ips.c + patch-ups.c + png-io.c + ring-fifo.c + string.c + table.c + text-codec.c + vfs.c) + +set(GUI_FILES + gui.c + gui/file-select.c + gui/font.c + gui/font-metrics.c + gui/menu.c) + +set(TEST_FILES + test/text-codec.c + test/vfs.c) + +source_group("Utilities" FILES ${SOURCE_FILES}) +source_group("GUI source" FILES ${GUI_FILES}) +source_group("Utilities tests" FILES ${TEST_FILES}) + +export_directory(UTIL SOURCE_FILES) +export_directory(GUI GUI_FILES) +export_directory(UTIL_TEST TEST_FILES) \ No newline at end of file From ebf35aaaf73915c115635764c83354ae8668c7cc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2019 14:14:46 -0700 Subject: [PATCH 408/429] ARM: Fix build --- src/arm/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arm/CMakeLists.txt b/src/arm/CMakeLists.txt index 3eaa2d0d3..a86f0bea1 100644 --- a/src/arm/CMakeLists.txt +++ b/src/arm/CMakeLists.txt @@ -1,7 +1,6 @@ include(ExportDirectory) set(SOURCE_FILES arm.c - core.c decoder-arm.c decoder.c decoder-thumb.c From c9c80df43370f39acfbfb25ac4d5b9a62ab25d79 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Thu, 20 Jun 2019 23:12:19 +0200 Subject: [PATCH 409/429] SDL: Fix SDL2 package search --- src/platform/cmake/FindSDL2.cmake | 48 +++++++++++++++---------------- src/platform/sdl/CMakeLists.txt | 6 ++++ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/platform/cmake/FindSDL2.cmake b/src/platform/cmake/FindSDL2.cmake index 091faba16..be210361c 100644 --- a/src/platform/cmake/FindSDL2.cmake +++ b/src/platform/cmake/FindSDL2.cmake @@ -1,6 +1,6 @@ -# SDL2_LIBRARY, the name of the library to link against +# SDL2_LIBRARIES, the name of the library to link against # SDL2_FOUND, if false, do not try to link to SDL2 -# SDL2_INCLUDE_DIR, where to find SDL.h +# SDL2_INCLUDE_DIRS, where to find SDL.h # # This module responds to the the flag: # SDL2_BUILDING_LIBRARY @@ -8,7 +8,7 @@ # only applications need main(). # Otherwise, it is assumed you are building an application and this # module will attempt to locate and set the the proper link flags -# as part of the returned SDL2_LIBRARY variable. +# as part of the returned SDL2_LIBRARIES variable. # # Don't forget to include SDLmain.h and SDLmain.m your project for the # OS X framework based version. (Other versions link to -lSDL2main which @@ -16,13 +16,13 @@ # module will automatically add the -framework Cocoa on your behalf. # # -# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration -# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# Additional Note: If you see an empty SDL2_LIBRARIES_TEMP in your configuration +# and no SDL2_LIBRARIES, it means CMake did not find your SDL2 library # (SDL2.dll, libsdl2.so, SDL2.framework, etc). -# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Set SDL2_LIBRARIES_TEMP to point to your SDL2 library, and configure again. # Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value -# as appropriate. These values are used to generate the final SDL2_LIBRARY -# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# as appropriate. These values are used to generate the final SDL2_LIBRARIES +# variable, but when these values are unset, SDL2_LIBRARIES does not get created. # # # $SDL2DIR is an environment variable that would @@ -42,7 +42,7 @@ # # On OSX, this will prefer the Framework version (if found) over others. # People will have to manually change the cache values of -# SDL2_LIBRARY to override this selection or set the CMake environment +# SDL2_LIBRARIES to override this selection or set the CMake environment # CMAKE_INCLUDE_PATH to modify the search paths. # # Note that the header path has changed from SDL2/SDL.h to just SDL.h @@ -94,23 +94,23 @@ SET(SDL2_SEARCH_PATHS ${SDL2_PATH} ) -FIND_PATH(SDL2_INCLUDE_DIR SDL.h +FIND_PATH(SDL2_INCLUDE_DIRS SDL.h HINTS $ENV{SDL2DIR} PATH_SUFFIXES include/SDL2 include - PATHS ${SDL2_SEARCH_PATHS} ${SDL2_LIBRARY_TEMP}/../.. + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_LIBRARIES_TEMP}/../.. ) -FIND_LIBRARY(SDL2_LIBRARY_TEMP +FIND_LIBRARY(SDL2_LIBRARIES_TEMP NAMES SDL2 HINTS $ENV{SDL2DIR} PATH_SUFFIXES lib64 lib - PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIR}/../.. + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIRS}/../.. ) IF(NOT SDL2_BUILDING_LIBRARY) - IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + IF(NOT ${SDL2_INCLUDE_DIRS} MATCHES ".framework") # Non-OS X framework versions expect you to also dynamically link to # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms # seem to provide SDL2main for compatibility even though they don't @@ -122,7 +122,7 @@ IF(NOT SDL2_BUILDING_LIBRARY) PATH_SUFFIXES lib64 lib PATHS ${SDL2_SEARCH_PATHS} ) - ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + ENDIF(NOT ${SDL2_INCLUDE_DIRS} MATCHES ".framework") ENDIF(NOT SDL2_BUILDING_LIBRARY) # SDL2 may require threads on your system. @@ -140,11 +140,11 @@ IF(MINGW) SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") ENDIF(MINGW) -IF(SDL2_LIBRARY_TEMP) +IF(SDL2_LIBRARIES_TEMP) # For SDL2main IF(NOT SDL2_BUILDING_LIBRARY) IF(SDL2MAIN_LIBRARY) - SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + SET(SDL2_LIBRARIES_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARIES_TEMP}) ENDIF(SDL2MAIN_LIBRARY) ENDIF(NOT SDL2_BUILDING_LIBRARY) @@ -155,27 +155,27 @@ IF(SDL2_LIBRARY_TEMP) # So I use a temporary variable until the end so I can set the # "real" variable in one-shot. IF(APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + SET(SDL2_LIBRARIES_TEMP ${SDL2_LIBRARIES_TEMP} "-framework Cocoa") ENDIF(APPLE) # For threads, as mentioned Apple doesn't need this. # In fact, there seems to be a problem if I used the Threads package # and try using this line, so I'm just skipping it entirely for OS X. IF(NOT APPLE) - SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + SET(SDL2_LIBRARIES_TEMP ${SDL2_LIBRARIES_TEMP} ${CMAKE_THREAD_LIBS_INIT}) ENDIF(NOT APPLE) # For MinGW library IF(MINGW) - SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + SET(SDL2_LIBRARIES_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARIES_TEMP}) ENDIF(MINGW) # Set the final string here so the GUI reflects the final state. - SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + SET(SDL2_LIBRARIES ${SDL2_LIBRARIES_TEMP} CACHE STRING "Where the SDL2 Library can be found") # Set the temp variable to INTERNAL so it is not seen in the CMake GUI - SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") -ENDIF(SDL2_LIBRARY_TEMP) + SET(SDL2_LIBRARIES_TEMP "${SDL2_LIBRARIES_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARIES_TEMP) INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARIES SDL2_INCLUDE_DIRS) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 6f3bdf5ed..12b803175 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -13,6 +13,12 @@ if (SDL_VERSION EQUAL "2") link_directories(${SDL2_LIBDIR}) set(SDL_VERSION_DEBIAN "2-2.0-0") set(SDL_FOUND ON PARENT_SCOPE) + + if (NOT SDL2MAIN_LIBRARY) + set(SDL2MAIN_LIBRARY "") + endif() + + set(SDLMAIN_LIBRARY ${SDL2MAIN_LIBRARY}) endif() endif() From 98d2671c6d90e662b50e676921ef431dc0b20979 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Fri, 21 Jun 2019 00:21:25 +0200 Subject: [PATCH 410/429] Util: Removed broken dllexport symbol --- include/mgba-util/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index cb6b35735..e268dbad5 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -222,7 +222,6 @@ typedef intptr_t ssize_t; #define _CONSTRUCTOR(FN, PRE) \ static void FN(void); \ __declspec(allocate(".CRT$XCU")) void (*_CONSTRUCTOR_ ## FN)(void) = FN; \ - __pragma(comment(linker,"/include:" PRE "_CONSTRUCTOR_" #FN)) \ static void FN(void) #ifdef _WIN64 #define CONSTRUCTOR(FN) _CONSTRUCTOR(FN, "") From 2d04d03d32aa433fba030cda907d1e2a7b9e6f79 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 10:35:21 -0700 Subject: [PATCH 411/429] CMake: Fix Windows static build --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4c617d89..e87a69dce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -785,6 +785,7 @@ source_group("Extra features" FILES ${FEATURE_SRC}) source_group("Third-party code" FILES ${THIRD_PARTY_SRC}) # Platform binaries +set(OS_DEFINES) if(DEFINED 3DS) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/platform/3ds ${CMAKE_CURRENT_BINARY_DIR}/3ds) endif() @@ -841,12 +842,13 @@ if(NOT SKIP_LIBRARY) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) - set_target_properties(${BINARY_NAME}-static PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") + set_target_properties(${BINARY_NAME}-static PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES};BUILD_STATIC" COMPILE_OPTIONS "${FEATURE_FLAGS}") install(TARGETS ${BINARY_NAME}-static DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) add_dependencies(${BINARY_NAME}-static version-info) endif() else() add_library(${BINARY_NAME} STATIC ${SRC}) + list(APPEND OS_DEFINES BUILD_STATIC) endif() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) From 3f044a5791166da2f05f1e72c8d6d06b6cd2d846 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2019 12:30:08 -0700 Subject: [PATCH 412/429] Core: Add support for loading Libretro-style cht files --- CHANGES | 1 + include/mgba-util/string.h | 2 + include/mgba/core/cheats.h | 2 + src/core/cheats.c | 115 +++++++++++++++++++++++++++- src/platform/qt/CheatsView.cpp | 4 +- src/util/string.c | 63 ++++++++++++++- src/util/test/string-parser.c | 136 +++++++++++++++++++++++++++++++++ 7 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 src/util/test/string-parser.c diff --git a/CHANGES b/CHANGES index d28e64d8b..80786cc0c 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,7 @@ Features: - Switch: Option to use built-in brightness sensor for Boktai - Ports: Ability to enable or disable all SGB features (closes mgba.io/i/1205) - Ports: Ability to crop SGB borders off screen (closes mgba.io/i/1204) + - Cheats: Add support for loading Libretro-style cht files Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba-util/string.h b/include/mgba-util/string.h index 7e9465719..fe5f48f59 100644 --- a/include/mgba-util/string.h +++ b/include/mgba-util/string.h @@ -39,6 +39,8 @@ const char* hex4(const char* line, uint8_t* out); void rtrim(char* string); +ssize_t parseQuotedString(const char* unparsed, ssize_t unparsedLen, char* parsed, ssize_t parsedLen); + CXX_GUARD_END #endif diff --git a/include/mgba/core/cheats.h b/include/mgba/core/cheats.h index 32c7cad42..dbc94199f 100644 --- a/include/mgba/core/cheats.h +++ b/include/mgba/core/cheats.h @@ -100,6 +100,8 @@ void mCheatRemoveSet(struct mCheatDevice*, struct mCheatSet*); bool mCheatParseFile(struct mCheatDevice*, struct VFile*); bool mCheatSaveFile(struct mCheatDevice*, struct VFile*); +bool mCheatParseLibretroFile(struct mCheatDevice*, struct VFile*); + #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 void mCheatAutosave(struct mCheatDevice*); #endif diff --git a/src/core/cheats.c b/src/core/cheats.c index 464ebfc39..92b6aa778 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -9,7 +9,8 @@ #include #include -#define MAX_LINE_LENGTH 128 +#define MAX_LINE_LENGTH 512 +#define MAX_CHEATS 1000 const uint32_t M_CHEAT_DEVICE_ID = 0xABADC0DE; @@ -191,6 +192,12 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { break; default: if (!set) { + if (strncmp(cheat, "cheats = ", 9) == 0) { + // This is in libretro format, switch over to that parser + vf->seek(vf, 0, SEEK_SET); + StringListDeinit(&directives); + return mCheatParseLibretroFile(device, vf); + } set = device->createSet(device, NULL); set->enabled = !nextDisabled; nextDisabled = false; @@ -211,6 +218,112 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { return true; } +bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { + char cheat[MAX_LINE_LENGTH]; + char parsed[MAX_LINE_LENGTH]; + struct mCheatSet* set = NULL; + unsigned long i = 0; + bool startFound = false; + + while (true) { + ssize_t bytesRead = vf->readline(vf, cheat, sizeof(cheat)); + if (bytesRead == 0) { + break; + } + if (bytesRead < 0) { + return false; + } + if (cheat[0] == '\n') { + continue; + } + if (strncmp(cheat, "cheat", 5) != 0) { + return false; + } + char* underscore = strchr(&cheat[5], '_'); + if (!underscore) { + if (!startFound && cheat[5] == 's') { + startFound = true; + char* eq = strchr(&cheat[6], '='); + if (!eq) { + return false; + } + ++eq; + while (isspace((int) eq[0])) { + if (eq[0] == '\0') { + return false; + } + ++eq; + } + + char* end; + unsigned long nCheats = strtoul(eq, &end, 10); + if (end[0] != '\0' && !isspace(end[0])) { + return false; + } + + if (nCheats > MAX_CHEATS) { + return false; + } + + while (nCheats > mCheatSetsSize(&device->cheats)) { + struct mCheatSet* newSet = device->createSet(device, NULL); + if (!newSet) { + return false; + } + mCheatAddSet(device, newSet); + } + continue; + } + return false; + } + char* underscore2; + i = strtoul(&cheat[5], &underscore2, 10); + if (underscore2 != underscore) { + return false; + } + ++underscore; + char* eq = strchr(underscore, '='); + if (!eq) { + return false; + } + ++eq; + while (isspace((int) eq[0])) { + if (eq[0] == '\0') { + return false; + } + ++eq; + } + + if (i >= mCheatSetsSize(&device->cheats)) { + return false; + } + set = *mCheatSetsGetPointer(&device->cheats, i); + + if (strncmp(underscore, "desc", 4) == 0) { + parseQuotedString(eq, strlen(eq), parsed, sizeof(parsed)); + mCheatSetRename(set, parsed); + } else if (strncmp(underscore, "enable", 6) == 0) { + set->enabled = strncmp(eq, "true\n", 5) == 0; + } else if (strncmp(underscore, "code", 4) == 0) { + parseQuotedString(eq, strlen(eq), parsed, sizeof(parsed)); + char* cur = parsed; + char* next; + while ((next = strchr(cur, '+'))) { + next[0] = '\0'; + mCheatAddLine(set, cur, 0); + cur = &next[1]; + } + mCheatAddLine(set, cur, 0); + + for (++i; i < mCheatSetsSize(&device->cheats); ++i) { + struct mCheatSet* newSet = *mCheatSetsGetPointer(&device->cheats, i); + newSet->copyProperties(newSet, set); + } + } + } + return true; +} + bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { static const char lineStart[3] = "# "; static const char lineEnd = '\n'; diff --git a/src/platform/qt/CheatsView.cpp b/src/platform/qt/CheatsView.cpp index 315edcae1..4a631c932 100644 --- a/src/platform/qt/CheatsView.cpp +++ b/src/platform/qt/CheatsView.cpp @@ -109,14 +109,14 @@ bool CheatsView::eventFilter(QObject* object, QEvent* event) { } void CheatsView::load() { - QString filename = GBAApp::app()->getOpenFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats *.cht *.clt)"))); + QString filename = GBAApp::app()->getOpenFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats *.cht)"))); if (!filename.isEmpty()) { m_model.loadFile(filename); } } void CheatsView::save() { - QString filename = GBAApp::app()->getSaveFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats *.cht *.clt)"))); + QString filename = GBAApp::app()->getSaveFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats)"))); if (!filename.isEmpty()) { m_model.saveFile(filename); } diff --git a/src/util/string.c b/src/util/string.c index cef28e5cd..f3835f04b 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015 Jeffrey Pfau +/* Copyright (c) 2013-2019 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 @@ -373,3 +373,64 @@ void rtrim(char* string) { --end; } } + +ssize_t parseQuotedString(const char* unparsed, ssize_t unparsedLen, char* parsed, ssize_t parsedLen) { + memset(parsed, 0, parsedLen); + bool escaped = false; + char start = '\0'; + ssize_t len = 0; + ssize_t i; + for (i = 0; i < unparsedLen && len < parsedLen; ++i) { + if (i == 0) { + switch (unparsed[0]) { + case '"': + case '\'': + start = unparsed[0]; + break; + default: + return -1; + } + continue; + } + if (escaped) { + switch (unparsed[i]) { + case 'n': + parsed[len] = '\n'; + break; + case 'r': + parsed[len] = '\r'; + break; + case '\\': + parsed[len] = '\\'; + break; + case '\'': + parsed[len] = '\''; + break; + case '"': + parsed[len] = '"'; + break; + default: + return -1; + } + escaped = false; + ++len; + continue; + } + if (unparsed[i] == start) { + return len; + } + switch (unparsed[i]) { + case '\\': + escaped = true; + break; + case '\n': + case '\r': + return len; + default: + parsed[len] = unparsed[i]; + ++len; + break; + } + } + return -1; +} \ No newline at end of file diff --git a/src/util/test/string-parser.c b/src/util/test/string-parser.c new file mode 100644 index 000000000..38650d0c9 --- /dev/null +++ b/src/util/test/string-parser.c @@ -0,0 +1,136 @@ +/* Copyright (c) 2013-2019 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 "util/test/suite.h" + +#include + +M_TEST_DEFINE(nullString) { + const char* unparsed = ""; + char parsed[2]; + assert_int_equal(parseQuotedString(unparsed, 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(emptyString2) { + const char* unparsed = "\"\""; + char parsed[2]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), 0); +} + +M_TEST_DEFINE(emptyString) { + const char* unparsed = "''"; + char parsed[2]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), 0); +} + +M_TEST_DEFINE(plainString) { + const char* unparsed = "\"plain\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), strlen("plain")); + assert_string_equal(parsed, "plain"); +} + +M_TEST_DEFINE(plainString2) { + const char* unparsed = "\"plain\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed), parsed, sizeof(parsed)), strlen("plain")); + assert_string_equal(parsed, "plain"); +} + +M_TEST_DEFINE(trailingString) { + const char* unparsed = "\"trailing\"T"; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), strlen("trailing")); + assert_string_equal(parsed, "trailing"); +} + +M_TEST_DEFINE(leadingString) { + const char* unparsed = "L\"leading\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(backslashString) { + const char* unparsed = "\"back\\\\slash\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), strlen("back\\slash")); + assert_string_equal(parsed, "back\\slash"); +} + +M_TEST_DEFINE(doubleBackslashString) { + const char* unparsed = "\"back\\\\\\\\slash\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), strlen("back\\\\slash")); + assert_string_equal(parsed, "back\\\\slash"); +} + +M_TEST_DEFINE(escapeCharsString) { + const char* unparsed = "\"\\\"\\'\\n\\r\\\\\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), strlen("\"'\n\r\\")); + assert_string_equal(parsed, "\"'\n\r\\"); +} + +M_TEST_DEFINE(invalidEscapeCharString) { + const char* unparsed = "\"\\z\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(overflowString) { + const char* unparsed = "\"longstring\""; + char parsed[4]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(unclosedString) { + const char* unparsed = "\"forever"; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(unclosedString2) { + const char* unparsed = "\"forever"; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, 4, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(unclosedBackslashString) { + const char* unparsed = "\"backslash\\"; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed), parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(unclosedBackslashString2) { + const char* unparsed = "\"backslash\\"; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), -1); +} + +M_TEST_DEFINE(highCharacterString) { + const char* unparsed = "\"\200\""; + char parsed[32]; + assert_int_equal(parseQuotedString(unparsed, strlen(unparsed) + 1, parsed, sizeof(parsed)), 1); + assert_string_equal(parsed, "\200"); +} + +M_TEST_SUITE_DEFINE(StringParser, + cmocka_unit_test(nullString), + cmocka_unit_test(emptyString), + cmocka_unit_test(emptyString2), + cmocka_unit_test(plainString), + cmocka_unit_test(plainString2), + cmocka_unit_test(leadingString), + cmocka_unit_test(trailingString), + cmocka_unit_test(backslashString), + cmocka_unit_test(doubleBackslashString), + cmocka_unit_test(escapeCharsString), + cmocka_unit_test(invalidEscapeCharString), + cmocka_unit_test(overflowString), + cmocka_unit_test(unclosedString), + cmocka_unit_test(unclosedString2), + cmocka_unit_test(unclosedBackslashString), + cmocka_unit_test(unclosedBackslashString2), + cmocka_unit_test(highCharacterString)) From f3ec9db9d7c8988fad58cbd650697aa87f3e29fb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 13:03:53 -0700 Subject: [PATCH 413/429] Core: Fix crash when exiting game with cheats loaded --- CHANGES | 1 + src/core/cheats.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 80786cc0c..b44079e20 100644 --- a/CHANGES +++ b/CHANGES @@ -33,6 +33,7 @@ Other fixes: - Core: Fix crashes if core directories aren't set - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) - GB SIO: Fix lockstep failing games aren't reloaded + - Core: Fix crash when exiting game with cheats loaded Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/core/cheats.c b/src/core/cheats.c index 92b6aa778..d8b6fa7b0 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -83,11 +83,11 @@ void mCheatSetInit(struct mCheatSet* set, const char* name) { } void mCheatSetDeinit(struct mCheatSet* set) { - mCheatListDeinit(&set->list); size_t i; for (i = 0; i < StringListSize(&set->lines); ++i) { free(*StringListGetPointer(&set->lines, i)); } + mCheatListDeinit(&set->list); if (set->name) { free(set->name); } From 81098060aa14903062555bdd3d7a2ec50733344f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 13:04:34 -0700 Subject: [PATCH 414/429] GBA Cheats: Fix PARv3 Thumb hooks --- CHANGES | 1 + src/gba/cheats/parv3.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index b44079e20..c452e9fb7 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Other fixes: - Qt: Fix menu bar staying hidden in full screen (fixes mgba.io/i/317) - GB SIO: Fix lockstep failing games aren't reloaded - Core: Fix crash when exiting game with cheats loaded + - GBA Cheats: Fix PARv3 Thumb hooks Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gba/cheats/parv3.c b/src/gba/cheats/parv3.c index 0d74aaed4..4f3a89310 100644 --- a/src/gba/cheats/parv3.c +++ b/src/gba/cheats/parv3.c @@ -284,7 +284,7 @@ bool GBACheatAddProActionReplayRaw(struct GBACheatSet* cheats, uint32_t op1, uin return false; } cheats->hook = malloc(sizeof(*cheats->hook)); - cheats->hook->address = BASE_CART0 | (op1 & (SIZE_CART0 - 1)); + cheats->hook->address = BASE_CART0 | (op1 & (SIZE_CART0 - 2)); cheats->hook->mode = MODE_THUMB; cheats->hook->refs = 1; cheats->hook->reentries = 0; From 9f5adf2dccff8e3a7a6703911fcc1a03bce4f616 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Sun, 23 Jun 2019 03:06:32 +0200 Subject: [PATCH 415/429] Qt: Simplified search of Qt5 modules --- 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 49be1cda7..6df091760 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -22,10 +22,7 @@ endif() set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) -find_package(Qt5Multimedia) -find_package(Qt5Network) -find_package(Qt5OpenGL) -find_package(Qt5Widgets) +find_package(Qt5 COMPONENTS Core Widgets OpenGL Network Multimedia) if(NOT BUILD_GL AND NOT BUILD_GLES2) message(WARNING "OpenGL is recommended to build the Qt port") From 0a06f4dad025ed321de45acfb16d7a67c3b83a87 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Sun, 23 Jun 2019 03:35:23 +0200 Subject: [PATCH 416/429] All: Added exports for qt --- include/mgba/core/log.h | 3 ++- include/mgba/gba/interface.h | 3 ++- include/mgba/internal/gb/io.h | 3 ++- include/mgba/internal/gba/io.h | 2 +- include/mgba/internal/gba/video.h | 3 ++- src/gb/io.c | 2 +- src/gba/hardware.c | 2 +- src/gba/video.c | 2 +- 8 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/mgba/core/log.h b/include/mgba/core/log.h index d7491f4cf..71614cf2c 100644 --- a/include/mgba/core/log.h +++ b/include/mgba/core/log.h @@ -7,6 +7,7 @@ #define M_LOG_H #include +#include CXX_GUARD_START @@ -65,7 +66,7 @@ void mLog(int category, enum mLogLevel level, const char* format, ...); _mLOG_CAT_ ## CATEGORY = mLogGenerateCategory(NAME, ID); \ } -mLOG_DECLARE_CATEGORY(STATUS) +MGBA_EXPORT mLOG_DECLARE_CATEGORY(STATUS) CXX_GUARD_END diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 930faa925..730d651e2 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -7,6 +7,7 @@ #define GBA_INTERFACE_H #include +#include CXX_GUARD_START @@ -39,7 +40,7 @@ struct GBAAudio; struct GBASIO; struct GBAVideoRenderer; -extern const int GBA_LUX_LEVELS[10]; +extern MGBA_EXPORT const int GBA_LUX_LEVELS[10]; enum { mPERIPH_GBA_LUMINANCE = 0x1000, diff --git a/include/mgba/internal/gb/io.h b/include/mgba/internal/gb/io.h index 15172ff0f..b28a7cc01 100644 --- a/include/mgba/internal/gb/io.h +++ b/include/mgba/internal/gb/io.h @@ -7,6 +7,7 @@ #define GB_IO_H #include +#include CXX_GUARD_START @@ -108,7 +109,7 @@ enum GBIORegisters { REG_MAX = 0x100 }; -extern const char* const GBIORegisterNames[]; +extern MGBA_EXPORT const char* const GBIORegisterNames[]; struct GB; void GBIOInit(struct GB* gb); diff --git a/include/mgba/internal/gba/io.h b/include/mgba/internal/gba/io.h index 959babf05..9875061f3 100644 --- a/include/mgba/internal/gba/io.h +++ b/include/mgba/internal/gba/io.h @@ -161,7 +161,7 @@ enum GBAIORegisters { mLOG_DECLARE_CATEGORY(GBA_IO); -extern const char* const GBAIORegisterNames[]; +extern MGBA_EXPORT const char* const GBAIORegisterNames[]; struct GBA; void GBAIOInit(struct GBA* gba); diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index ea65699aa..4fe4d111e 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -7,6 +7,7 @@ #define GBA_VIDEO_H #include +#include CXX_GUARD_START @@ -228,7 +229,7 @@ struct GBASerializedState; void GBAVideoSerialize(const struct GBAVideo* video, struct GBASerializedState* state); void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState* state); -extern const int GBAVideoObjSizes[16][2]; +extern MGBA_EXPORT const int GBAVideoObjSizes[16][2]; CXX_GUARD_END diff --git a/src/gb/io.c b/src/gb/io.c index c7b08dd03..e008dbb26 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -11,7 +11,7 @@ mLOG_DEFINE_CATEGORY(GB_IO, "GB I/O", "gb.io"); -const char* const GBIORegisterNames[] = { +MGBA_EXPORT const char* const GBIORegisterNames[] = { [REG_JOYP] = "JOYP", [REG_SB] = "SB", [REG_SC] = "SC", diff --git a/src/gba/hardware.c b/src/gba/hardware.c index dedbd9af3..593386bef 100644 --- a/src/gba/hardware.c +++ b/src/gba/hardware.c @@ -13,7 +13,7 @@ mLOG_DEFINE_CATEGORY(GBA_HW, "GBA Pak Hardware", "gba.hardware"); -const int GBA_LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 }; +MGBA_EXPORT const int GBA_LUX_LEVELS[10] = { 5, 11, 18, 27, 42, 62, 84, 109, 139, 183 }; static void _readPins(struct GBACartridgeHardware* hw); static void _outputPins(struct GBACartridgeHardware* hw, unsigned pins); diff --git a/src/gba/video.c b/src/gba/video.c index 7660e0b04..a05d6a7f0 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -33,7 +33,7 @@ static void GBAVideoDummyRendererPutPixels(struct GBAVideoRenderer* renderer, si static void _startHblank(struct mTiming*, void* context, uint32_t cyclesLate); static void _startHdraw(struct mTiming*, void* context, uint32_t cyclesLate); -const int GBAVideoObjSizes[16][2] = { +MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 8, 8 }, { 16, 16 }, { 32, 32 }, From f98da2ab3ff0a8c7171c256ead46f819536618e2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 22:02:10 -0700 Subject: [PATCH 417/429] Qt: Fix disabling audio channels --- src/platform/qt/Window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index d8b64b5cb..19ff6ffab 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -787,7 +787,7 @@ void Window::gameStarted() { if (nAudio) { for (size_t i = 0; i < nAudio; ++i) { Action* action = m_actions.addBooleanAction(audioChannels[i].visibleName, QString("audioChannel.%1").arg(audioChannels[i].internalName), [this, audioChannels, i](bool enable) { - m_controller->thread()->core->enableVideoLayer(m_controller->thread()->core, audioChannels[i].id, enable); + m_controller->thread()->core->enableAudioChannel(m_controller->thread()->core, audioChannels[i].id, enable); }, "audioChannels"); action->setActive(true); } From 68fc62073d2d6705613439c81d278c3070f1fa96 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 23:17:58 -0700 Subject: [PATCH 418/429] GB Audio: Only reset channel 3 sample in DMG mode --- CHANGES | 1 + src/gb/audio.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c452e9fb7..0fed364fe 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Emulation fixes: - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) - GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432) - GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430) + - GB Audio: Only reset channel 3 sample in DMG mode Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/audio.c b/src/gb/audio.c index 08ba1fa9e..01e66802b 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -329,7 +329,9 @@ void GBAudioWriteNR34(struct GBAudio* audio, uint8_t value) { } } audio->ch3.window = 0; - audio->ch3.sample = 0; + if (audio->style == GB_AUDIO_DMG) { + audio->ch3.sample = 0; + } } mTimingDeschedule(audio->timing, &audio->ch3Fade); mTimingDeschedule(audio->timing, &audio->ch3Event); From 6d53c44422fad289cef0ed67bbebb25433c4e8bf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 22 Jun 2019 23:15:43 -0700 Subject: [PATCH 419/429] GB Audio: Sample inactive channels (fixes #1455, fixes #1456) --- CHANGES | 1 + src/gb/audio.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 0fed364fe..5b4a414a9 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Emulation fixes: - GBA Video: Fix wrapped sprite mosaic clamping (fixes mgba.io/i/1432) - GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430) - GB Audio: Only reset channel 3 sample in DMG mode + - GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/audio.c b/src/gb/audio.c index 01e66802b..633739c00 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -598,7 +598,7 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { int sampleLeft = dcOffset; int sampleRight = dcOffset; - if (audio->playingCh1 && !audio->forceDisableCh[0]) { + if (!audio->forceDisableCh[0]) { if (audio->ch1Left) { sampleLeft += audio->ch1.sample; } @@ -608,7 +608,7 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { } } - if (audio->playingCh2 && !audio->forceDisableCh[1]) { + if (!audio->forceDisableCh[1]) { if (audio->ch2Left) { sampleLeft += audio->ch2.sample; } @@ -618,7 +618,7 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { } } - if (audio->playingCh3 && !audio->forceDisableCh[2]) { + if (!audio->forceDisableCh[2]) { if (audio->ch3Left) { sampleLeft += audio->ch3.sample; } @@ -628,7 +628,7 @@ void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) { } } - if (audio->playingCh4 && !audio->forceDisableCh[3]) { + if (!audio->forceDisableCh[3]) { int8_t sample = _coalesceNoiseChannel(&audio->ch4); if (audio->ch4Left) { sampleLeft += sample; From 46f8dffcd7a48c6f9c385e2d4d5645cdf3a046de Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 23 Jun 2019 12:42:38 -0700 Subject: [PATCH 420/429] CMake: Move export header generation (fixes #1464) --- CMakeLists.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e87a69dce..0adb3c57d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -851,10 +851,6 @@ if(NOT SKIP_LIBRARY) list(APPEND OS_DEFINES BUILD_STATIC) endif() - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) - include(GenerateExportHeader) - generate_export_header(${BINARY_NAME} BASE_NAME mgba STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) - target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) @@ -999,8 +995,11 @@ if(BUILD_EXAMPLE) endif() endif() +include(GenerateExportHeader) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/core/flags.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h) +generate_export_header(${BINARY_NAME} BASE_NAME ${BINARY_NAME} STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba-util DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT ${BINARY_NAME}-dev) From e40617f8505102c1b62953c8882b8997ae93cffe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 23 Jun 2019 12:46:14 -0700 Subject: [PATCH 421/429] CMake: Libepoxy is only needed on Windows if building the library or frontends --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0adb3c57d..3bb4585d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -703,7 +703,7 @@ elseif(BUILD_GLES2) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libgles2") endif() -if (WIN32 AND NOT USE_EPOXY) +if(WIN32 AND NOT SKIP_LIBRARY AND NOT USE_EPOXY) message(FATAL_ERROR "Windows requires epoxy module!") endif() From fb72b70505dd649af912c4bbf74ad4ff06d27eb8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 08:30:28 -0700 Subject: [PATCH 422/429] All: Don't require dllexports.h on standalone builds (really fixes #1464) --- CMakeLists.txt | 11 ++++++----- include/mgba-util/common.h | 7 +++++++ include/mgba/core/log.h | 1 - include/mgba/core/version.h | 4 ++++ include/mgba/gba/interface.h | 1 - include/mgba/internal/gb/io.h | 1 - include/mgba/internal/gba/input.h | 1 - include/mgba/internal/gba/video.h | 1 - 8 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bb4585d8..6ee4c2a70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -855,6 +855,10 @@ if(NOT SKIP_LIBRARY) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) + include(GenerateExportHeader) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) + generate_export_header(${BINARY_NAME} BASE_NAME ${BINARY_NAME} STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) + target_link_libraries(${BINARY_NAME} ${DEBUGGER_LIB} ${DEPENDENCY_LIB} ${OS_LIB}) install(TARGETS ${BINARY_NAME} LIBRARY DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME} NAMELINK_SKIP ARCHIVE DESTINATION ${LIBDIR} RUNTIME DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME}) if(UNIX AND NOT APPLE AND NOT HAIKU) @@ -906,7 +910,7 @@ if(BUILD_LIBRETRO) file(GLOB RETRO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/libretro/*.c) add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC}) add_dependencies(${BINARY_NAME}_libretro version-info) - set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") + set_target_properties(${BINARY_NAME}_libretro PROPERTIES PREFIX "" COMPILE_DEFINITIONS "__LIBRETRO__;COLOR_16_BIT;COLOR_5_6_5;DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) if(MSVC) install(TARGETS ${BINARY_NAME}_libretro RUNTIME DESTINATION ${LIBRETRO_LIBDIR} COMPONENT ${BINARY_NAME}_libretro) @@ -925,7 +929,7 @@ if(BUILD_OPENEMU) BUNDLE TRUE BUNDLE_EXTENSION oecoreplugin OUTPUT_NAME ${PROJECT_NAME} - COMPILE_DEFINITIONS "DISABLE_THREADING;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=1") + COMPILE_DEFINITIONS "DISABLE_THREADING;MGBA_STANDALONE;${OS_DEFINES};${FUNCTION_DEFINES};MINIMAL_CORE=1") target_link_libraries(${BINARY_NAME}-openemu ${OS_LIB} ${FOUNDATION} ${OPENEMUBASE}) install(TARGETS ${BINARY_NAME}-openemu LIBRARY DESTINATION ${OE_LIBDIR} COMPONENT ${BINARY_NAME}.oecoreplugin NAMELINK_SKIP) endif() @@ -995,11 +999,8 @@ if(BUILD_EXAMPLE) endif() endif() -include(GenerateExportHeader) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/core/flags.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h) -generate_export_header(${BINARY_NAME} BASE_NAME ${BINARY_NAME} STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba-util DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT ${BINARY_NAME}-dev FILES_MATCHING PATTERN "*.h") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT ${BINARY_NAME}-dev) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index e268dbad5..1b31bfccb 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -65,6 +65,13 @@ typedef intptr_t ssize_t; #include #endif +#ifndef MGBA_STANDALONE +#include +#else +#define MGBA_EXPORT +#define MGBA_NO_EXPORT +#endif + #ifndef SSIZE_MAX #define SSIZE_MAX ((ssize_t) (SIZE_MAX >> 1)) #endif diff --git a/include/mgba/core/log.h b/include/mgba/core/log.h index 71614cf2c..e2ac55e4b 100644 --- a/include/mgba/core/log.h +++ b/include/mgba/core/log.h @@ -7,7 +7,6 @@ #define M_LOG_H #include -#include CXX_GUARD_START diff --git a/include/mgba/core/version.h b/include/mgba/core/version.h index b261ab6d3..7749723c1 100644 --- a/include/mgba/core/version.h +++ b/include/mgba/core/version.h @@ -10,7 +10,11 @@ extern "C" { #endif +#ifdef MGBA_STANDALONE +#define MGBA_EXPORT +#else #include +#endif extern MGBA_EXPORT const char* const gitCommit; extern MGBA_EXPORT const char* const gitCommitShort; diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index 730d651e2..33c7a8e88 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -7,7 +7,6 @@ #define GBA_INTERFACE_H #include -#include CXX_GUARD_START diff --git a/include/mgba/internal/gb/io.h b/include/mgba/internal/gb/io.h index b28a7cc01..1df09da2f 100644 --- a/include/mgba/internal/gb/io.h +++ b/include/mgba/internal/gb/io.h @@ -7,7 +7,6 @@ #define GB_IO_H #include -#include CXX_GUARD_START diff --git a/include/mgba/internal/gba/input.h b/include/mgba/internal/gba/input.h index 179e935f4..cdfde6e1f 100644 --- a/include/mgba/internal/gba/input.h +++ b/include/mgba/internal/gba/input.h @@ -7,7 +7,6 @@ #define GBA_INPUT_H #include -#include CXX_GUARD_START diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 4fe4d111e..77ff3cf0e 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -7,7 +7,6 @@ #define GBA_VIDEO_H #include -#include CXX_GUARD_START From 06d407f130ca454bc23668051a7b73a84b9c1dd7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 09:05:38 -0700 Subject: [PATCH 423/429] GB Video: Increment BCPS/OCPS even in mode 3 (fixes #1462) --- CHANGES | 1 + src/gb/io.c | 4 ++-- src/gb/video.c | 32 ++++++++++++++++++-------------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 5b4a414a9..3a5e1033b 100644 --- a/CHANGES +++ b/CHANGES @@ -27,6 +27,7 @@ Emulation fixes: - GBA Memory: Fix STM to VRAM (fixes mgba.io/i/1430) - GB Audio: Only reset channel 3 sample in DMG mode - GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456) + - GB Video: Increment BCPS/OCPS even in mode 3 (fixes mgba.io/i/1462) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/io.c b/src/gb/io.c index e008dbb26..2c4b9b4b3 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -499,8 +499,8 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { case REG_BCPD: if (gb->video.mode != 3) { GBVideoProcessDots(&gb->video, 0); - GBVideoWritePalette(&gb->video, address, value); } + GBVideoWritePalette(&gb->video, address, value); return; case REG_OCPS: gb->video.ocpIndex = value & 0x3F; @@ -510,8 +510,8 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { case REG_OCPD: if (gb->video.mode != 3) { GBVideoProcessDots(&gb->video, 0); - GBVideoWritePalette(&gb->video, address, value); } + GBVideoWritePalette(&gb->video, address, value); return; case REG_SVBK: GBMemorySwitchWramBank(&gb->memory, value); diff --git a/src/gb/video.c b/src/gb/video.c index cfe80f913..020889ca9 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -505,14 +505,16 @@ void GBVideoWritePalette(struct GBVideo* video, uint16_t address, uint8_t value) } else { switch (address) { case REG_BCPD: - if (video->bcpIndex & 1) { - video->palette[video->bcpIndex >> 1] &= 0x00FF; - video->palette[video->bcpIndex >> 1] |= value << 8; - } else { - video->palette[video->bcpIndex >> 1] &= 0xFF00; - video->palette[video->bcpIndex >> 1] |= value; + if (video->mode != 3) { + if (video->bcpIndex & 1) { + video->palette[video->bcpIndex >> 1] &= 0x00FF; + video->palette[video->bcpIndex >> 1] |= value << 8; + } else { + video->palette[video->bcpIndex >> 1] &= 0xFF00; + video->palette[video->bcpIndex >> 1] |= value; + } + video->renderer->writePalette(video->renderer, video->bcpIndex >> 1, video->palette[video->bcpIndex >> 1]); } - video->renderer->writePalette(video->renderer, video->bcpIndex >> 1, video->palette[video->bcpIndex >> 1]); if (video->bcpIncrement) { ++video->bcpIndex; video->bcpIndex &= 0x3F; @@ -522,14 +524,16 @@ void GBVideoWritePalette(struct GBVideo* video, uint16_t address, uint8_t value) video->p->memory.io[REG_BCPD] = video->palette[video->bcpIndex >> 1] >> (8 * (video->bcpIndex & 1)); break; case REG_OCPD: - if (video->ocpIndex & 1) { - video->palette[8 * 4 + (video->ocpIndex >> 1)] &= 0x00FF; - video->palette[8 * 4 + (video->ocpIndex >> 1)] |= value << 8; - } else { - video->palette[8 * 4 + (video->ocpIndex >> 1)] &= 0xFF00; - video->palette[8 * 4 + (video->ocpIndex >> 1)] |= value; + if (video->mode != 3) { + if (video->ocpIndex & 1) { + video->palette[8 * 4 + (video->ocpIndex >> 1)] &= 0x00FF; + video->palette[8 * 4 + (video->ocpIndex >> 1)] |= value << 8; + } else { + video->palette[8 * 4 + (video->ocpIndex >> 1)] &= 0xFF00; + video->palette[8 * 4 + (video->ocpIndex >> 1)] |= value; + } + video->renderer->writePalette(video->renderer, 8 * 4 + (video->ocpIndex >> 1), video->palette[8 * 4 + (video->ocpIndex >> 1)]); } - video->renderer->writePalette(video->renderer, 8 * 4 + (video->ocpIndex >> 1), video->palette[8 * 4 + (video->ocpIndex >> 1)]); if (video->ocpIncrement) { ++video->ocpIndex; video->ocpIndex &= 0x3F; From 51e70703023773fbe37a527c13c3df9f9fc05c69 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 09:15:35 -0700 Subject: [PATCH 424/429] GB Audio: Deschedule channel 3 when disabled (fixes #1463) --- CHANGES | 1 + src/gb/audio.c | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 3a5e1033b..a2b844363 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Emulation fixes: - GB Audio: Only reset channel 3 sample in DMG mode - GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456) - GB Video: Increment BCPS/OCPS even in mode 3 (fixes mgba.io/i/1462) + - GB Audio: Deschedule channel 3 when disabled (fixes mgba.io/i/1463) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/audio.c b/src/gb/audio.c index 633739c00..b4c745404 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -279,6 +279,7 @@ void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR30(struct GBAudio* audio, uint8_t value) { audio->ch3.enable = GBAudioRegisterBankGetEnable(value); if (!audio->ch3.enable) { + mTimingDeschedule(audio->timing, &audio->ch3Event); audio->playingCh3 = false; *audio->nr52 &= ~0x0004; } From ba547b26d1c645b6f62739f01d7194794cca6949 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 13:15:37 -0700 Subject: [PATCH 425/429] mGUI: Fix crash if last loaded ROM directory disappears (fixes #1466) --- CHANGES | 1 + src/feature/gui/gui-runner.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index a2b844363..4aad6498f 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,7 @@ Other fixes: - GB SIO: Fix lockstep failing games aren't reloaded - Core: Fix crash when exiting game with cheats loaded - GBA Cheats: Fix PARv3 Thumb hooks + - mGUI: Fix crash if last loaded ROM directory disappears (fixes mgba.io/i/1466) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 038d30a3c..af6584ee0 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -212,8 +212,12 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) { const char* lastPath = mCoreConfigGetValue(&runner->config, "lastDirectory"); if (lastPath) { - strncpy(runner->params.currentPath, lastPath, PATH_MAX - 1); - runner->params.currentPath[PATH_MAX - 1] = '\0'; + struct VDir* dir = VDirOpen(lastPath); + if (dir) { + dir->close(dir); + strncpy(runner->params.currentPath, lastPath, PATH_MAX - 1); + runner->params.currentPath[PATH_MAX - 1] = '\0'; + } } #ifndef DISABLE_THREADING From aead90a2c14949fbf063a8ef210867a949f9e437 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 14:02:56 -0700 Subject: [PATCH 426/429] Windows: Fix ATOMIC_*_PTR in MSVC --- include/mgba-util/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 1b31bfccb..f8b705e11 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -102,8 +102,8 @@ typedef intptr_t ssize_t; #define ATOMIC_OR(DST, OP) InterlockedOrRelease(&DST, OP) #define ATOMIC_AND(DST, OP) InterlockedAndRelease(&DST, OP) #define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED) -#define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(DST, SRC) -#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(SRC, 0, 0) +#define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(&DST, SRC) +#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(&SRC, 0, 0) #else // TODO #define ATOMIC_STORE(DST, SRC) DST = SRC From 43b6004cea5aacf62a61d92ef190f3b3a24911d0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2019 19:01:20 -0700 Subject: [PATCH 427/429] Switch: Support file associations --- CHANGES | 1 + src/platform/switch/CMakeLists.txt | 3 ++- src/platform/switch/fileassoc.cfg.in | 18 ++++++++++++++++++ src/platform/switch/main.c | 24 ++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/platform/switch/fileassoc.cfg.in diff --git a/CHANGES b/CHANGES index 4aad6498f..d47dfe64f 100644 --- a/CHANGES +++ b/CHANGES @@ -64,6 +64,7 @@ Misc: - mGUI: Remember name and position of last loaded game - Core: Create game-related paths if they don't exist (fixes mgba.io/i/1446) - Qt: Add option to pause on minimizing window (closes mgba.io/i/1379) + - Switch: Support file associations 0.7.2: (2019-05-25) Emulation fixes: diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 6666b8a01..2d98ad0a5 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -42,9 +42,10 @@ add_custom_command(OUTPUT control.nacp add_custom_command(OUTPUT romfs.bin COMMAND ${CMAKE_COMMAND} -E make_directory romfs COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/res/font-new.png" romfs/ + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/fileassoc.cfg.in" romfs/ COMMAND ${BUILD_ROMFS} romfs romfs.bin COMMAND ${CMAKE_COMMAND} -E remove_directory romfs - DEPENDS "${CMAKE_SOURCE_DIR}/res/font-new.png") + DEPENDS "${CMAKE_SOURCE_DIR}/res/font-new.png" "${CMAKE_CURRENT_SOURCE_DIR}/fileassoc.cfg.in") add_custom_target(${BINARY_NAME}.nro ALL ${ELF2NRO} ${BINARY_NAME}.elf ${BINARY_NAME}.nro --romfs=romfs.bin --nacp=control.nacp --icon="${CMAKE_CURRENT_SOURCE_DIR}/icon.jpg" diff --git a/src/platform/switch/fileassoc.cfg.in b/src/platform/switch/fileassoc.cfg.in new file mode 100644 index 000000000..cbf5be1a4 --- /dev/null +++ b/src/platform/switch/fileassoc.cfg.in @@ -0,0 +1,18 @@ +fileassoc={ + app_path="%s"; + + targets=( + { + file_extension=".gba"; + }, + { + file_extension=".gb"; + }, + { + file_extension=".gbc"; + }, + { + file_extension=".sgb"; + } + ); +}; \ No newline at end of file diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index c0624423d..f87caf667 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -921,6 +922,29 @@ int main(int argc, char* argv[]) { audoutStartAudioOut(); + if (argc > 0) { + struct VFile* vf = VFileOpen("romfs:/fileassoc.cfg.in", O_RDONLY); + if (vf) { + size_t size = vf->size(vf); + const char* arg0 = strchr(argv[0], '/'); + char* buffer[2] = { + calloc(size + 1, 1), + malloc(size + strlen(arg0) + 1) + }; + vf->read(vf, buffer[0], vf->size(vf)); + vf->close(vf); + snprintf(buffer[1], size + strlen(arg0), buffer[0], arg0); + mkdir("sdmc:/config/nx-hbmenu/fileassoc", 0755); + vf = VFileOpen("sdmc:/config/nx-hbmenu/fileassoc/mgba.cfg", O_CREAT | O_TRUNC | O_WRONLY); + if (vf) { + vf->write(vf, buffer[1], strlen(buffer[1])); + vf->close(vf); + } + free(buffer[0]); + free(buffer[1]); + } + } + if (argc > 1) { size_t i; for (i = 0; runner.keySources[i].id; ++i) { From 417a749fecb8c991e7dd3ec28171fbad64378d53 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 26 Jun 2019 10:15:51 -0700 Subject: [PATCH 428/429] Libretro: Fix crash changing allowing opposing directions (backports libretro/mgba@2619aa) --- CHANGES | 1 + src/platform/libretro/libretro.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d47dfe64f..89f2cf58b 100644 --- a/CHANGES +++ b/CHANGES @@ -40,6 +40,7 @@ Other fixes: - Core: Fix crash when exiting game with cheats loaded - GBA Cheats: Fix PARv3 Thumb hooks - mGUI: Fix crash if last loaded ROM directory disappears (fixes mgba.io/i/1466) + - Libretro: Fix crash changing allowing opposing directions (hhromic) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 29dbc9033..badc917b0 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -297,7 +297,18 @@ void retro_run(void) { .value = 0 }; if (environCallback(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - ((struct GBA*) core->board)->allowOpposingDirections = strcmp(var.value, "yes") == 0; + struct GBA* gba = core->board; + struct GB* gb = core->board; + switch (core->platform(core)) { + case PLATFORM_GBA: + gba->allowOpposingDirections = strcmp(var.value, "yes") == 0; + break; + case PLATFORM_GB: + gb->allowOpposingDirections = strcmp(var.value, "yes") == 0; + break; + default: + break; + } } var.key = "mgba_frameskip"; From 042a77a932d2d2f2d7606df365c6ed8eb87b69f6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 26 Jun 2019 10:33:36 -0700 Subject: [PATCH 429/429] GB Audio: Deschedule channel 1 when disabled by sweep (fixes #1467) --- CHANGES | 1 + src/gb/audio.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 89f2cf58b..2b334801f 100644 --- a/CHANGES +++ b/CHANGES @@ -29,6 +29,7 @@ Emulation fixes: - GB Audio: Sample inactive channels (fixes mgba.io/i/1455, mgba.io/i/1456) - GB Video: Increment BCPS/OCPS even in mode 3 (fixes mgba.io/i/1462) - GB Audio: Deschedule channel 3 when disabled (fixes mgba.io/i/1463) + - GB Audio: Deschedule channel 1 when disabled by sweep (fixes mgba.io/i/1467) Other fixes: - Qt: Fix some Qt display driver race conditions - Core: Improved lockstep driver reliability (Le Hoang Quyen) diff --git a/src/gb/audio.c b/src/gb/audio.c index b4c745404..666ab42b8 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -513,6 +513,9 @@ void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) { audio->playingCh1 = _updateSweep(&audio->ch1, false); *audio->nr52 &= ~0x0001; *audio->nr52 |= audio->playingCh1; + if (!audio->playingCh1) { + mTimingDeschedule(audio->timing, &audio->ch1Event); + } } } // Fall through