From ee1a860ac4e944e8c450bf182baa5587621d926a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 04:57:19 -0700 Subject: [PATCH 001/148] SDL: Fix build on SDL 2.0.12 --- src/platform/sdl/sdl-events.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 383775636..cd34a7781 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -920,12 +920,14 @@ static const char* const buttonNamesXboxOne[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Share", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = { @@ -940,12 +942,14 @@ static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "R3", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L1", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R1", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = { @@ -960,12 +964,14 @@ static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Share", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = { From b5a2f62c88957217d4b0b1a18806b3f602947684 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 3 Apr 2024 04:59:04 -0700 Subject: [PATCH 002/148] SDL: Really fix the build this time --- src/platform/sdl/sdl-events.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index cd34a7781..08a369c73 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -899,12 +899,14 @@ static const char* const buttonNamesXbox360[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; #if SDL_VERSION_ATLEAST(2, 0, 12) @@ -986,12 +988,14 @@ static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = { [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS", [SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB", [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB", +#if SDL_VERSION_ATLEAST(2, 0, 14) [SDL_CONTROLLER_BUTTON_MISC1] = "Misc", [SDL_CONTROLLER_BUTTON_PADDLE1] = "P1", [SDL_CONTROLLER_BUTTON_PADDLE2] = "P2", [SDL_CONTROLLER_BUTTON_PADDLE3] = "P3", [SDL_CONTROLLER_BUTTON_PADDLE4] = "P4", [SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch", +#endif }; #endif From 104d746c1ead326f9499abe443c131f9bf701a98 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 00:28:58 -0700 Subject: [PATCH 003/148] Core: Fix some mutex ordering --- src/core/thread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/thread.c b/src/core/thread.c index 4b470777d..11465e232 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -433,13 +433,13 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { threadContext->run(threadContext); } } + MutexLock(&impl->stateMutex); } - while (impl->state < mTHREAD_SHUTDOWN) { - MutexLock(&impl->stateMutex); + if (impl->state < mTHREAD_SHUTDOWN) { impl->state = mTHREAD_SHUTDOWN; - MutexUnlock(&impl->stateMutex); } + MutexUnlock(&impl->stateMutex); if (core->opts.rewindEnable) { mCoreRewindContextDeinit(&impl->rewind); From 008a6f3f237bb7cb86b43386cc5c160e97053704 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 00:31:47 -0700 Subject: [PATCH 004/148] Scripting: Attempt to fix MSVC build --- include/mgba/script/macros.h | 4 ++-- include/mgba/script/types.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/mgba/script/macros.h b/include/mgba/script/macros.h index 7d2057d4e..70eed0af5 100644 --- a/include/mgba/script/macros.h +++ b/include/mgba/script/macros.h @@ -323,7 +323,7 @@ CXX_GUARD_START } \ #define _mSCRIPT_DECLARE_STRUCT_OVERLOADED_METHOD_BINDING(TYPE, NAME, T) \ - static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME[]; \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## TYPE ## _ ## NAME[mSCRIPT_OVERLOADS_MAX]; \ static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \ UNUSED(ctx); \ const struct mScriptFunctionOverload* overload = mScriptFunctionFindOverload(_mSTStructBindingOverloads_ ## TYPE ## _ ## NAME, &frame->arguments); \ @@ -468,7 +468,7 @@ CXX_GUARD_START #define mSCRIPT_DEFINE_DEFAULTS_END } #define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOADS(STRUCT, METHOD) \ - static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## STRUCT ## _ ## METHOD[] = { \ + static const struct mScriptFunctionOverload _mSTStructBindingOverloads_ ## STRUCT ## _ ## METHOD[mSCRIPT_OVERLOADS_MAX] = { \ #define mSCRIPT_DEFINE_STRUCT_METHOD_OVERLOAD(TYPE, FUNCTION) { \ .type = &_mSTStructBindingType_ ## TYPE ## _ ## FUNCTION, \ diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index 5770456e6..5b07abe3b 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -16,6 +16,7 @@ CXX_GUARD_START #define mSCRIPT_VALUE_UNREF -1 #define mSCRIPT_PARAMS_MAX 8 +#define mSCRIPT_OVERLOADS_MAX 8 #define mSCRIPT_VALUE_DOC_FUNCTION(NAME) (&_mScriptDoc_ ## NAME) From e61a324df28d250c67e6bec3f37ca6de1b9b119d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 4 Apr 2024 22:49:48 -0700 Subject: [PATCH 005/148] Core: More threading cleanup --- include/mgba/core/thread.h | 3 ++- src/core/thread.c | 42 +++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/mgba/core/thread.h b/include/mgba/core/thread.h index d3d8a9e92..9f2c229be 100644 --- a/include/mgba/core/thread.h +++ b/include/mgba/core/thread.h @@ -87,7 +87,8 @@ struct mCoreThreadInternal { int requested; Mutex stateMutex; - Condition stateCond; + Condition stateOnThreadCond; + Condition stateOffThreadCond; int interruptDepth; bool frameWasOn; diff --git a/src/core/thread.c b/src/core/thread.c index 11465e232..e0ace6240 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -44,12 +44,12 @@ static void _mCoreLog(struct mLogger* logger, int category, enum mLogLevel level static void _changeState(struct mCoreThreadInternal* threadContext, enum mCoreThreadState newState) { threadContext->state = newState; - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOffThreadCond); } static void _waitOnInterrupt(struct mCoreThreadInternal* threadContext) { while (threadContext->state == mTHREAD_INTERRUPTED || threadContext->state == mTHREAD_INTERRUPTING) { - ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); + ConditionWait(&threadContext->stateOnThreadCond, &threadContext->stateMutex); } } @@ -110,7 +110,7 @@ static void _wait(struct mCoreThreadInternal* threadContext) { #endif MutexLock(&threadContext->stateMutex); - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOnThreadCond); } static void _waitOnRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { @@ -140,7 +140,7 @@ static void _sendRequest(struct mCoreThreadInternal* threadContext, enum mCoreTh static void _cancelRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { threadContext->requested &= ~request; _pokeRequest(threadContext); - ConditionWake(&threadContext->stateCond); + ConditionWake(&threadContext->stateOffThreadCond); } void _frameStarted(void* context) { @@ -351,19 +351,18 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { while (impl->state >= mTHREAD_MIN_WAITING && impl->state < mTHREAD_EXITING) { if (impl->state == mTHREAD_INTERRUPTING) { - impl->state = mTHREAD_INTERRUPTED; - ConditionWake(&impl->stateCond); + _changeState(impl, mTHREAD_INTERRUPTED); } while (impl->state >= mTHREAD_MIN_WAITING && impl->state <= mTHREAD_MAX_WAITING) { #ifdef USE_DEBUGGERS if (debugger && debugger->state != DEBUGGER_SHUTDOWN) { mDebuggerUpdate(debugger); - ConditionWaitTimed(&impl->stateCond, &impl->stateMutex, 10); + ConditionWaitTimed(&impl->stateOnThreadCond, &impl->stateMutex, 10); } else #endif { - ConditionWait(&impl->stateCond, &impl->stateMutex); + ConditionWait(&impl->stateOnThreadCond, &impl->stateMutex); } if (impl->sync.audioWait) { @@ -392,14 +391,13 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->state == mTHREAD_REQUEST) { if (pendingRequests) { if (pendingRequests & mTHREAD_REQ_PAUSE) { - impl->state = mTHREAD_PAUSED; + _changeState(impl, mTHREAD_PAUSED); } if (pendingRequests & mTHREAD_REQ_WAIT) { - impl->state = mTHREAD_PAUSED; + _changeState(impl, mTHREAD_PAUSED); } } else { - impl->state = mTHREAD_RUNNING; - ConditionWake(&threadContext->impl->stateCond); + _changeState(impl, mTHREAD_RUNNING); } } MutexUnlock(&impl->stateMutex); @@ -439,6 +437,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->state < mTHREAD_SHUTDOWN) { impl->state = mTHREAD_SHUTDOWN; } + ConditionWake(&threadContext->impl->stateOffThreadCond); MutexUnlock(&impl->stateMutex); if (core->opts.rewindEnable) { @@ -477,7 +476,8 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { } MutexInit(&threadContext->impl->stateMutex); - ConditionInit(&threadContext->impl->stateCond); + ConditionInit(&threadContext->impl->stateOnThreadCond); + ConditionInit(&threadContext->impl->stateOffThreadCond); MutexInit(&threadContext->impl->sync.videoFrameMutex); ConditionInit(&threadContext->impl->sync.videoFrameAvailableCond); @@ -502,7 +502,7 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); ThreadCreate(&threadContext->impl->thread, _mCoreThreadRun, threadContext); while (threadContext->impl->state < mTHREAD_RUNNING) { - ConditionWait(&threadContext->impl->stateCond, &threadContext->impl->stateMutex); + ConditionWait(&threadContext->impl->stateOffThreadCond, &threadContext->impl->stateMutex); } MutexUnlock(&threadContext->impl->stateMutex); @@ -544,7 +544,7 @@ bool mCoreThreadHasCrashed(struct mCoreThread* threadContext) { void mCoreThreadMarkCrashed(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); - threadContext->impl->state = mTHREAD_CRASHED; + _changeState(threadContext->impl, mTHREAD_CRASHED); MutexUnlock(&threadContext->impl->stateMutex); } @@ -552,7 +552,7 @@ void mCoreThreadClearCrashed(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); if (threadContext->impl->state == mTHREAD_CRASHED) { threadContext->impl->state = mTHREAD_REQUEST; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } @@ -561,7 +561,7 @@ void mCoreThreadEnd(struct mCoreThread* threadContext) { MutexLock(&threadContext->impl->stateMutex); _waitOnInterrupt(threadContext->impl); threadContext->impl->state = mTHREAD_EXITING; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); MutexUnlock(&threadContext->impl->stateMutex); MutexLock(&threadContext->impl->sync.audioBufferMutex); threadContext->impl->sync.audioWait = 0; @@ -590,7 +590,8 @@ void mCoreThreadJoin(struct mCoreThread* threadContext) { ThreadJoin(&threadContext->impl->thread); MutexDeinit(&threadContext->impl->stateMutex); - ConditionDeinit(&threadContext->impl->stateCond); + ConditionDeinit(&threadContext->impl->stateOnThreadCond); + ConditionDeinit(&threadContext->impl->stateOffThreadCond); MutexDeinit(&threadContext->impl->sync.videoFrameMutex); ConditionWake(&threadContext->impl->sync.videoFrameAvailableCond); @@ -642,7 +643,6 @@ void mCoreThreadInterruptFromThread(struct mCoreThread* threadContext) { return; } threadContext->impl->state = mTHREAD_INTERRUPTING; - ConditionWake(&threadContext->impl->stateCond); MutexUnlock(&threadContext->impl->stateMutex); } @@ -658,7 +658,7 @@ void mCoreThreadContinue(struct mCoreThread* threadContext) { } else { threadContext->impl->state = mTHREAD_RUNNING; } - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } @@ -718,7 +718,7 @@ void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool rewinding) threadContext->impl->rewinding = rewinding; if (rewinding && threadContext->impl->state == mTHREAD_CRASHED) { threadContext->impl->state = mTHREAD_REQUEST; - ConditionWake(&threadContext->impl->stateCond); + ConditionWake(&threadContext->impl->stateOnThreadCond); } MutexUnlock(&threadContext->impl->stateMutex); } From 1f2d0d505625414eacbd38f426b94e274ea18aa6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 5 Apr 2024 00:10:09 -0700 Subject: [PATCH 006/148] GBA GPIO: Fix gyro read-out start (fixes #3141) --- CHANGES | 1 + src/gba/cart/gpio.c | 10 ++++++---- src/platform/3ds/main.c | 2 +- src/platform/libretro/libretro.c | 2 +- src/platform/psp2/psp2-context.c | 2 +- src/platform/sdl/sdl-events.c | 4 ++-- src/platform/switch/main.c | 2 +- src/platform/wii/main.c | 2 +- 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index efb7d494e..5abed6a7e 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ Emulation fixes: - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) + - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 53c14dafd..811dc1e8a 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -320,18 +320,20 @@ void _gyroReadPins(struct GBACartridgeHardware* hw) { return; } + // Write bit on falling edge + bool doOutput = hw->gyroEdge && !(hw->pinState & 2); if (hw->pinState & 1) { if (gyro->sample) { gyro->sample(gyro); } int32_t sample = gyro->readGyroZ(gyro); - // Normalize to ~12 bits, focused on 0x6C0 - hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative + // Normalize to ~12 bits, focused on 0x700 + hw->gyroSample = (sample >> 21) + 0x700; // Crop off an extra bit so that we can't go negative + doOutput = true; } - if (hw->gyroEdge && !(hw->pinState & 2)) { - // Write bit on falling edge + if (doOutput) { unsigned bit = hw->gyroSample >> 15; hw->gyroSample <<= 1; _outputPins(hw, bit << 2); diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 0f7bb27b9..36df49a9c 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -704,7 +704,7 @@ static int32_t _readTiltY(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) { struct m3DSRotationSource* rotation = (struct m3DSRotationSource*) source; - return rotation->gyro.y << 18L; // Yes, y + return rotation->gyro.y << 17L; // Yes, y } static void _startRequestImage(struct mImageSource* source, unsigned w, unsigned h, int colorFormats) { diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index bea9f6273..69c547b57 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -1390,7 +1390,7 @@ static void _updateRotation(struct mRotationSource* source) { tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * 2e8f; } if (gyroEnabled) { - gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f; + gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -5.5e8f; } } diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index a7504f7cc..1e48c2f24 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -149,7 +149,7 @@ static int32_t _readTiltY(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) { struct mSceRotationSource* rotation = (struct mSceRotationSource*) source; - return rotation->state.gyro.z * -0x10000000; + return rotation->state.gyro.z * -0x8000000; } static void _setRumble(struct mRumble* source, int enable) { diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 08a369c73..46807cae1 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -823,14 +823,14 @@ static void _mSDLRotationSample(struct mRotationSource* source) { float theta[3]; int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_GYRO, theta, 3); if (count >= 0) { - rotation->zDelta = theta[1] / -10.f; + rotation->zDelta = theta[1] / -20.f; } return; } } #endif if (rotation->gyroZ >= 0) { - rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 1.e5f; + rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 2.e5f; return; } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index ef3e12164..15196aaec 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -644,7 +644,7 @@ void _sampleRotation(struct mRotationSource* source) { } tiltX = sixaxis.acceleration.x * 3e8f; tiltY = sixaxis.acceleration.y * -3e8f; - gyroZ = sixaxis.angular_velocity.z * -1.1e9f; + gyroZ = sixaxis.angular_velocity.z * -5.5e8f; } int32_t _readTiltX(struct mRotationSource* source) { diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index db3ed7242..60d4e95ae 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -1731,7 +1731,7 @@ void _sampleRotation(struct mRotationSource* source) { return; } gyroZ = exp.mp.rz - 0x1FA0; - gyroZ <<= 18; + gyroZ <<= 17; } int32_t _readTiltX(struct mRotationSource* source) { From 04a95a5445b2617a0015a268bd3e36577c521214 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:10:58 -0700 Subject: [PATCH 007/148] CHANGES: Remove duplicate entry --- CHANGES | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGES b/CHANGES index 5abed6a7e..e08179d72 100644 --- a/CHANGES +++ b/CHANGES @@ -11,7 +11,6 @@ Emulation fixes: - GB Serialize: Add missing Pocket Cam state to savestates - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception - - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) From 47ec447dd0902661c3e21766b60788a43778d401 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:11:14 -0700 Subject: [PATCH 008/148] CMakeLists: Fix strtof_l detection logic --- CMakeLists.txt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f2ff4686..aee8ac512 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -345,18 +345,14 @@ find_function(popcount32) find_function(futimens) find_function(futimes) +find_function(localtime_r) find_function(realpath) if(ANDROID AND ANDROID_NDK_MAJOR GREATER 13) - find_function(localtime_r) - set(HAVE_STRTOF_L ON) -elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_function(localtime_r) + list(APPEND FUNCTION_DEFINES HAVE_STRTOF_L) +elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") # The strtof_l on Linux not actually exposed nor actually strtof_l - set(HAVE_STRTOF_L OFF) -else() - find_function(localtime_r) find_function(strtof_l) endif() From 02b2f5a98a7f430c60d66948d8ab57102261c302 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:52:47 -0700 Subject: [PATCH 009/148] flags.h: Add missing flags --- src/core/flags.h.in | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/flags.h.in b/src/core/flags.h.in index 3bd142a44..5a9e4e6ef 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -59,6 +59,10 @@ #cmakedefine USE_DEBUGGERS #endif +#ifndef USE_DISCORD_RPC +#cmakedefine USE_DISCORD_RPC +#endif + #ifndef USE_EDITLINE #cmakedefine USE_EDITLINE #endif @@ -133,6 +137,10 @@ #cmakedefine HAVE_CRC32 #endif +#ifndef HAVE_LOCALE +#cmakedefine HAVE_LOCALE +#endif + #ifndef HAVE_LOCALTIME_R #cmakedefine HAVE_LOCALTIME_R #endif @@ -149,6 +157,10 @@ #cmakedefine HAVE_PTHREAD_SETNAME_NP #endif +#ifndef HAVE_SNPRINTF_L +#cmakedefine HAVE_SNPRINTF_L +#endif + #ifndef HAVE_STRDUP #cmakedefine HAVE_STRDUP #endif From 4652bbb4271af4054acfbf779df8720e424ad80b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 02:53:00 -0700 Subject: [PATCH 010/148] Util: Fix #if into #ifdef --- src/util/formatting.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/formatting.c b/src/util/formatting.c index e1e1c0bf0..2506ddc9c 100644 --- a/src/util/formatting.c +++ b/src/util/formatting.c @@ -46,26 +46,26 @@ float strtof_l(const char* restrict str, char** restrict end, locale_t locale) { #endif int ftostr_u(char* restrict str, size_t size, float f) { -#if HAVE_LOCALE +#ifdef HAVE_LOCALE locale_t l = newlocale(LC_NUMERIC_MASK, "C", 0); #else locale_t l = "C"; #endif int res = ftostr_l(str, size, f, l); -#if HAVE_LOCALE +#ifdef HAVE_LOCALE freelocale(l); #endif return res; } float strtof_u(const char* restrict str, char** restrict end) { -#if HAVE_LOCALE +#ifdef HAVE_LOCALE locale_t l = newlocale(LC_NUMERIC_MASK, "C", 0); #else locale_t l = "C"; #endif float res = strtof_l(str, end, l); -#if HAVE_LOCALE +#ifdef HAVE_LOCALE freelocale(l); #endif return res; From 0e441527c896022ff7a558529618f2a28036f6b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 03:08:10 -0700 Subject: [PATCH 011/148] CMake: Rename USE_DEBUGGERS and USE_GDB_STUB to ENABLE_DEBUGGERS and ENABLE_GDB_STUB ENABLE flags are for optional features, USE flags are for optional dependencies --- CMakeLists.txt | 26 +++++++++---------- include/mgba/core/core.h | 6 ++--- include/mgba/core/scripting.h | 6 ++--- include/mgba/internal/arm/decoder.h | 2 +- include/mgba/internal/gba/gba.h | 2 +- src/arm/decoder.c | 2 +- src/core/core.c | 2 +- src/core/flags.h.in | 16 ++++++------ src/core/scripting.c | 16 ++++++------ src/core/test/scripting.c | 4 +-- src/core/thread.c | 6 ++--- src/debugger/CMakeLists.txt | 2 +- src/debugger/cli-debugger.c | 2 +- src/debugger/debugger.c | 6 ++--- src/feature/commandline.c | 12 ++++----- src/gb/core.c | 6 ++--- src/gb/gb.c | 4 +-- src/gba/core.c | 8 +++--- src/gba/gba.c | 14 +++++----- src/platform/python/_builder.h | 2 +- src/platform/python/engine.c | 10 +++---- src/platform/python/lib.h | 2 +- src/platform/qt/CMakeLists.txt | 4 +-- src/platform/qt/CoreController.cpp | 8 +++--- src/platform/qt/CoreController.h | 4 +-- src/platform/qt/GDBController.h | 2 +- src/platform/qt/Window.cpp | 20 +++++++------- src/platform/qt/Window.h | 8 +++--- .../qt/scripting/ScriptingController.cpp | 2 +- src/platform/sdl/main.c | 6 ++--- src/platform/sdl/sdl-events.c | 2 +- src/platform/test/rom-test-main.c | 6 ++--- src/script/stdlib.c | 2 +- 33 files changed, 110 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aee8ac512..24caaaf9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,11 +46,11 @@ else() endif() if(NOT LIBMGBA_ONLY) - set(USE_DEBUGGERS ON CACHE BOOL "Whether or not to enable the debugging infrastructure") + set(ENABLE_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(ENABLE_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") @@ -301,7 +301,7 @@ endif() if(DEFINED 3DS OR DEFINED PSP2 OR DEFINED WII OR DEFINED SWITCH) set(IS_EMBEDDED ON) - set(USE_DEBUGGERS OFF) + set(ENABLE_DEBUGGERS OFF) set(USE_SQLITE3 OFF) set(USE_DISCORD_RPC OFF) set(USE_LIBZIP OFF CACHE BOOL "") @@ -313,12 +313,12 @@ if(DEFINED SWITCH) endif() if(NOT M_CORE_GBA) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) endif() -if(NOT USE_DEBUGGERS) +if(NOT ENABLE_DEBUGGERS) set(USE_EDITLINE OFF) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) endif() if(WII) @@ -489,7 +489,7 @@ if(NOT BUILD_GLES2 AND NOT BUILD_GLES3 AND NOT LIBMGBA_ONLY) endif() if(DISABLE_DEPS) - set(USE_GDB_STUB OFF) + set(ENABLE_GDB_STUB OFF) set(USE_DISCORD_RPC OFF) set(USE_JSON_C OFF) set(USE_SQLITE3 OFF) @@ -541,8 +541,8 @@ else() set(DEBUGGER_LIB "") endif() -if(USE_GDB_STUB) - list(APPEND FEATURES GDB_STUB) +if(ENABLE_GDB_STUB) + list(APPEND ENABLES GDB_STUB) endif() source_group("Debugger" FILES ${DEBUGGER_SRC}) @@ -851,10 +851,10 @@ if(M_CORE_GBA) list(APPEND TEST_SRC ${ARM_TEST_SRC} ${GBA_TEST_SRC}) endif() -if(USE_DEBUGGERS) +if(ENABLE_DEBUGGERS) list(APPEND FEATURE_SRC ${DEBUGGER_SRC}) list(APPEND TEST_SRC ${DEBUGGER_TEST_SRC}) - list(APPEND FEATURES DEBUGGERS) + list(APPEND ENABLES DEBUGGERS) endif() if(ENABLE_SCRIPTING) @@ -1312,11 +1312,11 @@ if(NOT QUIET AND NOT LIBMGBA_ONLY) message(STATUS " Game Boy Advance: ${M_CORE_GBA}") message(STATUS " Game Boy: ${M_CORE_GB}") message(STATUS "Features:") - message(STATUS " Debuggers: ${USE_DEBUGGERS}") + message(STATUS " Debuggers: ${ENABLE_DEBUGGERS}") if(NOT WIN32) message(STATUS " CLI debugger: ${USE_EDITLINE}") endif() - message(STATUS " GDB stub: ${USE_GDB_STUB}") + message(STATUS " GDB stub: ${ENABLE_GDB_STUB}") message(STATUS " GIF/Video recording: ${USE_FFMPEG}") message(STATUS " Screenshot/advanced savestate support: ${USE_PNG}") message(STATUS " ZIP support: ${SUMMARY_ZIP}") diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 052e36795..99bfd0e83 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -18,7 +18,7 @@ CXX_GUARD_START #include #endif #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif @@ -146,7 +146,7 @@ struct mCore { bool (*readRegister)(const struct mCore*, const char* name, void* out); bool (*writeRegister)(struct mCore*, const char* name, const void* in); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType); struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*); struct CLIDebuggerSystem* (*cliDebuggerSystem)(struct mCore*); @@ -219,7 +219,7 @@ const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint3 #ifdef USE_ELF struct ELF; bool mCoreLoadELF(struct mCore* core, struct ELF* elf); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF*); #endif #endif diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index 645874883..a8fdbc425 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -10,7 +10,7 @@ CXX_GUARD_START -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif #include @@ -35,7 +35,7 @@ struct mScriptEngine { void (*run)(struct mScriptEngine*); bool (*lookupSymbol)(struct mScriptEngine*, const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void (*debuggerEntered)(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif }; @@ -63,7 +63,7 @@ void mScriptBridgeDestroy(struct mScriptBridge*); void mScriptBridgeInstallEngine(struct mScriptBridge*, struct mScriptEngine*); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mScriptBridgeSetDebugger(struct mScriptBridge*, struct mDebugger*); struct mDebugger* mScriptBridgeGetDebugger(struct mScriptBridge*); void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); diff --git a/include/mgba/internal/arm/decoder.h b/include/mgba/internal/arm/decoder.h index c0efb22e8..f6e197698 100644 --- a/include/mgba/internal/arm/decoder.h +++ b/include/mgba/internal/arm/decoder.h @@ -221,7 +221,7 @@ bool ARMDecodeThumbCombine(struct ARMInstructionInfo* info1, struct ARMInstructi struct ARMInstructionInfo* out); uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegisterFile* regs, uint32_t pc); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebuggerSymbols; int ARMDisassemble(const struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen); #endif diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index 020dd2ab5..e66ac47f3 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -160,7 +160,7 @@ struct ELF; bool GBAVerifyELFEntry(struct ELF* elf, uint32_t target); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger; void GBAAttachDebugger(struct GBA* gba, struct mDebugger* debugger); void GBADetachDebugger(struct GBA* gba); diff --git a/src/arm/decoder.c b/src/arm/decoder.c index 01622cc9d..21ea0e872 100644 --- a/src/arm/decoder.c +++ b/src/arm/decoder.c @@ -9,7 +9,7 @@ #include #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #define ADVANCE(AMOUNT) \ if (AMOUNT >= blen) { \ buffer[blen - 1] = '\0'; \ diff --git a/src/core/core.c b/src/core/core.c index a7de23943..bc68fd5d2 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -467,7 +467,7 @@ bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { return true; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF* elf) { size_t symIndex = ELFFindSection(elf, ".symtab"); size_t names = ELFFindSection(elf, ".strtab"); diff --git a/src/core/flags.h.in b/src/core/flags.h.in index 5a9e4e6ef..ebfd67ed9 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -49,16 +49,20 @@ // ENABLE flags +#ifndef ENABLE_DEBUGGERS +#cmakedefine ENABLE_DEBUGGERS +#endif + +#ifndef ENABLE_GDB_STUB +#cmakedefine ENABLE_GDB_STUB +#endif + #ifndef ENABLE_SCRIPTING #cmakedefine ENABLE_SCRIPTING #endif // USE flags -#ifndef USE_DEBUGGERS -#cmakedefine USE_DEBUGGERS -#endif - #ifndef USE_DISCORD_RPC #cmakedefine USE_DISCORD_RPC #endif @@ -79,10 +83,6 @@ #cmakedefine USE_FFMPEG #endif -#ifndef USE_GDB_STUB -#cmakedefine USE_GDB_STUB -#endif - #ifndef USE_JSON_C #cmakedefine USE_JSON_C #endif diff --git a/src/core/scripting.c b/src/core/scripting.c index 5b1f39a63..1fd37aeb9 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -64,7 +64,7 @@ static void _seRun(const char* key, void* value, void* user) { se->run(se); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptDebuggerEntry { enum mDebuggerEntryReason reason; struct mDebuggerEntryInfo* info; @@ -98,7 +98,7 @@ void mScriptBridgeInstallEngine(struct mScriptBridge* sb, struct mScriptEngine* HashTableInsert(&sb->engines, name, se); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mScriptBridgeSetDebugger(struct mScriptBridge* sb, struct mDebugger* debugger) { if (sb->debugger == debugger) { return; @@ -159,7 +159,7 @@ struct mScriptMemoryDomain { struct mCoreMemoryBlock block; }; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptBreakpointName { uint32_t address; uint32_t maxAddress; @@ -189,7 +189,7 @@ struct mScriptCoreAdapter { struct mCore* core; struct mScriptContext* context; struct mScriptValue memory; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mScriptDebugger debugger; #endif struct mRumble rumble; @@ -701,7 +701,7 @@ static void _rebuildMemoryMap(struct mScriptContext* context, struct mScriptCore } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static void _freeBreakpoint(void* bp) { struct mScriptBreakpoint* point = bp; HashTableDeinit(&point->callbacks); @@ -929,7 +929,7 @@ static bool _mScriptCoreAdapterClearBreakpoint(struct mScriptCoreAdapter* adapte static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) { _clearMemoryMap(adapter->context, adapter, false); adapter->memory.type->free(&adapter->memory); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (adapter->core->debugger) { mDebuggerDetachModule(adapter->core->debugger, &adapter->debugger.d); } @@ -982,7 +982,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, _deinit, _mScriptCoreAdap mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, reset, _mScriptCoreAdapterReset, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WTABLE, setRotationCallbacks, _mScriptCoreAdapterSetRotationCbTable, 1, WTABLE, cbTable); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, setSolarSensorCallback, _mScriptCoreAdapterSetLuminanceCb, 1, WRAPPER, callback); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); @@ -1040,7 +1040,7 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) "Note that the full range of values is not used by games, and the exact range depends on the calibration done by the game itself." ) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setSolarSensorCallback) -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) mSCRIPT_DEFINE_DOCSTRING("Clear a breakpoint or watchpoint for a given id returned by a previous call") diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index c2593bf14..d2f0f0a00 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -327,7 +327,7 @@ M_TEST_DEFINE(screenshot) { TEARDOWN_CORE; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void _setupBp(struct mCore* core) { switch (core->platform(core)) { #ifdef M_CORE_GBA @@ -727,7 +727,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, cmocka_unit_test(memoryWrite), cmocka_unit_test(logging), cmocka_unit_test(screenshot), -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #ifdef M_CORE_GBA cmocka_unit_test(basicBreakpointGBA), #endif diff --git a/src/core/thread.c b/src/core/thread.c index e0ace6240..43a569d4f 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -103,7 +103,7 @@ static void _wait(struct mCoreThreadInternal* threadContext) { MutexUnlock(&threadContext->sync.audioBufferMutex); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (threadContext->core && threadContext->core->debugger) { mDebuggerInterrupt(threadContext->core->debugger); } @@ -330,7 +330,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { MutexLock(&impl->stateMutex); while (impl->state < mTHREAD_EXITING) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger* debugger = core->debugger; if (debugger) { MutexUnlock(&impl->stateMutex); @@ -355,7 +355,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } while (impl->state >= mTHREAD_MIN_WAITING && impl->state <= mTHREAD_MAX_WAITING) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (debugger && debugger->state != DEBUGGER_SHUTDOWN) { mDebuggerUpdate(debugger); ConditionWaitTimed(&impl->stateOnThreadCond, &impl->stateMutex, 10); diff --git a/src/debugger/CMakeLists.txt b/src/debugger/CMakeLists.txt index ce2ade635..976f88c93 100644 --- a/src/debugger/CMakeLists.txt +++ b/src/debugger/CMakeLists.txt @@ -15,7 +15,7 @@ if(USE_EDITLINE) list(APPEND SOURCE_FILES cli-el-backend.c) endif() -if(USE_GDB_STUB) +if(ENABLE_GDB_STUB) list(APPEND SOURCE_FILES gdb-stub.c) endif() diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 9c9696f9f..6d5b70e97 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -1420,7 +1420,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(symbolTable, elf); #endif ELFClose(elf); diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index 7de4772d7..a03f106d9 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -10,7 +10,7 @@ #include #include -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include #endif @@ -37,7 +37,7 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC union DebugUnion { struct mDebuggerModule d; struct CLIDebugger cli; -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB struct GDBStub gdb; #endif }; @@ -52,7 +52,7 @@ struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mC CLIDebuggerAttachSystem(&debugger->cli, sys); break; case DEBUGGER_GDB: -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB GDBStubCreate(&debugger->gdb); struct Address localHost = { .version = IPV4, diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 7e720886d..cdf788b19 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -12,7 +12,7 @@ #include #include -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include #endif #ifdef USE_EDITLINE @@ -40,7 +40,7 @@ static const struct option _options[] = { #ifdef USE_EDITLINE { "debug", no_argument, 0, 'd' }, #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB { "gdb", no_argument, 0, 'g' }, #endif { "help", no_argument, 0, 'h' }, @@ -85,7 +85,7 @@ bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struc #ifdef USE_EDITLINE "d" #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB "g" #endif ; @@ -151,7 +151,7 @@ bool mArgumentsParse(struct mArguments* args, int argc, char* const* argv, struc args->debugCli = true; break; #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB case 'g': args->debugAtStart = true; args->debugGdb = true; @@ -231,7 +231,7 @@ bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, } #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (args->debugGdb) { struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_GDB, core); if (module) { @@ -355,7 +355,7 @@ void usage(const char* arg0, const char* prologue, const char* epilogue, const s #ifdef USE_EDITLINE " -d, --debug Use command-line debugger\n" #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB " -g, --gdb Start GDB session (default port 2345)\n" #endif " -l, --log-level N Log level mask\n" diff --git a/src/gb/core.c b/src/gb/core.c index 9154221d6..1018b9f82 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -164,7 +164,7 @@ static void _GBCoreDeinit(struct mCore* core) { #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (core->symbolTable) { mDebuggerSymbolTableDestroy(core->symbolTable); } @@ -1060,7 +1060,7 @@ static bool _GBCoreWriteRegister(struct mCore* core, const char* name, const voi return false; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _GBCoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); switch (type) { @@ -1352,7 +1352,7 @@ struct mCore* GBCoreCreate(void) { core->listRegisters = _GBCoreListRegisters; core->readRegister = _GBCoreReadRegister; core->writeRegister = _GBCoreWriteRegister; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS core->supportsDebuggerType = _GBCoreSupportsDebuggerType; core->debuggerPlatform = _GBCoreDebuggerPlatform; core->cliDebuggerSystem = _GBCoreCliDebuggerSystem; diff --git a/src/gb/gb.c b/src/gb/gb.c index b3bb62a80..c0e966c27 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -940,7 +940,7 @@ void GBProcessEvents(struct SM83Core* cpu) { nextEvent = cycles; do { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS gb->timing.globalCycles += nextEvent; #endif nextEvent = mTimingTick(&gb->timing, nextEvent); @@ -1057,7 +1057,7 @@ void GBStop(struct SM83Core* cpu) { void GBIllegal(struct SM83Core* cpu) { struct GB* gb = (struct GB*) cpu->master; mLOG(GB, GAME_ERROR, "Hit illegal opcode at address %04X:%02X", cpu->pc, cpu->bus); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) { struct mDebuggerEntryInfo info = { .address = cpu->pc, diff --git a/src/gba/core.c b/src/gba/core.c index 54c436b3a..dd5df523b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -313,7 +313,7 @@ static void _GBACoreDeinit(struct mCore* core) { #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 mDirectorySetDeinit(&core->dirs); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (core->symbolTable) { mDebuggerSymbolTableDestroy(core->symbolTable); } @@ -1218,7 +1218,7 @@ static bool _GBACoreWriteRegister(struct mCore* core, const char* name, const vo return true; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _GBACoreSupportsDebuggerType(struct mCore* core, enum mDebuggerType type) { UNUSED(core); switch (type) { @@ -1280,7 +1280,7 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(core->symbolTable, elf); #endif ELFClose(elf); @@ -1565,7 +1565,7 @@ struct mCore* GBACoreCreate(void) { core->listRegisters = _GBACoreListRegisters; core->readRegister = _GBACoreReadRegister; core->writeRegister = _GBACoreWriteRegister; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS core->supportsDebuggerType = _GBACoreSupportsDebuggerType; core->debuggerPlatform = _GBACoreDebuggerPlatform; core->cliDebuggerSystem = _GBACoreCliDebuggerSystem; diff --git a/src/gba/gba.c b/src/gba/gba.c index 31008507c..41eee7435 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -49,7 +49,7 @@ static void GBATestIRQNoDelay(struct ARMCore* cpu); static void _triggerIRQ(struct mTiming*, void* user, uint32_t cyclesLate); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _setSoftwareBreakpoint(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode); static void _clearSoftwareBreakpoint(struct ARMDebugger*, const struct ARMDebugBreakpoint*); #endif @@ -305,7 +305,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { do { int32_t cycles = cpu->cycles; cpu->cycles = 0; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS gba->timing.globalCycles += cycles < nextEvent ? nextEvent : cycles; #endif #ifndef NDEBUG @@ -338,7 +338,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void GBAAttachDebugger(struct GBA* gba, struct mDebugger* debugger) { gba->debugger = (struct ARMDebugger*) debugger->platform; gba->debugger->setSoftwareBreakpoint = _setSoftwareBreakpoint; @@ -850,7 +850,7 @@ void GBAGetGameTitle(const struct GBA* gba, char* out) { void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) { struct GBA* gba = (struct GBA*) cpu->master; UNUSED(gba); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (gba->debugger) { struct mDebuggerEntryInfo info = { .address = _ARMPCAddress(cpu), @@ -873,7 +873,7 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) { // TODO: More sensible category? mLOG(GBA, WARN, "Illegal opcode: %08x", opcode); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (gba->debugger) { struct mDebuggerEntryInfo info = { .address = _ARMPCAddress(cpu), @@ -888,7 +888,7 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) { void GBABreakpoint(struct ARMCore* cpu, int immediate) { struct GBA* gba = (struct GBA*) cpu->master; switch (immediate) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS case CPU_COMPONENT_DEBUGGER: if (gba->debugger) { struct mDebuggerEntryInfo info = { @@ -1053,7 +1053,7 @@ void GBAClearBreakpoint(struct GBA* gba, uint32_t address, enum ExecutionMode mo } } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static bool _setSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) { GBASetBreakpoint((struct GBA*) debugger->cpu->master, &debugger->d.p->d, address, mode, opcode); return true; diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index eef4cf046..e06e4f5cc 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -67,7 +67,7 @@ void free(void*); #include #include #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #include #endif diff --git a/src/platform/python/engine.c b/src/platform/python/engine.c index 67d1d7b49..86ec2cf5c 100644 --- a/src/platform/python/engine.c +++ b/src/platform/python/engine.c @@ -9,7 +9,7 @@ #include #include -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS #include #endif @@ -23,7 +23,7 @@ static bool mPythonScriptEngineLoadScript(struct mScriptEngine*, const char* nam static void mPythonScriptEngineRun(struct mScriptEngine*); static bool mPythonScriptEngineLookupSymbol(struct mScriptEngine*, const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS static void mPythonScriptDebuggerEntered(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif @@ -41,7 +41,7 @@ struct mPythonScriptEngine* mPythonCreateScriptEngine(void) { engine->d.loadScript = mPythonScriptEngineLoadScript; engine->d.run = mPythonScriptEngineRun; engine->d.lookupSymbol = mPythonScriptEngineLookupSymbol; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS engine->d.debuggerEntered = mPythonScriptDebuggerEntered; #endif engine->sb = NULL; @@ -82,7 +82,7 @@ bool mPythonScriptEngineLoadScript(struct mScriptEngine* se, const char* name, s void mPythonScriptEngineRun(struct mScriptEngine* se) { struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger* debugger = mScriptBridgeGetDebugger(engine->sb); if (debugger) { mPythonSetDebugger(debugger); @@ -97,7 +97,7 @@ bool mPythonScriptEngineLookupSymbol(struct mScriptEngine* se, const char* name, return mPythonLookupSymbol(name, out); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void mPythonScriptDebuggerEntered(struct mScriptEngine* se, enum mDebuggerEntryReason reason, struct mDebuggerEntryInfo* info) { struct mPythonScriptEngine* engine = (struct mPythonScriptEngine*) se; diff --git a/src/platform/python/lib.h b/src/platform/python/lib.h index 0dd8754ed..d0893101f 100644 --- a/src/platform/python/lib.h +++ b/src/platform/python/lib.h @@ -6,7 +6,7 @@ extern bool mPythonLoadScript(const char*, struct VFile*); extern void mPythonRunPending(); extern bool mPythonLookupSymbol(const char* name, int32_t* out); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS extern void mPythonSetDebugger(struct mDebugger*); extern void mPythonDebuggerEntered(enum mDebuggerEntryReason, struct mDebuggerEntryInfo*); #endif diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index fe898be1e..05f5add0a 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -249,7 +249,7 @@ if(NOT AUDIO_SRC) return() endif() -if(USE_DEBUGGERS) +if(ENABLE_DEBUGGERS) list(APPEND SOURCE_FILES DebuggerController.cpp DebuggerConsole.cpp @@ -257,7 +257,7 @@ if(USE_DEBUGGERS) MemoryAccessLogView.cpp) endif() -if(USE_GDB_STUB) +if(ENABLE_GDB_STUB) list(APPEND SOURCE_FILES GDBController.cpp GDBWindow.cpp) endif() diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index dd74cce78..660de1f57 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -49,7 +49,7 @@ CoreController::CoreController(mCore* core, QObject* parent) GBASIODolphinCreate(&m_dolphin); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebuggerInit(&m_debugger); #endif @@ -218,7 +218,7 @@ CoreController::~CoreController() { mCoreThreadJoin(&m_threadContext); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebuggerDeinit(&m_debugger); #endif @@ -331,7 +331,7 @@ void CoreController::loadConfig(ConfigController* config) { #endif } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void CoreController::attachDebugger(bool interrupt) { Interrupter interrupter(this); if (!m_threadContext.core->debugger) { @@ -478,7 +478,7 @@ void CoreController::start() { void CoreController::stop() { setSync(false); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS detachDebugger(); #endif setPaused(false); diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index c46b4d6e9..684d864d0 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -107,7 +107,7 @@ public: mCheatDevice* cheatDevice() { return m_threadContext.core->cheatDevice(m_threadContext.core); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mDebugger* debugger() { return &m_debugger; } void attachDebugger(bool interrupt = true); void detachDebugger(); @@ -305,7 +305,7 @@ private: bool m_autoload; int m_autosaveCounter = 0; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger m_debugger; #endif diff --git a/src/platform/qt/GDBController.h b/src/platform/qt/GDBController.h index 6bf0a7132..50c0fb927 100644 --- a/src/platform/qt/GDBController.h +++ b/src/platform/qt/GDBController.h @@ -7,7 +7,7 @@ #include "DebuggerController.h" -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB #include diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 6216e2247..117da820d 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -211,7 +211,7 @@ void Window::argumentsPassed() { m_pendingState = args->savestate; } -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (args->debugGdb) { if (!m_gdbController) { m_gdbController = new GDBController(this); @@ -224,7 +224,7 @@ void Window::argumentsPassed() { } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (args->debugCli) { consoleOpen(); } @@ -607,7 +607,7 @@ std::function Window::openNamedControllerTView(std::unique_ptr* name, }; } -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB void Window::gdbOpen() { if (!m_gdbController) { m_gdbController = new GDBController(this); @@ -619,7 +619,7 @@ void Window::gdbOpen() { } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void Window::consoleOpen() { if (!m_console) { m_console = new DebuggerConsoleController(this); @@ -1677,14 +1677,14 @@ void Window::setupMenu(QMenuBar* menubar) { m_actions.addAction(tr("Make portable"), "makePortable", this, &Window::tryMakePortable, "tools"); m_actions.addSeparator("tools"); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS m_actions.addAction(tr("Open debugger console..."), "debuggerWindow", this, &Window::consoleOpen, "tools"); -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB auto gdbWindow = addGameAction(tr("Start &GDB server..."), "gdbWindow", this, &Window::gdbOpen, "tools"); m_platformActions.insert(mPLATFORM_GBA, gdbWindow); #endif #endif -#if defined(USE_DEBUGGERS) || defined(ENABLE_SCRIPTING) +#if defined(ENABLE_DEBUGGERS) || defined(ENABLE_SCRIPTING) m_actions.addSeparator("tools"); #endif @@ -1714,7 +1714,7 @@ void Window::setupMenu(QMenuBar* menubar) { addGameAction(tr("Search memory..."), "memorySearch", openControllerTView(), "stateViews"); addGameAction(tr("View &I/O registers..."), "ioViewer", openControllerTView(), "stateViews"); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS addGameAction(tr("Log memory &accesses..."), "memoryAccessView", openControllerTView(), "tools"); #endif @@ -2132,13 +2132,13 @@ void Window::setController(CoreController* controller, const QString& fname) { } #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB if (m_gdbController) { m_gdbController->setController(m_controller); } #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (m_console) { m_console->setController(m_controller); } diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index b2e8de82b..4bcb6b7f9 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -108,11 +108,11 @@ public slots: void startVideoLog(); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS void consoleOpen(); #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB void gdbOpen(); #endif @@ -206,7 +206,7 @@ private: LogController m_log{0}; LogView* m_logView; -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS DebuggerConsoleController* m_console = nullptr; #endif LoadSaveState* m_stateWindow = nullptr; @@ -249,7 +249,7 @@ private: std::unique_ptr m_gifView; #endif -#ifdef USE_GDB_STUB +#ifdef ENABLE_GDB_STUB GDBController* m_gdbController = nullptr; #endif diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index 79b46e9d0..b1d68e22a 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -302,7 +302,7 @@ void ScriptingController::updateGamepad() { void ScriptingController::attach() { CoreController::Interrupter interrupter(m_controller); mScriptContextAttachCore(&m_scriptContext, m_controller->thread()->core); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS m_controller->attachDebugger(false); #endif } diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index d6a41f611..1a1d3f6fc 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -217,12 +217,12 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { #ifdef ENABLE_PYTHON mPythonSetup(bridge); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS CLIDebuggerScriptEngineInstall(bridge); #endif #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger debugger; mDebuggerInit(&debugger); bool hasDebugger = mArgumentsApplyDebugger(args, renderer->core, &debugger); @@ -292,7 +292,7 @@ int mSDLRun(struct mSDLRenderer* renderer, struct mArguments* args) { mScriptBridgeDestroy(bridge); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { renderer->core->detachDebugger(renderer->core); mDebuggerDeinit(&debugger); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 46807cae1..eceaf1808 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -505,7 +505,7 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* } if (event->type == SDL_KEYDOWN) { switch (event->keysym.sym) { -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS case SDLK_F11: if (context->core->debugger) { mDebuggerEnter(context->core->debugger, DEBUGGER_ENTER_MANUAL, NULL); diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 8c0d4fd3d..8524a852f 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -139,7 +139,7 @@ int main(int argc, char * argv[]) { goto loadError; } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS struct mDebugger debugger; mDebuggerInit(&debugger); bool hasDebugger = mArgumentsApplyDebugger(&args, core, &debugger); @@ -165,7 +165,7 @@ int main(int argc, char * argv[]) { savestate->close(savestate); } -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { do { mDebuggerRun(&debugger); @@ -178,7 +178,7 @@ int main(int argc, char * argv[]) { core->unloadROM(core); -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS if (hasDebugger) { core->detachDebugger(core); mDebuggerDeinit(&debugger); diff --git a/src/script/stdlib.c b/src/script/stdlib.c index 33ec0b751..6e81cfd86 100644 --- a/src/script/stdlib.c +++ b/src/script/stdlib.c @@ -160,7 +160,7 @@ void mScriptContextAttachStdlib(struct mScriptContext* context) { mSCRIPT_KV_SENTINEL }); #endif -#ifdef USE_DEBUGGERS +#ifdef ENABLE_DEBUGGERS mScriptContextExportConstants(context, "WATCHPOINT_TYPE", (struct mScriptKVPair[]) { mSCRIPT_CONSTANT_PAIR(WATCHPOINT, WRITE), mSCRIPT_CONSTANT_PAIR(WATCHPOINT, READ), From 2037e97fc9e4d58ed9565dd4f6b0b25f813841ef Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 22:42:18 +0000 Subject: [PATCH 012/148] Qt: Update translation (Chinese (Simplified)) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/zh_Hans/ --- src/platform/qt/ts/mgba-zh_CN.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 150ad5404..6992a6280 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -4366,7 +4366,7 @@ Download size: %3 Save games and save states (%1) - 保存游戏和即时存档(%1) + 保存游戏和即时存档 (%1) @@ -4376,7 +4376,7 @@ Download size: %3 Save games (%1) - 保存游戏(%1) + 保存游戏 (%1) @@ -6124,7 +6124,7 @@ Download size: %3 Save games (%1) - 保存游戏(%1) + 保存游戏 (%1) @@ -6134,7 +6134,7 @@ Download size: %3 mGBA save state files (%1) - mGBA 即时存档文件(%1) + mGBA 即时存档文件 (%1) From 61172d837fc22dfb715f0bb1aec2e41cadb8fd76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 8 Apr 2024 19:59:11 -0700 Subject: [PATCH 013/148] Core: Fix thread not waking up properly on canceling request --- src/core/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/thread.c b/src/core/thread.c index 43a569d4f..18c1c20e1 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -140,7 +140,7 @@ static void _sendRequest(struct mCoreThreadInternal* threadContext, enum mCoreTh static void _cancelRequest(struct mCoreThreadInternal* threadContext, enum mCoreThreadRequest request) { threadContext->requested &= ~request; _pokeRequest(threadContext); - ConditionWake(&threadContext->stateOffThreadCond); + ConditionWake(&threadContext->stateOnThreadCond); } void _frameStarted(void* context) { From 72202544bb0dcc444a4ef6ff5f52cf22c34f1da4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 9 Apr 2024 00:50:23 -0700 Subject: [PATCH 014/148] Core: Don't trigger watchpoints with access inside of a script (fixes #3050) --- src/core/scripting.c | 104 +++++++++++++++++++++++++++++++++++++- src/core/test/scripting.c | 35 +++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/core/scripting.c b/src/core/scripting.c index 1fd37aeb9..acf324e1f 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -182,6 +182,7 @@ struct mScriptDebugger { struct Table cbidMap; struct Table bpidMap; int64_t nextBreakpoint; + bool reentered; }; #endif @@ -779,6 +780,7 @@ static void _scriptDebuggerInit(struct mDebuggerModule* debugger) { struct mScriptDebugger* scriptDebugger = (struct mScriptDebugger*) debugger; debugger->isPaused = false; debugger->needsCallback = false; + scriptDebugger->reentered = false; HashTableInit(&scriptDebugger->breakpoints, 0, _freeBreakpoint); HashTableInit(&scriptDebugger->cbidMap, 0, NULL); @@ -812,6 +814,11 @@ static void _scriptDebuggerEntered(struct mDebuggerModule* debugger, enum mDebug default: return; } + + if (scriptDebugger->reentered) { + return; + } + _runCallbacks(scriptDebugger, point); debugger->isPaused = false; } @@ -976,18 +983,105 @@ static void _mScriptCoreAdapterSetLuminanceCb(struct mScriptCoreAdapter* adapter adapter->luminanceCb = callback; } +static uint32_t _mScriptCoreAdapterRead8(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead8(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static uint32_t _mScriptCoreAdapterRead16(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead16(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static uint32_t _mScriptCoreAdapterRead32(struct mScriptCoreAdapter* adapter, uint32_t address) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + uint32_t value = adapter->core->busRead32(adapter->core, address); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static struct mScriptValue* _mScriptCoreAdapterReadRange(struct mScriptCoreAdapter* adapter, uint32_t address, uint32_t length) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + struct mScriptValue* value = mScriptStringCreateEmpty(length); + char* buffer = value->value.string->buffer; + uint32_t i; + for (i = 0; i < length; ++i, ++address) { + buffer[i] = adapter->core->busRead8(adapter->core, address); + } +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif + return value; +} + +static void _mScriptCoreAdapterWrite8(struct mScriptCoreAdapter* adapter, uint32_t address, uint8_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite8(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + +static void _mScriptCoreAdapterWrite16(struct mScriptCoreAdapter* adapter, uint32_t address, uint16_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite16(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + +static void _mScriptCoreAdapterWrite32(struct mScriptCoreAdapter* adapter, uint32_t address, uint32_t value) { +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = true; +#endif + adapter->core->busWrite32(adapter->core, address, value); +#ifdef ENABLE_DEBUGGERS + adapter->debugger.reentered = false; +#endif +} + mSCRIPT_DECLARE_STRUCT(mScriptCoreAdapter); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, W(mCore), _get, _mScriptCoreAdapterGet, 1, CHARP, name); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, _deinit, _mScriptCoreAdapterDeinit, 0); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, reset, _mScriptCoreAdapterReset, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WTABLE, setRotationCallbacks, _mScriptCoreAdapterSetRotationCbTable, 1, WTABLE, cbTable); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, setSolarSensorCallback, _mScriptCoreAdapterSetLuminanceCb, 1, WRAPPER, callback); + +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read8, _mScriptCoreAdapterRead8, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read16, _mScriptCoreAdapterRead16, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U32, read32, _mScriptCoreAdapterRead32, 1, U32, address); +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, WSTR, readRange, _mScriptCoreAdapterReadRange, 2, U32, address, U32, length); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write8, _mScriptCoreAdapterWrite8, 2, U32, address, U8, value); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write16, _mScriptCoreAdapterWrite16, 2, U32, address, U16, value); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write32, _mScriptCoreAdapterWrite32, 2, U32, address, U32, value); + #ifdef ENABLE_DEBUGGERS mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, BOOL, clearBreakpoint, _mScriptCoreAdapterClearBreakpoint, 1, S64, cbid); -#endif mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptCoreAdapter, setBreakpoint) mSCRIPT_NO_DEFAULT, @@ -1009,6 +1103,7 @@ mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptCoreAdapter, setRangeWatchpoint) mSCRIPT_NO_DEFAULT, mSCRIPT_S32(-1) mSCRIPT_DEFINE_DEFAULTS_END; +#endif mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_CLASS_DOCSTRING( @@ -1040,6 +1135,13 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) "Note that the full range of values is not used by games, and the exact range depends on the calibration done by the game itself." ) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setSolarSensorCallback) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read8) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read16) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, read32) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, readRange) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write8) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write16) + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write32) #ifdef ENABLE_DEBUGGERS mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index d2f0f0a00..e66f2a722 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -547,6 +547,40 @@ M_TEST_DEFINE(basicWatchpoint) { mDebuggerDeinit(&debugger); } +M_TEST_DEFINE(watchpointReentrant) { + SETUP_LUA; + mScriptContextAttachStdlib(&context); + CREATE_CORE; + struct mDebugger debugger; + core->reset(core); + mScriptContextAttachCore(&context, core); + + mDebuggerInit(&debugger); + mDebuggerAttach(&debugger, core); + + TEST_PROGRAM( + "hit = 0\n" + "function bkpt()\n" + " hit = hit + 1\n" + "end" + ); + struct mScriptValue base = mSCRIPT_MAKE_S32(RAM_BASE); + lua->setGlobal(lua, "base", &base); + TEST_PROGRAM("assert(0 < emu:setWatchpoint(bkpt, base, C.WATCHPOINT_TYPE.READ))"); + + TEST_PROGRAM("hit = 0"); + core->busRead8(core, RAM_BASE); + TEST_PROGRAM("assert(hit == 1)"); + TEST_PROGRAM("emu:read8(base)"); + TEST_PROGRAM("assert(hit == 1)"); + core->busRead8(core, RAM_BASE); + TEST_PROGRAM("assert(hit == 2)"); + + mScriptContextDeinit(&context); + TEARDOWN_CORE; + mDebuggerDeinit(&debugger); +} + M_TEST_DEFINE(removeBreakpoint) { SETUP_LUA; mScriptContextAttachStdlib(&context); @@ -736,6 +770,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptCore, #endif cmocka_unit_test(multipleBreakpoint), cmocka_unit_test(basicWatchpoint), + cmocka_unit_test(watchpointReentrant), cmocka_unit_test(removeBreakpoint), cmocka_unit_test(overlappingBreakpoint), cmocka_unit_test(overlappingWatchpoint), From cbd117eb3a9eba367e58b9139f46f29294fe7ebe Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 10 Apr 2024 23:54:40 -0700 Subject: [PATCH 015/148] Util: Start bringing up better audio resampling --- include/mgba-util/interpolator.h | 33 +++++++++++++ src/util/CMakeLists.txt | 1 + src/util/interpolator.c | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 include/mgba-util/interpolator.h create mode 100644 src/util/interpolator.c diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h new file mode 100644 index 000000000..4cb7231fd --- /dev/null +++ b/include/mgba-util/interpolator.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2013-2024 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_INTERPOLATOR_H +#define M_INTERPOLATOR_H + +#include + +struct mSampleBuffer { + int16_t* data; + size_t samples; + int channels; +}; + +struct mInterpolator { + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mSampleBuffer* data, double time, double sampleStep); +}; + +struct mInterpolatorSinc { + struct mInterpolator d; + + unsigned resolution; + unsigned width; + double* sincLut; + double* windowLut; +}; + +void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); +void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); + +#endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index eb82215d7..820a178d5 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -19,6 +19,7 @@ set(SOURCE_FILES image.c image/export.c image/png-io.c + interpolator.c patch.c patch-fast.c patch-ips.c diff --git a/src/util/interpolator.c b/src/util/interpolator.c new file mode 100644 index 000000000..2fceee898 --- /dev/null +++ b/src/util/interpolator.c @@ -0,0 +1,83 @@ +/* Copyright (c) 2013-2024 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 + +enum { + mSINC_RESOLUTION = 8192, + mSINC_WIDTH = 8, +}; + +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mSampleBuffer* data, double time, double sampleStep); + +void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { + interp->d.interpolate = mInterpolatorSincInterpolate; + + if (!resolution) { + resolution = mSINC_RESOLUTION; + } + if (!width) { + width = mSINC_WIDTH; + } + unsigned samples = resolution * width; + double dy = M_PI / samples; + double y = dy; + double dx = dy * width; + double x = dx; + + interp->sincLut = calloc(samples + 1, sizeof(double)); + interp->windowLut = calloc(samples + 1, sizeof(double)); + + interp->sincLut[0] = 0; + interp->windowLut[0] = 1; + + unsigned i; + for (i = 1; i <= samples; ++i, x += dx, y += dy) { + interp->sincLut[i] = x < width ? sin(x) / x : 0.0; + // Three term Nuttall window with continuous first derivative + interp->windowLut[i] = 0.40897 + 0.5 * cos(y) + 0.09103 * cos(2 * y); + } +} + +void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { + free(interp->sincLut); + free(interp->windowLut); +} + +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mSampleBuffer* data, double time, double sampleStep) { + struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; + ssize_t index = (ssize_t) time; + double subsample = time - floor(time); + unsigned step = sampleStep > 1 ? interp->resolution * sampleStep : interp->resolution; + unsigned yShift = subsample * step; + unsigned xShift = subsample * interp->resolution; + double sum = 0.0; + double kernelSum = 0.0; + double kernel; + + ssize_t i; + for (i = 1 - (ssize_t) interp->width; i <= (ssize_t) interp->width; ++i) { + unsigned window = i * interp->resolution; + if (yShift > window) { + window = yShift - window; + } else { + window -= yShift; + } + + unsigned sinc = i * step; + if (xShift > sinc) { + sinc = xShift - sinc; + } else { + sinc -= xShift; + } + + kernel = interp->sincLut[sinc] * interp->windowLut[window]; + kernelSum += kernel; + if (index + i >= 0 && index + i < (ssize_t) data->samples) { + sum += data->data[(index + i) * data->channels] * kernel; + } + } + return sum / kernelSum; +} From 2d03ae64ba7b72a2d722cbc90b26b024d7006d02 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Apr 2024 00:47:45 -0700 Subject: [PATCH 016/148] 3DS: Handle audio resampling in DSP --- src/platform/3ds/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 36df49a9c..fb4f63a56 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -343,9 +343,8 @@ static void _gameLoaded(struct mGUIRunner* runner) { } osSetSpeedupEnable(true); - double ratio = GBAAudioCalculateRatio(1, 268111856.f / 4481136.f, 1); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768 * ratio); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768); if (hasSound != NO_SOUND) { audioPos = 0; } @@ -858,7 +857,7 @@ int main(int argc, char* argv[]) { ndspChnReset(0); ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); ndspChnSetInterp(0, NDSP_INTERP_NONE); - ndspChnSetRate(0, 0x8000); + ndspChnSetRate(0, 32822); ndspChnWaveBufClear(0); audioLeft = linearMemAlign(AUDIO_SAMPLES * DSP_BUFFERS * 2 * sizeof(int16_t), 0x80); memset(dspBuffer, 0, sizeof(dspBuffer)); From a8023e4f6a2614a77d445f03082825346789880e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Apr 2024 20:33:51 -0700 Subject: [PATCH 017/148] Qt: Remove debug message from CMakeLists --- src/platform/qt/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 05f5add0a..673170f0f 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -29,7 +29,6 @@ set(QT_VERSIONS 6 5) foreach(V ${QT_VERSIONS}) set(QT Qt${V}) set(QT_V ${V}) - message("${V} ${QT} ${QT_V}") find_package(${QT} COMPONENTS Core Widgets Network OPTIONAL_COMPONENTS Multimedia) if(QT_V GREATER_EQUAL 6) find_package(${QT} COMPONENTS OpenGL OpenGLWidgets) From bc6a80137fcd96c8f3dcf33284906acf0ae64a2b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 00:46:12 -0700 Subject: [PATCH 018/148] Util: Start adding CircleBuffer tests --- src/util/CMakeLists.txt | 1 + src/util/test/circle-buffer.c | 163 ++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 src/util/test/circle-buffer.c diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 820a178d5..f0bc85a3d 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -36,6 +36,7 @@ set(GUI_FILES gui/menu.c) set(TEST_FILES + test/circle-buffer.c test/color.c test/geometry.c test/image.c diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c new file mode 100644 index 000000000..ff580e23e --- /dev/null +++ b/src/util/test/circle-buffer.c @@ -0,0 +1,163 @@ +/* Copyright (c) 2013-2024 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(basicCircle) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 63; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 63; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(basicAlignment16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t i; + for (i = 0; i < 29; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + for (i = 0; i < 29; ++i) { + int16_t value; + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 29; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + for (i = 0; i < 29; ++i) { + int16_t value; + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } +} + + +M_TEST_DEFINE(basicAlignment32) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int32_t i; + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + for (i = 0; i < 15; ++i) { + int32_t value; + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(capacity) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 64; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + for (i = 0; i < 64; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + for (i = 0; i < 64; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferWrite8(&buffer, 64), 0); + + for (i = 0; i < 64; ++i) { + int8_t value; + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } +} + +M_TEST_DEFINE(overCapacity16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i; + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); +} + +M_TEST_SUITE_DEFINE(CircleBuffer, + cmocka_unit_test(basicCircle), + cmocka_unit_test(basicAlignment16), + cmocka_unit_test(basicAlignment32), + cmocka_unit_test(capacity), + cmocka_unit_test(overCapacity16), +) From cecb4543c328b5a8216d9665508946717d48d0f3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 00:54:54 -0700 Subject: [PATCH 019/148] Util: Remember to free memory in tests --- src/util/test/circle-buffer.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index ff580e23e..0415f83a1 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -30,6 +30,8 @@ M_TEST_DEFINE(basicCircle) { assert_int_equal(CircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { @@ -59,6 +61,8 @@ M_TEST_DEFINE(basicAlignment16) { assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } @@ -113,6 +117,8 @@ M_TEST_DEFINE(basicAlignment32) { assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(capacity) { @@ -140,6 +146,8 @@ M_TEST_DEFINE(capacity) { assert_int_equal(CircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } + + CircleBufferDeinit(&buffer); } M_TEST_DEFINE(overCapacity16) { @@ -152,6 +160,8 @@ M_TEST_DEFINE(overCapacity16) { assert_int_equal(CircleBufferWrite8(&buffer, i), 1); } assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); + + CircleBufferDeinit(&buffer); } M_TEST_SUITE_DEFINE(CircleBuffer, From 042a66bb8040a1bb0c15d119130866cb86a1a764 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 20:52:16 -0700 Subject: [PATCH 020/148] Scripting: Fix leak when freeing painters --- src/script/image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/script/image.c b/src/script/image.c index 7705ebd9a..2bd5a8736 100644 --- a/src/script/image.c +++ b/src/script/image.c @@ -131,6 +131,7 @@ static struct mScriptValue* _mScriptPainterGet(struct mScriptPainter* painter, c void _mScriptPainterDeinit(struct mScriptPainter* painter) { mScriptValueDeref(painter->image); + free(painter); } mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mPainter, setBlend, _mPainterSetBlend, 1, BOOL, enable); From 6d2109dd48b784e44e173f84f41cc2cbfe0da045 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 21:27:35 -0700 Subject: [PATCH 021/148] Util: Add offset parameter to CircleBufferDump, more tests --- include/mgba-util/circle-buffer.h | 2 +- src/util/circle-buffer.c | 11 +-- src/util/test/circle-buffer.c | 116 ++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 6 deletions(-) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index dee1f1f2a..995f2f32b 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -31,7 +31,7 @@ int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length); -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length); +size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset); CXX_GUARD_END diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index c77a71eba..d58ea0c44 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -264,15 +264,16 @@ size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length return length; } -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length) { +size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset) { int8_t* data = buffer->readPtr; - if (buffer->size == 0) { + if (buffer->size <= offset) { return 0; } - if (length > buffer->size) { - length = buffer->size; + if (length > buffer->size - offset) { + length = buffer->size - offset; } - size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data); + data += offset; + size_t remaining = buffer->capacity - ((uintptr_t) data - (uintptr_t) buffer->data); if (length <= remaining) { memcpy(output, data, length); } else { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 0415f83a1..1bfb0c111 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -164,10 +164,126 @@ M_TEST_DEFINE(overCapacity16) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(writeLenCapacity) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 48); + assert_memory_equal(data, databuf, 48); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 48); + assert_memory_equal(data, &databuf[48], 16); + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(dumpBasic) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_memory_equal(data, databuf, 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_memory_equal(data, databuf, 48); + assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(data, databuf, 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 32); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(&data[16], databuf, 32); + + assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_memory_equal(&data[16], databuf, 32); + assert_memory_equal(data, &databuf[32], 32); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_memory_equal(&data[16], databuf, 32); + assert_memory_equal(data, &databuf[32], 32); + assert_int_equal(CircleBufferSize(&buffer), 0); + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(dumpOffset) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(data, databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 16); + assert_memory_equal(&data[32], databuf, 16); + + assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(CircleBufferSize(&buffer), 32); + assert_memory_equal(data, databuf, 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 16); + assert_memory_equal(&data[32], databuf, 16); + + assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_memory_equal(&data[16], databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_memory_equal(&data[32], databuf, 16); + assert_memory_equal(data, &databuf[16], 16); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 32); + assert_memory_equal(data, databuf, 32); + assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 48), 16); + assert_memory_equal(&data[16], databuf, 16); + + CircleBufferDeinit(&buffer); +} + M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), cmocka_unit_test(capacity), cmocka_unit_test(overCapacity16), + cmocka_unit_test(writeLenCapacity), + cmocka_unit_test(dumpBasic), + cmocka_unit_test(dumpOffset), ) From c689a7fd48a5f66cc30898d487eafecab9bfc6da Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 21:31:06 -0700 Subject: [PATCH 022/148] Util: Add CircleBufferWriteTruncate --- include/mgba-util/circle-buffer.h | 1 + src/util/circle-buffer.c | 7 +++++++ src/util/test/circle-buffer.c | 27 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index 995f2f32b..137b6a7f9 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -27,6 +27,7 @@ int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value); int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value); int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value); size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length); +size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length); int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index d58ea0c44..12ead5033 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -153,6 +153,13 @@ size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t return length; } +size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length) { + if (buffer->size + length > buffer->capacity) { + length = buffer->capacity - buffer->size; + } + return CircleBufferWrite(buffer, input, length); +} + int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { int8_t* data = buffer->readPtr; if (buffer->size < sizeof(int8_t)) { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 1bfb0c111..b60f73a56 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -196,6 +196,32 @@ M_TEST_DEFINE(writeLenCapacity) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(writeTruncate) { + struct CircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + CircleBufferInit(&buffer, 64); + + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(CircleBufferSize(&buffer), 0); + assert_memory_equal(data, databuf, 64); + + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 48); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 16); + assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_memory_equal(data, databuf, 48); + assert_memory_equal(data, &databuf[48], 16); + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(dumpBasic) { struct CircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; @@ -284,6 +310,7 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(capacity), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), + cmocka_unit_test(writeTruncate), cmocka_unit_test(dumpBasic), cmocka_unit_test(dumpOffset), ) From ce46b6fe786a3dd31eeae05333b856ba45bebdbd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 22:20:12 -0700 Subject: [PATCH 023/148] Util: Fix overzealous CircleBufferRead/Write16, lots more tests --- src/util/circle-buffer.c | 4 +- src/util/test/circle-buffer.c | 216 +++++++++++++++++++++++++++++++--- 2 files changed, 199 insertions(+), 21 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 12ead5033..274720661 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -102,7 +102,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x3) { + if ((intptr_t) data & 0x1) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -187,7 +187,7 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { if (buffer->size < sizeof(int16_t)) { return 0; } - if ((intptr_t) data & 0x3) { + if ((intptr_t) data & 0x1) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index b60f73a56..0d8234d0c 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -22,41 +22,36 @@ M_TEST_DEFINE(basicCircle) { assert_int_equal(value, i); } - for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); - } - for (i = 0; i < 63; ++i) { - int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); - assert_int_equal(value, i); - } - CircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { struct CircleBuffer buffer; + int8_t i8; CircleBufferInit(&buffer, 64); + // Aligned buffer int16_t i; - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { assert_int_equal(CircleBufferWrite16(&buffer, i), 2); } - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { int16_t value; assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - int8_t i8; + // Misaligned buffer + CircleBufferClear(&buffer); assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - for (i = 0; i < 29; ++i) { + for (i = 0; i < 31; ++i) { assert_int_equal(CircleBufferWrite16(&buffer, i), 2); } - for (i = 0; i < 29; ++i) { + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 31; ++i) { int16_t value; assert_int_equal(CircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); @@ -65,12 +60,12 @@ M_TEST_DEFINE(basicAlignment16) { CircleBufferDeinit(&buffer); } - M_TEST_DEFINE(basicAlignment32) { struct CircleBuffer buffer; CircleBufferInit(&buffer, 64); + // Aligned buffer int32_t i; for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); @@ -81,37 +76,51 @@ M_TEST_DEFINE(basicAlignment32) { assert_int_equal(value, i); } + // Singly misaligned buffer int8_t i8; assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + // Doubly misaligned buffer assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } + // Triply misaligned buffer assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 2), 1); for (i = 0; i < 15; ++i) { assert_int_equal(CircleBufferWrite32(&buffer, i), 4); } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { int32_t value; assert_int_equal(CircleBufferRead32(&buffer, &value), 4); @@ -150,6 +159,168 @@ M_TEST_DEFINE(capacity) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(overflowWrap8) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t value; + int8_t i; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + } + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + for (i = 0; i < 63; ++i) { + assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t value; + int16_t i; + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap16_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int16_t value; + int16_t i; + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 31; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_2) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int16_t i16; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead16(&buffer, &i16), 2); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(overflowWrap32_3) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 64); + + int8_t i8; + int32_t value; + int32_t i; + assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + } + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 15; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i); + } + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(overCapacity16) { struct CircleBuffer buffer; @@ -308,6 +479,13 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), cmocka_unit_test(capacity), + cmocka_unit_test(overflowWrap8), + cmocka_unit_test(overflowWrap16), + cmocka_unit_test(overflowWrap16_1), + cmocka_unit_test(overflowWrap32), + cmocka_unit_test(overflowWrap32_1), + cmocka_unit_test(overflowWrap32_2), + cmocka_unit_test(overflowWrap32_3), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), cmocka_unit_test(writeTruncate), From e8c6613b12276ca439c5a3881f3ae93ab7efd861 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 22:59:08 -0700 Subject: [PATCH 024/148] Util: Fix misaligned end pointer case --- src/util/circle-buffer.c | 8 +- src/util/test/circle-buffer.c | 468 ++++++++++++++++++++++++++++++++++ 2 files changed, 472 insertions(+), 4 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 274720661..032418e16 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -72,7 +72,7 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { if (buffer->size + sizeof(int32_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x3) { + if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -102,7 +102,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } - if ((intptr_t) data & 0x1) { + if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int written = 0; written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); @@ -187,7 +187,7 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { if (buffer->size < sizeof(int16_t)) { return 0; } - if ((intptr_t) data & 0x1) { + if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); @@ -215,7 +215,7 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { if (buffer->size < sizeof(int32_t)) { return 0; } - if ((intptr_t) data & 0x3) { + if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int read = 0; read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 0d8234d0c..545b7cffb 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -321,6 +321,470 @@ M_TEST_DEFINE(overflowWrap32_3) { CircleBufferDeinit(&buffer); } +M_TEST_DEFINE(weirdSize16) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 15); + + // Aligned, no overflow wrap + int16_t value; + int16_t i; + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 7), 0); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Misaligned, no overflow wrap + CircleBufferClear(&buffer); + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 6; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + // Misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 6; ++i) { + assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + } + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 7; ++i) { + assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(value, i * 0x102); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_1) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 13); + + // Aligned, no overflow wrap + int32_t value; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Misaligned, no overflow wrap + CircleBufferClear(&buffer); + int8_t i8; + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_2) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 14); + + // Aligned, no overflow wrap + int32_t value; + int8_t i8; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + +M_TEST_DEFINE(weirdSize32_3) { + struct CircleBuffer buffer; + + CircleBufferInit(&buffer, 15); + + // Aligned, no overflow wrap + int32_t value; + int8_t i8; + int32_t i; + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Triply misaligned, no overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Aligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Singly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Doubly misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + // Triply misaligned, overflow wrap + CircleBufferClear(&buffer); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + + for (i = 0; i < 2; ++i) { + assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + } + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + for (i = 0; i < 3; ++i) { + assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(value, i * 0x1020304); + } + + CircleBufferDeinit(&buffer); +} + M_TEST_DEFINE(overCapacity16) { struct CircleBuffer buffer; @@ -486,6 +950,10 @@ M_TEST_SUITE_DEFINE(CircleBuffer, cmocka_unit_test(overflowWrap32_1), cmocka_unit_test(overflowWrap32_2), cmocka_unit_test(overflowWrap32_3), + cmocka_unit_test(weirdSize16), + cmocka_unit_test(weirdSize32_1), + cmocka_unit_test(weirdSize32_2), + cmocka_unit_test(weirdSize32_3), cmocka_unit_test(overCapacity16), cmocka_unit_test(writeLenCapacity), cmocka_unit_test(writeTruncate), From b62ae33f38954df4acfc966117eb6cbc83f5ceb4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 23:17:07 -0700 Subject: [PATCH 025/148] Util: Change mInterpolator data API --- include/mgba-util/interpolator.h | 8 +++----- src/util/interpolator.c | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 4cb7231fd..43b75da27 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -8,14 +8,12 @@ #include -struct mSampleBuffer { - int16_t* data; - size_t samples; - int channels; +struct mInterpData { + int16_t (*at)(const void* mInterpData, size_t index); }; struct mInterpolator { - int16_t (*interpolate)(const struct mInterpolator* interp, const struct mSampleBuffer* data, double time, double sampleStep); + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpData* data, double time, double sampleStep); }; struct mInterpolatorSinc { diff --git a/src/util/interpolator.c b/src/util/interpolator.c index 2fceee898..a9daaa539 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -10,7 +10,7 @@ enum { mSINC_WIDTH = 8, }; -static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mSampleBuffer* data, double time, double sampleStep); +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -46,7 +46,7 @@ void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { free(interp->windowLut); } -int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mSampleBuffer* data, double time, double sampleStep) { +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpData* data, double time, double sampleStep) { struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; ssize_t index = (ssize_t) time; double subsample = time - floor(time); @@ -75,9 +75,7 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c kernel = interp->sincLut[sinc] * interp->windowLut[window]; kernelSum += kernel; - if (index + i >= 0 && index + i < (ssize_t) data->samples) { - sum += data->data[(index + i) * data->channels] * kernel; - } + sum += data->at(data, index + i) * kernel; } return sum / kernelSum; } From fd4175ebf85ce589ddd0c6da95b41f8f8cdb7bf2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 12 Apr 2024 23:27:37 -0700 Subject: [PATCH 026/148] Util: Rename CircleBuffer to mCircleBuffer --- include/mgba-util/circle-buffer.h | 32 +- include/mgba-util/vfs.h | 4 +- include/mgba/internal/gba/audio.h | 2 +- src/feature/gui/gui-runner.c | 16 +- src/feature/gui/gui-runner.h | 2 +- src/feature/video-logger.c | 64 +-- src/gba/extra/audio-mixer.c | 14 +- src/platform/psp2/psp2-context.c | 12 +- src/platform/sdl/sdl-events.c | 20 +- src/platform/sdl/sdl-events.h | 4 +- src/util/circle-buffer.c | 60 +-- src/util/patch-ups.c | 28 +- src/util/test/circle-buffer.c | 868 +++++++++++++++--------------- src/util/vfs/vfs-fifo.c | 12 +- 14 files changed, 569 insertions(+), 569 deletions(-) diff --git a/include/mgba-util/circle-buffer.h b/include/mgba-util/circle-buffer.h index 137b6a7f9..c93040c6a 100644 --- a/include/mgba-util/circle-buffer.h +++ b/include/mgba-util/circle-buffer.h @@ -10,7 +10,7 @@ CXX_GUARD_START -struct CircleBuffer { +struct mCircleBuffer { void* data; size_t capacity; size_t size; @@ -18,21 +18,21 @@ struct CircleBuffer { void* writePtr; }; -void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity); -void CircleBufferDeinit(struct CircleBuffer* buffer); -size_t CircleBufferSize(const struct CircleBuffer* buffer); -size_t CircleBufferCapacity(const struct CircleBuffer* buffer); -void CircleBufferClear(struct CircleBuffer* buffer); -int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value); -int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value); -int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value); -size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length); -size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length); -int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value); -int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value); -int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value); -size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length); -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset); +void mCircleBufferInit(struct mCircleBuffer* buffer, unsigned capacity); +void mCircleBufferDeinit(struct mCircleBuffer* buffer); +size_t mCircleBufferSize(const struct mCircleBuffer* buffer); +size_t mCircleBufferCapacity(const struct mCircleBuffer* buffer); +void mCircleBufferClear(struct mCircleBuffer* buffer); +int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value); +int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value); +int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value); +size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_t length); +size_t mCircleBufferWriteTruncate(struct mCircleBuffer* buffer, const void* input, size_t length); +int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value); +int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value); +int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value); +size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t length); +size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_t length, size_t offset); CXX_GUARD_END diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index eee68b99e..b9c4ca6b2 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -73,8 +73,8 @@ struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); struct VFile* VFileMemChunk(const void* mem, size_t size); -struct CircleBuffer; -struct VFile* VFileFIFO(struct CircleBuffer* backing); +struct mCircleBuffer; +struct VFile* VFileFIFO(struct mCircleBuffer* backing); struct VDir* VDirOpen(const char* path); struct VDir* VDirOpenArchive(const char* path); diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 8b212dd6a..f2d878e4e 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -253,7 +253,7 @@ struct GBAMP2kTrack { struct GBAMP2kMusicPlayerTrack track; struct GBAMP2kSoundChannel* channel; uint8_t lastCommand; - struct CircleBuffer buffer; + struct mCircleBuffer buffer; uint32_t samplePlaying; float currentOffset; bool waiting; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 8c25a79fb..b3ce21ad9 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -220,7 +220,7 @@ void mGUIInit(struct mGUIRunner* runner, const char* port) { runner->fps = 0; runner->lastFpsCheck = 0; runner->totalDelta = 0; - CircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); + mCircleBufferInit(&runner->fpsBuffer, FPS_BUFFER_SIZE * sizeof(uint32_t)); mInputMapInit(&runner->params.keyMap, &_mGUIKeyInfo); mCoreConfigInit(&runner->config, runner->port); @@ -284,7 +284,7 @@ void mGUIDeinit(struct mGUIRunner* runner) { if (runner->teardown) { runner->teardown(runner); } - CircleBufferDeinit(&runner->fpsBuffer); + mCircleBufferDeinit(&runner->fpsBuffer); mInputMapDeinit(&runner->params.keyMap); mCoreConfigDeinit(&runner->config); if (logger.vf) { @@ -502,7 +502,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->fps = 0; bool fastForward = false; while (running) { - CircleBufferClear(&runner->fpsBuffer); + mCircleBufferClear(&runner->fpsBuffer); runner->totalDelta = 0; struct timeval tv; gettimeofday(&tv, 0); @@ -610,17 +610,17 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { uint64_t delta = t - runner->lastFpsCheck; runner->lastFpsCheck = t; if (delta > 0x7FFFFFFFLL) { - CircleBufferClear(&runner->fpsBuffer); + mCircleBufferClear(&runner->fpsBuffer); runner->fps = 0; } - if (CircleBufferSize(&runner->fpsBuffer) == CircleBufferCapacity(&runner->fpsBuffer)) { + if (mCircleBufferSize(&runner->fpsBuffer) == mCircleBufferCapacity(&runner->fpsBuffer)) { int32_t last; - CircleBufferRead32(&runner->fpsBuffer, &last); + mCircleBufferRead32(&runner->fpsBuffer, &last); runner->totalDelta -= last; } - CircleBufferWrite32(&runner->fpsBuffer, delta); + mCircleBufferWrite32(&runner->fpsBuffer, delta); runner->totalDelta += delta; - runner->fps = (CircleBufferSize(&runner->fpsBuffer) * FPS_GRANULARITY * 1000000.0f) / (runner->totalDelta * sizeof(uint32_t)); + runner->fps = (mCircleBufferSize(&runner->fpsBuffer) * FPS_GRANULARITY * 1000000.0f) / (runner->totalDelta * sizeof(uint32_t)); } } if (frame % (AUTOSAVE_GRANULARITY * (fastForwarding ? 2 : 1)) == 0) { diff --git a/src/feature/gui/gui-runner.h b/src/feature/gui/gui-runner.h index 0dc412838..334ef57d9 100644 --- a/src/feature/gui/gui-runner.h +++ b/src/feature/gui/gui-runner.h @@ -78,7 +78,7 @@ struct mGUIRunner { float fps; int64_t lastFpsCheck; int32_t totalDelta; - struct CircleBuffer fpsBuffer; + struct mCircleBuffer fpsBuffer; void (*setup)(struct mGUIRunner*); void (*teardown)(struct mGUIRunner*); diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index fb2065b42..978700864 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -87,8 +87,8 @@ struct mVideoLogChannel { enum mVideoLoggerInjectionPoint injectionPoint; uint32_t ignorePackets; - struct CircleBuffer injectedBuffer; - struct CircleBuffer buffer; + struct mCircleBuffer injectedBuffer; + struct mCircleBuffer buffer; }; struct mVideoLogContext { @@ -662,8 +662,8 @@ 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); + mCircleBufferInit(&context->channels[i].injectedBuffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[i].buffer, BUFFER_BASE_SIZE); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; context->channels[i].p = context; @@ -676,8 +676,8 @@ bool mVideoLogContextLoad(struct mVideoLogContext* context, struct VFile* vf) { #ifdef USE_ZLIB static void _flushBufferCompressed(struct mVideoLogContext* context) { - struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; - if (!CircleBufferSize(buffer)) { + struct mCircleBuffer* buffer = &context->channels[context->activeChannel].buffer; + if (!mCircleBufferSize(buffer)) { return; } struct VFile* vfm = VFileMemChunk(NULL, 0); @@ -707,20 +707,20 @@ static void _flushBuffer(struct mVideoLogContext* context) { } #endif - struct CircleBuffer* buffer = &context->channels[context->activeChannel].buffer; - if (!CircleBufferSize(buffer)) { + struct mCircleBuffer* buffer = &context->channels[context->activeChannel].buffer; + if (!mCircleBufferSize(buffer)) { return; } struct mVLBlockHeader header = { 0 }; STORE_32LE(mVL_BLOCK_DATA, 0, &header.blockType); - STORE_32LE(CircleBufferSize(buffer), 0, &header.length); + STORE_32LE(mCircleBufferSize(buffer), 0, &header.length); STORE_32LE(context->activeChannel, 0, &header.channelId); context->backing->write(context->backing, &header, sizeof(header)); uint8_t writeBuffer[0x800]; - while (CircleBufferSize(buffer)) { - size_t read = CircleBufferRead(buffer, writeBuffer, sizeof(writeBuffer)); + while (mCircleBufferSize(buffer)) { + size_t read = mCircleBufferRead(buffer, writeBuffer, sizeof(writeBuffer)); context->backing->write(context->backing, writeBuffer, read); } } @@ -743,8 +743,8 @@ 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); + mCircleBufferDeinit(&context->channels[i].injectedBuffer); + mCircleBufferDeinit(&context->channels[i].buffer); #ifdef USE_ZLIB if (context->channels[i].inflating) { inflateEnd(&context->channels[i].inflateStream); @@ -778,8 +778,8 @@ 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); + mCircleBufferClear(&context->channels[i].injectedBuffer); + mCircleBufferClear(&context->channels[i].buffer); context->channels[i].bufferRemaining = 0; context->channels[i].currentPointer = pointer; #ifdef USE_ZLIB @@ -805,8 +805,8 @@ 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); + mCircleBufferInit(&context->channels[chid].injectedBuffer, BUFFER_BASE_SIZE); + mCircleBufferInit(&context->channels[chid].buffer, BUFFER_BASE_SIZE); context->channels[chid].injecting = false; context->channels[chid].injectionPoint = LOGGER_INJECTION_IMMEDIATE; context->channels[chid].ignorePackets = 0; @@ -898,7 +898,7 @@ static size_t _readBufferCompressed(struct VFile* vf, struct mVideoLogChannel* c } } - thisWrite = CircleBufferWrite(&channel->buffer, zbuffer, thisWrite - channel->inflateStream.avail_out); + thisWrite = mCircleBufferWrite(&channel->buffer, zbuffer, thisWrite - channel->inflateStream.avail_out); length -= thisWrite; read += thisWrite; @@ -921,7 +921,7 @@ static void _readBuffer(struct VFile* vf, struct mVideoLogChannel* channel, size if (thisRead <= 0) { return; } - size_t thisWrite = CircleBufferWrite(&channel->buffer, buffer, thisRead); + size_t thisWrite = mCircleBufferWrite(&channel->buffer, buffer, thisRead); length -= thisWrite; channel->bufferRemaining -= thisWrite; channel->currentPointer += thisWrite; @@ -986,16 +986,16 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (channelId >= mVL_MAX_CHANNELS) { return 0; } - struct CircleBuffer* buffer = &channel->buffer; + struct mCircleBuffer* buffer = &channel->buffer; if (channel->injecting) { buffer = &channel->injectedBuffer; } - if (CircleBufferSize(buffer) >= length) { - return CircleBufferRead(buffer, data, length); + if (mCircleBufferSize(buffer) >= length) { + return mCircleBufferRead(buffer, data, length); } ssize_t size = 0; - if (CircleBufferSize(buffer)) { - size = CircleBufferRead(buffer, data, CircleBufferSize(buffer)); + if (mCircleBufferSize(buffer)) { + size = mCircleBufferRead(buffer, data, mCircleBufferSize(buffer)); if (size <= 0) { return size; } @@ -1005,7 +1005,7 @@ static ssize_t mVideoLoggerReadChannel(struct mVideoLogChannel* channel, void* d if (channel->injecting || !_fillBuffer(context, channelId, BUFFER_BASE_SIZE)) { return size; } - size += CircleBufferRead(buffer, data, length); + size += mCircleBufferRead(buffer, data, length); return size; } @@ -1019,20 +1019,20 @@ static ssize_t mVideoLoggerWriteChannel(struct mVideoLogChannel* channel, const _flushBuffer(context); context->activeChannel = channelId; } - struct CircleBuffer* buffer = &channel->buffer; + struct mCircleBuffer* buffer = &channel->buffer; if (channel->injecting) { buffer = &channel->injectedBuffer; } - if (CircleBufferCapacity(buffer) - CircleBufferSize(buffer) < length) { + if (mCircleBufferCapacity(buffer) - mCircleBufferSize(buffer) < length) { _flushBuffer(context); - if (CircleBufferCapacity(buffer) < length) { - CircleBufferDeinit(buffer); - CircleBufferInit(buffer, toPow2(length << 1)); + if (mCircleBufferCapacity(buffer) < length) { + mCircleBufferDeinit(buffer); + mCircleBufferInit(buffer, toPow2(length << 1)); } } - ssize_t read = CircleBufferWrite(buffer, data, length); - if (CircleBufferCapacity(buffer) == CircleBufferSize(buffer)) { + ssize_t read = mCircleBufferWrite(buffer, data, length); + if (mCircleBufferCapacity(buffer) == mCircleBufferSize(buffer)) { _flushBuffer(context); } return read; diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c index 2a14f1ce6..e01b609b4 100644 --- a/src/gba/extra/audio-mixer.c +++ b/src/gba/extra/audio-mixer.c @@ -43,7 +43,7 @@ void _mp2kInit(void* cpu, struct mCPUComponent* component) { 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); + mCircleBufferInit(&mixer->activeTracks[i].buffer, 0x10000); } } @@ -51,7 +51,7 @@ 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); + mCircleBufferDeinit(&mixer->activeTracks[i].buffer); } } @@ -130,8 +130,8 @@ static void _stepSample(struct GBAAudioMixer* mixer, struct GBAMP2kTrack* track) (sample * track->channel->rightVolume * track->channel->envelopeV) >> 9 }; - CircleBufferWrite16(&track->buffer, stereo.left); - CircleBufferWrite16(&track->buffer, stereo.right); + mCircleBufferWrite16(&track->buffer, stereo.left); + mCircleBufferWrite16(&track->buffer, stereo.right); sampleOffset += mixer->p->sampleInterval / OVERSAMPLE; while (sampleOffset > freq) { @@ -265,7 +265,7 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { } else { track->currentOffset = 0; track->samplePlaying = 0; - CircleBufferClear(&track->buffer); + mCircleBufferClear(&track->buffer); } } mixer->frame -= VIDEO_TOTAL_LENGTH / mixer->tempo; @@ -281,9 +281,9 @@ void _mp2kStep(struct GBAAudioMixer* mixer) { continue; } int16_t value; - CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.left += value; - CircleBufferRead16(&mixer->activeTracks[track].buffer, &value); + mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); sample.right += value; } sample.left = (sample.left * mixer->p->masterVolume) >> 8; diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 1e48c2f24..34623a876 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -65,7 +65,7 @@ static struct mSceRotationSource { static struct mSceRumble { struct mRumble d; - struct CircleBuffer history; + struct mCircleBuffer history; int current; } rumble; @@ -155,12 +155,12 @@ static int32_t _readGyroZ(struct mRotationSource* source) { static void _setRumble(struct mRumble* source, int enable) { struct mSceRumble* rumble = (struct mSceRumble*) source; rumble->current += enable; - if (CircleBufferSize(&rumble->history) == RUMBLE_PWM) { + if (mCircleBufferSize(&rumble->history) == RUMBLE_PWM) { int8_t oldLevel; - CircleBufferRead8(&rumble->history, &oldLevel); + mCircleBufferRead8(&rumble->history, &oldLevel); rumble->current -= oldLevel; } - CircleBufferWrite8(&rumble->history, enable); + mCircleBufferWrite8(&rumble->history, enable); int small = (rumble->current << 21) / 65793; int big = ((rumble->current * rumble->current) << 18) / 65793; struct SceCtrlActuator state = { @@ -342,7 +342,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation.d); rumble.d.setRumble = _setRumble; - CircleBufferInit(&rumble.history, RUMBLE_PWM); + mCircleBufferInit(&rumble.history, RUMBLE_PWM); runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); camera.d.startRequestImage = _startRequestImage; @@ -482,7 +482,7 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); - CircleBufferDeinit(&rumble.history); + mCircleBufferDeinit(&rumble.history); vita2d_free_texture(tex[0]); vita2d_free_texture(tex[1]); vita2d_free_texture(screenshot); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index eceaf1808..950bb94f3 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -202,7 +202,7 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { #if SDL_VERSION_ATLEAST(2, 0, 0) player->rumble.d.setRumble = _mSDLSetRumble; - CircleBufferInit(&player->rumble.history, RUMBLE_PWM); + mCircleBufferInit(&player->rumble.history, RUMBLE_PWM); player->rumble.level = 0; player->rumble.activeLevel = 0; player->rumble.p = player; @@ -219,7 +219,7 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { player->rotation.gyroY = 1; player->rotation.gyroZ = -1; player->rotation.zDelta = 0; - CircleBufferInit(&player->rotation.zHistory, sizeof(float) * GYRO_STEPS); + mCircleBufferInit(&player->rotation.zHistory, sizeof(float) * GYRO_STEPS); player->rotation.p = player; player->playerId = events->playersAttached; @@ -293,9 +293,9 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } } --events->playersAttached; - CircleBufferDeinit(&player->rotation.zHistory); + mCircleBufferDeinit(&player->rotation.zHistory); #if SDL_VERSION_ATLEAST(2, 0, 0) - CircleBufferDeinit(&player->rumble.history); + mCircleBufferDeinit(&player->rumble.history); #endif } @@ -739,12 +739,12 @@ static void _mSDLSetRumble(struct mRumble* rumble, int enable) { int8_t originalLevel = sdlRumble->level; sdlRumble->level += enable; - if (CircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { + if (mCircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { int8_t oldLevel; - CircleBufferRead8(&sdlRumble->history, &oldLevel); + mCircleBufferRead8(&sdlRumble->history, &oldLevel); sdlRumble->level -= oldLevel; } - CircleBufferWrite8(&sdlRumble->history, enable); + mCircleBufferWrite8(&sdlRumble->history, enable); if (sdlRumble->level == originalLevel) { return; } @@ -851,10 +851,10 @@ static void _mSDLRotationSample(struct mRotationSource* source) { rotation->oldY = y; float oldZ = 0; - if (CircleBufferSize(&rotation->zHistory) == GYRO_STEPS * sizeof(float)) { - CircleBufferRead32(&rotation->zHistory, (int32_t*) &oldZ); + if (mCircleBufferSize(&rotation->zHistory) == GYRO_STEPS * sizeof(float)) { + mCircleBufferRead32(&rotation->zHistory, (int32_t*) &oldZ); } - CircleBufferWrite32(&rotation->zHistory, theta.i); + mCircleBufferWrite32(&rotation->zHistory, theta.i); rotation->zDelta += theta.f - oldZ; } diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 741503be4..877818a01 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -76,7 +76,7 @@ struct mSDLPlayer { int level; float activeLevel; - struct CircleBuffer history; + struct mCircleBuffer history; } rumble; #else int newWidth; @@ -98,7 +98,7 @@ struct mSDLPlayer { int gyroY; int gyroZ; float gyroSensitivity; - struct CircleBuffer zHistory; + struct mCircleBuffer zHistory; int oldX; int oldY; float zDelta; diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 032418e16..f0d074d36 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -6,7 +6,7 @@ #include #ifndef NDEBUG -static int _checkIntegrity(struct CircleBuffer* buffer) { +static int _checkIntegrity(struct mCircleBuffer* buffer) { if ((int8_t*) buffer->writePtr - (int8_t*) buffer->readPtr == (ssize_t) buffer->size) { return 1; } @@ -20,32 +20,32 @@ static int _checkIntegrity(struct CircleBuffer* buffer) { } #endif -void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity) { +void mCircleBufferInit(struct mCircleBuffer* buffer, unsigned capacity) { buffer->data = malloc(capacity); buffer->capacity = capacity; - CircleBufferClear(buffer); + mCircleBufferClear(buffer); } -void CircleBufferDeinit(struct CircleBuffer* buffer) { +void mCircleBufferDeinit(struct mCircleBuffer* buffer) { free(buffer->data); buffer->data = 0; } -size_t CircleBufferSize(const struct CircleBuffer* buffer) { +size_t mCircleBufferSize(const struct mCircleBuffer* buffer) { return buffer->size; } -size_t CircleBufferCapacity(const struct CircleBuffer* buffer) { +size_t mCircleBufferCapacity(const struct mCircleBuffer* buffer) { return buffer->capacity; } -void CircleBufferClear(struct CircleBuffer* buffer) { +void mCircleBufferClear(struct mCircleBuffer* buffer) { buffer->size = 0; buffer->readPtr = buffer->data; buffer->writePtr = buffer->data; } -int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) { +int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value) { int8_t* data = buffer->writePtr; if (buffer->size + sizeof(int8_t) > buffer->capacity) { return 0; @@ -67,17 +67,17 @@ int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value) { return 1; } -int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { +int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value) { int32_t* data = buffer->writePtr; if (buffer->size + sizeof(int32_t) > buffer->capacity) { return 0; } if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int written = 0; - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[2]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[3]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[0]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[1]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[2]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[3]); return written; } *data = value; @@ -97,15 +97,15 @@ int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value) { return 4; } -int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { +int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value) { int16_t* data = buffer->writePtr; if (buffer->size + sizeof(int16_t) > buffer->capacity) { return 0; } if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int written = 0; - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[0]); - written += CircleBufferWrite8(buffer, ((int8_t*) &value)[1]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[0]); + written += mCircleBufferWrite8(buffer, ((int8_t*) &value)[1]); return written; } *data = value; @@ -125,7 +125,7 @@ int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value) { return 2; } -size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length) { +size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_t length) { int8_t* data = buffer->writePtr; if (buffer->size + length > buffer->capacity) { return 0; @@ -153,14 +153,14 @@ size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t return length; } -size_t CircleBufferWriteTruncate(struct CircleBuffer* buffer, const void* input, size_t length) { +size_t mCircleBufferWriteTruncate(struct mCircleBuffer* buffer, const void* input, size_t length) { if (buffer->size + length > buffer->capacity) { length = buffer->capacity - buffer->size; } - return CircleBufferWrite(buffer, input, length); + return mCircleBufferWrite(buffer, input, length); } -int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { +int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value) { int8_t* data = buffer->readPtr; if (buffer->size < sizeof(int8_t)) { return 0; @@ -182,15 +182,15 @@ int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value) { return 1; } -int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { +int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value) { int16_t* data = buffer->readPtr; if (buffer->size < sizeof(int16_t)) { return 0; } if (((intptr_t) data & 0x1) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int16_t)) { int read = 0; - read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[0]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[1]); return read; } *value = *data; @@ -210,17 +210,17 @@ int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value) { return 2; } -int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { +int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value) { int32_t* data = buffer->readPtr; if (buffer->size < sizeof(int32_t)) { return 0; } if (((intptr_t) data & 0x3) || (uintptr_t) data - (uintptr_t) buffer->data > buffer->capacity - sizeof(int32_t)) { int read = 0; - read += CircleBufferRead8(buffer, &((int8_t*) value)[0]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[1]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[2]); - read += CircleBufferRead8(buffer, &((int8_t*) value)[3]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[0]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[1]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[2]); + read += mCircleBufferRead8(buffer, &((int8_t*) value)[3]); return read; } *value = *data; @@ -240,7 +240,7 @@ int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value) { return 4; } -size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length) { +size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t length) { int8_t* data = buffer->readPtr; if (buffer->size == 0) { return 0; @@ -271,7 +271,7 @@ size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length return length; } -size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length, size_t offset) { +size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_t length, size_t offset) { int8_t* data = buffer->readPtr; if (buffer->size <= offset) { return 0; diff --git a/src/util/patch-ups.c b/src/util/patch-ups.c index bce88e74d..72d0e14a8 100644 --- a/src/util/patch-ups.c +++ b/src/util/patch-ups.c @@ -23,7 +23,7 @@ static size_t _UPSOutputSize(struct Patch* patch, size_t inSize); static bool _UPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize); static bool _BPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize); -static size_t _decodeLength(struct VFile* vf, struct CircleBuffer* buffer); +static size_t _decodeLength(struct VFile* vf, struct mCircleBuffer* buffer); bool loadPatchUPS(struct Patch* patch) { patch->vf->seek(patch->vf, 0, SEEK_SET); @@ -77,42 +77,42 @@ bool _UPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* ou return false; } - struct CircleBuffer buffer; + struct mCircleBuffer buffer; memcpy(out, in, inSize > outSize ? outSize : inSize); size_t offset = 0; size_t alreadyRead = 0; uint8_t* buf = out; - CircleBufferInit(&buffer, BUFFER_SIZE); + mCircleBufferInit(&buffer, BUFFER_SIZE); while (alreadyRead < filesize + IN_CHECKSUM) { offset += _decodeLength(patch->vf, &buffer); int8_t byte; while (true) { - if (!CircleBufferSize(&buffer)) { + if (!mCircleBufferSize(&buffer)) { uint8_t block[BUFFER_SIZE]; ssize_t read = patch->vf->read(patch->vf, block, sizeof(block)); if (read < 1) { - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); return false; } - CircleBufferWrite(&buffer, block, read); + mCircleBufferWrite(&buffer, block, read); } - CircleBufferRead8(&buffer, &byte); + mCircleBufferRead8(&buffer, &byte); if (!byte) { break; } if (offset >= outSize) { - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); return false; } buf[offset] ^= byte; ++offset; } ++offset; - alreadyRead = patch->vf->seek(patch->vf, 0, SEEK_CUR) - CircleBufferSize(&buffer); + alreadyRead = patch->vf->seek(patch->vf, 0, SEEK_CUR) - mCircleBufferSize(&buffer); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); uint32_t goodCrc32; patch->vf->seek(patch->vf, OUT_CHECKSUM, SEEK_END); @@ -223,21 +223,21 @@ bool _BPSApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* ou return true; } -size_t _decodeLength(struct VFile* vf, struct CircleBuffer* buffer) { +size_t _decodeLength(struct VFile* vf, struct mCircleBuffer* buffer) { size_t shift = 1; size_t value = 0; uint8_t byte; while (true) { if (buffer) { - if (!CircleBufferSize(buffer)) { + if (!mCircleBufferSize(buffer)) { uint8_t block[BUFFER_SIZE]; ssize_t read = vf->read(vf, block, sizeof(block)); if (read < 1) { return false; } - CircleBufferWrite(buffer, block, read); + mCircleBufferWrite(buffer, block, read); } - CircleBufferRead8(buffer, (int8_t*) &byte); + mCircleBufferRead8(buffer, (int8_t*) &byte); } else { if (vf->read(vf, &byte, 1) != 1) { break; diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 545b7cffb..9ba383971 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -8,937 +8,937 @@ #include M_TEST_DEFINE(basicCircle) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } for (i = 0; i < 63; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; int8_t i8; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); // Aligned buffer int16_t i; for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } for (i = 0; i < 31; ++i) { int16_t value; - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } // Misaligned buffer - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 31; ++i) { int16_t value; - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(basicAlignment32) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); // Aligned buffer int32_t i; for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Singly misaligned buffer int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Doubly misaligned buffer - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 1), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } // Triply misaligned buffer - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 1), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 2), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 1), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 2), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { int32_t value; - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(capacity) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 64; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } for (i = 0; i < 64; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } for (i = 0; i < 64; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferWrite8(&buffer, 64), 0); + assert_int_equal(mCircleBufferWrite8(&buffer, 64), 0); for (i = 0; i < 64; ++i) { int8_t value; - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap8) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t value; int8_t i; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferRead8(&buffer, &value), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &value), 1); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int16_t value; int16_t i; - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap16_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int16_t value; int16_t i; - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 31; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_2) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int16_t i16; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite16(&buffer, 0), 2); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite16(&buffer, 0), 2); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead16(&buffer, &i16), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &i16), 2); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overflowWrap32_3) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i8; int32_t value; int32_t i; - assert_int_equal(CircleBufferWrite32(&buffer, 0), 4); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 0), 4); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 15; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 15); + mCircleBufferInit(&buffer, 15); // Aligned, no overflow wrap int16_t value; int16_t i; for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 7), 0); + assert_int_equal(mCircleBufferWrite16(&buffer, 7), 0); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Misaligned, no overflow wrap - CircleBufferClear(&buffer); + mCircleBufferClear(&buffer); int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 6; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 2); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } // Misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 6; ++i) { - assert_int_equal(CircleBufferWrite16(&buffer, i * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, i * 0x102), 2); } - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite16(&buffer, 6 * 0x102), 2); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite16(&buffer, 6 * 0x102), 2); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 7; ++i) { - assert_int_equal(CircleBufferRead16(&buffer, &value), 2); + assert_int_equal(mCircleBufferRead16(&buffer, &value), 2); assert_int_equal(value, i * 0x102); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_1) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 13); + mCircleBufferInit(&buffer, 13); // Aligned, no overflow wrap int32_t value; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Misaligned, no overflow wrap - CircleBufferClear(&buffer); + mCircleBufferClear(&buffer); int8_t i8; - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_2) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 14); + mCircleBufferInit(&buffer, 14); // Aligned, no overflow wrap int32_t value; int8_t i8; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(weirdSize32_3) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 15); + mCircleBufferInit(&buffer, 15); // Aligned, no overflow wrap int32_t value; int8_t i8; int32_t i; for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 3), 0); + assert_int_equal(mCircleBufferWrite32(&buffer, 3), 0); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Triply misaligned, no overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Aligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Singly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Doubly misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } // Triply misaligned, overflow wrap - CircleBufferClear(&buffer); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); - assert_int_equal(CircleBufferWrite8(&buffer, 0), 1); + mCircleBufferClear(&buffer); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, 0), 1); for (i = 0; i < 2; ++i) { - assert_int_equal(CircleBufferWrite32(&buffer, i * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, i * 0x1020304), 4); } - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 0); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferWrite32(&buffer, 2 * 0x1020304), 4); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 0); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferWrite32(&buffer, 2 * 0x1020304), 4); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); - assert_int_equal(CircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); + assert_int_equal(mCircleBufferRead8(&buffer, &i8), 1); for (i = 0; i < 3; ++i) { - assert_int_equal(CircleBufferRead32(&buffer, &value), 4); + assert_int_equal(mCircleBufferRead32(&buffer, &value), 4); assert_int_equal(value, i * 0x1020304); } - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(overCapacity16) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); int8_t i; for (i = 0; i < 63; ++i) { - assert_int_equal(CircleBufferWrite8(&buffer, i), 1); + assert_int_equal(mCircleBufferWrite8(&buffer, i), 1); } - assert_int_equal(CircleBufferWrite16(&buffer, 0xFFFF), 0); + assert_int_equal(mCircleBufferWrite16(&buffer, 0xFFFF), 0); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(writeLenCapacity) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 48); assert_memory_equal(data, databuf, 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 48); assert_memory_equal(data, &databuf[48], 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(writeTruncate) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 0); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferWriteTruncate(&buffer, data, 48), 16); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 0); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWriteTruncate(&buffer, data, 48), 16); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); assert_memory_equal(data, databuf, 48); assert_memory_equal(data, &databuf[48], 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(dumpBasic) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 0); assert_memory_equal(data, databuf, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 48, 0), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); assert_memory_equal(data, databuf, 48); - assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(data, databuf, 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 48, 0), 32); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 48, 0), 32); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 64, 0), 64); - assert_int_equal(CircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); assert_memory_equal(&data[16], databuf, 32); assert_memory_equal(data, &databuf[32], 32); - assert_int_equal(CircleBufferRead(&buffer, databuf, 64), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 64), 64); assert_memory_equal(&data[16], databuf, 32); assert_memory_equal(data, &databuf[32], 32); - assert_int_equal(CircleBufferSize(&buffer), 0); + assert_int_equal(mCircleBufferSize(&buffer), 0); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } M_TEST_DEFINE(dumpOffset) { - struct CircleBuffer buffer; + struct mCircleBuffer buffer; const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; char databuf[64]; - CircleBufferInit(&buffer, 64); + mCircleBufferInit(&buffer, 64); - assert_int_equal(CircleBufferWrite(&buffer, data, 48), 48); - assert_int_equal(CircleBufferSize(&buffer), 48); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferWrite(&buffer, data, 48), 48); + assert_int_equal(mCircleBufferSize(&buffer), 48); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(data, databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 32), 16); assert_memory_equal(&data[32], databuf, 16); - assert_int_equal(CircleBufferRead(&buffer, databuf, 16), 16); - assert_int_equal(CircleBufferSize(&buffer), 32); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); assert_memory_equal(data, databuf, 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 16); assert_memory_equal(&data[32], databuf, 16); - assert_int_equal(CircleBufferWrite(&buffer, data, 32), 32); - assert_int_equal(CircleBufferSize(&buffer), 64); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 0), 32); + assert_int_equal(mCircleBufferWrite(&buffer, data, 32), 32); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 0), 32); assert_memory_equal(&data[16], databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 16), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 16), 32); assert_memory_equal(&data[32], databuf, 16); assert_memory_equal(data, &databuf[16], 16); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 32), 32); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 32), 32); assert_memory_equal(data, databuf, 32); - assert_int_equal(CircleBufferDump(&buffer, databuf, 32, 48), 16); + assert_int_equal(mCircleBufferDump(&buffer, databuf, 32, 48), 16); assert_memory_equal(&data[16], databuf, 16); - CircleBufferDeinit(&buffer); + mCircleBufferDeinit(&buffer); } -M_TEST_SUITE_DEFINE(CircleBuffer, +M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), cmocka_unit_test(basicAlignment32), diff --git a/src/util/vfs/vfs-fifo.c b/src/util/vfs/vfs-fifo.c index 5b6af5760..c7bb5be04 100644 --- a/src/util/vfs/vfs-fifo.c +++ b/src/util/vfs/vfs-fifo.c @@ -8,7 +8,7 @@ struct VFileFIFO { struct VFile d; - struct CircleBuffer* backing; + struct mCircleBuffer* backing; }; static bool _vffClose(struct VFile* vf); @@ -21,7 +21,7 @@ static void _vffTruncate(struct VFile* vf, size_t size); static ssize_t _vffSize(struct VFile* vf); static bool _vffSync(struct VFile* vf, void* buffer, size_t size); -struct VFile* VFileFIFO(struct CircleBuffer* backing) { +struct VFile* VFileFIFO(struct mCircleBuffer* backing) { if (!backing) { return NULL; } @@ -61,12 +61,12 @@ static off_t _vffSeek(struct VFile* vf, off_t offset, int whence) { static ssize_t _vffRead(struct VFile* vf, void* buffer, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferRead(vff->backing, buffer, size); + return mCircleBufferRead(vff->backing, buffer, size); } static ssize_t _vffWrite(struct VFile* vf, const void* buffer, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferWrite(vff->backing, buffer, size); + return mCircleBufferWrite(vff->backing, buffer, size); } static void* _vffMap(struct VFile* vf, size_t size, int flags) { @@ -85,13 +85,13 @@ static void _vffUnmap(struct VFile* vf, void* memory, size_t size) { static void _vffTruncate(struct VFile* vf, size_t size) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; if (!size) { - CircleBufferClear(vff->backing); + mCircleBufferClear(vff->backing); } } static ssize_t _vffSize(struct VFile* vf) { struct VFileFIFO* vff = (struct VFileFIFO*) vf; - return CircleBufferSize(vff->backing); + return mCircleBufferSize(vff->backing); } static bool _vffSync(struct VFile* vf, void* buffer, size_t size) { From 237d502404632de326c9c467f8a2c691f89f25c2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 13 Apr 2024 00:48:37 -0700 Subject: [PATCH 027/148] Util: Add prototype mAudioBuffer wrapper --- include/mgba-util/audio-buffer.h | 34 ++++++++++++++++++ src/util/audio-buffer.c | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 include/mgba-util/audio-buffer.h create mode 100644 src/util/audio-buffer.c diff --git a/include/mgba-util/audio-buffer.h b/include/mgba-util/audio-buffer.h new file mode 100644 index 000000000..b6d760822 --- /dev/null +++ b/include/mgba-util/audio-buffer.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2013-2024 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_AUDIO_BUFFER_H +#define M_AUDIO_BUFFER_H + +#include + +CXX_GUARD_START + +#include + +struct mAudioBuffer { + struct mCircleBuffer data; + unsigned channels; +}; + +void mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels); +void mAudioBufferDeinit(struct mAudioBuffer* buffer); + +size_t mAudioBufferAvailable(const struct mAudioBuffer* buffer); +size_t mAudioBufferCapacity(const struct mAudioBuffer* buffer); + +void mAudioBufferClear(struct mAudioBuffer* buffer); +int16_t mAudioBufferPeek(const struct mAudioBuffer* buffer, unsigned channel, size_t offset); +size_t mAudioBufferDump(const struct mAudioBuffer* buffer, int16_t* samples, size_t count, size_t offset); +size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t count); +size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count); + +CXX_GUARD_END + +#endif diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c new file mode 100644 index 000000000..bb705b38c --- /dev/null +++ b/src/util/audio-buffer.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2013-2024 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 mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels) { + mCircleBufferInit(&buffer->data, capacity * channels * sizeof(int16_t)); + buffer->channels = capacity; +} + +void mAudioBufferDeinit(struct mAudioBuffer* buffer) { + mCircleBufferDeinit(&buffer->data); +} + +size_t mAudioBufferAvailable(const struct mAudioBuffer* buffer) { + return mCircleBufferSize(&buffer->data) / (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferCapacity(const struct mAudioBuffer* buffer) { + return mCircleBufferCapacity(&buffer->data) / (buffer->channels * sizeof(int16_t)); +} + +void mAudioBufferClear(struct mAudioBuffer* buffer) { + mCircleBufferClear(&buffer->data); +} + +int16_t mAudioBufferPeek(const struct mAudioBuffer* buffer, unsigned channel, size_t offset) { + int16_t sample; + if (!mCircleBufferDump(&buffer->data, &sample, sizeof(int16_t), (offset * buffer->channels + channel) * sizeof(int16_t))) { + return 0; + } + return sample; +} + +size_t mAudioBufferDump(const struct mAudioBuffer* buffer, int16_t* samples, size_t count, size_t offset) { + return mCircleBufferDump(&buffer->data, + samples, + count * buffer->channels * sizeof(int16_t), + offset * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t count) { + return mCircleBufferRead(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} + +size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count) { + size_t free = mCircleBufferCapacity(&buffer->data) - mCircleBufferSize(&buffer->data); + if (count * buffer->channels * sizeof(int16_t) > free) { + count = free / (buffer->channels * sizeof(int16_t)); + } + return mCircleBufferWrite(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / + (buffer->channels * sizeof(int16_t)); +} From f13a087b040e07a41f0ce61d5b5b0b1ab581e67b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:17:15 -0700 Subject: [PATCH 028/148] Feature: Fix (unused) mVideoProxyBackendRun with block=true --- src/feature/proxy-backend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feature/proxy-backend.c b/src/feature/proxy-backend.c index fb6e555ed..3cfe7c39d 100644 --- a/src/feature/proxy-backend.c +++ b/src/feature/proxy-backend.c @@ -229,7 +229,7 @@ bool mVideoProxyBackendRun(struct mVideoProxyBackend* proxy, bool block) { } ok = true; } - } while (block); + } while (block && !ok); return ok; } From 2d7000c8ae4cf0c7da4d283fe1f711290f2847ab Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:18:43 -0700 Subject: [PATCH 029/148] Util: Remove unreachable code --- src/util/string.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/util/string.c b/src/util/string.c index b2bf376c6..4a9e35de5 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -285,9 +285,6 @@ char* latin1ToUtf8(const char* latin1, size_t length) { size_t utf8TotalBytes = 0; size_t utf8Length = 0; for (offset = 0; offset < length; ++offset) { - if (length == 0) { - break; - } uint8_t unichar = latin1[offset]; size_t bytes = toUtf8(unichar, buffer); utf8Length += bytes; From a999a8760733cd226741d5e9cc05557aeda3eee3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 04:22:40 -0700 Subject: [PATCH 030/148] Debugger: Actually handle parseLexedExpression returning false --- src/debugger/cli-debugger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 6d5b70e97..95b2037dc 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -615,7 +615,7 @@ static struct ParseTree* _parseTree(const char** string) { struct ParseTree* tree = NULL; if (!error) { tree = parseTreeCreate(); - parseLexedExpression(tree, &lv); + error = !parseLexedExpression(tree, &lv); } lexFree(&lv); LexVectorClear(&lv); From e8e6b803f25d0a873bcce75d71c4ff40ef4371ae Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 16:54:02 -0700 Subject: [PATCH 031/148] Qt: Fix window resizing when no game is loaded --- src/platform/qt/Window.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 117da820d..fe2253367 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1523,10 +1523,18 @@ void Window::setupMenu(QMenuBar* menubar) { auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { auto setSize = m_frameSizes[i]; showNormal(); - QSize size(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); +#if defined(M_CORE_GBA) + QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); +#elif defined(M_CORE_GB) + QSize minimumSize = QSize(GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS); +#endif + QSize size; if (m_display) { size = m_display->contentSize(); } + if (size.isNull()) { + size = minimumSize; + } size *= i; m_savedScale = i; m_config->setOption("scaleMultiplier", i); // TODO: Port to other From be85200b3e1eecd291dc93193a5594b104438653 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 20:22:11 -0700 Subject: [PATCH 032/148] Qt: Fix race condition in Qt display driver that could cause division by zero --- src/platform/qt/DisplayQt.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 1d9efebec..db84c2689 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -130,6 +130,10 @@ void DisplayQt::paintEvent(QPaintEvent*) { struct mRectangle frame; VideoBackendGetFrame(&m_backend, &frame); QPoint origin(-frame.x, -frame.y); + QSize drawSize(contentSize()); + if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) { + return; + } QRect full(clampSize(contentSize(), size(), isAspectRatioLocked(), isIntegerScalingLocked())); painter.save(); painter.translate(full.topLeft()); From d1a6e6b747990356754d988e65842eaa02ab9e0c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 14 Apr 2024 20:39:58 -0700 Subject: [PATCH 033/148] Qt: Add option to lock the maximum frame size (closes #1493) --- CHANGES | 1 + include/mgba/feature/proxy-backend.h | 2 ++ include/mgba/feature/video-backend.h | 2 +- src/feature/proxy-backend.c | 10 +++++---- src/platform/opengl/gl.c | 23 ++++++++++++++------- src/platform/opengl/gles2.c | 20 ++++++++++++------ src/platform/qt/Display.h | 2 ++ src/platform/qt/DisplayGL.cpp | 15 +++++++++++++- src/platform/qt/DisplayGL.h | 3 +++ src/platform/qt/DisplayQt.cpp | 17 +++++++++++++-- src/platform/qt/DisplayQt.h | 5 ++++- src/platform/qt/Window.cpp | 31 +++++++++++++++++++++++++++- src/platform/qt/Window.h | 1 + src/platform/sdl/gl-common.c | 2 +- 14 files changed, 110 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index e08179d72..6249e67d8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ 0.11.0: (Future) Features: + - New option to lock the maximum frame size - Scripting: New `input` API for getting raw keyboard/mouse/controller state - Scripting: New `storage` API for saving data for a script, e.g. settings - Scripting: Debugger integration to allow for breakpoints and watchpoints diff --git a/include/mgba/feature/proxy-backend.h b/include/mgba/feature/proxy-backend.h index 8c0b9e427..ffd38eb47 100644 --- a/include/mgba/feature/proxy-backend.h +++ b/include/mgba/feature/proxy-backend.h @@ -38,6 +38,8 @@ union mVideoBackendCommandData { struct { unsigned width; unsigned height; + unsigned maxW; + unsigned maxH; } u; const void* image; }; diff --git a/include/mgba/feature/video-backend.h b/include/mgba/feature/video-backend.h index adf6f8395..f01e656c9 100644 --- a/include/mgba/feature/video-backend.h +++ b/include/mgba/feature/video-backend.h @@ -48,7 +48,7 @@ struct VideoBackend { void (*layerDimensions)(const struct VideoBackend*, enum VideoLayer, struct mRectangle*); void (*swap)(struct VideoBackend*); void (*clear)(struct VideoBackend*); - void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h); + void (*contextResized)(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH); void (*setImageSize)(struct VideoBackend*, enum VideoLayer, int w, int h); void (*imageSize)(struct VideoBackend*, enum VideoLayer, int* w, int* h); void (*setImage)(struct VideoBackend*, enum VideoLayer, const void* frame); diff --git a/src/feature/proxy-backend.c b/src/feature/proxy-backend.c index 3cfe7c39d..540034227 100644 --- a/src/feature/proxy-backend.c +++ b/src/feature/proxy-backend.c @@ -61,7 +61,7 @@ static void _mVideoProxyBackendClear(struct VideoBackend* v) { mVideoProxyBackendSubmit(proxy, &cmd, NULL); } -static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { struct mVideoProxyBackend* proxy = (struct mVideoProxyBackend*) v; struct mVideoBackendCommand cmd = { .cmd = mVB_CMD_CONTEXT_RESIZED, @@ -69,6 +69,8 @@ static void _mVideoProxyBackendContextResized(struct VideoBackend* v, unsigned w .u = { .width = w, .height = h, + .maxW = maxW, + .maxH = maxH, } } }; @@ -139,8 +141,8 @@ void mVideoProxyBackendInit(struct mVideoProxyBackend* proxy, struct VideoBacken proxy->d.drawFrame = _mVideoProxyBackendDrawFrame; proxy->backend = backend; - RingFIFOInit(&proxy->in, 0x400); - RingFIFOInit(&proxy->out, 0x400); + RingFIFOInit(&proxy->in, sizeof(union mVideoBackendCommandData) * 0x80); + RingFIFOInit(&proxy->out, sizeof(union mVideoBackendCommandData) * 0x80); MutexInit(&proxy->inLock); MutexInit(&proxy->outLock); ConditionInit(&proxy->inWait); @@ -209,7 +211,7 @@ bool mVideoProxyBackendRun(struct mVideoProxyBackend* proxy, bool block) { proxy->backend->clear(proxy->backend); break; case mVB_CMD_CONTEXT_RESIZED: - proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height); + proxy->backend->contextResized(proxy->backend, cmd.data.u.width, cmd.data.u.height, cmd.data.u.maxW, cmd.data.u.maxH); break; case mVB_CMD_SET_IMAGE_SIZE: proxy->backend->setImageSize(proxy->backend, cmd.layer, cmd.data.s.width, cmd.data.s.height); diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index fe24d04cf..b0cef1f0d 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -103,20 +103,29 @@ static void mGLContextDeinit(struct VideoBackend* v) { glDeleteTextures(VIDEO_LAYER_MAX, context->layers); } -static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void mGLContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { unsigned drawW = w; unsigned drawH = h; - unsigned maxW; - unsigned maxH; - VideoBackendGetFrameSize(v, &maxW, &maxH); + + if (maxW && drawW > maxW) { + drawW = maxW; + } + + if (maxH && drawH > maxH) { + drawH = maxH; + } + + unsigned lockW; + unsigned lockH; + VideoBackendGetFrameSize(v, &lockW, &lockH); if (v->lockAspectRatio) { - lockAspectRatioUInt(maxW, maxH, &drawW, &drawH); + lockAspectRatioUInt(lockW, lockH, &drawW, &drawH); } if (v->lockIntegerScaling) { - lockIntegerRatioUInt(maxW, &drawW); - lockIntegerRatioUInt(maxH, &drawH); + lockIntegerRatioUInt(lockW, &drawW); + lockIntegerRatioUInt(lockH, &drawH); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 51180813e..6350bd287 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -271,20 +271,28 @@ static void mGLES2ContextDeinit(struct VideoBackend* v) { free(context->initialShader.uniforms); } -static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h) { +static void mGLES2ContextResized(struct VideoBackend* v, unsigned w, unsigned h, unsigned maxW, unsigned maxH) { struct mGLES2Context* context = (struct mGLES2Context*) v; unsigned drawW = w; unsigned drawH = h; - unsigned maxW = context->width; - unsigned maxH = context->height; + if (maxW && drawW > maxW) { + drawW = maxW; + } + + if (maxH && drawH > maxH) { + drawH = maxH; + } + + unsigned lockW = context->width; + unsigned lockH = context->height; if (v->lockAspectRatio) { - lockAspectRatioUInt(maxW, maxH, &drawW, &drawH); + lockAspectRatioUInt(lockW, lockH, &drawW, &drawH); } if (v->lockIntegerScaling) { - lockIntegerRatioUInt(maxW, &drawW); - lockIntegerRatioUInt(maxH, &drawH); + lockIntegerRatioUInt(lockW, &drawW); + lockIntegerRatioUInt(lockH, &drawH); } size_t n; for (n = 0; n < context->nShaders; ++n) { diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index ff6f0c23b..bb16b268e 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -57,6 +57,7 @@ public: virtual void setVideoScale(int) {} virtual void setBackgroundImage(const QImage&) = 0; virtual QSize contentSize() const = 0; + virtual void setMaximumSize(const QSize& size) = 0; virtual void setVideoProxy(std::shared_ptr proxy) { m_videoProxy = std::move(proxy); } std::shared_ptr videoProxy() { return m_videoProxy; } @@ -105,6 +106,7 @@ private: bool m_filter = false; QTimer m_mouseTimer; std::shared_ptr m_videoProxy; + QSize m_maxSize; }; } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 3a4c3ffdd..5b60eb46e 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -524,6 +524,10 @@ int DisplayGL::framebufferHandle() { return m_painter->glTex(); } +void DisplayGL::setMaximumSize(const QSize& size) { + QMetaObject::invokeMethod(m_painter.get(), "setMaximumSize", Q_ARG(const QSize&, size)); +} + PainterGL::PainterGL(QWindow* window, mGLWidget* widget, const QSurfaceFormat& format) : m_window(window) , m_format(format) @@ -720,6 +724,11 @@ void PainterGL::resize(const QSize& size) { } } +void PainterGL::setMaximumSize(const QSize& size) { + m_maxSize = size; + resizeContext(); +} + void PainterGL::lockAspectRatio(bool lock) { m_backend->lockAspectRatio = lock; resize(m_size); @@ -911,7 +920,11 @@ void PainterGL::unpause() { void PainterGL::performDraw() { float r = m_window->devicePixelRatio(); - m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r); + QSize maxSize = m_maxSize; + if (!maxSize.isValid()) { + maxSize = QSize(0, 0); + } + m_backend->contextResized(m_backend, m_size.width() * r, m_size.height() * r, maxSize.width() * r, maxSize.height() * r); if (m_buffer) { m_backend->setImage(m_backend, VIDEO_LAYER_IMAGE, m_buffer); } diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 71e2de597..5b0aab2cd 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -95,6 +95,7 @@ public: void setVideoProxy(std::shared_ptr) override; int framebufferHandle() override; QSize contentSize() const override { return m_cachedContentSize; } + void setMaximumSize(const QSize& size) override; static bool highestCompatible(QSurfaceFormat&); static bool supportsFormat(const QSurfaceFormat&); @@ -172,6 +173,7 @@ public slots: void pause(); void unpause(); void resize(const QSize& size); + void setMaximumSize(const QSize& size); void lockAspectRatio(bool lock); void lockIntegerScaling(bool lock); void interframeBlending(bool enable); @@ -230,6 +232,7 @@ private: VideoBackend* m_backend = nullptr; QSize m_size; QSize m_dims; + QSize m_maxSize; MessagePainter* m_messagePainter = nullptr; QElapsedTimer m_delayTimer; std::shared_ptr m_videoProxy; diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index db84c2689..3723a8445 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -134,7 +134,20 @@ void DisplayQt::paintEvent(QPaintEvent*) { if (!drawSize.isValid() || drawSize.width() < 1 || drawSize.height() < 1) { return; } - QRect full(clampSize(contentSize(), size(), isAspectRatioLocked(), isIntegerScalingLocked())); + QSize usedSize = size(); + QPoint screenOrigin(0, 0); + if (m_maxSize.isValid()) { + if (m_maxSize.width() < usedSize.width()) { + screenOrigin.setX((usedSize.width() - m_maxSize.width()) / 2); + usedSize.setWidth(m_maxSize.width()); + } + if (m_maxSize.height() < usedSize.height()) { + screenOrigin.setY((usedSize.height() - m_maxSize.height()) / 2); + usedSize.setHeight(m_maxSize.height()); + } + } + QRect full(clampSize(contentSize(), usedSize, isAspectRatioLocked(), isIntegerScalingLocked())); + full.translate(screenOrigin); painter.save(); painter.translate(full.topLeft()); painter.scale(full.width() / static_cast(frame.width), full.height() / static_cast(frame.height)); @@ -220,7 +233,7 @@ void DisplayQt::swap(struct VideoBackend*) { void DisplayQt::clear(struct VideoBackend*) { } -void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned) { +void DisplayQt::contextResized(struct VideoBackend*, unsigned, unsigned, unsigned, unsigned) { } void DisplayQt::setImageSize(struct VideoBackend* v, enum VideoLayer layer, int w, int h) { diff --git a/src/platform/qt/DisplayQt.h b/src/platform/qt/DisplayQt.h index c1363dede..a6816a18b 100644 --- a/src/platform/qt/DisplayQt.h +++ b/src/platform/qt/DisplayQt.h @@ -27,6 +27,8 @@ public: VideoShader* shaders() override { return nullptr; } QSize contentSize() const override; VideoBackend* videoBackend() override { return &m_backend; } + void setMaximumSize(const QSize& size) override { m_maxSize = size; } + public slots: void stopDrawing() override; @@ -56,7 +58,7 @@ private: static void layerDimensions(const struct VideoBackend*, enum VideoLayer, struct mRectangle*); static void swap(struct VideoBackend*); static void clear(struct VideoBackend*); - static void contextResized(struct VideoBackend*, unsigned w, unsigned h); + static void contextResized(struct VideoBackend*, unsigned w, unsigned h, unsigned maxW, unsigned maxH); static void setImageSize(struct VideoBackend*, enum VideoLayer, int w, int h); static void imageSize(struct VideoBackend*, enum VideoLayer, int* w, int* h); static void setImage(struct VideoBackend*, enum VideoLayer, const void* frame); @@ -69,6 +71,7 @@ private: int m_width = -1; int m_height = -1; QImage m_oldBacking{nullptr}; + QSize m_maxSize; std::shared_ptr m_context = nullptr; }; diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index fe2253367..bd52b0862 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -252,6 +252,9 @@ void Window::argumentsPassed() { void Window::resizeFrame(const QSize& size) { QSize newSize(size); + if (!m_config->getOption("lockFrameSize").toInt()) { + m_savedSize = size; + } if (windowHandle()) { QRect geom = windowHandle()->screen()->availableGeometry(); if (newSize.width() > geom.width()) { @@ -1522,7 +1525,10 @@ void Window::setupMenu(QMenuBar* menubar) { for (int i = 1; i <= 8; ++i) { auto setSize = m_actions.addAction(tr("%1×").arg(QString::number(i)), QString("frame.%1x").arg(QString::number(i)), [this, i]() { auto setSize = m_frameSizes[i]; - showNormal(); + bool lockFrameSize = m_config->getOption("lockFrameSize").toInt(); + if (!lockFrameSize) { + showNormal(); + } #if defined(M_CORE_GBA) QSize minimumSize = QSize(GBA_VIDEO_HORIZONTAL_PIXELS, GBA_VIDEO_VERTICAL_PIXELS); #elif defined(M_CORE_GB) @@ -1538,7 +1544,11 @@ void Window::setupMenu(QMenuBar* menubar) { size *= i; m_savedScale = i; m_config->setOption("scaleMultiplier", i); // TODO: Port to other + m_savedSize = size; resizeFrame(size); + if (lockFrameSize) { + m_display->setMaximumSize(size); + } setSize->setActive(true); }, "frame"); setSize->setExclusive(true); @@ -1553,8 +1563,22 @@ void Window::setupMenu(QMenuBar* menubar) { #else fullscreenKeys = QKeySequence("Ctrl+F"); #endif + m_actions.addSeparator("frame"); m_actions.addAction(tr("Toggle fullscreen"), "fullscreen", this, &Window::toggleFullScreen, "frame", fullscreenKeys); + ConfigOption* lockFrameSize = m_config->addOption("lockFrameSize"); + lockFrameSize->addBoolean(tr("&Lock frame size"), &m_actions, "frame"); + lockFrameSize->connect([this](const QVariant& value) { + if (m_display) { + if (value.toBool()) { + m_display->setMaximumSize(m_display->size()); + } else { + m_display->setMaximumSize({}); + } + } + }, this); + m_config->updateOption("lockFrameSize"); + ConfigOption* lockAspectRatio = m_config->addOption("lockAspectRatio"); lockAspectRatio->addBoolean(tr("Lock aspect ratio"), &m_actions, "av"); lockAspectRatio->connect([this](const QVariant& value) { @@ -2216,6 +2240,11 @@ void Window::setController(CoreController* controller, const QString& fname) { void Window::attachDisplay() { m_display->attach(m_controller); connect(m_display.get(), &QGBA::Display::drawingStarted, this, &Window::changeRenderer); + if (m_config->getOption("lockFrameSize").toInt()) { + m_display->setMaximumSize(m_savedSize); + } else { + m_display->setMaximumSize({}); + } m_display->startDrawing(m_controller); #ifdef ENABLE_SCRIPTING diff --git a/src/platform/qt/Window.h b/src/platform/qt/Window.h index 4bcb6b7f9..f91e3ff30 100644 --- a/src/platform/qt/Window.h +++ b/src/platform/qt/Window.h @@ -194,6 +194,7 @@ private: std::unique_ptr m_display; QSize m_initialSize; + QSize m_savedSize; int m_savedScale; // TODO: Move these to a new class diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 1ce9100e8..f2ccdd7e2 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -15,7 +15,7 @@ #endif void mSDLGLDoViewport(int w, int h, struct VideoBackend* v) { - v->contextResized(v, w, h); + v->contextResized(v, w, h, 0, 0); v->clear(v); v->swap(v); v->clear(v); From 4bd09bdac297571927469c5d5150a69260465ed5 Mon Sep 17 00:00:00 2001 From: oltolm Date: Thu, 28 Mar 2024 21:37:31 +0100 Subject: [PATCH 034/148] fix hang in AudioDevice --- src/platform/qt/AudioDevice.cpp | 8 ++++++-- src/platform/qt/AudioDevice.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index d19fc20d3..1ae71af19 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -64,11 +64,15 @@ qint64 AudioDevice::writeData(const char*, qint64) { } bool AudioDevice::atEnd() const { + return !bytesAvailable(); +} + +qint64 AudioDevice::bytesAvailable() const { if (!m_context->core) { return true; } mCoreSyncLockAudio(&m_context->impl->sync); - bool available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)) == 0; + int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)); mCoreSyncUnlockAudio(&m_context->impl->sync); - return available; + return available * sizeof(mStereoSample); } diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index 86c5b17a6..e4386bda2 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -21,6 +21,7 @@ public: void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); bool atEnd() const override; + qint64 bytesAvailable() const override; protected: virtual qint64 readData(char* data, qint64 maxSize) override; From 9fa825e3360d9c553cda5f8f636ba547e68ca938 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 01:21:29 -0700 Subject: [PATCH 035/148] Util: Start bringing up new resampler --- include/mgba-util/audio-resampler.h | 37 ++++++++++++ include/mgba-util/interpolator.h | 11 +++- src/util/CMakeLists.txt | 2 + src/util/audio-buffer.c | 2 +- src/util/audio-resampler.c | 94 +++++++++++++++++++++++++++++ src/util/interpolator.c | 21 ++++--- 6 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 include/mgba-util/audio-resampler.h create mode 100644 src/util/audio-resampler.c diff --git a/include/mgba-util/audio-resampler.h b/include/mgba-util/audio-resampler.h new file mode 100644 index 000000000..50f298930 --- /dev/null +++ b/include/mgba-util/audio-resampler.h @@ -0,0 +1,37 @@ +/* Copyright (c) 2013-2024 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_AUDIO_RESAMPLER_H +#define M_AUDIO_RESAMPLER_H + +#include + +CXX_GUARD_START + +#include + +struct mAudioBuffer; +struct mAudioResampler { + struct mAudioBuffer* source; + struct mAudioBuffer* destination; + double sourceRate; + double destRate; + double timestamp; + double lowWaterMark; + double highWaterMark; + struct mInterpolatorSinc interp; + bool consume; +}; + +void mAudioResamplerInit(struct mAudioResampler*); +void mAudioResamplerDeinit(struct mAudioResampler*); +void mAudioResamplerSetSource(struct mAudioResampler*, struct mAudioBuffer* source, double rate, bool consume); +void mAudioResamplerSetDestination(struct mAudioResampler*, struct mAudioBuffer* destination, double rate); +size_t mAudioResamplerProcess(struct mAudioResampler*); + +CXX_GUARD_END + +#endif + diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 43b75da27..f01048f34 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -8,12 +8,15 @@ #include -struct mInterpData { - int16_t (*at)(const void* mInterpData, size_t index); +CXX_GUARD_START + +struct mInterpolationData { + int16_t (*at)(int index, const void* context); + void* context; }; struct mInterpolator { - int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpData* data, double time, double sampleStep); + int16_t (*interpolate)(const struct mInterpolator* interp, const struct mInterpolationData* data, double time, double sampleStep); }; struct mInterpolatorSinc { @@ -28,4 +31,6 @@ struct mInterpolatorSinc { void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); +CXX_GUARD_END + #endif diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index f0bc85a3d..66cd6ca47 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -13,6 +13,8 @@ set(BASE_SOURCE_FILES set(SOURCE_FILES ${BASE_SOURCE_FILES} + audio-buffer.c + audio-resampler.c convolve.c elf-read.c geometry.c diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c index bb705b38c..5d67827fb 100644 --- a/src/util/audio-buffer.c +++ b/src/util/audio-buffer.c @@ -9,7 +9,7 @@ void mAudioBufferInit(struct mAudioBuffer* buffer, size_t capacity, unsigned channels) { mCircleBufferInit(&buffer->data, capacity * channels * sizeof(int16_t)); - buffer->channels = capacity; + buffer->channels = channels; } void mAudioBufferDeinit(struct mAudioBuffer* buffer) { diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c new file mode 100644 index 000000000..0f0147c34 --- /dev/null +++ b/src/util/audio-resampler.c @@ -0,0 +1,94 @@ +/* Copyright (c) 2013-2024 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 + +#define MAX_CHANNELS 2 + +struct mAudioResamplerData { + struct mAudioResampler* resampler; + unsigned channel; +}; + +static int16_t _sampleAt(int index, const void* context) { + const struct mAudioResamplerData* data = context; + if (index < 0) { + return 0; + } + return mAudioBufferPeek(data->resampler->source, data->channel, index); +} + +void mAudioResamplerInit(struct mAudioResampler* resampler) { + memset(resampler, 0, sizeof(*resampler)); + mInterpolatorSincInit(&resampler->interp, 0, 0); + resampler->lowWaterMark = resampler->interp.width; + resampler->highWaterMark = 0; +} + +void mAudioResamplerDeinit(struct mAudioResampler* resampler) { + mInterpolatorSincDeinit(&resampler->interp); + resampler->source = NULL; + resampler->destination = NULL; +} + +void mAudioResamplerSetSource(struct mAudioResampler* resampler, struct mAudioBuffer* source, double rate, bool consume) { + resampler->source = source; + resampler->sourceRate = rate; + resampler->consume = consume; +} + +void mAudioResamplerSetDestination(struct mAudioResampler* resampler, struct mAudioBuffer* destination, double rate) { + resampler->destination = destination; + resampler->destRate = rate; +} + +size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { + int16_t sampleBuffer[MAX_CHANNELS] = {0}; + double timestep = resampler->sourceRate / resampler->destRate; + double timestamp = resampler->timestamp; + struct mInterpolator* interp = &resampler->interp.d; + struct mAudioResamplerData context = { + .resampler = resampler, + }; + struct mInterpolationData data = { + .at = _sampleAt, + .context = &context, + }; + + size_t read = 0; + if (resampler->source->channels > MAX_CHANNELS) { + abort(); + } + + while (true) { + if (timestamp + resampler->highWaterMark >= mAudioBufferAvailable(resampler->source)) { + break; + } + if (mAudioBufferAvailable(resampler->destination) == mAudioBufferCapacity(resampler->destination)) { + break; + } + + size_t channel; + for (channel = 0; channel < resampler->source->channels; ++channel) { + context.channel = channel; + sampleBuffer[channel] = interp->interpolate(interp, &data, timestamp, timestep); + } + if (!mAudioBufferWrite(resampler->destination, sampleBuffer, 1)) { + break; + } + timestamp += timestep; + ++read; + } + + if (resampler->consume && timestamp > resampler->lowWaterMark) { + size_t drop = timestamp - resampler->lowWaterMark; + drop = mAudioBufferRead(resampler->source, NULL, drop); + timestamp -= drop; + } + resampler->timestamp = timestamp; + return read; +} diff --git a/src/util/interpolator.c b/src/util/interpolator.c index a9daaa539..21dd91d2c 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -10,7 +10,7 @@ enum { mSINC_WIDTH = 8, }; -static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpData*, double time, double sampleStep); +static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -33,6 +33,9 @@ void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution interp->sincLut[0] = 0; interp->windowLut[0] = 1; + interp->width = width; + interp->resolution = resolution; + unsigned i; for (i = 1; i <= samples; ++i, x += dx, y += dy) { interp->sincLut[i] = x < width ? sin(x) / x : 0.0; @@ -46,27 +49,27 @@ void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp) { free(interp->windowLut); } -int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpData* data, double time, double sampleStep) { +int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, const struct mInterpolationData* data, double time, double sampleStep) { struct mInterpolatorSinc* interp = (struct mInterpolatorSinc*) interpolator; - ssize_t index = (ssize_t) time; + int index = time; double subsample = time - floor(time); - unsigned step = sampleStep > 1 ? interp->resolution * sampleStep : interp->resolution; + unsigned step = sampleStep < 1 ? interp->resolution * sampleStep : interp->resolution; unsigned yShift = subsample * step; unsigned xShift = subsample * interp->resolution; double sum = 0.0; double kernelSum = 0.0; double kernel; - ssize_t i; - for (i = 1 - (ssize_t) interp->width; i <= (ssize_t) interp->width; ++i) { - unsigned window = i * interp->resolution; + int i; + for (i = 1 - (int) interp->width; i <= (int) interp->width; ++i) { + unsigned window = (i >= 0 ? i : -i) * interp->resolution; if (yShift > window) { window = yShift - window; } else { window -= yShift; } - unsigned sinc = i * step; + unsigned sinc = (i >= 0 ? i : -i) * step; if (xShift > sinc) { sinc = xShift - sinc; } else { @@ -75,7 +78,7 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c kernel = interp->sincLut[sinc] * interp->windowLut[window]; kernelSum += kernel; - sum += data->at(data, index + i) * kernel; + sum += data->at(index + i, data->context) * kernel; } return sum / kernelSum; } From 76169c669a70a278b480176deeb1bd5a5ddd639b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 02:54:30 -0700 Subject: [PATCH 036/148] Util: Fix circle buffer dump offset forcing an early wrap --- src/util/circle-buffer.c | 12 +++++++++++- src/util/test/circle-buffer.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index f0d074d36..037a23501 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -279,8 +279,18 @@ size_t mCircleBufferDump(const struct mCircleBuffer* buffer, void* output, size_ if (length > buffer->size - offset) { length = buffer->size - offset; } - data += offset; size_t remaining = buffer->capacity - ((uintptr_t) data - (uintptr_t) buffer->data); + if (offset) { + if (remaining >= offset) { + data += offset; + remaining -= offset; + } else { + offset -= remaining; + data = buffer->data; + data += offset; + } + } + if (length <= remaining) { memcpy(output, data, length); } else { diff --git a/src/util/test/circle-buffer.c b/src/util/test/circle-buffer.c index 9ba383971..bff0c9485 100644 --- a/src/util/test/circle-buffer.c +++ b/src/util/test/circle-buffer.c @@ -938,6 +938,38 @@ M_TEST_DEFINE(dumpOffset) { mCircleBufferDeinit(&buffer); } +M_TEST_DEFINE(dumpOffsetWrap) { + struct mCircleBuffer buffer; + const char* data = " Lorem ipsum dolor sit amet, consectetur adipiscing elit placerat."; + char databuf[64]; + + mCircleBufferInit(&buffer, 64); + + assert_int_equal(mCircleBufferWrite(&buffer, data, 64), 64); + assert_int_equal(mCircleBufferSize(&buffer), 64); + assert_int_equal(mCircleBufferRead(&buffer, databuf, 48), 48); + assert_memory_equal(data, databuf, 48); + assert_int_equal(mCircleBufferSize(&buffer), 16); + assert_int_equal(mCircleBufferWrite(&buffer, data, 16), 16); + assert_int_equal(mCircleBufferSize(&buffer), 32); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 0), 32); + assert_memory_equal(&data[48], databuf, 16); + assert_memory_equal(data, &databuf[16], 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 8), 24); + assert_memory_equal(&data[56], databuf, 8); + assert_memory_equal(data, &databuf[8], 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 16), 16); + assert_memory_equal(data, databuf, 16); + + assert_int_equal(mCircleBufferDump(&buffer, databuf, 64, 24), 8); + assert_memory_equal(&data[8], databuf, 8); + + mCircleBufferDeinit(&buffer); +} + M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(basicCircle), cmocka_unit_test(basicAlignment16), @@ -959,4 +991,5 @@ M_TEST_SUITE_DEFINE(mCircleBuffer, cmocka_unit_test(writeTruncate), cmocka_unit_test(dumpBasic), cmocka_unit_test(dumpOffset), + cmocka_unit_test(dumpOffsetWrap), ) From 96a2ef5f42a2a8f453bd71ed38bdead5d9c027c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 02:54:48 -0700 Subject: [PATCH 037/148] Util: Enable dropping part of a circle buffer with a null read --- src/util/circle-buffer.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index 037a23501..ec14bfc4f 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -250,15 +250,19 @@ size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t leng } size_t remaining = buffer->capacity - ((int8_t*) data - (int8_t*) buffer->data); if (length <= remaining) { - memcpy(output, data, length); + if (output) { + memcpy(output, data, length); + } if (length == remaining) { buffer->readPtr = buffer->data; } else { buffer->readPtr = (int8_t*) data + length; } } else { - memcpy(output, data, remaining); - memcpy((int8_t*) output + remaining, buffer->data, length - remaining); + if (output) { + memcpy(output, data, remaining); + memcpy((int8_t*) output + remaining, buffer->data, length - remaining); + } buffer->readPtr = (int8_t*) buffer->data + length - remaining; } From 73a39dea65cd90f2a36a7d2f1f87eb8cf204d8e0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 20:44:59 -0700 Subject: [PATCH 038/148] Core: Finally kill off GBAAudioCalculateRatio --- include/mgba/core/core.h | 2 ++ include/mgba/internal/gba/audio.h | 2 -- src/core/core.c | 6 ++++++ src/gba/audio.c | 4 ---- src/platform/psp2/psp2-context.c | 2 +- src/platform/qt/AudioDevice.cpp | 2 +- src/platform/sdl/sdl-audio.c | 5 ++--- src/platform/switch/main.c | 2 +- src/platform/wii/main.c | 4 ++-- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 99bfd0e83..b34a9451f 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -216,6 +216,8 @@ void* mCoreGetMemoryBlock(struct mCore* core, uint32_t start, size_t* size); void* mCoreGetMemoryBlockMasked(struct mCore* core, uint32_t start, size_t* size, uint32_t mask); const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint32_t address); +double mCoreCalculateFramerateRatio(const struct mCore* core, double desiredFrameRate); + #ifdef USE_ELF struct ELF; bool mCoreLoadELF(struct mCore* core, struct ELF* elf); diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index f2d878e4e..6702f5ff4 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -313,8 +313,6 @@ struct GBASerializedState; void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state); void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state); -float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRatio); - CXX_GUARD_END #endif diff --git a/src/core/core.c b/src/core/core.c index bc68fd5d2..bcc72115a 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -442,6 +442,12 @@ const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint3 return NULL; } +double mCoreCalculateFramerateRatio(const struct mCore* core, double desiredFrameRate) { + uint32_t clockRate = core->frequency(core); + uint32_t frameCycles = core->frameCycles(core); + return clockRate / (desiredFrameRate * frameCycles); +} + #ifdef USE_ELF bool mCoreLoadELF(struct mCore* core, struct ELF* elf) { struct ELFProgramHeaders ph; diff --git a/src/gba/audio.c b/src/gba/audio.c index fb0e1b62c..b25273f16 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -587,7 +587,3 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState } mTimingSchedule(&audio->p->timing, &audio->sampleEvent, when); } - -float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) { - return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate); -} diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 34623a876..755021f6f 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -376,7 +376,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { void mPSP2LoadROM(struct mGUIRunner* runner) { float rate = 60.0f / 1.001f; sceDisplayGetRefreshRate(&rate); - double ratio = GBAAudioCalculateRatio(1, rate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, rate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index 1ae71af19..ec6dd3133 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -26,7 +26,7 @@ void AudioDevice::setFormat(const QAudioFormat& format) { LOG(QT, INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = GBAAudioCalculateRatio(1, m_context->impl->sync.fpsTarget, 1); + double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); mCoreSyncLockAudio(&m_context->impl->sync); blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index f1666aa4e..2d1fc9f85 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -103,12 +103,11 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { if (audioContext->core) { left = audioContext->core->getAudioChannel(audioContext->core, 0); right = audioContext->core->getAudioChannel(audioContext->core, 1); - clockRate = audioContext->core->frequency(audioContext->core); } double fauxClock = 1; if (audioContext->sync) { - if (audioContext->sync->fpsTarget > 0) { - fauxClock = GBAAudioCalculateRatio(1, audioContext->sync->fpsTarget, 1); + if (audioContext->sync->fpsTarget > 0 && audioContext->core) { + fauxClock = mCoreCalculateFramerateRatio(audioContext->core, audioContext->sync->fpsTarget); } mCoreSyncLockAudio(audioContext->sync); } diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 15196aaec..7dd8dc742 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -330,7 +330,7 @@ static void _setup(struct mGUIRunner* runner) { static void _gameLoaded(struct mGUIRunner* runner) { u32 samplerate = audoutGetSampleRate(); - double ratio = GBAAudioCalculateRatio(1, 60.0, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio); diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 60d4e95ae..4e955a0ad 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -247,7 +247,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { runner->params.width = vmode->fbWidth * guiScale * wAdjust; runner->params.height = vmode->efbHeight * guiScale * hAdjust; if (runner->core) { - double ratio = GBAAudioCalculateRatio(1, audioSampleRate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); } @@ -1422,7 +1422,7 @@ void _setup(struct mGUIRunner* runner) { } runner->core->setAudioBufferSize(runner->core, SAMPLES); - double ratio = GBAAudioCalculateRatio(1, audioSampleRate, 1); + double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); From 7b2edbd1bdc26717f85f7b391936f7af18998489 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 21:01:58 -0700 Subject: [PATCH 039/148] Core: Add functions to get native sample rates --- include/mgba/core/core.h | 1 + src/gb/core.c | 6 ++++++ src/gba/core.c | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index b34a9451f..7eeb1d8fb 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -78,6 +78,7 @@ struct mCore { void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); void (*putPixels)(struct mCore*, const void* buffer, size_t stride); + unsigned (*audioSampleRate)(const struct mCore*); struct blip_t* (*getAudioChannel)(struct mCore*, int ch); void (*setAudioBufferSize)(struct mCore*, size_t samples); size_t (*getAudioBufferSize)(struct mCore*); diff --git a/src/gb/core.c b/src/gb/core.c index 1018b9f82..9ee6d3f84 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -445,6 +445,11 @@ static void _GBCoreSetAudioBufferSize(struct mCore* core, size_t samples) { GBAudioResizeBuffer(&gb->audio, samples); } +static unsigned _GBCoreAudioSampleRate(const struct mCore* core) { + UNUSED(core); + return 131072; +} + static size_t _GBCoreGetAudioBufferSize(struct mCore* core) { struct GB* gb = core->board; return gb->audio.samples; @@ -1302,6 +1307,7 @@ struct mCore* GBCoreCreate(void) { core->setVideoGLTex = _GBCoreSetVideoGLTex; core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; + core->audioSampleRate = _GBCoreAudioSampleRate; core->getAudioChannel = _GBCoreGetAudioChannel; core->setAudioBufferSize = _GBCoreSetAudioBufferSize; core->getAudioBufferSize = _GBCoreGetAudioBufferSize; diff --git a/src/gba/core.c b/src/gba/core.c index dd5df523b..4fb801c4a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -559,6 +559,11 @@ static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t str gba->video.renderer->putPixels(gba->video.renderer, stride, buffer); } +static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { + UNUSED(core); + return 65536; +} + static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) { struct GBA* gba = core->board; switch (ch) { @@ -1515,6 +1520,7 @@ struct mCore* GBACoreCreate(void) { core->setVideoGLTex = _GBACoreSetVideoGLTex; core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; + core->audioSampleRate = _GBACoreAudioSampleRate; core->getAudioChannel = _GBACoreGetAudioChannel; core->setAudioBufferSize = _GBACoreSetAudioBufferSize; core->getAudioBufferSize = _GBACoreGetAudioBufferSize; From 5d92c3ca0a2b58db253b4296cdcd220335316040 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 16 Apr 2024 22:38:49 -0700 Subject: [PATCH 040/148] SDL: Fix GB audio speed --- src/platform/sdl/sdl-audio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index 2d1fc9f85..ff7ddd2da 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -99,8 +99,9 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { } blip_t* left = NULL; blip_t* right = NULL; - int32_t clockRate = GBA_ARM7TDMI_FREQUENCY; + int32_t clockRate = 1; if (audioContext->core) { + clockRate = audioContext->core->frequency(audioContext->core); left = audioContext->core->getAudioChannel(audioContext->core, 0); right = audioContext->core->getAudioChannel(audioContext->core, 1); } From b40cdd070c442030b347cb89ba4ce2dc0b01a84a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 02:39:36 -0700 Subject: [PATCH 041/148] Switch: Switch to resampling with audren --- src/platform/switch/main.c | 127 +++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 7dd8dc742..657941094 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -21,15 +22,9 @@ #define AUTO_INPUT 0x4E585031 #define SAMPLES 0x200 -#define N_BUFFERS 4 +#define N_BUFFERS 6 #define ANALOG_DEADZONE 0x4000 -#if (SAMPLES * 4) < 0x1000 -#define BUFFER_SIZE 0x1000 -#else -#define BUFFER_SIZE (SAMPLES * 4) -#endif - TimeType __nx_time_type = TimeType_UserSystemClock; static EGLDisplay s_display; @@ -94,9 +89,9 @@ static struct mSwitchRumble { HidVibrationValue value; } rumble; static struct mRotationSource rotation = {0}; -static int audioBufferActive; -static AudioOutBuffer audoutBuffer[N_BUFFERS]; -static int enqueuedBuffers; +static AudioDriver audrenDriver; +static AudioDriverWaveBuf audrvBuffer[N_BUFFERS]; +static struct mStereoSample* audioBuffer[N_BUFFERS]; static bool frameLimiter = true; static unsigned framecount = 0; static unsigned framecap = 10; @@ -116,8 +111,6 @@ static float gyroZ = 0; static float tiltX = 0; static float tiltY = 0; -static struct mStereoSample audioBuffer[N_BUFFERS][BUFFER_SIZE / 4] __attribute__((__aligned__(0x1000))); - static enum ScreenMode { SM_PA, SM_AF, @@ -274,22 +267,6 @@ static void _updateRenderer(struct mGUIRunner* runner, bool gl) { } } -static int _audioWait(u64 timeout) { - AudioOutBuffer* releasedBuffers; - u32 nReleasedBuffers = 0; - Result rc; - if (timeout) { - rc = audoutWaitPlayFinish(&releasedBuffers, &nReleasedBuffers, timeout); - } else { - rc = audoutGetReleasedAudioOutBuffer(&releasedBuffers, &nReleasedBuffers); - } - if (R_FAILED(rc)) { - return 0; - } - enqueuedBuffers -= nReleasedBuffers; - return nReleasedBuffers; -} - static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_B, GBA_KEY_B); @@ -325,15 +302,22 @@ static void _setup(struct mGUIRunner* runner) { } runner->core->setAudioBufferSize(runner->core, SAMPLES); + + u32 samplerate = runner->core->audioSampleRate(runner->core); + double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); + blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate); + blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate); + + audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); + audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); + audrvUpdate(&audrenDriver); } static void _gameLoaded(struct mGUIRunner* runner) { - u32 samplerate = audoutGetSampleRate(); - - double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate * ratio); - mCoreConfigGetUIntValue(&runner->config, "fastForwardCap", &framecap); unsigned mode; @@ -388,6 +372,7 @@ static void _gameUnloaded(struct mGUIRunner* runner) { memcpy(&values[2], &vibrationStop, sizeof(rumble.value)); memcpy(&values[3], &vibrationStop, sizeof(rumble.value)); hidSendVibrationValues(vibrationDeviceHandles, values, 4); + audrvVoiceStop(&audrenDriver, 0); } static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, bool faded, bool blendTop) { @@ -565,9 +550,7 @@ static void _incrementScreenMode(struct mGUIRunner* runner) { static void _setFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); if (!frameLimiter && limit) { - while (enqueuedBuffers > 2) { - _audioWait(100000000); - } + audrenWaitFrame(); } frameLimiter = limit; eglSwapInterval(s_surface, limit); @@ -593,27 +576,34 @@ static bool _running(struct mGUIRunner* runner) { static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { UNUSED(stream); - _audioWait(0); - while (enqueuedBuffers >= N_BUFFERS - 1) { + int i; + while (true) { + audrvUpdate(&audrenDriver); + for (i = 0; i < N_BUFFERS; ++i) { + if (audrvBuffer[i].state == AudioDriverWaveBufState_Free || audrvBuffer[i].state == AudioDriverWaveBufState_Done) { + break; + } + } + if (i < N_BUFFERS) { + break; + } if (!frameLimiter) { blip_clear(left); blip_clear(right); return; } - _audioWait(10000000); + audrenWaitFrame(); } - if (enqueuedBuffers >= N_BUFFERS) { - blip_clear(left); - blip_clear(right); - return; - } - struct mStereoSample* samples = audioBuffer[audioBufferActive]; + struct mStereoSample* samples = audioBuffer[i]; blip_read_samples(left, &samples[0].left, SAMPLES, true); blip_read_samples(right, &samples[0].right, SAMPLES, true); - audoutAppendAudioOutBuffer(&audoutBuffer[audioBufferActive]); - ++audioBufferActive; - audioBufferActive %= N_BUFFERS; - ++enqueuedBuffers; + armDCacheFlush(samples, SAMPLES * sizeof(struct mStereoSample)); + audrvVoiceAddWaveBuf(&audrenDriver, 0, &audrvBuffer[i]); + + if (!audrvVoiceIsPlaying(&audrenDriver, 0)) { + audrvVoiceStart(&audrenDriver, 0); + } + audrvUpdate(&audrenDriver); } void _setRumble(struct mRumble* rumble, int enable) { @@ -865,9 +855,26 @@ int main(int argc, char* argv[]) { nxlinkStdio(); eglInit(); romfsInit(); - audoutInitialize(); psmInitialize(); + const AudioRendererConfig audren = { + .output_rate = AudioRendererOutputRate_48kHz, + .num_voices = 24, + .num_effects = 0, + .num_sinks = 1, + .num_mix_objs = 1, + .num_mix_buffers = 2, + }; + const u8 channels[] = { 0, 1 }; + audrenInitialize(&audren); + audrvCreate(&audrenDriver, &audren, 2); + struct mStereoSample* buffers = memalign(AUDREN_MEMPOOL_ALIGNMENT, SAMPLES * N_BUFFERS * sizeof(struct mStereoSample)); + int mempool = audrvMemPoolAdd(&audrenDriver, buffers, SAMPLES * N_BUFFERS * sizeof(struct mStereoSample)); + audrvMemPoolAttach(&audrenDriver, mempool); + audrvDeviceSinkAdd(&audrenDriver, AUDREN_DEFAULT_DEVICE_NAME, 2, channels); + audrvUpdate(&audrenDriver); + audrenStartAudioRenderer(); + font = GUIFontCreate(); vmode = appletGetOperationMode(); @@ -888,16 +895,13 @@ int main(int argc, char* argv[]) { stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; - memset(audioBuffer, 0, sizeof(audioBuffer)); - audioBufferActive = 0; - enqueuedBuffers = 0; size_t i; for (i = 0; i < N_BUFFERS; ++i) { - audoutBuffer[i].next = NULL; - audoutBuffer[i].buffer = audioBuffer[i]; - audoutBuffer[i].buffer_size = BUFFER_SIZE; - audoutBuffer[i].data_size = SAMPLES * 4; - audoutBuffer[i].data_offset = 0; + audrvBuffer[i].data_raw = buffers; + audrvBuffer[i].size = SAMPLES * N_BUFFERS * sizeof(struct mStereoSample); + audrvBuffer[i].start_sample_offset = SAMPLES * i; + audrvBuffer[i].end_sample_offset = SAMPLES * (i + 1); + audioBuffer[i] = &buffers[SAMPLES * i]; } bool illuminanceAvailable = false; @@ -1074,8 +1078,6 @@ int main(int argc, char* argv[]) { _mapKey(&runner.params.keyMap, AUTO_INPUT, HidNpadButton_Left, GUI_INPUT_LEFT); _mapKey(&runner.params.keyMap, AUTO_INPUT, HidNpadButton_Right, GUI_INPUT_RIGHT); - audoutStartAudioOut(); - if (argc > 0) { struct VFile* vf = VFileOpen("romfs:/fileassoc.cfg.in", O_RDONLY); if (vf) { @@ -1108,7 +1110,8 @@ int main(int argc, char* argv[]) { mGUIDeinit(&runner); - audoutStopAudioOut(); + audrvClose(&audrenDriver); + audrenExit(); GUIFontDestroy(font); glDeinit(); From 61791c91cb41eaafd4a710f8c6229840e5a343b4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 02:41:59 -0700 Subject: [PATCH 042/148] Switch: Fix warnings --- src/platform/switch/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 657941094..0dc866dfd 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -366,6 +366,7 @@ static void _gameLoaded(struct mGUIRunner* runner) { } static void _gameUnloaded(struct mGUIRunner* runner) { + UNUSED(runner); HidVibrationValue values[4]; memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); @@ -392,6 +393,7 @@ static void _drawTex(struct mGUIRunner* runner, unsigned width, unsigned height, float aspectY = inheight / vheight; float max = 1.f; switch (screenMode) { + case SM_MAX: // This should never get hit, so just fall through to silence warning case SM_PA: if (aspectX > aspectY) { max = floor(1.f / aspectX); @@ -616,6 +618,7 @@ void _setRumble(struct mRumble* rumble, int enable) { } void _sampleRotation(struct mRotationSource* source) { + UNUSED(source); HidSixAxisSensorState sixaxis = {0}; u64 styles = padGetStyleSet(&pad); if (styles & HidNpadStyleTag_NpadHandheld) { From f298c0185ec0e7186991128b99c7fa4790aca6a7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 17:36:31 -0700 Subject: [PATCH 043/148] Qt: Add option to force a specific version of Qt --- src/platform/qt/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 673170f0f..041ad0830 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -25,7 +25,13 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QT_LIBRARIES) -set(QT_VERSIONS 6 5) +option(FORCE_QT_VERSION "Force the used Qt version" OFF) + +if(FORCE_QT_VERSION EQUAL 5 OR FORCE_QT_VERSION EQUAL 6) + set(QT_VERSIONS ${FORCE_QT_VERSION}) +else() + set(QT_VERSIONS 6 5) +endif() foreach(V ${QT_VERSIONS}) set(QT Qt${V}) set(QT_V ${V}) From f84208a3e4a14ebd81e1851bca1f90cb955926d3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 20 Apr 2024 22:55:13 -0700 Subject: [PATCH 044/148] GBA Memory: Let raw access read high MMIO addresses --- CHANGES | 1 + src/gba/memory.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 6249e67d8..f06956bfc 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Updater: Fix updating appimage across filesystems Misc: diff --git a/src/gba/memory.c b/src/gba/memory.c index 455c70bdb..4c72ca80e 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1118,10 +1118,8 @@ uint32_t GBAView32(struct ARMCore* cpu, uint32_t address) { value = GBALoad32(cpu, address, 0); break; case GBA_REGION_IO: - if ((address & OFFSET_MASK) < GBA_REG_MAX) { - value = gba->memory.io[(address & OFFSET_MASK) >> 1]; - value |= gba->memory.io[((address & OFFSET_MASK) >> 1) + 1] << 16; - } + value = GBAView16(cpu, address); + value |= GBAView16(cpu, address + 2) << 16; break; case GBA_REGION_SRAM: value = GBALoad8(cpu, address, 0); @@ -1159,7 +1157,10 @@ uint16_t GBAView16(struct ARMCore* cpu, uint32_t address) { value = GBALoad16(cpu, address, 0); break; case GBA_REGION_IO: - if ((address & OFFSET_MASK) < GBA_REG_MAX) { + if ((address & OFFSET_MASK) < GBA_REG_MAX || (address & OFFSET_MASK) == GBA_REG_POSTFLG) { + value = gba->memory.io[(address & OFFSET_MASK) >> 1]; + } else if ((address & OFFSET_MASK) == GBA_REG_EXWAITCNT_LO || (address & OFFSET_MASK) == GBA_REG_EXWAITCNT_HI) { + address += GBA_REG_INTERNAL_EXWAITCNT_LO - GBA_REG_EXWAITCNT_LO; value = gba->memory.io[(address & OFFSET_MASK) >> 1]; } break; From 2eca3c14779dfb5ad3e82c04e12244b2e4d5f7d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 03:01:33 -0700 Subject: [PATCH 045/148] Vita: Switch to using lw mutexes --- include/mgba-util/platform/psp2/threading.h | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/include/mgba-util/platform/psp2/threading.h b/include/mgba-util/platform/psp2/threading.h index 4c084804c..2edcc4806 100644 --- a/include/mgba-util/platform/psp2/threading.h +++ b/include/mgba-util/platform/psp2/threading.h @@ -9,7 +9,7 @@ #include typedef SceUID Thread; -typedef SceUID Mutex; +typedef SceKernelLwMutexWork Mutex; typedef struct { Mutex mutex; SceUID semaphore; @@ -20,28 +20,23 @@ typedef THREAD_ENTRY (*ThreadEntry)(void*); #define THREAD_EXIT(RES) return RES static inline int MutexInit(Mutex* mutex) { - Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0); - if (id < 0) { - return id; - } - *mutex = id; - return 0; + return sceKernelCreateLwMutex(mutex, "mutex", 0, 0, 0); } static inline int MutexDeinit(Mutex* mutex) { - return sceKernelDeleteMutex(*mutex); + return sceKernelDeleteLwMutex(mutex); } static inline int MutexLock(Mutex* mutex) { - return sceKernelLockMutex(*mutex, 1, 0); + return sceKernelLockLwMutex(mutex, 1, 0); } static inline int MutexTryLock(Mutex* mutex) { - return sceKernelTryLockMutex(*mutex, 1); + return sceKernelTryLockLwMutex(mutex, 1); } static inline int MutexUnlock(Mutex* mutex) { - return sceKernelUnlockMutex(*mutex, 1); + return sceKernelUnlockLwMutex(mutex, 1); } static inline int ConditionInit(Condition* cond) { From afa8a25b5bb032b7a2ce5c41fe39c4101bb00e30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 16:26:20 -0700 Subject: [PATCH 046/148] Util: Add cosine interpolator --- include/mgba-util/interpolator.h | 10 ++++++++++ src/util/interpolator.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index f01048f34..538115c37 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -28,9 +28,19 @@ struct mInterpolatorSinc { double* windowLut; }; +struct mInterpolatorCosine { + struct mInterpolator d; + + unsigned resolution; + double* lut; +}; + void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width); void mInterpolatorSincDeinit(struct mInterpolatorSinc* interp); +void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution); +void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp); + CXX_GUARD_END #endif diff --git a/src/util/interpolator.c b/src/util/interpolator.c index 21dd91d2c..a69d19e81 100644 --- a/src/util/interpolator.c +++ b/src/util/interpolator.c @@ -8,9 +8,12 @@ enum { mSINC_RESOLUTION = 8192, mSINC_WIDTH = 8, + + mCOSINE_RESOLUTION = 8192, }; static int16_t mInterpolatorSincInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); +static int16_t mInterpolatorCosineInterpolate(const struct mInterpolator*, const struct mInterpolationData*, double time, double sampleStep); void mInterpolatorSincInit(struct mInterpolatorSinc* interp, unsigned resolution, unsigned width) { interp->d.interpolate = mInterpolatorSincInterpolate; @@ -82,3 +85,32 @@ int16_t mInterpolatorSincInterpolate(const struct mInterpolator* interpolator, c } return sum / kernelSum; } + +void mInterpolatorCosineInit(struct mInterpolatorCosine* interp, unsigned resolution) { + interp->d.interpolate = mInterpolatorCosineInterpolate; + + if (!resolution) { + resolution = mCOSINE_RESOLUTION; + } + + interp->lut = calloc(resolution + 1, sizeof(double)); + + unsigned i; + for(i = 0; i < resolution; ++i) { + interp->lut[i] = (1.0 - cos(M_PI * i / resolution) * M_PI) * 0.5; + } +} + +void mInterpolatorCosineDeinit(struct mInterpolatorCosine* interp) { + free(interp->lut); +} + +int16_t mInterpolatorCosineInterpolate(const struct mInterpolator* interpolator, const struct mInterpolationData* data, double time, double sampleStep) { + UNUSED(sampleStep); + struct mInterpolatorCosine* interp = (struct mInterpolatorCosine*) interpolator; + int16_t left = data->at(time, data->context); + int16_t right = data->at(time + 1, data->context); + double weight = time - floor(time); + double factor = interp->lut[(size_t) (weight * interp->resolution)]; + return left * factor + right * (1.0 - factor); +} From febedc3a389a88e29ee0237a87b6dee3dfbdec2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 21 Apr 2024 16:32:45 -0700 Subject: [PATCH 047/148] Util: Allow audio resampler to use different interpolators --- include/mgba-util/audio-resampler.h | 9 +++++++-- include/mgba-util/interpolator.h | 5 +++++ src/util/audio-resampler.c | 29 +++++++++++++++++++++++------ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/audio-resampler.h b/include/mgba-util/audio-resampler.h index 50f298930..e1ec3d84c 100644 --- a/include/mgba-util/audio-resampler.h +++ b/include/mgba-util/audio-resampler.h @@ -21,11 +21,16 @@ struct mAudioResampler { double timestamp; double lowWaterMark; double highWaterMark; - struct mInterpolatorSinc interp; + enum mInterpolatorType interpType; + union { + struct mInterpolator interp; + struct mInterpolatorSinc sinc; + struct mInterpolatorCosine cosine; + }; bool consume; }; -void mAudioResamplerInit(struct mAudioResampler*); +void mAudioResamplerInit(struct mAudioResampler*, enum mInterpolatorType); void mAudioResamplerDeinit(struct mAudioResampler*); void mAudioResamplerSetSource(struct mAudioResampler*, struct mAudioBuffer* source, double rate, bool consume); void mAudioResamplerSetDestination(struct mAudioResampler*, struct mAudioBuffer* destination, double rate); diff --git a/include/mgba-util/interpolator.h b/include/mgba-util/interpolator.h index 538115c37..b7a59acd5 100644 --- a/include/mgba-util/interpolator.h +++ b/include/mgba-util/interpolator.h @@ -10,6 +10,11 @@ CXX_GUARD_START +enum mInterpolatorType { + mINTERPOLATOR_SINC, + mINTERPOLATOR_COSINE, +}; + struct mInterpolationData { int16_t (*at)(int index, const void* context); void* context; diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c index 0f0147c34..5b7a069e4 100644 --- a/src/util/audio-resampler.c +++ b/src/util/audio-resampler.c @@ -22,15 +22,32 @@ static int16_t _sampleAt(int index, const void* context) { return mAudioBufferPeek(data->resampler->source, data->channel, index); } -void mAudioResamplerInit(struct mAudioResampler* resampler) { +void mAudioResamplerInit(struct mAudioResampler* resampler, enum mInterpolatorType interpType) { memset(resampler, 0, sizeof(*resampler)); - mInterpolatorSincInit(&resampler->interp, 0, 0); - resampler->lowWaterMark = resampler->interp.width; - resampler->highWaterMark = 0; + resampler->interpType = interpType; + switch (interpType) { + case mINTERPOLATOR_SINC: + mInterpolatorSincInit(&resampler->sinc, 0, 0); + resampler->lowWaterMark = resampler->sinc.width; + resampler->highWaterMark = resampler->sinc.width; + break; + case mINTERPOLATOR_COSINE: + mInterpolatorCosineInit(&resampler->cosine, 0); + resampler->lowWaterMark = 0; + resampler->highWaterMark = 1; + break; + } } void mAudioResamplerDeinit(struct mAudioResampler* resampler) { - mInterpolatorSincDeinit(&resampler->interp); + switch (resampler->interpType) { + case mINTERPOLATOR_SINC: + mInterpolatorSincDeinit(&resampler->sinc); + break; + case mINTERPOLATOR_COSINE: + mInterpolatorCosineDeinit(&resampler->cosine); + break; + } resampler->source = NULL; resampler->destination = NULL; } @@ -50,7 +67,7 @@ size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { int16_t sampleBuffer[MAX_CHANNELS] = {0}; double timestep = resampler->sourceRate / resampler->destRate; double timestamp = resampler->timestamp; - struct mInterpolator* interp = &resampler->interp.d; + struct mInterpolator* interp = &resampler->interp; struct mAudioResamplerData context = { .resampler = resampler, }; From 89866aff958499ceb64dd7e2c8824112db448b50 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:29:11 -0700 Subject: [PATCH 048/148] GBA Audio: Remove broken XQ audio pending rewrite Gone but not forgotten. --- CHANGES | 1 + include/mgba/internal/gba/audio.h | 23 -- include/mgba/internal/gba/extra/audio-mixer.h | 19 -- src/gba/CMakeLists.txt | 1 - src/gba/audio.c | 56 +--- src/gba/core.c | 16 - src/gba/extra/audio-mixer.c | 306 ------------------ src/gba/gba.c | 4 - src/platform/qt/SettingsView.cpp | 7 - src/platform/qt/SettingsView.h | 1 - src/platform/qt/SettingsView.ui | 9 +- src/platform/qt/Window.cpp | 9 - 12 files changed, 16 insertions(+), 436 deletions(-) delete mode 100644 include/mgba/internal/gba/extra/audio-mixer.h delete mode 100644 src/gba/extra/audio-mixer.c diff --git a/CHANGES b/CHANGES index f06956bfc..13d7b0f4c 100644 --- a/CHANGES +++ b/CHANGES @@ -28,6 +28,7 @@ Misc: - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs + - GBA Audio: Remove broken XQ audio pending rewrite - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 6702f5ff4..a6eb4824d 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -56,7 +56,6 @@ DECL_BITFIELD(GBARegisterSOUNDBIAS, uint16_t); DECL_BITS(GBARegisterSOUNDBIAS, Bias, 0, 10); DECL_BITS(GBARegisterSOUNDBIAS, Resolution, 14, 2); -struct GBAAudioMixer; struct GBAAudio { struct GBA* p; @@ -82,8 +81,6 @@ struct GBAAudio { size_t samples; GBARegisterSOUNDBIAS soundbias; - struct GBAAudioMixer* mixer; - bool externalMixing; int32_t sampleInterval; int32_t lastSample; @@ -259,26 +256,6 @@ struct GBAMP2kTrack { 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 mStereoSample 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 deleted file mode 100644 index 369a4aaa3..000000000 --- a/include/mgba/internal/gba/extra/audio-mixer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* 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/CMakeLists.txt b/src/gba/CMakeLists.txt index 4bf354f3a..933ba3fac 100644 --- a/src/gba/CMakeLists.txt +++ b/src/gba/CMakeLists.txt @@ -40,7 +40,6 @@ set(SIO_FILES sio/lockstep.c) set(EXTRA_FILES - extra/audio-mixer.c extra/battlechip.c extra/proxy.c) diff --git a/src/gba/audio.c b/src/gba/audio.c index b25273f16..56f42b14f 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -50,11 +50,9 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000); blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000); - audio->externalMixing = false; audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; - audio->mixer = NULL; } void GBAAudioReset(struct GBAAudio* audio) { @@ -131,27 +129,6 @@ void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* mLOG(GBA_AUDIO, GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest); return; } - if (audio->mixer) { - uint32_t source = info->source; - uint32_t offsets[] = { 0x350, 0x980 }; - size_t i; - for (i = 0; i < sizeof(offsets) / sizeof(*offsets); ++i) { - if (source < GBA_BASE_EWRAM + offsets[i]) { - continue; - } - if (source >= GBA_BASE_IO + offsets[i]) { - continue; - } - uint32_t value = GBALoad32(audio->p->cpu, source - offsets[i], NULL); - if (value - MP2K_MAGIC <= MP2K_LOCK_MAX) { - audio->mixer->engage(audio->mixer, source - offsets[i]); - break; - } - } - if (i == sizeof(offsets) / sizeof(*offsets)) { - audio->externalMixing = false; - } - } } void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) { @@ -392,28 +369,23 @@ void GBAAudioSample(struct GBAAudio* audio, int32_t timestamp) { sampleLeft >>= psgShift; sampleRight >>= psgShift; - if (audio->mixer) { - audio->mixer->step(audio->mixer); - } - if (!audio->externalMixing) { - if (!audio->forceDisableChA) { - if (audio->chALeft) { - sampleLeft += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; - } - - if (audio->chARight) { - sampleRight += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; - } + if (!audio->forceDisableChA) { + if (audio->chALeft) { + sampleLeft += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; } - if (!audio->forceDisableChB) { - if (audio->chBLeft) { - sampleLeft += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; - } + if (audio->chARight) { + sampleRight += (audio->chA.samples[sample] << 2) >> !audio->volumeChA; + } + } - if (audio->chBRight) { - sampleRight += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; - } + if (!audio->forceDisableChB) { + if (audio->chBLeft) { + sampleLeft += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; + } + + if (audio->chBRight) { + sampleRight += (audio->chB.samples[sample] << 2) >> !audio->volumeChB; } } diff --git a/src/gba/core.c b/src/gba/core.c index 4fb801c4a..fbdd5e85b 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #ifndef DISABLE_THREADING #include @@ -191,7 +190,6 @@ static const struct mCoreRegisterInfo _GBARegisters[] = { struct mVideoLogContext; -#define CPU_COMPONENT_AUDIO_MIXER CPU_COMPONENT_MISC_1 #define LOGO_CRC32 0xD0BEB55E struct GBACore { @@ -216,7 +214,6 @@ struct GBACore { bool hasOverride; struct mDebuggerPlatform* debuggerPlatform; struct mCheatDevice* cheatDevice; - struct GBAAudioMixer* audioMixer; struct mCoreMemoryBlock memoryBlocks[12]; size_t nMemoryBlocks; int memoryBlockType; @@ -269,7 +266,6 @@ static bool _GBACoreInit(struct mCore* core) { #ifndef MINIMAL_CORE gbacore->logContext = NULL; #endif - gbacore->audioMixer = NULL; GBACreate(gba); // TODO: Restore cheats @@ -324,7 +320,6 @@ static void _GBACoreDeinit(struct mCore* core) { if (gbacore->cheatDevice) { mCheatDeviceDestroy(gbacore->cheatDevice); } - free(gbacore->audioMixer); mCoreConfigFreeOpts(&core->opts); free(core); } @@ -387,7 +382,6 @@ 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.forceGbp"); - mCoreConfigCopyValue(&core->config, config, "gba.audioHle"); mCoreConfigCopyValue(&core->config, config, "vbaBugCompat"); #ifndef DISABLE_THREADING @@ -734,16 +728,6 @@ static void _GBACoreReset(struct mCore* core) { } } -#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 - bool forceGbp = false; bool vbaBugCompat = true; mCoreConfigGetBoolValue(&core->config, "gba.forceGbp", &forceGbp); diff --git a/src/gba/extra/audio-mixer.c b/src/gba/extra/audio-mixer.c deleted file mode 100644 index e01b609b4..000000000 --- a/src/gba/extra/audio-mixer.c +++ /dev/null @@ -1,306 +0,0 @@ -/* 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]; - mCircleBufferInit(&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) { - mCircleBufferDeinit(&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 mStereoSample stereo = { - (sample * track->channel->leftVolume * track->channel->envelopeV) >> 9, - (sample * track->channel->rightVolume * track->channel->envelopeV) >> 9 - }; - - mCircleBufferWrite16(&track->buffer, stereo.left); - mCircleBufferWrite16(&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)); - } - if (track->track.runningStatus == 0xCD) { - // XCMD isn't supported - mixer->p->externalMixing = false; - } - } -} - -bool _mp2kEngage(struct GBAAudioMixer* mixer, uint32_t address) { - if (address != mixer->contextAddress) { - mixer->contextAddress = address; - mixer->p->externalMixing = true; - _mp2kReload(mixer); - } - return true; -} - -void _mp2kStep(struct GBAAudioMixer* mixer) { - 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; - mCircleBufferClear(&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 mStereoSample sample = {0}; - size_t track; - for (track = 0; track < MP2K_MAX_SOUND_CHANNELS; ++track) { - if (!mixer->activeTracks[track].channel->status) { - continue; - } - int16_t value; - mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); - sample.left += value; - mCircleBufferRead16(&mixer->activeTracks[track].buffer, &value); - sample.right += value; - } - sample.left = (sample.left * mixer->p->masterVolume) >> 8; - sample.right = (sample.right * mixer->p->masterVolume) >> 8; - 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.right - mixer->last.right); - } - 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 41eee7435..fb0a84ae7 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -928,10 +928,6 @@ 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); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index e95da696c..66c125466 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -607,12 +607,6 @@ void SettingsView::updateConfig() { emit languageChanged(); } - bool oldAudioHle = m_controller->getOption("gba.audioHle", "0") != "0"; - if (oldAudioHle != m_ui.audioHle->isChecked()) { - saveSetting("gba.audioHle", m_ui.audioHle); - emit audioHleChanged(); - } - if (m_ui.multiplayerAudioAll->isChecked()) { m_controller->setQtOption("multiplayerAudio", "all"); } else if (m_ui.multiplayerAudio1->isChecked()) { @@ -740,7 +734,6 @@ void SettingsView::reloadConfig() { loadSetting("logToStdout", m_ui.logToStdout); loadSetting("logFile", m_ui.logFile); loadSetting("useDiscordPresence", m_ui.useDiscordPresence); - loadSetting("gba.audioHle", m_ui.audioHle); loadSetting("dynamicTitle", m_ui.dynamicTitle, true); loadSetting("gba.forceGbp", m_ui.forceGbp); loadSetting("vbaBugCompat", m_ui.vbaBugCompat, true); diff --git a/src/platform/qt/SettingsView.h b/src/platform/qt/SettingsView.h index 3543419fc..010b4ef0d 100644 --- a/src/platform/qt/SettingsView.h +++ b/src/platform/qt/SettingsView.h @@ -63,7 +63,6 @@ signals: void pathsChanged(); void languageChanged(); void libraryCleared(); - void audioHleChanged(); public slots: void selectPage(Page); diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index 42e4af5a0..8539e6bdb 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -1307,14 +1307,7 @@ - - - - XQ GBA audio (experimental) - - - - + OpenGL enhancements diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index bd52b0862..c75a163ef 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -543,15 +543,6 @@ void Window::openSettingsWindow(SettingsView::Page page) { connect(settingsWindow, &SettingsView::videoRendererChanged, this, &Window::changeRenderer); connect(settingsWindow, &SettingsView::languageChanged, this, &Window::mustRestart); connect(settingsWindow, &SettingsView::pathsChanged, this, &Window::reloadConfig); - connect(settingsWindow, &SettingsView::audioHleChanged, this, [this]() { - if (!m_controller) { - return; - } - if (m_controller->platform() != mPLATFORM_GBA) { - return; - } - mustReset(); - }); #ifdef USE_SQLITE3 connect(settingsWindow, &SettingsView::libraryCleared, m_libraryView, &LibraryController::clear); #endif From f51cb153d109f842fdc5325715be97a71fcacd28 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:42:26 -0700 Subject: [PATCH 049/148] Core: Switch from blip to mAudioResampler --- include/mgba/core/core.h | 3 +- include/mgba/core/interface.h | 4 +- include/mgba/core/sync.h | 5 +- include/mgba/internal/gb/audio.h | 8 +-- include/mgba/internal/gba/audio.h | 4 -- src/core/sync.c | 10 +-- src/core/thread.c | 4 +- src/gb/audio.c | 55 ++++----------- src/gb/core.c | 13 +--- src/gba/audio.c | 51 +++----------- src/gba/core.c | 13 +--- src/platform/3ds/main.c | 22 +++--- src/platform/libretro/libretro.c | 26 +++---- src/platform/psp2/psp2-context.c | 102 +++++++++++++++------------ src/platform/python/_builder.h | 1 - src/platform/python/_builder.py | 1 - src/platform/python/mgba/audio.py | 57 --------------- src/platform/python/mgba/core.py | 8 --- src/platform/qt/AudioDevice.cpp | 67 ++++++++++++++---- src/platform/qt/AudioDevice.h | 13 ++++ src/platform/qt/AudioProcessorQt.cpp | 11 ++- src/platform/qt/AudioProcessorQt.h | 1 + src/platform/sdl/sdl-audio.c | 37 ++++------ src/platform/sdl/sdl-audio.h | 4 ++ src/platform/switch/main.c | 12 +--- src/platform/test/fuzz-main.c | 7 +- src/platform/test/perf-main.c | 1 - src/platform/wii/main.c | 79 ++++++++++----------- 28 files changed, 257 insertions(+), 362 deletions(-) delete mode 100644 src/platform/python/mgba/audio.py diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 7eeb1d8fb..a4bf5826c 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -32,6 +32,7 @@ enum mCoreChecksumType { mCHECKSUM_CRC32, }; +struct mAudioBuffer; struct mCoreConfig; struct mCoreSync; struct mDebuggerSymbols; @@ -79,7 +80,7 @@ struct mCore { void (*putPixels)(struct mCore*, const void* buffer, size_t stride); unsigned (*audioSampleRate)(const struct mCore*); - struct blip_t* (*getAudioChannel)(struct mCore*, int ch); + struct mAudioBuffer* (*getAudioBuffer)(struct mCore*); void (*setAudioBufferSize)(struct mCore*, size_t samples); size_t (*getAudioBufferSize)(struct mCore*); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index f1af5e50d..b07f300f3 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -16,7 +16,7 @@ CXX_GUARD_START struct mCore; struct mStateExtdataItem; -struct blip_t; +struct mAudioBuffer; enum mCoreFeature { mCORE_FEATURE_OPENGL = 1, @@ -41,7 +41,7 @@ struct mAVStream { void (*audioRateChanged)(struct mAVStream*, unsigned rate); void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride); void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right); - void (*postAudioBuffer)(struct mAVStream*, struct blip_t* left, struct blip_t* right); + void (*postAudioBuffer)(struct mAVStream*, struct mAudioBuffer*); }; struct mStereoSample { diff --git a/include/mgba/core/sync.h b/include/mgba/core/sync.h index a44994b07..df4e777bb 100644 --- a/include/mgba/core/sync.h +++ b/include/mgba/core/sync.h @@ -22,6 +22,7 @@ struct mCoreSync { bool audioWait; Condition audioRequiredCond; Mutex audioBufferMutex; + size_t audioHighWater; float fpsTarget; }; @@ -32,8 +33,8 @@ bool mCoreSyncWaitFrameStart(struct mCoreSync* sync); void mCoreSyncWaitFrameEnd(struct mCoreSync* sync); void mCoreSyncSetVideoSync(struct mCoreSync* sync, bool wait); -struct blip_t; -bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct blip_t*, size_t samples); +struct mAudioBuffer; +bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct mAudioBuffer*); void mCoreSyncLockAudio(struct mCoreSync* sync); void mCoreSyncUnlockAudio(struct mCoreSync* sync); void mCoreSyncConsumeAudio(struct mCoreSync* sync); diff --git a/include/mgba/internal/gb/audio.h b/include/mgba/internal/gb/audio.h index 5b8993ac5..8b9b775c3 100644 --- a/include/mgba/internal/gb/audio.h +++ b/include/mgba/internal/gb/audio.h @@ -12,6 +12,7 @@ CXX_GUARD_START #include #include +#include #define GB_MAX_SAMPLES 32 @@ -166,14 +167,9 @@ struct GBAudio { struct GBAudioWaveChannel ch3; struct GBAudioNoiseChannel ch4; - struct blip_t* left; - struct blip_t* right; - int16_t lastLeft; - int16_t lastRight; + struct mAudioBuffer buffer; int32_t capLeft; int32_t capRight; - int clock; - int32_t clockRate; uint8_t volumeRight; uint8_t volumeLeft; diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index a6eb4824d..5b5db3a62 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -63,10 +63,6 @@ struct GBAAudio { struct GBAAudioFIFO chA; struct GBAAudioFIFO chB; - int16_t lastLeft; - int16_t lastRight; - int clock; - uint8_t volume; bool volumeChA; bool volumeChB; diff --git a/src/core/sync.c b/src/core/sync.c index b2a65493b..e46e7dcda 100644 --- a/src/core/sync.c +++ b/src/core/sync.c @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include +#include static void _changeVideoSync(struct mCoreSync* sync, bool wait) { // Make sure the video thread can process events while the GBA thread is paused @@ -79,17 +79,17 @@ void mCoreSyncSetVideoSync(struct mCoreSync* sync, bool wait) { _changeVideoSync(sync, wait); } -bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct blip_t* buf, size_t samples) { +bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct mAudioBuffer* buf) { if (!sync) { return true; } - size_t produced = blip_samples_avail(buf); + size_t produced = mAudioBufferAvailable(buf); size_t producedNew = produced; - while (sync->audioWait && producedNew >= samples) { + while (sync->audioWait && sync->audioHighWater && producedNew >= sync->audioHighWater) { ConditionWait(&sync->audioRequiredCond, &sync->audioBufferMutex); produced = producedNew; - producedNew = blip_samples_avail(buf); + producedNew = mAudioBufferAvailable(buf); } MutexUnlock(&sync->audioBufferMutex); return producedNew != produced; diff --git a/src/core/thread.c b/src/core/thread.c index 18c1c20e1..0be5f81e2 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include #include #ifdef ENABLE_SCRIPTING #include @@ -368,7 +367,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { if (impl->sync.audioWait) { MutexUnlock(&impl->stateMutex); mCoreSyncLockAudio(&impl->sync); - mCoreSyncProduceAudio(&impl->sync, core->getAudioChannel(core, 0), core->getAudioBufferSize(core)); + mCoreSyncProduceAudio(&impl->sync, core->getAudioBuffer(core)); MutexLock(&impl->stateMutex); } } @@ -498,6 +497,7 @@ bool mCoreThreadStart(struct mCoreThread* threadContext) { threadContext->impl->sync.audioWait = threadContext->core->opts.audioSync; threadContext->impl->sync.videoFrameWait = threadContext->core->opts.videoSync; threadContext->impl->sync.fpsTarget = threadContext->core->opts.fpsTarget; + threadContext->impl->sync.audioHighWater = 512; MutexLock(&threadContext->impl->stateMutex); ThreadCreate(&threadContext->impl->thread, _mCoreThreadRun, threadContext); diff --git a/src/gb/audio.c b/src/gb/audio.c index cf5445e15..4230fb88c 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#include #include #include #include @@ -15,15 +14,10 @@ #include #endif -#ifdef __3DS__ -#define blip_add_delta blip_add_delta_fast -#endif - +#define AUDIO_BUFFER_SAMPLES 0x4000 #define FRAME_CYCLES (DMG_SM83_FREQUENCY >> 9) const uint32_t DMG_SM83_FREQUENCY = 0x400000; -static const int CLOCKS_PER_BLIP_FRAME = 0x1000; -static const unsigned BLIP_BUFFER_SIZE = 0x4000; static const int SAMPLE_INTERVAL = 32; static const int FILTER = 65368; const int GB_AUDIO_VOLUME_MAX = 0x100; @@ -57,12 +51,7 @@ static const int _squareChannelDuty[4][8] = { void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style) { audio->samples = samples; - audio->left = blip_new(BLIP_BUFFER_SIZE); - audio->right = blip_new(BLIP_BUFFER_SIZE); - audio->clockRate = DMG_SM83_FREQUENCY; - // Guess too large; we hang producing extra samples if we guess too low - blip_set_rates(audio->left, DMG_SM83_FREQUENCY, 96000); - blip_set_rates(audio->right, DMG_SM83_FREQUENCY, 96000); + mAudioBufferInit(&audio->buffer, AUDIO_BUFFER_SAMPLES, 2); audio->forceDisableCh[0] = false; audio->forceDisableCh[1] = false; audio->forceDisableCh[2] = false; @@ -86,8 +75,7 @@ void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAu } void GBAudioDeinit(struct GBAudio* audio) { - blip_delete(audio->left); - blip_delete(audio->right); + mAudioBufferDeinit(&audio->buffer); } void GBAudioReset(struct GBAudio* audio) { @@ -123,11 +111,9 @@ void GBAudioReset(struct GBAudio* audio) { audio->sampleInterval = SAMPLE_INTERVAL * GB_MAX_SAMPLES; audio->lastSample = 0; audio->sampleIndex = 0; - audio->lastLeft = 0; - audio->lastRight = 0; audio->capLeft = 0; audio->capRight = 0; - audio->clock = 0; + mAudioBufferClear(&audio->buffer); audio->playingCh1 = false; audio->playingCh2 = false; audio->playingCh3 = false; @@ -140,14 +126,8 @@ void GBAudioReset(struct GBAudio* audio) { } void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples) { - if (samples > BLIP_BUFFER_SIZE / 2) { - samples = BLIP_BUFFER_SIZE / 2; - } mCoreSyncLockAudio(audio->p->sync); audio->samples = samples; - blip_clear(audio->left); - blip_clear(audio->right); - audio->clock = 0; mCoreSyncConsumeAudio(audio->p->sync); } @@ -845,34 +825,25 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { unsigned produced; int i; for (i = 0; i < GB_MAX_SAMPLES; ++i) { - int16_t sampleLeft = audio->currentSamples[i].left; - int16_t sampleRight = audio->currentSamples[i].right; - if ((size_t) blip_samples_avail(audio->left) < audio->samples) { - blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft); - blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight); - audio->lastLeft = sampleLeft; - audio->lastRight = sampleRight; - audio->clock += SAMPLE_INTERVAL; - if (audio->clock >= CLOCKS_PER_BLIP_FRAME) { - blip_end_frame(audio->left, CLOCKS_PER_BLIP_FRAME); - blip_end_frame(audio->right, CLOCKS_PER_BLIP_FRAME); - audio->clock -= CLOCKS_PER_BLIP_FRAME; - } - } + int16_t sample[2] = { + audio->currentSamples[i].left, + audio->currentSamples[i].right + }; + mAudioBufferWrite(&audio->buffer, sample, 1); if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight); + audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); } } - produced = blip_samples_avail(audio->left); + produced = mAudioBufferAvailable(&audio->buffer); bool wait = produced >= audio->samples; - if (!mCoreSyncProduceAudio(audio->p->sync, audio->left, audio->samples)) { + if (!mCoreSyncProduceAudio(audio->p->sync, &audio->buffer)) { // Interrupted audio->p->earlyExit = true; } if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, audio->left, audio->right); + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); } mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate); } diff --git a/src/gb/core.c b/src/gb/core.c index 9ee6d3f84..7023b29f7 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -428,16 +428,9 @@ static void _GBCorePutPixels(struct mCore* core, const void* buffer, size_t stri gbcore->renderer.d.putPixels(&gbcore->renderer.d, stride, buffer); } -static struct blip_t* _GBCoreGetAudioChannel(struct mCore* core, int ch) { +static struct mAudioBuffer* _GBCoreGetAudioBuffer(struct mCore* core) { struct GB* gb = core->board; - switch (ch) { - case 0: - return gb->audio.left; - case 1: - return gb->audio.right; - default: - return NULL; - } + return &gb->audio.buffer; } static void _GBCoreSetAudioBufferSize(struct mCore* core, size_t samples) { @@ -1308,7 +1301,7 @@ struct mCore* GBCoreCreate(void) { core->getPixels = _GBCoreGetPixels; core->putPixels = _GBCorePutPixels; core->audioSampleRate = _GBCoreAudioSampleRate; - core->getAudioChannel = _GBCoreGetAudioChannel; + core->getAudioBuffer = _GBCoreGetAudioBuffer; core->setAudioBufferSize = _GBCoreSetAudioBufferSize; core->getAudioBufferSize = _GBCoreGetAudioBufferSize; core->setAVStream = _GBCoreSetAVStream; diff --git a/src/gba/audio.c b/src/gba/audio.c index 56f42b14f..8ccc7f9d8 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -16,17 +15,12 @@ #define MP2K_LOCK_MAX 8 -#ifdef __3DS__ -#define blip_add_delta blip_add_delta_fast -#endif - mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio", "gba.audio"); const unsigned GBA_AUDIO_SAMPLES = 2048; const int GBA_AUDIO_VOLUME_MAX = 0x100; static const int SAMPLE_INTERVAL = GBA_ARM7TDMI_FREQUENCY / 0x4000; -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); @@ -41,14 +35,10 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { #ifdef __BIG_ENDIAN__ ++nr52; #endif - GBAudioInit(&audio->psg, 0, nr52, GB_AUDIO_GBA); + GBAudioInit(&audio->psg, samples, nr52, GB_AUDIO_GBA); audio->psg.timing = &audio->p->timing; - audio->psg.clockRate = GBA_ARM7TDMI_FREQUENCY; audio->psg.frameEvent.context = audio; audio->samples = samples; - // Guess too large; we hang producing extra samples if we guess too low - blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000); - blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000); audio->forceDisableChA = false; audio->forceDisableChB = false; @@ -93,10 +83,6 @@ void GBAAudioReset(struct GBAAudio* audio) { audio->enable = false; audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; audio->psg.sampleInterval = audio->sampleInterval; - - blip_clear(audio->psg.left); - blip_clear(audio->psg.right); - audio->clock = 0; } void GBAAudioDeinit(struct GBAAudio* audio) { @@ -104,14 +90,9 @@ void GBAAudioDeinit(struct GBAAudio* audio) { } void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) { - if (samples > 0x2000) { - samples = 0x2000; - } mCoreSyncLockAudio(audio->p->sync); audio->samples = samples; - blip_clear(audio->psg.left); - blip_clear(audio->psg.right); - audio->clock = 0; + audio->psg.samples = samples; mCoreSyncConsumeAudio(audio->p->sync); } @@ -414,34 +395,24 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { unsigned produced; int i; for (i = 0; i < samples; ++i) { - int16_t sampleLeft = audio->currentSamples[i].left; - int16_t sampleRight = audio->currentSamples[i].right; - if ((size_t) blip_samples_avail(audio->psg.left) < audio->samples) { - blip_add_delta(audio->psg.left, audio->clock, sampleLeft - audio->lastLeft); - blip_add_delta(audio->psg.right, audio->clock, sampleRight - audio->lastRight); - audio->lastLeft = sampleLeft; - audio->lastRight = sampleRight; - audio->clock += audio->sampleInterval; - if (audio->clock >= CLOCKS_PER_FRAME) { - blip_end_frame(audio->psg.left, CLOCKS_PER_FRAME); - blip_end_frame(audio->psg.right, CLOCKS_PER_FRAME); - audio->clock -= CLOCKS_PER_FRAME; - } - } - + int16_t sample[2] = { + audio->currentSamples[i].left, + audio->currentSamples[i].right + }; + mAudioBufferWrite(&audio->psg.buffer, sample, 1); if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight); + audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); } } - produced = blip_samples_avail(audio->psg.left); + produced = mAudioBufferAvailable(&audio->psg.buffer); bool wait = produced >= audio->samples; - if (!mCoreSyncProduceAudio(audio->p->sync, audio->psg.left, audio->samples)) { + if (!mCoreSyncProduceAudio(audio->p->sync, &audio->psg.buffer)) { // Interrupted audio->p->earlyExit = true; } if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, audio->psg.left, audio->psg.right); + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); } mTimingSchedule(timing, &audio->sampleEvent, SAMPLE_INTERVAL - cyclesLate); diff --git a/src/gba/core.c b/src/gba/core.c index fbdd5e85b..4a437f36d 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -558,16 +558,9 @@ static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { return 65536; } -static struct blip_t* _GBACoreGetAudioChannel(struct mCore* core, int ch) { +static struct mAudioBuffer* _GBACoreGetAudioBuffer(struct mCore* core) { struct GBA* gba = core->board; - switch (ch) { - case 0: - return gba->audio.psg.left; - case 1: - return gba->audio.psg.right; - default: - return NULL; - } + return &gba->audio.psg.buffer; } static void _GBACoreSetAudioBufferSize(struct mCore* core, size_t samples) { @@ -1505,7 +1498,7 @@ struct mCore* GBACoreCreate(void) { core->getPixels = _GBACoreGetPixels; core->putPixels = _GBACorePutPixels; core->audioSampleRate = _GBACoreAudioSampleRate; - core->getAudioChannel = _GBACoreGetAudioChannel; + core->getAudioBuffer = _GBACoreGetAudioBuffer; core->setAudioBufferSize = _GBACoreSetAudioBufferSize; core->getAudioBufferSize = _GBACoreGetAudioBufferSize; core->addCoreCallbacks = _GBACoreAddCoreCallbacks; diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index fb4f63a56..c85103bce 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -4,7 +4,6 @@ * 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 #ifdef M_CORE_GBA @@ -61,7 +60,7 @@ static enum DarkenMode { #define _3DS_INPUT 0x3344534B -#define AUDIO_SAMPLES 384 +#define AUDIO_SAMPLES 1280 #define AUDIO_SAMPLE_BUFFER (AUDIO_SAMPLES * 16) #define DSP_BUFFERS 4 @@ -190,7 +189,7 @@ static void _map3DSKey(struct mInputMap* map, int ctrKey, int key) { mInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer); static void _drawStart(void) { if (frameStarted) { @@ -343,12 +342,13 @@ static void _gameLoaded(struct mGUIRunner* runner) { } osSetSpeedupEnable(true); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 32768); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 32768); if (hasSound != NO_SOUND) { audioPos = 0; } if (hasSound == DSP_SUPPORTED) { + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + double fauxClock = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); + ndspChnSetRate(0, sampleRate * fauxClock); memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); } unsigned mode; @@ -607,8 +607,7 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_FLIP_VERT(1)); if (hasSound == NO_SOUND) { - blip_clear(runner->core->getAudioChannel(runner->core, 0)); - blip_clear(runner->core->getAudioChannel(runner->core, 1)); + mAudioBufferClear(runner->core->getAudioBuffer(runner->core)); } _drawTex(runner->core, faded, interframeBlending); @@ -775,15 +774,14 @@ static void _requestImage(struct mImageSource* source, const void** buffer, size CAMU_SetReceiving(&imageSource->handles[0], imageSource->buffer, PORT_CAM1, imageSource->bufferSize, imageSource->transferSize); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); if (hasSound == DSP_SUPPORTED) { int startId = bufferId; while (dspBuffer[bufferId].status == NDSP_WBUF_QUEUED || dspBuffer[bufferId].status == NDSP_WBUF_PLAYING) { bufferId = (bufferId + 1) & (DSP_BUFFERS - 1); if (bufferId == startId) { - blip_clear(left); - blip_clear(right); + mAudioBufferClear(buffer); return; } } @@ -791,8 +789,7 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig memset(&dspBuffer[bufferId], 0, sizeof(dspBuffer[bufferId])); dspBuffer[bufferId].data_pcm16 = tmpBuf; dspBuffer[bufferId].nsamples = AUDIO_SAMPLES; - blip_read_samples(left, dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES, true); - blip_read_samples(right, dspBuffer[bufferId].data_pcm16 + 1, AUDIO_SAMPLES, true); + mAudioBufferRead(buffer, dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES); DSP_FlushDataCache(dspBuffer[bufferId].data_pcm16, AUDIO_SAMPLES * 2 * sizeof(int16_t)); ndspChnWaveBufAdd(0, &dspBuffer[bufferId]); } @@ -857,7 +854,6 @@ int main(int argc, char* argv[]) { ndspChnReset(0); ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); ndspChnSetInterp(0, NDSP_INTERP_NONE); - ndspChnSetRate(0, 32822); ndspChnWaveBufClear(0); audioLeft = linearMemAlign(AUDIO_SAMPLES * DSP_BUFFERS * 2 * sizeof(int16_t), 0x80); memset(dspBuffer, 0, sizeof(dspBuffer)); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 69c547b57..8478eb298 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -7,7 +7,6 @@ #include -#include #include #include #include @@ -30,7 +29,6 @@ #include "libretro_core_options.h" #define GB_SAMPLES 512 -#define SAMPLE_RATE 32768 /* An alpha factor of 1/180 is *somewhat* equivalent * to calculating the average for the last 180 * frames, or 3 seconds of runtime... */ @@ -54,7 +52,7 @@ static retro_set_sensor_state_t sensorStateCallback; static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); -static void _postAudioBuffer(struct mAVStream*, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); static void _setRumble(struct mRumble* rumble, int enable); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); @@ -424,7 +422,7 @@ void retro_get_system_av_info(struct retro_system_av_info* info) { info->geometry.aspect_ratio = width / (double) height; info->timing.fps = core->frequency(core) / (float) core->frameCycles(core); - info->timing.sample_rate = SAMPLE_RATE; + info->timing.sample_rate = core->audioSampleRate(core); } void retro_init(void) { @@ -613,9 +611,8 @@ void retro_run(void) { #ifdef M_CORE_GBA if (core->platform(core) == mPLATFORM_GBA) { - blip_t *audioChannelLeft = core->getAudioChannel(core, 0); - blip_t *audioChannelRight = core->getAudioChannel(core, 1); - int samplesAvail = blip_samples_avail(audioChannelLeft); + struct mAudioBuffer *buffer = core->getAudioBuffer(core); + int samplesAvail = mAudioBufferAvailable(buffer); if (samplesAvail > 0) { /* Update 'running average' of number of * samples per frame. @@ -632,8 +629,7 @@ void retro_run(void) { audioSampleBufferSize = (samplesToRead * 2); audioSampleBuffer = realloc(audioSampleBuffer, audioSampleBufferSize * sizeof(int16_t)); } - int produced = blip_read_samples(audioChannelLeft, audioSampleBuffer, samplesToRead, true); - blip_read_samples(audioChannelRight, audioSampleBuffer + 1, samplesToRead, true); + int produced = mAudioBufferRead(buffer, audioSampleBuffer, samplesToRead); if (produced > 0) { if (audioLowPassEnabled) { _audioLowPassFilter(audioSampleBuffer, produced); @@ -884,9 +880,9 @@ bool retro_load_game(const struct retro_game_info* game) { * to nominal number of samples per frame. * Buffer will be resized as required in * retro_run(). */ - size_t audioSamplesPerFrame = (size_t)((float) SAMPLE_RATE * (float) core->frameCycles(core) / + size_t audioSamplesPerFrame = (size_t)((float) core->audioSampleRate(core) * (float) core->frameCycles(core) / (float)core->frequency(core)); - audioSampleBufferSize = audioSamplesPerFrame * 2; + audioSampleBufferSize = ceil(audioSamplesPerFrame) * 2; audioSampleBuffer = malloc(audioSampleBufferSize * sizeof(int16_t)); audioSamplesPerFrameAvg = (float) audioSamplesPerFrame; /* Internal audio buffer size should be @@ -918,9 +914,6 @@ bool retro_load_game(const struct retro_game_info* game) { core->setAudioBufferSize(core, GB_SAMPLES); } - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), SAMPLE_RATE); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), SAMPLE_RATE); - core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); core->setPeripheral(core, mPERIPH_ROTATION, &rotation); @@ -1238,10 +1231,9 @@ void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, con } /* Used only for GB/GBC content */ -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); - int produced = blip_read_samples(left, audioSampleBuffer, GB_SAMPLES, true); - blip_read_samples(right, audioSampleBuffer + 1, GB_SAMPLES, true); + int produced = mAudioBufferRead(buffer, audioSampleBuffer, GB_SAMPLES); if (produced > 0) { if (audioLowPassEnabled) { _audioLowPassFilter(audioSampleBuffer, produced); diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 755021f6f..36253aa07 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -5,7 +5,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "psp2-context.h" -#include #include #ifdef M_CORE_GBA @@ -18,9 +17,10 @@ #include "feature/gui/gui-runner.h" #include -#include +#include #include #include +#include #include #include #include @@ -84,14 +84,21 @@ bool frameLimiter = true; extern const uint8_t _binary_backdrop_png_start[]; static vita2d_texture* backdrop = 0; +#define BUFFERS 16 #define PSP2_SAMPLES 512 -#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * 16) +#define PSP2_AUDIO_BUFFER_SIZE (PSP2_SAMPLES * BUFFERS) + +struct mPSP2AudioBuffer { + int16_t samples[PSP2_SAMPLES * 2] __attribute__((__aligned__(64))); + bool full; +}; static struct mPSP2AudioContext { - struct mStereoSample buffer[PSP2_AUDIO_BUFFER_SIZE]; - size_t writeOffset; - size_t readOffset; - size_t samples; + struct mPSP2AudioBuffer outputBuffers[BUFFERS]; + int currentAudioBuffer; + int nextAudioBuffer; + struct mAudioBuffer buffer; + struct mAudioResampler resampler; Mutex mutex; Condition cond; bool running; @@ -103,29 +110,26 @@ void mPSP2MapKey(struct mInputMap* map, int pspKey, int key) { static THREAD_ENTRY _audioThread(void* context) { struct mPSP2AudioContext* audio = (struct mPSP2AudioContext*) context; - uint32_t zeroBuffer[PSP2_SAMPLES] = {0}; - void* buffer = zeroBuffer; + const int16_t zeroBuffer[PSP2_SAMPLES * 2] __attribute__((__aligned__(64))) = {0}; + const void* buffer = zeroBuffer; int audioPort = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, PSP2_SAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO); + struct mPSP2AudioBuffer* outputBuffer = NULL; while (audio->running) { MutexLock(&audio->mutex); - if (buffer != zeroBuffer) { + if (outputBuffer) { // Can only happen in successive iterations - audio->samples -= PSP2_SAMPLES; + outputBuffer->full = false; ConditionWake(&audio->cond); } - if (audio->samples >= PSP2_SAMPLES) { - buffer = &audio->buffer[audio->readOffset]; - audio->readOffset += PSP2_SAMPLES; - if (audio->readOffset >= PSP2_AUDIO_BUFFER_SIZE) { - audio->readOffset = 0; - } - // Don't mark samples as read until the next loop iteration to prevent - // writing to the buffer while being read (see above) + outputBuffer = &audio->outputBuffers[audio->currentAudioBuffer]; + if (outputBuffer->full) { + buffer = outputBuffer->samples; + audio->currentAudioBuffer = (audio->currentAudioBuffer + 1) % BUFFERS; } else { buffer = zeroBuffer; + outputBuffer = NULL; } MutexUnlock(&audio->mutex); - sceAudioOutOutput(audioPort, buffer); } sceAudioOutReleasePort(audioPort); @@ -243,25 +247,21 @@ static void _requestImage(struct mImageSource* source, const void** buffer, size sceCameraRead(imageSource->cam - 1, &read); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) { UNUSED(stream); MutexLock(&audioContext.mutex); - while (audioContext.samples + PSP2_SAMPLES >= PSP2_AUDIO_BUFFER_SIZE) { - if (!frameLimiter) { - blip_clear(left); - blip_clear(right); - MutexUnlock(&audioContext.mutex); - return; + mAudioResamplerProcess(&audioContext.resampler); + while (mAudioBufferAvailable(&audioContext.buffer) >= PSP2_SAMPLES) { + struct mPSP2AudioBuffer* buffer = &audioContext.outputBuffers[audioContext.nextAudioBuffer]; + while (buffer->full) { + if (!frameLimiter) { + break; + } + ConditionWait(&audioContext.cond, &audioContext.mutex); } - ConditionWait(&audioContext.cond, &audioContext.mutex); - } - struct mStereoSample* samples = &audioContext.buffer[audioContext.writeOffset]; - blip_read_samples(left, &samples[0].left, PSP2_SAMPLES, true); - blip_read_samples(right, &samples[0].right, PSP2_SAMPLES, true); - audioContext.samples += PSP2_SAMPLES; - audioContext.writeOffset += PSP2_SAMPLES; - if (audioContext.writeOffset >= PSP2_AUDIO_BUFFER_SIZE) { - audioContext.writeOffset = 0; + mAudioBufferRead(&audioContext.buffer, buffer->samples, PSP2_SAMPLES); + buffer->full = true; + audioContext.nextAudioBuffer = (audioContext.nextAudioBuffer + 1) % BUFFERS; } MutexUnlock(&audioContext.mutex); } @@ -294,7 +294,11 @@ void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit) { UNUSED(runner); if (!frameLimiter && limit) { MutexLock(&audioContext.mutex); - while (audioContext.samples) { + while (true) { + struct mPSP2AudioBuffer* buffer = &audioContext.outputBuffers[audioContext.currentAudioBuffer]; + if (!buffer->full) { + break; + } ConditionWait(&audioContext.cond, &audioContext.mutex); } MutexUnlock(&audioContext.mutex); @@ -334,6 +338,9 @@ void mPSP2Setup(struct mGUIRunner* runner) { runner->core->setVideoBuffer(runner->core, vita2d_texture_get_datap(tex[currentTex]), 256); runner->core->setAudioBufferSize(runner->core, PSP2_SAMPLES); + mAudioBufferInit(&audioContext.buffer, PSP2_AUDIO_BUFFER_SIZE, 2); + mAudioResamplerInit(&audioContext.resampler, mINTERPOLATOR_COSINE); + mAudioResamplerSetDestination(&audioContext.resampler, &audioContext.buffer, 48000); rotation.d.sample = _sampleRotation; rotation.d.readTiltX = _readTiltX; @@ -374,12 +381,6 @@ void mPSP2Setup(struct mGUIRunner* runner) { } void mPSP2LoadROM(struct mGUIRunner* runner) { - float rate = 60.0f / 1.001f; - sceDisplayGetRefreshRate(&rate); - double ratio = mCoreCalculateFramerateRatio(runner->core, rate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); - switch (runner->core->platform(runner->core)) { #ifdef M_CORE_GBA case mPLATFORM_GBA: @@ -415,10 +416,17 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { MutexInit(&audioContext.mutex); ConditionInit(&audioContext.cond); - memset(audioContext.buffer, 0, sizeof(audioContext.buffer)); - audioContext.readOffset = 0; - audioContext.writeOffset = 0; + mAudioBufferClear(&audioContext.buffer); + audioContext.nextAudioBuffer = 0; + audioContext.currentAudioBuffer = 0; audioContext.running = true; + + float rate = 60.0f / 1.001f; + sceDisplayGetRefreshRate(&rate); + double ratio = mCoreCalculateFramerateRatio(runner->core, rate); + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + mAudioBufferClear(&audioContext.buffer); + mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / ratio, true); ThreadCreate(&audioThread, _audioThread, &audioContext); } @@ -483,6 +491,8 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); mCircleBufferDeinit(&rumble.history); + mAudioResamplerDeinit(&audioContext.resampler); + mAudioBufferDeinit(&audioContext.buffer); vita2d_free_texture(tex[0]); vita2d_free_texture(tex[1]); vita2d_free_texture(screenshot); diff --git a/src/platform/python/_builder.h b/src/platform/python/_builder.h index e06e4f5cc..0b51eb19d 100644 --- a/src/platform/python/_builder.h +++ b/src/platform/python/_builder.h @@ -36,7 +36,6 @@ void free(void*); #include -#include #include #include #include diff --git a/src/platform/python/_builder.py b/src/platform/python/_builder.py index 1e21cc82f..1defca537 100644 --- a/src/platform/python/_builder.py +++ b/src/platform/python/_builder.py @@ -21,7 +21,6 @@ ffi.set_source("mgba._pylib", """ #define MGBA_EXPORT #include #define OPAQUE_THREADING -#include #include #include #include diff --git a/src/platform/python/mgba/audio.py b/src/platform/python/mgba/audio.py deleted file mode 100644 index a833d0827..000000000 --- a/src/platform/python/mgba/audio.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (c) 2013-2018 Jeffrey Pfau -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -from ._pylib import ffi, lib # pylint: disable=no-name-in-module - - -class Buffer(object): - def __init__(self, native, internal_rate): - self._native = native - self._internal_rate = internal_rate - - @property - def available(self): - return lib.blip_samples_avail(self._native) - - def set_rate(self, rate): - lib.blip_set_rates(self._native, self._internal_rate, rate) - - def read(self, samples): - buffer = ffi.new("short[%i]" % samples) - count = self.read_into(buffer, samples, 1, 0) - return buffer[:count] - - def read_into(self, buffer, samples, channels=1, interleave=0): - return lib.blip_read_samples(self._native, ffi.addressof(buffer, interleave), samples, channels == 2) - - def clear(self): - lib.blip_clear(self._native) - - -class StereoBuffer(object): - def __init__(self, left, right): - self._left = left - self._right = right - - @property - def available(self): - return min(self._left.available, self._right.available) - - def set_rate(self, rate): - self._left.set_rate(rate) - self._right.set_rate(rate) - - def read(self, samples): - buffer = ffi.new("short[%i]" % (2 * samples)) - count = self.read_into(buffer, samples) - return buffer[0:2 * count] - - def read_into(self, buffer, samples): - samples = self._left.read_into(buffer, samples, 2, 0) - return self._right.read_into(buffer, samples, 2, 1) - - def clear(self): - self._left.clear() - self._right.clear() diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 51f543d3a..75fd1a1cc 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -250,14 +250,6 @@ class Core(object): def audio_buffer_size(self): return self._core.getAudioBufferSize(self._core) - @protected - def get_audio_channels(self): - return audio.StereoBuffer(self.get_audio_channel(0), self.get_audio_channel(1)); - - @protected - def get_audio_channel(self, channel): - return audio.Buffer(self._core.getAudioChannel(self._core, channel), self.frequency) - @protected def reset(self): self._core.reset(self._core) diff --git a/src/platform/qt/AudioDevice.cpp b/src/platform/qt/AudioDevice.cpp index ec6dd3133..bf027cd43 100644 --- a/src/platform/qt/AudioDevice.cpp +++ b/src/platform/qt/AudioDevice.cpp @@ -7,11 +7,12 @@ #include "LogController.h" -#include #include #include #include +#include + using namespace QGBA; AudioDevice::AudioDevice(QObject* parent) @@ -19,6 +20,13 @@ AudioDevice::AudioDevice(QObject* parent) , m_context(nullptr) { setOpenMode(ReadOnly); + mAudioBufferInit(&m_buffer, 0x4000, 2); + mAudioResamplerInit(&m_resampler, mINTERPOLATOR_SINC); +} + +AudioDevice::~AudioDevice() { + mAudioResamplerDeinit(&m_resampler); + mAudioBufferDeinit(&m_buffer); } void AudioDevice::setFormat(const QAudioFormat& format) { @@ -26,15 +34,18 @@ void AudioDevice::setFormat(const QAudioFormat& format) { LOG(QT, INFO) << tr("Can't set format of context-less audio device"); return; } - double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); mCoreSyncLockAudio(&m_context->impl->sync); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 0), - m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); - blip_set_rates(m_context->core->getAudioChannel(m_context->core, 1), - m_context->core->frequency(m_context->core), format.sampleRate() * fauxClock); + mCore* core = m_context->core; + mAudioResamplerSetSource(&m_resampler, core->getAudioBuffer(core), core->audioSampleRate(core), true); + m_format = format; + adjustResampler(); mCoreSyncUnlockAudio(&m_context->impl->sync); } +void AudioDevice::setBufferSamples(int samples) { + m_samples = samples; +} + void AudioDevice::setInput(mCoreThread* input) { m_context = input; } @@ -45,15 +56,25 @@ qint64 AudioDevice::readData(char* data, qint64 maxSize) { return 0; } - maxSize /= sizeof(mStereoSample); + if (!maxSize) { + return 0; + } + mCoreSyncLockAudio(&m_context->impl->sync); - int available = std::min({ - blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)), - maxSize, + mAudioResamplerProcess(&m_resampler); + if (mAudioBufferAvailable(&m_buffer) < 128) { + mCoreSyncConsumeAudio(&m_context->impl->sync); + // Audio is running slow...let's wait a tiny bit for more to come in + QThread::usleep(100); + mCoreSyncLockAudio(&m_context->impl->sync); + mAudioResamplerProcess(&m_resampler); + } + quint64 available = std::min({ + mAudioBufferAvailable(&m_buffer), + static_cast(maxSize / sizeof(mStereoSample)), std::numeric_limits::max() }); - blip_read_samples(m_context->core->getAudioChannel(m_context->core, 0), &reinterpret_cast(data)->left, available, true); - blip_read_samples(m_context->core->getAudioChannel(m_context->core, 1), &reinterpret_cast(data)->right, available, true); + mAudioBufferRead(&m_buffer, reinterpret_cast(data), available); mCoreSyncConsumeAudio(&m_context->impl->sync); return available * sizeof(mStereoSample); } @@ -64,15 +85,33 @@ qint64 AudioDevice::writeData(const char*, qint64) { } bool AudioDevice::atEnd() const { - return !bytesAvailable(); + return false; } qint64 AudioDevice::bytesAvailable() const { + if (!m_context->core) { + return true; + } + int available = mAudioBufferAvailable(&m_buffer); + return available * sizeof(mStereoSample); +} + +qint64 AudioDevice::bytesAvailable() { if (!m_context->core) { return true; } mCoreSyncLockAudio(&m_context->impl->sync); - int available = blip_samples_avail(m_context->core->getAudioChannel(m_context->core, 0)); + adjustResampler(); + mAudioResamplerProcess(&m_resampler); + int available = mAudioBufferAvailable(&m_buffer); mCoreSyncUnlockAudio(&m_context->impl->sync); return available * sizeof(mStereoSample); } + +void AudioDevice::adjustResampler() { + mCore* core = m_context->core; + double fauxClock = mCoreCalculateFramerateRatio(m_context->core, m_context->impl->sync.fpsTarget); + mAudioResamplerSetDestination(&m_resampler, &m_buffer, m_format.sampleRate() * fauxClock); + m_context->impl->sync.audioHighWater = m_samples + m_resampler.highWaterMark + m_resampler.lowWaterMark; + m_context->impl->sync.audioHighWater *= core->audioSampleRate(core) / (m_format.sampleRate() * fauxClock); +} diff --git a/src/platform/qt/AudioDevice.h b/src/platform/qt/AudioDevice.h index e4386bda2..04247cf98 100644 --- a/src/platform/qt/AudioDevice.h +++ b/src/platform/qt/AudioDevice.h @@ -8,6 +8,9 @@ #include #include +#include +#include + struct mCoreThread; namespace QGBA { @@ -17,18 +20,28 @@ Q_OBJECT public: AudioDevice(QObject* parent = nullptr); + virtual ~AudioDevice(); void setInput(mCoreThread* input); void setFormat(const QAudioFormat& format); + void setBufferSamples(int samples); bool atEnd() const override; qint64 bytesAvailable() const override; + qint64 bytesAvailable(); + bool isSequential() const override { return true; } protected: virtual qint64 readData(char* data, qint64 maxSize) override; virtual qint64 writeData(const char* data, qint64 maxSize) override; private: + size_t m_samples = 512; + QAudioFormat m_format; mCoreThread* m_context; + mAudioBuffer m_buffer; + mAudioResampler m_resampler; + + void adjustResampler(); }; } diff --git a/src/platform/qt/AudioProcessorQt.cpp b/src/platform/qt/AudioProcessorQt.cpp index 3e4c5474e..87ad5b5ac 100644 --- a/src/platform/qt/AudioProcessorQt.cpp +++ b/src/platform/qt/AudioProcessorQt.cpp @@ -83,6 +83,7 @@ bool AudioProcessorQt::start() { if (state != QAudio::IdleState) { return; } + recheckUnderflow(); m_recheckTimer.start(); }); #endif @@ -91,6 +92,7 @@ bool AudioProcessorQt::start() { if (m_audioOutput->state() == QAudio::SuspendedState) { m_audioOutput->resume(); } else { + m_device->setBufferSamples(m_samples); m_device->setInput(input()); m_device->setFormat(m_audioOutput->format()); m_audioOutput->start(m_device.get()); @@ -107,12 +109,17 @@ void AudioProcessorQt::pause() { } } -void AudioProcessorQt::setBufferSamples(int) { +void AudioProcessorQt::setBufferSamples(int samples) { + m_samples = samples; + if (m_device) { + m_device->setBufferSamples(samples); + } } void AudioProcessorQt::inputParametersChanged() { if (m_device) { m_device->setFormat(m_audioOutput->format()); + m_device->setBufferSamples(m_samples); } } @@ -138,7 +145,7 @@ void AudioProcessorQt::recheckUnderflow() { m_recheckTimer.stop(); return; } - if (!m_device->atEnd()) { + if (m_device->bytesAvailable()) { start(); m_recheckTimer.stop(); } diff --git a/src/platform/qt/AudioProcessorQt.h b/src/platform/qt/AudioProcessorQt.h index bdfa17a77..bc01a8c07 100644 --- a/src/platform/qt/AudioProcessorQt.h +++ b/src/platform/qt/AudioProcessorQt.h @@ -51,6 +51,7 @@ private: std::unique_ptr m_audioOutput; #endif std::unique_ptr m_device; + size_t m_samples = 1024; unsigned m_sampleRate = 44100; }; diff --git a/src/platform/sdl/sdl-audio.c b/src/platform/sdl/sdl-audio.c index ff7ddd2da..d90ad95d3 100644 --- a/src/platform/sdl/sdl-audio.c +++ b/src/platform/sdl/sdl-audio.c @@ -7,12 +7,6 @@ #include #include -#include -#include - -#include - -#define BUFFER_SIZE (GBA_AUDIO_SAMPLES >> 2) mLOG_DEFINE_CATEGORY(SDL_AUDIO, "SDL Audio", "platform.sdl.audio"); @@ -47,6 +41,10 @@ bool mSDLInitAudio(struct mSDLAudio* context, struct mCoreThread* threadContext) } context->core = 0; + mAudioBufferInit(&context->buffer, context->samples, context->obtainedSpec.channels); + mAudioResamplerInit(&context->resampler, mINTERPOLATOR_SINC); + mAudioResamplerSetDestination(&context->resampler, &context->buffer, context->obtainedSpec.freq); + if (threadContext) { context->core = threadContext->core; context->sync = &threadContext->impl->sync; @@ -70,6 +68,8 @@ void mSDLDeinitAudio(struct mSDLAudio* context) { SDL_PauseAudio(1); SDL_CloseAudio(); #endif + mAudioBufferDeinit(&context->buffer); + mAudioResamplerDeinit(&context->resampler); SDL_QuitSubSystem(SDL_INIT_AUDIO); } @@ -97,13 +97,11 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { memset(data, 0, len); return; } - blip_t* left = NULL; - blip_t* right = NULL; - int32_t clockRate = 1; + struct mAudioBuffer* buffer = NULL; + unsigned sampleRate = 32768; if (audioContext->core) { - clockRate = audioContext->core->frequency(audioContext->core); - left = audioContext->core->getAudioChannel(audioContext->core, 0); - right = audioContext->core->getAudioChannel(audioContext->core, 1); + buffer = audioContext->core->getAudioBuffer(audioContext->core); + sampleRate = audioContext->core->audioSampleRate(audioContext->core); } double fauxClock = 1; if (audioContext->sync) { @@ -111,18 +109,13 @@ static void _mSDLAudioCallback(void* context, Uint8* data, int len) { fauxClock = mCoreCalculateFramerateRatio(audioContext->core, audioContext->sync->fpsTarget); } mCoreSyncLockAudio(audioContext->sync); + audioContext->sync->audioHighWater = audioContext->samples + audioContext->resampler.highWaterMark + audioContext->resampler.lowWaterMark; + audioContext->sync->audioHighWater *= sampleRate / (fauxClock * audioContext->obtainedSpec.freq); } - blip_set_rates(left, clockRate, audioContext->obtainedSpec.freq * fauxClock); - blip_set_rates(right, clockRate, audioContext->obtainedSpec.freq * fauxClock); + mAudioResamplerSetSource(&audioContext->resampler, buffer, sampleRate / fauxClock, true); + mAudioResamplerProcess(&audioContext->resampler); len /= 2 * audioContext->obtainedSpec.channels; - int available = blip_samples_avail(left); - if (available > len) { - available = len; - } - blip_read_samples(left, (short*) data, available, audioContext->obtainedSpec.channels == 2); - if (audioContext->obtainedSpec.channels == 2) { - blip_read_samples(right, ((short*) data) + 1, available, 1); - } + int available = mAudioBufferRead(&audioContext->buffer, (int16_t*) data, len); if (audioContext->sync) { mCoreSyncConsumeAudio(audioContext->sync); diff --git a/src/platform/sdl/sdl-audio.h b/src/platform/sdl/sdl-audio.h index 2ae920af4..b8fa00c85 100644 --- a/src/platform/sdl/sdl-audio.h +++ b/src/platform/sdl/sdl-audio.h @@ -11,6 +11,8 @@ CXX_GUARD_START #include +#include +#include #include // Altivec sometimes defines this @@ -30,6 +32,8 @@ struct mSDLAudio { unsigned sampleRate; // State + struct mAudioBuffer buffer; + struct mAudioResampler resampler; SDL_AudioSpec desiredSpec; SDL_AudioSpec obtainedSpec; #if SDL_VERSION_ATLEAST(2, 0, 0) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 0dc866dfd..8307f9811 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -4,7 +4,6 @@ * 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 "feature/gui/gui-runner.h" -#include #include #include #include @@ -305,9 +304,6 @@ static void _setup(struct mGUIRunner* runner) { u32 samplerate = runner->core->audioSampleRate(runner->core); double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), samplerate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), samplerate); - audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); @@ -576,7 +572,7 @@ static bool _running(struct mGUIRunner* runner) { return appletMainLoop(); } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); int i; while (true) { @@ -590,15 +586,13 @@ static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* rig break; } if (!frameLimiter) { - blip_clear(left); - blip_clear(right); + mAudioBufferClear(buffer); return; } audrenWaitFrame(); } struct mStereoSample* samples = audioBuffer[i]; - blip_read_samples(left, &samples[0].left, SAMPLES, true); - blip_read_samples(right, &samples[0].right, SAMPLES, true); + mAudioBufferRead(buffer, (int16_t*) samples, SAMPLES); armDCacheFlush(samples, SAMPLES * sizeof(struct mStereoSample)); audrvVoiceAddWaveBuf(&audrenDriver, 0, &audrvBuffer[i]); diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index eb42b449b..af3bcf083 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -3,7 +3,6 @@ * 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 @@ -153,9 +152,6 @@ int main(int argc, char** argv) { savestate = 0; } - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 0x8000); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 0x8000); - _fuzzRunloop(core, fuzzOpts.frames); if (hasDebugger) { @@ -188,8 +184,7 @@ static void _fuzzRunloop(struct mCore* core, int frames) { do { core->runFrame(core); --frames; - blip_clear(core->getAudioChannel(core, 0)); - blip_clear(core->getAudioChannel(core, 1)); + mAudioBufferClear(core->getAudioBuffer(core)); } while (frames > 0 && !_dispatchExiting); } diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index 668205296..38d50b30c 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -3,7 +3,6 @@ * 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 diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 4e955a0ad..f21c7e19b 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -14,13 +14,13 @@ #include -#include #include #include "feature/gui/gui-runner.h" #include #include #include #include +#include #include #include #include @@ -76,7 +76,7 @@ static enum VideoMode { static void _retraceCallback(u32 count); -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right); +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); static void _audioDMA(void); static void _setRumble(struct mRumble* rumble, int enable); static void _sampleRotation(struct mRotationSource* source); @@ -141,12 +141,14 @@ static void* framebuffer[2] = { 0, 0 }; static int whichFb = 0; static struct AudioBuffer { - struct mStereoSample samples[SAMPLES] __attribute__((__aligned__(32))); - volatile size_t size; -} audioBuffer[BUFFERS] = {0}; + int16_t samples[SAMPLES * 2] __attribute__((__aligned__(32))); + volatile bool full; +} audioBuffers[BUFFERS] = {0}; +static struct mAudioBuffer audioBuffer; static volatile int currentAudioBuffer = 0; static volatile int nextAudioBuffer = 0; static double audioSampleRate = 60.0 / 1.001; +static struct mAudioResampler resampler; static struct GUIFont* font; @@ -246,11 +248,6 @@ static void reconfigureScreen(struct mGUIRunner* runner) { if (runner) { runner->params.width = vmode->fbWidth * guiScale * wAdjust; runner->params.height = vmode->efbHeight * guiScale * hAdjust; - if (runner->core) { - double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); - } } } @@ -269,7 +266,10 @@ int main(int argc, char* argv[]) { AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback(_audioDMA); - memset(audioBuffer, 0, sizeof(audioBuffer)); + memset(audioBuffers, 0, sizeof(audioBuffers)); + mAudioBufferInit(&audioBuffer, SAMPLES * BUFFERS, 2); + mAudioResamplerInit(&resampler, mINTERPOLATOR_COSINE); + mAudioResamplerSetDestination(&resampler, &audioBuffer, 48000); #ifdef FIXED_ROM_BUFFER romBufferSize = GBA_SIZE_ROM0; romBuffer = SYS_GetArena2Lo(); @@ -663,6 +663,9 @@ int main(int argc, char* argv[]) { VIDEO_WaitVSync(); mGUIDeinit(&runner); + mAudioResamplerDeinit(&resampler); + mAudioBufferDeinit(&audioBuffer); + free(fifo); free(texmem); free(rescaleTexmem); @@ -678,41 +681,38 @@ int main(int argc, char* argv[]) { } static void _audioDMA(void) { - struct AudioBuffer* buffer = &audioBuffer[currentAudioBuffer]; - if (buffer->size != SAMPLES) { + struct AudioBuffer* buffer = &audioBuffers[currentAudioBuffer]; + if (!buffer->full) { + printf("Recv %i %i%s", currentAudioBuffer, buffer->full, buffer->full ? "" : "!"); return; } DCFlushRange(buffer->samples, SAMPLES * sizeof(struct mStereoSample)); AUDIO_InitDMA((u32) buffer->samples, SAMPLES * sizeof(struct mStereoSample)); - buffer->size = 0; + buffer->full = false; currentAudioBuffer = (currentAudioBuffer + 1) % BUFFERS; } -static void _postAudioBuffer(struct mAVStream* stream, blip_t* left, blip_t* right) { +static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) { UNUSED(stream); - + UNUSED(buf); + mAudioResamplerProcess(&resampler); u32 level = 0; + bool gotAudio = false; _CPU_ISR_Disable(level); - struct AudioBuffer* buffer = &audioBuffer[nextAudioBuffer]; - int available = blip_samples_avail(left); - if (available + buffer->size > SAMPLES) { - available = SAMPLES - buffer->size; - } - if (available > 0) { - // These appear to be reversed for AUDIO_InitDMA - blip_read_samples(left, &buffer->samples[buffer->size].right, available, true); - blip_read_samples(right, &buffer->samples[buffer->size].left, available, true); - buffer->size += available; - } - if (buffer->size == SAMPLES) { - int next = (nextAudioBuffer + 1) % BUFFERS; - if ((currentAudioBuffer + BUFFERS - next) % BUFFERS != 1) { - nextAudioBuffer = next; - } - if (!AUDIO_GetDMAEnableFlag()) { - _audioDMA(); - AUDIO_StartDMA(); + while (mAudioBufferAvailable(&audioBuffer) >= SAMPLES) { + struct AudioBuffer* buffer = &audioBuffers[nextAudioBuffer]; + if (buffer->full) { + printf("Send %i %i%s", nextAudioBuffer, buffer->full, buffer->full ? "!!" : ""); + break; } + mAudioBufferRead(&audioBuffer, buffer->samples, SAMPLES); + buffer->full = true; + nextAudioBuffer = (nextAudioBuffer + 1) % BUFFERS; + gotAudio = true; + } + if (gotAudio && !AUDIO_GetDMAEnableFlag()) { + _audioDMA(); + AUDIO_StartDMA(); } _CPU_ISR_Restore(level); } @@ -1416,15 +1416,11 @@ void _setup(struct mGUIRunner* runner) { nextAudioBuffer = 0; currentAudioBuffer = 0; - int i; - for (i = 0; i < BUFFERS; ++i) { - audioBuffer[i].size = 0; - } + memset(audioBuffers, 0, sizeof(audioBuffers)); runner->core->setAudioBufferSize(runner->core, SAMPLES); double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - blip_set_rates(runner->core->getAudioChannel(runner->core, 0), runner->core->frequency(runner->core), 48000 * ratio); - blip_set_rates(runner->core->getAudioChannel(runner->core, 1), runner->core->frequency(runner->core), 48000 * ratio); + mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), runner->core->audioSampleRate(runner->core) / ratio, true); frameLimiter = true; } @@ -1433,6 +1429,7 @@ void _gameUnloaded(struct mGUIRunner* runner) { UNUSED(runner); AUDIO_StopDMA(); frameLimiter = true; + mAudioBufferClear(&audioBuffer); VIDEO_SetBlack(true); VIDEO_Flush(); VIDEO_WaitVSync(); From fa2fe8eed4fdf47766e8107b3a75ec5af762be9d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:49:34 -0700 Subject: [PATCH 050/148] Third-Party: Remove blip_buf --- CMakeLists.txt | 4 +- README.md | 1 - README_DE.md | 1 - README_ES.md | 1 - README_ZH_CN.md | 1 - include/mgba/core/blip_buf.h | 72 ---- res/licenses/blip_buf.txt | 504 --------------------------- src/third-party/blip_buf/blip_buf.c | 344 ------------------ src/third-party/blip_buf/license.txt | 504 --------------------------- 9 files changed, 1 insertion(+), 1431 deletions(-) delete mode 100644 include/mgba/core/blip_buf.h delete mode 100644 res/licenses/blip_buf.txt delete mode 100644 src/third-party/blip_buf/blip_buf.c delete mode 100644 src/third-party/blip_buf/license.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 24caaaf9f..d573b0c6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -586,8 +586,6 @@ if(USE_FFMPEG) endif() endif() -list(APPEND THIRD_PARTY_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/blip_buf/blip_buf.c") - if(WANT_ZLIB AND NOT USE_ZLIB) set(SKIP_INSTALL_ALL ON) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/zlib zlib EXCLUDE_FROM_ALL) @@ -1085,7 +1083,7 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/mgba-util DESTINATION ${CM install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/mgba/flags.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mgba COMPONENT ${BINARY_NAME}-dev) # Packaging -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/res/licenses/blip_buf.txt DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT ${BINARY_NAME}) +install(FILES 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}) diff --git a/README.md b/README.md index 78b69f255..d937fa0c9 100644 --- a/README.md +++ b/README.md @@ -260,7 +260,6 @@ mGBA is Copyright © 2013 – 2023 Jeffrey Pfau. It is distributed under the [Mo mGBA contains the following third-party libraries: - [inih](https://github.com/benhoyt/inih), which is copyright © 2009 – 2020 Ben Hoyt and used under a BSD 3-clause license. -- [blip-buf](https://code.google.com/archive/p/blip-buf), which is copyright © 2003 – 2009 Shay Green and used under a Lesser GNU Public License. - [LZMA SDK](http://www.7-zip.org/sdk.html), which is public domain. - [MurmurHash3](https://github.com/aappleby/smhasher) implementation by Austin Appleby, which is public domain. - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), which is public domain. diff --git a/README_DE.md b/README_DE.md index 9b653c5d2..9a4066a0f 100644 --- a/README_DE.md +++ b/README_DE.md @@ -247,7 +247,6 @@ Copyright für mGBA © 2013 – 2021 Jeffrey Pfau. mGBA wird unter der [Mozilla mGBA beinhaltet die folgenden Bibliotheken von Drittanbietern: - [inih](https://github.com/benhoyt/inih), Copyright © 2009 - 2020 Ben Hoyt, verwendet unter einer BSD 3-clause-Lizenz. -- [blip-buf](https://code.google.com/archive/b/blip-buf), Copyright © 2003 - 2009 Shay Green, verwendet unter einer Lesser GNU Public License. - [LZMA SDK](http://www.7-zip.org/sdk.html), Public Domain. - [MurmurHash3](https://github.com/aappleby/smhasher), Implementierung von Austin Appleby, Public Domain. - [getopt fot MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), Public Domain. diff --git a/README_ES.md b/README_ES.md index f174e114c..1a6d0b797 100644 --- a/README_ES.md +++ b/README_ES.md @@ -247,7 +247,6 @@ mGBA es Copyright © 2013 – 2021 Jeffrey Pfau. Es distribuído bajo la [licenc mGBA contiene las siguientes bibliotecas de terceros: - [inih](https://github.com/benhoyt/inih), que es copyright © 2009 - 2020 Ben Hoyt y se utiliza bajo licencia de la cláusula 3 de BSD. -- [blip-buf](https://code.google.com/archive/p/blip-buf), que es copyright © 2003 - 2009 Shay Green y se usa bajo LGPL. - [LZMA SDK](http://www.7-zip.org/sdk.html), la cual está en el dominio público. - [MurmurHash3](https://github.com/aappleby/smhasher), implementación por Austin Appleby, la cual está en el dominio público. - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/), la cual está en el dominio público. diff --git a/README_ZH_CN.md b/README_ZH_CN.md index 757f1d0c6..ab725694c 100644 --- a/README_ZH_CN.md +++ b/README_ZH_CN.md @@ -245,7 +245,6 @@ mGBA 版权 © 2013 – 2020 Jeffrey Pfau。基于 [Mozilla 公共许可证版 mGBA 包含以下第三方库: - [inih](https://github.com/benhoyt/inih):版权 © 2009 – 2020 Ben Hoyt,基于 BSD 3-clause 许可证使用。 -- [blip-buf](https://code.google.com/archive/p/blip-buf):版权 © 2003 – 2009 Shay Green,基于 Lesser GNU 公共许可证使用。 - [LZMA SDK](http://www.7-zip.org/sdk.html):属公有领域使用。 - [MurmurHash3](https://github.com/aappleby/smhasher):由 Austin Appleby 实施,属公有领域使用。 - [getopt for MSVC](https://github.com/skandhurkat/Getopt-for-Visual-Studio/):属公有领域使用。 diff --git a/include/mgba/core/blip_buf.h b/include/mgba/core/blip_buf.h deleted file mode 100644 index 22b0a3ec8..000000000 --- a/include/mgba/core/blip_buf.h +++ /dev/null @@ -1,72 +0,0 @@ -/** \file -Sample buffer that resamples from input clock rate to output sample rate */ - -/* blip_buf 1.1.0 */ -#ifndef BLIP_BUF_H -#define BLIP_BUF_H - -#ifdef __cplusplus - extern "C" { -#endif - -/** First parameter of most functions is blip_t*, or const blip_t* if nothing -is changed. */ -typedef struct blip_t blip_t; - -/** Creates new buffer that can hold at most sample_count samples. Sets rates -so that there are blip_max_ratio clocks per sample. Returns pointer to new -buffer, or NULL if insufficient memory. */ -blip_t* blip_new( int sample_count ); - -/** Sets approximate input clock rate and output sample rate. For every -clock_rate input clocks, approximately sample_rate samples are generated. */ -void blip_set_rates( blip_t*, double clock_rate, double sample_rate ); - -enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate, -clock_rate must not be greater than sample_rate*blip_max_ratio. */ -blip_max_ratio = 0x100000 }; - -/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */ -void blip_clear( blip_t* ); - -/** Adds positive/negative delta into buffer at specified clock time. */ -void blip_add_delta( blip_t*, unsigned int clock_time, int delta ); - -/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */ -void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta ); - -/** Length of time frame, in clocks, needed to make sample_count additional -samples available. */ -int blip_clocks_needed( const blip_t*, int sample_count ); - -enum { /** Maximum number of samples that can be generated from one time frame. */ -blip_max_frame = 4000 }; - -/** Makes input clocks before clock_duration available for reading as output -samples. Also begins new time frame at clock_duration, so that clock time 0 in -the new time frame specifies the same clock as clock_duration in the old time -frame specified. Deltas can have been added slightly past clock_duration (up to -however many clocks there are in two output samples). */ -void blip_end_frame( blip_t*, unsigned int clock_duration ); - -/** Number of buffered samples available for reading. */ -int blip_samples_avail( const blip_t* ); - -/** Reads and removes at most 'count' samples and writes them to 'out'. If -'stereo' is true, writes output to every other element of 'out', allowing easy -interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed -samples. Returns number of samples actually read. */ -int blip_read_samples( blip_t*, short out [], int count, int stereo ); - -/** Frees buffer. No effect if NULL is passed. */ -void blip_delete( blip_t* ); - - -/* Deprecated */ -typedef blip_t blip_buffer_t; - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/res/licenses/blip_buf.txt b/res/licenses/blip_buf.txt deleted file mode 100644 index 5faba9d48..000000000 --- a/res/licenses/blip_buf.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/src/third-party/blip_buf/blip_buf.c b/src/third-party/blip_buf/blip_buf.c deleted file mode 100644 index 6bc7da8bd..000000000 --- a/src/third-party/blip_buf/blip_buf.c +++ /dev/null @@ -1,344 +0,0 @@ -/* blip_buf 1.1.0. http://www.slack.net/~ant/ */ - -#include - -#include -#include -#include -#include - -/* Library Copyright (C) 2003-2009 Shay Green. This library is free software; -you can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -library 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. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#if defined (BLARGG_TEST) && BLARGG_TEST - #include "blargg_test.h" -#endif - -/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000. -Avoids constants that don't fit in 32 bits. */ -#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF - typedef unsigned long fixed_t; - enum { pre_shift = 32 }; - -#elif defined(ULLONG_MAX) - typedef unsigned long long fixed_t; - enum { pre_shift = 32 }; - -#else - typedef unsigned fixed_t; - enum { pre_shift = 0 }; - -#endif - -enum { time_bits = pre_shift + 20 }; - -static fixed_t const time_unit = (fixed_t) 1 << time_bits; - -enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */ -enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */ - -enum { half_width = 8 }; -enum { buf_extra = half_width*2 + end_frame_extra }; -enum { phase_bits = 5 }; -enum { phase_count = 1 << phase_bits }; -enum { delta_bits = 15 }; -enum { delta_unit = 1 << delta_bits }; -enum { frac_bits = time_bits - pre_shift }; - -/* We could eliminate avail and encode whole samples in offset, but that would -limit the total buffered samples to blip_max_frame. That could only be -increased by decreasing time_bits, which would reduce resample ratio accuracy. -*/ - -/** Sample buffer that resamples to output rate and accumulates samples -until they're read out */ -struct blip_t -{ - fixed_t factor; - fixed_t offset; - int avail; - int size; - int integrator; -}; - -typedef int buf_t; - -/* probably not totally portable */ -#define SAMPLES( buf ) ((buf_t*) ((buf) + 1)) - -/* Arithmetic (sign-preserving) right shift */ -#define ARITH_SHIFT( n, shift ) \ - ((n) >> (shift)) - -enum { max_sample = +32767 }; -enum { min_sample = -32768 }; - -#define CLAMP( n ) \ - {\ - if ( (short) n != n )\ - n = ARITH_SHIFT( n, 16 ) ^ max_sample;\ - } - -static void check_assumptions( void ) -{ - int n; - - #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF - #error "int must be at least 32 bits" - #endif - - assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */ - - n = max_sample * 2; - CLAMP( n ); - assert( n == max_sample ); - - n = min_sample * 2; - CLAMP( n ); - assert( n == min_sample ); - - assert( blip_max_ratio <= time_unit ); - assert( blip_max_frame <= (fixed_t) -1 >> time_bits ); -} - -blip_t* blip_new( int size ) -{ - blip_t* m; - assert( size >= 0 ); - - m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) ); - if ( m ) - { - m->factor = time_unit / blip_max_ratio; - m->size = size; - blip_clear( m ); - check_assumptions(); - } - return m; -} - -void blip_delete( blip_t* m ) -{ - if ( m != NULL ) - { - /* Clear fields in case user tries to use after freeing */ - memset( m, 0, sizeof *m ); - free( m ); - } -} - -void blip_set_rates( blip_t* m, double clock_rate, double sample_rate ) -{ - double factor = time_unit * sample_rate / clock_rate; - m->factor = (fixed_t) factor; - - /* Fails if clock_rate exceeds maximum, relative to sample_rate */ - assert( 0 <= factor - m->factor && factor - m->factor < 1 ); - - /* Avoid requiring math.h. Equivalent to - m->factor = (int) ceil( factor ) */ - if ( m->factor < factor ) - m->factor++; - - /* At this point, factor is most likely rounded up, but could still - have been rounded down in the floating-point calculation. */ -} - -void blip_clear( blip_t* m ) -{ - /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if - factor is rounded up. factor-1 is suitable if factor is rounded down. - Since we don't know rounding direction, factor/2 accommodates either, - with the slight loss of showing an error in half the time. Since for - a 64-bit factor this is years, the halving isn't a problem. */ - - m->offset = m->factor / 2; - m->avail = 0; - m->integrator = 0; - memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) ); -} - -int blip_clocks_needed( const blip_t* m, int samples ) -{ - fixed_t needed; - - /* Fails if buffer can't hold that many more samples */ - assert( samples >= 0 && m->avail + samples <= m->size ); - - needed = (fixed_t) samples * time_unit; - if ( needed < m->offset ) - return 0; - - return (needed - m->offset + m->factor - 1) / m->factor; -} - -void blip_end_frame( blip_t* m, unsigned t ) -{ - fixed_t off = t * m->factor + m->offset; - m->avail += off >> time_bits; - m->offset = off & (time_unit - 1); - - /* Fails if buffer size was exceeded */ - assert( m->avail <= m->size ); -} - -int blip_samples_avail( const blip_t* m ) -{ - return m->avail; -} - -static void remove_samples( blip_t* m, int count ) -{ - buf_t* buf = SAMPLES( m ); - int remain = m->avail + buf_extra - count; - m->avail -= count; - - memmove( &buf [0], &buf [count], remain * sizeof buf [0] ); - memset( &buf [remain], 0, count * sizeof buf [0] ); -} - -int blip_read_samples( blip_t* m, short out [], int count, int stereo ) -{ - assert( count >= 0 ); - - if ( count > m->avail ) - count = m->avail; - - if ( count ) - { - int const step = stereo ? 2 : 1; - buf_t const* in = SAMPLES( m ); - buf_t const* end = in + count; - int sum = m->integrator; - do - { - /* Eliminate fraction */ - int s = ARITH_SHIFT( sum, delta_bits ); - - sum += *in++; - - CLAMP( s ); - - *out = s; - out += step; - - /* High-pass filter */ - sum -= s << (delta_bits - bass_shift); - } - while ( in != end ); - m->integrator = sum; - - remove_samples( m, count ); - } - - return count; -} - -/* Things that didn't help performance on x86: - __attribute__((aligned(128))) - #define short int - restrict -*/ - -/* Sinc_Generator( 0.9, 0.55, 4.5 ) */ -static short const bl_step [phase_count + 1] [half_width] = -{ -{ 43, -115, 350, -488, 1136, -914, 5861,21022}, -{ 44, -118, 348, -473, 1076, -799, 5274,21001}, -{ 45, -121, 344, -454, 1011, -677, 4706,20936}, -{ 46, -122, 336, -431, 942, -549, 4156,20829}, -{ 47, -123, 327, -404, 868, -418, 3629,20679}, -{ 47, -122, 316, -375, 792, -285, 3124,20488}, -{ 47, -120, 303, -344, 714, -151, 2644,20256}, -{ 46, -117, 289, -310, 634, -17, 2188,19985}, -{ 46, -114, 273, -275, 553, 117, 1758,19675}, -{ 44, -108, 255, -237, 471, 247, 1356,19327}, -{ 43, -103, 237, -199, 390, 373, 981,18944}, -{ 42, -98, 218, -160, 310, 495, 633,18527}, -{ 40, -91, 198, -121, 231, 611, 314,18078}, -{ 38, -84, 178, -81, 153, 722, 22,17599}, -{ 36, -76, 157, -43, 80, 824, -241,17092}, -{ 34, -68, 135, -3, 8, 919, -476,16558}, -{ 32, -61, 115, 34, -60, 1006, -683,16001}, -{ 29, -52, 94, 70, -123, 1083, -862,15422}, -{ 27, -44, 73, 106, -184, 1152,-1015,14824}, -{ 25, -36, 53, 139, -239, 1211,-1142,14210}, -{ 22, -27, 34, 170, -290, 1261,-1244,13582}, -{ 20, -20, 16, 199, -335, 1301,-1322,12942}, -{ 18, -12, -3, 226, -375, 1331,-1376,12293}, -{ 15, -4, -19, 250, -410, 1351,-1408,11638}, -{ 13, 3, -35, 272, -439, 1361,-1419,10979}, -{ 11, 9, -49, 292, -464, 1362,-1410,10319}, -{ 9, 16, -63, 309, -483, 1354,-1383, 9660}, -{ 7, 22, -75, 322, -496, 1337,-1339, 9005}, -{ 6, 26, -85, 333, -504, 1312,-1280, 8355}, -{ 4, 31, -94, 341, -507, 1278,-1205, 7713}, -{ 3, 35, -102, 347, -506, 1238,-1119, 7082}, -{ 1, 40, -110, 350, -499, 1190,-1021, 6464}, -{ 0, 43, -115, 350, -488, 1136, -914, 5861} -}; - -/* Shifting by pre_shift allows calculation using unsigned int rather than -possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient. -And by having pre_shift 32, a 32-bit platform can easily do the shift by -simply ignoring the low half. */ - -void blip_add_delta( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int const phase_shift = frac_bits - phase_bits; - int phase = fixed >> phase_shift & (phase_count - 1); - short const* in = bl_step [phase]; - short const* rev = bl_step [phase_count - phase]; - - int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1); - int delta2 = (delta * interp) >> delta_bits; - delta -= delta2; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [0] += in[0]*delta + in[half_width+0]*delta2; - out [1] += in[1]*delta + in[half_width+1]*delta2; - out [2] += in[2]*delta + in[half_width+2]*delta2; - out [3] += in[3]*delta + in[half_width+3]*delta2; - out [4] += in[4]*delta + in[half_width+4]*delta2; - out [5] += in[5]*delta + in[half_width+5]*delta2; - out [6] += in[6]*delta + in[half_width+6]*delta2; - out [7] += in[7]*delta + in[half_width+7]*delta2; - - in = rev; - out [ 8] += in[7]*delta + in[7-half_width]*delta2; - out [ 9] += in[6]*delta + in[6-half_width]*delta2; - out [10] += in[5]*delta + in[5-half_width]*delta2; - out [11] += in[4]*delta + in[4-half_width]*delta2; - out [12] += in[3]*delta + in[3-half_width]*delta2; - out [13] += in[2]*delta + in[2-half_width]*delta2; - out [14] += in[1]*delta + in[1-half_width]*delta2; - out [15] += in[0]*delta + in[0-half_width]*delta2; -} - -void blip_add_delta_fast( blip_t* m, unsigned time, int delta ) -{ - unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift); - buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits); - - int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1); - int delta2 = delta * interp; - - /* Fails if buffer size was exceeded */ - assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] ); - - out [7] += delta * delta_unit - delta2; - out [8] += delta2; -} diff --git a/src/third-party/blip_buf/license.txt b/src/third-party/blip_buf/license.txt deleted file mode 100644 index 5faba9d48..000000000 --- a/src/third-party/blip_buf/license.txt +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - From d422cbe65d8074365d85e1fd52ebf8d2e721bdfd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 00:52:26 -0700 Subject: [PATCH 051/148] OpenEmu: Remove upstream core This is maintained downstream and not synchronized back upstream --- CMakeLists.txt | 29 +- src/platform/openemu/Info.plist.in | 52 --- .../openemu/OEGBASystemResponderClient.h | 51 --- src/platform/openemu/mGBAGameCore.h | 6 - src/platform/openemu/mGBAGameCore.m | 298 ------------------ 5 files changed, 1 insertion(+), 435 deletions(-) delete mode 100644 src/platform/openemu/Info.plist.in delete mode 100644 src/platform/openemu/OEGBASystemResponderClient.h delete mode 100644 src/platform/openemu/mGBAGameCore.h delete mode 100644 src/platform/openemu/mGBAGameCore.m diff --git a/CMakeLists.txt b/CMakeLists.txt index d573b0c6c..2d69b000b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,9 +68,6 @@ if(NOT LIBMGBA_ONLY) 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") @@ -80,7 +77,7 @@ if(NOT LIBMGBA_ONLY) 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(SKIP_LIBRARY OFF CACHE BOOL "Skip building the library (useful for only building libretro core)") set(BUILD_GL ON CACHE BOOL "Build with OpenGL") set(BUILD_GLES2 ON CACHE BOOL "Build with OpenGL|ES 2") set(BUILD_GLES3 ON CACHE BOOL "Build with OpenGL|ES 3") @@ -144,11 +141,6 @@ if (BUILD_LIBRETRO) mark_as_advanced(LIBRETRO_LIBDIR) endif() -if (BUILD_OPENEMU) - set(OE_LIBDIR "${LIBDIR}" CACHE PATH "Installed library directory (OpenEmu)") - mark_as_advanced(OE_LIBDIR) -endif() - if (DISTBUILD) set(EXTRA_LICENSES "" CACHE FILEPATH "Extra licenses to include in distribution packaages") mark_as_advanced(EXTRA_LICENSES) @@ -1001,22 +993,6 @@ if(BUILD_LIBRETRO) endif() endif() -if(BUILD_OPENEMU) - find_library(FOUNDATION Foundation) - find_library(OPENEMUBASE OpenEmuBase) - file(GLOB OE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/openemu/*.m) - add_library(${BINARY_NAME}-openemu MODULE ${CORE_SRC} ${OS_SRC}) - set_target_properties(${BINARY_NAME}-openemu PROPERTIES - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/openemu/Info.plist.in - BUNDLE TRUE - BUNDLE_EXTENSION oecoreplugin - OUTPUT_NAME ${PROJECT_NAME} - COMPILE_OPTIONS "-fobjc-arc" - 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() - if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")) set(BUILD_UPDATER ON) endif() @@ -1345,9 +1321,6 @@ if(NOT QUIET AND NOT LIBMGBA_ONLY) message(STATUS " ROM tester: ${BUILD_ROM_TEST}") message(STATUS "Cores:") message(STATUS " Libretro core: ${BUILD_LIBRETRO}") - if(APPLE) - message(STATUS " OpenEmu core: ${BUILD_OPENEMU}") - endif() message(STATUS "Libraries:") message(STATUS " Static: ${BUILD_STATIC}") message(STATUS " Shared: ${BUILD_SHARED}") diff --git a/src/platform/openemu/Info.plist.in b/src/platform/openemu/Info.plist.in deleted file mode 100644 index b4ecfa95e..000000000 --- a/src/platform/openemu/Info.plist.in +++ /dev/null @@ -1,52 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${PROJECT_NAME} - CFBundleIconFile - mGBA - CFBundleIdentifier - com.endrift.mgba - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - BNDL - CFBundleSignature - ???? - CFBundleVersion - ${VERSION_STRING} - NSPrincipalClass - OEGameCoreController - OEGameCoreClass - mGBAGameCore - OEGameCoreOptions - - openemu.system.gba - - OEGameCoreRewindBufferSeconds - 60 - OEGameCoreRewindInterval - 0 - OEGameCoreSupportsRewinding - - OEGameCoreSupportsCheatCode - - - - OEGameCorePlayerCount - 1 - OEProjectURL - https://mgba.io/ - OESystemIdentifiers - - openemu.system.gba - - SUEnableAutomaticChecks - 1 - SUFeedURL - https://raw.github.com/OpenEmu/OpenEmu-Update/master/mgba_appcast.xml - - diff --git a/src/platform/openemu/OEGBASystemResponderClient.h b/src/platform/openemu/OEGBASystemResponderClient.h deleted file mode 100644 index 4fc0179d1..000000000 --- a/src/platform/openemu/OEGBASystemResponderClient.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2011, OpenEmu Team - - 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 the OpenEmu Team 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 OpenEmu Team ''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 OpenEmu Team 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. - */ - -#import - -@protocol OESystemResponderClient; - -typedef enum _OEGBAButton -{ - OEGBAButtonUp, - OEGBAButtonDown, - OEGBAButtonLeft, - OEGBAButtonRight, - OEGBAButtonA, - OEGBAButtonB, - OEGBAButtonL, - OEGBAButtonR, - OEGBAButtonStart, - OEGBAButtonSelect, - OEGBAButtonCount -} OEGBAButton; - -@protocol OEGBASystemResponderClient - -- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player; -- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player; - -@end diff --git a/src/platform/openemu/mGBAGameCore.h b/src/platform/openemu/mGBAGameCore.h deleted file mode 100644 index 744fdecfe..000000000 --- a/src/platform/openemu/mGBAGameCore.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -OE_EXPORTED_CLASS -@interface mGBAGameCore : OEGameCore -@end diff --git a/src/platform/openemu/mGBAGameCore.m b/src/platform/openemu/mGBAGameCore.m deleted file mode 100644 index 7656a8945..000000000 --- a/src/platform/openemu/mGBAGameCore.m +++ /dev/null @@ -1,298 +0,0 @@ -/* - Copyright (c) 2016, Jeffrey Pfau - - 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. - */ - -#import "mGBAGameCore.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#import -#import "OEGBASystemResponderClient.h" -#import - -#define SAMPLES 1024 - -@interface mGBAGameCore () -{ - struct mCore* core; - void* outputBuffer; - NSMutableDictionary *cheatSets; -} -@end - -@implementation mGBAGameCore - -- (id)init -{ - if ((self = [super init])) - { - core = GBACoreCreate(); - mCoreInitConfig(core, nil); - - struct mCoreOptions opts = { - .useBios = true, - }; - mCoreConfigLoadDefaults(&core->config, &opts); - core->init(core); - outputBuffer = nil; - - unsigned width, height; - core->baseVideoSize(core, &width, &height); - outputBuffer = malloc(width * height * BYTES_PER_PIXEL); - core->setVideoBuffer(core, outputBuffer, width); - core->setAudioBufferSize(core, SAMPLES); - cheatSets = [[NSMutableDictionary alloc] init]; - } - - return self; -} - -- (void)dealloc -{ - mCoreConfigDeinit(&core->config); - core->deinit(core); - free(outputBuffer); -} - -#pragma mark - Execution - -- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error -{ - NSString *batterySavesDirectory = [self batterySavesDirectoryPath]; - [[NSFileManager defaultManager] createDirectoryAtURL:[NSURL fileURLWithPath:batterySavesDirectory] - withIntermediateDirectories:YES - attributes:nil - error:nil]; - if (core->dirs.save) { - core->dirs.save->close(core->dirs.save); - } - core->dirs.save = VDirOpen([batterySavesDirectory fileSystemRepresentation]); - - if (!mCoreLoadFile(core, [path fileSystemRepresentation])) { - *error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:nil]; - return NO; - } - mCoreAutoloadSave(core); - - core->reset(core); - - return YES; -} - -- (void)executeFrame -{ - core->runFrame(core); - - int16_t samples[SAMPLES * 2]; - size_t available = 0; - available = blip_samples_avail(core->getAudioChannel(core, 0)); - blip_read_samples(core->getAudioChannel(core, 0), samples, available, true); - blip_read_samples(core->getAudioChannel(core, 1), samples + 1, available, true); - [[self ringBufferAtIndex:0] write:samples maxLength:available * 4]; -} - -- (void)resetEmulation -{ - core->reset(core); -} - -- (void)setupEmulation -{ - blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768); - blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768); -} - -#pragma mark - Video - -- (OEIntSize)aspectSize -{ - return OEIntSizeMake(3, 2); -} - -- (OEIntRect)screenRect -{ - unsigned width, height; - core->currentVideoSize(core, &width, &height); - return OEIntRectMake(0, 0, width, height); -} - -- (OEIntSize)bufferSize -{ - unsigned width, height; - core->baseVideoSize(core, &width, &height); - return OEIntSizeMake(width, height); -} - -- (const void *)getVideoBufferWithHint:(void *)hint -{ - OEIntSize bufferSize = [self bufferSize]; - - if (!hint) { - hint = outputBuffer; - } - - outputBuffer = hint; - core->setVideoBuffer(core, hint, bufferSize.width); - - return hint; -} - -- (GLenum)pixelFormat -{ - return GL_RGBA; -} - -- (GLenum)pixelType -{ - return GL_UNSIGNED_INT_8_8_8_8_REV; -} - -- (NSTimeInterval)frameInterval -{ - return core->frequency(core) / (double) core->frameCycles(core); -} - -#pragma mark - Audio - -- (NSUInteger)channelCount -{ - return 2; -} - -- (double)audioSampleRate -{ - return 32768; -} - -#pragma mark - Save State - -- (NSData *)serializeStateWithError:(NSError **)outError -{ - struct VFile* vf = VFileMemChunk(nil, 0); - if (!mCoreSaveStateNamed(core, vf, SAVESTATE_SAVEDATA)) { - *outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil]; - vf->close(vf); - return nil; - } - size_t size = vf->size(vf); - void* data = vf->map(vf, size, MAP_READ); - NSData *nsdata = [NSData dataWithBytes:data length:size]; - vf->unmap(vf, data, size); - vf->close(vf); - return nsdata; -} - -- (BOOL)deserializeState:(NSData *)state withError:(NSError **)outError -{ - struct VFile* vf = VFileFromConstMemory(state.bytes, state.length); - if (!mCoreLoadStateNamed(core, vf, SAVESTATE_SAVEDATA)) { - *outError = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadStateError userInfo:nil]; - vf->close(vf); - return NO; - } - vf->close(vf); - return YES; -} - -- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block -{ - struct VFile* vf = VFileOpen([fileName fileSystemRepresentation], O_CREAT | O_TRUNC | O_RDWR); - block(mCoreSaveStateNamed(core, vf, 0), nil); - vf->close(vf); -} - -- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block -{ - struct VFile* vf = VFileOpen([fileName fileSystemRepresentation], O_RDONLY); - block(mCoreLoadStateNamed(core, vf, 0), nil); - vf->close(vf); -} - -#pragma mark - Input - -const int GBAMap[] = { - GBA_KEY_UP, - GBA_KEY_DOWN, - GBA_KEY_LEFT, - GBA_KEY_RIGHT, - GBA_KEY_A, - GBA_KEY_B, - GBA_KEY_L, - GBA_KEY_R, - GBA_KEY_START, - GBA_KEY_SELECT -}; - -- (oneway void)didPushGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player -{ - UNUSED(player); - core->addKeys(core, 1 << GBAMap[button]); -} - -- (oneway void)didReleaseGBAButton:(OEGBAButton)button forPlayer:(NSUInteger)player -{ - UNUSED(player); - core->clearKeys(core, 1 << GBAMap[button]); -} - -#pragma mark - Cheats - -- (void)setCheat:(NSString *)code setType:(NSString *)type setEnabled:(BOOL)enabled -{ - code = [code stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - code = [code stringByReplacingOccurrencesOfString:@" " withString:@""]; - - NSString *codeId = [code stringByAppendingFormat:@"/%@", type]; - struct mCheatSet* cheatSet = [[cheatSets objectForKey:codeId] pointerValue]; - if (cheatSet) { - cheatSet->enabled = enabled; - return; - } - struct mCheatDevice* cheats = core->cheatDevice(core); - cheatSet = cheats->createSet(cheats, [codeId UTF8String]); - size_t size = mCheatSetsSize(&cheats->cheats); - if (size) { - cheatSet->copyProperties(cheatSet, *mCheatSetsGetPointer(&cheats->cheats, size - 1)); - } - int codeType = GBA_CHEAT_AUTODETECT; - NSArray *codeSet = [code componentsSeparatedByString:@"+"]; - for (id c in codeSet) { - mCheatAddLine(cheatSet, [c UTF8String], codeType); - } - cheatSet->enabled = enabled; - [cheatSets setObject:[NSValue valueWithPointer:cheatSet] forKey:codeId]; - mCheatAddSet(cheats, cheatSet); -} -@end - From 2cbbaea48359c3bbd3367c99298c0ad9a3e5eb88 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:04:34 -0700 Subject: [PATCH 052/148] Python: Attempt to fix build --- src/platform/python/mgba/core.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/platform/python/mgba/core.py b/src/platform/python/mgba/core.py index 75fd1a1cc..22965b3f9 100644 --- a/src/platform/python/mgba/core.py +++ b/src/platform/python/mgba/core.py @@ -4,7 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. from ._pylib import ffi, lib # pylint: disable=no-name-in-module -from . import tile, audio +from . import tile from cached_property import cached_property from functools import wraps @@ -242,14 +242,6 @@ class Core(object): def set_video_buffer(self, image): self._core.setVideoBuffer(self._core, image.buffer, image.stride) - @protected - def set_audio_buffer_size(self, size): - self._core.setAudioBufferSize(self._core, size) - - @property - def audio_buffer_size(self): - return self._core.getAudioBufferSize(self._core) - @protected def reset(self): self._core.reset(self._core) From 21d4f0f5fc52ede32c71c1bf2a2b4fd90b7ec098 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:07:54 -0700 Subject: [PATCH 053/148] All: Split ENABLE_VFS out from MINIMAL_CORE=2 --- CMakeLists.txt | 21 +++++++++++++---- include/mgba-util/configuration.h | 4 +++- include/mgba-util/image.h | 4 ++++ include/mgba-util/vfs.h | 9 ++++--- include/mgba/core/cheats.h | 2 +- include/mgba/core/config.h | 2 +- include/mgba/core/core.h | 6 ++--- include/mgba/core/directories.h | 2 +- include/mgba/core/library.h | 4 ++++ include/mgba/core/scripting.h | 2 ++ include/mgba/gba/interface.h | 4 +++- include/mgba/script/context.h | 2 ++ src/core/CMakeLists.txt | 6 ++++- src/core/cheats.c | 2 +- src/core/config.c | 2 +- src/core/core.c | 12 ++++++---- src/core/directories.c | 2 +- src/core/flags.h.in | 4 ++++ src/core/log.c | 5 ++-- src/core/scripting.c | 38 ++++++++++++++++++++---------- src/core/test/core.c | 4 ++-- src/debugger/cli-debugger.c | 24 ++++++++++++------- src/debugger/cli-el-backend.c | 4 ++++ src/feature/CMakeLists.txt | 6 ++++- src/feature/commandline.c | 5 ++++ src/gb/core.c | 8 +++---- src/gb/debugger/cli.c | 6 ++--- src/gba/cart/ereader.c | 4 +++- src/gba/core.c | 8 +++---- src/gba/debugger/cli.c | 6 ++--- src/platform/3ds/CMakeLists.txt | 4 ++-- src/platform/opengl/gles2.c | 2 ++ src/platform/opengl/gles2.h | 2 ++ src/platform/psp2/CMakeLists.txt | 4 ++-- src/platform/switch/CMakeLists.txt | 4 ++-- src/platform/wii/CMakeLists.txt | 4 ++-- src/script/CMakeLists.txt | 2 +- src/script/context.c | 2 ++ src/script/image.c | 24 ++++++++++++++----- src/util/configuration.c | 26 ++++++++++---------- src/util/image.c | 4 ++++ src/util/test/vfs.c | 4 ++-- src/util/vfs.c | 4 ++++ 43 files changed, 199 insertions(+), 95 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d69b000b..ae561189e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,7 @@ if(WIN32) endif() 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) + list(APPEND 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}) elseif(UNIX) @@ -230,7 +230,7 @@ elseif(UNIX) add_definitions(-D_GNU_SOURCE) 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) + list(APPEND 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) source_group("POSIX-specific code" FILES ${OS_SRC}) endif() @@ -349,6 +349,9 @@ elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() check_include_files("xlocale.h" HAVE_XLOCALE) + +set(ENABLE_VFS ON) + if(CMAKE_SYSTEM_NAME STREQUAL "Generic") if(NOT IS_EMBEDDED) set(DISABLE_DEPS ON CACHE BOOL "This platform cannot build with dependencies" FORCE) @@ -852,6 +855,10 @@ if(ENABLE_SCRIPTING) list(APPEND TEST_SRC ${SCRIPT_TEST_SRC}) endif() +if(ENABLE_VFS) + list(APPEND ENABLES VFS) +endif() + foreach(FEATURE IN LISTS FEATURES) list(APPEND FEATURE_DEFINES "USE_${FEATURE}") endforeach() @@ -890,7 +897,11 @@ list(APPEND CORE_SRC ${THIRD_PARTY_SRC}) list(APPEND TEST_SRC ${UTIL_TEST_SRC}) -set(SRC ${CORE_SRC} ${VFS_SRC}) +set(SRC ${CORE_SRC}) +if(ENABLE_VFS) + list(APPEND SRC ${VFS_SRC}) +endif() + if(NOT MINIMAL_CORE) set(ENABLE_EXTRA ON) if(M_CORE_GBA) @@ -922,7 +933,7 @@ if(NOT SKIP_LIBRARY) endif() if(BUILD_SHARED) - add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC}) + add_library(${BINARY_NAME} SHARED ${SRC}) set(EXPORT_DEFINES MGBA_DLL) if(BUILD_STATIC) add_library(${BINARY_NAME}-static STATIC ${SRC}) @@ -993,7 +1004,7 @@ if(BUILD_LIBRETRO) endif() endif() -if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux")) +if(BUILD_QT AND (WIN32 OR APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Linux") AND ENABLE_VFS) set(BUILD_UPDATER ON) endif() diff --git a/include/mgba-util/configuration.h b/include/mgba-util/configuration.h index e19ad13ef..f4c206d6a 100644 --- a/include/mgba-util/configuration.h +++ b/include/mgba-util/configuration.h @@ -34,10 +34,12 @@ const char* ConfigurationGetValue(const struct Configuration*, const char* secti void ConfigurationClearValue(struct Configuration*, const char* section, const char* key); +#ifdef ENABLE_VFS bool ConfigurationRead(struct Configuration*, const char* path); -bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf); bool ConfigurationWrite(const struct Configuration*, const char* path); bool ConfigurationWriteSection(const struct Configuration*, const char* path, const char* section); +#endif +bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf); bool ConfigurationWriteVFile(const struct Configuration*, struct VFile* vf); void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user); diff --git a/include/mgba-util/image.h b/include/mgba-util/image.h index b86b2135a..681e0a3a6 100644 --- a/include/mgba-util/image.h +++ b/include/mgba-util/image.h @@ -114,12 +114,16 @@ struct VFile; struct mImage* mImageCreate(unsigned width, unsigned height, enum mColorFormat format); struct mImage* mImageCreateWithStride(unsigned width, unsigned height, unsigned stride, enum mColorFormat format); struct mImage* mImageCreateFromConstBuffer(unsigned width, unsigned height, unsigned stride, enum mColorFormat format, const void* pixels); +#ifdef ENABLE_VFS struct mImage* mImageLoad(const char* path); +#endif struct mImage* mImageLoadVF(struct VFile* vf); struct mImage* mImageConvertToFormat(const struct mImage*, enum mColorFormat format); void mImageDestroy(struct mImage*); +#ifdef ENABLE_VFS bool mImageSave(const struct mImage*, const char* path, const char* format); +#endif bool mImageSaveVF(const struct mImage*, struct VFile* vf, const char* format); uint32_t mImageGetPixel(const struct mImage* image, unsigned x, unsigned y); diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index b9c4ca6b2..0ff100143 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -50,6 +50,7 @@ struct VFile { bool (*sync)(struct VFile* vf, void* buffer, size_t size); }; +#ifdef ENABLE_VFS struct VDirEntry { const char* (*name)(struct VDirEntry* vde); enum VFSType (*type)(struct VDirEntry* vde); @@ -68,6 +69,7 @@ struct VFile* VFileOpen(const char* path, int flags); struct VFile* VFileOpenFD(const char* path, int flags); struct VFile* VFileFromFD(int fd); +#endif struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); @@ -76,6 +78,7 @@ struct VFile* VFileMemChunk(const void* mem, size_t size); struct mCircleBuffer; struct VFile* VFileFIFO(struct mCircleBuffer* backing); +#ifdef ENABLE_VFS struct VDir* VDirOpen(const char* path); struct VDir* VDirOpenArchive(const char* path); @@ -92,20 +95,20 @@ struct VDir* VDeviceList(void); #endif bool VDirCreate(const char* path); +struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); +struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); #ifdef USE_VFS_FILE struct VFile* VFileFOpen(const char* path, const char* mode); struct VFile* VFileFromFILE(FILE* file); #endif +#endif void separatePath(const char* path, char* dirname, char* basename, char* extension); bool isAbsolute(const char* path); void makeAbsolute(const char* path, const char* base, char* out); -struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); -struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); - ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size); ssize_t VFileWrite32LE(struct VFile* vf, int32_t word); diff --git a/include/mgba/core/cheats.h b/include/mgba/core/cheats.h index 1da1aa859..a1c6c555c 100644 --- a/include/mgba/core/cheats.h +++ b/include/mgba/core/cheats.h @@ -118,7 +118,7 @@ bool mCheatSaveFile(struct mCheatDevice*, struct VFile*); bool mCheatParseLibretroFile(struct mCheatDevice*, struct VFile*); bool mCheatParseEZFChtFile(struct mCheatDevice*, struct VFile*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mCheatAutosave(struct mCheatDevice*); #endif diff --git a/include/mgba/core/config.h b/include/mgba/core/config.h index 2082c11db..4a68b49ee 100644 --- a/include/mgba/core/config.h +++ b/include/mgba/core/config.h @@ -64,7 +64,7 @@ struct mCoreOptions { void mCoreConfigInit(struct mCoreConfig*, const char* port); void mCoreConfigDeinit(struct mCoreConfig*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS bool mCoreConfigLoad(struct mCoreConfig*); bool mCoreConfigSave(const struct mCoreConfig*); bool mCoreConfigLoadPath(struct mCoreConfig*, const char* path); diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index a4bf5826c..97f256c82 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -11,7 +11,7 @@ CXX_GUARD_START #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS #include #endif #ifndef MINIMAL_CORE @@ -46,7 +46,7 @@ struct mCore { struct mDebuggerSymbols* symbolTable; struct mVideoLogger* videoLogger; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct mDirectorySet dirs; #endif #ifndef MINIMAL_CORE @@ -176,7 +176,7 @@ struct mCore { #endif }; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct mCore* mCoreFind(const char* path); bool mCoreLoadFile(struct mCore* core, const char* path); diff --git a/include/mgba/core/directories.h b/include/mgba/core/directories.h index d421e7f51..f9f59cb8d 100644 --- a/include/mgba/core/directories.h +++ b/include/mgba/core/directories.h @@ -10,7 +10,7 @@ CXX_GUARD_START -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS struct VDir; struct mDirectorySet { diff --git a/include/mgba/core/library.h b/include/mgba/core/library.h index d12aa0411..ededd5463 100644 --- a/include/mgba/core/library.h +++ b/include/mgba/core/library.h @@ -10,6 +10,8 @@ CXX_GUARD_START +#ifdef ENABLE_VFS + #include #include @@ -48,6 +50,8 @@ void mLibraryAttachGameDB(struct mLibrary* library, const struct NoIntroDB* db); #endif +#endif + CXX_GUARD_END #endif diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index a8fdbc425..c0fdcb413 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -70,7 +70,9 @@ void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReas #endif void mScriptBridgeRun(struct mScriptBridge*); +#ifdef ENABLE_VFS bool mScriptBridgeLoadScript(struct mScriptBridge*, const char* name); +#endif bool mScriptBridgeLookupSymbol(struct mScriptBridge*, const char* name, int32_t* out); diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index c64d00391..a04685e49 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -139,7 +139,7 @@ struct GBA; void GBACartEReaderQueueCard(struct GBA* gba, const void* data, size_t size); struct EReaderScan; -#ifdef USE_PNG +#if defined(USE_PNG) && defined(ENABLE_VFS) MGBA_EXPORT struct EReaderScan* EReaderScanLoadImagePNG(const char* filename); #endif MGBA_EXPORT struct EReaderScan* EReaderScanLoadImage(const void* pixels, unsigned width, unsigned height, unsigned stride); @@ -149,7 +149,9 @@ MGBA_EXPORT void EReaderScanDestroy(struct EReaderScan*); MGBA_EXPORT bool EReaderScanCard(struct EReaderScan*); MGBA_EXPORT void EReaderScanOutputBitmap(const struct EReaderScan*, void* output, size_t stride); +#ifdef ENABLE_VFS MGBA_EXPORT bool EReaderScanSaveRaw(const struct EReaderScan*, const char* filename, bool strict); +#endif CXX_GUARD_END diff --git a/include/mgba/script/context.h b/include/mgba/script/context.h index 25628d785..ef740fb45 100644 --- a/include/mgba/script/context.h +++ b/include/mgba/script/context.h @@ -109,7 +109,9 @@ const char* mScriptEngineGetDocstring(struct mScriptEngineContext*, const char* struct VFile; bool mScriptContextLoadVF(struct mScriptContext*, const char* name, struct VFile* vf); +#ifdef ENABLE_VFS bool mScriptContextLoadFile(struct mScriptContext*, const char* path); +#endif struct mScriptContext* mScriptActiveContext(void); bool mScriptContextActivate(struct mScriptContext*); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 184445023..e86e4fe55 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -8,7 +8,6 @@ set(SOURCE_FILES directories.c input.c interface.c - library.c lockstep.c log.c map-cache.c @@ -23,6 +22,11 @@ set(SOURCE_FILES set(TEST_FILES test/core.c) +if(ENABLE_VFS) + list(APPEND SOURCE_FILES + library.c) +endif() + if(ENABLE_SCRIPTING) set(SCRIPTING_FILES scripting.c) diff --git a/src/core/cheats.c b/src/core/cheats.c index 60f73abcc..85a06b80d 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -622,7 +622,7 @@ bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { return true; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mCheatAutosave(struct mCheatDevice* device) { if (!device->autosave) { return; diff --git a/src/core/config.c b/src/core/config.c index 4d4733cd9..4fa27ba55 100644 --- a/src/core/config.c +++ b/src/core/config.c @@ -167,7 +167,7 @@ void mCoreConfigDeinit(struct mCoreConfig* config) { free(config->port); } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS bool mCoreConfigLoad(struct mCoreConfig* config) { char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); diff --git a/src/core/core.c b/src/core/core.c index bcc72115a..20f9fdefc 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -15,6 +15,10 @@ #include #endif +#ifdef USE_PNG +#include +#endif + #ifdef M_CORE_GB #include #include @@ -86,9 +90,7 @@ struct mCore* mCoreCreate(enum mPlatform platform) { return NULL; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 -#include - +#ifdef ENABLE_VFS #ifdef PSP2 #include #endif @@ -381,7 +383,7 @@ void mCoreInitConfig(struct mCore* core, const char* port) { } void mCoreLoadConfig(struct mCore* core) { -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mCoreConfigLoad(&core->config); #endif mCoreLoadForeignConfig(core, &core->config); @@ -389,7 +391,7 @@ void mCoreLoadConfig(struct mCore* core) { void mCoreLoadForeignConfig(struct mCore* core, const struct mCoreConfig* config) { mCoreConfigMap(config, &core->opts); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetMapOptions(&core->dirs, &core->opts); #endif if (core->opts.audioBuffers) { diff --git a/src/core/directories.c b/src/core/directories.c index c35773f1e..c4551b6c7 100644 --- a/src/core/directories.c +++ b/src/core/directories.c @@ -8,7 +8,7 @@ #include #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS void mDirectorySetInit(struct mDirectorySet* dirs) { dirs->base = NULL; dirs->archive = NULL; diff --git a/src/core/flags.h.in b/src/core/flags.h.in index ebfd67ed9..b91e1907a 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -61,6 +61,10 @@ #cmakedefine ENABLE_SCRIPTING #endif +#ifndef ENABLE_VFS +#cmakedefine ENABLE_VFS +#endif + // USE flags #ifndef USE_DISCORD_RPC diff --git a/src/core/log.c b/src/core/log.c index b897fedb4..39d6db88c 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -278,15 +278,16 @@ void mStandardLoggerDeinit(struct mStandardLogger* logger) { } void mStandardLoggerConfig(struct mStandardLogger* logger, struct mCoreConfig* config) { +#ifdef ENABLE_VFS bool logToFile = false; const char* logFile = mCoreConfigGetValue(config, "logFile"); - mCoreConfigGetBoolValue(config, "logToStdout", &logger->logToStdout); mCoreConfigGetBoolValue(config, "logToFile", &logToFile); if (logToFile && logFile) { logger->logFile = VFileOpen(logFile, O_WRONLY | O_CREAT | O_APPEND); } - +#endif + mCoreConfigGetBoolValue(config, "logToStdout", &logger->logToStdout); mLogFilterLoad(logger->d.filter, config); } diff --git a/src/core/scripting.c b/src/core/scripting.c index acf324e1f..57d0eed2b 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -129,6 +129,7 @@ void mScriptBridgeRun(struct mScriptBridge* sb) { HashTableEnumerate(&sb->engines, _seRun, NULL); } +#ifdef ENABLE_VFS bool mScriptBridgeLoadScript(struct mScriptBridge* sb, const char* name) { struct VFile* vf = VFileOpen(name, O_RDONLY); if (!vf) { @@ -143,6 +144,7 @@ bool mScriptBridgeLoadScript(struct mScriptBridge* sb, const char* name) { vf->close(vf); return info.success; } +#endif bool mScriptBridgeLookupSymbol(struct mScriptBridge* sb, const char* name, int32_t* out) { struct mScriptSymbol info = { @@ -417,6 +419,7 @@ static struct mScriptValue* _mScriptCoreSaveState(struct mCore* core, int32_t fl return value; } +#ifdef ENABLE_VFS static int _mScriptCoreSaveStateFile(struct mCore* core, const char* path, int flags) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_TRUNC | O_CREAT); if (!vf) { @@ -427,13 +430,6 @@ static int _mScriptCoreSaveStateFile(struct mCore* core, const char* path, int f return ok; } -static int32_t _mScriptCoreLoadState(struct mCore* core, struct mScriptString* buffer, int32_t flags) { - struct VFile* vf = VFileFromConstMemory(buffer->buffer, buffer->size); - int ret = mCoreLoadStateNamed(core, vf, flags); - vf->close(vf); - return ret; -} - static int _mScriptCoreLoadStateFile(struct mCore* core, const char* path, int flags) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -456,6 +452,14 @@ static void _mScriptCoreTakeScreenshot(struct mCore* core, const char* filename) mCoreTakeScreenshot(core); } } +#endif + +static int32_t _mScriptCoreLoadState(struct mCore* core, struct mScriptString* buffer, int32_t flags) { + struct VFile* vf = VFileFromConstMemory(buffer->buffer, buffer->size); + int ret = mCoreLoadStateNamed(core, vf, flags); + vf->close(vf); + return ret; +} static struct mScriptValue* _mScriptCoreTakeScreenshotToImage(struct mCore* core) { size_t stride; @@ -480,10 +484,12 @@ static struct mScriptValue* _mScriptCoreTakeScreenshotToImage(struct mCore* core return result; } +#ifdef ENABLE_VFS // Loading functions mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadFile, mCoreLoadFile, 1, CHARP, path); mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, autoloadSave, mCoreAutoloadSave, 0); mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadSaveFile, mCoreLoadSaveFile, 2, CHARP, path, BOOL, temporary); +#endif // Info functions mSCRIPT_DECLARE_STRUCT_CD_METHOD(mCore, S32, platform, 0); @@ -523,27 +529,31 @@ mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRegister, _mScriptCoreReadRegiste mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, writeRegister, _mScriptCoreWriteRegister, 2, CHARP, regName, S32, value); // Savestate functions -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, WSTR, saveStateBuffer, _mScriptCoreSaveState, 1, S32, flags); +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags); +#ifdef ENABLE_VFS +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateFile, _mScriptCoreSaveStateFile, 2, CHARP, path, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateSlot, mCoreLoadState, 2, S32, slot, S32, flags); -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateFile, _mScriptCoreLoadStateFile, 2, CHARP, path, S32, flags); // Miscellaneous functions mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mCore, screenshot, _mScriptCoreTakeScreenshot, 1, CHARP, filename); +#endif mSCRIPT_DECLARE_STRUCT_METHOD(mCore, W(mImage), screenshotToImage, _mScriptCoreTakeScreenshotToImage, 0); mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_CLASS_DOCSTRING( "An instance of an emulator core." ) +#ifdef ENABLE_VFS mSCRIPT_DEFINE_DOCSTRING("Load a ROM file into the current state of this core") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadFile) mSCRIPT_DEFINE_DOCSTRING("Load the save data associated with the currently loaded ROM file") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, autoloadSave) mSCRIPT_DEFINE_DOCSTRING("Load save data from the given path. If the `temporary` flag is set, the given save data will not be written back to disk") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadSaveFile) +#endif mSCRIPT_DEFINE_DOCSTRING("Get which platform is being emulated. See C.PLATFORM for possible values") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, platform) @@ -605,21 +615,23 @@ mSCRIPT_DEFINE_STRUCT(mCore) mSCRIPT_DEFINE_DOCSTRING("Write the value of the register with the given name") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, writeRegister) - mSCRIPT_DEFINE_DOCSTRING("Save state to the slot number. See C.SAVESTATE for possible values for `flags`") - mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateSlot) mSCRIPT_DEFINE_DOCSTRING("Save state and return as a buffer. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateBuffer) + mSCRIPT_DEFINE_DOCSTRING("Load state from a buffer. See C.SAVESTATE for possible values for `flags`") + mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateBuffer) +#ifdef ENABLE_VFS + mSCRIPT_DEFINE_DOCSTRING("Save state to the slot number. See C.SAVESTATE for possible values for `flags`") + mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateSlot) mSCRIPT_DEFINE_DOCSTRING("Save state to the given path. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, saveStateFile) mSCRIPT_DEFINE_DOCSTRING("Load state from the slot number. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateSlot) - mSCRIPT_DEFINE_DOCSTRING("Load state from a buffer. See C.SAVESTATE for possible values for `flags`") - mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateBuffer) mSCRIPT_DEFINE_DOCSTRING("Load state from the given path. See C.SAVESTATE for possible values for `flags`") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, loadStateFile) mSCRIPT_DEFINE_DOCSTRING("Save a screenshot to a file") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshot) +#endif mSCRIPT_DEFINE_DOCSTRING("Get a screenshot in an struct::mImage") mSCRIPT_DEFINE_STRUCT_METHOD(mCore, screenshotToImage) mSCRIPT_DEFINE_END; diff --git a/src/core/test/core.c b/src/core/test/core.c index 10c566b2c..645a45486 100644 --- a/src/core/test/core.c +++ b/src/core/test/core.c @@ -8,7 +8,7 @@ #include #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS M_TEST_DEFINE(findNullPath) { struct mCore* core = mCoreFind(NULL); assert_null(core); @@ -29,7 +29,7 @@ M_TEST_DEFINE(findEmpty) { } M_TEST_SUITE_DEFINE(mCore, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS cmocka_unit_test(findNullPath), #endif cmocka_unit_test(findNullVF), diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index 95b2037dc..b5a6595d3 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -75,13 +75,15 @@ static void _dumpByte(struct CLIDebugger*, struct CLIDebugVector*); static void _dumpHalfword(struct CLIDebugger*, struct CLIDebugVector*); static void _dumpWord(struct CLIDebugger*, struct CLIDebugVector*); static void _events(struct CLIDebugger*, struct CLIDebugVector*); -#ifdef ENABLE_SCRIPTING -static void _source(struct CLIDebugger*, struct CLIDebugVector*); -#endif static void _backtrace(struct CLIDebugger*, struct CLIDebugVector*); static void _finish(struct CLIDebugger*, struct CLIDebugVector*); static void _setStackTraceMode(struct CLIDebugger*, struct CLIDebugVector*); +#ifdef ENABLE_VFS static void _loadSymbols(struct CLIDebugger*, struct CLIDebugVector*); +#ifdef ENABLE_SCRIPTING +static void _source(struct CLIDebugger*, struct CLIDebugVector*); +#endif +#endif static void _setSymbol(struct CLIDebugger*, struct CLIDebugVector*); static void _findSymbol(struct CLIDebugger*, struct CLIDebugVector*); @@ -96,6 +98,9 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "help", _printHelp, "S", "Print help" }, { "listb", _listBreakpoints, "", "List breakpoints" }, { "listw", _listWatchpoints, "", "List watchpoints" }, +#ifdef ENABLE_VFS + { "load-symbols", _loadSymbols, "S", "Load symbols from an external file" }, +#endif { "next", _next, "", "Execute next instruction" }, { "print", _print, "S+", "Print a value" }, { "print/t", _printBin, "S+", "Print a value as binary" }, @@ -106,10 +111,12 @@ 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" }, { "set", _setSymbol, "SI", "Assign a symbol to an address" }, +#if defined(ENABLE_SCRIPTING) && defined(ENABLE_VFS) + { "source", _source, "S", "Load a script" }, +#endif { "stack", _setStackTraceMode, "S", "Change the stack tracing mode" }, { "status", _printStatus, "", "Print the current status" }, { "symbol", _findSymbol, "I", "Find the symbol name for an address" }, - { "load-symbols", _loadSymbols, "S", "Load symbols from an external file" }, { "trace", _trace, "Is", "Trace a number of instructions" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, @@ -126,9 +133,6 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "x/1", _dumpByte, "Ii", "Examine bytes at a specified offset" }, { "x/2", _dumpHalfword, "Ii", "Examine halfwords at a specified offset" }, { "x/4", _dumpWord, "Ii", "Examine words at a specified offset" }, -#ifdef ENABLE_SCRIPTING - { "source", _source, "S", "Load a script" }, -#endif #if !defined(NDEBUG) && !defined(_WIN32) { "!", _breakInto, "", "Break into attached debugger (for developers)" }, #endif @@ -586,7 +590,7 @@ static void _dumpWord(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { } } -#ifdef ENABLE_SCRIPTING +#if defined(ENABLE_SCRIPTING) && defined(ENABLE_VFS) static void _source(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { if (!dv) { debugger->backend->printf(debugger->backend, "Needs a filename\n"); @@ -829,9 +833,11 @@ static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { if (debugger->traceRemaining == 0) { return; } +#ifdef ENABLE_VFS if (dv->next && dv->next->charValue) { debugger->traceVf = VFileOpen(dv->next->charValue, O_CREAT | O_WRONLY | O_APPEND); } +#endif if (_doTrace(debugger)) { debugger->d.isPaused = false; mDebuggerUpdatePaused(debugger->d.p); @@ -1398,6 +1404,7 @@ static void _setStackTraceMode(struct CLIDebugger* debugger, struct CLIDebugVect } } +#ifdef ENABLE_VFS static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct mDebuggerSymbols* symbolTable = debugger->d.p->core->symbolTable; if (!symbolTable) { @@ -1431,6 +1438,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv } vf->close(vf); } +#endif static void _setSymbol(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct mDebuggerSymbols* symbolTable = debugger->d.p->core->symbolTable; diff --git a/src/debugger/cli-el-backend.c b/src/debugger/cli-el-backend.c index 382a05c14..b32afb159 100644 --- a/src/debugger/cli-el-backend.c +++ b/src/debugger/cli-el-backend.c @@ -85,6 +85,7 @@ static void CLIDebuggerEditLineInit(struct CLIDebuggerBackend* be) { history(elbe->histate, &ev, H_SETSIZE, 200); el_set(elbe->elstate, EL_HIST, history, elbe->histate); +#ifdef ENABLE_VFS char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); if (path[0]) { @@ -99,6 +100,7 @@ static void CLIDebuggerEditLineInit(struct CLIDebuggerBackend* be) { vf->close(vf); } } +#endif MutexInit(&elbe->promptMutex); ConditionInit(&elbe->promptRead); @@ -120,6 +122,7 @@ static void CLIDebuggerEditLineDeinit(struct CLIDebuggerBackend* be) { MutexUnlock(&elbe->promptMutex); ThreadJoin(&elbe->promptThread); +#ifdef ENABLE_VFS char path[PATH_MAX + 1]; mCoreConfigDirectory(path, PATH_MAX); if (path[0]) { @@ -139,6 +142,7 @@ static void CLIDebuggerEditLineDeinit(struct CLIDebuggerBackend* be) { vf->close(vf); } } +#endif history_end(elbe->histate); el_end(elbe->elstate); free(elbe); diff --git a/src/feature/CMakeLists.txt b/src/feature/CMakeLists.txt index b692338f4..966c25520 100644 --- a/src/feature/CMakeLists.txt +++ b/src/feature/CMakeLists.txt @@ -3,10 +3,14 @@ set(SOURCE_FILES commandline.c proxy-backend.c thread-proxy.c - updater.c video-backend.c video-logger.c) +if(ENABLE_VFS) + list(APPEND SOURCE_FILES + updater.c) +endif() + set(GUI_FILES gui/cheats.c gui/gui-config.c diff --git a/src/feature/commandline.c b/src/feature/commandline.c index cdf788b19..59735e69b 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -245,6 +245,7 @@ bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, } void mArgumentsApplyFileLoads(const struct mArguments* args, struct mCore* core) { +#ifdef ENABLE_VFS if (args->patch) { struct VFile* patch = VFileOpen(args->patch, O_RDONLY); if (patch) { @@ -266,6 +267,10 @@ void mArgumentsApplyFileLoads(const struct mArguments* args, struct mCore* core) } else { mCoreAutoloadCheats(core); } +#else + UNUSED(args); + UNUSED(core); +#endif } void mArgumentsDeinit(struct mArguments* args) { diff --git a/src/gb/core.c b/src/gb/core.c index 7023b29f7..9dbf36bc1 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -149,7 +149,7 @@ static bool _GBCoreInit(struct mCore* core) { gbcore->keys = 0; gb->keySource = &gbcore->keys; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetInit(&core->dirs); #endif @@ -161,7 +161,7 @@ static void _GBCoreDeinit(struct mCore* core) { GBDestroy(core->board); mappedMemoryFree(core->cpu, sizeof(struct SM83Core)); mappedMemoryFree(core->board, sizeof(struct GB)); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetDeinit(&core->dirs); #endif #ifdef ENABLE_DEBUGGERS @@ -597,7 +597,7 @@ static void _GBCoreReset(struct mCore* core) { } } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!gb->biosVf && core->opts.useBios) { struct VFile* bios = NULL; bool found = false; @@ -1108,7 +1108,7 @@ static void _GBCoreDetachDebugger(struct mCore* core) { static void _GBCoreLoadSymbols(struct mCore* core, struct VFile* vf) { core->symbolTable = mDebuggerSymbolTableCreate(); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!vf && core->dirs.base) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); } diff --git a/src/gb/debugger/cli.c b/src/gb/debugger/cli.c index f32f299a3..0b3ec6678 100644 --- a/src/gb/debugger/cli.c +++ b/src/gb/debugger/cli.c @@ -16,14 +16,14 @@ static void _GBCLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBCLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); #endif struct CLIDebuggerCommandSummary _GBCLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, #endif @@ -78,7 +78,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbDebugger->inVblank = GBRegisterSTATGetMode(((struct GB*) gbDebugger->core->board)->memory.io[GB_REG_STAT]) == 1; } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { diff --git a/src/gba/cart/ereader.c b/src/gba/cart/ereader.c index 6a3ce58b0..fc4d4c11d 100644 --- a/src/gba/cart/ereader.c +++ b/src/gba/cart/ereader.c @@ -875,7 +875,7 @@ void EReaderScanDestroy(struct EReaderScan* scan) { free(scan); } -#ifdef USE_PNG +#if defined(USE_PNG) && defined(ENABLE_VFS) struct EReaderScan* EReaderScanLoadImagePNG(const char* filename) { struct VFile* vf = VFileOpen(filename, O_RDONLY); if (!vf) { @@ -1564,6 +1564,7 @@ void EReaderScanOutputBitmap(const struct EReaderScan* scan, void* output, size_ } } +#ifdef ENABLE_VFS bool EReaderScanSaveRaw(const struct EReaderScan* scan, const char* filename, bool strict) { size_t blocks = EReaderBlockListSize(&scan->blocks); if (!blocks) { @@ -1633,5 +1634,6 @@ bool EReaderScanSaveRaw(const struct EReaderScan* scan, const char* filename, bo free(data); return true; } +#endif #endif diff --git a/src/gba/core.c b/src/gba/core.c index 4a437f36d..47da3a0e0 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -294,7 +294,7 @@ static bool _GBACoreInit(struct mCore* core) { gbacore->proxyRenderer.logger = NULL; #endif -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetInit(&core->dirs); #endif @@ -306,7 +306,7 @@ static void _GBACoreDeinit(struct mCore* core) { GBADestroy(core->board); mappedMemoryFree(core->cpu, sizeof(struct ARMCore)); mappedMemoryFree(core->board, sizeof(struct GBA)); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS mDirectorySetDeinit(&core->dirs); #endif #ifdef ENABLE_DEBUGGERS @@ -741,7 +741,7 @@ static void _GBACoreReset(struct mCore* core) { } gbacore->memoryBlockType = -2; -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS if (!gba->biosVf && core->opts.useBios) { struct VFile* bios = NULL; bool found = false; @@ -1244,7 +1244,7 @@ static void _GBACoreDetachDebugger(struct mCore* core) { static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { bool closeAfter = false; core->symbolTable = mDebuggerSymbolTableCreate(); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS #ifdef USE_ELF if (!vf && core->dirs.base) { closeAfter = true; diff --git a/src/gba/debugger/cli.c b/src/gba/debugger/cli.c index 8538f4515..8cb6c6043 100644 --- a/src/gba/debugger/cli.c +++ b/src/gba/debugger/cli.c @@ -16,14 +16,14 @@ static void _GBACLIDebuggerInit(struct CLIDebuggerSystem*); static bool _GBACLIDebuggerCustom(struct CLIDebuggerSystem*); static void _frame(struct CLIDebugger*, struct CLIDebugVector*); -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger*, struct CLIDebugVector*); static void _save(struct CLIDebugger*, struct CLIDebugVector*); #endif struct CLIDebuggerCommandSummary _GBACLIDebuggerCommands[] = { { "frame", _frame, "", "Frame advance" }, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS { "load", _load, "*", "Load a savestate" }, { "save", _save, "*", "Save a savestate" }, #endif @@ -77,7 +77,7 @@ static void _frame(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { gbaDebugger->inVblank = GBARegisterDISPSTATGetInVblank(((struct GBA*) gbaDebugger->core->board)->memory.io[GBA_REG(DISPSTAT)]); } -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS static void _load(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { struct CLIDebuggerBackend* be = debugger->backend; if (!dv || dv->type != CLIDV_INT_TYPE) { diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index ef70eed51..7469fe6d4 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -31,9 +31,9 @@ source_group("3DS-specific code" FILES ${OS_SRC}) if(USE_VFS_3DS) list(APPEND OS_DEFINES USE_VFS_3DS) else() - list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) list(APPEND GUI_SRC diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 6350bd287..fa6716be9 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -1081,6 +1081,7 @@ static bool _loadUniform(struct Configuration* description, size_t pass, struct return true; } +#ifdef ENABLE_VFS bool mGLES2ShaderLoad(struct VideoShader* shader, struct VDir* dir) { struct VFile* manifest = dir->openFile(dir, "manifest.ini", O_RDONLY); if (!manifest) { @@ -1204,6 +1205,7 @@ bool mGLES2ShaderLoad(struct VideoShader* shader, struct VDir* dir) { ConfigurationDeinit(&description); return success; } +#endif void mGLES2ShaderFree(struct VideoShader* shader) { free((void*) shader->name); diff --git a/src/platform/opengl/gles2.h b/src/platform/opengl/gles2.h index e53a1bab5..e3f46a9c0 100644 --- a/src/platform/opengl/gles2.h +++ b/src/platform/opengl/gles2.h @@ -106,8 +106,10 @@ void mGLES2ShaderDeinit(struct mGLES2Shader*); void mGLES2ShaderAttach(struct mGLES2Context*, struct mGLES2Shader*, size_t nShaders); void mGLES2ShaderDetach(struct mGLES2Context*); +#ifdef ENABLE_VFS struct VDir; bool mGLES2ShaderLoad(struct VideoShader*, struct VDir*); +#endif void mGLES2ShaderFree(struct VideoShader*); CXX_GUARD_END diff --git a/src/platform/psp2/CMakeLists.txt b/src/platform/psp2/CMakeLists.txt index c42f5355b..9653205fb 100644 --- a/src/platform/psp2/CMakeLists.txt +++ b/src/platform/psp2/CMakeLists.txt @@ -10,8 +10,8 @@ file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/psp2-*.c) set(OS_SRC ${OS_SRC} PARENT_SCOPE) source_group("PS Vita-specific code" FILES ${OS_SRC}) -list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c) -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +list(APPEND VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sce-vfs.c) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_LIB -lvita2d -l${M_LIBRARY} -lSceAppMgr_stub diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 716b33449..55db05d12 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -5,7 +5,7 @@ find_library(GLAPI_LIBRARY glapi REQUIRED) find_library(EGL_LIBRARY EGL REQUIRED) set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64) -list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) +list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) include_directories(AFTER ${OPENGLES3_INCLUDE_DIR} ${OPENGL_EGL_INCLUDE_DIR}) @@ -17,7 +17,7 @@ else() find_library(NOUVEAU_LIBRARY drm_nouveau REQUIRED) list(APPEND OS_LIB nx) endif() -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) set(OS_LIB ${OS_LIB} PARENT_SCOPE) diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index 569408523..f8e6984f4 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -9,14 +9,14 @@ if(WIIDRC_LIBRARY) endif() set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER) -list(APPEND CORE_VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) +list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) include_directories(${CMAKE_CURRENT_BINARY_DIR}) list(APPEND OS_LIB wiiuse bte fat ogc) set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("Wii-specific code" FILES ${OS_SRC}) -set(CORE_VFS_SRC ${CORE_VFS_SRC} PARENT_SCOPE) +set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) set(OS_DEFINES ${OS_DEFINES} PARENT_SCOPE) list(APPEND GUI_SRC ${CMAKE_CURRENT_BINARY_DIR}/font.c ${CMAKE_CURRENT_BINARY_DIR}/icons.c ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index 0f64514c0..a72f48d22 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -12,7 +12,7 @@ set(TEST_FILES test/classes.c test/types.c) -if(USE_JSON_C) +if(USE_JSON_C AND ENABLE_VFS) list(APPEND SOURCE_FILES storage.c) endif() diff --git a/src/script/context.c b/src/script/context.c index 47a4460f6..ab0937500 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -424,6 +424,7 @@ bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, stru return info.context->load(info.context, name, vf); } +#ifdef ENABLE_VFS bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -433,6 +434,7 @@ bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) { vf->close(vf); return ret; } +#endif struct mScriptContext* mScriptActiveContext(void) { return ThreadLocalGetValue(_threadContext); diff --git a/src/script/image.c b/src/script/image.c index 2bd5a8736..533af131f 100644 --- a/src/script/image.c +++ b/src/script/image.c @@ -29,6 +29,7 @@ static struct mScriptValue* _mImageNew(unsigned width, unsigned height) { return result; } +#ifdef ENABLE_VFS static struct mScriptValue* _mImageLoad(const char* path) { struct mImage* image = mImageLoad(path); if (!image) { @@ -39,6 +40,7 @@ static struct mScriptValue* _mImageLoad(const char* path) { result->flags = mSCRIPT_VALUE_FLAG_DEINIT; return result; } +#endif static struct mScriptValue* _mImageNewPainter(struct mScriptValue* image) { mScriptValueRef(image); @@ -54,16 +56,10 @@ static struct mScriptValue* _mImageNewPainter(struct mScriptValue* image) { mSCRIPT_DECLARE_STRUCT_C_METHOD(mImage, U32, getPixel, mImageGetPixel, 2, U32, x, U32, y); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, setPixel, mImageSetPixel, 3, U32, x, U32, y, U32, color); -mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(mImage, BOOL, save, mImageSave, 2, CHARP, path, CHARP, format); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, _deinit, mImageDestroy, 0); mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mImage, drawImageOpaque, mImageBlit, 3, CS(mImage), image, U32, x, U32, y); mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mImage, drawImage, mImageCompositeWithAlpha, 4, CS(mImage), image, U32, x, U32, y, F32, alpha); -mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, save) - mSCRIPT_NO_DEFAULT, - mSCRIPT_CHARP("PNG") -mSCRIPT_DEFINE_DEFAULTS_END; - mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, drawImage) mSCRIPT_NO_DEFAULT, mSCRIPT_NO_DEFAULT, @@ -71,13 +67,23 @@ mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, drawImage) mSCRIPT_F32(1.0f) mSCRIPT_DEFINE_DEFAULTS_END; +#ifdef ENABLE_VFS +mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(mImage, BOOL, save, mImageSave, 2, CHARP, path, CHARP, format); +mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mImage, save) + mSCRIPT_NO_DEFAULT, + mSCRIPT_CHARP("PNG") +mSCRIPT_DEFINE_DEFAULTS_END; +#endif + mSCRIPT_DEFINE_STRUCT(mImage) mSCRIPT_DEFINE_CLASS_DOCSTRING( "A single, static image." ) mSCRIPT_DEFINE_STRUCT_DEINIT(mImage) +#ifdef ENABLE_VFS mSCRIPT_DEFINE_DOCSTRING("Save the image to a file. Currently, only `PNG` format is supported") mSCRIPT_DEFINE_STRUCT_METHOD(mImage, save) +#endif mSCRIPT_DEFINE_DOCSTRING("Get the ARGB value of the pixel at a given coordinate") mSCRIPT_DEFINE_STRUCT_METHOD(mImage, getPixel) mSCRIPT_DEFINE_DOCSTRING("Set the ARGB value of the pixel at a given coordinate") @@ -93,7 +99,9 @@ mSCRIPT_DEFINE_STRUCT(mImage) mSCRIPT_DEFINE_END; mSCRIPT_BIND_FUNCTION(mImageNew_Binding, W(mImage), _mImageNew, 2, U32, width, U32, height); +#ifdef ENABLE_VFS mSCRIPT_BIND_FUNCTION(mImageLoad_Binding, W(mImage), _mImageLoad, 1, CHARP, path); +#endif mSCRIPT_BIND_FUNCTION(mImageNewPainter_Binding, W(mScriptPainter), _mImageNewPainter, 1, W(mImage), image); void _mPainterSetBlend(struct mPainter* painter, bool enable) { @@ -186,12 +194,16 @@ mSCRIPT_DEFINE_END; void mScriptContextAttachImage(struct mScriptContext* context) { mScriptContextExportNamespace(context, "image", (struct mScriptKVPair[]) { mSCRIPT_KV_PAIR(new, &mImageNew_Binding), +#ifdef ENABLE_VFS mSCRIPT_KV_PAIR(load, &mImageLoad_Binding), +#endif mSCRIPT_KV_PAIR(newPainter, &mImageNewPainter_Binding), mSCRIPT_KV_SENTINEL }); mScriptContextSetDocstring(context, "image", "Methods for creating struct::mImage and struct::mPainter instances"); mScriptContextSetDocstring(context, "image.new", "Create a new image with the given dimensions"); +#ifdef ENABLE_VFS mScriptContextSetDocstring(context, "image.load", "Load an image from a path. Currently, only `PNG` format is supported"); +#endif mScriptContextSetDocstring(context, "image.newPainter", "Create a new painter from an existing image"); } diff --git a/src/util/configuration.c b/src/util/configuration.c index dbcefef8f..8b7320b5c 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c @@ -160,6 +160,7 @@ static char* _vfgets(char* stream, int size, void* user) { return 0; } +#ifdef ENABLE_VFS bool ConfigurationRead(struct Configuration* configuration, const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -170,12 +171,6 @@ bool ConfigurationRead(struct Configuration* configuration, const char* path) { return res; } -bool ConfigurationReadVFile(struct Configuration* configuration, struct VFile* vf) { - HashTableClear(&configuration->root); - HashTableClear(&configuration->sections); - return ini_parse_stream(_vfgets, vf, _iniRead, configuration) == 0; -} - bool ConfigurationWrite(const struct Configuration* configuration, const char* path) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { @@ -186,12 +181,6 @@ bool ConfigurationWrite(const struct Configuration* configuration, const char* p return res; } -bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) { - HashTableEnumerate(&configuration->root, _keyHandler, vf); - HashTableEnumerate(&configuration->sections, _sectionHandler, vf); - return true; -} - bool ConfigurationWriteSection(const struct Configuration* configuration, const char* path, const char* section) { const struct Table* currentSection = &configuration->root; struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_APPEND); @@ -213,6 +202,19 @@ bool ConfigurationWriteSection(const struct Configuration* configuration, const vf->close(vf); return true; } +#endif + +bool ConfigurationReadVFile(struct Configuration* configuration, struct VFile* vf) { + HashTableClear(&configuration->root); + HashTableClear(&configuration->sections); + return ini_parse_stream(_vfgets, vf, _iniRead, configuration) == 0; +} + +bool ConfigurationWriteVFile(const struct Configuration* configuration, struct VFile* vf) { + HashTableEnumerate(&configuration->root, _keyHandler, vf); + HashTableEnumerate(&configuration->sections, _sectionHandler, vf); + return true; +} void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user) { struct ConfigurationSectionHandlerData handlerData = { handler, user }; diff --git a/src/util/image.c b/src/util/image.c index f1f1a0fef..64e8aeec6 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -132,6 +132,7 @@ struct mImage* mImageCreateFromConstBuffer(unsigned width, unsigned height, unsi return image; } +#ifdef ENABLE_VFS struct mImage* mImageLoad(const char* path) { struct VFile* vf = VFileOpen(path, O_RDONLY); if (!vf) { @@ -141,6 +142,7 @@ struct mImage* mImageLoad(const char* path) { vf->close(vf); return image; } +#endif #ifdef USE_PNG static struct mImage* mImageLoadPNG(struct VFile* vf) { @@ -299,6 +301,7 @@ void mImageDestroy(struct mImage* image) { free(image); } +#ifdef ENABLE_VFS bool mImageSave(const struct mImage* image, const char* path, const char* format) { struct VFile* vf = VFileOpen(path, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { @@ -314,6 +317,7 @@ bool mImageSave(const struct mImage* image, const char* path, const char* format vf->close(vf); return success; } +#endif #ifdef USE_PNG bool mImageSavePNG(const struct mImage* image, struct VFile* vf) { diff --git a/src/util/test/vfs.c b/src/util/test/vfs.c index 4fd995275..2d1cfd56a 100644 --- a/src/util/test/vfs.c +++ b/src/util/test/vfs.c @@ -7,7 +7,7 @@ #include -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS M_TEST_DEFINE(openNullPathR) { struct VFile* vf = VFileOpen(NULL, O_RDONLY); assert_null(vf); @@ -146,7 +146,7 @@ M_TEST_DEFINE(mapMemChunk) { } M_TEST_SUITE_DEFINE(VFS, -#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 +#ifdef ENABLE_VFS cmocka_unit_test(openNullPathR), cmocka_unit_test(openNullPathW), cmocka_unit_test(openNullPathCreate), diff --git a/src/util/vfs.c b/src/util/vfs.c index d99f5020f..09ae81047 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -18,6 +18,7 @@ #include #endif +#ifdef ENABLE_VFS struct VFile* VFileOpen(const char* path, int flags) { #ifdef USE_VFS_FILE const char* chflags; @@ -115,6 +116,7 @@ struct VDir* VDirOpenArchive(const char* path) { #endif return dir; } +#endif ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size) { size_t bytesRead = 0; @@ -246,6 +248,7 @@ void makeAbsolute(const char* path, const char* base, char* out) { strncpy(out, buf, PATH_MAX); } +#ifdef ENABLE_VFS struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)) { dir->rewind(dir); struct VDirEntry* dirent = dir->listNext(dir); @@ -310,3 +313,4 @@ struct VFile* VDirFindNextAvailable(struct VDir* dir, const char* basename, cons path[PATH_MAX - 1] = '\0'; return dir->openFile(dir, path, mode); } +#endif From 267167a236f1451da59cf17105e07f2836bd0c3a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:24:22 -0700 Subject: [PATCH 054/148] Libretro: Fix non-ENABLE_VFS build --- CMakeLists.txt | 2 +- src/platform/libretro/libretro.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae561189e..7fc7e05fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -995,7 +995,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 ${BINARY_NAME}-version-info) - 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") + 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};ENABLE_VFS;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/libretro/libretro.c b/src/platform/libretro/libretro.c index 8478eb298..86a692837 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -848,9 +848,11 @@ bool retro_load_game(const struct retro_game_info* game) { dataSize = game->size; memcpy(data, game->data, game->size); rom = VFileFromMemory(data, game->size); +#ifdef ENABLE_VFS } else { - data = 0; + data = NULL; rom = VFileOpen(game->path, O_RDONLY); +#endif } if (!rom) { return false; @@ -973,6 +975,7 @@ bool retro_load_game(const struct retro_game_info* game) { } #endif +#ifdef ENABLE_VFS if (core->opts.useBios && sysDir && biosName) { snprintf(biosPath, sizeof(biosPath), "%s%s%s", sysDir, PATH_SEP, biosName); struct VFile* bios = VFileOpen(biosPath, O_RDONLY); @@ -980,6 +983,7 @@ bool retro_load_game(const struct retro_game_info* game) { core->loadBIOS(core, bios, 0); } } +#endif core->reset(core); _setupMaps(core); From d5e49a5981da1d7e08c6174c8a8f0718a27eab00 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 03:34:55 -0700 Subject: [PATCH 055/148] All: Remove unmaintained RasPi and Pandora code --- CMakeLists.txt | 14 ---- src/platform/sdl/CMakeLists.txt | 40 +++------- src/platform/sdl/gles2-sdl.c | 15 +--- src/platform/sdl/main.c | 4 - src/platform/sdl/main.h | 24 ------ src/platform/sdl/pandora-sdl.c | 129 -------------------------------- src/platform/sdl/rpi-common.c | 84 --------------------- src/platform/sdl/rpi-common.h | 20 ----- src/platform/sdl/sdl-events.c | 18 ----- 9 files changed, 12 insertions(+), 336 deletions(-) delete mode 100644 src/platform/sdl/pandora-sdl.c delete mode 100644 src/platform/sdl/rpi-common.c delete mode 100644 src/platform/sdl/rpi-common.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fc7e05fb..3767bae8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -269,20 +269,6 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf") endif() -if(BUILD_BBB OR BUILD_RASPI OR BUILD_PANDORA) - if(NOT BUILD_EGL) - add_definitions(-DCOLOR_16_BIT -DCOLOR_5_6_5) - endif() -endif() - -if(BUILD_RASPI) - set(BUILD_GL OFF CACHE BOOL "OpenGL not supported" FORCE) -endif() - -if(BUILD_PANDORA) - add_definitions(-DBUILD_PANDORA) -endif() - if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*") enable_language(ASM) endif() diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index ca1919da9..38e328d73 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -80,37 +80,19 @@ set(SDLMAIN_LIBRARY "${SDLMAIN_LIBRARY}" PARENT_SCOPE) set(MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -if(BUILD_RASPI) - add_definitions(-DBUILD_RASPI) - list(APPEND PLATFORM_SRC ${PROJECT_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c ${CMAKE_CURRENT_SOURCE_DIR}/rpi-common.c) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) - set(OPENGLES2_LIBRARY "-lEGL -lGLESv2 -lbcm_host") - set(BUILD_GLES2 ON CACHE BOOL "Using OpenGL|ES 2" FORCE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fgnu89-inline") - add_executable(${BINARY_NAME}-rpi ${PLATFORM_SRC} ${MAIN_SRC}) - set_target_properties(${BINARY_NAME}-rpi PROPERTIES COMPILE_DEFINITIONS "${FEATURE_DEFINES};${FUNCTION_DEFINES}") - target_link_libraries(${BINARY_NAME}-rpi ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OPENGLES2_LIBRARY}) - install(TARGETS ${BINARY_NAME}-rpi DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-rpi) - unset(OPENGLES2_INCLUDE_DIR CACHE) # Clear NOTFOUND +if(BUILD_GL) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) endif() - -if(BUILD_PANDORA) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/pandora-sdl.c) +if(BUILD_GLES2) + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) + list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) + include_directories(${OPENGLES2_INCLUDE_DIR}) +endif() +if(SDL_VERSION EQUAL "2") + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl2.c) else() - if(BUILD_GL) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) - endif() - if(BUILD_GLES2) - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gles2-sdl.c) - list(APPEND PLATFORM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gl-common.c) - include_directories(${OPENGLES2_INCLUDE_DIR}) - endif() - if(SDL_VERSION EQUAL "2") - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl2.c) - else() - list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl1.c) - endif() + list(APPEND MAIN_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sw-sdl1.c) endif() if(ENABLE_SCRIPTING) diff --git a/src/platform/sdl/gles2-sdl.c b/src/platform/sdl/gles2-sdl.c index 9bae33b95..a4aa386df 100644 --- a/src/platform/sdl/gles2-sdl.c +++ b/src/platform/sdl/gles2-sdl.c @@ -6,9 +6,6 @@ #include "main.h" #include "gl-common.h" -#ifdef BUILD_RASPI -#include "rpi-common.h" -#endif #include @@ -43,11 +40,7 @@ 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); struct mRectangle dims = { @@ -66,13 +59,7 @@ void mSDLGLES2Deinit(struct mSDLRenderer* renderer) { if (renderer->gl2.d.deinit) { renderer->gl2.d.deinit(&renderer->gl2.d); } -#ifdef BUILD_RASPI - 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) +#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_GL_DeleteContext(renderer->glCtx); #endif free(renderer->outputBuffer); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 1a1d3f6fc..b1b850e21 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -133,11 +133,7 @@ int main(int argc, char** argv) { mSDLGLCreate(&renderer); } else #elif defined(BUILD_GLES2) || defined(USE_EPOXY) -#ifdef BUILD_RASPI - mRPIGLCommonInit(&renderer); -#else if (mSDLGLCommonInit(&renderer)) -#endif { mSDLGLES2Create(&renderer); } else diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 10135da2f..43701b3c2 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -18,17 +18,6 @@ CXX_GUARD_START #include "platform/opengl/gl.h" #endif -#ifdef BUILD_RASPI -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#include -#include - -#include -#pragma GCC diagnostic pop -#endif - #if defined(BUILD_GLES2) || defined(BUILD_GLES3) || defined(USE_EPOXY) #include "gl-common.h" #include "platform/opengl/gles2.h" @@ -82,19 +71,6 @@ struct mSDLRenderer { pixman_image_t* pix; pixman_image_t* screenpix; #endif - -#ifdef BUILD_RASPI - EGLDisplay eglDisplay; - EGLSurface eglSurface; - EGLContext eglContext; - EGL_DISPMANX_WINDOW_T eglWindow; -#endif - -#ifdef BUILD_PANDORA - int fb; - int odd; - void* base[2]; -#endif }; void mSDLSWCreate(struct mSDLRenderer* renderer); diff --git a/src/platform/sdl/pandora-sdl.c b/src/platform/sdl/pandora-sdl.c deleted file mode 100644 index 673d419b6..000000000 --- a/src/platform/sdl/pandora-sdl.c +++ /dev/null @@ -1,129 +0,0 @@ -/* 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 "gba/supervisor/thread.h" - -#include -#include -#include -#include - -#ifndef FBIO_WAITFORVSYNC -#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -#endif - -static bool mSDLInit(struct SDLSoftwareRenderer* renderer); -static void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer); -static void mSDLDeinit(struct SDLSoftwareRenderer* renderer); - -void mSDLGLCreate(struct SDLSoftwareRenderer* renderer) { - renderer->init = mSDLInit; - renderer->deinit = mSDLDeinit; - renderer->runloop = mSDLRunloop; -} - -void mSDLSWCreate(struct SDLSoftwareRenderer* renderer) { - renderer->init = mSDLInit; - renderer->deinit = mSDLDeinit; - renderer->runloop = mSDLRunloop; -} - -bool mSDLInit(struct SDLSoftwareRenderer* renderer) { - SDL_SetVideoMode(800, 480, 16, SDL_FULLSCREEN); - - renderer->odd = 0; - renderer->fb = open("/dev/fb1", O_RDWR); - if (renderer->fb < 0) { - return false; - } - - struct omapfb_plane_info plane; - struct omapfb_mem_info mem; - if (ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane) < 0) { - return false; - } - if (ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem) < 0) { - return false; - } - - if (plane.enabled) { - plane.enabled = 0; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - } - - mem.size = GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4; - ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); - - plane.enabled = 1; - plane.pos_x = 40; - plane.pos_y = 0; - plane.out_width = 720; - plane.out_height = 480; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - - struct fb_var_screeninfo info; - ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - 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, 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 = GBA_VIDEO_HORIZONTAL_PIXELS; - return true; -} - -void mSDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) { - SDL_Event event; - - while (context->state < THREAD_EXITING) { - while (SDL_PollEvent(&event)) { - mSDLHandleEventGBA(context, &renderer->player, &event); - } - - if (mCoreSyncWaitFrameStart(&context->sync)) { - struct fb_var_screeninfo info; - ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); - info.yoffset = GBA_VIDEO_VERTICAL_PIXELS * renderer->odd; - ioctl(renderer->fb, FBIOPAN_DISPLAY, &info); - - int arg = 0; - ioctl(renderer->fb, FBIO_WAITFORVSYNC, &arg); - - renderer->odd = !renderer->odd; - renderer->d.outputBuffer = renderer->base[renderer->odd]; - } - mCoreSyncWaitFrameEnd(&context->sync); - } -} - -void mSDLDeinit(struct SDLSoftwareRenderer* renderer) { - munmap(renderer->base[0], GBA_VIDEO_HORIZONTAL_PIXELS * GBA_VIDEO_VERTICAL_PIXELS * 4); - - struct omapfb_plane_info plane; - struct omapfb_mem_info mem; - ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane); - ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem); - - mem.size = 0; - ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); - - plane.enabled = 0; - plane.pos_x = 0; - plane.pos_y = 0; - plane.out_width = 0; - plane.out_height = 0; - ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); - - close(renderer->fb); -} diff --git a/src/platform/sdl/rpi-common.c b/src/platform/sdl/rpi-common.c deleted file mode 100644 index be141718e..000000000 --- a/src/platform/sdl/rpi-common.c +++ /dev/null @@ -1,84 +0,0 @@ -/* 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 deleted file mode 100644 index b58532de5..000000000 --- a/src/platform/sdl/rpi-common.h +++ /dev/null @@ -1,20 +0,0 @@ -/* 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 diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 950bb94f3..afeedba68 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -143,18 +143,6 @@ void mSDLEventsLoadConfig(struct mSDLEvents* context, const struct Configuration } void mSDLInitBindingsGBA(struct mInputMap* inputMap) { -#ifdef BUILD_PANDORA - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_PAGEDOWN, GBA_KEY_A); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_END, GBA_KEY_B); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RSHIFT, GBA_KEY_L); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RCTRL, GBA_KEY_R); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LALT, GBA_KEY_START); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LCTRL, GBA_KEY_SELECT); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_UP, GBA_KEY_UP); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); - mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); -#else mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_x, GBA_KEY_A); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_z, GBA_KEY_B); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_a, GBA_KEY_L); @@ -165,7 +153,6 @@ void mSDLInitBindingsGBA(struct mInputMap* inputMap) { mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_DOWN, GBA_KEY_DOWN); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_LEFT, GBA_KEY_LEFT); mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT); -#endif #if SDL_VERSION_ATLEAST(2, 0, 0) mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_A, GBA_KEY_A); @@ -522,11 +509,6 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* context->frameCallback = _pauseAfterFrame; mCoreThreadUnpause(context); return; -#ifdef BUILD_PANDORA - case SDLK_ESCAPE: - mCoreThreadEnd(context); - return; -#endif default: if ((event->keysym.mod & GUI_MOD) && (event->keysym.mod & GUI_MOD) == event->keysym.mod) { switch (event->keysym.sym) { From 3f54bcbc878b8cc27211adf729d6231474e53976 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 04:19:50 -0700 Subject: [PATCH 056/148] GB, GBA Audio: More efficient sample writing --- src/gb/audio.c | 14 +++++--------- src/gba/audio.c | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 4230fb88c..9603175a8 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -823,15 +823,11 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { mCoreSyncLockAudio(audio->p->sync); unsigned produced; - int i; - for (i = 0; i < GB_MAX_SAMPLES; ++i) { - int16_t sample[2] = { - audio->currentSamples[i].left, - audio->currentSamples[i].right - }; - mAudioBufferWrite(&audio->buffer, sample, 1); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); + mAudioBufferWrite(&audio->buffer, (int16_t*) audio->currentSamples, GB_MAX_SAMPLES); + if (audio->p->stream && audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < GB_MAX_SAMPLES; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); } } diff --git a/src/gba/audio.c b/src/gba/audio.c index 8ccc7f9d8..8c07bcb51 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -393,15 +393,11 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { mCoreSyncLockAudio(audio->p->sync); unsigned produced; - int i; - for (i = 0; i < samples; ++i) { - int16_t sample[2] = { - audio->currentSamples[i].left, - audio->currentSamples[i].right - }; - mAudioBufferWrite(&audio->psg.buffer, sample, 1); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - audio->p->stream->postAudioFrame(audio->p->stream, sample[0], sample[1]); + mAudioBufferWrite(&audio->psg.buffer, (int16_t*) audio->currentSamples, samples); + if (audio->p->stream && audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < samples; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); } } produced = mAudioBufferAvailable(&audio->psg.buffer); From 2bce03023bb051aeb22e16a2b3a7160713c672b7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 21:38:54 -0700 Subject: [PATCH 057/148] GB, GBA Audio: Refactor stream code to do less when no stream is present --- src/gb/audio.c | 25 +++++++++++++------------ src/gba/audio.c | 24 +++++++++++++----------- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 9603175a8..b090018f6 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -822,25 +822,26 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { GBAudioSample(audio, mTimingCurrentTime(audio->timing)); mCoreSyncLockAudio(audio->p->sync); - unsigned produced; mAudioBufferWrite(&audio->buffer, (int16_t*) audio->currentSamples, GB_MAX_SAMPLES); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - int i; - for (i = 0; i < GB_MAX_SAMPLES; ++i) { - audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + if (audio->p->stream) { + if (audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < GB_MAX_SAMPLES; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + } + } + if (audio->p->stream->postAudioBuffer) { + unsigned produced = mAudioBufferAvailable(&audio->buffer); + bool wait = produced >= audio->samples; + if (wait) { + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); + } } } - - produced = mAudioBufferAvailable(&audio->buffer); - bool wait = produced >= audio->samples; if (!mCoreSyncProduceAudio(audio->p->sync, &audio->buffer)) { // Interrupted audio->p->earlyExit = true; } - - if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, &audio->buffer); - } mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate); } diff --git a/src/gba/audio.c b/src/gba/audio.c index 8c07bcb51..c84d6ce27 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -392,25 +392,27 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) { memset(audio->chB.samples, audio->chB.samples[samples - 1], sizeof(audio->chB.samples)); mCoreSyncLockAudio(audio->p->sync); - unsigned produced; mAudioBufferWrite(&audio->psg.buffer, (int16_t*) audio->currentSamples, samples); - if (audio->p->stream && audio->p->stream->postAudioFrame) { - int i; - for (i = 0; i < samples; ++i) { - audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + if (audio->p->stream) { + if (audio->p->stream->postAudioFrame) { + int i; + for (i = 0; i < samples; ++i) { + audio->p->stream->postAudioFrame(audio->p->stream, audio->currentSamples[i].left,audio->currentSamples[i].right); + } + } + if (audio->p->stream->postAudioBuffer) { + unsigned produced = mAudioBufferAvailable(&audio->psg.buffer); + bool wait = produced >= audio->samples; + if (wait) { + audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); + } } } - produced = mAudioBufferAvailable(&audio->psg.buffer); - bool wait = produced >= audio->samples; if (!mCoreSyncProduceAudio(audio->p->sync, &audio->psg.buffer)) { // Interrupted audio->p->earlyExit = true; } - if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) { - audio->p->stream->postAudioBuffer(audio->p->stream, &audio->psg.buffer); - } - mTimingSchedule(timing, &audio->sampleEvent, SAMPLE_INTERVAL - cyclesLate); } From 55add8a2c6b69faa97a08682cb62d59572aef16d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 22 Apr 2024 21:42:34 -0700 Subject: [PATCH 058/148] Util: Early exist mAudioBufferRead if the buffer is full --- src/util/audio-buffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/audio-buffer.c b/src/util/audio-buffer.c index 5d67827fb..028946b48 100644 --- a/src/util/audio-buffer.c +++ b/src/util/audio-buffer.c @@ -52,6 +52,9 @@ size_t mAudioBufferRead(struct mAudioBuffer* buffer, int16_t* samples, size_t co size_t mAudioBufferWrite(struct mAudioBuffer* buffer, const int16_t* samples, size_t count) { size_t free = mCircleBufferCapacity(&buffer->data) - mCircleBufferSize(&buffer->data); if (count * buffer->channels * sizeof(int16_t) > free) { + if (!free) { + return 0; + } count = free / (buffer->channels * sizeof(int16_t)); } return mCircleBufferWrite(&buffer->data, samples, count * buffer->channels * sizeof(int16_t)) / From 96702f7db19e62388a23ab64a495e49a7c3f2184 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 23 Apr 2024 22:33:57 -0700 Subject: [PATCH 059/148] Util: Use HAS_IPV6 more where appropriate --- include/mgba-util/socket.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba-util/socket.h b/include/mgba-util/socket.h index ff9d89626..4b109eaea 100644 --- a/include/mgba-util/socket.h +++ b/include/mgba-util/socket.h @@ -234,7 +234,7 @@ static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) #else err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo)); #endif -#if !defined(__3DS__) && !defined(GEKKO) +#ifdef HAS_IPV6 } else { struct sockaddr_in6 bindInfo; memset(&bindInfo, 0, sizeof(bindInfo)); @@ -333,7 +333,7 @@ static inline Socket SocketAccept(Socket socket, struct Address* address) { #else return accept(socket, (struct sockaddr*) &addrInfo, &len); #endif -#if !defined(__3DS__) && !defined(GEKKO) +#ifdef HAS_IPV6 } else { struct sockaddr_in6 addrInfo; memset(&addrInfo, 0, sizeof(addrInfo)); From 88a8f80ebdea737885ee885600d1b2288e8bde9c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 24 Apr 2024 22:54:43 -0700 Subject: [PATCH 060/148] VFS: Rename USE_VFS_* to ENABLE_VFS_* --- include/mgba-util/vfs.h | 2 +- src/platform/3ds/3ds-vfs.c | 2 +- src/platform/3ds/CMakeLists.txt | 8 ++++---- src/util/vfs.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 0ff100143..004dbd685 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -98,7 +98,7 @@ bool VDirCreate(const char* path); struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); -#ifdef USE_VFS_FILE +#ifdef ENABLE_VFS_FILE struct VFile* VFileFOpen(const char* path, const char* mode); struct VFile* VFileFromFILE(FILE* file); #endif diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c index f2aaeb84a..88297e9cd 100644 --- a/src/platform/3ds/3ds-vfs.c +++ b/src/platform/3ds/3ds-vfs.c @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -#ifdef USE_VFS_3DS +#ifdef ENABLE_VFS_3DS #include #include diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 7469fe6d4..2073e13fe 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -1,5 +1,5 @@ -set(USE_VFS_3DS OFF CACHE BOOL "Use 3DS-specific file support") -mark_as_advanced(USE_VFS_3DS) +set(ENABLE_VFS_3DS OFF CACHE BOOL "Use 3DS-specific file support") +mark_as_advanced(ENABLE_VFS_3DS) find_program(3DSLINK 3dslink) find_program(3DSXTOOL 3dsxtool) @@ -28,8 +28,8 @@ set(OS_SRC set(OS_LIB ${OS_LIB} PARENT_SCOPE) source_group("3DS-specific code" FILES ${OS_SRC}) -if(USE_VFS_3DS) - list(APPEND OS_DEFINES USE_VFS_3DS) +if(ENABLE_VFS_3DS) + list(APPEND OS_DEFINES ENABLE_VFS_3DS) else() list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() diff --git a/src/util/vfs.c b/src/util/vfs.c index 09ae81047..74a96b369 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -20,7 +20,7 @@ #ifdef ENABLE_VFS struct VFile* VFileOpen(const char* path, int flags) { -#ifdef USE_VFS_FILE +#ifdef ENABLE_VFS_FILE const char* chflags; switch (flags & O_ACCMODE) { case O_WRONLY: @@ -68,7 +68,7 @@ struct VFile* VFileOpen(const char* path, int flags) { sceFlags |= SCE_O_CREAT; } return VFileOpenSce(path, sceFlags, 0666); -#elif defined(USE_VFS_3DS) +#elif defined(ENABLE_VFS_3DS) int ctrFlags = FS_OPEN_READ; switch (flags & O_ACCMODE) { case O_WRONLY: From 87653b7b197d0bd2a217dd6b61421d1518bc9191 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 24 Apr 2024 23:19:31 -0700 Subject: [PATCH 061/148] Qt: Fix potential crash when configuring shortcuts --- CHANGES | 1 + src/platform/qt/ShortcutModel.cpp | 48 +++++++++++++++++-------------- src/platform/qt/ShortcutModel.h | 4 +-- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 13d7b0f4c..328de47b8 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Other fixes: - GB: Fix uninitialized save data when loading undersized temporary saves - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) + - Qt: Fix potential crash when configuring shortcuts - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/ShortcutModel.cpp b/src/platform/qt/ShortcutModel.cpp index b73982cad..f90667935 100644 --- a/src/platform/qt/ShortcutModel.cpp +++ b/src/platform/qt/ShortcutModel.cpp @@ -28,11 +28,11 @@ QVariant ShortcutModel::data(const QModelIndex& index, int role) const { if (role != Qt::DisplayRole || !index.isValid()) { return QVariant(); } - const Item* item = static_cast(index.internalPointer()); - const Shortcut* shortcut = item->shortcut; + const Item& item = m_cache[index.internalId()]; + const Shortcut* shortcut = item.shortcut; switch (index.column()) { case 0: - return m_controller->visibleName(item->name); + return m_controller->visibleName(item.name); case 1: return shortcut ? keyName(shortcut->shortcut()) : QVariant(); case 2: @@ -77,28 +77,31 @@ QVariant ShortcutModel::headerData(int section, Qt::Orientation orientation, int QModelIndex ShortcutModel::index(int row, int column, const QModelIndex& parent) const { QString pmenu; if (parent.isValid()) { - pmenu = static_cast(parent.internalPointer())->name; + const Item& item = m_cache[parent.internalId()]; + pmenu = item.name; } QString name = m_controller->name(row, pmenu); - Item* item = &m_cache[name]; - item->name = name; - item->shortcut = m_controller->shortcut(name); - return createIndex(row, column, item); + size_t hash = qHash(name); + Item& item = m_cache[hash]; + item.name = name; + item.shortcut = m_controller->shortcut(name); + return createIndex(row, column, hash); } 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); + const Item& item = m_cache[index.internalId()]; + QString parent = m_controller->parent(item.name); if (parent.isNull()) { return QModelIndex(); } - Item* pitem = &m_cache[parent]; - pitem->name = parent; - pitem->shortcut = m_controller->shortcut(parent); - return createIndex(m_controller->indexIn(parent), 0, pitem); + size_t hash = qHash(parent); + Item& pitem = m_cache[hash]; + pitem.name = parent; + pitem.shortcut = m_controller->shortcut(parent); + return createIndex(m_controller->indexIn(parent), 0, hash); } int ShortcutModel::columnCount(const QModelIndex&) const { @@ -109,25 +112,26 @@ 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); + const Item& item = m_cache[index.internalId()]; + 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; + const Item& item = m_cache[index.internalId()]; + 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); + size_t hash = qHash(name); + Item& item = m_cache[hash]; + 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); + beginInsertRows(createIndex(m_controller->indexIn(parent), 0, hash), index, index + 1); endInsertRows(); } diff --git a/src/platform/qt/ShortcutModel.h b/src/platform/qt/ShortcutModel.h index 3eb3b1178..64a1d3301 100644 --- a/src/platform/qt/ShortcutModel.h +++ b/src/platform/qt/ShortcutModel.h @@ -44,7 +44,7 @@ private: const Shortcut* shortcut = nullptr; }; - mutable QHash m_cache; + mutable QHash m_cache; }; -} \ No newline at end of file +} From aae9c502f02e097e8154fbe23e85b0a676288652 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 25 Apr 2024 01:03:08 -0700 Subject: [PATCH 062/148] Misc: Fix a slew of less-than-important warnings --- src/core/cheats.c | 12 ++++++------ src/feature/commandline.c | 5 ++++- src/gb/audio.c | 2 +- src/gba/cart/ereader.c | 2 +- src/gba/sharkport.c | 4 ++-- src/util/image.c | 6 +++--- src/util/image/png-io.c | 7 +++++-- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/core/cheats.c b/src/core/cheats.c index 85a06b80d..53f71e907 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -282,14 +282,14 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { StringListDeinit(&directives); return false; } - while (isspace((int) cheat[i])) { + while (isspace((unsigned) cheat[i])) { ++i; } switch (cheat[i]) { case '#': do { ++i; - } while (isspace((int) cheat[i])); + } while (isspace((unsigned) cheat[i])); newSet = device->createSet(device, &cheat[i]); newSet->enabled = !nextDisabled; nextDisabled = false; @@ -305,7 +305,7 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { case '!': do { ++i; - } while (isspace((int) cheat[i])); + } while (isspace((unsigned) cheat[i])); if (strcasecmp(&cheat[i], "disabled") == 0) { nextDisabled = true; break; @@ -384,7 +384,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { return false; } ++eq; - while (isspace((int) eq[0])) { + while (isspace((unsigned) eq[0])) { if (eq[0] == '\0') { return false; } @@ -393,7 +393,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { char* end; unsigned long nCheats = strtoul(eq, &end, 10); - if (end[0] != '\0' && !isspace(end[0])) { + if (end[0] != '\0' && !isspace((unsigned) end[0])) { return false; } @@ -423,7 +423,7 @@ bool mCheatParseLibretroFile(struct mCheatDevice* device, struct VFile* vf) { return false; } ++eq; - while (isspace((int) eq[0])) { + while (isspace((unsigned) eq[0])) { if (eq[0] == '\0') { return false; } diff --git a/src/feature/commandline.c b/src/feature/commandline.c index 59735e69b..fca5c7747 100644 --- a/src/feature/commandline.c +++ b/src/feature/commandline.c @@ -217,9 +217,12 @@ void mArgumentsApply(const struct mArguments* args, struct mSubParser* subparser } bool mArgumentsApplyDebugger(const struct mArguments* args, struct mCore* core, struct mDebugger* debugger) { + UNUSED(args); + UNUSED(core); + UNUSED(debugger); bool hasDebugger = false; - #ifdef USE_EDITLINE +#ifdef USE_EDITLINE if (args->debugCli) { struct mDebuggerModule* module = mDebuggerCreateModule(DEBUGGER_CLI, core); if (module) { diff --git a/src/gb/audio.c b/src/gb/audio.c index b090018f6..783b1fcb9 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -602,7 +602,7 @@ void GBAudioRun(struct GBAudio* audio, int32_t timestamp, int channels) { int32_t last = 0; int samples = 0; int positiveSamples = 0; - int lsb; + int lsb = 0; int coeff; if (audio->ch4.power) { // TODO: Can this be batched too? diff --git a/src/gba/cart/ereader.c b/src/gba/cart/ereader.c index fc4d4c11d..1712f2833 100644 --- a/src/gba/cart/ereader.c +++ b/src/gba/cart/ereader.c @@ -371,7 +371,7 @@ void GBACartEReaderScan(struct GBACartEReader* ereader, const void* data, size_t memset(ereader->dots, 0, EREADER_DOTCODE_SIZE); uint8_t blockRS[44][0x10]; - uint8_t block0[0x30]; + uint8_t block0[0x30] = {0}; bool parsed = false; bool bitmap = false; bool reducedHeader = false; diff --git a/src/gba/sharkport.c b/src/gba/sharkport.c index 2f33e3d41..f6b908f3a 100644 --- a/src/gba/sharkport.c +++ b/src/gba/sharkport.c @@ -202,7 +202,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) { char c[0x1C]; int32_t i; } buffer; - uint32_t size = strlen(SHARKPORT_HEADER); + int32_t size = strlen(SHARKPORT_HEADER); STORE_32(size, 0, &buffer.i); if (vf->write(vf, &buffer.i, 4) < 4) { return false; @@ -271,7 +271,7 @@ bool GBASavedataExportSharkPort(const struct GBA* gba, struct VFile* vf) { } uint32_t checksum = 0; - size_t i; + ssize_t i; for (i = 0; i < 0x1C; ++i) { checksum += buffer.c[i] << (checksum % 24); } diff --git a/src/util/image.c b/src/util/image.c index 64e8aeec6..e5ee9f9e2 100644 --- a/src/util/image.c +++ b/src/util/image.c @@ -904,9 +904,9 @@ uint32_t mColorConvert(uint32_t color, enum mColorFormat from, enum mColorFormat return color; } - int r; - int g; - int b; + int r = 0; + int g = 0; + int b = 0; int a = 0xFF; switch (from) { diff --git a/src/util/image/png-io.c b/src/util/image/png-io.c index e7df1d64f..0207e03a8 100644 --- a/src/util/image/png-io.c +++ b/src/util/image/png-io.c @@ -62,7 +62,7 @@ static png_infop _pngWriteHeader(png_structp png, unsigned width, unsigned heigh } png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height, enum mColorFormat fmt) { - int type; + int type = -1; switch (fmt) { case mCOLOR_XBGR8: case mCOLOR_XRGB8: @@ -94,6 +94,9 @@ png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height, enum type = PNG_COLOR_TYPE_PALETTE; break; } + if (type < 0) { + return NULL; + } return _pngWriteHeader(png, width, height, NULL, 0, type); } @@ -373,6 +376,7 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s } else { depth = 3; } + stride *= mColorFormatBytes(fmt); png_bytep row = malloc(sizeof(png_byte) * width * depth); if (!row) { return false; @@ -383,7 +387,6 @@ bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned s return false; } const png_byte* pixelRow = pixelData; - stride *= mColorFormatBytes(fmt); unsigned i; for (i = 0; i < height; ++i, pixelRow += stride) { switch (fmt) { From db1e02521e5835059117c35abefe971f0861e7c5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 26 Apr 2024 19:05:38 -0700 Subject: [PATCH 063/148] GBA Core: Fix audio sample rate dynamically changing (fixes #3194) --- src/gba/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 47da3a0e0..3d874dfe3 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -554,8 +554,8 @@ static void _GBACorePutPixels(struct mCore* core, const void* buffer, size_t str } static unsigned _GBACoreAudioSampleRate(const struct mCore* core) { - UNUSED(core); - return 65536; + struct GBA* gba = core->board; + return GBA_ARM7TDMI_FREQUENCY / gba->audio.sampleInterval; } static struct mAudioBuffer* _GBACoreGetAudioBuffer(struct mCore* core) { From 5a28564b125bf135b55686fe6d94a659a3d11f99 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:17:50 -0700 Subject: [PATCH 064/148] Switch: Fix audio resampling after GBA fix --- src/platform/switch/main.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 8307f9811..9a3441b9b 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -20,7 +20,7 @@ #include #define AUTO_INPUT 0x4E585031 -#define SAMPLES 0x200 +#define SAMPLES 0x400 #define N_BUFFERS 6 #define ANALOG_DEADZONE 0x4000 @@ -91,6 +91,7 @@ static struct mRotationSource rotation = {0}; static AudioDriver audrenDriver; static AudioDriverWaveBuf audrvBuffer[N_BUFFERS]; static struct mStereoSample* audioBuffer[N_BUFFERS]; +static double fpsRatio = 1; static bool frameLimiter = true; static unsigned framecount = 0; static unsigned framecap = 10; @@ -266,6 +267,19 @@ static void _updateRenderer(struct mGUIRunner* runner, bool gl) { } } +static void _resetSampleRate(u32 samplerate) { + if (!samplerate) { + samplerate = 32768; + } + audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / fpsRatio); + audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); + audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); + audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); + audrvUpdate(&audrenDriver); +} + static void _setup(struct mGUIRunner* runner) { _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, AUTO_INPUT, HidNpadButton_B, GBA_KEY_B); @@ -303,14 +317,8 @@ static void _setup(struct mGUIRunner* runner) { runner->core->setAudioBufferSize(runner->core, SAMPLES); u32 samplerate = runner->core->audioSampleRate(runner->core); - double ratio = mCoreCalculateFramerateRatio(runner->core, 60.0); - audrvVoiceInit(&audrenDriver, 0, 2, PcmFormat_Int16, samplerate / ratio); - audrvVoiceSetDestinationMix(&audrenDriver, 0, AUDREN_FINAL_MIX_ID); - audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 0, 0); - audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 0, 1); - audrvVoiceSetMixFactor(&audrenDriver, 0, 0.0f, 1, 0); - audrvVoiceSetMixFactor(&audrenDriver, 0, 1.0f, 1, 1); - audrvUpdate(&audrenDriver); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, 60.0); + _resetSampleRate(samplerate); } static void _gameLoaded(struct mGUIRunner* runner) { @@ -572,6 +580,11 @@ static bool _running(struct mGUIRunner* runner) { return appletMainLoop(); } +static void _audioRateChanged(struct mAVStream* stream, uint32_t samplerate) { + UNUSED(stream); + _resetSampleRate(samplerate); +} + static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer) { UNUSED(stream); int i; @@ -891,6 +904,7 @@ int main(int argc, char* argv[]) { stream.postVideoFrame = NULL; stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; size_t i; for (i = 0; i < N_BUFFERS; ++i) { From 5e581b0ade6b78e744dddd647fa6175f921ba65e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:29:29 -0700 Subject: [PATCH 065/148] 3DS: Fix audio resampling after GBA fix --- src/platform/3ds/main.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index c85103bce..de6575eff 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -90,6 +90,7 @@ static color_t* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; +static double fpsRatio; static C3D_Tex outputTexture[2]; static int activeOutputTexture = 0; static ndspWaveBuf dspBuffer[DSP_BUFFERS]; @@ -189,8 +190,6 @@ static void _map3DSKey(struct mInputMap* map, int ctrKey, int key) { mInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key); } -static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buffer); - static void _drawStart(void) { if (frameStarted) { return; @@ -347,8 +346,11 @@ static void _gameLoaded(struct mGUIRunner* runner) { } if (hasSound == DSP_SUPPORTED) { unsigned sampleRate = runner->core->audioSampleRate(runner->core); - double fauxClock = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); - ndspChnSetRate(0, sampleRate * fauxClock); + if (!sampleRate) { + sampleRate = 32768; + } + fpsRatio = mCoreCalculateFramerateRatio(runner->core, 16756991. / 280095.); + ndspChnSetRate(0, sampleRate * fpsRatio); memset(audioLeft, 0, AUDIO_SAMPLE_BUFFER * 2 * sizeof(int16_t)); } unsigned mode; @@ -795,6 +797,14 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff } } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + sampleRate = 32768; + } + ndspChnSetRate(0, sampleRate * fpsRatio); +} + static enum GUIKeyboardStatus _keyboardRun(struct GUIKeyboardParams* keyboard) { SwkbdState swkbd; swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, keyboard->maxLen); @@ -830,10 +840,11 @@ int main(int argc, char* argv[]) { rotation.d.readTiltY = _readTiltY; rotation.d.readGyroZ = _readGyroZ; - stream.videoDimensionsChanged = 0; - stream.postVideoFrame = 0; - stream.postAudioFrame = 0; + stream.videoDimensionsChanged = NULL; + stream.postVideoFrame = NULL; + stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; camera.d.startRequestImage = _startRequestImage; camera.d.stopRequestImage = _stopRequestImage; From 4aba51e9553343b64b56fafee48bcd609c402f16 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 18:55:18 -0700 Subject: [PATCH 066/148] Vita: Fix audio resampling after GBA fix --- src/platform/psp2/psp2-context.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 36253aa07..0f456fa7e 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -54,6 +54,7 @@ static int currentTex; static vita2d_texture* tex[2]; static vita2d_texture* screenshot; static Thread audioThread; +static double fpsRatio = 1; static bool interframeBlending = false; static bool sgbCrop = false; static bool blurry = false; @@ -266,6 +267,20 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) MutexUnlock(&audioContext.mutex); } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + return; + } + if (!audioContext.resampler.source || !audioContext.resampler.destination) { + return; + } + MutexLock(&audioContext.mutex); + mAudioResamplerProcess(&audioContext.resampler); + mAudioResamplerSetSource(&audioContext.resampler, audioContext.resampler.source, sampleRate / fpsRatio, true); + MutexUnlock(&audioContext.mutex); +} + uint16_t mPSP2PollInput(struct mGUIRunner* runner) { SceCtrlData pad; sceCtrlPeekBufferPositiveExt2(0, &pad, 1); @@ -364,6 +379,7 @@ void mPSP2Setup(struct mGUIRunner* runner) { stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; stream.postVideoFrame = NULL; + stream.audioRateChanged = _audioRateChanged; runner->core->setAVStream(runner->core, &stream); frameLimiter = true; @@ -423,10 +439,13 @@ void mPSP2LoadROM(struct mGUIRunner* runner) { float rate = 60.0f / 1.001f; sceDisplayGetRefreshRate(&rate); - double ratio = mCoreCalculateFramerateRatio(runner->core, rate); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, rate); unsigned sampleRate = runner->core->audioSampleRate(runner->core); + if (!sampleRate) { + sampleRate = 32768; + } mAudioBufferClear(&audioContext.buffer); - mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / ratio, true); + mAudioResamplerSetSource(&audioContext.resampler, runner->core->getAudioBuffer(runner->core), sampleRate / fpsRatio, true); ThreadCreate(&audioThread, _audioThread, &audioContext); } From df75204a0bfe0453540ad92c6d30abb9d83a5388 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 27 Apr 2024 19:15:04 -0700 Subject: [PATCH 067/148] Wii: Fix audio resampling after GBA fix --- src/platform/wii/main.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index f21c7e19b..55bae9738 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -77,6 +77,7 @@ static enum VideoMode { static void _retraceCallback(u32 count); static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); +static void _audioRateChanged(struct mAVStream* stream, unsigned); static void _audioDMA(void); static void _setRumble(struct mRumble* rumble, int enable); static void _sampleRotation(struct mRotationSource* source); @@ -147,7 +148,8 @@ static struct AudioBuffer { static struct mAudioBuffer audioBuffer; static volatile int currentAudioBuffer = 0; static volatile int nextAudioBuffer = 0; -static double audioSampleRate = 60.0 / 1.001; +static double fps = 60.0 / 1.001; +static double fpsRatio = 1; static struct mAudioResampler resampler; static struct GUIFont* font; @@ -162,7 +164,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { wAdjust = 1.f; hAdjust = 1.f; guiScale = GUI_SCALE; - audioSampleRate = 60.0 / 1.001; + fps = 60.0 / 1.001; s32 signalMode = CONF_GetVideo(); @@ -210,7 +212,7 @@ static void reconfigureScreen(struct mGUIRunner* runner) { break; } wAdjust = 0.5f; - audioSampleRate = 90.0 / 1.50436; + fps = 90.0 / 1.50436; guiScale = GUI_SCALE_240p; break; } @@ -348,6 +350,7 @@ int main(int argc, char* argv[]) { stream.postVideoFrame = NULL; stream.postAudioFrame = NULL; stream.postAudioBuffer = _postAudioBuffer; + stream.audioRateChanged = _audioRateChanged; struct mGUIRunner runner = { .params = { @@ -717,6 +720,18 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buf) _CPU_ISR_Restore(level); } +static void _audioRateChanged(struct mAVStream* stream, unsigned sampleRate) { + UNUSED(stream); + if (!sampleRate) { + return; + } + if (!resampler.source || !resampler.destination) { + return; + } + mAudioResamplerProcess(&resampler); + mAudioResamplerSetSource(&resampler, resampler.source, sampleRate / fpsRatio, true); +} + static void _drawStart(void) { VIDEO_SetBlack(false); @@ -1419,8 +1434,12 @@ void _setup(struct mGUIRunner* runner) { memset(audioBuffers, 0, sizeof(audioBuffers)); runner->core->setAudioBufferSize(runner->core, SAMPLES); - double ratio = mCoreCalculateFramerateRatio(runner->core, audioSampleRate); - mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), runner->core->audioSampleRate(runner->core) / ratio, true); + fpsRatio = mCoreCalculateFramerateRatio(runner->core, fps); + unsigned sampleRate = runner->core->audioSampleRate(runner->core); + if (!sampleRate) { + sampleRate = 32768; + } + mAudioResamplerSetSource(&resampler, runner->core->getAudioBuffer(runner->core), sampleRate / fpsRatio, true); frameLimiter = true; } From 1d2b8bf918890e4e71957a1677a7bee72c796c08 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 30 Apr 2024 02:57:41 -0700 Subject: [PATCH 068/148] Libretro: Add Super Game Boy Color support (closes #3188) --- CHANGES | 1 + src/platform/libretro/libretro.c | 4 ++++ src/platform/libretro/libretro_core_options.h | 11 ++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 328de47b8..15f85e7f0 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 86a692837..d2565a42b 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -268,6 +268,8 @@ static void _reloadSettings(void) { model = GB_MODEL_SGB; } else if (strcmp(var.value, "Game Boy Color") == 0) { model = GB_MODEL_CGB; + } else if (strcmp(var.value, "Super Game Boy Color") == 0) { + model = GB_MODEL_SCGB; } else if (strcmp(var.value, "Game Boy Advance") == 0) { model = GB_MODEL_AGB; } else { @@ -278,6 +280,8 @@ static void _reloadSettings(void) { mCoreConfigSetDefaultValue(&core->config, "gb.model", modelName); mCoreConfigSetDefaultValue(&core->config, "sgb.model", modelName); mCoreConfigSetDefaultValue(&core->config, "cgb.model", modelName); + mCoreConfigSetDefaultValue(&core->config, "cgb.hybridModel", modelName); + mCoreConfigSetDefaultValue(&core->config, "cgb.sgbModel", modelName); } var.key = "mgba_sgb_borders"; diff --git a/src/platform/libretro/libretro_core_options.h b/src/platform/libretro/libretro_core_options.h index 76ca634f9..f0a4b3f04 100644 --- a/src/platform/libretro/libretro_core_options.h +++ b/src/platform/libretro/libretro_core_options.h @@ -87,11 +87,12 @@ struct retro_core_option_v2_definition option_defs_us[] = { NULL, "system", { - { "Autodetect", NULL }, - { "Game Boy", NULL }, - { "Super Game Boy", NULL }, - { "Game Boy Color", NULL }, - { "Game Boy Advance", NULL }, + { "Autodetect", NULL }, + { "Game Boy", NULL }, + { "Super Game Boy", NULL }, + { "Game Boy Color", NULL }, + { "Super Game Boy Color", NULL }, + { "Game Boy Advance", NULL }, { NULL, NULL }, }, "Autodetect" From d9e080b9a9f2b9fec8631988474bcf18b52d249a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 6 May 2024 15:35:23 -0700 Subject: [PATCH 069/148] GBA: Prefix SIO constants with GBA_ --- include/mgba/gba/interface.h | 12 +++---- src/gba/cart/gpio.c | 2 +- src/gba/core.c | 4 +-- src/gba/extra/battlechip.c | 4 +-- src/gba/gba.c | 2 +- src/gba/sio.c | 40 ++++++++++----------- src/gba/sio/gbp.c | 4 +-- src/gba/sio/lockstep.c | 42 +++++++++++------------ src/platform/python/mgba/gba.py | 14 ++++---- src/platform/qt/CoreController.cpp | 4 +-- src/platform/qt/MultiplayerController.cpp | 10 +++--- 11 files changed, 69 insertions(+), 69 deletions(-) diff --git a/include/mgba/gba/interface.h b/include/mgba/gba/interface.h index a04685e49..97e0a5b9c 100644 --- a/include/mgba/gba/interface.h +++ b/include/mgba/gba/interface.h @@ -21,12 +21,12 @@ enum { }; enum GBASIOMode { - SIO_NORMAL_8 = 0, - SIO_NORMAL_32 = 1, - SIO_MULTI = 2, - SIO_UART = 3, - SIO_GPIO = 8, - SIO_JOYBUS = 12 + GBA_SIO_NORMAL_8 = 0, + GBA_SIO_NORMAL_32 = 1, + GBA_SIO_MULTI = 2, + GBA_SIO_UART = 3, + GBA_SIO_GPIO = 8, + GBA_SIO_JOYBUS = 12 }; enum GBASIOJOYCommand { diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 811dc1e8a..0a396f746 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -525,7 +525,7 @@ void GBAHardwareDeserialize(struct GBACartridgeHardware* hw, const struct GBASer uint32_t when; LOAD_32(when, 0, &state->hw.gbpNextEvent); if (hw->devices & HW_GB_PLAYER) { - GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, SIO_NORMAL_32); + GBASIOSetDriver(&hw->p->sio, &hw->p->sio.gbp.d, GBA_SIO_NORMAL_32); if (hw->p->memory.io[GBA_REG(SIOCNT)] & 0x0080) { mTimingSchedule(&hw->p->timing, &hw->p->sio.gbp.event, when); } diff --git a/src/gba/core.c b/src/gba/core.c index 3d874dfe3..256aebdab 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -891,8 +891,8 @@ static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { gba->luminanceSource = periph; break; case mPERIPH_GBA_BATTLECHIP_GATE: - GBASIOSetDriver(&gba->sio, periph, SIO_MULTI); - GBASIOSetDriver(&gba->sio, periph, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, periph, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, periph, GBA_SIO_NORMAL_32); break; default: return; diff --git a/src/gba/extra/battlechip.c b/src/gba/extra/battlechip.c index fa6be9796..3ab9f1403 100644 --- a/src/gba/extra/battlechip.c +++ b/src/gba/extra/battlechip.c @@ -84,7 +84,7 @@ uint16_t GBASIOBattlechipGateWriteRegister(struct GBASIODriver* driver, uint32_t void _battlechipTransfer(struct GBASIOBattlechipGate* gate) { int32_t cycles; - if (gate->d.p->mode == SIO_NORMAL_32) { + if (gate->d.p->mode == GBA_SIO_NORMAL_32) { cycles = GBA_ARM7TDMI_FREQUENCY / 0x40000; } else { cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(gate->d.p->siocnt)][1]; @@ -97,7 +97,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle UNUSED(timing); struct GBASIOBattlechipGate* gate = user; - if (gate->d.p->mode == SIO_NORMAL_32) { + if (gate->d.p->mode == GBA_SIO_NORMAL_32) { gate->d.p->p->memory.io[GBA_REG(SIODATA32_LO)] = 0; gate->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] = 0; gate->d.p->siocnt = GBASIONormalClearStart(gate->d.p->siocnt); diff --git a/src/gba/gba.c b/src/gba/gba.c index fb0a84ae7..94ed7562a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -232,7 +232,7 @@ void GBAReset(struct ARMCore* cpu) { // GB Player SIO control should not be engaged before detection, even if we already know it's GBP gba->memory.hw.devices &= ~HW_GB_PLAYER; if (gba->sio.drivers.normal == &gba->sio.gbp.d) { - GBASIOSetDriver(&gba->sio, NULL, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, NULL, GBA_SIO_NORMAL_32); } bool isELF = false; diff --git a/src/gba/sio.c b/src/gba/sio.c index 1082d0062..beb8efdfe 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -20,12 +20,12 @@ const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { switch (mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: return sio->drivers.normal; - case SIO_MULTI: + case GBA_SIO_MULTI: return sio->drivers.multiplayer; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: return sio->drivers.joybus; default: return 0; @@ -34,15 +34,15 @@ static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mo static const char* _modeName(enum GBASIOMode mode) { switch (mode) { - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: return "NORMAL8"; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: return "NORMAL32"; - case SIO_MULTI: + case GBA_SIO_MULTI: return "MULTI"; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: return "JOYBUS"; - case SIO_GPIO: + case GBA_SIO_GPIO: return "GPIO"; default: return "(unknown)"; @@ -113,22 +113,22 @@ void GBASIOReset(struct GBASIO* sio) { } void GBASIOSetDriverSet(struct GBASIO* sio, struct GBASIODriverSet* drivers) { - GBASIOSetDriver(sio, drivers->normal, SIO_NORMAL_8); - GBASIOSetDriver(sio, drivers->multiplayer, SIO_MULTI); - GBASIOSetDriver(sio, drivers->joybus, SIO_JOYBUS); + GBASIOSetDriver(sio, drivers->normal, GBA_SIO_NORMAL_8); + GBASIOSetDriver(sio, drivers->multiplayer, GBA_SIO_MULTI); + GBASIOSetDriver(sio, drivers->joybus, GBA_SIO_JOYBUS); } void GBASIOSetDriver(struct GBASIO* sio, struct GBASIODriver* driver, enum GBASIOMode mode) { struct GBASIODriver** driverLoc; switch (mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: driverLoc = &sio->drivers.normal; break; - case SIO_MULTI: + case GBA_SIO_MULTI: driverLoc = &sio->drivers.multiplayer; break; - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: driverLoc = &sio->drivers.joybus; break; default: @@ -182,8 +182,8 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { } else { // Dummy drivers switch (sio->mode) { - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: value = GBASIONormalFillSi(value); if ((value & 0x0081) == 0x0081) { if (GBASIONormalIsIrq(value)) { @@ -193,7 +193,7 @@ void GBASIOWriteSIOCNT(struct GBASIO* sio, uint16_t value) { value = GBASIONormalClearStart(value); } break; - case SIO_MULTI: + case GBA_SIO_MULTI: value &= 0xFF83; value |= 0xC; break; @@ -211,7 +211,7 @@ uint16_t GBASIOWriteRegister(struct GBASIO* sio, uint32_t address, uint16_t valu } // Dummy drivers switch (sio->mode) { - case SIO_JOYBUS: + case GBA_SIO_JOYBUS: switch (address) { case GBA_REG_JOYCNT: return (value & 0x0040) | (sio->p->memory.io[GBA_REG(JOYCNT)] & ~(value & 0x7) & ~0x0040); diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index 8400cc8b1..b5f987352 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -56,7 +56,7 @@ void GBASIOPlayerInit(struct GBASIOPlayer* gbp) { void GBASIOPlayerReset(struct GBASIOPlayer* gbp) { if (gbp->p->sio.drivers.normal == &gbp->d) { - GBASIOSetDriver(&gbp->p->sio, NULL, SIO_NORMAL_32); + GBASIOSetDriver(&gbp->p->sio, NULL, GBA_SIO_NORMAL_32); } } @@ -88,7 +88,7 @@ void GBASIOPlayerUpdate(struct GBA* gba) { gba->sio.gbp.oldCallback = gba->keyCallback; gba->keyCallback = &gba->sio.gbp.callback.d; // TODO: Check if the SIO driver is actually used first - GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &gba->sio.gbp.d, GBA_SIO_NORMAL_32); } } diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 71373a237..4f12610f1 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -103,7 +103,7 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->mode = driver->p->mode; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; node->d.p->rcnt |= 3; ATOMIC_ADD(node->p->attachedMulti, 1); @@ -125,8 +125,8 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { node->d.p->siocnt = GBASIOMultiplayerClearSlave(node->d.p->siocnt); } break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: if (ATOMIC_ADD(node->p->attachedNormal, 1) > node->id + 1 && node->id > 0) { node->d.p->siocnt = GBASIONormalSetSi(node->d.p->siocnt, GBASIONormalGetIdleSo(node->p->players[node->id - 1]->d.p->siocnt)); } else { @@ -154,11 +154,11 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { node->mode = driver->p->mode; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: ATOMIC_SUB(node->p->attachedMulti, 1); break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: ATOMIC_SUB(node->p->attachedNormal, 1); break; default: @@ -180,7 +180,7 @@ bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) { } // Invalidate SIO mode - node->mode = SIO_GPIO; + node->mode = GBA_SIO_GPIO; mLockstepUnlock(&node->p->d); @@ -235,7 +235,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { struct GBASIO* sio = node->d.p; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: sio->p->memory.io[GBA_REG(SIOMULTI0)] = node->p->multiRecv[0]; sio->p->memory.io[GBA_REG(SIOMULTI1)] = node->p->multiRecv[1]; sio->p->memory.io[GBA_REG(SIOMULTI2)] = node->p->multiRecv[2]; @@ -247,7 +247,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); } break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: // TODO sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { @@ -260,7 +260,7 @@ static void _finishTransfer(struct GBASIOLockstepNode* node) { GBARaiseIRQ(sio->p, GBA_IRQ_SIO, 0); } break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: // TODO sio->siocnt = GBASIONormalClearStart(sio->siocnt); if (node->id) { @@ -299,7 +299,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; - if (node->mode == SIO_MULTI) { + if (node->mode == GBA_SIO_MULTI) { node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMulti == attached); } break; @@ -307,7 +307,7 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { // Start the transfer, but wait for the other GBAs to catch up node->transferFinished = false; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->p->multiRecv[0] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; node->d.p->p->memory.io[GBA_REG(SIOMULTI1)] = 0xFFFF; @@ -317,11 +317,11 @@ static int32_t _masterUpdate(struct GBASIOLockstepNode* node) { node->p->multiRecv[2] = 0xFFFF; node->p->multiRecv[3] = 0xFFFF; break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: node->p->multiRecv[0] = 0xFFFF; node->p->normalRecv[0] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: node->p->multiRecv[0] = 0xFFFF; mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_LO <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]); mLOG(GBA_SIO, DEBUG, "Lockstep %i: SIODATA32_HI <- %04X", node->id, node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)]); @@ -393,7 +393,7 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { ATOMIC_LOAD(transferActive, node->p->d.transferActive); ATOMIC_LOAD(attached, node->p->d.attached); - if (node->mode == SIO_MULTI) { + if (node->mode == GBA_SIO_MULTI) { ATOMIC_LOAD(attachedMode, node->p->attachedMulti); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, attachedMode == attached); } else { @@ -415,7 +415,7 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { } node->transferFinished = false; switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: node->d.p->rcnt &= ~1; node->p->multiRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIOMLT_SEND)]; node->d.p->p->memory.io[GBA_REG(SIOMULTI0)] = 0xFFFF; @@ -424,11 +424,11 @@ static uint32_t _slaveUpdate(struct GBASIOLockstepNode* node) { node->d.p->p->memory.io[GBA_REG(SIOMULTI3)] = 0xFFFF; node->d.p->siocnt = GBASIOMultiplayerFillBusy(node->d.p->siocnt); break; - case SIO_NORMAL_8: + case GBA_SIO_NORMAL_8: node->p->multiRecv[node->id] = 0xFFFF; node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA8)] & 0xFF; break; - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_32: node->p->multiRecv[node->id] = 0xFFFF; node->p->normalRecv[node->id] = node->d.p->p->memory.io[GBA_REG(SIODATA32_LO)]; node->p->normalRecv[node->id] |= node->d.p->p->memory.io[GBA_REG(SIODATA32_HI)] << 16; @@ -466,11 +466,11 @@ static void _GBASIOLockstepNodeProcessEvents(struct mTiming* timing, void* user, node->eventDiff += cyclesLate; if (node->p->d.attached < 2) { switch (node->mode) { - case SIO_MULTI: + case GBA_SIO_MULTI: cycles = GBASIOCyclesPerTransfer[GBASIOMultiplayerGetBaud(node->d.p->siocnt)][0]; break; - case SIO_NORMAL_8: - case SIO_NORMAL_32: + case GBA_SIO_NORMAL_8: + case GBA_SIO_NORMAL_32: if (node->nextEvent <= 0) { cycles = _masterUpdate(node); node->eventDiff = 0; diff --git a/src/platform/python/mgba/gba.py b/src/platform/python/mgba/gba.py index a0c86ac84..109de4d50 100644 --- a/src/platform/python/mgba/gba.py +++ b/src/platform/python/mgba/gba.py @@ -23,12 +23,12 @@ class GBA(Core): KEY_L = lib.GBA_KEY_L KEY_R = lib.GBA_KEY_R - SIO_NORMAL_8 = lib.SIO_NORMAL_8 - SIO_NORMAL_32 = lib.SIO_NORMAL_32 - SIO_MULTI = lib.SIO_MULTI - SIO_UART = lib.SIO_UART - SIO_JOYBUS = lib.SIO_JOYBUS - SIO_GPIO = lib.SIO_GPIO + SIO_NORMAL_8 = lib.GBA_SIO_NORMAL_8 + SIO_NORMAL_32 = lib.GBA_SIO_NORMAL_32 + SIO_MULTI = lib.GBA_SIO_MULTI + SIO_UART = lib.GBA_SIO_UART + SIO_JOYBUS = lib.GBA_SIO_JOYBUS + SIO_GPIO = lib.GBA_SIO_GPIO def __init__(self, native): super(GBA, self).__init__(native) @@ -52,7 +52,7 @@ class GBA(Core): super(GBA, self)._load() self.memory = GBAMemory(self._core, self._native.memory.romSize) - def attach_sio(self, link, mode=lib.SIO_MULTI): + def attach_sio(self, link, mode=lib.GBA_SIO_MULTI): self._sio.add(mode) lib.GBASIOSetDriver(ffi.addressof(self._native.sio), link._native, mode) diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 660de1f57..02cd4db4c 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -424,7 +424,7 @@ bool CoreController::attachDolphin(const Address& address) { } if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, &m_dolphin.d, SIO_JOYBUS); + GBASIOSetDriver(&gba->sio, &m_dolphin.d, GBA_SIO_JOYBUS); return true; } return false; @@ -433,7 +433,7 @@ bool CoreController::attachDolphin(const Address& address) { void CoreController::detachDolphin() { if (platform() == mPLATFORM_GBA) { GBA* gba = static_cast(m_threadContext.core->board); - GBASIOSetDriver(&gba->sio, nullptr, SIO_JOYBUS); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_JOYBUS); } GBASIODolphinDestroy(&m_dolphin); } diff --git a/src/platform/qt/MultiplayerController.cpp b/src/platform/qt/MultiplayerController.cpp index 7ded956a4..149df2386 100644 --- a/src/platform/qt/MultiplayerController.cpp +++ b/src/platform/qt/MultiplayerController.cpp @@ -92,7 +92,7 @@ MultiplayerController::MultiplayerController() { if (!id) { for (int i = 1; i < controller->m_players.count(); ++i) { player = controller->player(i); - if (player->node.gba->d.p->mode > SIO_MULTI) { + if (player->node.gba->d.p->mode > GBA_SIO_MULTI) { player->controller->setSync(true); continue; } @@ -254,8 +254,8 @@ bool MultiplayerController::attachGame(CoreController* controller) { GBASIOLockstepAttachNode(&m_gbaLockstep, node); player.node.gba = node; - GBASIOSetDriver(&gba->sio, &node->d, SIO_MULTI); - GBASIOSetDriver(&gba->sio, &node->d, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, &node->d, GBA_SIO_NORMAL_32); break; } #endif @@ -342,8 +342,8 @@ void MultiplayerController::detachGame(CoreController* controller) { case mPLATFORM_GBA: { GBA* gba = static_cast(thread->core->board); GBASIOLockstepNode* node = reinterpret_cast(gba->sio.drivers.multiplayer); - GBASIOSetDriver(&gba->sio, nullptr, SIO_MULTI); - GBASIOSetDriver(&gba->sio, nullptr, SIO_NORMAL_32); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_MULTI); + GBASIOSetDriver(&gba->sio, nullptr, GBA_SIO_NORMAL_32); if (node) { GBASIOLockstepDetachNode(&m_gbaLockstep, node); delete node; From ff2dfeb5164a3bd93a6fd517e00ad0d35dcfa32a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:02:49 -0700 Subject: [PATCH 070/148] Util: Clean up VFileOpen backing a bit more --- CMakeLists.txt | 4 +++- include/mgba-util/vfs.h | 12 +++++++----- src/core/flags.h.in | 8 ++++++++ src/platform/3ds/CMakeLists.txt | 1 + src/platform/switch/CMakeLists.txt | 2 +- src/platform/wii/CMakeLists.txt | 2 +- src/util/vfs.c | 4 +++- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3767bae8b..8b8262b8b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,7 @@ elseif(BUILD_PGO AND PGO_STAGE_2) endif() # Platform support +set(OS_DEFINES) if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) @@ -220,6 +221,7 @@ if(WIN32) endif() endif() list(APPEND OS_LIB ws2_32 shlwapi) + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND 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}) @@ -230,6 +232,7 @@ elseif(UNIX) add_definitions(-D_GNU_SOURCE) endif() + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND 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) source_group("POSIX-specific code" FILES ${OS_SRC}) @@ -858,7 +861,6 @@ 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() diff --git a/include/mgba-util/vfs.h b/include/mgba-util/vfs.h index 004dbd685..0279fb755 100644 --- a/include/mgba-util/vfs.h +++ b/include/mgba-util/vfs.h @@ -66,11 +66,18 @@ struct VDir { }; struct VFile* VFileOpen(const char* path, int flags); +#endif +#ifdef ENABLE_VFS_FD struct VFile* VFileOpenFD(const char* path, int flags); struct VFile* VFileFromFD(int fd); #endif +#ifdef ENABLE_VFS_FILE +struct VFile* VFileFOpen(const char* path, const char* mode); +struct VFile* VFileFromFILE(FILE* file); +#endif + struct VFile* VFileFromMemory(void* mem, size_t size); struct VFile* VFileFromConstMemory(const void* mem, size_t size); struct VFile* VFileMemChunk(const void* mem, size_t size); @@ -97,11 +104,6 @@ struct VDir* VDeviceList(void); bool VDirCreate(const char* path); struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*)); struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode); - -#ifdef ENABLE_VFS_FILE -struct VFile* VFileFOpen(const char* path, const char* mode); -struct VFile* VFileFromFILE(FILE* file); -#endif #endif void separatePath(const char* path, char* dirname, char* basename, char* extension); diff --git a/src/core/flags.h.in b/src/core/flags.h.in index b91e1907a..3507df032 100644 --- a/src/core/flags.h.in +++ b/src/core/flags.h.in @@ -65,6 +65,14 @@ #cmakedefine ENABLE_VFS #endif +#ifndef ENABLE_VFS_FD +#cmakedefine ENABLE_VFS_FD +#endif + +#ifndef ENABLE_VFS_FILE +#cmakedefine ENABLE_VFS_FILE +#endif + // USE flags #ifndef USE_DISCORD_RPC diff --git a/src/platform/3ds/CMakeLists.txt b/src/platform/3ds/CMakeLists.txt index 2073e13fe..a52c5e81e 100644 --- a/src/platform/3ds/CMakeLists.txt +++ b/src/platform/3ds/CMakeLists.txt @@ -31,6 +31,7 @@ source_group("3DS-specific code" FILES ${OS_SRC}) if(ENABLE_VFS_3DS) list(APPEND OS_DEFINES ENABLE_VFS_3DS) else() + list(APPEND OS_DEFINES ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) endif() set(VFS_SRC ${VFS_SRC} PARENT_SCOPE) diff --git a/src/platform/switch/CMakeLists.txt b/src/platform/switch/CMakeLists.txt index 55db05d12..66e5b6f4a 100644 --- a/src/platform/switch/CMakeLists.txt +++ b/src/platform/switch/CMakeLists.txt @@ -4,7 +4,7 @@ find_program(BUILD_ROMFS build_romfs) find_library(GLAPI_LIBRARY glapi REQUIRED) find_library(EGL_LIBRARY EGL REQUIRED) -set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64) +set(OS_DEFINES _GNU_SOURCE IOAPI_NO_64 ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) list(APPEND GUI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/gui-font.c) diff --git a/src/platform/wii/CMakeLists.txt b/src/platform/wii/CMakeLists.txt index f8e6984f4..a5f77e84d 100644 --- a/src/platform/wii/CMakeLists.txt +++ b/src/platform/wii/CMakeLists.txt @@ -8,7 +8,7 @@ if(WIIDRC_LIBRARY) add_definitions(-DWIIDRC) endif() -set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER) +set(OS_DEFINES _GNU_SOURCE COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64 FIXED_ROM_BUFFER ENABLE_VFS_FD) list(APPEND VFS_SRC ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-dirent.c ${PROJECT_SOURCE_DIR}/src/util/vfs/vfs-devlist.c) include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/util/vfs.c b/src/util/vfs.c index 74a96b369..a14100bbf 100644 --- a/src/util/vfs.c +++ b/src/util/vfs.c @@ -96,8 +96,10 @@ struct VFile* VFileOpen(const char* path, int flags) { vf->seek(vf, vf->size(vf), SEEK_SET); } return vf; -#else +#elif defined(ENABLE_VFS_FD) return VFileOpenFD(path, flags); +#else +#error "Can't build VFS subsystem without a VFile backend" #endif } From 8106fbf51c05878050747842722b6f544edb45d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:05:27 -0700 Subject: [PATCH 071/148] Libretro: Fix build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b8262b8b..1742cb805 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -981,7 +981,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_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC} ${VFS_SRC}) add_dependencies(${BINARY_NAME}_libretro ${BINARY_NAME}-version-info) 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};ENABLE_VFS;MINIMAL_CORE=2") target_link_libraries(${BINARY_NAME}_libretro ${OS_LIB}) From e5333f4e7c92d9a12c853cbcbedaa3f190342579 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:32:33 -0700 Subject: [PATCH 072/148] GBA Audio: Call audioRateChanged on reset if applicable --- src/gba/audio.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/gba/audio.c b/src/gba/audio.c index c84d6ce27..e6b495382 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -43,6 +43,7 @@ void GBAAudioInit(struct GBAAudio* audio, size_t samples) { audio->forceDisableChA = false; audio->forceDisableChB = false; audio->masterVolume = GBA_AUDIO_VOLUME_MAX; + audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; } void GBAAudioReset(struct GBAAudio* audio) { @@ -81,7 +82,12 @@ void GBAAudioReset(struct GBAAudio* audio) { audio->chBLeft = false; audio->chBTimer = false; audio->enable = false; - audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; + if (audio->sampleInterval != GBA_ARM7TDMI_FREQUENCY / 0x8000) { + audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / 0x8000; + if (audio->p->stream && audio->p->stream->audioRateChanged) { + audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); + } + } audio->psg.sampleInterval = audio->sampleInterval; } From 1ca75446c6f4f3c26c4593c03ff4a8f26330fa42 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 7 May 2024 22:32:58 -0700 Subject: [PATCH 073/148] Libretro: Fix audio resampling after GBA fix --- src/platform/libretro/libretro.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index d2565a42b..8191d4868 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -53,6 +53,7 @@ static retro_set_sensor_state_t sensorStateCallback; static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args); static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); +static void _audioRateChanged(struct mAVStream*, unsigned rate); static void _setRumble(struct mRumble* rumble, int enable); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); @@ -498,10 +499,11 @@ void retro_init(void) { logger.log = GBARetroLog; mLogSetDefaultLogger(&logger); - stream.videoDimensionsChanged = 0; - stream.postAudioFrame = 0; - stream.postAudioBuffer = _postAudioBuffer; - stream.postVideoFrame = 0; + stream.videoDimensionsChanged = NULL; + stream.postAudioFrame = NULL; + stream.postAudioBuffer = NULL; + stream.postVideoFrame = NULL; + stream.audioRateChanged = _audioRateChanged; imageSource.startRequestImage = _startImage; imageSource.stopRequestImage = _stopImage; @@ -913,13 +915,14 @@ bool retro_load_game(const struct retro_game_info* game) { * using the regular stream-set _postAudioBuffer() * callback with a fixed buffer size, which seems * (historically) to produce adequate results */ - core->setAVStream(core, &stream); + stream.postAudioBuffer = _postAudioBuffer; audioSampleBufferSize = GB_SAMPLES * 2; audioSampleBuffer = malloc(audioSampleBufferSize * sizeof(int16_t)); audioSamplesPerFrameAvg = GB_SAMPLES; core->setAudioBufferSize(core, GB_SAMPLES); } + core->setAVStream(core, &stream); core->setPeripheral(core, mPERIPH_RUMBLE, &rumble); core->setPeripheral(core, mPERIPH_ROTATION, &rotation); @@ -1250,6 +1253,13 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff } } +static void _audioRateChanged(struct mAVStream* stream, unsigned rate) { + UNUSED(stream); + struct retro_system_av_info info; + retro_get_system_av_info(&info); + environCallback(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info); +} + static void _setRumble(struct mRumble* rumble, int enable) { UNUSED(rumble); if (!rumbleInitDone) { From e73f302aee38323ee77a5242c84ae2f87298daf0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2024 17:06:53 -0700 Subject: [PATCH 074/148] Libretro: Attempt to fix #3202 --- src/platform/libretro/libretro.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 8191d4868..38fbcdbb9 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -744,7 +744,7 @@ static void _setupMaps(struct mCore* core) { #ifdef M_CORE_GB if (core->platform(core) == mPLATFORM_GB) { struct GB* gb = core->board; - struct retro_memory_descriptor descs[11]; + struct retro_memory_descriptor descs[12]; struct retro_memory_map mmaps; memset(descs, 0, sizeof(descs)); @@ -814,8 +814,16 @@ static void _setupMaps(struct mCore* core) { if (savedataSize) { descs[i].ptr = savedata; descs[i].start = GB_BASE_EXTERNAL_RAM; - descs[i].len = savedataSize; + descs[i].len = savedataSize < GB_SIZE_EXTERNAL_RAM ? savedataSize : GB_SIZE_EXTERNAL_RAM; i++; + + if ((savedataSize & ~0xFF) > GB_SIZE_EXTERNAL_RAM) { + descs[i].ptr = savedata; + descs[i].offset = GB_SIZE_EXTERNAL_RAM; + descs[i].start = GB_BASE_EXTERNAL_RAM; + descs[i].len = savedataSize - GB_SIZE_EXTERNAL_RAM; + i++; + } } if (gb->model >= GB_MODEL_CGB) { @@ -825,7 +833,6 @@ static void _setupMaps(struct mCore* core) { descs[i].ptr = gb->memory.wram + 0x2000; descs[i].start = 0x10000; descs[i].len = GB_SIZE_WORKING_RAM - 0x2000; - descs[i].select = 0xFFFFA000; i++; } From f6851eba95a94d7018f4744ae11ce63011a27e2b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 8 May 2024 17:26:54 -0700 Subject: [PATCH 075/148] Libretro: Fix mapped high SRAM start address --- src/platform/libretro/libretro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 38fbcdbb9..b7d7d8243 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -820,7 +820,7 @@ static void _setupMaps(struct mCore* core) { if ((savedataSize & ~0xFF) > GB_SIZE_EXTERNAL_RAM) { descs[i].ptr = savedata; descs[i].offset = GB_SIZE_EXTERNAL_RAM; - descs[i].start = GB_BASE_EXTERNAL_RAM; + descs[i].start = 0x16000; descs[i].len = savedataSize - GB_SIZE_EXTERNAL_RAM; i++; } From 92b67f960c447296f8693e7e0485156e91a48b77 Mon Sep 17 00:00:00 2001 From: Evrins Hu Date: Sat, 11 May 2024 10:46:28 +0800 Subject: [PATCH 076/148] doc: update readme in zh_cn --- README_ZH_CN.md | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/README_ZH_CN.md b/README_ZH_CN.md index ab725694c..1991e2d1d 100644 --- a/README_ZH_CN.md +++ b/README_ZH_CN.md @@ -5,7 +5,9 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 可在以下网址找到最新新闻和下载:[mgba.io](https://mgba.io/)。 -[![Build status](https://travis-ci.org/mgba-emu/mgba.svg?branch=master)](https://travis-ci.org/mgba-emu/mgba) +[![Build status](https://buildbot.mgba.io/badges/build-win32.svg)](https://buildbot.mgba.io) +[![Translation status](https://hosted.weblate.org/widgets/mgba/-/svg-badge.svg)](https://hosted.weblate.org/engage/mgba) + 功能 -------- @@ -13,7 +15,7 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - 支持高精确的 Game Boy Advance 硬件[[1]](#missing)。 - 支持 Game Boy/Game Boy Color 硬件。 - 快速模拟:已知即使在低端硬件(例如上网本)上也能够全速运行。 -- 用于重型和轻型前端的 Qt 和 SDL 端口。 +- 可用于重型和轻型前端的 Qt 和 SDL 移植。 - 支持本地(同一台计算机)链接电缆。 - 存档类型检测,即使是闪存大小也可检测[[2]](#flashdetect)。 - 支持附带有运动传感器和振动机制的卡带(仅适用于游戏控制器)。 @@ -21,6 +23,7 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - 支持《我们的太阳》系列游戏的太阳能传感器。 - 支持 Game Boy 相机和 Game Boy 打印机。 - 内置 BIOS 执行,并具有加载外部 BIOS 文件的功能。 +- 支持使用 Lua 编写脚本 - 支持 Turbo/快进功能(按住 Tab 键)。 - 支持倒带(按住反引号键)。 - 支持跳帧,最多可配置 10 级。 @@ -32,10 +35,11 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - 可重新映射键盘和游戏手柄的控制键。 - 支持从 ZIP 和 7z 文件中加载。 - 支持 IPS、UPS 和 BPS 补丁。 -- 支持通过命令行界面和 GDB 远程支持进行游戏调试,兼容 IDA Pro。 +- 支持通过命令行界面和 GDB 远程支持进行游戏调试,兼容 Ghidra 和 IDA Pro。 - 支持可配置的模拟倒带。 - 支持载入和导出 GameShark 和 Action Replay 快照。 - 适用于 RetroArch/Libretro 和 OpenEmu 的内核。 +- 社区支持的多种语言翻译 [Weblate](https://hosted.weblate.org/engage/mgba). - 许许多多的小玩意。 #### Game Boy 映射器(mapper) @@ -51,9 +55,10 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - MBC5+振动 - MBC7 - Wisdom Tree(未授权) +- NT "old type" 1 and 2 (未授权多合一卡带) +- NT "new type" (未授权 MBC5-like) - Pokémon Jade/Diamond(未授权) -- BBD(未授权、类 MBC5) -- Hitek(未授权、类 MBC5) +- Sachen MMC1 (未授权) 部分支持以下 mapper: @@ -63,6 +68,11 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - TAMA5(缺少 RTC 支持) - HuC-1(缺少 IR 支持) - HuC-3(缺少 IR 和 RTC 支持) +- Sachen MMC2 (缺少备用接线支持) +- BBD (缺少图标切换) +- Hitek (缺少图标切换) +- GGB-81 (缺少图标切换) +- Li Cheng (缺少图标切换) ### 计划加入的功能 @@ -70,7 +80,6 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - 支持 Dolphin/JOY 总线链接电缆。 - MP2k 音频混合,获得比硬件更高质量的声音。 - 支持针对工具辅助竞速(Tool-Assisted Speedrun)的重录功能。 -- 支持 Lua 脚本。 - 全方位的调试套件。 - 支持无线适配器。 @@ -112,17 +121,19 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 编译 --------- -编译需要使用 CMake 3.1 或更新版本。已知 GCC 和 Clang 都可以编译 mGBA,而 Visual Studio 2013 和更旧的版本则无法编译。我们即将实现对 Visual Studio 2015 或更新版本的支持。 +编译需要使用 CMake 3.1 或更新版本。已知 GCC , Clang 和 Visual Studio 2013 都可以编译 mGBA。 #### Docker 构建 对于大多数平台来说,建议使用 Docker 进行构建。我们提供了多个 Docker 映像,其中包含在多个平台上构建 mGBA 所需的工具链和依赖项。 +注意: 如果你是用的是 Widnows 10 之前的旧版本 Windows 系统, 你可能需要配置你的 Docker 使用 VirtualBox 共享文件夹以正确映射你当前 mGBA 检出目录到 Docker 镜像中的工作目录. 详细细节参见 issue [#1985](https://mgba.io/i/1985) + 要使用 Docker 映像构建 mGBA,只需在 mGBA 的签出(checkout)根目录中运行以下命令: docker run --rm -t -v $PWD:/home/mgba/src mgba/windows:w32 -此命令将生成 `build-win32` 目录。将 `mgba/windows:w32` 替换为其他平台上的 Docker 映像,会生成相应的其他目录。Docker Hub 上提供了以下 Docker 映像: +启动 Docker 容器之后, 此命令将生成 `build-win32` 目录, 此目录中包含编译产物。将 `mgba/windows:w32` 替换为其他平台上的 Docker 映像,会生成相应的其他目录。Docker Hub 上提供了以下 Docker 映像: - mgba/3ds - mgba/switch @@ -135,6 +146,8 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 - mgba/windows:w32 - mgba/windows:w64 +如果你希望加速编译过程, 可以考虑添加编译选项 `-e MAKEFLAGS=-jN`, 使用 `N` 个 CPU 核心来并行构建 mGBA + #### *nix 构建 要在基于 Unix 的系统上使用 CMake 进行构建,推荐执行以下命令: @@ -147,7 +160,7 @@ mGBA 是一个运行 Game Boy Advance 游戏的模拟器。mGBA 的目标是比 这些命令将构建 mGBA 并将其安装到 `/usr/bin` 和 `/usr/lib` 中。系统会自动检测已安装的依赖项,如果未找到依赖项,则会在提示找不到依赖项的情况下运行 `cmake` 命令,并显示已被禁用的功能。 -如果您使用的是 MacOS,则步骤略有不同。假设您使用的是自制软件包管理器,建议使用以下命令来获取依赖项并进行构建: +如果您使用的是 MacOS,则步骤略有不同。假设您使用的 homebrew 软件包管理器,建议使用以下命令来获取依赖项并进行构建: brew install cmake ffmpeg libzip qt5 sdl2 libedit pkg-config mkdir build @@ -220,10 +233,12 @@ mGBA 没有硬性的依赖项,但是特定功能需要以下可选的依赖项 - libzip 或 zlib:载入储存在 ZIP 文件中的 ROM 的所需依赖项。 - SQLite3:游戏数据库的所需依赖项 - libelf:ELF 载入的所需依赖项 +- Lua: 脚本支持 +- json-c: 脚本 `storage` API 支持 SQLite3、libpng 以及 zlib 已包含在模拟器中,因此不需要先对这些依赖项进行外部编译。 -Footnotes +脚注 --------- [1] 目前缺失的功能有 @@ -232,7 +247,7 @@ Footnotes [2] 闪存大小检测在某些情况下不起作用。 这些可以在运行时中进行配置,但如果遇到此类情况,建议提交错误。 -[3] 仅 Qt 端口需要 10.9。应该可以在 10.7 或更早版本上构建或运行 Qt 端口,但这类操作不受官方支持。已知 SDL 端口可以在 10.5 上运行,并且可能能够在旧版本上运行。 +[3] 仅 Qt 移植需要 10.9。应该可以在 10.7 或更早版本上构建或运行 Qt 移植,但这类操作不受官方支持。已知 SDL 移植可以在 10.5 上运行,并且可能能够在旧版本上运行。 [downloads]: http://mgba.io/downloads.html [source]: https://github.com/mgba-emu/mgba/ @@ -240,7 +255,7 @@ Footnotes 版权 --------- -mGBA 版权 © 2013 – 2020 Jeffrey Pfau。基于 [Mozilla 公共许可证版本 2.0](https://www.mozilla.org/MPL/2.0/) 许可证分发。分发的 LICENSE 文件中提供了许可证的副本。 +mGBA 版权 © 2013 – 2023 Jeffrey Pfau。基于 [Mozilla 公共许可证版本 2.0](https://www.mozilla.org/MPL/2.0/) 许可证分发。分发的 LICENSE 文件中提供了许可证的副本。 mGBA 包含以下第三方库: From 6e3a00e0814d4f3a6af080bfdbb9c0d073f95da9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 11 May 2024 21:40:56 -0700 Subject: [PATCH 077/148] Qt: Fix crash when applying changes to GB I/O registers in I/O view --- CHANGES | 1 + src/platform/qt/IOViewer.cpp | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 15f85e7f0..899b3391a 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts + - Qt: Fix crash when applying changes to GB I/O registers in I/O view - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index 531ba6955..ef995921c 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1687,7 +1687,20 @@ void IOViewer::bitFlipped() { void IOViewer::writeback() { { CoreController::Interrupter interrupter(m_controller); - GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + switch (m_controller->platform()) { +#ifdef M_CORE_GB + case mPLATFORM_GB: + GBIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + break; +#endif +#ifdef M_CORE_GBA + case mPLATFORM_GBA: + GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + break; +#endif + case mPLATFORM_NONE: + return; + } } updateRegister(); } From b723ed47645c0d87c3a95197de12bd17648570a5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2024 02:48:05 -0700 Subject: [PATCH 078/148] Qt: Better fix for I/O viewer --- src/platform/qt/IOViewer.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index ef995921c..90a97fdbb 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1687,19 +1687,14 @@ void IOViewer::bitFlipped() { void IOViewer::writeback() { { CoreController::Interrupter interrupter(m_controller); - switch (m_controller->platform()) { -#ifdef M_CORE_GB - case mPLATFORM_GB: - GBIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + mCore* core = m_controller->thread()->core; + switch (m_width) { + case 0: + core->busWrite8(core, m_base + m_register, m_value); break; -#endif -#ifdef M_CORE_GBA - case mPLATFORM_GBA: - GBAIOWrite(static_cast(m_controller->thread()->core->board), m_register, m_value); + case 1: + core->busWrite16(core, m_base + m_register, m_value); break; -#endif - case mPLATFORM_NONE: - return; } } updateRegister(); From 8b1efec1161411c57d9643f4d437fd9bbdc4a5fb Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 12 May 2024 02:51:07 -0700 Subject: [PATCH 079/148] Qt: Fix LCDC background priority/enable bit being mis-mapped in I/O view --- CHANGES | 1 + src/platform/qt/IOViewer.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 899b3391a..60c1a61fb 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts - Qt: Fix crash when applying changes to GB I/O registers in I/O view + - Qt: Fix LCDC background priority/enable bit being mis-mapped in I/O view - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) diff --git a/src/platform/qt/IOViewer.cpp b/src/platform/qt/IOViewer.cpp index 90a97fdbb..9b44af04f 100644 --- a/src/platform/qt/IOViewer.cpp +++ b/src/platform/qt/IOViewer.cpp @@ -1323,7 +1323,7 @@ const QList& IOViewer::registerDescriptions(mPlat }); // 0xFF40: LCDC regGB.append({ - { tr("Background enable/priority"), 1 }, + { tr("Background enable/priority"), 0 }, { tr("Enable sprites"), 1 }, { tr("Double-height sprites"), 2 }, { tr("Background tile map"), 3, 1, { From 649be1b5056ad8c99e00c7d8d308cfc9fe8bcd5c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 21 May 2024 23:02:35 -0700 Subject: [PATCH 080/148] SDL: Properly disable SDL build if libsdl isn't found (fixes #3213) --- src/platform/sdl/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 38e328d73..d62c74694 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -40,6 +40,7 @@ endif() if (NOT SDL2_FOUND AND NOT SDL_FOUND) set(SDL_FOUND OFF PARENT_SCOPE) + set(BUILD_SDL OFF PARENT_SCOPE) return() endif() From 8c0a28477b23db01c0ce8ec916542097c1aa05f5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 01:31:25 -0700 Subject: [PATCH 081/148] GBA SIO: Improve MULTI timing --- src/gba/sio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gba/sio.c b/src/gba/sio.c index beb8efdfe..4ffeb6388 100644 --- a/src/gba/sio.c +++ b/src/gba/sio.c @@ -12,10 +12,10 @@ mLOG_DEFINE_CATEGORY(GBA_SIO, "GBA Serial I/O", "gba.sio"); const int GBASIOCyclesPerTransfer[4][MAX_GBAS] = { - { 38326, 73003, 107680, 142356 }, - { 9582, 18251, 26920, 35589 }, - { 6388, 12167, 17947, 23726 }, - { 3194, 6075, 8973, 11863 } + { 31976, 63427, 94884, 125829 }, + { 8378, 16241, 24104, 31457 }, + { 5750, 10998, 16241, 20972 }, + { 3140, 5755, 8376, 10486 } }; static struct GBASIODriver* _lookupDriver(struct GBASIO* sio, enum GBASIOMode mode) { From 2b394e1e26a38359c731a6db507fea6559723cce Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 24 May 2024 21:17:10 -0700 Subject: [PATCH 082/148] GBA SIO: Remove erroneous RCNT setting --- src/gba/sio/lockstep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gba/sio/lockstep.c b/src/gba/sio/lockstep.c index 4f12610f1..ba620911e 100644 --- a/src/gba/sio/lockstep.c +++ b/src/gba/sio/lockstep.c @@ -105,7 +105,6 @@ bool GBASIOLockstepNodeLoad(struct GBASIODriver* driver) { switch (node->mode) { case GBA_SIO_MULTI: node->d.writeRegister = GBASIOLockstepNodeMultiWriteRegister; - node->d.p->rcnt |= 3; ATOMIC_ADD(node->p->attachedMulti, 1); node->d.p->siocnt = GBASIOMultiplayerSetReady(node->d.p->siocnt, node->p->attachedMulti == node->p->d.attached); if (node->id) { From 3a3ebb5dc7a1dc6f8f893093d213a637acfc4024 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 25 May 2024 01:33:26 -0700 Subject: [PATCH 083/148] Third-Party: Cherry-pick rapidjson buildfix --- src/third-party/discord-rpc/include/rapidjson/document.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/third-party/discord-rpc/include/rapidjson/document.h b/src/third-party/discord-rpc/include/rapidjson/document.h index e3e20dfbd..b0f1f70be 100644 --- a/src/third-party/discord-rpc/include/rapidjson/document.h +++ b/src/third-party/discord-rpc/include/rapidjson/document.h @@ -316,8 +316,6 @@ struct GenericStringRef { 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; } From c7b5d1054644b31d3fcd7b60d471948eb33648ed Mon Sep 17 00:00:00 2001 From: oltolm Date: Sat, 25 May 2024 14:11:53 +0200 Subject: [PATCH 084/148] fix Qt deprecation warnings --- src/platform/qt/ConfigController.cpp | 4 ++++ src/platform/qt/FrameView.cpp | 8 ++++++++ src/platform/qt/MapView.cpp | 5 +++++ src/platform/qt/MemoryModel.cpp | 10 ++++++++++ src/platform/qt/SaveConverter.cpp | 2 +- src/platform/qt/Swatch.cpp | 5 +++++ src/platform/qt/TilePainter.cpp | 5 +++++ src/platform/qt/Window.cpp | 8 ++++++++ src/platform/qt/main.cpp | 6 ++++++ 9 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 91ecf8e7a..ccec60432 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -318,7 +318,11 @@ void ConfigController::setOption(const char* key, const char* value) { } void ConfigController::setOption(const char* key, const QVariant& value) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (value.type() == QVariant::Bool) { +#else + if (value.typeId() == QMetaType::Type::Bool) { +#endif setOption(key, value.toBool()); return; } diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index 2fe37e64c..ada077d74 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -505,12 +505,20 @@ bool FrameView::eventFilter(QObject*, QEvent* event) { QPointF pos; switch (event->type()) { case QEvent::MouseButtonPress: +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) pos = static_cast(event)->localPos(); +#else + pos = static_cast(event)->position(); +#endif pos /= m_ui.magnification->value(); selectLayer(pos); return true; case QEvent::MouseButtonDblClick: +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) pos = static_cast(event)->localPos(); +#else + pos = static_cast(event)->position(); +#endif pos /= m_ui.magnification->value(); disableLayer(pos); return true; diff --git a/src/platform/qt/MapView.cpp b/src/platform/qt/MapView.cpp index a00c63c0e..aef8c58b7 100644 --- a/src/platform/qt/MapView.cpp +++ b/src/platform/qt/MapView.cpp @@ -161,8 +161,13 @@ bool MapView::eventFilter(QObject*, QEvent* event) { if (event->type() != QEvent::MouseButtonPress) { return false; } +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = static_cast(event)->x(); int y = static_cast(event)->y(); +#else + int x = static_cast(event)->position().x(); + int y = static_cast(event)->position().y(); +#endif x /= 8 * m_ui.magnification->value(); y /= 8 * m_ui.magnification->value(); selectTile(x, y); diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 538ce2c51..9bcf54223 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -511,8 +511,13 @@ void MemoryModel::wheelEvent(QWheelEvent* event) { } void MemoryModel::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { +#else + if (event->position().x() < m_margins.left() || event->position().y() < m_margins.top() || + event->position().x() > size().width() - m_margins.right()) { +#endif m_selection = qMakePair(0, 0); return; } @@ -540,8 +545,13 @@ void MemoryModel::mousePressEvent(QMouseEvent* event) { } void MemoryModel::mouseMoveEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { +#else + if (event->position().x() < m_margins.left() || event->position().y() < m_margins.top() || + event->position().x() > size().width() - m_margins.right()) { +#endif return; } diff --git a/src/platform/qt/SaveConverter.cpp b/src/platform/qt/SaveConverter.cpp index d16eeeea4..974f31af0 100644 --- a/src/platform/qt/SaveConverter.cpp +++ b/src/platform/qt/SaveConverter.cpp @@ -281,7 +281,7 @@ void SaveConverter::detectFromHeaders(std::shared_ptr vf) { } free(data); } - } else if (buffer.left(gsv.count()) == gsv) { + } else if (buffer.left(gsv.size()) == gsv) { size_t size; void* data = GBASavedataGSVGetPayload(*vf, &size, nullptr, false); if (data) { diff --git a/src/platform/qt/Swatch.cpp b/src/platform/qt/Swatch.cpp index 3eb85d780..f4a9ad7c3 100644 --- a/src/platform/qt/Swatch.cpp +++ b/src/platform/qt/Swatch.cpp @@ -56,8 +56,13 @@ void Swatch::paintEvent(QPaintEvent*) { } void Swatch::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = event->x() / (m_size + 1); int y = event->y() / (m_size + 1); +#else + int x = event->position().x() / (m_size + 1); + int y = event->position().y() / (m_size + 1); +#endif emit indexPressed(y * m_dims.width() + x); } diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index c27ade72e..fcb62d420 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -39,8 +39,13 @@ void TilePainter::resizeEvent(QResizeEvent*) { } void TilePainter::mousePressEvent(QMouseEvent* event) { +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) int x = event->x() / m_size; int y = event->y() / m_size; +#else + int x = event->position().x() / m_size; + int y = event->position().y() / m_size; +#endif int index = y * (width() / m_size) + x; if (index < m_tileCount) { emit indexPressed(index); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index c75a163ef..a5576c1c9 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -918,7 +918,11 @@ void Window::gameStarted() { #ifdef M_CORE_GBA if (m_controller->platform() == mPLATFORM_GBA) { QVariant eCardList = m_config->takeArgvOption(QString("ecard")); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (eCardList.canConvert(QMetaType::QStringList)) { +#else + if (QMetaType::canConvert(eCardList.metaType(), QMetaType(QMetaType::QStringList))) { +#endif m_controller->scanCards(eCardList.toStringList()); } } @@ -2149,7 +2153,11 @@ void Window::setController(CoreController* controller, const QString& fname) { #ifdef M_CORE_GBA if (m_controller->platform() == mPLATFORM_GBA) { QVariant mb = m_config->takeArgvOption(QString("mb")); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (mb.canConvert(QMetaType::QString)) { +#else + if (QMetaType::canConvert(mb.metaType(), QMetaType(QMetaType::QString))) { +#endif m_controller->replaceGame(mb.toString()); } } diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 62967bf1a..f98d2cd88 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -90,7 +90,9 @@ int main(int argc, char* argv[]) { QApplication::setApplicationName(projectName); QApplication::setApplicationVersion(projectVersion); +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); +#endif #ifdef BUILD_GLES2 QSurfaceFormat format; @@ -109,7 +111,11 @@ int main(int argc, char* argv[]) { #endif QTranslator qtTranslator; +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { +#else + if (qtTranslator.load(locale, "qt", "_", QLibraryInfo::path(QLibraryInfo::TranslationsPath))) { +#endif application.installTranslator(&qtTranslator); } From b7729c9e80736e34a46ff9f38fcaf0d1ed97a7b2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 27 May 2024 02:57:11 -0700 Subject: [PATCH 085/148] GBA Video: Add special circlular window handling in OpenGL renderer --- CHANGES | 1 + include/mgba/internal/gba/renderers/gl.h | 2 + src/gba/renderers/gl.c | 138 ++++++++++++++++++++++- 3 files changed, 139 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 60c1a61fb..3d477b022 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - GBA Video: Add special circlular window handling in OpenGL renderer - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) - mGUI: Persist fast forwarding after closing menu (fixes mgba.io/i/2414) diff --git a/include/mgba/internal/gba/renderers/gl.h b/include/mgba/internal/gba/renderers/gl.h index 14cf11678..74baec41e 100644 --- a/include/mgba/internal/gba/renderers/gl.h +++ b/include/mgba/internal/gba/renderers/gl.h @@ -118,6 +118,8 @@ enum { GBA_GL_WIN_FLAGS, GBA_GL_WIN_WIN0, GBA_GL_WIN_WIN1, + GBA_GL_WIN_CIRCLE0, + GBA_GL_WIN_CIRCLE1, GBA_GL_FINALIZE_SCALE = 2, GBA_GL_FINALIZE_LAYERS, diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index c80da2bcb..afc9c54ac 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -486,6 +486,8 @@ static const struct GBAVideoGLUniform _uniformsWindow[] = { { "flags", GBA_GL_WIN_FLAGS, }, { "win0", GBA_GL_WIN_WIN0, }, { "win1", GBA_GL_WIN_WIN1, }, + { "circle0", GBA_GL_WIN_CIRCLE0, }, + { "circle1", GBA_GL_WIN_CIRCLE1, }, { 0 } }; @@ -496,6 +498,8 @@ static const char* const _renderWindow = "uniform ivec3 flags;\n" "uniform ivec4 win0[160];\n" "uniform ivec4 win1[160];\n" + "uniform vec3 circle0;\n" + "uniform vec3 circle1;\n" "OUT(0) out ivec4 window;\n" "bool crop(vec4 windowParams) {\n" @@ -529,13 +533,20 @@ static const char* const _renderWindow = " return vec4(mix(bottom.xy, top.xy, fract(texCoord.y)), top.zw);\n" "}\n" + "bool test(vec3 circle, vec4 top, vec4 bottom) {\n" + " if (circle.z > 0) {\n" + " return distance(circle.xy, texCoord.xy) <= circle.z;\n" + " }\n" + " return crop(interpolate(top, bottom));\n" + "}\n" + "void main() {\n" " ivec4 windowFlags = ivec4(flags.z, blend, 0);\n" " int top = int(texCoord.y);\n" " int bottom = max(top - 1, 0);\n" - " if ((dispcnt & 0x20) != 0 && crop(interpolate(vec4(win0[top]), vec4(win0[bottom])))) { \n" + " if ((dispcnt & 0x20) != 0 && test(circle0, vec4(win0[top]), vec4(win0[bottom]))) {\n" " windowFlags.x = flags.x;\n" - " } else if ((dispcnt & 0x40) != 0 && crop(interpolate(vec4(win1[top]), vec4(win1[bottom])))) {\n" + " } else if ((dispcnt & 0x40) != 0 && test(circle1, vec4(win1[top]), vec4(win1[bottom]))) {\n" " windowFlags.x = flags.y;\n" " }\n" " window = windowFlags;\n" @@ -1924,6 +1935,127 @@ void GBAVideoGLRendererDrawBackgroundMode5(struct GBAVideoGLRenderer* renderer, glDrawBuffers(1, (GLenum[]) { GL_COLOR_ATTACHMENT0 }); } +static void _detectCircle(struct GBAVideoGLRenderer* renderer, int y, int window) { + int lastStart = 0; + int lastEnd = 0; + + int startX = 0; + int endX = 0; + + int firstY = -1; + float centerX; + float centerY = -1; + float radius = 0; + bool invalid = false; + + int i; + for (i = renderer->firstY; i <= y; ++i) { + lastStart = startX; + lastEnd = endX; + startX = renderer->winNHistory[window][i * 4]; + endX = renderer->winNHistory[window][i * 4 + 1]; + int startY = renderer->winNHistory[window][i * 4 + 2]; + int endY = renderer->winNHistory[window][i * 4 + 3]; + + if (startX == endX || i < startY || i >= endY) { + if (firstY >= 0) { + // The bottom edge of the circle + centerY = (firstY + i) / 2.f; + firstY = -1; + } + continue; + } + if (lastEnd - lastStart <= 0) { + continue; + } + + // The previous segment was non-zero + if (startX >= GBA_VIDEO_HORIZONTAL_PIXELS) { + invalid = true; + break; + } + + int startDiff = lastStart - startX; + int endDiff = endX - lastEnd; + // Make sure the slopes match, otherwise this isn't a circle + if (startDiff - endDiff < -1 || startDiff - endDiff > 1) { + invalid = true; + break; + } + + if (startX < lastStart) { + centerX = (startX + endX) / 2.f; + if (radius > 0) { + // We found two separate shapes, which the interpolation can't handle + invalid = true; + break; + } + } else if (startX > lastStart && radius <= 0) { + radius = (lastEnd - lastStart) / 2.f; + } + + if (firstY < 0 && i - 1 >= startY && i - 1 < endY) { + firstY = i - 1; + } + } + + if (radius <= 0) { + invalid = true; + } + if (centerY < 0) { + invalid = true; + } + + // Check validity + for (i = renderer->firstY; i <= y && !invalid; ++i) { + int startX = renderer->winNHistory[window][i * 4]; + int endX = renderer->winNHistory[window][i * 4 + 1]; + int startY = renderer->winNHistory[window][i * 4 + 2]; + int endY = renderer->winNHistory[window][i * 4 + 3]; + + bool xActive = startX < endX; + bool yActive = i >= startY && i < endY; + + if (xActive && yActive) { + // Real window would be active, make sure simulated window would too + if (centerY - i > radius) { + // y is above the radius + invalid = true; + break; + } + if (i - centerY > radius) { + // y is below the radius + invalid = true; + break; + } + + float cosine = fabsf(i - centerY); + float sine = sqrtf(radius * radius - cosine * cosine); + if (fabsf(centerX - sine - startX) <= 1 && fabsf(centerX + sine - endX) <= 1) { + continue; + } + + if (radius >= cosine + 1) { + sine = sqrtf(radius * radius - (cosine + 1) * (cosine + 1)); + if (fabsf(centerX - sine - startX) <= 1 && fabsf(centerX + sine - endX) <= 1) { + continue; + } + } + // y is active on the wrong parts of the scanline + invalid = true; + } else if (centerY - i < radius && i - centerY < radius) { + // Real window would be inactive, make sure simulated window would too + invalid = true; + } + } + + if (invalid) { + glUniform3f(renderer->windowShader.uniforms[GBA_GL_WIN_CIRCLE0 + window], 0, 0, 0); + } else { + glUniform3f(renderer->windowShader.uniforms[GBA_GL_WIN_CIRCLE0 + window], centerX, centerY, radius - 0.499); + } +} + void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { const struct GBAVideoGLShader* shader = &renderer->windowShader; const GLuint* uniforms = shader->uniforms; @@ -1950,6 +2082,8 @@ void GBAVideoGLRendererDrawWindow(struct GBAVideoGLRenderer* renderer, int y) { 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]); + _detectCircle(renderer, y, 0); + _detectCircle(renderer, y, 1); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); break; } From 56023cfd02a1a95c3c9f15b4463ff0c6479550c9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 1 Jun 2024 00:07:19 -0700 Subject: [PATCH 086/148] Core: Fix warnings --- src/core/thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/thread.c b/src/core/thread.c index 0be5f81e2..2462407cc 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -459,11 +459,11 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) { } logger->filter = NULL; - return 0; + THREAD_EXIT(0); } bool mCoreThreadStart(struct mCoreThread* threadContext) { - threadContext->impl = calloc(sizeof(*threadContext->impl), 1); + threadContext->impl = calloc(1, sizeof(*threadContext->impl)); threadContext->impl->state = mTHREAD_INITIALIZED; threadContext->impl->requested = 0; threadContext->logger.p = threadContext; From 942167acdf44a3d99494179a63dfd942ecf725d5 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:17:24 -0700 Subject: [PATCH 087/148] ARM: Backport some CPU table improvements from medusa --- include/mgba/internal/arm/emitter-arm.h | 521 ++++++++++++------------ 1 file changed, 261 insertions(+), 260 deletions(-) diff --git a/include/mgba/internal/arm/emitter-arm.h b/include/mgba/internal/arm/emitter-arm.h index e99a1b7ee..bdea1db8a 100644 --- a/include/mgba/internal/arm/emitter-arm.h +++ b/include/mgba/internal/arm/emitter-arm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014 Jeffrey Pfau +/* Copyright (c) 2013-2024 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 @@ -67,269 +67,270 @@ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \ DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)) -#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \ - DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2)))) +#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2, NAME3) \ + DO_8(DO_INTERLACE( \ + DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))), \ + DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME3))))) #define DECLARE_ARM_SWI_BLOCK(EMITTER) \ DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI)) #define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \ - DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, BX), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ - DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \ - DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \ - DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \ - DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \ - DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \ - DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ - DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ - DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \ - DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \ - DECLARE_ARM_SWI_BLOCK(EMITTER) + /* -00---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \ + /* -01---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \ + /* -02---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \ + /* -03---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \ + /* -04---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \ + /* -05---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \ + /* -06---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \ + /* -07---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \ + /* -08---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \ + /* -09---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \ + /* -0A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \ + /* -0B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \ + /* -0C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \ + /* -0D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \ + /* -0E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \ + /* -0F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \ + /* -10---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \ + /* -10---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \ + /* -10---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \ + /* -10---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -10---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -11---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \ + /* -12---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \ + /* -12---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, BX), \ + /* -12---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \ + /* -12---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \ + /* -12---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -12---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -13---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ + /* -14---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \ + /* -14---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \ + /* -14---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \ + /* -14---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -14---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -15---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \ + /* -16---0- */ DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \ + /* -16---1- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---2- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---3- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---4- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---5- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---6- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---7- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---8- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---9- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---A- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---B- */ DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \ + /* -16---C- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---D- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---E- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -16---F- */ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + /* -17---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \ + /* -18---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \ + /* -19---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \ + /* -1A---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \ + /* -1B---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \ + /* -1C---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \ + /* -1D---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \ + /* -1E---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \ + /* -1F---X- */ DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \ + /* -20---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \ + /* -21---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \ + /* -22---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \ + /* -23---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \ + /* -24---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \ + /* -25---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \ + /* -26---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \ + /* -27---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \ + /* -28---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \ + /* -29---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \ + /* -2A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \ + /* -2B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \ + /* -2C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \ + /* -2D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \ + /* -2E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \ + /* -2F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \ + /* -30---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ + /* -31---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \ + /* -32---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \ + /* -33---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \ + /* -34---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ + /* -35---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \ + /* -36---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \ + /* -37---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \ + /* -38---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \ + /* -39---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \ + /* -3A---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \ + /* -3B---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \ + /* -3C---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \ + /* -3D---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \ + /* -3E---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \ + /* -3F---X- */ DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \ + /* -40---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \ + /* -41---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \ + /* -42---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \ + /* -43---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \ + /* -44---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \ + /* -45---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \ + /* -46---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \ + /* -47---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \ + /* -48---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \ + /* -49---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \ + /* -4A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \ + /* -4B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \ + /* -4C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \ + /* -4D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \ + /* -4E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \ + /* -4F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \ + /* -50---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \ + /* -51---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \ + /* -52---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \ + /* -53---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \ + /* -54---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \ + /* -55---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \ + /* -56---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \ + /* -57---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \ + /* -58---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \ + /* -59---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \ + /* -5A---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \ + /* -5B---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \ + /* -5C---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \ + /* -5D---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \ + /* -5E---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \ + /* -5F---X- */ DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \ + /* -60---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \ + /* -61---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \ + /* -62---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \ + /* -63---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \ + /* -64---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \ + /* -65---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \ + /* -66---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \ + /* -67---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \ + /* -68---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \ + /* -69---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \ + /* -6A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \ + /* -6B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \ + /* -6C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \ + /* -6D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \ + /* -6E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \ + /* -6F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \ + /* -70---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \ + /* -71---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \ + /* -72---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \ + /* -73---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \ + /* -74---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \ + /* -75---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \ + /* -76---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \ + /* -77---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \ + /* -78---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \ + /* -79---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \ + /* -7A---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \ + /* -7B---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \ + /* -7C---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \ + /* -7D---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \ + /* -7E---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \ + /* -7F---X- */ DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \ + /* -80---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \ + /* -81---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \ + /* -82---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \ + /* -83---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \ + /* -84---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \ + /* -85---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \ + /* -86---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \ + /* -87---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \ + /* -88---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \ + /* -89---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \ + /* -8A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \ + /* -8B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \ + /* -8C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \ + /* -8D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \ + /* -8E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \ + /* -8F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \ + /* -90---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \ + /* -91---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \ + /* -92---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \ + /* -93---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \ + /* -94---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \ + /* -95---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \ + /* -96---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \ + /* -97---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \ + /* -98---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \ + /* -99---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \ + /* -9A---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \ + /* -9B---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \ + /* -9C---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \ + /* -9D---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \ + /* -9E---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \ + /* -9F---X- */ DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \ + /* -AX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \ + /* -BX---X- */ DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \ + /* -C0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \ + /* -C1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \ + /* -C2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \ + /* -C3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \ + /* -C4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \ + /* -C5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \ + /* -C6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \ + /* -C7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \ + /* -C8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \ + /* -C9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \ + /* -CA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \ + /* -CB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \ + /* -CC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \ + /* -CD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \ + /* -CE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \ + /* -CF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \ + /* -D0---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \ + /* -D1---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \ + /* -D2---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \ + /* -D3---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \ + /* -D4---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ + /* -D5---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ + /* -D6---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ + /* -D7---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ + /* -D8---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \ + /* -D9---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \ + /* -DA---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \ + /* -DB---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \ + /* -DC---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \ + /* -DD---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \ + /* -DE---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \ + /* -DF---X- */ DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \ + /* -EX---X- */ DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR, MRC), \ + /* -FX---X- */ DECLARE_ARM_SWI_BLOCK(EMITTER) #endif From e4e455dd5ed09ac38d65d099aba2d2e0e082fad8 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:30:17 -0700 Subject: [PATCH 088/148] ARM: Add framework for coprocessor support --- CHANGES | 1 + include/mgba/internal/arm/arm.h | 7 ++++++ src/arm/arm.c | 1 + src/arm/isa-arm.c | 39 ++++++++++++++++++++++++++++++--- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 3d477b022..7c48e3ab1 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Features: - New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81 - Debugger: Add range watchpoints Emulation fixes: + - ARM: Add framework for coprocessor support - GB Audio: Fix audio envelope timing resetting too often (fixes mgba.io/i/3164) - GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501) - GB Serialize: Add missing Pocket Cam state to savestates diff --git a/include/mgba/internal/arm/arm.h b/include/mgba/internal/arm/arm.h index f9eeafdb6..5f25acf90 100644 --- a/include/mgba/internal/arm/arm.h +++ b/include/mgba/internal/arm/arm.h @@ -134,6 +134,12 @@ struct ARMMemory { void (*setActiveRegion)(struct ARMCore*, uint32_t address); }; +struct ARMCoprocessor { + int32_t (*mrc)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2); + void (*mcr)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, int32_t value); + void (*cdp)(struct ARMCore*, int crn, int crm, int crd, int opcode1, int opcode2); +}; + struct ARMInterruptHandler { void (*reset)(struct ARMCore* cpu); void (*processEvents)(struct ARMCore* cpu); @@ -179,6 +185,7 @@ struct ARMCore { struct ARMMemory memory; struct ARMInterruptHandler irqh; + struct ARMCoprocessor cp[16]; struct mCPUComponent* master; diff --git a/src/arm/arm.c b/src/arm/arm.c index cb93136aa..0b92d7f55 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -45,6 +45,7 @@ void ARMSetPrivilegeMode(struct ARMCore* cpu, enum PrivilegeMode mode) { } void ARMInit(struct ARMCore* cpu) { + memset(cpu->cp, 0, sizeof(cpu->cp)); cpu->master->init(cpu, cpu->master); size_t i; for (i = 0; i < cpu->numComponents; ++i) { diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 7f158dc6e..aaecf2517 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -655,11 +655,44 @@ DEFINE_INSTRUCTION_ARM(BX, // Begin coprocessor definitions -DEFINE_INSTRUCTION_ARM(CDP, ARM_STUB) +#define DEFINE_COPROCESSOR_INSTRUCTION(NAME, BODY) \ + DEFINE_INSTRUCTION_ARM(NAME, \ + int op1 = (opcode >> 21) & 7; \ + int op2 = (opcode >> 5) & 7; \ + int rd = (opcode >> 12) & 0xF; \ + int cp = (opcode >> 8) & 0xF; \ + int crn = (opcode >> 16) & 0xF; \ + int crm = opcode & 0xF; \ + UNUSED(op1); \ + UNUSED(op2); \ + UNUSED(rd); \ + UNUSED(crn); \ + UNUSED(crm); \ + BODY;) + +DEFINE_COPROCESSOR_INSTRUCTION(MRC, + if (cpu->cp[cp].mrc) { + cpu->gprs[rd] = cpu->cp[cp].mrc(cpu, crn, crm, op1, op2); + } else { + ARM_ILL; + }) + +DEFINE_COPROCESSOR_INSTRUCTION(MCR, + if (cpu->cp[cp].mcr) { + cpu->cp[cp].mcr(cpu, crn, crm, op1, op2, cpu->gprs[rd]); + } else { + ARM_ILL; + }) + +DEFINE_COPROCESSOR_INSTRUCTION(CDP, + if (cpu->cp[cp].cdp) { + cpu->cp[cp].cdp(cpu, crn, crm, rd, op1, op2); + } else { + ARM_ILL; + }) + DEFINE_INSTRUCTION_ARM(LDC, ARM_STUB) DEFINE_INSTRUCTION_ARM(STC, ARM_STUB) -DEFINE_INSTRUCTION_ARM(MCR, ARM_STUB) -DEFINE_INSTRUCTION_ARM(MRC, ARM_STUB) // Begin miscellaneous definitions From 455060ec08548905a16428a0aeebb34a3e1faafd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:33:25 -0700 Subject: [PATCH 089/148] GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations --- CHANGES | 1 + src/gba/gba.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/CHANGES b/CHANGES index 7c48e3ab1..2ff272fb6 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Emulation fixes: - GB Serialize: Add missing Pocket Cam state to savestates - GB Video: Implement DMG-style sprite ordering - GBA: Unhandled bkpt should be treated as an undefined exception + - GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) diff --git a/src/gba/gba.c b/src/gba/gba.c index 94ed7562a..3783a0c44 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -40,6 +40,8 @@ static const uint8_t GBA_ROM_MAGIC2[] = { 0x96 }; static const size_t GBA_MB_MAGIC_OFFSET = 0xC0; static void GBAInit(void* cpu, struct mCPUComponent* component); +static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2); +static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2); static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh); static void GBAProcessEvents(struct ARMCore* cpu); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); @@ -72,6 +74,8 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { gba->sync = 0; GBAInterruptHandlerInit(&gba->cpu->irqh); + gba->cpu->cp[0].cdp = GBACP0Process; + gba->cpu->cp[14].mrc = GBACP14Read; GBAMemoryInit(gba); gba->memory.savedata.timing = &gba->timing; @@ -186,6 +190,20 @@ void GBADestroy(struct GBA* gba) { mCoreCallbacksListDeinit(&gba->coreCallbacks); } +static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2) { + UNUSED(cpu); + mLOG(GBA, INFO, "Hit Wii U VC opcode: cdp p0, %i, c%i, c%i, c%i, %i", opcode1, crd, crn, crm, opcode2); +} + +static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2) { + UNUSED(cpu); + UNUSED(crn); + UNUSED(crm); + UNUSED(opcode1); + UNUSED(opcode2); + return 0xF000B570; +} + void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { irqh->reset = GBAReset; irqh->processEvents = GBAProcessEvents; From cf959fe20e13744690c5830a3fd9a81f182317d6 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 2 Jun 2024 17:37:18 -0700 Subject: [PATCH 090/148] GBA: Actually it reads open bus --- src/gba/gba.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gba/gba.c b/src/gba/gba.c index 3783a0c44..2f0ae76d6 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -196,12 +196,12 @@ static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int op } static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2) { - UNUSED(cpu); UNUSED(crn); UNUSED(crm); UNUSED(opcode1); UNUSED(opcode2); - return 0xF000B570; + mLOG(GBA, GAME_ERROR, "Read from missing CP14"); + return GBALoadBad(cpu); } void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { From 8b041e9a2315ebed008d92bbf7b2aa3fce19a582 Mon Sep 17 00:00:00 2001 From: yeah-its-gloria <32610623+yeah-its-gloria@users.noreply.github.com> Date: Mon, 3 Jun 2024 19:49:23 -0400 Subject: [PATCH 091/148] Qt: Ignore rewind while loading/saving states --- src/platform/qt/Window.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index a5576c1c9..010dde782 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1464,6 +1464,11 @@ void Window::setupMenu(QMenuBar* menubar) { }, "emu"); auto rewindHeld = m_actions.addHeldAction(tr("Rewind (held)"), "holdRewind", [this](bool held) { + // Prevent rewinding while the load/save state window is active + if (held && this->m_stateWindow != nullptr) { + return; + } + if (m_controller) { m_controller->setRewinding(held); } From 7451decdacc7f0abcdac36ad9f6951e8ae7090b3 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 3 Jun 2024 18:44:01 -0700 Subject: [PATCH 092/148] Windows: Inno Setup fixes Update minimum Windows version to 7, add DisableDirPage=no --- src/platform/windows/setup/setup.iss.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/setup/setup.iss.in b/src/platform/windows/setup/setup.iss.in index 3aad9ef1b..7fdda053e 100644 --- a/src/platform/windows/setup/setup.iss.in +++ b/src/platform/windows/setup/setup.iss.in @@ -32,10 +32,11 @@ DefaultDirName={pf}\{#AppName} DefaultGroupName={#AppName} AllowNoIcons=yes DirExistsWarning=no +DisableDirPage=no ChangesAssociations=True AppendDefaultDirName=False UninstallDisplayIcon={app}\{#AppName}.exe -MinVersion=0,6.0 +MinVersion=6.1 AlwaysShowDirOnReadyPage=True UsePreviousSetupType=True UsePreviousTasks=True @@ -52,7 +53,7 @@ OutputBaseFilename={#AppName}-setup-{#CleanVersionString}-win{#WinBits} UsePreviousLanguage=False DisableWelcomePage=False VersionInfoDescription={#AppName} is an open-source Game Boy Advance emulator -VersionInfoCopyright= 20132022 Jeffrey Pfau +VersionInfoCopyright= 20132024 Jeffrey Pfau VersionInfoProductName={#AppName} VersionInfoVersion={#AppVer} Compression=lzma2/ultra From 59f4fb71326205d890b75ade9e523fe7b59d2b2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 00:55:07 -0700 Subject: [PATCH 093/148] Test: Read config file in rom-test --- src/platform/test/rom-test-main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/test/rom-test-main.c b/src/platform/test/rom-test-main.c index 8524a852f..be9f36e8e 100644 --- a/src/platform/test/rom-test-main.c +++ b/src/platform/test/rom-test-main.c @@ -93,6 +93,7 @@ int main(int argc, char * argv[]) { mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "remove"); mCoreConfigSetDefaultIntValue(&core->config, "logToStdout", true); + mCoreLoadConfig(core); mStandardLoggerInit(&_logger); mStandardLoggerConfig(&_logger, &core->config); From 6f261f6f1b164451f903a541949577d70ac56f45 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 01:12:14 -0700 Subject: [PATCH 094/148] Scripting: Split console implementation out from Core scripting --- include/mgba/core/scripting.h | 27 ---- include/mgba/script.h | 1 + src/core/scripting.c | 133 ----------------- .../qt/scripting/ScriptingTextBuffer.h | 1 + src/script/CMakeLists.txt | 1 + src/script/console.c | 141 ++++++++++++++++++ 6 files changed, 144 insertions(+), 160 deletions(-) create mode 100644 src/script/console.c diff --git a/include/mgba/core/scripting.h b/include/mgba/core/scripting.h index c0fdcb413..bab2009cf 100644 --- a/include/mgba/core/scripting.h +++ b/include/mgba/core/scripting.h @@ -20,8 +20,6 @@ struct mCore; struct mScriptTextBuffer; mSCRIPT_DECLARE_STRUCT(mCore); mSCRIPT_DECLARE_STRUCT(mLogger); -mSCRIPT_DECLARE_STRUCT(mScriptConsole); -mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer); struct mScriptBridge; struct VFile; @@ -40,24 +38,6 @@ struct mScriptEngine { #endif }; -struct mScriptTextBuffer { - void (*init)(struct mScriptTextBuffer*, const char* name); - void (*deinit)(struct mScriptTextBuffer*); - - void (*setName)(struct mScriptTextBuffer*, const char* text); - - uint32_t (*getX)(const struct mScriptTextBuffer*); - uint32_t (*getY)(const struct mScriptTextBuffer*); - uint32_t (*cols)(const struct mScriptTextBuffer*); - uint32_t (*rows)(const struct mScriptTextBuffer*); - - void (*print)(struct mScriptTextBuffer*, const char* text); - void (*clear)(struct mScriptTextBuffer*); - void (*setSize)(struct mScriptTextBuffer*, uint32_t cols, uint32_t rows); - void (*moveCursor)(struct mScriptTextBuffer*, uint32_t x, uint32_t y); - void (*advance)(struct mScriptTextBuffer*, int32_t); -}; - struct mScriptBridge* mScriptBridgeCreate(void); void mScriptBridgeDestroy(struct mScriptBridge*); @@ -80,13 +60,6 @@ struct mScriptContext; void mScriptContextAttachCore(struct mScriptContext*, struct mCore*); void mScriptContextDetachCore(struct mScriptContext*); -struct mLogger; -void mScriptContextAttachLogger(struct mScriptContext*, struct mLogger*); -void mScriptContextDetachLogger(struct mScriptContext*); - -typedef struct mScriptTextBuffer* (*mScriptContextBufferFactory)(void*); -void mScriptContextSetTextBufferFactory(struct mScriptContext*, mScriptContextBufferFactory factory, void* cbContext); - CXX_GUARD_END #endif diff --git a/include/mgba/script.h b/include/mgba/script.h index 747dfedc1..44ec86b3c 100644 --- a/include/mgba/script.h +++ b/include/mgba/script.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include diff --git a/src/core/scripting.c b/src/core/scripting.c index 57d0eed2b..13cc403c8 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -207,12 +207,6 @@ struct mScriptCoreAdapter { #endif }; -struct mScriptConsole { - struct mLogger* logger; - mScriptContextBufferFactory textBufferFactory; - void* textBufferContext; -}; - #define CALCULATE_SEGMENT_INFO \ uint32_t segmentSize = adapter->block.end - adapter->block.start; \ uint32_t segmentStart = adapter->block.segmentStart - adapter->block.start; \ @@ -1354,130 +1348,3 @@ void mScriptContextDetachCore(struct mScriptContext* context) { mScriptContextRemoveGlobal(context, "emu"); } - -static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) { - struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext); - buffer->init(buffer, name); - return buffer; -} - -static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); - } -} - -static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); - } -} - -static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) { - if (console->logger) { - mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); - } else { - mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); - } -} - -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg); -mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name); - -mSCRIPT_DEFINE_STRUCT(mScriptConsole) - mSCRIPT_DEFINE_CLASS_DOCSTRING( - "A global singleton object `console` that can be used for presenting textual information to the user via a console." - ) - mSCRIPT_DEFINE_DOCSTRING("Print a log to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log) - mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn) - mSCRIPT_DEFINE_DOCSTRING("Print an error to the console") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error) - mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer) -mSCRIPT_DEFINE_END; - -mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer) - mSCRIPT_CHARP(NULL) -mSCRIPT_DEFINE_DEFAULTS_END; - -static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) { - struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); - if (value) { - return value->value.opaque; - } - struct mScriptConsole* console = calloc(1, sizeof(*console)); - value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole)); - value->value.opaque = console; - value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; - mScriptContextSetGlobal(context, "console", value); - mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole"); - return console; -} - -void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) { - struct mScriptConsole* console = _ensureConsole(context); - console->logger = logger; -} - -void mScriptContextDetachLogger(struct mScriptContext* context) { - struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); - if (!value) { - return; - } - struct mScriptConsole* console = value->value.opaque; - console->logger = mLogGetContext(); -} - -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0); -mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv); -mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name); - -mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer) - mSCRIPT_DEFINE_CLASS_DOCSTRING( - "An object that can be used to present texual data to the user. It is displayed monospaced, " - "and text can be edited after sending by moving the cursor or clearing the buffer." - ) - mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit) - mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX) - mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY) - mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols) - mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows) - mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print) - mSCRIPT_DEFINE_DOCSTRING("Clear the buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear) - mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize) - mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor) - mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance) - mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer") - mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName) -mSCRIPT_DEFINE_END; - -void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) { - struct mScriptConsole* console = _ensureConsole(context); - console->textBufferFactory = factory; - console->textBufferContext = cbContext; -} diff --git a/src/platform/qt/scripting/ScriptingTextBuffer.h b/src/platform/qt/scripting/ScriptingTextBuffer.h index b70e9f82a..b4a9c5b83 100644 --- a/src/platform/qt/scripting/ScriptingTextBuffer.h +++ b/src/platform/qt/scripting/ScriptingTextBuffer.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace QGBA { diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index a72f48d22..19802c278 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -1,6 +1,7 @@ include(ExportDirectory) set(SOURCE_FILES canvas.c + console.c context.c input.c image.c diff --git a/src/script/console.c b/src/script/console.c new file mode 100644 index 000000000..d908534f6 --- /dev/null +++ b/src/script/console.c @@ -0,0 +1,141 @@ +/* Copyright (c) 2013-2024 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 + +struct mScriptConsole { + struct mLogger* logger; + mScriptContextBufferFactory textBufferFactory; + void* textBufferContext; +}; + +static struct mScriptTextBuffer* _mScriptConsoleCreateBuffer(struct mScriptConsole* lib, const char* name) { + struct mScriptTextBuffer* buffer = lib->textBufferFactory(lib->textBufferContext); + buffer->init(buffer, name); + return buffer; +} + +static void mScriptConsoleLog(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_INFO, "%s", msg); + } +} + +static void mScriptConsoleWarn(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_WARN, "%s", msg); + } +} + +static void mScriptConsoleError(struct mScriptConsole* console, const char* msg) { + if (console->logger) { + mLogExplicit(console->logger, _mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); + } else { + mLog(_mLOG_CAT_SCRIPT, mLOG_ERROR, "%s", msg); + } +} + +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, log, mScriptConsoleLog, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, warn, mScriptConsoleWarn, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptConsole, error, mScriptConsoleError, 1, CHARP, msg); +mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptConsole, S(mScriptTextBuffer), createBuffer, _mScriptConsoleCreateBuffer, 1, CHARP, name); + +mSCRIPT_DEFINE_STRUCT(mScriptConsole) + mSCRIPT_DEFINE_CLASS_DOCSTRING( + "A global singleton object `console` that can be used for presenting textual information to the user via a console." + ) + mSCRIPT_DEFINE_DOCSTRING("Print a log to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, log) + mSCRIPT_DEFINE_DOCSTRING("Print a warning to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, warn) + mSCRIPT_DEFINE_DOCSTRING("Print an error to the console") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, error) + mSCRIPT_DEFINE_DOCSTRING("Create a text buffer that can be used to display custom information") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptConsole, createBuffer) +mSCRIPT_DEFINE_END; + +mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(mScriptConsole, createBuffer) + mSCRIPT_CHARP(NULL) +mSCRIPT_DEFINE_DEFAULTS_END; + +static struct mScriptConsole* _ensureConsole(struct mScriptContext* context) { + struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); + if (value) { + return value->value.opaque; + } + struct mScriptConsole* console = calloc(1, sizeof(*console)); + value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S(mScriptConsole)); + value->value.opaque = console; + value->flags = mSCRIPT_VALUE_FLAG_FREE_BUFFER; + mScriptContextSetGlobal(context, "console", value); + mScriptContextSetDocstring(context, "console", "Singleton instance of struct::mScriptConsole"); + return console; +} + +void mScriptContextAttachLogger(struct mScriptContext* context, struct mLogger* logger) { + struct mScriptConsole* console = _ensureConsole(context); + console->logger = logger; +} + +void mScriptContextDetachLogger(struct mScriptContext* context) { + struct mScriptValue* value = mScriptContextGetGlobal(context, "console"); + if (!value) { + return; + } + struct mScriptConsole* console = value->value.opaque; + console->logger = mLogGetContext(); +} + +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, deinit, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getX, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, getY, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, cols, 0); +mSCRIPT_DECLARE_STRUCT_CD_METHOD(mScriptTextBuffer, U32, rows, 0); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, print, 1, CHARP, text); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, clear, 0); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setSize, 2, U32, cols, U32, rows); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, moveCursor, 2, U32, x, U32, y); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, advance, 1, S32, adv); +mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD(mScriptTextBuffer, setName, 1, CHARP, name); + +mSCRIPT_DEFINE_STRUCT(mScriptTextBuffer) + mSCRIPT_DEFINE_CLASS_DOCSTRING( + "An object that can be used to present texual data to the user. It is displayed monospaced, " + "and text can be edited after sending by moving the cursor or clearing the buffer." + ) + mSCRIPT_DEFINE_STRUCT_DEINIT_NAMED(mScriptTextBuffer, deinit) + mSCRIPT_DEFINE_DOCSTRING("Get the current x position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getX) + mSCRIPT_DEFINE_DOCSTRING("Get the current y position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, getY) + mSCRIPT_DEFINE_DOCSTRING("Get number of columns in the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, cols) + mSCRIPT_DEFINE_DOCSTRING("Get number of rows in the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, rows) + mSCRIPT_DEFINE_DOCSTRING("Print a string to the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, print) + mSCRIPT_DEFINE_DOCSTRING("Clear the buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, clear) + mSCRIPT_DEFINE_DOCSTRING("Set the number of rows and columns") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setSize) + mSCRIPT_DEFINE_DOCSTRING("Set the position of the cursor") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, moveCursor) + mSCRIPT_DEFINE_DOCSTRING("Advance the cursor a number of columns") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, advance) + mSCRIPT_DEFINE_DOCSTRING("Set the user-visible name of this buffer") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptTextBuffer, setName) +mSCRIPT_DEFINE_END; + +void mScriptContextSetTextBufferFactory(struct mScriptContext* context, mScriptContextBufferFactory factory, void* cbContext) { + struct mScriptConsole* console = _ensureConsole(context); + console->textBufferFactory = factory; + console->textBufferContext = cbContext; +} From 2c975157427090c93dfda6cf296b6a216a64f5d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 01:15:25 -0700 Subject: [PATCH 095/148] Script: Add missing include --- include/mgba/script/console.h | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 include/mgba/script/console.h diff --git a/include/mgba/script/console.h b/include/mgba/script/console.h new file mode 100644 index 000000000..8e7a64345 --- /dev/null +++ b/include/mgba/script/console.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2013-2024 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_SCRIPT_CONSOLE_H +#define M_SCRIPT_CONSOLE_H + +#include + +CXX_GUARD_START + +#include +#include +#include + +struct mCore; +struct mScriptTextBuffer; +mSCRIPT_DECLARE_STRUCT(mCore); +mSCRIPT_DECLARE_STRUCT(mLogger); +mSCRIPT_DECLARE_STRUCT(mScriptConsole); +mSCRIPT_DECLARE_STRUCT(mScriptTextBuffer); + +struct mScriptTextBuffer { + void (*init)(struct mScriptTextBuffer*, const char* name); + void (*deinit)(struct mScriptTextBuffer*); + + void (*setName)(struct mScriptTextBuffer*, const char* text); + + uint32_t (*getX)(const struct mScriptTextBuffer*); + uint32_t (*getY)(const struct mScriptTextBuffer*); + uint32_t (*cols)(const struct mScriptTextBuffer*); + uint32_t (*rows)(const struct mScriptTextBuffer*); + + void (*print)(struct mScriptTextBuffer*, const char* text); + void (*clear)(struct mScriptTextBuffer*); + void (*setSize)(struct mScriptTextBuffer*, uint32_t cols, uint32_t rows); + void (*moveCursor)(struct mScriptTextBuffer*, uint32_t x, uint32_t y); + void (*advance)(struct mScriptTextBuffer*, int32_t); +}; + +struct mLogger; +void mScriptContextAttachLogger(struct mScriptContext*, struct mLogger*); +void mScriptContextDetachLogger(struct mScriptContext*); + +typedef struct mScriptTextBuffer* (*mScriptContextBufferFactory)(void*); +void mScriptContextSetTextBufferFactory(struct mScriptContext*, mScriptContextBufferFactory factory, void* cbContext); + +CXX_GUARD_END + +#endif From e16dfc264a7b0949cbfad2ce347adc1686849206 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 9 Jun 2024 02:20:27 -0700 Subject: [PATCH 096/148] GBA: CP14 mcr also is a no-op --- src/gba/gba.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gba/gba.c b/src/gba/gba.c index 2f0ae76d6..6e1fb8923 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -42,6 +42,7 @@ static const size_t GBA_MB_MAGIC_OFFSET = 0xC0; static void GBAInit(void* cpu, struct mCPUComponent* component); static void GBACP0Process(struct ARMCore* cpu, int crn, int crm, int crd, int opcode1, int opcode2); static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2); +static void GBACP14Write(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2, int32_t value); static void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh); static void GBAProcessEvents(struct ARMCore* cpu); static void GBAHitStub(struct ARMCore* cpu, uint32_t opcode); @@ -76,6 +77,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { GBAInterruptHandlerInit(&gba->cpu->irqh); gba->cpu->cp[0].cdp = GBACP0Process; gba->cpu->cp[14].mrc = GBACP14Read; + gba->cpu->cp[14].mcr = GBACP14Write; GBAMemoryInit(gba); gba->memory.savedata.timing = &gba->timing; @@ -204,6 +206,16 @@ static int32_t GBACP14Read(struct ARMCore* cpu, int crn, int crm, int opcode1, i return GBALoadBad(cpu); } +static void GBACP14Write(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2, int32_t value) { + UNUSED(cpu); + UNUSED(crn); + UNUSED(crm); + UNUSED(opcode1); + UNUSED(opcode2); + UNUSED(value); + mLOG(GBA, GAME_ERROR, "Write to missing CP14"); +} + void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { irqh->reset = GBAReset; irqh->processEvents = GBAProcessEvents; From 20fc7b6ef30cc9a51499b374762f46e54704b1af Mon Sep 17 00:00:00 2001 From: Rib <1957489+RibShark@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:28:51 +0100 Subject: [PATCH 097/148] GBA Memory: Support the Chinese version of Digimon Sapphire by Vast Fame --- include/mgba/internal/gba/cart/vfame.h | 3 ++- src/gba/cart/vfame.c | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/mgba/internal/gba/cart/vfame.h b/include/mgba/internal/gba/cart/vfame.h index eff24a039..cda1d145c 100644 --- a/include/mgba/internal/gba/cart/vfame.h +++ b/include/mgba/internal/gba/cart/vfame.h @@ -16,7 +16,8 @@ CXX_GUARD_START enum GBAVFameCartType { VFAME_NO = 0, VFAME_STANDARD = 1, - VFAME_GEORGE = 2 + VFAME_ALTERNATE = 2, + VFAME_GEORGE = 3 }; struct GBAVFameCart { diff --git a/src/gba/cart/vfame.c b/src/gba/cart/vfame.c index aedcf5d3e..0daabcc8c 100644 --- a/src/gba/cart/vfame.c +++ b/src/gba/cart/vfame.c @@ -7,12 +7,18 @@ #include #include +#include static const uint8_t ADDRESS_REORDERING[4][16] = { { 15, 14, 9, 1, 8, 10, 7, 3, 5, 11, 4, 0, 13, 12, 2, 6 }, { 15, 7, 13, 5, 11, 6, 0, 9, 12, 2, 10, 14, 3, 1, 8, 4 }, { 15, 0, 3, 12, 2, 4, 14, 13, 1, 8, 6, 7, 9, 5, 11, 10 } }; +static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { + { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, + { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, + { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } +}; static const uint8_t ADDRESS_REORDERING_GEORGE[4][16] = { { 15, 7, 13, 1, 11, 10, 14, 9, 12, 2, 4, 0, 3, 5, 8, 6 }, { 15, 14, 3, 12, 8, 4, 0, 13, 5, 11, 6, 7, 9, 1, 2, 10 }, @@ -23,6 +29,11 @@ static const uint8_t VALUE_REORDERING[4][16] = { { 3, 2, 1, 0, 7, 6, 5, 4 }, { 1, 0, 7, 6, 5, 4, 3, 2 } }; +static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { + { 5, 4, 7, 2, 1, 0, 3, 6 }, + { 1, 2, 3, 0, 5, 6, 7, 4 }, + { 3, 0, 1, 6, 7, 4, 5, 2 } +}; static const uint8_t VALUE_REORDERING_GEORGE[4][16] = { { 3, 0, 7, 2, 1, 4, 5, 6 }, { 1, 4, 3, 0, 5, 6, 7, 2 }, @@ -65,13 +76,18 @@ void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { mLOG(GBA_MEM, INFO, "Vast Fame game detected"); } - // This game additionally operates with a different set of SRAM modes - // Its initialisation seems to be identical so the difference must be in the cart HW itself + // These games additionally operates with a different set of SRAM modes + // Their initialisation seems to be identical so the difference must be in the cart HW itself // Other undumped games may have similar differences if (memcmp("George Sango", &((struct GBACartridge*) rom)->title, 12) == 0) { cart->cartType = VFAME_GEORGE; mLOG(GBA_MEM, INFO, "George mode"); } + // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering + // so we have to use some other way to detect it + else if (doCrc32(rom, romSize) == 0x793A328F) { + cart->cartType = VFAME_STANDARD; + } } // This is not currently being used but would be called on ROM reads @@ -256,6 +272,8 @@ static uint32_t _modifySramAddress(enum GBAVFameCartType type, uint32_t address, return address; } else if (type == VFAME_GEORGE) { return _reorderBits(address, ADDRESS_REORDERING_GEORGE[mode - 1], 16); + } else if (type == VFAME_ALTERNATE) { + return _reorderBits(address, ADDRESS_REORDERING_ALTERNATE[mode - 1], 16); } else { return _reorderBits(address, ADDRESS_REORDERING[mode - 1], 16); } @@ -266,6 +284,8 @@ static int8_t _modifySramValue(enum GBAVFameCartType type, uint8_t value, int mo if (reorderType != 0) { if (type == VFAME_GEORGE) { value = _reorderBits(value, VALUE_REORDERING_GEORGE[reorderType - 1], 8); + } else if (type == VFAME_ALTERNATE) { + value = _reorderBits(value, VALUE_REORDERING_ALTERNATE[reorderType - 1], 8); } else { value = _reorderBits(value, VALUE_REORDERING[reorderType - 1], 8); } From 58651f205451054d4869238031b3bf56bd3e5133 Mon Sep 17 00:00:00 2001 From: Rib <1957489+RibShark@users.noreply.github.com> Date: Sun, 9 Jun 2024 22:28:51 +0100 Subject: [PATCH 098/148] GBA Memory: Clean up Vast Fame code somewhat --- include/mgba/internal/gba/cart/vfame.h | 8 ++++--- src/gba/cart/vfame.c | 32 ++++++++++++-------------- src/gba/gba.c | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/mgba/internal/gba/cart/vfame.h b/include/mgba/internal/gba/cart/vfame.h index cda1d145c..5bee28848 100644 --- a/include/mgba/internal/gba/cart/vfame.h +++ b/include/mgba/internal/gba/cart/vfame.h @@ -13,11 +13,13 @@ CXX_GUARD_START +#define DIGIMON_SAPPHIRE_CHINESE_CRC32 0x793A328F + enum GBAVFameCartType { VFAME_NO = 0, VFAME_STANDARD = 1, - VFAME_ALTERNATE = 2, - VFAME_GEORGE = 3 + VFAME_GEORGE = 2, + VFAME_ALTERNATE = 3, }; struct GBAVFameCart { @@ -29,7 +31,7 @@ struct GBAVFameCart { }; void GBAVFameInit(struct GBAVFameCart* cart); -void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize); +void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize, uint32_t crc32); void GBAVFameSramWrite(struct GBAVFameCart* cart, uint32_t address, uint8_t value, uint8_t* sramData); uint32_t GBAVFameModifyRomAddress(struct GBAVFameCart* cart, uint32_t address, size_t romSize); uint32_t GBAVFameGetPatternValue(uint32_t address, int bits); diff --git a/src/gba/cart/vfame.c b/src/gba/cart/vfame.c index 0daabcc8c..260db35b8 100644 --- a/src/gba/cart/vfame.c +++ b/src/gba/cart/vfame.c @@ -7,38 +7,37 @@ #include #include -#include static const uint8_t ADDRESS_REORDERING[4][16] = { { 15, 14, 9, 1, 8, 10, 7, 3, 5, 11, 4, 0, 13, 12, 2, 6 }, { 15, 7, 13, 5, 11, 6, 0, 9, 12, 2, 10, 14, 3, 1, 8, 4 }, { 15, 0, 3, 12, 2, 4, 14, 13, 1, 8, 6, 7, 9, 5, 11, 10 } }; -static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { - { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, - { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, - { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } -}; static const uint8_t ADDRESS_REORDERING_GEORGE[4][16] = { { 15, 7, 13, 1, 11, 10, 14, 9, 12, 2, 4, 0, 3, 5, 8, 6 }, { 15, 14, 3, 12, 8, 4, 0, 13, 5, 11, 6, 7, 9, 1, 2, 10 }, { 15, 0, 9, 5, 2, 6, 7, 3, 1, 8, 10, 14, 13, 12, 11, 4 } }; +static const uint8_t ADDRESS_REORDERING_ALTERNATE[4][16] = { + { 15, 0, 13, 5, 8, 4, 7, 3, 1, 2, 10, 14, 9, 12, 11, 6 }, + { 15, 7, 9, 1, 2, 6, 14, 13, 12, 11, 4, 0, 3, 5, 8, 10 }, + { 15, 14, 3, 12, 11, 10, 0, 9, 5, 8, 6, 7, 13, 1, 2, 4 } +}; static const uint8_t VALUE_REORDERING[4][16] = { { 5, 4, 3, 2, 1, 0, 7, 6 }, { 3, 2, 1, 0, 7, 6, 5, 4 }, { 1, 0, 7, 6, 5, 4, 3, 2 } }; -static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { - { 5, 4, 7, 2, 1, 0, 3, 6 }, - { 1, 2, 3, 0, 5, 6, 7, 4 }, - { 3, 0, 1, 6, 7, 4, 5, 2 } -}; static const uint8_t VALUE_REORDERING_GEORGE[4][16] = { { 3, 0, 7, 2, 1, 4, 5, 6 }, { 1, 4, 3, 0, 5, 6, 7, 2 }, { 5, 2, 1, 6, 7, 0, 3, 4 } }; +static const uint8_t VALUE_REORDERING_ALTERNATE[4][16] = { + { 5, 4, 7, 2, 1, 0, 3, 6 }, + { 1, 2, 3, 0, 5, 6, 7, 4 }, + { 3, 0, 1, 6, 7, 4, 5, 2 } +}; static const int8_t MODE_CHANGE_START_SEQUENCE[5] = { 0x99, 0x02, 0x05, 0x02, 0x03 }; static const int8_t MODE_CHANGE_END_SEQUENCE[5] = { 0x99, 0x03, 0x62, 0x02, 0x56 }; @@ -60,7 +59,7 @@ void GBAVFameInit(struct GBAVFameCart* cart) { cart->acceptingModeChange = false; } -void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { +void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize, uint32_t crc32) { cart->cartType = VFAME_NO; // The initialisation code is also present & run in the dumps of Digimon Ruby & Sapphire from hacked/deprotected reprint carts, @@ -82,11 +81,10 @@ void GBAVFameDetect(struct GBAVFameCart* cart, uint32_t* rom, size_t romSize) { if (memcmp("George Sango", &((struct GBACartridge*) rom)->title, 12) == 0) { cart->cartType = VFAME_GEORGE; mLOG(GBA_MEM, INFO, "George mode"); - } - // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering - // so we have to use some other way to detect it - else if (doCrc32(rom, romSize) == 0x793A328F) { - cart->cartType = VFAME_STANDARD; + } else if (crc32 == DIGIMON_SAPPHIRE_CHINESE_CRC32) { + // Chinese version of Digimon Sapphire; header is identical to the English version which uses the normal reordering + // so we have to use some other way to detect it + cart->cartType = VFAME_ALTERNATE; } } diff --git a/src/gba/gba.c b/src/gba/gba.c index 6e1fb8923..0ceb8209a 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -493,7 +493,7 @@ bool GBALoadROM(struct GBA* gba, struct VFile* vf) { 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); + GBAVFameDetect(&gba->memory.vfame, gba->memory.rom, gba->memory.romSize, gba->romCrc32); // TODO: error check return true; } From ab0194fb49b24a45181acbc7c538a3499d0e17ab Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 03:08:21 -0700 Subject: [PATCH 099/148] GB MBC: Switch Pocket Cam to using standard color conversion methods --- src/gb/mbc/pocket-cam.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/gb/mbc/pocket-cam.c b/src/gb/mbc/pocket-cam.c index c587dfa6a..0eab34aba 100644 --- a/src/gb/mbc/pocket-cam.c +++ b/src/gb/mbc/pocket-cam.c @@ -95,39 +95,32 @@ void _GBPocketCamCapture(struct GBMemory* memory) { case mCOLOR_XRGB8: case mCOLOR_ARGB8: case mCOLOR_ABGR8: - color = ((const uint32_t*) image)[y * stride + x]; - gray = (color & 0xFF) + ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF); - break; case mCOLOR_BGRX8: case mCOLOR_RGBX8: case mCOLOR_RGBA8: case mCOLOR_BGRA8: color = ((const uint32_t*) image)[y * stride + x]; - gray = ((color >> 8) & 0xFF) + ((color >> 16) & 0xFF) + ((color >> 24) & 0xFF); break; case mCOLOR_BGR5: case mCOLOR_RGB5: case mCOLOR_ARGB5: case mCOLOR_ABGR5: - color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 3) & 0xF8) + ((color >> 2) & 0xF8) + ((color >> 7) & 0xF8); - break; case mCOLOR_BGR565: case mCOLOR_RGB565: - color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 3) & 0xF8) + ((color >> 3) & 0xFC) + ((color >> 8) & 0xF8); - break; case mCOLOR_BGRA5: case mCOLOR_RGBA5: color = ((const uint16_t*) image)[y * stride + x]; - gray = ((color << 2) & 0xF8) + ((color >> 3) & 0xF8) + ((color >> 8) & 0xF8); + break; + case mCOLOR_L8: + color = ((const uint8_t*) image)[y * stride + x]; break; default: mLOG(GB_MBC, WARN, "Unsupported pixel format: %X", format); return; } uint16_t exposure = (pocketCam->registers[2] << 8) | (pocketCam->registers[3]); - gray = (gray + 1) * exposure / 0x300; + gray = mColorConvert(color, format, mCOLOR_L8); + gray = (gray + 1) * exposure / 0x100; // TODO: Additional processing int matrixEntry = 3 * ((x & 3) + 4 * (y & 3)); if (gray < pocketCam->registers[matrixEntry + 6]) { From 3837ea8444d84a90720a54eb81e9484dfb4c10c1 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 23:20:52 -0700 Subject: [PATCH 100/148] GB Debugger: Fix file formatting --- src/gb/debugger/debugger.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gb/debugger/debugger.c b/src/gb/debugger/debugger.c index cc05bb7a5..1a3743e42 100644 --- a/src/gb/debugger/debugger.c +++ b/src/gb/debugger/debugger.c @@ -3,14 +3,14 @@ * 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 - #include +#include +#include +#include +#include +#include +#include static const struct SM83Segment _GBSegments[] = { { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, From 745e36e6bcc6b0c2758193fe18f2b9a70a38573f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 10 Jun 2024 23:23:13 -0700 Subject: [PATCH 101/148] GB Video: Remove leftover #include --- src/gb/video.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gb/video.c b/src/gb/video.c index 37c1e3650..38be72a5a 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include From 458300b02ec9934948d7c1e9255bde1e0c987456 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 16 Jun 2024 23:28:04 -0700 Subject: [PATCH 102/148] Core: Improve rumble emulation by averaging state over entire frame (fixes #3232) --- CHANGES | 1 + include/mgba/core/interface.h | 15 +++++++- include/mgba/internal/gb/memory.h | 1 + include/mgba/internal/gba/gba.h | 1 + src/core/interface.c | 41 ++++++++++++++++++++++ src/core/scripting.c | 15 ++++++-- src/gb/gb.c | 6 ++++ src/gb/mbc.c | 1 + src/gb/mbc/mbc.c | 4 ++- src/gb/mbc/unlicensed.c | 4 ++- src/gba/cart/gpio.c | 4 ++- src/gba/gba.c | 7 ++++ src/gba/sio/gbp.c | 5 +-- src/platform/libretro/libretro.c | 34 +++++------------- src/platform/psp2/psp2-context.c | 27 ++++----------- src/platform/qt/input/SDLInputDriver.cpp | 2 +- src/platform/sdl/main.c | 2 +- src/platform/sdl/sdl-events.c | 44 +++++++----------------- src/platform/sdl/sdl-events.h | 5 +-- src/platform/switch/main.c | 40 +++++++-------------- src/platform/wii/main.c | 5 +-- 21 files changed, 142 insertions(+), 122 deletions(-) diff --git a/CHANGES b/CHANGES index 2ff272fb6..626e9aa41 100644 --- a/CHANGES +++ b/CHANGES @@ -30,6 +30,7 @@ Other fixes: - Updater: Fix updating appimage across filesystems Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) + - Core: Improve rumble emulation by averaging state over entire frame (fixes mgba.io/i/3232) - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index b07f300f3..3e6261e9c 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -110,9 +110,22 @@ struct mRTCGenericState { void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core); struct mRumble { - void (*setRumble)(struct mRumble*, int enable); + void (*reset)(struct mRumble*, bool enable); + void (*setRumble)(struct mRumble*, bool enable, uint32_t sinceLast); + void (*integrate)(struct mRumble*, uint32_t period); }; +struct mRumbleIntegrator { + struct mRumble d; + bool state; + uint32_t timeOn; + uint32_t totalTime; + + void (*setRumble)(struct mRumbleIntegrator*, float value); +}; + +void mRumbleIntegratorInit(struct mRumbleIntegrator*); + struct mCoreChannelInfo { size_t id; const char* internalName; diff --git a/include/mgba/internal/gb/memory.h b/include/mgba/internal/gb/memory.h index 052a9f77e..e4b34088b 100644 --- a/include/mgba/internal/gb/memory.h +++ b/include/mgba/internal/gb/memory.h @@ -339,6 +339,7 @@ struct GBMemory { struct mRTCSource* rtc; struct mRotationSource* rotation; struct mRumble* rumble; + int32_t lastRumble; struct mImageSource* cam; }; diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index e66ac47f3..83246ff98 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -91,6 +91,7 @@ struct GBA { struct GBALuminanceSource* luminanceSource; struct mRTCSource* rtcSource; struct mRumble* rumble; + int32_t lastRumble; bool isPristine; size_t pristineRomSize; diff --git a/src/core/interface.c b/src/core/interface.c index d63754895..e5b7f8378 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -109,3 +109,44 @@ void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core) { rtc->d.serialize = _rtcGenericSerialize; rtc->d.deserialize = _rtcGenericDeserialize; } + +static void mRumbleIntegratorReset(struct mRumble* rumble, bool enable) { + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + integrator->state = enable; + integrator->timeOn = 0; + integrator->totalTime = 0; +} + +static void mRumbleIntegratorSetRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + + if (integrator->state) { + integrator->timeOn += sinceLast; + } + integrator->totalTime += sinceLast; + integrator->state = enable; +} + +static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) { + if (!period) { + return; + } + + struct mRumbleIntegrator* integrator = (struct mRumbleIntegrator*) rumble; + if (integrator->state) { + integrator->timeOn += period - integrator->totalTime; + } + integrator->setRumble(integrator, fminf(integrator->timeOn / (float) period, 1.0f)); + + integrator->totalTime = 0; + integrator->timeOn = 0; +} + +void mRumbleIntegratorInit(struct mRumbleIntegrator* integrator) { + integrator->d.reset = mRumbleIntegratorReset; + integrator->d.setRumble = mRumbleIntegratorSetRumble; + integrator->d.integrate = mRumbleIntegratorIntegrate; + + integrator->state = false; + integrator->timeOn = 0; +} diff --git a/src/core/scripting.c b/src/core/scripting.c index 13cc403c8..ea0af459d 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -196,6 +196,7 @@ struct mScriptCoreAdapter { struct mScriptDebugger debugger; #endif struct mRumble rumble; + struct mRumbleIntegrator rumbleIntegrator; struct mRumble* oldRumble; struct mRotationSource rotation; struct mScriptValue* rotationCbTable; @@ -1165,16 +1166,22 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_STRUCT_CAST_TO_MEMBER(mScriptCoreAdapter, CS(mCore), _core) mSCRIPT_DEFINE_END; -static void _setRumble(struct mRumble* rumble, int enable) { +static void _setRumble(struct mRumble* rumble, bool enable, uint32_t timeSince) { struct mScriptCoreAdapter* adapter = containerof(rumble, struct mScriptCoreAdapter, rumble); if (adapter->oldRumble) { - adapter->oldRumble->setRumble(adapter->oldRumble, enable); + adapter->oldRumble->setRumble(adapter->oldRumble, enable, timeSince); } + adapter->rumbleIntegrator.d.setRumble(&adapter->rumbleIntegrator.d, enable, timeSince); +} + +static void _setRumbleFloat(struct mRumbleIntegrator* integrator, float level) { + struct mScriptCoreAdapter* adapter = containerof(integrator, struct mScriptCoreAdapter, rumbleIntegrator); + struct mScriptList args; mScriptListInit(&args, 1); - *mScriptListAppend(&args) = mSCRIPT_MAKE_BOOL(!!enable); + *mScriptListAppend(&args) = mSCRIPT_MAKE_F32(level); mScriptContextTriggerCallback(adapter->context, "rumble", &args); mScriptListDeinit(&args); } @@ -1293,6 +1300,8 @@ void mScriptContextAttachCore(struct mScriptContext* context, struct mCore* core adapter->memory.type = mSCRIPT_TYPE_MS_TABLE; adapter->memory.type->alloc(&adapter->memory); + mRumbleIntegratorInit(&adapter->rumbleIntegrator); + adapter->rumbleIntegrator.setRumble = _setRumbleFloat; adapter->rumble.setRumble = _setRumble; adapter->rotation.sample = _rotationSample; adapter->rotation.readTiltX = _rotationReadTiltX; diff --git a/src/gb/gb.c b/src/gb/gb.c index c0e966c27..c6198ed58 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1174,6 +1174,12 @@ void GBFrameEnded(struct GB* gb) { } } + struct mRumble* rumble = gb->memory.rumble; + if (rumble && rumble->integrate) { + gb->memory.lastRumble = mTimingCurrentTime(&gb->timing); + rumble->integrate(rumble, GB_VIDEO_TOTAL_LENGTH); + } + // TODO: Move to common code if (gb->stream && gb->stream->postVideoFrame) { const color_t* pixels; diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 76c005f96..c9ebed546 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -540,6 +540,7 @@ void GBMBCReset(struct GB* gb) { gb->memory.cartBus = 0xFF; gb->memory.cartBusPc = 0; gb->memory.cartBusDecay = 1; + gb->memory.lastRumble = 0; memset(&gb->memory.mbcState, 0, sizeof(gb->memory.mbcState)); GBMBCInit(gb); diff --git a/src/gb/mbc/mbc.c b/src/gb/mbc/mbc.c index 864b6e9f8..699bdb209 100644 --- a/src/gb/mbc/mbc.c +++ b/src/gb/mbc/mbc.c @@ -253,7 +253,9 @@ void _GBMBC5(struct GB* gb, uint16_t address, uint8_t value) { case 0x4: case 0x5: if (memory->mbcType == GB_MBC5_RUMBLE && memory->rumble) { - memory->rumble->setRumble(memory->rumble, (value >> 3) & 1); + int32_t currentTime = mTimingCurrentTime(&gb->timing); + memory->rumble->setRumble(memory->rumble, (value >> 3) & 1, currentTime - memory->lastRumble); + memory->lastRumble = currentTime; value &= ~8; } GBMBCSwitchSramBank(gb, value & 0xF); diff --git a/src/gb/mbc/unlicensed.c b/src/gb/mbc/unlicensed.c index 1577a15fa..950ddf074 100644 --- a/src/gb/mbc/unlicensed.c +++ b/src/gb/mbc/unlicensed.c @@ -228,7 +228,9 @@ void _GBNTOld2(struct GB* gb, uint16_t address, uint8_t value) { } if (mbcState->rumble && memory->rumble) { - memory->rumble->setRumble(memory->rumble, !!(mbcState->swapped ? value & 0x08 : value & 0x02)); + int32_t currentTime = mTimingCurrentTime(&gb->timing); + memory->rumble->setRumble(memory->rumble, !!(mbcState->swapped ? value & 0x08 : value & 0x02), currentTime - memory->lastRumble); + memory->lastRumble = currentTime; } break; } diff --git a/src/gba/cart/gpio.c b/src/gba/cart/gpio.c index 0a396f746..fde4e3714 100644 --- a/src/gba/cart/gpio.c +++ b/src/gba/cart/gpio.c @@ -354,7 +354,9 @@ void _rumbleReadPins(struct GBACartridgeHardware* hw) { return; } - rumble->setRumble(rumble, !!(hw->pinState & 8)); + int32_t currentTime = mTimingCurrentTime(&hw->p->timing); + rumble->setRumble(rumble, !!(hw->pinState & 8), currentTime - hw->p->lastRumble); + hw->p->lastRumble = currentTime; } // == Light sensor diff --git a/src/gba/gba.c b/src/gba/gba.c index 0ceb8209a..013dcad4e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -250,6 +250,7 @@ void GBAReset(struct ARMCore* cpu) { gba->memory.romMask = toPow2(gba->memory.romSize) - 1; gba->yankedRomSize = 0; } + gba->lastRumble = 0; mTimingClear(&gba->timing); GBAMemoryReset(gba); GBAVideoReset(&gba->video); @@ -993,6 +994,12 @@ void GBAFrameEnded(struct GBA* gba) { GBASIOPlayerUpdate(gba); } + struct mRumble* rumble = gba->rumble; + if (rumble && rumble->integrate) { + gba->lastRumble = mTimingCurrentTime(&gba->timing); + rumble->integrate(rumble, VIDEO_TOTAL_LENGTH); + } + size_t c; for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) { struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c); diff --git a/src/gba/sio/gbp.c b/src/gba/sio/gbp.c index b5f987352..d992ebe2e 100644 --- a/src/gba/sio/gbp.c +++ b/src/gba/sio/gbp.c @@ -108,12 +108,13 @@ uint16_t _gbpSioWriteRegister(struct GBASIODriver* driver, uint32_t address, uin if (gbp->txPosition < 12 && gbp->txPosition > 0) { // TODO: Check expected } else if (gbp->txPosition >= 12) { - uint32_t mask = 0x33; // 0x00 = Stop // 0x11 = Hard Stop // 0x22 = Start if (gbp->p->rumble) { - gbp->p->rumble->setRumble(gbp->p->rumble, (rx & mask) == 0x22); + int32_t currentTime = mTimingCurrentTime(&gbp->p->timing); + gbp->p->rumble->setRumble(gbp->p->rumble, (rx & 0x33) == 0x22, currentTime - gbp->p->lastRumble); + gbp->p->lastRumble = currentTime; } } mTimingDeschedule(&gbp->p->timing, &gbp->event); diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index b7d7d8243..88743b63e 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -33,7 +33,6 @@ * to calculating the average for the last 180 * frames, or 3 seconds of runtime... */ #define SAMPLES_PER_FRAME_MOVING_AVG_ALPHA (1.0f / 180.0f) -#define RUMBLE_PWM 35 #define EVENT_RATE 60 #define VIDEO_WIDTH_MAX 256 @@ -54,7 +53,7 @@ static void GBARetroLog(struct mLogger* logger, int category, enum mLogLevel lev static void _postAudioBuffer(struct mAVStream*, struct mAudioBuffer*); static void _audioRateChanged(struct mAVStream*, unsigned rate); -static void _setRumble(struct mRumble* rumble, int enable); +static void _setRumble(struct mRumbleIntegrator*, float level); static uint8_t _readLux(struct GBALuminanceSource* lux); static void _updateLux(struct GBALuminanceSource* lux); static void _updateCamera(const uint32_t* buffer, unsigned width, unsigned height, size_t pitch); @@ -77,9 +76,7 @@ static void* savedata; static struct mAVStream stream; static bool sensorsInitDone; static bool rumbleInitDone; -static int rumbleUp; -static int rumbleDown; -static struct mRumble rumble; +static struct mRumbleIntegrator rumble; static struct GBALuminanceSource lux; static struct mRotationSource rotation; static bool tiltEnabled; @@ -467,6 +464,7 @@ void retro_init(void) { // TODO: RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME when BIOS booting is supported rumbleInitDone = false; + mRumbleIntegratorInit(&rumble); rumble.setRumble = _setRumble; rumbleCallback = 0; @@ -645,18 +643,6 @@ void retro_run(void) { } } #endif - - if (rumbleCallback) { - if (rumbleUp) { - rumbleCallback(0, RETRO_RUMBLE_STRONG, rumbleUp * 0xFFFF / (rumbleUp + rumbleDown)); - rumbleCallback(0, RETRO_RUMBLE_WEAK, rumbleUp * 0xFFFF / (rumbleUp + rumbleDown)); - } else { - rumbleCallback(0, RETRO_RUMBLE_STRONG, 0); - rumbleCallback(0, RETRO_RUMBLE_WEAK, 0); - } - rumbleUp = 0; - rumbleDown = 0; - } } static void _setupMaps(struct mCore* core) { @@ -848,10 +834,8 @@ static void _setupMaps(struct mCore* core) { void retro_reset(void) { core->reset(core); + mRumbleIntegratorInit(&rumble); _setupMaps(core); - - rumbleUp = 0; - rumbleDown = 0; } bool retro_load_game(const struct retro_game_info* game) { @@ -1267,7 +1251,7 @@ static void _audioRateChanged(struct mAVStream* stream, unsigned rate) { environCallback(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &info); } -static void _setRumble(struct mRumble* rumble, int enable) { +static void _setRumble(struct mRumbleIntegrator* rumble, float level) { UNUSED(rumble); if (!rumbleInitDone) { _initRumble(); @@ -1275,11 +1259,9 @@ static void _setRumble(struct mRumble* rumble, int enable) { if (!rumbleCallback) { return; } - if (enable) { - ++rumbleUp; - } else { - ++rumbleDown; - } + + rumbleCallback(0, RETRO_RUMBLE_STRONG, level * 0xFFFF); + rumbleCallback(0, RETRO_RUMBLE_WEAK, level * 0xFFFF); } static void _updateLux(struct GBALuminanceSource* lux) { diff --git a/src/platform/psp2/psp2-context.c b/src/platform/psp2/psp2-context.c index 0f456fa7e..be9ff4495 100644 --- a/src/platform/psp2/psp2-context.c +++ b/src/platform/psp2/psp2-context.c @@ -36,7 +36,6 @@ #include -#define RUMBLE_PWM 8 #define CDRAM_ALIGN 0x40000 mLOG_DECLARE_CATEGORY(GUI_PSP2); @@ -64,11 +63,7 @@ static struct mSceRotationSource { struct SceMotionSensorState state; } rotation; -static struct mSceRumble { - struct mRumble d; - struct mCircleBuffer history; - int current; -} rumble; +static struct mRumbleIntegrator rumble; static struct mSceImageSource { struct mImageSource d; @@ -157,17 +152,10 @@ static int32_t _readGyroZ(struct mRotationSource* source) { return rotation->state.gyro.z * -0x8000000; } -static void _setRumble(struct mRumble* source, int enable) { - struct mSceRumble* rumble = (struct mSceRumble*) source; - rumble->current += enable; - if (mCircleBufferSize(&rumble->history) == RUMBLE_PWM) { - int8_t oldLevel; - mCircleBufferRead8(&rumble->history, &oldLevel); - rumble->current -= oldLevel; - } - mCircleBufferWrite8(&rumble->history, enable); - int small = (rumble->current << 21) / 65793; - int big = ((rumble->current * rumble->current) << 18) / 65793; +static void _setRumble(struct mRumbleIntegrator* source, float level) { + UNUSED(source); + int small = level * 255; + int big = (level * level) * 255; struct SceCtrlActuator state = { small, big @@ -363,8 +351,8 @@ void mPSP2Setup(struct mGUIRunner* runner) { rotation.d.readGyroZ = _readGyroZ; runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation.d); - rumble.d.setRumble = _setRumble; - mCircleBufferInit(&rumble.history, RUMBLE_PWM); + mRumbleIntegratorInit(&rumble); + rumble.setRumble = _setRumble; runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); camera.d.startRequestImage = _startRequestImage; @@ -509,7 +497,6 @@ void mPSP2Unpaused(struct mGUIRunner* runner) { void mPSP2Teardown(struct mGUIRunner* runner) { UNUSED(runner); - mCircleBufferDeinit(&rumble.history); mAudioResamplerDeinit(&audioContext.resampler); mAudioBufferDeinit(&audioContext.buffer); vita2d_free_texture(tex[0]); diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 72d148057..402b92a12 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -112,7 +112,7 @@ void SDLInputDriver::bindDefaults(InputController* controller) { mRumble* SDLInputDriver::rumble() { #if SDL_VERSION_ATLEAST(2, 0, 0) if (m_playerAttached) { - return &m_sdlPlayer.rumble.d; + return &m_sdlPlayer.rumble.d.d; } #endif return nullptr; diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index b1b850e21..4debea3ee 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -157,7 +157,7 @@ int main(int argc, char** argv) { mSDLPlayerLoadConfig(&renderer.player, mCoreConfigGetInput(&renderer.core->config)); #if SDL_VERSION_ATLEAST(2, 0, 0) - renderer.core->setPeripheral(renderer.core, mPERIPH_RUMBLE, &renderer.player.rumble.d); + renderer.core->setPeripheral(renderer.core, mPERIPH_RUMBLE, &renderer.player.rumble.d.d); #endif int ret; diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index afeedba68..ca8345d22 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -22,15 +22,14 @@ #endif #define GYRO_STEPS 100 -#define RUMBLE_PWM 16 -#define RUMBLE_STEPS 2 +#define RUMBLE_THRESHOLD 1.f / 128.f mLOG_DEFINE_CATEGORY(SDL_EVENTS, "SDL Events", "platform.sdl.events"); DEFINE_VECTOR(SDL_JoystickList, struct SDL_JoystickCombo); #if SDL_VERSION_ATLEAST(2, 0, 0) -static void _mSDLSetRumble(struct mRumble* rumble, int enable); +static void _mSDLSetRumble(struct mRumbleIntegrator* rumble, float level); #endif static int32_t _mSDLReadTiltX(struct mRotationSource* rumble); static int32_t _mSDLReadTiltY(struct mRotationSource* rumble); @@ -188,9 +187,8 @@ bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } #if SDL_VERSION_ATLEAST(2, 0, 0) + mRumbleIntegratorInit(&player->rumble.d); player->rumble.d.setRumble = _mSDLSetRumble; - mCircleBufferInit(&player->rumble.history, RUMBLE_PWM); - player->rumble.level = 0; player->rumble.activeLevel = 0; player->rumble.p = player; #endif @@ -281,9 +279,6 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) { } --events->playersAttached; mCircleBufferDeinit(&player->rotation.zHistory); -#if SDL_VERSION_ATLEAST(2, 0, 0) - mCircleBufferDeinit(&player->rumble.history); -#endif } void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration* config) { @@ -701,7 +696,7 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext, } #if SDL_VERSION_ATLEAST(2, 0, 0) -static void _mSDLSetRumble(struct mRumble* rumble, int enable) { +static void _mSDLSetRumble(struct mRumbleIntegrator* rumble, float level) { struct mSDLRumble* sdlRumble = (struct mSDLRumble*) rumble; if (!sdlRumble->p->joystick) { return; @@ -719,36 +714,23 @@ static void _mSDLSetRumble(struct mRumble* rumble, int enable) { } #endif - int8_t originalLevel = sdlRumble->level; - sdlRumble->level += enable; - if (mCircleBufferSize(&sdlRumble->history) == RUMBLE_PWM) { - int8_t oldLevel; - mCircleBufferRead8(&sdlRumble->history, &oldLevel); - sdlRumble->level -= oldLevel; - } - mCircleBufferWrite8(&sdlRumble->history, enable); - if (sdlRumble->level == originalLevel) { - return; - } - float activeLevel = ceil(RUMBLE_STEPS * sdlRumble->level / (float) RUMBLE_PWM) / RUMBLE_STEPS; - if (fabsf(sdlRumble->activeLevel - activeLevel) < 0.75 / RUMBLE_STEPS) { - return; - } - sdlRumble->activeLevel = activeLevel; #if SDL_VERSION_ATLEAST(2, 0, 9) - if (sdlRumble->p->joystick->controller) { - SDL_GameControllerRumble(sdlRumble->p->joystick->controller, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); - } else { - SDL_JoystickRumble(sdlRumble->p->joystick->joystick, activeLevel * 0xFFFF, activeLevel * 0xFFFF, 500); + if (sdlRumble->activeLevel > RUMBLE_THRESHOLD || level > RUMBLE_THRESHOLD) { + if (sdlRumble->p->joystick->controller) { + SDL_GameControllerRumble(sdlRumble->p->joystick->controller, level * 0xFFFF, level * 0xFFFF, 67); + } else { + SDL_JoystickRumble(sdlRumble->p->joystick->joystick, level * 0xFFFF, level * 0xFFFF, 67); + } } #else - if (sdlRumble->activeLevel > 0.5 / RUMBLE_STEPS) { + if (sdlRumble->activeLevel > RUMBLE_THRESHOLD || level > RUMBLE_THRESHOLD) { SDL_HapticRumbleStop(sdlRumble->p->joystick->haptic); - SDL_HapticRumblePlay(sdlRumble->p->joystick->haptic, activeLevel, 500); + SDL_HapticRumblePlay(sdlRumble->p->joystick->haptic, level, 500); } else { SDL_HapticRumbleStop(sdlRumble->p->joystick->haptic); } #endif + sdlRumble->activeLevel = level; } #endif diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 877818a01..59b7c7e92 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -71,12 +71,9 @@ struct mSDLPlayer { SDL_Window* window; struct mSDLRumble { - struct mRumble d; + struct mRumbleIntegrator d; struct mSDLPlayer* p; - - int level; float activeLevel; - struct mCircleBuffer history; } rumble; #else int newWidth; diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 9a3441b9b..c829ab9b0 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -82,9 +82,7 @@ static struct GUIFont* font; static color_t* frameBuffer; static struct mAVStream stream; static struct mSwitchRumble { - struct mRumble d; - int up; - int down; + struct mRumbleIntegrator d; HidVibrationValue value; } rumble; static struct mRotationSource rotation = {0}; @@ -298,7 +296,8 @@ static void _setup(struct mGUIRunner* runner) { } _updateRenderer(runner, fakeBool); - runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d); + mRumbleIntegratorInit(&rumble.d); + runner->core->setPeripheral(runner->core, mPERIPH_RUMBLE, &rumble.d.d); runner->core->setPeripheral(runner->core, mPERIPH_ROTATION, &rotation); runner->core->setAVStream(runner->core, &stream); @@ -365,12 +364,12 @@ static void _gameLoaded(struct mGUIRunner* runner) { } } - rumble.up = 0; - rumble.down = 0; + mRumbleIntegratorInit(&rumble.d); } static void _gameUnloaded(struct mGUIRunner* runner) { UNUSED(runner); + mRumbleIntegratorInit(&rumble.d); HidVibrationValue values[4]; memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); @@ -510,24 +509,12 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { _drawTex(runner, width, height, faded, false); } - HidVibrationValue values[4]; - if (rumble.up) { - rumble.value.amp_low = rumble.up / (float) (rumble.up + rumble.down); - rumble.value.amp_high = rumble.up / (float) (rumble.up + rumble.down); - memcpy(&values[0], &rumble.value, sizeof(rumble.value)); - memcpy(&values[1], &rumble.value, sizeof(rumble.value)); - memcpy(&values[2], &rumble.value, sizeof(rumble.value)); - memcpy(&values[3], &rumble.value, sizeof(rumble.value)); - } else { - memcpy(&values[0], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[1], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[2], &vibrationStop, sizeof(rumble.value)); - memcpy(&values[3], &vibrationStop, sizeof(rumble.value)); - } + memcpy(&values[0], &rumble.value, sizeof(rumble.value)); + memcpy(&values[1], &rumble.value, sizeof(rumble.value)); + memcpy(&values[2], &rumble.value, sizeof(rumble.value)); + memcpy(&values[3], &rumble.value, sizeof(rumble.value)); hidSendVibrationValues(vibrationDeviceHandles, values, 4); - rumble.up = 0; - rumble.down = 0; } static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { @@ -615,13 +602,10 @@ static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer* buff audrvUpdate(&audrenDriver); } -void _setRumble(struct mRumble* rumble, int enable) { +void _setRumble(struct mRumbleIntegrator* rumble, float level) { struct mSwitchRumble* sr = (struct mSwitchRumble*) rumble; - if (enable) { - ++sr->up; - } else { - ++sr->down; - } + sr->value.amp_low = level; + sr->value.amp_high = level; } void _sampleRotation(struct mRotationSource* source) { diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 55bae9738..f05e00897 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -79,7 +79,7 @@ static void _retraceCallback(u32 count); static void _postAudioBuffer(struct mAVStream* stream, struct mAudioBuffer*); static void _audioRateChanged(struct mAVStream* stream, unsigned); static void _audioDMA(void); -static void _setRumble(struct mRumble* rumble, int enable); +static void _setRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast); static void _sampleRotation(struct mRotationSource* source); static int32_t _readTiltX(struct mRotationSource* source); static int32_t _readTiltY(struct mRotationSource* source); @@ -1722,8 +1722,9 @@ void _incrementScreenMode(struct mGUIRunner* runner) { } } -void _setRumble(struct mRumble* rumble, int enable) { +void _setRumble(struct mRumble* rumble, bool enable, uint32_t sinceLast) { UNUSED(rumble); + UNUSED(sinceLast); WPAD_Rumble(0, enable); if (enable) { PAD_ControlMotor(0, PAD_MOTOR_RUMBLE); From 2ea11feda65c7b632c78a8f0ecca565aaf4ad9ac Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 17 Jun 2024 02:27:31 -0700 Subject: [PATCH 103/148] GBA Memory: Improve VRAM access stall cycle estimation --- CHANGES | 1 + include/mgba/internal/gba/video.h | 8 ++- src/gba/memory.c | 80 +++++++++++++++++++++------- src/gba/video.c | 86 +++++++++++++++++++++++++++++-- 4 files changed, 151 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index 626e9aa41..6119069f3 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Misc: - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - GBA Audio: Remove broken XQ audio pending rewrite + - GBA Memory: Improve VRAM access stall cycle estimation - GBA Video: Add special circlular window handling in OpenGL renderer - Libretro: Add Super Game Boy Color support (closes mgba.io/i/3188) - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 5b12d1541..b29b3d607 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -16,6 +16,12 @@ CXX_GUARD_START mLOG_DECLARE_CATEGORY(GBA_VIDEO); +#define GBA_VSTALL_T4(X) (0x011 << (X)) +#define GBA_VSTALL_T8(X) (0x010 << (X)) +#define GBA_VSTALL_A2 0x100 +#define GBA_VSTALL_A3 0x200 +#define GBA_VSTALL_B 0x400 + enum { VIDEO_HBLANK_PIXELS = 68, VIDEO_HDRAW_LENGTH = 1008, @@ -208,7 +214,7 @@ struct GBAVideo { struct mTimingEvent event; int vcount; - int shouldStall; + unsigned stallMask; uint16_t palette[512]; uint16_t* vram; diff --git a/src/gba/memory.c b/src/gba/memory.c index 4c72ca80e..62b26b1e3 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -401,7 +401,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) { LOAD_32(value, address & 0x0001FFFC, gba->video.vram); \ } \ ++wait; \ - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ wait += GBAMemoryStallVRAM(gba, wait, 1); \ } @@ -561,7 +561,7 @@ uint32_t GBALoad16(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } else { LOAD_16(value, address & 0x0001FFFE, gba->video.vram); } - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -676,7 +676,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } else { value = ((uint8_t*) gba->video.vram)[address & 0x0001FFFF]; } - if (gba->video.shouldStall) { + if (gba->video.stallMask) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -781,7 +781,7 @@ uint32_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) { } \ } \ ++wait; \ - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { \ wait += GBAMemoryStallVRAM(gba, wait, 1); \ } @@ -908,7 +908,7 @@ void GBAStore16(struct ARMCore* cpu, uint32_t address, int16_t value, int* cycle gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } } - if (gba->video.shouldStall && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { + if (gba->video.stallMask && (address & 0x0001FFFF) < ((GBARegisterDISPCNTGetMode(gba->memory.io[GBA_REG(DISPCNT)]) >= 3) ? 0x00014000 : 0x00010000)) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -1038,7 +1038,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo gba->video.renderer->vram[(address & 0x1FFFE) >> 1] = ((uint8_t) value) | (value << 8); gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); } - if (gba->video.shouldStall) { + if (gba->video.stallMask) { wait += GBAMemoryStallVRAM(gba, wait, 0); } break; @@ -1778,20 +1778,64 @@ int32_t GBAMemoryStall(struct ARMCore* cpu, int32_t wait) { } int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) { - UNUSED(extra); - // TODO - uint16_t dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; - int32_t stall = 0; - switch (GBARegisterDISPCNTGetMode(dispcnt)) { - case 2: - if (GBARegisterDISPCNTIsBg2Enable(dispcnt) && GBARegisterDISPCNTIsBg3Enable(dispcnt)) { - // If both backgrounds are enabled, VRAM access is entirely blocked during hdraw - stall = mTimingUntil(&gba->timing, &gba->video.event); + static const uint16_t stallLUT[32] = { + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T8(0) | GBA_VSTALL_A3, + GBA_VSTALL_T8(1) | GBA_VSTALL_A3, + GBA_VSTALL_T8(2) | GBA_VSTALL_A2, + GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T4(0) | GBA_VSTALL_A3, + GBA_VSTALL_T4(1) | GBA_VSTALL_A3, + GBA_VSTALL_T4(2) | GBA_VSTALL_A2, + GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_A3, + GBA_VSTALL_A3, + GBA_VSTALL_A2, + GBA_VSTALL_A3 | GBA_VSTALL_B, + + GBA_VSTALL_T8(0) | GBA_VSTALL_A3, + GBA_VSTALL_T8(1) | GBA_VSTALL_A3, + GBA_VSTALL_T8(2) | GBA_VSTALL_A2, + GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + }; + + int32_t until = mTimingUntil(&gba->timing, &gba->video.event); + int period = -until & 0x1F; + + int32_t stall = until; + + int i; + for (i = 0; i < 16; ++i) { + if (!(stallLUT[(period + i) & 0x1F] & gba->video.stallMask)) { + if (!extra) { + stall = i; + break; + } + --extra; } - break; - default: - return 0; } + stall -= wait; if (stall < 0) { return 0; diff --git a/src/gba/video.c b/src/gba/video.c index bfe556943..5a4d2c8c0 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -32,6 +32,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); +static unsigned _calculateStallMask(struct GBA* gba); MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 8, 8 }, @@ -78,7 +79,7 @@ void GBAVideoReset(struct GBAVideo* video) { video->frameCounter = 0; video->frameskipCounter = 0; - video->shouldStall = 0; + video->stallMask = 0; memset(video->palette, 0, sizeof(video->palette)); memset(video->oam.raw, 0, sizeof(video->oam.raw)); @@ -149,7 +150,7 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount; if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) { - video->shouldStall = 1; + video->stallMask = _calculateStallMask(video->p); } GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)]; @@ -214,7 +215,7 @@ void _startHblank(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (GBARegisterDISPSTATIsHblankIRQ(dispstat)) { GBARaiseIRQ(video->p, GBA_IRQ_HBLANK, cyclesLate - 6); // TODO: Where does this fudge factor come from? } - video->shouldStall = 0; + video->stallMask = 0; video->p->memory.io[GBA_REG(DISPSTAT)] = dispstat; } @@ -224,6 +225,81 @@ void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value) { // TODO: Does a VCounter IRQ trigger on write? } +static unsigned _calculateStallMask(struct GBA* gba) { + unsigned mask = 0; + + unsigned dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; + switch (GBARegisterDISPCNTGetMode(dispcnt)) { + case 0: + if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG0CNT)])) { + mask |= GBA_VSTALL_T8(0); + } else { + mask |= GBA_VSTALL_T4(0); + } + } + if (GBARegisterDISPCNTIsBg1Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG1CNT)])) { + mask |= GBA_VSTALL_T8(1); + } else { + mask |= GBA_VSTALL_T4(1); + } + } + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG2CNT)])) { + mask |= GBA_VSTALL_T8(2); + } else { + mask |= GBA_VSTALL_T4(2); + } + } + if (GBARegisterDISPCNTIsBg3Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG3CNT)])) { + mask |= GBA_VSTALL_T8(3); + } else { + mask |= GBA_VSTALL_T4(3); + } + } + break; + case 1: + if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG0CNT)])) { + mask |= GBA_VSTALL_T8(0); + } else { + mask |= GBA_VSTALL_T4(0); + } + } + if (GBARegisterDISPCNTIsBg1Enable(dispcnt)) { + if (GBARegisterBGCNTIs256Color(gba->memory.io[GBA_REG(BG1CNT)])) { + mask |= GBA_VSTALL_T8(1); + } else { + mask |= GBA_VSTALL_T4(1); + } + } + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_A2; + } + break; + case 2: + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_A2; + } + if (GBARegisterDISPCNTIsBg3Enable(dispcnt)) { + mask |= GBA_VSTALL_A3; + } + break; + case 3: + case 4: + case 5: + if (GBARegisterDISPCNTIsBg2Enable(dispcnt)) { + mask |= GBA_VSTALL_B; + } + break; + default: + break; + } + return mask; +} + static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer) { UNUSED(renderer); // Nothing to do @@ -353,7 +429,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState } LOAD_32(video->frameCounter, 0, &state->video.frameCounter); - video->shouldStall = 0; + video->stallMask = 0; int32_t flags; LOAD_32(flags, 0, &state->video.flags); GBARegisterDISPSTAT dispstat = state->io[GBA_REG(DISPSTAT)]; @@ -370,7 +446,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState break; case 2: video->event.callback = _startHblank; - video->shouldStall = 1; + video->stallMask = _calculateStallMask(video->p); break; case 3: video->event.callback = _startHdraw; From 9318e9b2cb1c019e8862755c0aad5675405648de Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2024 02:20:36 -0700 Subject: [PATCH 104/148] All: Clean up how assertions are done --- include/mgba-util/common.h | 20 ++++++++++++++++ src/core/tile-cache.c | 10 ++------ src/gba/gba.c | 13 +++-------- src/script/canvas.c | 6 ++--- src/script/context.c | 4 +--- src/script/types.c | 13 ++++------- src/util/audio-resampler.c | 4 +--- src/util/circle-buffer.c | 48 +++++++------------------------------- src/util/sfo.c | 4 +--- src/util/vfs/vfs-zip.c | 4 +--- 10 files changed, 43 insertions(+), 83 deletions(-) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index d91a6557c..c5008e01f 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -314,6 +314,26 @@ typedef intptr_t ssize_t; #define ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31))) +#define mASSERT(COND) \ + if (!(COND)) { \ + abort(); \ + } +#define mASSERT_DEBUG(COND) assert((COND)) + +#define mASSERT_LOG(CAT, COND, ...) \ + if (!(COND)) { \ + mLOG(CAT, FATAL, __VA_ARGS__); \ + } + +#ifdef NDEBUG +#define mASSERT_DEBUG_LOG(...) +#else +#define mASSERT_DEBUG_LOG(CAT, COND, ...) \ + if (!(COND)) { \ + mLOG(CAT, FATAL, __VA_ARGS__); \ + } +#endif + CXX_GUARD_END #endif diff --git a/src/core/tile-cache.c b/src/core/tile-cache.c index 249cd0116..d9f68066c 100644 --- a/src/core/tile-cache.c +++ b/src/core/tile-cache.c @@ -197,14 +197,8 @@ static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { if (mTileCacheConfigurationIsShouldStore(cache->config)) { unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); -#ifndef NDEBUG - if (tileId >= tiles) { - abort(); - } - if (paletteId >= 1U << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)) { - abort(); - } -#endif + mASSERT(tileId < tiles); + mASSERT_DEBUG(paletteId < 1U << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig)); return &cache->cache[(tileId + paletteId * tiles) << 6]; } else { return cache->temporaryTile; diff --git a/src/gba/gba.c b/src/gba/gba.c index 013dcad4e..2d10f5cc9 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -339,11 +339,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { #ifdef ENABLE_DEBUGGERS gba->timing.globalCycles += cycles < nextEvent ? nextEvent : cycles; #endif -#ifndef NDEBUG - if (cycles < 0) { - mLOG(GBA, FATAL, "Negative cycles passed: %i", cycles); - } -#endif + mASSERT_DEBUG_LOG(GBA, cycles >= 0, "Negative cycles passed: %i", cycles); nextEvent = mTimingTick(&gba->timing, cycles < nextEvent ? nextEvent : cycles); } while (gba->cpuBlocked && !gba->earlyExit); @@ -353,12 +349,9 @@ static void GBAProcessEvents(struct ARMCore* cpu) { if (!gba->memory.io[GBA_REG(IME)] || !gba->memory.io[GBA_REG(IE)]) { break; } + } else { + mASSERT_DEBUG_LOG(GBA, nextEvent >= 0, "Negative cycles will pass: %i", nextEvent); } -#ifndef NDEBUG - else if (nextEvent < 0) { - mLOG(GBA, FATAL, "Negative cycles will pass: %i", nextEvent); - } -#endif if (gba->earlyExit) { break; } diff --git a/src/script/canvas.c b/src/script/canvas.c index 5e931943d..0a0ce5b80 100644 --- a/src/script/canvas.c +++ b/src/script/canvas.c @@ -157,10 +157,8 @@ static struct mScriptValue* mScriptCanvasLayerCreate(struct mScriptCanvasContext } struct mScriptCanvasLayer* layer = &context->overlays[next]; - if (layer->image) { - // This shouldn't exist yet - abort(); - } + // This shouldn't exist yet + mASSERT(!layer->image); layer->image = mImageCreate(w, h, mCOLOR_ABGR8); layer->dirty = true; diff --git a/src/script/context.c b/src/script/context.c index ab0937500..d9afd55a1 100644 --- a/src/script/context.c +++ b/src/script/context.c @@ -458,9 +458,7 @@ bool mScriptContextActivate(struct mScriptContext* context) { void mScriptContextDeactivate(struct mScriptContext* context) { #ifndef NDEBUG struct mScriptContext* threadContext = ThreadLocalGetValue(_threadContext); - if (threadContext != context) { - abort(); - } + mASSERT(threadContext == context); #endif --context->threadDepth; diff --git a/src/script/types.c b/src/script/types.c index d860d40c0..be58a43bf 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -895,9 +895,8 @@ struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) { } void mScriptValueRef(struct mScriptValue* val) { - if (val->refs == INT_MAX) { - abort(); - } else if (val->refs == mSCRIPT_VALUE_UNREF) { + mASSERT(val->refs != INT_MAX); + if (val->refs == mSCRIPT_VALUE_UNREF) { return; } ++val->refs; @@ -1238,12 +1237,8 @@ static void _mScriptClassInit(struct mScriptTypeClass* cls, const struct mScript member->docstring = docstring; docstring = NULL; } - if (detail->info.member.type->base != mSCRIPT_TYPE_FUNCTION) { - abort(); - } - if (detail->info.member.type->details.function.parameters.count != 3) { - abort(); - } + mASSERT(detail->info.member.type->base == mSCRIPT_TYPE_FUNCTION); + mASSERT(detail->info.member.type->details.function.parameters.count == 3); HashTableInsert(&cls->setters, detail->info.member.type->details.function.parameters.entries[2]->name, member); break; case mSCRIPT_CLASS_INIT_INTERNAL: diff --git a/src/util/audio-resampler.c b/src/util/audio-resampler.c index 5b7a069e4..3b1848190 100644 --- a/src/util/audio-resampler.c +++ b/src/util/audio-resampler.c @@ -77,9 +77,7 @@ size_t mAudioResamplerProcess(struct mAudioResampler* resampler) { }; size_t read = 0; - if (resampler->source->channels > MAX_CHANNELS) { - abort(); - } + mASSERT(resampler->source->channels <= MAX_CHANNELS); while (true) { if (timestamp + resampler->highWaterMark >= mAudioBufferAvailable(resampler->source)) { diff --git a/src/util/circle-buffer.c b/src/util/circle-buffer.c index ec14bfc4f..cd13c082f 100644 --- a/src/util/circle-buffer.c +++ b/src/util/circle-buffer.c @@ -59,11 +59,7 @@ int mCircleBufferWrite8(struct mCircleBuffer* buffer, int8_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int8_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 1; } @@ -89,11 +85,7 @@ int mCircleBufferWrite32(struct mCircleBuffer* buffer, int32_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int32_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 4; } @@ -117,11 +109,7 @@ int mCircleBufferWrite16(struct mCircleBuffer* buffer, int16_t value) { buffer->writePtr = buffer->data; } buffer->size += sizeof(int16_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 2; } @@ -145,11 +133,7 @@ size_t mCircleBufferWrite(struct mCircleBuffer* buffer, const void* input, size_ } buffer->size += length; -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return length; } @@ -174,11 +158,7 @@ int mCircleBufferRead8(struct mCircleBuffer* buffer, int8_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int8_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 1; } @@ -202,11 +182,7 @@ int mCircleBufferRead16(struct mCircleBuffer* buffer, int16_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int16_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 2; } @@ -232,11 +208,7 @@ int mCircleBufferRead32(struct mCircleBuffer* buffer, int32_t* value) { buffer->readPtr = buffer->data; } buffer->size -= sizeof(int32_t); -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return 4; } @@ -267,11 +239,7 @@ size_t mCircleBufferRead(struct mCircleBuffer* buffer, void* output, size_t leng } buffer->size -= length; -#ifndef NDEBUG - if (!_checkIntegrity(buffer)) { - abort(); - } -#endif + mASSERT_DEBUG(_checkIntegrity(buffer)); return length; } diff --git a/src/util/sfo.c b/src/util/sfo.c index 339da1d8e..97c4e3853 100644 --- a/src/util/sfo.c +++ b/src/util/sfo.c @@ -209,9 +209,7 @@ bool SfoWrite(struct Table* sfo, struct VFile* vf) { } } - if (keysSize != ALIGN4(keysOffset) || dataSize != dataOffset) { - abort(); - } + mASSERT(keysSize == ALIGN4(keysOffset) && dataSize == dataOffset); free(sortedEntries); diff --git a/src/util/vfs/vfs-zip.c b/src/util/vfs/vfs-zip.c index 65e1c1e32..bd803d7bb 100644 --- a/src/util/vfs/vfs-zip.c +++ b/src/util/vfs/vfs-zip.c @@ -309,9 +309,7 @@ ssize_t _vfzRead(struct VFile* vf, void* buffer, size_t size) { if (!vfz->buffer) { vfz->bufferSize = BLOCK_SIZE; vfz->buffer = malloc(BLOCK_SIZE); - if (vfz->readSize) { - abort(); - } + mASSERT(!vfz->readSize); } while (bytesRead < size) { From d8375a5896e9ebf2d742f884d3229c0e8e3b61d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 20 Jun 2024 22:30:16 -0700 Subject: [PATCH 105/148] GBA Memory: Fix affine background timing errors --- src/gba/memory.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 62b26b1e3..1ddd2eb99 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1782,42 +1782,42 @@ int32_t GBAMemoryStallVRAM(struct GBA* gba, int32_t wait, int extra) { GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T8(0) | GBA_VSTALL_A3, GBA_VSTALL_T8(1) | GBA_VSTALL_A3, GBA_VSTALL_T8(2) | GBA_VSTALL_A2, - GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T8(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T4(0) | GBA_VSTALL_A3, GBA_VSTALL_T4(1) | GBA_VSTALL_A3, GBA_VSTALL_T4(2) | GBA_VSTALL_A2, - GBA_VSTALL_T4(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T4(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_A3, GBA_VSTALL_A3, GBA_VSTALL_A2, - GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_A2 | GBA_VSTALL_B, GBA_VSTALL_T8(0) | GBA_VSTALL_A3, GBA_VSTALL_T8(1) | GBA_VSTALL_A3, GBA_VSTALL_T8(2) | GBA_VSTALL_A2, - GBA_VSTALL_T8(3) | GBA_VSTALL_A3 | GBA_VSTALL_B, + GBA_VSTALL_T8(3) | GBA_VSTALL_A2 | GBA_VSTALL_B, }; int32_t until = mTimingUntil(&gba->timing, &gba->video.event); From e8bfaa210a2fc3112d72596989c4153dcef50d34 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Jun 2024 01:16:12 -0700 Subject: [PATCH 106/148] GBA Video: Fix VRAM access stalling even during force blanking --- src/gba/video.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/gba/video.c b/src/gba/video.c index 5a4d2c8c0..63e7115c1 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -32,7 +32,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); -static unsigned _calculateStallMask(struct GBA* gba); +static unsigned _calculateStallMask(struct GBA* gba, unsigned dispcnt); MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 8, 8 }, @@ -150,7 +150,8 @@ void _startHdraw(struct mTiming* timing, void* context, uint32_t cyclesLate) { video->p->memory.io[GBA_REG(VCOUNT)] = video->vcount; if (video->vcount < GBA_VIDEO_VERTICAL_PIXELS) { - video->stallMask = _calculateStallMask(video->p); + unsigned dispcnt = video->p->memory.io[GBA_REG(DISPCNT)]; + video->stallMask = _calculateStallMask(video->p, dispcnt); } GBARegisterDISPSTAT dispstat = video->p->memory.io[GBA_REG(DISPSTAT)]; @@ -225,10 +226,13 @@ void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value) { // TODO: Does a VCounter IRQ trigger on write? } -static unsigned _calculateStallMask(struct GBA* gba) { +static unsigned _calculateStallMask(struct GBA* gba, unsigned dispcnt) { unsigned mask = 0; - unsigned dispcnt = gba->memory.io[GBA_REG(DISPCNT)]; + if (GBARegisterDISPCNTIsForcedBlank(dispcnt)) { + return 0; + } + switch (GBARegisterDISPCNTGetMode(dispcnt)) { case 0: if (GBARegisterDISPCNTIsBg0Enable(dispcnt)) { @@ -446,7 +450,7 @@ void GBAVideoDeserialize(struct GBAVideo* video, const struct GBASerializedState break; case 2: video->event.callback = _startHblank; - video->stallMask = _calculateStallMask(video->p); + video->stallMask = _calculateStallMask(video->p, state->io[GBA_REG(DISPCNT)]); break; case 3: video->event.callback = _startHdraw; From 1a3873da671958901e1ea26cbef7e501f7761af9 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 03:13:33 -0700 Subject: [PATCH 107/148] GBA Serialize: Fix some minor save state edge cases There are two edge cases fixed in this commit. The first one involves audio FIFO DMA state not being properly updated if the game reconfigured it between save and load. This doesn't happen often, but it could conceivably affect custom sound engines. The second case is the extremely rare case of a save state being taken directly after a DMA ending but before an open bus read. The chances of this happening are negligible, but it's still a bug regargless. --- CHANGES | 1 + include/mgba/internal/gba/serialize.h | 14 +++++++++++--- src/gba/audio.c | 12 ++++++++++++ src/gba/io.c | 2 ++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 6119069f3..132d5ae44 100644 --- a/CHANGES +++ b/CHANGES @@ -16,6 +16,7 @@ Emulation fixes: - GBA: Add baseline CP0 (Wii U VC) and CP1 (DCC) implementations - GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) + - GBA Serialize: Fix some minor save state edge cases - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) Other fixes: diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index 25bd170d6..b31fd0f5a 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -20,7 +20,7 @@ extern MGBA_EXPORT const uint32_t GBASavestateVersion; mLOG_DECLARE_CATEGORY(GBA_STATE); /* Savestate format: - * 0x00000 - 0x00003: Version Magic (0x01000006) + * 0x00000 - 0x00003: Version Magic (0x01000007) * 0x00004 - 0x00007: BIOS checksum (e.g. 0xBAAE187F for official BIOS) * 0x00008 - 0x0000B: ROM CRC32 * 0x0000C - 0x0000F: Master cycles @@ -107,6 +107,9 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * | 0x001E0 - 0x001E3: Last sample * | 0x001E4 - 0x001E7: Additional audio flags * | bits 0 - 3: Current sample index + * | bits 4 - 5: Channel A DMA source + * | bits 6 - 7: Channel B DMA source + * | bits 8 - 31: Reserved * | 0x001E8 - 0x001EF: Reserved * 0x001F0 - 0x001FF: Video miscellaneous state * | 0x001F0 - 0x001F3: Reserved @@ -232,7 +235,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE); * 0x00370 - 0x0037F: Audio FIFO A samples * 0x00380 - 0x0038F: Audio FIFO B samples * 0x00390 - 0x003CF: Audio rendered samples - * 0x003D0 - 0x003FF: Reserved (leave zero) + * 0x003D0 - 0x003D3: Memory bus value + * 0x003D4 - 0x003FF: Reserved (leave zero) * 0x00400 - 0x007FF: I/O memory * 0x00800 - 0x00BFF: Palette * 0x00C00 - 0x00FFF: OAM @@ -250,6 +254,8 @@ DECL_BITS(GBASerializedAudioFlags, FIFOSamplesA, 7, 3); DECL_BITFIELD(GBASerializedAudioFlags2, uint32_t); DECL_BITS(GBASerializedAudioFlags2, SampleIndex, 0, 4); +DECL_BITS(GBASerializedAudioFlags2, ChASource, 4, 2); +DECL_BITS(GBASerializedAudioFlags2, ChBSource, 6, 2); DECL_BITFIELD(GBASerializedVideoFlags, uint32_t); DECL_BITS(GBASerializedVideoFlags, Mode, 0, 2); @@ -405,7 +411,9 @@ struct GBASerializedState { struct mStereoSample currentSamples[GBA_MAX_SAMPLES]; - uint32_t reserved[12]; + uint32_t bus; + + uint32_t reserved[11]; uint16_t io[GBA_SIZE_IO >> 1]; uint16_t pram[GBA_SIZE_PALETTE_RAM >> 1]; diff --git a/src/gba/audio.c b/src/gba/audio.c index e6b495382..aca2f2765 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -475,6 +475,10 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* GBASerializedAudioFlags2 flags2 = 0; flags2 = GBASerializedAudioFlags2SetSampleIndex(flags2, audio->sampleIndex); + // This flag was introduced in 0.11 and will only ever be 0, 1 or 2, so we + // add 1 and use a non-zero value to mark its presence in the state file + flags2 = GBASerializedAudioFlags2SetChASource(flags2, audio->chA.dmaSource + 1); + flags2 = GBASerializedAudioFlags2SetChBSource(flags2, audio->chB.dmaSource + 1); STORE_32(flags2, 0, &state->audio.gbaFlags2); STORE_32(audio->sampleEvent.when - mTimingCurrentTime(&audio->p->timing), 0, &state->audio.nextSample); @@ -526,6 +530,14 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState GBASerializedAudioFlags2 flags2; LOAD_32(flags2, 0, &state->audio.gbaFlags2); audio->sampleIndex = GBASerializedAudioFlags2GetSampleIndex(flags2); + // This flag was introduced in 0.11 and will only ever be 0, 1 or 2, so we + // add 1 and use a non-zero value to mark its presence in the state file + if (GBASerializedAudioFlags2GetChASource(flags2) > 0) { + audio->chA.dmaSource = GBASerializedAudioFlags2GetChASource(flags2) - 1; + } + if (GBASerializedAudioFlags2GetChBSource(flags2) > 0) { + audio->chB.dmaSource = GBASerializedAudioFlags2GetChBSource(flags2) - 1; + } uint32_t when; LOAD_32(when, 0, &state->audio.nextSample); diff --git a/src/gba/io.c b/src/gba/io.c index 184146511..397eb9253 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -941,6 +941,7 @@ void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { STORE_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); STORE_32(gba->dmaPC, 0, &state->dmaBlockPC); + STORE_32(gba->bus, 0, &state->bus); GBAHardwareSerialize(&gba->memory.hw, state); } @@ -987,6 +988,7 @@ void GBAIODeserialize(struct GBA* gba, const struct GBASerializedState* state) { LOAD_32(gba->memory.dmaTransferRegister, 0, &state->dmaTransferRegister); LOAD_32(gba->dmaPC, 0, &state->dmaBlockPC); + LOAD_32(gba->bus, 0, &state->bus); GBADMAUpdate(gba); GBAHardwareDeserialize(&gba->memory.hw, state); From a4c2571d981a9aa9e71bbfd420e350ad3f65a044 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 03:43:22 -0700 Subject: [PATCH 108/148] GBA Audio: Fix crash if audio FIFOs and timers get out of sync --- CHANGES | 1 + src/gba/audio.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 132d5ae44..c73b2528b 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/src/gba/audio.c b/src/gba/audio.c index aca2f2765..25e400b19 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -321,6 +321,9 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) { int bits = 2 << GBARegisterSOUNDBIASGetResolution(audio->soundbias); until += 1 << (9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias)); until >>= 9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias); + if (UNLIKELY(bits < until)) { + until = bits; + } int i; for (i = bits - until; i < bits; ++i) { channel->samples[i] = channel->internalSample; From 79193b914bdd2221b7d5222ab64750d54fccb339 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jun 2024 04:08:47 -0700 Subject: [PATCH 109/148] GBA Audio: Fix crash in audio subsampling if timing lockstep breaks --- CHANGES | 1 + include/mgba/internal/gba/audio.h | 2 +- src/gba/audio.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c73b2528b..a0b87e214 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - GBA Audio: Fix crash if audio FIFOs and timers get out of sync + - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/include/mgba/internal/gba/audio.h b/include/mgba/internal/gba/audio.h index 5b5db3a62..fba5090bf 100644 --- a/include/mgba/internal/gba/audio.h +++ b/include/mgba/internal/gba/audio.h @@ -80,7 +80,7 @@ struct GBAAudio { int32_t sampleInterval; int32_t lastSample; - int sampleIndex; + unsigned sampleIndex; struct mStereoSample currentSamples[GBA_MAX_SAMPLES]; bool forceDisableChA; diff --git a/src/gba/audio.c b/src/gba/audio.c index 25e400b19..a6ebafbae 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -232,6 +232,9 @@ void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) { if (oldSampleInterval != audio->sampleInterval) { timestamp -= audio->lastSample; audio->sampleIndex = timestamp >> (9 - GBARegisterSOUNDBIASGetResolution(value)); + if (audio->sampleIndex >= GBA_MAX_SAMPLES) { + audio->sampleIndex = 0; + } if (audio->p->stream && audio->p->stream->audioRateChanged) { audio->p->stream->audioRateChanged(audio->p->stream, GBA_ARM7TDMI_FREQUENCY / audio->sampleInterval); } From a824989e5a1ecf32775d7d33a0ae47a86b28c7f4 Mon Sep 17 00:00:00 2001 From: oltolm Date: Tue, 30 Apr 2024 19:01:52 +0200 Subject: [PATCH 110/148] fix shortcuts --- src/platform/qt/KeyEditor.cpp | 49 +++++------------------------------ src/platform/qt/KeyEditor.h | 2 +- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/src/platform/qt/KeyEditor.cpp b/src/platform/qt/KeyEditor.cpp index 50702da73..818b6c703 100644 --- a/src/platform/qt/KeyEditor.cpp +++ b/src/platform/qt/KeyEditor.cpp @@ -41,7 +41,7 @@ void KeyEditor::setValue(int key) { if (m_button) { updateButtonText(); } else { - if (key < 0) { + if (key == Qt::Key_unknown) { setText(tr("---")); } else { setText(keyName(key)); @@ -78,7 +78,7 @@ void KeyEditor::setValueHat(int hat, GamepadHatEvent::Direction direction) { void KeyEditor::clearButton() { m_button = true; - setValue(-1); + setValue(Qt::Key_unknown); } void KeyEditor::clearAxis() { @@ -106,48 +106,11 @@ QSize KeyEditor::sizeHint() const { void KeyEditor::keyPressEvent(QKeyEvent* event) { if (!m_button) { - if (m_key < 0 || !m_lastKey.isActive()) { - m_key = 0; + if (!m_lastKey.isActive()) { + m_key = Qt::Key_unknown; } m_lastKey.start(KEY_TIME); - if (m_key) { - if (ShortcutController::isModifierKey(m_key)) { - switch (event->key()) { - case Qt::Key_Shift: - setValue(Qt::ShiftModifier); - break; - case Qt::Key_Control: - setValue(Qt::ControlModifier); - break; - case Qt::Key_Alt: - setValue(Qt::AltModifier); - break; - case Qt::Key_Meta: - setValue(Qt::MetaModifier); - break; - } - } - if (ShortcutController::isModifierKey(event->key())) { - switch (event->key()) { - case Qt::Key_Shift: - setValue(m_key | Qt::ShiftModifier); - break; - case Qt::Key_Control: - setValue(m_key | Qt::ControlModifier); - break; - case Qt::Key_Alt: - setValue(m_key | Qt::AltModifier); - break; - case Qt::Key_Meta: - setValue(m_key | Qt::MetaModifier); - break; - } - } else { - setValue(event->key() | (m_key & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier))); - } - } else { - setValue(event->key()); - } + setValue(ShortcutController::isModifierKey(event->key()) ? event->modifiers() : event->key() | event->modifiers()); } event->accept(); } @@ -213,7 +176,7 @@ void KeyEditor::updateButtonText() { break; } } - if (m_key >= 0) { + if (m_key != Qt::Key_unknown) { std::shared_ptr gamepad; if (m_controller && m_controller->gamepadDriver()) { gamepad = m_controller->gamepadDriver()->activeGamepad(); diff --git a/src/platform/qt/KeyEditor.h b/src/platform/qt/KeyEditor.h index 93af927ac..66599ad60 100644 --- a/src/platform/qt/KeyEditor.h +++ b/src/platform/qt/KeyEditor.h @@ -57,7 +57,7 @@ private: void updateButtonText(); - int m_key = -1; + int m_key = Qt::Key_unknown; int m_axis = -1; int m_hat = -1; bool m_button = false; From 916fa1dba0a0452a0db9c870f6fe7ce2133b868a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 00:51:15 -0700 Subject: [PATCH 111/148] CMake: Fix compile flags for docgen --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1742cb805..78fddfce4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1014,6 +1014,7 @@ endif() if(ENABLE_SCRIPTING AND BUILD_DOCGEN) add_executable(docgen ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/docgen.c) target_link_libraries(docgen ${OS_LIB} ${PLATFORM_LIBRARY} ${BINARY_NAME}) + set_target_properties(docgen PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FUNCTION_DEFINES};${FEATURE_DEFINES}") endif() if(BUILD_MAINTAINER_TOOLS) From 0a57aca1a5c6c75eb68abba79d0e487968655d4a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 20:45:26 -0700 Subject: [PATCH 112/148] Qt: Fix closure argument types --- src/platform/qt/input/SDLInputDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 402b92a12..620602f03 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -159,7 +159,7 @@ void SDLInputDriver::updateGamepads() { m_gamepads.removeAt(i); --i; } - std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto b) { + std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto& b) { return a->m_index < b->m_index; }); @@ -173,7 +173,7 @@ void SDLInputDriver::updateGamepads() { } m_gamepads.append(std::make_shared(this, i)); } - std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto b) { + std::sort(m_gamepads.begin(), m_gamepads.end(), [](const auto& a, const auto& b) { return a->m_index < b->m_index; }); } From f394c51a750b550cbfd536ef5df12d4e168b3f59 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 1 Jul 2024 20:52:04 -0700 Subject: [PATCH 113/148] Qt: Fix some controllers with multiple players (e.g. Mayflash GC adapter) getting duplicated --- src/platform/qt/input/SDLInputDriver.cpp | 6 +++--- src/platform/qt/input/SDLInputDriver.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/input/SDLInputDriver.cpp b/src/platform/qt/input/SDLInputDriver.cpp index 620602f03..792c84834 100644 --- a/src/platform/qt/input/SDLInputDriver.cpp +++ b/src/platform/qt/input/SDLInputDriver.cpp @@ -249,6 +249,7 @@ SDLGamepad::SDLGamepad(SDLInputDriver* driver, int index, QObject* parent) #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick; SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), m_guid, sizeof(m_guid)); + m_id = SDL_JoystickInstanceID(joystick); #endif } @@ -395,11 +396,10 @@ QString SDLGamepad::visibleName() const { #if SDL_VERSION_ATLEAST(2, 0, 0) bool SDLGamepad::updateIndex() { - char guid[34]; for (size_t i = 0; i < SDL_JoystickListSize(&s_sdlEvents.joysticks); ++i) { SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, i)->joystick; - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), guid, sizeof(guid)); - if (memcmp(guid, m_guid, 33) == 0) { + SDL_JoystickID id = SDL_JoystickInstanceID(joystick); + if (id == m_id) { m_index = i; return true; } diff --git a/src/platform/qt/input/SDLInputDriver.h b/src/platform/qt/input/SDLInputDriver.h index 217dc40a7..70c7eed17 100644 --- a/src/platform/qt/input/SDLInputDriver.h +++ b/src/platform/qt/input/SDLInputDriver.h @@ -109,6 +109,7 @@ private: size_t m_index; #if SDL_VERSION_ATLEAST(2, 0, 0) char m_guid[34]{}; + SDL_JoystickID m_id; #endif bool verify() const; From bdffa83e6b57e879cdbe113771124f7a088e5e30 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:03:06 -0700 Subject: [PATCH 114/148] GB, GBA Core: Fix memory leak if reloading debug symbols Also fix loading an ELF if the current seek is not 0 --- CHANGES | 1 + src/gb/core.c | 4 +++- src/gba/core.c | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index a0b87e214..5f82de643 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,7 @@ Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves + - GB, GBA Core: Fix memory leak if reloading debug symbols - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Memory: Let raw access read high MMIO addresses diff --git a/src/gb/core.c b/src/gb/core.c index 9dbf36bc1..4e8351fc6 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -1107,7 +1107,9 @@ static void _GBCoreDetachDebugger(struct mCore* core) { } static void _GBCoreLoadSymbols(struct mCore* core, struct VFile* vf) { - core->symbolTable = mDebuggerSymbolTableCreate(); + if (!core->symbolTable) { + core->symbolTable = mDebuggerSymbolTableCreate(); + } #ifdef ENABLE_VFS if (!vf && core->dirs.base) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); diff --git a/src/gba/core.c b/src/gba/core.c index 256aebdab..8e44990b5 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1243,7 +1243,14 @@ static void _GBACoreDetachDebugger(struct mCore* core) { static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { bool closeAfter = false; - core->symbolTable = mDebuggerSymbolTableCreate(); + if (!core->symbolTable) { + core->symbolTable = mDebuggerSymbolTableCreate(); + } + off_t seek; + if (vf) { + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } #ifdef ENABLE_VFS #ifdef USE_ELF if (!vf && core->dirs.base) { @@ -1273,6 +1280,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } if (closeAfter) { vf->close(vf); + } else { + vf->seek(vf, seek, SEEK_SET); } } From 5ebf3822cc22998c18acca507207f5cdeba69247 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:08:29 -0700 Subject: [PATCH 115/148] Debugger: Remove redundant ifdef --- src/debugger/cli-debugger.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index b5a6595d3..c21d17a72 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -1427,9 +1427,7 @@ static void _loadSymbols(struct CLIDebugger* debugger, struct CLIDebugVector* dv #ifdef USE_ELF struct ELF* elf = ELFOpen(vf); if (elf) { -#ifdef ENABLE_DEBUGGERS mCoreLoadELFSymbols(symbolTable, elf); -#endif ELFClose(elf); } else #endif From 4c161ff4df002e5810eb46d9af030434ca66f53e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 11:13:32 -0700 Subject: [PATCH 116/148] GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf --- CHANGES | 1 + src/gba/core.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGES b/CHANGES index 5f82de643..ff9c74489 100644 --- a/CHANGES +++ b/CHANGES @@ -26,6 +26,7 @@ Other fixes: - GB, GBA Core: Fix memory leak if reloading debug symbols - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks + - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf - GBA Memory: Let raw access read high MMIO addresses - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) - Qt: Fix potential crash when configuring shortcuts diff --git a/src/gba/core.c b/src/gba/core.c index 8e44990b5..6b8d15f1d 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1242,6 +1242,7 @@ static void _GBACoreDetachDebugger(struct mCore* core) { } static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { + struct GBA* gba = core->board; bool closeAfter = false; if (!core->symbolTable) { core->symbolTable = mDebuggerSymbolTableCreate(); @@ -1263,6 +1264,16 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); } #endif + if (!vf && gba->mbVf) { + vf = gba->mbVf; + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } + if (!vf && gba->romVf) { + vf = gba->romVf; + seek = vf->seek(vf, 0, SEEK_CUR); + vf->seek(vf, 0, SEEK_SET); + } if (!vf) { return; } From 0484cd5d3162fc252720a998910ce92d0a0f2640 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 7 Jul 2024 12:24:24 -0700 Subject: [PATCH 117/148] GBA: Remove unused field --- include/mgba/internal/gba/gba.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index 83246ff98..cc340d760 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -81,7 +81,6 @@ struct GBA { struct GBATimer timers[4]; - int springIRQ; struct mTimingEvent irqEvent; uint32_t biosChecksum; From 9b598d2fe4c5ae49180fd381c742e5cb8a0973f0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 11 Jul 2024 14:09:35 -0700 Subject: [PATCH 118/148] GBA Core: Fix crash after loading debug symbols (fixes #3254) --- src/gba/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gba/core.c b/src/gba/core.c index 6b8d15f1d..11b1ccfc4 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1265,11 +1265,13 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } #endif if (!vf && gba->mbVf) { + closeAfter = false; vf = gba->mbVf; seek = vf->seek(vf, 0, SEEK_CUR); vf->seek(vf, 0, SEEK_SET); } if (!vf && gba->romVf) { + closeAfter = false; vf = gba->romVf; seek = vf->seek(vf, 0, SEEK_CUR); vf->seek(vf, 0, SEEK_SET); From d1ab52112ae82392f5afbfcd4bcf5f34f35603e8 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Fri, 12 Jul 2024 19:15:45 -0500 Subject: [PATCH 119/148] Don't try to load non-.sym files as ARMIPS symbols --- src/gba/core.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index 11b1ccfc4..e05767dd6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1260,8 +1260,12 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { } #endif if (!vf && core->dirs.base) { - closeAfter = true; vf = mDirectorySetOpenSuffix(&core->dirs, core->dirs.base, ".sym", O_RDONLY); + if (vf) { + mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); + vf->close(vf); + } + return; } #endif if (!vf && gba->mbVf) { @@ -1286,11 +1290,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { mCoreLoadELFSymbols(core->symbolTable, elf); #endif ELFClose(elf); - } else -#endif - { - mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); } +#endif if (closeAfter) { vf->close(vf); } else { From eb1b5718c3d69cc3778865a0b6b59e55a0807766 Mon Sep 17 00:00:00 2001 From: Adam Higerd Date: Fri, 12 Jul 2024 19:26:42 -0500 Subject: [PATCH 120/148] Fix misplaced return in previous PR --- src/gba/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gba/core.c b/src/gba/core.c index e05767dd6..1f39afea6 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -1264,8 +1264,8 @@ static void _GBACoreLoadSymbols(struct mCore* core, struct VFile* vf) { if (vf) { mDebuggerLoadARMIPSSymbols(core->symbolTable, vf); vf->close(vf); + return; } - return; } #endif if (!vf && gba->mbVf) { From 09f456484cb401856d5dda1af5b80a659b7c2097 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 19 Jul 2024 19:42:38 -0700 Subject: [PATCH 121/148] GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 --- CHANGES | 1 + src/gb/serialize.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CHANGES b/CHANGES index ff9c74489..9af2528d9 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Other fixes: - Debugger: Fix writing to specific segment in command-line debugger - GB: Fix uninitialized save data when loading undersized temporary saves - GB, GBA Core: Fix memory leak if reloading debug symbols + - GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf diff --git a/src/gb/serialize.c b/src/gb/serialize.c index 0abdc1958..8f874d8eb 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -122,6 +122,13 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { mLOG(GB_STATE, WARN, "Savestate is corrupted: video y is out of range"); error = true; } + + GBSerializedVideoFlags videoFlags = state->video.flags; + if (check16 >= GB_VIDEO_VERTICAL_PIXELS && GBSerializedVideoFlagsGetMode(videoFlags) != 1) { + mLOG(GB_STATE, WARN, "Savestate is corrupted: video y is in vblank but mode is not vblank"); + error = true; + } + LOAD_16LE(ucheck16, 0, &state->memory.dmaDest); if (ucheck16 + state->memory.dmaRemaining > GB_SIZE_OAM) { mLOG(GB_STATE, WARN, "Savestate is corrupted: DMA destination is out of range"); From fde15b6e7d4fcd858ab4d59fc9e83752abe2b982 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Fri, 9 Aug 2024 10:52:47 +0800 Subject: [PATCH 122/148] Remove SDL_WINDOW_OPENGL flag in mSDLSWInit --- src/platform/sdl/sw-sdl2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/sdl/sw-sdl2.c b/src/platform/sdl/sw-sdl2.c index 75ad1c2ea..734ee903c 100644 --- a/src/platform/sdl/sw-sdl2.c +++ b/src/platform/sdl/sw-sdl2.c @@ -22,7 +22,7 @@ void mSDLSWCreate(struct mSDLRenderer* renderer) { bool mSDLSWInit(struct mSDLRenderer* renderer) { unsigned width, height; renderer->core->baseVideoSize(renderer->core, &width, &height); - renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); + renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->player.window = renderer->window; renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); From ff216ad83babf27476783b14ec3131517a7aa745 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 10 Aug 2024 21:20:08 -0700 Subject: [PATCH 123/148] Res: Update nointro.dat --- res/nointro.dat | 11625 ++++++++++++++++++++++++++++------------------ 1 file changed, 7139 insertions(+), 4486 deletions(-) diff --git a/res/nointro.dat b/res/nointro.dat index d63e3f818..48047026f 100644 --- a/res/nointro.dat +++ b/res/nointro.dat @@ -1,7 +1,7 @@ clrmamepro ( name "Nintendo - Game Boy Advance" description "Nintendo - Game Boy Advance" - version 20240104-012251 + version 20240807-214821 author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, FakeShemp, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Prominos, Psychofox11, psykopat, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" @@ -597,7 +597,7 @@ game ( 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 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 3abc30bd sha1 1438db8336bd6204ad81011a7ed2b2e04850326a ) ) game ( @@ -648,12 +648,6 @@ game ( 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 "2048 Pool (World) (Aftermarket) (Unl)" - description "2048 Pool (World) (Aftermarket) (Unl)" - rom ( name "2048 Pool (World) (Aftermarket) (Unl).gba" size 203440 crc 9df6ae4f sha1 c93a9cf3502237b474e70de8dee274901ee7ecb2 ) -) - game ( name "2K Sports - Major League Baseball 2K7 (USA) (Beta)" description "2K Sports - Major League Baseball 2K7 (USA) (Beta)" @@ -711,7 +705,7 @@ game ( 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 sha1 e91e58c62363fb10dd4ffcaeb09c98ca6b9b5a77 ) + rom ( name "3 Games in One! - Breakout + Centipede + Warlords (USA).gba" size 4194304 crc 02e0cca4 sha1 e91e58c62363fb10dd4ffcaeb09c98ca6b9b5a77 flags verified ) ) game ( @@ -993,13 +987,13 @@ game ( 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 sha1 16ba112f07d02484febd554f902bb18776144186 ) + 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 sha1 68778c93fc16d06b97462174d91035cb0d0d8bd5 ) + rom ( name "Adventures of Jimmy Neutron Boy Genius, The - Jet Fusion (USA, Europe).gba" size 4194304 crc 67756000 sha1 68778c93fc16d06b97462174d91035cb0d0d8bd5 flags verified ) ) game ( @@ -1075,9 +1069,9 @@ game ( ) game ( - name "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" - description "Agoria - Ode to Fate (World) (Aftermarket) (Unl)" - rom ( name "Agoria - Ode to Fate (World) (Aftermarket) (Unl).gba" size 2725504 crc 67d3361f sha1 cb0b83b85a290c223cd3249b37ae7207d3efde06 ) + name "Agoria - Ode to Fate (World) (Unl)" + description "Agoria - Ode to Fate (World) (Unl)" + rom ( name "Agoria - Ode to Fate (World) (Unl).gba" size 2725504 crc 67d3361f sha1 cb0b83b85a290c223cd3249b37ae7207d3efde06 ) ) game ( @@ -1110,6 +1104,12 @@ game ( rom ( name "Aigle de Guerre, L' (France).gba" size 8388608 crc 36a0e152 sha1 567809bf35d62418a69e469d0cfa9993a889c030 ) ) +game ( + name "Airball (World) (v1.3) (Unl)" + description "Airball (World) (v1.3) (Unl)" + rom ( name "Airball (World) (v1.3) (Unl).gba" size 1365740 crc 52dac8c6 sha1 50c772f91fa431b8b3d01133762015e127d4f816 ) +) + game ( name "AirForce Delta II (Japan) (En,Ja,Fr,De)" description "AirForce Delta II (Japan) (En,Ja,Fr,De)" @@ -1185,7 +1185,7 @@ game ( game ( name "Alex Rider - Stormbreaker (USA)" description "Alex Rider - Stormbreaker (USA)" - rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc cca55dfd sha1 e9ba9d340701173ccd3a4d279630e1541ed96a73 ) + rom ( name "Alex Rider - Stormbreaker (USA).gba" size 4194304 crc cca55dfd sha1 e9ba9d340701173ccd3a4d279630e1541ed96a73 flags verified ) ) game ( @@ -1269,7 +1269,7 @@ game ( game ( name "American Idol (USA)" description "American Idol (USA)" - rom ( name "American Idol (USA).gba" size 16777216 crc f053ffbf sha1 13236689db1e2236673ae59c2a8ff84340a8a8c2 ) + rom ( name "American Idol (USA).gba" size 16777216 crc f053ffbf sha1 13236689db1e2236673ae59c2a8ff84340a8a8c2 flags verified ) ) game ( @@ -1302,72 +1302,6 @@ game ( rom ( name "Angelique (Japan).gba" size 4194304 crc c9d41f35 sha1 cf01dfc9f25c805b9a72524903f742f11570a8eb ) ) -game ( - name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl).gba" size 1710888 crc 3346891f sha1 270c426705df767a4ad2dc69d039842442f779b2 flags verified ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl).gba" size 1729120 crc a354d555 sha1 d7cd0ab9d622187d4ce55bf0c7f14a24ee781710 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl).gba" size 1775856 crc 41ea5b0b sha1 e351bc6a9046ec002fc2dfdee061047908bd4350 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl).gba" size 597104 crc 0a9098b4 sha1 0992fb6f38e49426adc834fb3831748a1caa1bc0 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl).gba" size 811840 crc 63c1cc2c sha1 faca8225ee20b8e5edb14e005af77b63c6f51446 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl).gba" size 1714000 crc eebb016f sha1 008a9d06f78bccc540ca4ece4d1982de76f95901 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl).gba" size 1710624 crc ba271987 sha1 04f1e79e79e894d8f45ed1ea2ff5aa67053f0ab3 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl).gba" size 1710624 crc df7108e3 sha1 bd267fd7e762acb8cd595e54bfd51a139864759e ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" - description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt).gba" size 1714000 crc 54ff2e56 sha1 0386315fc140db2a43a6f927c04de658bd800da9 ) -) - -game ( - name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" - description "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" - rom ( name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl).gba" size 1710952 crc cb4e2768 sha1 a7297cf4ecffc1f93f86edde68e1ff42e8099f3b ) -) - game ( name "Animal Mania - Dokidoki Aishou Check (Japan)" description "Animal Mania - Dokidoki Aishou Check (Japan)" @@ -1405,15 +1339,15 @@ game ( ) game ( - name "Another World (Europe) (En,Fr) (v2.1) (Unl)" - description "Another World (Europe) (En,Fr) (v2.1) (Unl)" - rom ( name "Another World (Europe) (En,Fr) (v2.1) (Unl).gba" size 2010358 crc 86c4f772 sha1 41d39a0c34f72469dd3fbcc90190605b8ada93e6 ) + name "Another World (World) (En,Fr) (v2.1) (Unl)" + description "Another World (World) (En,Fr) (v2.1) (Unl)" + rom ( name "Another World (World) (En,Fr) (v2.1) (Unl).gba" size 2010358 crc 86c4f772 sha1 41d39a0c34f72469dd3fbcc90190605b8ada93e6 ) ) game ( - name "Another World (Europe) (Fr) (v1.2) (Unl)" - description "Another World (Europe) (Fr) (v1.2) (Unl)" - rom ( name "Another World (Europe) (Fr) (v1.2) (Unl).gba" size 1823864 crc 1a1397de sha1 5bcc5c9a633e2226411dd41f1a191b9fcc793d92 ) + name "Another World (World) (Fr) (v1.2) (Unl)" + description "Another World (World) (Fr) (v1.2) (Unl)" + rom ( name "Another World (World) (Fr) (v1.2) (Unl).gba" size 1823864 crc 1a1397de sha1 5bcc5c9a633e2226411dd41f1a191b9fcc793d92 ) ) game ( @@ -1446,22 +1380,16 @@ game ( rom ( name "Ao-Zora to Nakama-tachi - Yume no Bouken (Japan).gba" size 4194304 crc ad9af125 sha1 0e6c92477793ce495caa400899effb4f87384f3c ) ) -game ( - name "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" - description "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" - rom ( name "Apotris (World) (v3.4.5) (Aftermarket) (Unl).gba" size 4194304 crc 55ae4312 sha1 fb7142bcc30f71f187cc51b7fcbc5a3958374c6c ) -) - 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 sha1 5b1dcab6984d454e3ed3f3fe107f43a645283c0f ) + rom ( name "Archer Maclean's 3D Pool (USA).gba" size 4194304 crc 4202a9cd sha1 5b1dcab6984d454e3ed3f3fe107f43a645283c0f flags verified ) ) game ( name "Arctic Tale (USA)" description "Arctic Tale (USA)" - rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397ac0 sha1 9654a5c6a40b946c35cc9e09aae48bdd47ea7692 ) + rom ( name "Arctic Tale (USA).gba" size 4194304 crc 81397ac0 sha1 9654a5c6a40b946c35cc9e09aae48bdd47ea7692 flags verified ) ) game ( @@ -1578,6 +1506,12 @@ game ( 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) (Beta)" + description "Atomic Betty (USA, Europe) (Beta)" + rom ( name "Atomic Betty (USA, Europe) (Beta).gba" size 8388608 crc b79472b8 sha1 1dfa6ad1bdc0ee52b4e53c78f29d92ec208db1b1 ) +) + game ( name "Atomic Betty (USA, Europe)" description "Atomic Betty (USA, Europe)" @@ -1585,9 +1519,9 @@ game ( ) game ( - name "Atomic Betty (USA, Europe) (Beta)" - description "Atomic Betty (USA, Europe) (Beta)" - rom ( name "Atomic Betty (USA, Europe) (Beta).gba" size 8388608 crc b79472b8 sha1 1dfa6ad1bdc0ee52b4e53c78f29d92ec208db1b1 ) + name "Atomix (World) (Unl)" + description "Atomix (World) (Unl)" + rom ( name "Atomix (World) (Unl).gba" size 934600 crc fc610889 sha1 ecf3848324a25fa57988f67167f0b58e648989ce ) ) game ( @@ -1647,7 +1581,7 @@ game ( game ( name "Azumanga Daiou Advance (Japan)" description "Azumanga Daiou Advance (Japan)" - rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704f6 sha1 95b266e8ecdae1938cd180f597e5f21cb86d8b96 ) + rom ( name "Azumanga Daiou Advance (Japan).gba" size 8388608 crc 216704f6 sha1 95b266e8ecdae1938cd180f597e5f21cb86d8b96 flags verified ) ) game ( @@ -1737,7 +1671,7 @@ game ( game ( name "Backyard Football 2006 (USA)" description "Backyard Football 2006 (USA)" - rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc db0723e3 sha1 53d134268d2fc973388861687e50f77cc4682941 ) + rom ( name "Backyard Football 2006 (USA).gba" size 4194304 crc db0723e3 sha1 53d134268d2fc973388861687e50f77cc4682941 flags verified ) ) game ( @@ -1827,7 +1761,7 @@ game ( 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 sha1 f335fede72cd0273fcce925a20ca272ede08c15b ) + rom ( name "Banjo-Kazooie - Grunty's Revenge (Europe) (En,Fr,De).gba" size 8388608 crc fb4f38e2 sha1 f335fede72cd0273fcce925a20ca272ede08c15b flags verified ) ) game ( @@ -1890,6 +1824,30 @@ game ( 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) (Beta) (2005-01-21)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-01-21)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-01-21).gba" size 136680 crc ae6cf631 sha1 fb0548d72eff99b7dabdd34112e55f8bea6326ec ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-02-18).gba" size 360672 crc bd807770 sha1 84a5686f5c5dee770e6b1bbbc1a60648387cf255 ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-03-18).gba" size 1502628 crc 4b58b5d6 sha1 e822173e315138443e9fec509621dc88afcbcc0b ) +) + +game ( + name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15)" + description "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15)" + rom ( name "Barbie and the Magic of Pegasus (USA) (Beta) (2005-04-15).gba" size 2837392 crc 46f21e41 sha1 74e261c56123806b8cbd31ed907fe25a5ad99b62 ) +) + game ( name "Barbie and the Magic of Pegasus (USA)" description "Barbie and the Magic of Pegasus (USA)" @@ -2046,6 +2004,18 @@ game ( rom ( name "Battle Network - Rockman EXE 2 (Japan).gba" size 8388608 crc 98e4f096 sha1 6ed31ea56328673ba9d87186a7d506c701508e28 ) ) +game ( + name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" + description "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" + rom ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console).gba" size 8388608 crc 44d44721 sha1 1c2416dfb86936752c5f68861f6339feac21458f ) +) + +game ( + name "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection)" + description "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection)" + rom ( name "Battle Network - Rockman EXE 2 (World) (Ja) (Mega Man Battle Network Legacy Collection).gba" size 8388608 crc 046eed8d sha1 7f6e770282718813f1115b29ec502f77422ac300 ) +) + game ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1)" description "Battle Network - Rockman EXE 2 (Japan) (Rev 1)" @@ -2053,9 +2023,9 @@ game ( ) game ( - name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" - description "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console)" - rom ( name "Battle Network - Rockman EXE 2 (Japan) (Rev 1) (Virtual Console).gba" size 8388608 crc 44d44721 sha1 1c2416dfb86936752c5f68861f6339feac21458f ) + 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 ) ) game ( @@ -2071,15 +2041,9 @@ game ( ) 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 ) -) - -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 sha1 ff65af8fea15ecf5a556595efe414d1211a9ab4e ) + 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 sha1 e089a2254496a4791666c8122585cb785e3012fc ) ) game ( @@ -2089,9 +2053,9 @@ game ( ) 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 sha1 e089a2254496a4791666c8122585cb785e3012fc ) + 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 sha1 ff65af8fea15ecf5a556595efe414d1211a9ab4e ) ) game ( @@ -2121,7 +2085,7 @@ game ( game ( name "BattleBots - Design & Destroy (USA)" description "BattleBots - Design & Destroy (USA)" - rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8d5ffbca sha1 635986e584ebdc347c77eb45b1370a1206fbd7d7 ) + rom ( name "BattleBots - Design & Destroy (USA).gba" size 4194304 crc 8d5ffbca sha1 635986e584ebdc347c77eb45b1370a1206fbd7d7 flags verified ) ) game ( @@ -2193,7 +2157,7 @@ game ( 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 sha1 cd527c8c24e20e33913fc45199e64b3e6138a6e5 ) + rom ( name "Beyblade V-Force - Ultimate Blader Jam (USA).gba" size 8388608 crc 4a49272b sha1 cd527c8c24e20e33913fc45199e64b3e6138a6e5 flags verified ) ) game ( @@ -2262,6 +2226,12 @@ game ( 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 sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) +) + game ( name "Bionicle - Maze of Shadows (USA)" description "Bionicle - Maze of Shadows (USA)" @@ -2274,12 +2244,6 @@ game ( rom ( name "Bionicle - Maze of Shadows (Europe) (En,De) (Rev 1).gba" size 8388608 crc 9d66ec5e sha1 430c7dac6f7dd989294a8ac1cfdabd9e74b3e682 ) ) -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 sha1 7ff9811e2bd40b24da02be194213d41a0885aa34 ) -) - game ( name "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" description "Bionicle Heroes (USA) (En,Fr,De,Es,It,Da)" @@ -2352,6 +2316,12 @@ game ( rom ( name "Black Matrix Zero (Japan).gba" size 8388608 crc 2b2afa2e sha1 697f85513ab5704b8b1d554e087a45bfdb92ec33 ) ) +game ( + name "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10)" + description "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10)" + rom ( name "Black Sigil - Blade of the Exiled (USA) (Proto) (2007-02-10).gba" size 12478504 crc 010035a8 sha1 567e4efa496eabbf1db285e0ec02a8da8a8c07a3 ) +) + game ( name "Blackthorne (USA)" description "Blackthorne (USA)" @@ -2376,12 +2346,6 @@ game ( rom ( name "Bleach Advance - Kurenai ni Somaru Soul Society (Japan).gba" size 33554432 crc 9de5cd08 sha1 29d24c38d3ec8bbe9d81df2f5ff61c4a2dadcee4 ) ) -game ( - name "Blender Bros. (World) (Aftermarket) (Unl)" - description "Blender Bros. (World) (Aftermarket) (Unl)" - rom ( name "Blender Bros. (World) (Aftermarket) (Unl).gba" size 8388608 crc 440f2f06 sha1 8f9ca62306b7ab56d8da45673d7b7d0eb4c349c5 ) -) - game ( name "Blender Bros. (USA)" description "Blender Bros. (USA)" @@ -2415,7 +2379,7 @@ game ( game ( 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 ) + rom ( name "Board Game Classics - Backgammon & Chess & Draughts (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e5c745d8 sha1 f9a3058e55d72efdebc5e2b4d2b5d6e00e71e5ff flags verified ) ) game ( @@ -2442,6 +2406,12 @@ game ( 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) (Sample)" + description "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 - The Sun Is in Your Hand (USA)" description "Boktai - The Sun Is in Your Hand (USA)" @@ -2454,12 +2424,6 @@ game ( 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) (Sample)" - description "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)" @@ -2541,7 +2505,7 @@ game ( 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 sha1 4d514fe19b59d42be9a118c99e2008efee2aedcb ) + rom ( name "Bomberman Max 2 - Red Advance (Europe) (En,Fr,De).gba" size 16777216 crc 67d2e5b8 sha1 4d514fe19b59d42be9a118c99e2008efee2aedcb flags verified ) ) game ( @@ -2553,7 +2517,7 @@ game ( game ( name "Bomberman Tournament (USA, Europe)" description "Bomberman Tournament (USA, Europe)" - rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282e6 sha1 da44a5d65f1a00d75a57e5b46e30f9e4e2d18f6c ) + rom ( name "Bomberman Tournament (USA, Europe).gba" size 4194304 crc 240282e6 sha1 da44a5d65f1a00d75a57e5b46e30f9e4e2d18f6c flags verified ) ) game ( @@ -2691,7 +2655,7 @@ game ( game ( name "Bratz - The Movie (USA)" description "Bratz - The Movie (USA)" - rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2ef801c0 sha1 bfab6a139275b6968531a43ab34d4710e9efc7ef ) + rom ( name "Bratz - The Movie (USA).gba" size 4194304 crc 2ef801c0 sha1 bfab6a139275b6968531a43ab34d4710e9efc7ef flags verified ) ) game ( @@ -2784,12 +2748,6 @@ game ( rom ( name "Broken Circle (Europe) (En,It) (Proto).gba" size 8409344 crc e78bc690 sha1 d015a5039ff5d08eeba3ddb16470eaab259631d0 ) ) -game ( - name "Broken Circle (World) (En,It) (Aftermarket) (Unl)" - description "Broken Circle (World) (En,It) (Aftermarket) (Unl)" - rom ( name "Broken Circle (World) (En,It) (Aftermarket) (Unl).gba" size 16777216 crc 3212c09b sha1 e04a71dbe7b640cc53e81f447856e60666e64aa3 ) -) - 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)" @@ -2805,13 +2763,13 @@ game ( game ( name "Brother Bear (USA)" description "Brother Bear (USA)" - rom ( name "Brother Bear (USA).gba" size 8388608 crc 342de1d6 sha1 89e6903500f62e11483402b76c1454af788646c0 ) + rom ( name "Brother Bear (USA).gba" size 8388608 crc 342de1d6 sha1 89e6903500f62e11483402b76c1454af788646c0 flags verified ) ) 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 sha1 7e217e5f644b0333c51f3827df5fd64023ac7c0e ) + rom ( name "Brother Bear (Europe) (Fr,De,Es,It,Nl,Sv,Da).gba" size 8388608 crc fd814097 sha1 7e217e5f644b0333c51f3827df5fd64023ac7c0e flags verified ) ) game ( @@ -2877,7 +2835,7 @@ game ( 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 sha1 24962220f242b49231969f6d313e325148886106 ) + rom ( name "Butt-Ugly Martians - B.K.M. Battles (USA).gba" size 4194304 crc 74be9148 sha1 24962220f242b49231969f6d313e325148886106 flags verified ) ) game ( @@ -2901,7 +2859,7 @@ game ( 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 sha1 f6590b9f069856c1a9e43d19b4b05e3175a97e02 ) + rom ( name "Cabela's Big Game Hunter (USA).gba" size 8388608 crc 70a8a141 sha1 f6590b9f069856c1a9e43d19b4b05e3175a97e02 flags verified ) ) game ( @@ -3078,12 +3036,6 @@ game ( 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 sha1 2321b90c04690e8e4973a4495d25c9197ab5bfcc ) -) - game ( name "Casper (USA) (En,Fr,Es)" description "Casper (USA) (En,Fr,Es)" @@ -3091,9 +3043,15 @@ game ( ) game ( - name "Castlevania (Europe) (Virtual Console)" - description "Castlevania (Europe) (Virtual Console)" - rom ( name "Castlevania (Europe) (Virtual Console).gba" size 8388608 crc dba05255 sha1 b5fa3402a8fb86786f97d08f88b3cbc790bb5d6e ) + 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 sha1 2321b90c04690e8e4973a4495d25c9197ab5bfcc ) +) + +game ( + name "Castle Master (World) (Unl)" + description "Castle Master (World) (Unl)" + rom ( name "Castle Master (World) (Unl).gba" size 259192 crc 307f7d77 sha1 bf78a4efde3b5c3bab65bd7156c69907fb86b512 ) ) game ( @@ -3102,6 +3060,12 @@ game ( rom ( name "Castlevania (Europe) (Castlevania Advance Collection).gba" size 8388608 crc 050e2164 sha1 30a2fd3fe95a8a84b02da7ddbc8b2a90e0553d9b ) ) +game ( + name "Castlevania (Europe) (Virtual Console)" + description "Castlevania (Europe) (Virtual Console)" + rom ( name "Castlevania (Europe) (Virtual Console).gba" size 8388608 crc dba05255 sha1 b5fa3402a8fb86786f97d08f88b3cbc790bb5d6e ) +) + game ( name "Castlevania (Europe)" description "Castlevania (Europe)" @@ -3138,18 +3102,6 @@ game ( rom ( name "Castlevania - Aria of Sorrow (USA) (Castlevania Advance Collection).gba" size 8388608 crc ca9b82dd sha1 f2869a861f1be637a1d1b57009cb42cc06b82e09 ) ) -game ( - name "Castlevania - Aria of Sorrow (USA) (Virtual Console)" - description "Castlevania - Aria of Sorrow (USA) (Virtual Console)" - rom ( name "Castlevania - Aria of Sorrow (USA) (Virtual Console).gba" size 8388608 crc 28baa30e sha1 b69a77970878b453e2b308fe124641f66925ae6a ) -) - -game ( - name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" - description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" - rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console).gba" size 8388608 crc d97dbfec sha1 458c42a6b8fd6cf18579b0f7eef9dcd12b43c12b ) -) - game ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De)" @@ -3163,9 +3115,15 @@ game ( ) 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 sha1 3aeb81ee60fa3e56a56ee069b0ce0d8bc34d9c4c ) + name "Castlevania - Aria of Sorrow (USA) (Virtual Console)" + description "Castlevania - Aria of Sorrow (USA) (Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (USA) (Virtual Console).gba" size 8388608 crc 28baa30e sha1 b69a77970878b453e2b308fe124641f66925ae6a ) +) + +game ( + name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" + description "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console)" + rom ( name "Castlevania - Aria of Sorrow (Europe) (En,Fr,De) (Virtual Console).gba" size 8388608 crc d97dbfec sha1 458c42a6b8fd6cf18579b0f7eef9dcd12b43c12b ) ) game ( @@ -3175,9 +3133,9 @@ game ( ) game ( - name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" - description "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" - rom ( name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection).gba" size 8388608 crc 14c1ab7c sha1 9483aa48b384ff3142c47fe81c13ca874a608eb0 ) + name "Castlevania - Byakuya no Concerto (Japan)" + description "Castlevania - Byakuya no Concerto (Japan)" + rom ( name "Castlevania - Byakuya no Concerto (Japan).gba" size 8388608 crc 379b3248 sha1 3aeb81ee60fa3e56a56ee069b0ce0d8bc34d9c4c ) ) game ( @@ -3192,6 +3150,12 @@ game ( rom ( name "Castlevania - Circle of the Moon (USA) (Virtual Console).gba" size 8388608 crc d5412e91 sha1 e055b4ab00e16ec39c9036ef85463c770d809c6c ) ) +game ( + name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" + description "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection)" + rom ( name "Castlevania - Circle of the Moon (USA) (Castlevania Advance Collection).gba" size 8388608 crc 14c1ab7c sha1 9483aa48b384ff3142c47fe81c13ca874a608eb0 ) +) + game ( name "Castlevania - Harmony of Dissonance (Europe) (Castlevania Advance Collection)" description "Castlevania - Harmony of Dissonance (Europe) (Castlevania Advance Collection)" @@ -3246,12 +3210,6 @@ game ( rom ( name "Cat in the Hat, The (USA).gba" size 4194304 crc 13c2249e sha1 9340482db02bf5263429a15798d06c509017aa93 ) ) -game ( - name "Cat's Curse (World) (Aftermarket) (Unl)" - description "Cat's Curse (World) (Aftermarket) (Unl)" - rom ( name "Cat's Curse (World) (Aftermarket) (Unl).gba" size 353052 crc a35d87de sha1 4a149baad17840948c2d4ffdf068bfaf1116a024 ) -) - game ( name "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" description "Catwoman (USA, Europe) (En,Fr,De,Es,It,Nl)" @@ -3270,24 +3228,6 @@ game ( rom ( name "Catz (Europe) (En,Fr,De,It).gba" size 8388608 crc c3aa382d sha1 0dab5140ebc541e03dd00a8ce87cce4f0326b0e6 ) ) -game ( - name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl).gba" size 5416932 crc f79b0d53 sha1 756f02396a150698e695ad4afd24445e2af70576 ) -) - -game ( - name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl).gba" size 5418248 crc f5d36ad2 sha1 95a86dff641b11b4c2ed0d0fe8152c33b462d927 ) -) - -game ( - name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" - description "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl).gba" size 5418424 crc ff0e8ada sha1 08512605e5c02e81a72e24c2c8d4959d8e84e1f4 ) -) - game ( name "Chaoji Maliou 2 (China)" description "Chaoji Maliou 2 (China)" @@ -3333,19 +3273,7 @@ game ( game ( name "Cheetah Girls, The (USA)" description "Cheetah Girls, The (USA)" - rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc e2efc2aa sha1 f46296d4ab97d539dbcfa551e05ed6d58715c5b6 ) -) - -game ( - name "Chessmaster (USA)" - description "Chessmaster (USA)" - 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 sha1 76a69da6183239f4ab0c45ef43c3ef7e2bd96d03 ) + rom ( name "Cheetah Girls, The (USA).gba" size 8388608 crc e2efc2aa sha1 f46296d4ab97d539dbcfa551e05ed6d58715c5b6 flags verified ) ) game ( @@ -3360,6 +3288,18 @@ game ( 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 sha1 5e3ac500d119a2bbe67d480edc1c1dd09061e385 ) +) + +game ( + name "Chessmaster (Germany)" + description "Chessmaster (Germany)" + rom ( name "Chessmaster (Germany).gba" size 4194304 crc 06abacc5 sha1 76a69da6183239f4ab0c45ef43c3ef7e2bd96d03 ) +) + game ( name "Chi Vuol Essere Milionario (Italy)" description "Chi Vuol Essere Milionario (Italy)" @@ -3414,6 +3354,12 @@ game ( rom ( name "Chinmoku no Iseki - Estpolis Gaiden (Japan) (Virtual Console).gba" size 8388608 crc 36cc41bf sha1 882cc3c71ce7025abbe0a65a2f007428887d7113 ) ) +game ( + name "Chip Advance (World) (En,Fr) (v2.1) (Unl)" + description "Chip Advance (World) (En,Fr) (v2.1) (Unl)" + rom ( name "Chip Advance (World) (En,Fr) (v2.1) (Unl).gba" size 10498128 crc 586c4345 sha1 29c889b3c25b851f590685dea03400110e98fabd ) +) + game ( name "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" description "Chobits for Game Boy Advance - Atashi Dake no Hito (Japan)" @@ -3528,6 +3474,12 @@ game ( rom ( name "Cinnamoroll - Koko ni Iru yo (Japan).gba" size 4194304 crc 8376d53b sha1 f13533eb284f7321d8709df058ff28d61a031802 ) ) +game ( + name "City Connection (World) (Fr) (v1.7) (Unl)" + description "City Connection (World) (Fr) (v1.7) (Unl)" + rom ( name "City Connection (World) (Fr) (v1.7) (Unl).gba" size 1924768 crc 234a42a5 sha1 e1c6d46521310d96fedf46a39982ad1372cdc42c ) +) + game ( name "Classic NES Series - Bomberman (USA, Europe)" description "Classic NES Series - Bomberman (USA, Europe)" @@ -3573,7 +3525,7 @@ game ( 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 1048576 crc c28df82f sha1 843d853ed28a116c85a5357f9a94e9179f36a6d0 ) + rom ( name "Classic NES Series - Pac-Man (USA, Europe).gba" size 1048576 crc c28df82f sha1 843d853ed28a116c85a5357f9a94e9179f36a6d0 flags verified ) ) game ( @@ -3591,7 +3543,7 @@ game ( 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 1048576 crc 9cd2d5dd sha1 b2088582808480e0d70c63a777b046409d4e15c4 ) + rom ( name "Classic NES Series - Xevious (USA, Europe).gba" size 1048576 crc 9cd2d5dd sha1 b2088582808480e0d70c63a777b046409d4e15c4 flags verified ) ) game ( @@ -3624,6 +3576,12 @@ game ( rom ( name "Codename - Kids Next Door - Operation S.O.D.A. (USA).gba" size 8388608 crc 420a81b7 sha1 bbd176cc9a5331fdfdb332ad037d869610e4b3fb ) ) +game ( + name "Coin Adventure (World) (Unl)" + description "Coin Adventure (World) (Unl)" + rom ( name "Coin Adventure (World) (Unl).gba" size 677920 crc bb3a4566 sha1 088aeb8d40927969c690a66321d7006751a73e20 ) +) + game ( name "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" description "Colin McRae Rally 2.0 (Europe) (En,Fr,De)" @@ -3759,7 +3717,7 @@ game ( 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 sha1 95b5a68962ce552a71d8212850e85d90d2844b40 ) + rom ( name "Crash & Spyro Superpack - Spyro Orange - The Cortex Conspiracy + Crash Bandicoot Purple - Ripto's Rampage (USA).gba" size 33554432 crc 9b76b90b sha1 a14854c2189516501a51d9e3fce7f10f3593fc9a ) ) game ( @@ -3777,7 +3735,7 @@ game ( 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 sha1 972158859ea08aa5746ab2e0d4c81ac43728adff ) + rom ( name "Crash Bandicoot 2 - N-Tranced (USA).gba" size 8388608 crc 2e16184a sha1 972158859ea08aa5746ab2e0d4c81ac43728adff flags verified ) ) game ( @@ -3873,7 +3831,7 @@ game ( 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 sha1 e17baa57d339f7d85f562441111696e88088fcdd ) + rom ( name "Crayon Shin-chan - Densetsu o Yobu Omake no Miyako Shockgaan! (Japan).gba" size 33554432 crc 52f463fe sha1 10aa9bd3b72ed918e7c59fdbc0cc05e5b48dcc70 ) ) game ( @@ -3966,6 +3924,18 @@ game ( rom ( name "Croket! Great - Toki no Boukensha (Japan).gba" size 16777216 crc f0e81971 sha1 410fb8fe2fe07be146c8454122d874287f92fbac ) ) +game ( + name "Cross Town Heroes (USA)" + description "Cross Town Heroes (USA)" + rom ( name "Cross Town Heroes (USA).gba" size 4194304 crc 0fffb458 sha1 6baa6bfe76b077f365bedffa52346b94689b61d7 ) +) + +game ( + name "Cross Town Heroes (Europe)" + description "Cross Town Heroes (Europe)" + rom ( name "Cross Town Heroes (Europe).gba" size 4194304 crc c9ea02f5 sha1 13310b7f25a0332a8e09e722587ec79aee11c373 ) +) + game ( name "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" description "Crouching Tiger, Hidden Dragon (USA) (En,Fr,Es)" @@ -3979,15 +3949,15 @@ game ( ) 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 sha1 af24d128b28758a8a1bda45b5a24a299e1e14b90 ) + name "Crouching Tiger, Hidden Dragon (USA) (Beta 2)" + description "Crouching Tiger, Hidden Dragon (USA) (Beta 2)" + rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta 2).gba" size 8388608 crc 204ff8d5 sha1 af24d128b28758a8a1bda45b5a24a299e1e14b90 ) ) game ( - name "Cruis'n Velocity (USA, Europe) (Beta)" - description "Cruis'n Velocity (USA, Europe) (Beta)" - rom ( name "Cruis'n Velocity (USA, Europe) (Beta).gba" size 8388608 crc 5436d5da sha1 d1716d4603dd8db7ae8715d5142a60230d17e1d2 ) + name "Crouching Tiger, Hidden Dragon (USA) (Beta 1)" + description "Crouching Tiger, Hidden Dragon (USA) (Beta 1)" + rom ( name "Crouching Tiger, Hidden Dragon (USA) (Beta 1).gba" size 3353604 crc a1d2d006 sha1 3d554e4e33563211865b9c5481444b0b8b4e6127 ) ) game ( @@ -3996,6 +3966,12 @@ game ( rom ( name "Cruis'n Velocity (USA, Europe).gba" size 4194304 crc adf14db5 sha1 762aabc26501dee4aa566e8327600433c8edbf7a ) ) +game ( + name "Cruis'n Velocity (USA, Europe) (Beta)" + description "Cruis'n Velocity (USA, Europe) (Beta)" + rom ( name "Cruis'n Velocity (USA, Europe) (Beta).gba" size 8388608 crc 5436d5da sha1 d1716d4603dd8db7ae8715d5142a60230d17e1d2 ) +) + game ( name "Crushed Baseball (USA)" description "Crushed Baseball (USA)" @@ -4008,18 +3984,18 @@ game ( 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)" - 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 sha1 e178192ba2c78759245541bd54d96d83a8d5d9c6 flags verified ) -) - 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 sha1 fab8b62a141865f12c69334f4db14c837d9d94af ) ) +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 sha1 e178192ba2c78759245541bd54d96d83a8d5d9c6 flags verified ) +) + 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)" @@ -4107,7 +4083,7 @@ game ( game ( name "Dancing Sword - Senkou (Japan)" description "Dancing Sword - Senkou (Japan)" - rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc e2316d47 sha1 5c5f33e0453cba1a60039160564daa53a82db8aa ) + rom ( name "Dancing Sword - Senkou (Japan).gba" size 8388608 crc e2316d47 sha1 5c5f33e0453cba1a60039160564daa53a82db8aa flags verified ) ) game ( @@ -4248,6 +4224,12 @@ game ( rom ( name "Deal or No Deal (USA).gba" size 4194304 crc b6c00edb sha1 3691000350db3b36311439c5d9c9879ee756fea6 ) ) +game ( + name "Decoder Cart (Japan) (En) (Pirate)" + description "Decoder Cart (Japan) (En) (Pirate)" + rom ( name "Decoder Cart (Japan) (En) (Pirate).gba" size 8388608 crc 80aa9cc5 sha1 20c6f5aaf8299dfcdeb76bd633f12da209625b97 ) +) + game ( name "Defender (USA)" description "Defender (USA)" @@ -4272,6 +4254,12 @@ game ( rom ( name "Defender of the Crown (Europe).gba" size 4194304 crc 6968959a sha1 4e37071533e946efd4166efc409562cc21af83d2 ) ) +game ( + name "Deflektor (World) (v1.1) (Unl)" + description "Deflektor (World) (v1.1) (Unl)" + rom ( name "Deflektor (World) (v1.1) (Unl).gba" size 386508 crc 5ec91001 sha1 92682b2404be3b2fd48f96cad0c51f51d07c8159 ) +) + game ( name "DemiKids - Dark Version (USA)" description "DemiKids - Dark Version (USA)" @@ -4338,18 +4326,18 @@ game ( rom ( name "Densetsu no Stafy 3 (Japan) (Rev 1) (Virtual Console).gba" size 16777216 crc 59ca95c6 sha1 5506cbcfa1a275441f365099822a583c80397fde ) ) -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 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 sha1 dae5354bfe4ccafc92d22b1389265dbf1f79b636 ) ) +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 sha1 a7a742e779d314f6909f1350db2da8a63445c433 flags verified ) +) + game ( name "Derby Stallion Advance (Japan)" description "Derby Stallion Advance (Japan)" @@ -4368,12 +4356,6 @@ game ( rom ( name "Deutschland Sucht den Superstar (Germany).gba" size 16777216 crc 51f50f7d sha1 ce5253e82671569500af3d5df9d3131916fbe23d ) ) -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 sha1 e04dbb5e0534cf241e8fee85d17b1cc8a0032f14 ) -) - game ( name "Dexter's Laboratory - Chess Challenge (USA)" description "Dexter's Laboratory - Chess Challenge (USA)" @@ -4381,9 +4363,15 @@ game ( ) 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 sha1 f230375ba4b0346d749e50117fe701d8c1cbfffa ) + 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 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 sha1 b838b5bb37bfeb3315a68b6d372f29a5de635444 flags verified ) ) game ( @@ -4393,9 +4381,9 @@ game ( ) 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 flags verified ) + 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 sha1 f230375ba4b0346d749e50117fe701d8c1cbfffa ) ) game ( @@ -4419,7 +4407,7 @@ game ( 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 ) + rom ( name "Diddy Kong Pilot (Unknown) (Proto) (2001).gba" size 5080644 crc 5c206101 sha1 6a76def610829ac1502afb58740e38b5e6926b3d ) ) game ( @@ -4695,7 +4683,7 @@ game ( game ( name "Dogz (USA)" description "Dogz (USA)" - rom ( name "Dogz (USA).gba" size 8388608 crc 124f27c0 sha1 462f05c18534cb22fffc65d47351a29f10a3f254 ) + rom ( name "Dogz (USA).gba" size 8388608 crc 124f27c0 sha1 462f05c18534cb22fffc65d47351a29f10a3f254 flags verified ) ) game ( @@ -4872,12 +4860,6 @@ game ( rom ( name "Donkey Kong Country 3 (USA).gba" size 16777216 crc fe03e5af sha1 c50982b4c26e25ba3538be97b585d95737d7ade7 flags verified ) ) -game ( - name "Donsol (World) (Aftermarket) (Unl)" - description "Donsol (World) (Aftermarket) (Unl)" - rom ( name "Donsol (World) (Aftermarket) (Unl).gba" size 52520 crc aec144b3 sha1 751675b0d77c341f2265b0edd38858b0dbdb7b50 ) -) - game ( name "Doom (USA, Europe)" description "Doom (USA, Europe)" @@ -4905,7 +4887,7 @@ game ( 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 sha1 fa51e2102ce0a0e70c5db2f8776d2237c8d7db7d ) + rom ( name "Dora the Explorer - Super Spies (USA).gba" size 4194304 crc 650fdfdb sha1 fa51e2102ce0a0e70c5db2f8776d2237c8d7db7d flags verified ) ) game ( @@ -4923,7 +4905,7 @@ game ( 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 sha1 10d1df1cb3fd94a14fff239083968b5182772a4d ) + rom ( name "Dora the Explorer - The Search for the Pirate Pig's Treasure (USA).gba" size 4194304 crc 9439541c sha1 10d1df1cb3fd94a14fff239083968b5182772a4d flags verified ) ) game ( @@ -5082,6 +5064,12 @@ game ( rom ( name "Dragon Ball - Advanced Adventure (Europe) (En,Fr,De,Es,It) (Beta) (2005-02-25).gba" size 16777216 crc 2b136906 sha1 fe190755f05994f1c796286ad767d7da49c36385 ) ) +game ( + name "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27)" + description "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27)" + rom ( name "Dragon Ball GT - Transformation (USA) (Beta) (2005-04-27).gba" size 8388608 crc 431bc807 sha1 58875496c9ab89ba3b769dc47d89ac2839b7cb7f ) +) + game ( name "Dragon Ball GT - Transformation (USA)" description "Dragon Ball GT - Transformation (USA)" @@ -5178,6 +5166,18 @@ game ( 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 (USA) (Beta) (2003-01-23)" + description "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-23)" + rom ( name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-23).gba" size 7282372 crc 3c30f5b3 sha1 16f4c593a0ab0e243fbeca7cc1033ac88501e387 ) +) + +game ( + name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31)" + description "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31)" + rom ( name "Dragon Ball Z - The Legacy of Goku II (USA) (Beta) (2003-01-31).gba" size 7279012 crc 25f34dbc sha1 fc76f3477f19af7415a42a6f38bd5bda43c640d2 ) +) + game ( name "Dragon Ball Z - The Legacy of Goku II International (Japan)" description "Dragon Ball Z - The Legacy of Goku II International (Japan)" @@ -5418,6 +5418,12 @@ game ( rom ( name "Duel Masters 3 (Japan) (Rev 1).gba" size 8388608 crc d2b9cfb6 sha1 05ad843564c663a050e137ae0ec07d09f585c714 ) ) +game ( + name "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl)" + description "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl)" + rom ( name "Duke Nukem Advance (World) (En,Fr,De,It) (Evercade) (Unl).gba" size 8388608 crc 2b077058 sha1 926b6c74d408cb3ff37a5276ddc3be8e2512c0b3 ) +) + game ( name "Duke Nukem Advance (USA)" description "Duke Nukem Advance (USA)" @@ -5568,6 +5574,12 @@ game ( rom ( name "Eggo Mania (Europe) (En,Fr,De,Es,It,Nl).gba" size 4194304 crc 0b2961ce sha1 5514d090d08643a07457e4698d848657ae5cd179 ) ) +game ( + name "Elements of Darkness (World) (Demo) (Unl)" + description "Elements of Darkness (World) (Demo) (Unl)" + rom ( name "Elements of Darkness (World) (Demo) (Unl).gba" size 3039348 crc 5f3b0637 sha1 f425b0a88c46bca220bf47c2067020b57e96f736 ) +) + game ( name "Elemix! (Japan)" description "Elemix! (Japan)" @@ -5599,9 +5611,9 @@ game ( ) game ( - name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" - description "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl)" - rom ( name "Elland - The Crystal Wars (World) (Digital Release) (Aftermarket) (Unl).gba" size 4016344 crc e3128bcb sha1 67617136f205fa071d9fc239df09471e603c675c ) + name "Elite - The New Kind (World) (v1.7.1) (Unl)" + description "Elite - The New Kind (World) (v1.7.1) (Unl)" + rom ( name "Elite - The New Kind (World) (v1.7.1) (Unl).gba" size 546392 crc 5f9b4211 sha1 d3e6c12e6475ffb21617e3be7158d60ac535e74b ) ) game ( @@ -5637,7 +5649,7 @@ game ( 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 sha1 ecee20b629a38bab7edbc972c70b2c968f50c23c ) + rom ( name "ESPN Final Round Golf 2002 (USA).gba" size 8388608 crc c9bc75a5 sha1 ecee20b629a38bab7edbc972c70b2c968f50c23c flags verified ) ) game ( @@ -5985,7 +5997,7 @@ game ( game ( name "F24 Stealth Fighter (USA)" description "F24 Stealth Fighter (USA)" - rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387ea7c sha1 ac9188c7836dd388b488d02e8774dc61b1d30b4a ) + rom ( name "F24 Stealth Fighter (USA).gba" size 4194304 crc 9387ea7c sha1 ac9188c7836dd388b488d02e8774dc61b1d30b4a flags verified ) ) game ( @@ -6165,7 +6177,7 @@ game ( 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 sha1 0100d4e94c30adf73cd6082b89911dedf723ecd5 ) + rom ( name "Famicom Mini 22 - Nazo no Murasame Jou (Japan).gba" size 4194304 crc 8233349c sha1 0100d4e94c30adf73cd6082b89911dedf723ecd5 flags verified ) ) game ( @@ -6321,7 +6333,7 @@ game ( game ( name "Fear Factor - Unleashed (USA)" description "Fear Factor - Unleashed (USA)" - rom ( name "Fear Factor - Unleashed (USA).gba" size 8388608 crc 1289639c sha1 bf933c51bdcb52ae54d518e80129c687b751f836 ) + rom ( name "Fear Factor - Unleashed (USA).gba" size 8388608 crc bf91c27d sha1 d6f60f7d1707dca21c61f50db2b6324b7d680012 ) ) game ( @@ -6367,15 +6379,15 @@ game ( ) game ( - name "FILA Decathlon (Europe) (Beta)" - description "FILA Decathlon (Europe) (Beta)" - rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434e3a sha1 1dc940dda8da59ade503c1e8901a0e44285f4e9b ) + 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 sha1 41efd4b2fc8be52a12aadd1e4bf696fcc98230ca 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 sha1 41efd4b2fc8be52a12aadd1e4bf696fcc98230ca ) + name "FILA Decathlon (Europe) (Beta)" + description "FILA Decathlon (Europe) (Beta)" + rom ( name "FILA Decathlon (Europe) (Beta).gba" size 4194304 crc 07434e3a sha1 1dc940dda8da59ade503c1e8901a0e44285f4e9b ) ) game ( @@ -6438,24 +6450,6 @@ game ( rom ( name "Final Fantasy Tactics Advance (USA) (Virtual Console).gba" size 16777216 crc 5964df89 sha1 3ca7cffe302e733501a4777a576928ea159b89e4 ) ) -game ( - 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 sha1 9efaf328cbbcbc830be14940e42e4b92d90dfb58 flags verified ) -) - -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 sha1 fa9d23ee88c7fe24374337aca03eb864b5b991f4 flags verified ) -) - game ( name "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It) (Virtual Console)" description "Final Fantasy Tactics Advance (Europe) (En,Fr,De,Es,It) (Virtual Console)" @@ -6468,6 +6462,24 @@ game ( rom ( name "Final Fantasy Tactics Advance (Japan) (Virtual Console).gba" size 16777216 crc ee31422a sha1 8e90027e0831b27fa174e446e6a773f2a421aed1 ) ) +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 sha1 fa9d23ee88c7fe24374337aca03eb864b5b991f4 flags verified ) +) + +game ( + 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 sha1 9efaf328cbbcbc830be14940e42e4b92d90dfb58 flags verified ) +) + game ( name "Final Fantasy V Advance (Japan) (Virtual Console)" description "Final Fantasy V Advance (Japan) (Virtual Console)" @@ -6573,7 +6585,7 @@ game ( game ( name "Findet Nemo (Germany)" description "Findet Nemo (Germany)" - rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6b6b0908 sha1 5c5ee51c4bc8196bea226b3bf4750c8de1ee7f38 ) + rom ( name "Findet Nemo (Germany).gba" size 8388608 crc 6b6b0908 sha1 5c5ee51c4bc8196bea226b3bf4750c8de1ee7f38 flags verified ) ) game ( @@ -6780,6 +6792,12 @@ game ( rom ( name "Flintstones, The - Big Trouble in Bedrock (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 39782c26 sha1 3eb5a53a395acfaae672d8b8e3c79fc4442a00ab ) ) +game ( + name "Flood (World) (v0.9) (Proto) (Unl)" + description "Flood (World) (v0.9) (Proto) (Unl)" + rom ( name "Flood (World) (v0.9) (Proto) (Unl).gba" size 485108 crc 46ad658a sha1 c3e6dfaca1570fb7d2af45a25fd93e94e11beb1e ) +) + game ( name "Flushed Away (USA)" description "Flushed Away (USA)" @@ -6873,7 +6891,7 @@ game ( game ( name "Freekstyle (USA)" description "Freekstyle (USA)" - rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 sha1 dcecce5ebc93cfc421094ecb00a50dfe371bad24 ) + rom ( name "Freekstyle (USA).gba" size 8388608 crc 72434345 sha1 dcecce5ebc93cfc421094ecb00a50dfe371bad24 flags verified ) ) game ( @@ -7008,6 +7026,12 @@ game ( rom ( name "Futari wa Pretty Cure Max Heart - Maji Maji! Fight de IN Janai (Japan).gba" size 8388608 crc 541c18f9 sha1 fb6b864b13f41af2521c7e9c7bec0b490962452f ) ) +game ( + name "Fuzz & Rocket (USA) (Proto) (2005-01-18)" + description "Fuzz & Rocket (USA) (Proto) (2005-01-18)" + rom ( name "Fuzz & Rocket (USA) (Proto) (2005-01-18).gba" size 4124984 crc fd239437 sha1 e6dab28aa3e9a5b1417bbf3929c45ff7260803b0 ) +) + game ( name "Gachasute! Dino Device - Blue (Japan)" description "Gachasute! Dino Device - Blue (Japan)" @@ -7170,6 +7194,12 @@ game ( rom ( name "Gang del Bosco, La (Italy).gba" size 8388608 crc 52a5b59d sha1 75e7060b7dce72d01fbd6a6d1d8e1d752bfc92d0 ) ) +game ( + name "Gap-Man (World) (Unl)" + description "Gap-Man (World) (Unl)" + rom ( name "Gap-Man (World) (Unl).gba" size 122052 crc 05e327d1 sha1 839b1115f11192864e90637c964e79872c6b4b88 ) +) + 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)" @@ -7237,9 +7267,15 @@ game ( ) 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 sha1 55cf23d0b941b68fb89e35d5ee57a78d30b54827 ) + name "GBA Movie Player - 2nd Version (World) (V2.00) (Unl)" + description "GBA Movie Player - 2nd Version (World) (V2.00) (Unl)" + rom ( name "GBA Movie Player - 2nd Version (World) (V2.00) (Unl).gba" size 524288 crc 3fc91d4f sha1 36739e9467204c6b2a64211dcda7370af23972ed ) +) + +game ( + name "GBA Movie Player - 2nd Version (World) (Unl) [b]" + description "GBA Movie Player - 2nd Version (World) (Unl) [b]" + rom ( name "GBA Movie Player - 2nd Version (World) (Unl) [b].gba" size 1048576 crc c879b340 sha1 55cf23d0b941b68fb89e35d5ee57a78d30b54827 flags baddump ) ) game ( @@ -7350,12 +7386,6 @@ game ( rom ( name "Ghost Trap (Japan).gba" size 8388608 crc 81ea54e2 sha1 00efb5ed50127f91e2a2827926cf2d4491e4b1b3 ) ) -game ( - name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" - description "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" - rom ( name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl).gba" size 1210608 crc ab5ae65b sha1 e35037ff9cc24f8a7043d9a9d378e86d2ef80f9b ) -) - game ( name "Global Star - Sudoku Fever (USA)" description "Global Star - Sudoku Fever (USA)" @@ -7407,7 +7437,7 @@ game ( 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 sha1 5ecf4ead4b22a5916086a34bbf2abf299aaf3401 ) + rom ( name "Golden Nugget Casino (USA, Europe).gba" size 4194304 crc 56b9e9e1 sha1 5ecf4ead4b22a5916086a34bbf2abf299aaf3401 flags verified ) ) game ( @@ -7476,96 +7506,6 @@ game ( rom ( name "Golden Sun - The Lost Age (USA, Europe) (Virtual Console).gba" size 16777216 crc 726bb764 sha1 3c15317369ecafcd3c018d13c297d9107790f14f flags verified ) ) -game ( - name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220676 crc ab179d6e sha1 2ad1c4840f2f6c2138ed44b1a7aa36071c227a0a ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221620 crc 3aa591f1 sha1 2548615eeaecd7498e32d02b5c758b713ada27f4 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221368 crc d02cdb6a sha1 1e579e15bdc8dc1def99bcb3c30acfc185e0476b ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220496 crc 906717a5 sha1 31857a9ab4daa537322f80faa77482a4b8120483 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220252 crc d12372bd sha1 89ea5ea41133419c317fd28e7c7f172f5bb53ec3 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13216280 crc d3c8dffd sha1 c41c0596a4c52b0e26bb9ffe5c9f7f1c064e0be6 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13265660 crc 119f9ddc sha1 d6c23ff47b21a7bf2f8238ac916aeea3866042b5 ) -) - -game ( - name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" - description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" - rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13246576 crc b14cd1b4 sha1 0d15bd0584148b1658f7d47a2dda604a936ea166 ) -) - game ( name "GP-1 Racing (USA) (Proto)" description "GP-1 Racing (USA) (Proto)" @@ -7614,18 +7554,6 @@ game ( rom ( name "Green Eggs and Ham by Dr. Seuss (USA).gba" size 4194304 crc e4ae2cd1 sha1 be062fa28db26ec37ec96e5a7e6dc77cf4ad6907 ) ) -game ( - name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" - description "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" - rom ( name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl).gba" size 6639328 crc 78b81bbc sha1 fb090890bd767a22afe07b3323dd0992d698c906 ) -) - -game ( - name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" - description "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" - rom ( name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl).gba" size 6937384 crc 9fa9f00f sha1 005f4dc0d615d36d32bbe36e9cc9007b22be2ecd ) -) - game ( name "Greg Hastings' Tournament Paintball Max'd (USA)" description "Greg Hastings' Tournament Paintball Max'd (USA)" @@ -7638,18 +7566,18 @@ game ( rom ( name "Gremlins - Stripe vs Gizmo (Europe) (En,Fr,De,Es,It,Pt) (Beta).gba" size 4194304 crc 68ae6bbb sha1 6aa43d0624af03214473f329fda6334dc9c63009 ) ) -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 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)" + 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 sha1 a2c4bf97785e717ef45e4b73a6c66a2d4ae18192 ) +) + game ( name "Grim Adventures of Billy & Mandy, The (USA)" description "Grim Adventures of Billy & Mandy, The (USA)" @@ -7695,7 +7623,7 @@ game ( 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 sha1 1e81d7ad7a9d8c179ef9f1a2e334a155799fe788 ) + rom ( name "GT Advance 3 - Pro Concept Racing (Europe).gba" size 8388608 crc 03898e7f sha1 1e81d7ad7a9d8c179ef9f1a2e334a155799fe788 flags verified ) ) game ( @@ -7728,18 +7656,6 @@ game ( rom ( name "Gu Huo Lang 4 (Taiwan) (Unl).gba" size 33554432 crc 1608f6db sha1 8c40ce7a06f741fb11aa717b7ce2f151279fa2e2 ) ) -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 "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 sha1 bb064410c57324b25de96d297338cc5e73262fe6 ) -) - game ( name "Guilty Gear X - Advance Edition (Japan)" description "Guilty Gear X - Advance Edition (Japan)" @@ -7752,6 +7668,18 @@ game ( 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 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)" @@ -7789,9 +7717,9 @@ game ( ) game ( - name "Guru Logic Champ (Japan)" - description "Guru Logic Champ (Japan)" - rom ( name "Guru Logic Champ (Japan).gba" size 4194304 crc 30d04ad9 sha1 77588b6e802de57d1d826c4d43e4c3b0e3aebdae ) + name "Guru Logichamp (Japan)" + description "Guru Logichamp (Japan)" + rom ( name "Guru Logichamp (Japan).gba" size 4194304 crc 30d04ad9 sha1 77588b6e802de57d1d826c4d43e4c3b0e3aebdae ) ) game ( @@ -7959,7 +7887,7 @@ game ( game ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" description "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29)" - rom ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29).gba" size 16777216 crc fd630f6c sha1 14cf38e86f019572393f0109680ff2db345f9f50 ) + rom ( name "Hamtaro - Rainbow Rescue (USA) (Proto) (2003-07-29).gba" size 8388608 crc 5c5b934d sha1 b081395415fae9cd59963a5b85bc7cc0d5623cb9 ) ) game ( @@ -7977,13 +7905,13 @@ game ( 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 sha1 cbccce77bb727efa7ab4805509773121239faf13 ) + rom ( name "Happy Feet (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc b8653e59 sha1 1eabcfe84bd7558f64197e890a0eda8e76cdbc2c ) ) 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 sha1 e7c95cbc076e97ed2a414abc9f8d419e47174505 ) + rom ( name "Happy Feet (USA) (En,Fr).gba" size 33554432 crc 98235433 sha1 be8373ca6b9969af85303b1ec910ceb28b4f59f6 flags verified ) ) game ( @@ -8067,7 +7995,7 @@ game ( 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 sha1 a0e1a8f0c31ffd6e82ef99c95f903347a6eae623 ) + rom ( name "Harry Potter Collection (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).gba" size 33554432 crc 4f39c174 sha1 1af909d2e9604501b094da95dd3e4d96e72778e8 ) ) game ( @@ -8220,6 +8148,12 @@ game ( rom ( name "Hi Hi Puffy AmiYumi - Kaznapped! (Europe) (En,De).gba" size 8388608 crc e5531d04 sha1 4060be81c5a0bc741d759f75cd83823106e5b6b9 ) ) +game ( + name "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto)" + description "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto)" + rom ( name "Hi Hi Puffy AmiYumi - Puffy Ami Yumi and the Manga Madman! (USA) (Proto).gba" size 8388608 crc d048ec49 sha1 f0a5e83593a3dd2c32166e6a6e48d550d7de9ecb ) +) + game ( name "Higanbana (Japan) (Rev 1)" description "Higanbana (Japan) (Rev 1)" @@ -8337,7 +8271,7 @@ game ( 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 sha1 321bce711714f718ac3882acdc3c0f659db5191d ) + rom ( name "Home on the Range (USA) (En,Fr).gba" size 8388608 crc dbd4a6cb sha1 321bce711714f718ac3882acdc3c0f659db5191d flags verified ) ) game ( @@ -8520,18 +8454,18 @@ game ( 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 ) ) -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 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 ) ) +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 sha1 e752cad1fa3ffec56c9f6ca5886f37da0dc74240 ) +) + game ( name "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" description "Huo-Wen Zhanji - Fengyin Zhi Jian (China) (Proto)" @@ -8550,6 +8484,12 @@ game ( rom ( name "I Spy Challenger! (USA).gba" size 8388608 crc 946d2cbb sha1 532934239ea1151927fd45298d918e0646a6bea4 ) ) +game ( + name "I-Ninja (USA) (Proto)" + description "I-Ninja (USA) (Proto)" + rom ( name "I-Ninja (USA) (Proto).gba" size 8388608 crc 8f31e9c6 sha1 c5ca0f7d1d836285202fbd674ef914a7da87b024 ) +) + game ( name "Ice Age (USA) (En,Fr,Es)" description "Ice Age (USA) (En,Fr,Es)" @@ -8652,30 +8592,12 @@ game ( rom ( name "Increibles, Los (Spain).gba" size 8388608 crc fc6ccadb sha1 c87047934ae328f52ef6b01083a57c65cbbab514 ) ) -game ( - name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" - description "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl).gba" size 10592124 crc a9014760 sha1 2430c6c0784912ad2f0b51e633bf577f087f189f ) -) - -game ( - name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" - description "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl)" - rom ( name "Inheritors of the Oubliette (World) (GBA Jam) (Aftermarket) (Unl).gba" size 25516708 crc 965a1a75 sha1 ae23cfba1f53a9bbde025490f3d7bdf52c3970e4 ) -) - 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 sha1 abc8a136e00e38132bf07d38cf28e52a2719fab9 ) ) -game ( - name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" - description "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Inky and the Alien Aquarium (World) (Demo) (Aftermarket) (Unl).gba" size 3145728 crc 7ee7ae7f sha1 73d870fad3caa86b6f659e13b57eddac80db2f37 ) -) - 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)" @@ -8748,12 +8670,6 @@ game ( rom ( name "iQue Video & Audio (China).gba" size 16777216 crc 92852a72 sha1 79c7494c116e276f85a5f62d59f3a4588bd88391 ) ) -game ( - name "Iridion 3D (USA) (Aftermarket) (Unl)" - description "Iridion 3D (USA) (Aftermarket) (Unl)" - rom ( name "Iridion 3D (USA) (Aftermarket) (Unl).gba" size 4194304 crc 4c7ebe42 sha1 6f1c77ab88351d2d50da412e4788fc7ca8a6714d ) -) - game ( name "Iridion 3D (USA, Europe)" description "Iridion 3D (USA, Europe)" @@ -8778,12 +8694,6 @@ game ( rom ( name "Iridion II (USA) (Beta).gba" size 8388608 crc 9c63d17c sha1 3e951fd97bacd4f258bf30785af22934f7697a91 ) ) -game ( - name "Iridion II (USA) (Aftermarket) (Unl)" - description "Iridion II (USA) (Aftermarket) (Unl)" - rom ( name "Iridion II (USA) (Aftermarket) (Unl).gba" size 8388608 crc b371f070 sha1 cc788b38a047ff5ec8c445ce11efcd1852ad7c4d ) -) - game ( name "Iron Kid (Korea)" description "Iron Kid (Korea)" @@ -8793,7 +8703,7 @@ game ( 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 ) + 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 ( @@ -8907,7 +8817,7 @@ game ( 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 sha1 31ed7659e2e072d1c00baf95c0ee9c770e949900 ) + rom ( name "Jimmy Neutron - Boy Genius (USA).gba" size 4194304 crc d3ee0c51 sha1 31ed7659e2e072d1c00baf95c0ee9c770e949900 flags verified ) ) game ( @@ -9300,6 +9210,12 @@ game ( rom ( name "Kien (USA) (Proto).gba" size 8388608 crc 185c2eca sha1 da1673ec5ec35f8ececa3f04cb6a92d61237ce72 ) ) +game ( + name "Kien (World) (Proto) (Incub8 Games)" + description "Kien (World) (Proto) (Incub8 Games)" + rom ( name "Kien (World) (Proto) (Incub8 Games).gba" size 8350032 crc 5a64b473 sha1 3cf07cd95e5a83b65c773111051a50d9bef367eb flags verified ) +) + game ( name "Kikaika Guntai - Mech Platoon (Japan)" description "Kikaika Guntai - Mech Platoon (Japan)" @@ -9396,6 +9312,12 @@ game ( rom ( name "King of Fighters EX 2, The - Howling Blood (USA) (Beta) (2003-04-03).gba" size 8388608 crc 7704ff39 sha1 b859122c1813a5ec9fb565dcca815a9f0a52bf18 ) ) +game ( + 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)" @@ -9409,9 +9331,15 @@ game ( ) game ( - 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 ) + 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 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 ( @@ -9432,18 +9360,6 @@ game ( rom ( name "King of Fighters EX, The - NeoBlood (Europe).gba" size 8388608 crc 17e66b52 sha1 48c85734164d4d83a232b5aca6bb9a2c5b7f5317 ) ) -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 sha1 3031264c4b27cac55c2df38ab5f2bfcafa7c301d ) -) - -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 sha1 cde8454951d3509f0b2bf9de98221eef248f5f8d ) -) - game ( name "Kingdom Hearts - Chain of Memories (Japan)" description "Kingdom Hearts - Chain of Memories (Japan)" @@ -9487,9 +9403,9 @@ game ( ) game ( - name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" - rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) + 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 ( @@ -9499,9 +9415,15 @@ game ( ) 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 ) + name "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + description "Kirby - Nightmare in Dream Land (USA) (Virtual Console)" + rom ( name "Kirby - Nightmare in Dream Land (USA) (Virtual Console).gba" size 8388608 crc 1af07ac8 sha1 3d142008d50a64c315fd2d7cbd86ba94dffa2e12 ) +) + +game ( + name "Kirby & The Amazing Mirror (USA) (Virtual Console)" + description "Kirby & The Amazing Mirror (USA) (Virtual Console)" + rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) ) game ( @@ -9516,12 +9438,6 @@ game ( rom ( name "Kirby & The Amazing Mirror (USA).gba" size 16777216 crc 9f2a3048 sha1 274b102b6d940f46861a92b4e65f89a51815c12c flags verified ) ) -game ( - name "Kirby & The Amazing Mirror (USA) (Virtual Console)" - description "Kirby & The Amazing Mirror (USA) (Virtual Console)" - rom ( name "Kirby & The Amazing Mirror (USA) (Virtual Console).gba" size 16777216 crc f70ebb99 sha1 a7b758c2abf4f0ef722922eab4d394a1579b52e8 ) -) - game ( name "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" description "Kirby & The Amazing Mirror (Europe) (En,Fr,De,Es,It) (Virtual Console)" @@ -9555,13 +9471,7 @@ game ( 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 sha1 e4a81713b134e0b7409708843dad2a4948b903ef ) -) - -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 sha1 35c05676e65fd4c92220861662cd3709342f36e2 ) + rom ( name "Klonoa - Empire of Dreams (Europe).gba" size 4194304 crc 69492530 sha1 e4a81713b134e0b7409708843dad2a4948b903ef flags verified ) ) game ( @@ -9570,6 +9480,12 @@ game ( rom ( name "Klonoa 2 - Dream Champ Tournament (USA) (Virtual Console).gba" size 4194304 crc 766c7f9a sha1 455c6f19a703b2bd54a9a3a9588964239965e6db ) ) +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 sha1 35c05676e65fd4c92220861662cd3709342f36e2 ) +) + game ( name "Klonoa Heroes - Densetsu no Star Medal (Japan)" description "Klonoa Heroes - Densetsu no Star Medal (Japan)" @@ -9648,12 +9564,6 @@ game ( 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 sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) -) - game ( name "Konami Krazy Racers (USA) (Virtual Console)" description "Konami Krazy Racers (USA) (Virtual Console)" @@ -9667,9 +9577,9 @@ game ( ) game ( - name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" - rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) + name "Konami Krazy Racers (USA) (Beta)" + description "Konami Krazy Racers (USA) (Beta)" + rom ( name "Konami Krazy Racers (USA) (Beta).gba" size 4194304 crc 5f2ae8fe sha1 329b82282d633d1162f9afb3334c035b10b91e72 ) ) game ( @@ -9678,6 +9588,12 @@ game ( rom ( name "Konami Wai Wai Racing Advance (Japan).gba" size 4194304 crc aa039a8a sha1 e3549b9b7d7208b88e368e7b7a59e31eec8b1da6 ) ) +game ( + name "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + description "Konami Wai Wai Racing Advance (Japan) (Virtual Console)" + rom ( name "Konami Wai Wai Racing Advance (Japan) (Virtual Console).gba" size 4194304 crc f424858f sha1 29f850ea1a9900446a0e1ce8ef1c2fd85341f242 ) +) + game ( name "Konchuu Monster - Battle Master (Japan)" description "Konchuu Monster - Battle Master (Japan)" @@ -9765,7 +9681,7 @@ game ( game ( name "Korokoro Puzzle - Happy Panecchu! (Japan)" description "Korokoro Puzzle - Happy Panecchu! (Japan)" - rom ( name "Korokoro Puzzle - Happy Panecchu! (Japan).gba" size 4194304 crc 0bfe46e9 sha1 40cb751d119a49be0cd44cf0491c93ebc8795ef0 ) + rom ( name "Korokoro Puzzle - Happy Panecchu! (Japan).gba" size 4194304 crc 0bfe46e9 sha1 40cb751d119a49be0cd44cf0491c93ebc8795ef0 flags verified ) ) game ( @@ -9951,13 +9867,13 @@ game ( 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 sha1 4bc88f2c7325937bbe0f16dfebda10f279d5ed20 ) + rom ( name "Legend of Spyro, The - The Eternal Night (USA) (En,Fr).gba" size 33554432 crc 8d780224 sha1 6cfa38d08b735e8b6b1c3763aee8a8ed5da52977 ) ) 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 sha1 4bce80310b43882f57c7bb5b202e09ce23687473 ) + rom ( name "Legend of Spyro, The - The Eternal Night (Europe) (En,Fr,De,Es,It,Nl).gba" size 33554432 crc a3eed091 sha1 0fced99190bce676e83bed31134e2f165ef997b8 ) ) game ( @@ -10176,10 +10092,16 @@ game ( rom ( name "Lilo & Stitch 2 - Haemsterviel Havoc (USA).gba" size 8388608 crc 021a5755 sha1 70e0dc5a8dcdf876b5dd87a4c1bbca03b6e30148 ) ) +game ( + name "Lindsi Luna Blast (World) (v1.01) (Unl)" + description "Lindsi Luna Blast (World) (v1.01) (Unl)" + rom ( name "Lindsi Luna Blast (World) (v1.01) (Unl).gba" size 4981720 crc e6fadd1a sha1 6786c08957251b3a5ab2534b15f5b2def2ee9d86 ) +) + 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 sha1 382de6da61c5dc5c2844f5ffa28a1827d15319b1 ) + rom ( name "Lion King 1 1-2, The (USA).gba" size 8388608 crc ea5ed4c0 sha1 382de6da61c5dc5c2844f5ffa28a1827d15319b1 flags verified ) ) game ( @@ -10233,7 +10155,7 @@ game ( 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 sha1 7ace37aec21c058aa98e3de12140cb691c070e00 ) + rom ( name "Lizzie McGuire 2 - Lizzie Diaries (USA) (En,Fr).gba" size 4194304 crc f11009f9 sha1 7ace37aec21c058aa98e3de12140cb691c070e00 flags verified ) ) game ( @@ -10368,12 +10290,6 @@ game ( rom ( name "Lufia - The Ruins of Lore (USA).gba" size 8388608 crc de5ffcbc sha1 a2b7e80a6c7d586ebeec77c8a2c2545fe27e0592 ) ) -game ( - name "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" - description "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" - rom ( name "Luggage Retrieval Officer (World) (Aftermarket) (Unl).gba" size 3336260 crc 5aa30d90 sha1 84c9b2d50c8af74b8b04f88af367d9fac1a24ef6 ) -) - game ( name "Lunar Legend (Japan)" description "Lunar Legend (Japan)" @@ -10657,9 +10573,9 @@ game ( ) game ( - name "Mandrake the Magician (Italy) (It) (Proto)" - description "Mandrake the Magician (Italy) (It) (Proto)" - rom ( name "Mandrake the Magician (Italy) (It) (Proto).gba" size 8388608 crc 7cfe1889 sha1 ddb5f0cdd5db80c22a448650c1b05d02feb0b831 ) + 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 ) ) game ( @@ -11013,13 +10929,13 @@ game ( game ( 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 ) + 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 sha1 284059f03f0dda9ce511d3c57bf0607706b9fca3 ) + rom ( name "Mary-Kate and Ashley - Sweet 16 - Licensed to Drive (USA, Europe).gba" size 4194304 crc 5fe092c6 sha1 284059f03f0dda9ce511d3c57bf0607706b9fca3 flags verified ) ) game ( @@ -11058,18 +10974,6 @@ game ( rom ( name "Matantei Loki Ragnarok - Gensou no Labyrinth (Japan) (Rev 1).gba" size 8388608 crc d647ab18 sha1 3489569fa8a3c6a750c5cb0048915da78c5f40ab ) ) -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 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 sha1 13310b7f25a0332a8e09e722587ec79aee11c373 ) -) - game ( name "Math Patrol - The Kleptoid Threat (USA)" description "Math Patrol - The Kleptoid Threat (USA)" @@ -11142,6 +11046,12 @@ game ( rom ( name "Medabots - Metabee (Europe).gba" size 8388608 crc 50927f3e sha1 cd3d674e88f40a0707b150c4293588a659001d29 ) ) +game ( + name "Medabots - Metabee (USA)" + description "Medabots - Metabee (USA)" + rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59f208fc sha1 ca185b65ab50ef89a10c8db00d9cd76626b81610 ) +) + game ( name "Medabots - Metabee (Spain)" description "Medabots - Metabee (Spain)" @@ -11155,15 +11065,9 @@ game ( ) game ( - name "Medabots - Metabee (USA)" - description "Medabots - Metabee (USA)" - rom ( name "Medabots - Metabee (USA).gba" size 8388608 crc 59f208fc sha1 ca185b65ab50ef89a10c8db00d9cd76626b81610 ) -) - -game ( - name "Medabots - Rokusho (USA)" - description "Medabots - Rokusho (USA)" - rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc e144ded2 sha1 c4572428ea97b302f699a3b4eba2a1f0e87c1c9c ) + name "Medabots - Rokusho (Spain)" + description "Medabots - Rokusho (Spain)" + rom ( name "Medabots - Rokusho (Spain).gba" size 8388608 crc 046d86c4 sha1 90fe7f2927c592aabc9b33d0df00d92046c5cb92 ) ) game ( @@ -11185,15 +11089,9 @@ game ( ) 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 sha1 80c024df6d40e499776665d7f0c494a252973048 ) + name "Medabots - Rokusho (USA)" + description "Medabots - Rokusho (USA)" + rom ( name "Medabots - Rokusho (USA).gba" size 8388608 crc e144ded2 sha1 c4572428ea97b302f699a3b4eba2a1f0e87c1c9c ) ) game ( @@ -11202,6 +11100,12 @@ game ( 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 - Metabee Ver. (USA)" + description "Medabots AX - Metabee Ver. (USA)" + rom ( name "Medabots AX - Metabee Ver. (USA).gba" size 8388608 crc 03294511 sha1 80c024df6d40e499776665d7f0c494a252973048 ) +) + game ( name "Medabots AX - Metabee Ver. (USA) (Virtual Console)" description "Medabots AX - Metabee Ver. (USA) (Virtual Console)" @@ -11244,12 +11148,6 @@ game ( 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 (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 - Underground (USA)" description "Medal of Honor - Underground (USA)" @@ -11262,6 +11160,12 @@ game ( rom ( name "Medal of Honor - Underground (Europe) (En,Fr,Es,It) (Ubi Soft).gba" size 8388608 crc 9db145b8 sha1 e43aaba3f925443cfccf9294b870024a9c71a9a9 ) ) +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)" @@ -11550,18 +11454,6 @@ game ( rom ( name "Megaman - Battle Network 5 - Team Colonel (Europe) (Virtual Console).gba" size 8388608 crc 5247772c sha1 061c291b29629d5ce44011d2d83931f2e35044ed ) ) -game ( - name "Megaman - Battle Network 5 - Team Protoman (Europe)" - description "Megaman - Battle Network 5 - Team Protoman (Europe)" - rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe).gba" size 8388608 crc 79f45ed8 sha1 3d017ed23535e42174299ff89fff44678eb553c3 ) -) - -game ( - name "Megaman - Battle Network 5 - Team Protoman (USA)" - description "Megaman - Battle Network 5 - Team Protoman (USA)" - rom ( name "Megaman - Battle Network 5 - Team Protoman (USA).gba" size 8388608 crc a73e83a4 sha1 b3774e96b1f107bb8b1db79b216be41b9bc5bac0 ) -) - game ( name "Megaman - Battle Network 5 - Team Protoman (USA) (Virtual Console)" description "Megaman - Battle Network 5 - Team Protoman (USA) (Virtual Console)" @@ -11574,6 +11466,18 @@ game ( rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe) (Virtual Console).gba" size 8388608 crc 7e5bc83d sha1 b68b310e3106e7fa6a47d4155239be2e43959da4 ) ) +game ( + name "Megaman - Battle Network 5 - Team Protoman (Europe)" + description "Megaman - Battle Network 5 - Team Protoman (Europe)" + rom ( name "Megaman - Battle Network 5 - Team Protoman (Europe).gba" size 8388608 crc 79f45ed8 sha1 3d017ed23535e42174299ff89fff44678eb553c3 ) +) + +game ( + name "Megaman - Battle Network 5 - Team Protoman (USA)" + description "Megaman - Battle Network 5 - Team Protoman (USA)" + rom ( name "Megaman - Battle Network 5 - Team Protoman (USA).gba" size 8388608 crc a73e83a4 sha1 b3774e96b1f107bb8b1db79b216be41b9bc5bac0 ) +) + game ( name "Megaman - Battle Network 6 - Cybeast Falzar (Europe)" description "Megaman - Battle Network 6 - Cybeast Falzar (Europe)" @@ -11628,12 +11532,6 @@ game ( rom ( name "Megaman & Bass (USA) (Virtual Console).gba" size 8388608 crc b61f99d4 sha1 37db963a52aecec8018057cef3811860c3e889ed ) ) -game ( - name "Megaman & Bass (Europe)" - description "Megaman & Bass (Europe)" - rom ( name "Megaman & Bass (Europe).gba" size 8388608 crc 01b4d95e sha1 5d6f8fb1f52803a54e9857e53d0b88173cf8f48a flags verified ) -) - game ( name "Megaman & Bass (Europe) (Virtual Console)" description "Megaman & Bass (Europe) (Virtual Console)" @@ -11647,9 +11545,9 @@ game ( ) game ( - name "Megaman Zero (USA, Europe)" - description "Megaman Zero (USA, Europe)" - rom ( name "Megaman Zero (USA, Europe).gba" size 8388608 crc 9707d2a1 sha1 193b14120119162518a73c70876f0b8bffdbd96e flags verified ) + name "Megaman & Bass (Europe)" + description "Megaman & Bass (Europe)" + rom ( name "Megaman & Bass (Europe).gba" size 8388608 crc 01b4d95e sha1 5d6f8fb1f52803a54e9857e53d0b88173cf8f48a flags verified ) ) game ( @@ -11659,9 +11557,9 @@ game ( ) game ( - name "Megaman Zero 2 (USA) (Virtual Console)" - description "Megaman Zero 2 (USA) (Virtual Console)" - rom ( name "Megaman Zero 2 (USA) (Virtual Console).gba" size 8388608 crc 30d051fe sha1 d7a1edd912f8e01bc442809b922bceaf5a1f0176 ) + name "Megaman Zero (USA, Europe)" + description "Megaman Zero (USA, Europe)" + rom ( name "Megaman Zero (USA, Europe).gba" size 8388608 crc 9707d2a1 sha1 193b14120119162518a73c70876f0b8bffdbd96e flags verified ) ) game ( @@ -11683,9 +11581,9 @@ game ( ) game ( - name "Megaman Zero 3 (Europe) (Virtual Console)" - description "Megaman Zero 3 (Europe) (Virtual Console)" - rom ( name "Megaman Zero 3 (Europe) (Virtual Console).gba" size 8388608 crc 87e8656e sha1 8245ecb895caf0e0a2914f46bb79e4c9c5ba8c4a ) + name "Megaman Zero 2 (USA) (Virtual Console)" + description "Megaman Zero 2 (USA) (Virtual Console)" + rom ( name "Megaman Zero 2 (USA) (Virtual Console).gba" size 8388608 crc 30d051fe sha1 d7a1edd912f8e01bc442809b922bceaf5a1f0176 ) ) game ( @@ -11706,6 +11604,12 @@ game ( rom ( name "Megaman Zero 3 (USA).gba" size 8388608 crc 2784f3f2 sha1 403a78f2cad93d41e4b0f2e520ce08026531664b ) ) +game ( + name "Megaman Zero 3 (Europe) (Virtual Console)" + description "Megaman Zero 3 (Europe) (Virtual Console)" + rom ( name "Megaman Zero 3 (Europe) (Virtual Console).gba" size 8388608 crc 87e8656e sha1 8245ecb895caf0e0a2914f46bb79e4c9c5ba8c4a ) +) + game ( name "Megaman Zero 4 (Europe) (Virtual Console)" description "Megaman Zero 4 (Europe) (Virtual Console)" @@ -11784,6 +11688,12 @@ game ( rom ( name "Mermaid Melody - Pichi Pichi Pitch - Pichi Pichitto Live Start! (Japan).gba" size 33554432 crc 7a4fdec3 sha1 d6bd3140b83fb9b1c2d84b6faf21c7286e29d129 ) ) +game ( + name "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl)" + description "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl)" + rom ( name "Metal Gear Solid 2D - Sensible (World) (v0.31) (Demo) (Unl).gba" size 149668 crc c797641c sha1 e8a32fbd80f644e9828369603c1a926392a4c105 ) +) + game ( name "Metal Max 2 Kai (Japan)" description "Metal Max 2 Kai (Japan)" @@ -11826,12 +11736,6 @@ game ( rom ( name "Metal Slug Advance (Europe).gba" size 8388608 crc 3806f4ae sha1 0719aee29b0da365e7ad52bb0ae9545bcd377152 flags verified ) ) -game ( - name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" - description "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Metal Warrior 4 (World) (v1.3) (Aftermarket) (Unl).gba" size 524288 crc 7ec3485e sha1 729592141bc160ead0af51d4322c7f9f17da0b82 ) -) - game ( name "Metalgun Slinger (Japan)" description "Metalgun Slinger (Japan)" @@ -11844,6 +11748,24 @@ game ( rom ( name "Metroid - Zero Mission (Japan) (Virtual Console).gba" size 8388608 crc 220b68f5 sha1 24d99f32875464dbcef5ca8ec231ec42073ff1e8 ) ) +game ( + name "Metroid - Zero Mission (USA)" + description "Metroid - Zero Mission (USA)" + 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 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 sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) +) + game ( name "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta)" description "Metroid - Zero Mission (Europe) (En,Fr,De,Es,It) (Beta)" @@ -11869,21 +11791,27 @@ game ( ) game ( - name "Metroid - Zero Mission (USA)" - description "Metroid - Zero Mission (USA)" - rom ( name "Metroid - Zero Mission (USA).gba" size 8388608 crc 5c61a844 sha1 5de8536afe1f0078ee6fe1089f890e8c7aa0a6e8 flags verified ) + 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 ) ) 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 sha1 0fd107445a42e6f3a3e5ce8c865f412583179903 flags verified ) + 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)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16).gba" size 8388608 crc 1605e4f7 sha1 f688f2d3186a0a90040abb214efd1e8e93a424cd ) ) game ( - name "Metroid - Zero Mission (Japan)" - description "Metroid - Zero Mission (Japan)" - rom ( name "Metroid - Zero Mission (Japan).gba" size 8388608 crc 44b79e2b sha1 096f07685a3dc9286e71aa0b761f233b5efa2fcd ) + name "Metroid Fusion (USA) (Virtual Console)" + description "Metroid Fusion (USA) (Virtual Console)" + rom ( name "Metroid Fusion (USA) (Virtual Console).gba" size 8388608 crc 162a46b8 sha1 c63419a4ee7c2a5e412fa16645ee04cb24027724 ) +) + +game ( + name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" + description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" + rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc eee01b78 sha1 82e507863f647dc566bbf45227e8cd284052ecba ) ) game ( @@ -11910,30 +11838,6 @@ game ( 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 ) -) - -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)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Beta) (2002-09-16).gba" size 8388608 crc 1605e4f7 sha1 f688f2d3186a0a90040abb214efd1e8e93a424cd ) -) - -game ( - name "Metroid Fusion (USA) (Virtual Console)" - description "Metroid Fusion (USA) (Virtual Console)" - rom ( name "Metroid Fusion (USA) (Virtual Console).gba" size 8388608 crc 162a46b8 sha1 c63419a4ee7c2a5e412fa16645ee04cb24027724 ) -) - -game ( - name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" - description "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console)" - rom ( name "Metroid Fusion (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc eee01b78 sha1 82e507863f647dc566bbf45227e8cd284052ecba ) -) - game ( name "Mezase! Koushien (Japan)" description "Mezase! Koushien (Japan)" @@ -12036,24 +11940,6 @@ game ( rom ( name "Mini Moni. - Onegai Ohoshi-sama! (Japan).gba" size 8388608 crc f11c35cc sha1 d34795cf3679c6f259177db52a138c0d6e9fcdfd ) ) -game ( - name "Minicraft (World) (v1.0) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.0) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.0) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) -) - -game ( - name "Minicraft (World) (v1.1) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.1) (Aftermarket) (Unl).gba" size 131072 crc 07595773 sha1 fee5cfa5b9e1f3383780432772f29764ac0fc443 ) -) - -game ( - name "Minicraft (World) (v1.2) (Aftermarket) (Unl)" - description "Minicraft (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Minicraft (World) (v1.2) (Aftermarket) (Unl).gba" size 131072 crc 37e7ee7d sha1 dc7faa4952986d5c5f0e3b32203936cd717f97eb ) -) - game ( name "Minna de Puyo Puyo (Japan) (En,Ja)" description "Minna de Puyo Puyo (Japan) (En,Ja)" @@ -12162,12 +12048,6 @@ game ( rom ( name "Mirakuru! Panzou - 7-tsu no Hoshi no Uchuu Kaizoku (Japan).gba" size 4194304 crc 3a87f78b sha1 ad916495bbb9c3ee34b68c13f118a4cbcdb18b3b ) ) -game ( - name "Misfortune Advance (World) (Aftermarket) (Unl)" - description "Misfortune Advance (World) (Aftermarket) (Unl)" - rom ( name "Misfortune Advance (World) (Aftermarket) (Unl).gba" size 5125100 crc 18f2166d sha1 68e215025ac963220f16ea3c100e51698f97c4eb ) -) - game ( name "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" description "Mission Impossible - Operation Surma (Europe) (En,Fr,De,Es,It)" @@ -12420,18 +12300,6 @@ game ( rom ( name "Monsters, Inc. (Europe) (En,Es,Nl).gba" size 4194304 crc d13177e0 sha1 36645b8de074f0b27dbe61528e70ae3af28fb3b9 ) ) -game ( - name "Mooncat's Trio (World) (Aftermarket) (Unl)" - description "Mooncat's Trio (World) (Aftermarket) (Unl)" - rom ( name "Mooncat's Trio (World) (Aftermarket) (Unl).gba" size 1175680 crc b05d5339 sha1 890de7d73723d235d9762e4866d569d3554d1480 flags verified ) -) - -game ( - name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" - description "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" - rom ( name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl).gba" size 504220 crc cd3328ee sha1 c3ea5247f32c428bbcfd5c087218fc56779e3106 ) -) - 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)" @@ -12699,7 +12567,7 @@ game ( 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 sha1 e85cea8428d51e40cf1b7a90643e94604973679f ) + rom ( name "My Animal Centre in Africa (Europe) (En,Fr,De,Es,It).gba" size 33554432 crc d4f6c94d sha1 0f4f86e0c2243d847d16488e42b07e26679dc0ae ) ) game ( @@ -12765,7 +12633,7 @@ game ( game ( name "Namco Museum (Europe)" description "Namco Museum (Europe)" - rom ( name "Namco Museum (Europe).gba" size 4194304 crc bb82460a sha1 3e84508a0d2362a0abf31dede1d55b865566213c ) + rom ( name "Namco Museum (Europe).gba" size 4194304 crc bb82460a sha1 3e84508a0d2362a0abf31dede1d55b865566213c flags verified ) ) game ( @@ -12900,6 +12768,18 @@ game ( rom ( name "NBA Jam 2002 (USA, Europe).gba" size 4194304 crc ca428a7a sha1 38de98758669b120b895661bec3882c3474cf47e ) ) +game ( + name "Nebulus (World) (v1.2) (Unl)" + description "Nebulus (World) (v1.2) (Unl)" + rom ( name "Nebulus (World) (v1.2) (Unl).gba" size 557936 crc 77e2d5f0 sha1 086f7d7e86cfbaff43a4ce35c179e43adbccc4f6 ) +) + +game ( + name "Nebulus (World) (GBAX 2004) (Unl)" + description "Nebulus (World) (GBAX 2004) (Unl)" + rom ( name "Nebulus (World) (GBAX 2004) (Unl).gba" size 544372 crc fb414ccc sha1 4c25014b29e87dd53f3677339f89dd18d316d2f0 ) +) + 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)" @@ -12936,12 +12816,6 @@ game ( rom ( name "Need for Speed - Underground 2 (USA, Europe) (En,Fr,De,It).gba" size 8388608 crc 9a0c5090 sha1 f772000fbdfb84d8d5de9f69bd9c0de551389929 flags verified ) ) -game ( - name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" - description "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" - rom ( name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl).gba" size 508972 crc 55a0734d sha1 79d6977803cd7ee6b1c97ee149cc1bc037c50fb2 ) -) - game ( name "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" description "Neoromance Game - Harukanaru Toki no Naka de (Japan) (Rev 1)" @@ -13008,12 +12882,6 @@ game ( rom ( name "Nicktoons - Freeze Frame Frenzy (USA).gba" size 4194304 crc a8b6766e sha1 a200cdaf66606bd724ce7073fd7990ea3fe6bcdd ) ) -game ( - name "Nicktoons Racing (USA) (Beta)" - description "Nicktoons Racing (USA) (Beta)" - rom ( name "Nicktoons Racing (USA) (Beta).gba" size 4194304 crc 4ed6e860 sha1 d553a265d1405bb073034e16ea97e1a2df899025 ) -) - game ( name "Nicktoons Racing (USA)" description "Nicktoons Racing (USA)" @@ -13026,6 +12894,12 @@ game ( rom ( name "Nicktoons Racing (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc babccefd sha1 55b145de1810a4a6a8b5716ef4c9e9333a93e3ba ) ) +game ( + name "Nicktoons Racing (USA) (Beta)" + description "Nicktoons Racing (USA) (Beta)" + rom ( name "Nicktoons Racing (USA) (Beta).gba" size 4194304 crc 4ed6e860 sha1 d553a265d1405bb073034e16ea97e1a2df899025 ) +) + game ( name "Nicktoons Unite! (USA)" description "Nicktoons Unite! (USA)" @@ -13242,18 +13116,18 @@ game ( 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 sha1 82e48090b9615282c58747a1f7b105196866f8c9 ) -) - game ( name "Oshaberi Inko Club (Japan) (Beta)" description "Oshaberi Inko Club (Japan) (Beta)" rom ( name "Oshaberi Inko Club (Japan) (Beta).gba" size 8388608 crc f896bb9e sha1 e293d18a8a0fb856edafafa03b33454b2d04efd9 ) ) +game ( + name "Oshaberi Inko Club (Japan)" + description "Oshaberi Inko Club (Japan)" + rom ( name "Oshaberi Inko Club (Japan).gba" size 8388608 crc df6901f0 sha1 82e48090b9615282c58747a1f7b105196866f8c9 ) +) + game ( name "Oshare Princess (Japan)" description "Oshare Princess (Japan)" @@ -13461,7 +13335,7 @@ game ( 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 ) + rom ( name "Paws & Claws - Pet Vet (USA).gba" size 8388608 crc efee1ddf sha1 c121eea8f816c4f8cbab32058d6b9bac57f0d7e3 flags verified ) ) game ( @@ -13597,9 +13471,9 @@ game ( ) game ( - name "Phantom, The (Italy) (It) (Proto)" - description "Phantom, The (Italy) (It) (Proto)" - rom ( name "Phantom, The (Italy) (It) (Proto).gba" size 8388608 crc 5833169c sha1 ccd8e9d092a9ded9c3785ac776d40df66512b9b5 ) + name "Phantom, The (Italy) (Proto)" + description "Phantom, The (Italy) (Proto)" + rom ( name "Phantom, The (Italy) (Proto).gba" size 8388608 crc 5833169c sha1 ccd8e9d092a9ded9c3785ac776d40df66512b9b5 ) ) game ( @@ -13674,12 +13548,6 @@ game ( rom ( name "Pinball Tycoon (USA).gba" size 4194304 crc 1c4d3fdf sha1 fac76a646d112a775f9877b53f1386716d968a79 ) ) -game ( - name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" - description "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" - rom ( name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl).gba" size 1048576 crc 9ec140d3 sha1 9e19e8f97e8619a4755c3ceb482fa3e2ad5a4529 ) -) - game ( name "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" description "Pink Panther - Pinkadelic Pursuit (Europe) (En,Fr,De,Es,It)" @@ -13830,12 +13698,6 @@ game ( rom ( name "Pocket Dogs (USA).gba" size 8388608 crc beddc67f sha1 79a90b119ea84c5812575d20ba6107be7edbfee7 ) ) -game ( - name "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" - description "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" - rom ( name "Pocket Meat (World) (Proto) (Aftermarket) (Unl).gba" size 861952 crc 0b029da3 sha1 9958d9a66742cc00e234a96c311b2acec40f69d1 ) -) - game ( name "Pocket Monsters - Emerald (Japan)" description "Pocket Monsters - Emerald (Japan)" @@ -14700,6 +14562,12 @@ game ( rom ( name "Punch King - Arcade Boxing (USA).gba" size 8388608 crc 540b6cc1 sha1 021fdd9420a81a3aa8f37de884ac2b8f42e691ed ) ) +game ( + name "Punch King - Arcade Boxing (World) (Evercade) (Unl)" + description "Punch King - Arcade Boxing (World) (Evercade) (Unl)" + rom ( name "Punch King - Arcade Boxing (World) (Evercade) (Unl).gba" size 8388608 crc 2afd6ff9 sha1 9e145758d3727c664c0612407f4b4d04f7b1733d ) +) + game ( name "Puppy Luv - Spa and Resort (USA)" description "Puppy Luv - Spa and Resort (USA)" @@ -14803,15 +14671,15 @@ game ( ) 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 sha1 9bb5c036bca8f0d2e06013cac7ea6148a4f7f512 ) + name "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl)" + description "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl)" + rom ( name "Racing Fever (World) (En,De,Es,It) (Evercade) (Unl).gba" size 4194304 crc dbd09923 sha1 b10861c12a08826c58dffdbd3071ff72f753b76e ) ) game ( - name "Racing Gears Advance (USA) (Beta)" - description "Racing Gears Advance (USA) (Beta)" - rom ( name "Racing Gears Advance (USA) (Beta).gba" size 8388608 crc 7a3820b3 sha1 ff18dfe7d75a8154c0dcc3970e5d0d4cb75c3568 ) + 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 sha1 9bb5c036bca8f0d2e06013cac7ea6148a4f7f512 ) ) game ( @@ -14826,6 +14694,12 @@ game ( rom ( name "Racing Gears Advance (USA).gba" size 8388608 crc bf648e5c sha1 3f053865f9a687a75927172cd281390b2560201c ) ) +game ( + name "Racing Gears Advance (USA) (Beta)" + description "Racing Gears Advance (USA) (Beta)" + rom ( name "Racing Gears Advance (USA) (Beta).gba" size 8388608 crc 7a3820b3 sha1 ff18dfe7d75a8154c0dcc3970e5d0d4cb75c3568 ) +) + game ( name "Rampage - Puzzle Attack (USA, Europe)" description "Rampage - Puzzle Attack (USA, Europe)" @@ -14838,6 +14712,12 @@ game ( rom ( name "Rapala Pro Fishing (USA, Europe).gba" size 4194304 crc 964d39a7 sha1 e3df6fe7a447ab30faf6fd7d4c57e88f987a5639 ) ) +game ( + name "Ratatouille (Australia, Greece) (En)" + description "Ratatouille (Australia, Greece) (En)" + rom ( name "Ratatouille (Australia, Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc flags verified ) +) + game ( name "Ratatouille (USA)" description "Ratatouille (USA)" @@ -14862,12 +14742,6 @@ game ( rom ( name "Ratatouille (Europe) (En,It,Sv,No,Da).gba" size 8388608 crc 82f9c596 sha1 a5c4a636979c06670a81428c778ff76ed2c65eee ) ) -game ( - name "Ratatouille (Australia, Greece) (En)" - description "Ratatouille (Australia, Greece) (En)" - rom ( name "Ratatouille (Australia, Greece) (En).gba" size 8388608 crc 3e1711c7 sha1 58f2fa1d7e531c7345b11db268e1bbc10372bebc flags verified ) -) - game ( name "Rave Master - Special Attack Force! (USA)" description "Rave Master - Special Attack Force! (USA)" @@ -15006,12 +14880,6 @@ game ( 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 (Europe) (En,Fr,De,Es,It) (Beta)" - description "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" - rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 2189021c sha1 b6e2167272a68bd4e3833cccd68929d50a27a426 ) -) - game ( name "Rebelstar - Tactical Command (USA)" description "Rebelstar - Tactical Command (USA)" @@ -15024,6 +14892,12 @@ game ( rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc e448c5d4 sha1 669c47e62f2388ce0ba676f3dc641b5ad2ddb5c5 flags verified ) ) +game ( + name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" + description "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta)" + rom ( name "Rebelstar - Tactical Command (Europe) (En,Fr,De,Es,It) (Beta).gba" size 4194304 crc 2189021c sha1 b6e2167272a68bd4e3833cccd68929d50a27a426 ) +) + game ( name "Recca no Honoo - The Game (Japan)" description "Recca no Honoo - The Game (Japan)" @@ -15198,6 +15072,12 @@ game ( rom ( name "Robot Wars - Advanced Destruction (USA).gba" size 4194304 crc e6cb567d sha1 952adf4e17865abc2b983c79ad4080e9b4867370 ) ) +game ( + name "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20)" + description "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20)" + rom ( name "Robot Wars - Advanced Destruction (USA) (Beta) (2001-03-20).gba" size 585104 crc ce95bbd6 sha1 e045c21b0fef1959c1207bb46e509089b03fd6db ) +) + 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)" @@ -15210,6 +15090,12 @@ game ( 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 (Japan)" + description "Robots (Japan)" + rom ( name "Robots (Japan).gba" size 16777216 crc 1beb9e91 sha1 b1a670daf53d47f237a4078388178c16c843d4dc ) +) + game ( name "Robots (USA)" description "Robots (USA)" @@ -15222,12 +15108,6 @@ game ( 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 sha1 b1a670daf53d47f237a4078388178c16c843d4dc ) -) - game ( name "Rock 'N Roll Racing (USA)" description "Rock 'N Roll Racing (USA)" @@ -15279,7 +15159,7 @@ game ( 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 sha1 2e8fcf7afe49b57c2527f31288198a4b93df8bec ) + rom ( name "Rocket Power - Zero Gravity Zone (USA).gba" size 8388608 crc 26d62d32 sha1 2e8fcf7afe49b57c2527f31288198a4b93df8bec flags verified ) ) game ( @@ -15759,7 +15639,7 @@ game ( 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 sha1 9a483e98d72b1d7d8579511cc9344e5d27bcee61 ) + rom ( name "Scorpion King, The - Sword of Osiris (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc d5410d32 sha1 9a483e98d72b1d7d8579511cc9344e5d27bcee61 flags verified ) ) game ( @@ -15981,7 +15861,7 @@ game ( 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 sha1 0bca9c4dd35d02c52a5db98b2097a50ef159de32 ) + rom ( name "Shamu's Deep Sea Adventures (USA).gba" size 33554432 crc 7ecb7529 sha1 1927b344bba21bcd80544a55734234610972f373 flags verified ) ) game ( @@ -16518,12 +16398,6 @@ game ( 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 "Sips (World) (Aftermarket) (Unl)" - description "Sips (World) (Aftermarket) (Unl)" - rom ( name "Sips (World) (Aftermarket) (Unl).gba" size 6235380 crc 5c1fb22d sha1 bb725df7226307d55df04365f85e5698b199c3c9 ) -) - game ( name "Sister Princess - RePure (Japan)" description "Sister Princess - RePure (Japan)" @@ -16572,30 +16446,6 @@ game ( rom ( name "Sky Dancers - They Magically Fly! (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 3af1063b sha1 df749ac7e33a1c7ede3faadb6648a8e53fa77048 ) ) -game ( - name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl).gba" size 15887876 crc c798529d sha1 ea4a6494bcec25757f657c69550c91190e46cebd ) -) - -game ( - name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl).gba" size 15894868 crc af572de8 sha1 997bf192369d48433a7c35187c7e1d0b5fcc16e0 ) -) - -game ( - name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl).gba" size 15900084 crc df05edff sha1 1328d17668480b4e9bea338662532ace332c74a9 ) -) - -game ( - name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" - description "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" - rom ( name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl).gba" size 16075456 crc d271c516 sha1 0dbdf16b23afb70229eff2de269fd5d73659d745 ) -) - game ( name "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" description "Slime Morimori Dragon Quest - Shougeki no Shippo Dan (Japan)" @@ -16653,7 +16503,7 @@ game ( game ( name "Snood (USA)" description "Snood (USA)" - rom ( name "Snood (USA).gba" size 4194304 crc f1f1f148 sha1 2c09548ae924ac0c1a3e15412d9a7aae7707a753 ) + rom ( name "Snood (USA).gba" size 4194304 crc f1f1f148 sha1 2c09548ae924ac0c1a3e15412d9a7aae7707a753 flags verified ) ) game ( @@ -16884,6 +16734,12 @@ game ( rom ( name "Space Invaders EX (Japan) (En).gba" size 4194304 crc 297b9854 sha1 ae8cace77baccdb8f25c9b44ea3cf64d881b91a8 ) ) +game ( + name "Space Twins (World) (Proto) (Unl)" + description "Space Twins (World) (Proto) (Unl)" + rom ( name "Space Twins (World) (Proto) (Unl).gba" size 1350536 crc 0edc97d9 sha1 4a9848cc2262b30aba7e87013c0a197e01cc9617 ) +) + game ( name "Speedball 2 (Europe) (En,Fr,De,Es,It)" description "Speedball 2 (Europe) (En,Fr,De,Es,It)" @@ -17070,6 +16926,18 @@ game ( 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 - Lights, Camera, Pants! (USA) (Beta) (2005-08-03)" + description "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-03)" + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-03).gba" size 4291500 crc 52fd3771 sha1 72d84f52c796cbb06c2cd9291ca7952093d9b7dc ) +) + +game ( + name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05)" + description "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05)" + rom ( name "SpongeBob SquarePants - Lights, Camera, Pants! (USA) (Beta) (2005-08-05).gba" size 4519932 crc e1461b58 sha1 b30dc120107a70796250b831e7174fc4c03ae58a ) +) + game ( name "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" description "SpongeBob SquarePants - Revenge of the Flying Dutchman (USA) (Beta)" @@ -17166,6 +17034,24 @@ game ( rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-07-31).gba" size 4194304 crc f2f67f40 sha1 bb298d490ec9d8657cbd2fc402ae1e0a5792d406 ) ) +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-03-28).gba" size 4646712 crc 1407d86e sha1 2608c985c8ab5bffeae0687421bb21a46e34b681 ) +) + +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-03).gba" size 5477108 crc 0bc6dfaf sha1 c617321d405f4a5bb07c4fa769321df46a944bb8 ) +) + +game ( + name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04)" + description "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04)" + rom ( name "SpongeBob SquarePants - SuperSponge (USA, Europe) (Beta) (2001-04-04).gba" size 5477244 crc 23d7ba77 sha1 0177808f1bcd65738c10fd0fba477ecdd46a791f ) +) + 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)" @@ -17277,7 +17163,7 @@ game ( 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 sha1 854e788e5e1316b7d5cdf6b961d0969e5cd62119 ) + rom ( name "Spyro - Season of Ice (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc afd25827 sha1 854e788e5e1316b7d5cdf6b961d0969e5cd62119 flags verified ) ) game ( @@ -17349,7 +17235,7 @@ game ( game ( name "SSX 3 (USA, Europe)" description "SSX 3 (USA, Europe)" - rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232f58a sha1 4f2bd55bcd3118e10520179e285aae897aa21898 ) + rom ( name "SSX 3 (USA, Europe).gba" size 8388608 crc 8232f58a sha1 4f2bd55bcd3118e10520179e285aae897aa21898 flags verified ) ) game ( @@ -17385,7 +17271,7 @@ game ( 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 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 flags verified ) ) game ( @@ -17439,7 +17325,7 @@ game ( 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 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 ( @@ -17571,7 +17457,7 @@ game ( 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 sha1 fdb6d8098340966456cd05c7babe77b5a204608c ) + rom ( name "Stuart Little 2 (USA, Europe).gba" size 8388608 crc 6eb7c688 sha1 fdb6d8098340966456cd05c7babe77b5a204608c flags verified ) ) game ( @@ -17676,6 +17562,12 @@ game ( rom ( name "Super Bubble Pop (Europe) (En,Fr,De,Es,It,Nl,Pt,Sv).gba" size 4194304 crc 25123d97 sha1 f62396b5502437651d26e1ad27a8ec8c18b4268e ) ) +game ( + name "Super Bubble Pop (World) (Evercade) (Unl)" + description "Super Bubble Pop (World) (Evercade) (Unl)" + rom ( name "Super Bubble Pop (World) (Evercade) (Unl).gba" size 4194304 crc 940f385e sha1 fa2c3b84014a84143f519609a8808d13ca33bf22 ) +) + game ( name "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" description "Super Bust-A-Move (Europe) (En,Fr,De,Es,It)" @@ -17701,15 +17593,9 @@ game ( ) 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 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 sha1 a0ac6be19f385eef6bc48bca8d54520d4e8a00e7 flags verified ) + 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 ) ) game ( @@ -17719,9 +17605,15 @@ game ( ) 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 ) + name "Super Dodge Ball Advance (USA)" + description "Super Dodge Ball Advance (USA)" + 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 sha1 a0ac6be19f385eef6bc48bca8d54520d4e8a00e7 flags verified ) ) game ( @@ -17775,7 +17667,7 @@ game ( 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 sha1 038b533bb09845ade7b0a13c7ca9923348eb1100 ) + rom ( name "Super Hornet FA 18F (USA, Europe).gba" size 4194304 crc 9653bac5 sha1 038b533bb09845ade7b0a13c7ca9923348eb1100 flags verified ) ) game ( @@ -18169,9 +18061,9 @@ game ( ) game ( - name "Sushi the Cat (World) (Aftermarket) (Unl)" - description "Sushi the Cat (World) (Aftermarket) (Unl)" - rom ( name "Sushi the Cat (World) (Aftermarket) (Unl).gba" size 540296 crc 6f019a88 sha1 f6d523a073c21639e15d615947167bba3871c67a ) + name "Sushi the Cat (World) (Unl)" + description "Sushi the Cat (World) (Unl)" + rom ( name "Sushi the Cat (World) (Unl).gba" size 540296 crc 6f019a88 sha1 f6d523a073c21639e15d615947167bba3871c67a ) ) game ( @@ -18249,7 +18141,7 @@ game ( 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 sha1 0999a8ee2bae78a223c992408e987422ba0c0af9 ) + rom ( name "Tak - The Great Juju Challenge (USA, Europe).gba" size 8388608 crc 881c8416 sha1 0999a8ee2bae78a223c992408e987422ba0c0af9 flags verified ) ) game ( @@ -18261,7 +18153,7 @@ game ( 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 sha1 f90219db6359332eb997a2717986a8c66eaded2b ) + rom ( name "Tak 2 - The Staff of Dreams (USA).gba" size 8388608 crc 8f7eb026 sha1 f90219db6359332eb997a2717986a8c66eaded2b flags verified ) ) game ( @@ -18537,7 +18429,7 @@ game ( 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 sha1 4a1297b44208366a178cc1f2541f5ea8386f6f3e ) + rom ( name "Tetris Worlds (Europe) (En,Fr,De,Nl).gba" size 4194304 crc ad97eb3f sha1 4a1297b44208366a178cc1f2541f5ea8386f6f3e flags verified ) ) game ( @@ -18549,7 +18441,7 @@ game ( game ( name "Texas Hold 'em Poker (USA)" description "Texas Hold 'em Poker (USA)" - rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d ) + rom ( name "Texas Hold 'em Poker (USA).gba" size 4194304 crc 78b59aac sha1 5fcc9958210d8bde94a429516b15ca669427fe6d flags verified ) ) game ( @@ -18609,13 +18501,13 @@ game ( game ( name "Thunder Alley (USA)" description "Thunder Alley (USA)" - rom ( name "Thunder Alley (USA).gba" size 4194304 crc 25e8e649 sha1 d63aaf9ac4468f1d0ead35606d9a4f56327b2537 ) + 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 sha1 08c4b9b924f5cf0404cab5cd7fb6064fca872250 ) + rom ( name "Thunderbirds (USA, Europe).gba" size 4194304 crc f09b7bb0 sha1 08c4b9b924f5cf0404cab5cd7fb6064fca872250 flags verified ) ) game ( @@ -18633,7 +18525,7 @@ game ( 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 sha1 88b204b7b51995e41459b532580b3956d7db55ad ) + rom ( name "Tiger Woods PGA Tour Golf (USA, Europe).gba" size 8388608 crc f3f26acc sha1 88b204b7b51995e41459b532580b3956d7db55ad flags verified ) ) game ( @@ -18675,7 +18567,7 @@ game ( 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 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 ( @@ -18798,6 +18690,12 @@ game ( rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 6863ce1a sha1 092179cd51657a4572fa855eb3e5bc3f46c1d76f ) ) +game ( + name "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25)" + description "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25)" + rom ( name "Tom Clancy's Rainbow Six - Rogue Spear (USA, Europe) (En,Fr,De,Es,It) (Beta) (2001-10-25).gba" size 7963152 crc 666e31b5 sha1 d8426022537149670871817ff9336261b31172b5 ) +) + game ( name "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" description "Tom Clancy's Splinter Cell (USA) (En,Fr,Es)" @@ -19047,7 +18945,7 @@ game ( game ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube)" description "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube)" - rom ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 7cd6839c sha1 ace1d3587636d17fd9ebfe7a7cfd3ee36bc51b43 flags verified ) + rom ( name "Tottoko Hamutarou - Hamu-Hamu Sports (Japan) (Demo) (Kiosk, GameCube).gba" size 16777216 crc 7cd6839c sha1 ace1d3587636d17fd9ebfe7a7cfd3ee36bc51b43 ) ) game ( @@ -19119,37 +19017,7 @@ game ( 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 sha1 d89a2515f4fe0d0ac90b20e4633a80a2549175fc ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) -) - -game ( - name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - description "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) -) - -game ( - name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" - description "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) -) - -game ( - name "Tremblay Island (World) (Aftermarket) (Unl)" - description "Tremblay Island (World) (Aftermarket) (Unl)" - rom ( name "Tremblay Island (World) (Aftermarket) (Unl).gba" size 16225608 crc 95503690 sha1 634ea6be3df5ebd85c9c60871e34fc3c72ae5140 ) + rom ( name "Treasure Planet (Europe) (En,Fr,De,Es,It,Nl).gba" size 8388608 crc d52ddce1 sha1 d89a2515f4fe0d0ac90b20e4633a80a2549175fc flags verified ) ) game ( @@ -19461,7 +19329,7 @@ game ( game ( name "Unfabulous (USA)" description "Unfabulous (USA)" - rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547f3a1 sha1 a56e96a46ed7264bddbfc132925d291e3e8f0e38 ) + rom ( name "Unfabulous (USA).gba" size 4194304 crc 2547f3a1 sha1 a56e96a46ed7264bddbfc132925d291e3e8f0e38 flags verified ) ) game ( @@ -19494,6 +19362,36 @@ game ( rom ( name "Uno 52 (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 315360d0 sha1 f85709ec7a97c8b40504f2097497bd961531272d ) ) +game ( + name "Uranus (World) (Unl)" + description "Uranus (World) (Unl)" + rom ( name "Uranus (World) (Unl).gba" size 4194304 crc 8152384d sha1 2c99b0c66cea1ce8d203aaa0985baa43fcdd82bd ) +) + +game ( + name "Uranus 2 - Sun Tear (World) (En,Fr) (Unl)" + description "Uranus 2 - Sun Tear (World) (En,Fr) (Unl)" + rom ( name "Uranus 2 - Sun Tear (World) (En,Fr) (Unl).gba" size 4194304 crc f1c63552 sha1 7c68363212a7fb424429281a658cbadfe37de035 ) +) + +game ( + name "Uranus Zero - Sun Tear (World) (En,Fr) (Unl)" + description "Uranus Zero - Sun Tear (World) (En,Fr) (Unl)" + rom ( name "Uranus Zero - Sun Tear (World) (En,Fr) (Unl).gba" size 8388608 crc 117183cc sha1 258058fb9ca44a93478220e19d0cf09cde527003 ) +) + +game ( + name "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl)" + description "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl)" + rom ( name "Uranus Zero EV (World) (En,Fr) (v1.1) (Unl).gba" size 7609632 crc 1b463c9e sha1 bb2536ae8c6b625f3abfb66add7c1b3b74b942ee ) +) + +game ( + name "Uranus Zero EV (World) (En,Fr) (Unl)" + description "Uranus Zero EV (World) (En,Fr) (Unl)" + rom ( name "Uranus Zero EV (World) (En,Fr) (Unl).gba" size 7610684 crc adbcba92 sha1 405fb8cefb7ab0262a5f3bb7d290b9b60128db9b ) +) + game ( name "Urban Yeti! (USA, Europe)" description "Urban Yeti! (USA, Europe)" @@ -19611,7 +19509,7 @@ game ( 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 sha1 dce3603206745f3d9288f35eab33cc0f890c3751 ) + rom ( name "W.i.t.c.h. (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc ca4f6d5d sha1 dce3603206745f3d9288f35eab33cc0f890c3751 flags verified ) ) game ( @@ -19656,12 +19554,6 @@ game ( rom ( name "Wagamama Fairy Mirumo de Pon! - Yume no Kakera (Japan).gba" size 8388608 crc a606c803 sha1 0429693de0ff6e020b01807047dbb07b70b42529 ) ) -game ( - name "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" - description "Waimanu - Grinding Blocks Adventure (World) (Homebrew)" - rom ( name "Waimanu - Grinding Blocks Adventure (World) (Homebrew).gba" size 1739504 crc 0fe153c5 sha1 c4ce156b04fb257875bc5f539f3d64accbc08451 ) -) - game ( name "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" description "Wakeboarding Unleashed Featuring Shaun Murray (Europe)" @@ -19716,12 +19608,6 @@ game ( rom ( name "Wanwan Meitantei (Japan).gba" size 8388608 crc 5f41c9fe sha1 d438e3b030a814818ed7e96777ac3e46043922f9 ) ) -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 sha1 b9fe05a8080e124b67bce6a623234ee3b518a2c1 flags verified ) -) - game ( name "Wario Land 4 (USA, Europe) (Virtual Console)" description "Wario Land 4 (USA, Europe) (Virtual Console)" @@ -19729,9 +19615,9 @@ game ( ) game ( - name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" - description "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" - rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2d3e6b124c84877520b482ba1016b8e3c36bab14 ) + name "Wario Land 4 (USA, Europe)" + description "Wario Land 4 (USA, Europe)" + rom ( name "Wario Land 4 (USA, Europe).gba" size 8388608 crc d6141609 sha1 b9fe05a8080e124b67bce6a623234ee3b518a2c1 flags verified ) ) game ( @@ -19741,15 +19627,15 @@ game ( ) game ( - name "WarioWare - Twisted! (USA, Australia)" - description "WarioWare - Twisted! (USA, Australia)" - rom ( name "WarioWare - Twisted! (USA, Australia).gba" size 16777216 crc cb4e844b sha1 f0102d0d6f7596fe853d5d0a94682718278e083a flags verified ) + name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" + description "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console)" + rom ( name "Wario Land Advance - Youki no Otakara (Japan) (Virtual Console).gba" size 8388608 crc a8cd90f9 sha1 2d3e6b124c84877520b482ba1016b8e3c36bab14 ) ) 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 sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) + name "WarioWare - Twisted! (USA, Australia)" + description "WarioWare - Twisted! (USA, Australia)" + rom ( name "WarioWare - Twisted! (USA, Australia).gba" size 16777216 crc cb4e844b sha1 f0102d0d6f7596fe853d5d0a94682718278e083a flags verified ) ) game ( @@ -19765,9 +19651,9 @@ game ( ) game ( - name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" - rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) + name "WarioWare, Inc. - Mega Microgame$! (USA)" + description "WarioWare, Inc. - Mega Microgame$! (USA)" + rom ( name "WarioWare, Inc. - Mega Microgame$! (USA).gba" size 8388608 crc 785d8b8c sha1 3f556448d290fa5406d6ed367fee16cc02387ad3 flags verified ) ) game ( @@ -19776,6 +19662,12 @@ game ( 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. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + description "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console)" + rom ( name "WarioWare, Inc. - Minigame Mania (Europe) (En,Fr,De,Es,It) (Virtual Console).gba" size 8388608 crc 1fe34e43 sha1 dca921c60b3686be6b3a5feeec7a4f37a921aee3 ) +) + game ( name "Weekend Miljonairs (Netherlands)" description "Weekend Miljonairs (Netherlands)" @@ -19908,18 +19800,18 @@ game ( rom ( name "Winning Post for Game Boy Advance (Japan) (Rev 2).gba" size 4194304 crc 9fb4af0a sha1 9151cf54475c4f773bdd9ab86a42d3e1ba462afa ) ) -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 sha1 cc7e9c2a9e1df985aed3dc4a018c93140d7a1b2c ) -) - 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 ) ) +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 sha1 cc7e9c2a9e1df985aed3dc4a018c93140d7a1b2c ) +) + game ( name "Winter Sports (Europe) (En,Fr,De,Es,It)" description "Winter Sports (Europe) (En,Fr,De,Es,It)" @@ -19950,18 +19842,6 @@ game ( rom ( name "WinX Club - Quest for the Codex (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 9eb09c77 sha1 84951f8baabc405eee8a1fb94d420397623265ad ) ) -game ( - name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" - description "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" - rom ( name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl).gba" size 1449956 crc 4ffa611d sha1 89bbeb3fbce1533acf2f2113642ebe2a4f9f79a8 ) -) - -game ( - name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" - description "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" - rom ( name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl).gba" size 1449956 crc 27055186 sha1 b9ce91d55870e07434509f6e2e91c2f90b4afc97 ) -) - game ( name "Wizardry Summoner (Japan) (Rev 1)" description "Wizardry Summoner (Japan) (Rev 1)" @@ -20011,15 +19891,15 @@ game ( ) 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 ) + name "World Championship Poker (USA)" + description "World Championship Poker (USA)" + rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07f15152 sha1 1d72864021f88f8db2686c57cfc5176b33ce2015 flags verified ) ) game ( - name "World Championship Poker (USA)" - description "World Championship Poker (USA)" - rom ( name "World Championship Poker (USA).gba" size 4194304 crc 07f15152 sha1 1d72864021f88f8db2686c57cfc5176b33ce2015 ) + 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 ( @@ -20041,9 +19921,9 @@ game ( ) game ( - name "World Reborn (USA) (Aftermarket) (Unl)" - description "World Reborn (USA) (Aftermarket) (Unl)" - rom ( name "World Reborn (USA) (Aftermarket) (Unl).gba" size 4194304 crc eefb32ff sha1 c7ec2f8d7d3dec40a893cdfe2a41a8ed43ed71c4 ) + name "World Tennis Stars (Europe)" + description "World Tennis Stars (Europe)" + rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) ) game ( @@ -20053,9 +19933,9 @@ game ( ) game ( - name "World Tennis Stars (Europe)" - description "World Tennis Stars (Europe)" - rom ( name "World Tennis Stars (Europe).gba" size 4194304 crc b5830f5f sha1 2a93449943e85b7c5d75d0d7a9e1d8ad67c7a706 ) + 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 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) ) game ( @@ -20064,18 +19944,18 @@ game ( rom ( name "Worms - World Party (Europe) (En,Fr,De,Es,It).gba" size 4194304 crc 8ee32cbe sha1 5e0abe3d94d1489fadebe897df1ed5a5c0212901 ) ) -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 sha1 7b078976d9056aba7f81bb1ff33e5a36357f5f0b ) -) - 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 sha1 0da4ff24b61ae8b6d67ef59377770fd958517f2f ) ) +game ( + name "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl)" + description "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl)" + rom ( name "Worms Blast (World) (En,Fr,De,Es,It) (Evercade) (Unl).gba" size 4194304 crc 55c25c4a sha1 da4e430b5fef43bdb8a4c52a8fdec5ae98243ddb ) +) + game ( name "WTA Tour Tennis (USA)" description "WTA Tour Tennis (USA)" @@ -20118,18 +19998,18 @@ game ( rom ( name "X Zhan Jing (Taiwan) (Unl).gba" size 33554432 crc 652a2ebe sha1 a35c891af070819fd14e0704984197c8e04ae127 ) ) -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 sha1 a8354a51738c6b28660ab74acc7f8445a9a570a1 ) -) - 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 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 sha1 a8354a51738c6b28660ab74acc7f8445a9a570a1 ) +) + game ( name "X-Man - Armour of Might (Russia) (Unl)" description "X-Man - Armour of Might (Russia) (Unl)" @@ -20217,19 +20097,19 @@ game ( game ( name "Yggdra Union (Japan)" description "Yggdra Union (Japan)" - rom ( name "Yggdra Union (Japan).gba" size 33554432 crc a86f844a sha1 4ac5874b98f0fa3c3aad4c3ebe927f7fbc5b3267 ) + rom ( name "Yggdra Union (Japan).gba" size 33554432 crc bf53a3d2 sha1 b55d786fd8f80e71d24097ae45f5fcc5948f395b ) ) 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 sha1 b289083b01f2f8fc726c664cf872d72b3f4986e3 ) + rom ( name "Yggdra Union - We'll Never Fight Alone (USA).gba" size 33554432 crc 84b5666c sha1 75697060a9c262fd00552ddd06faec82fc310282 ) ) 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 sha1 e419c835200457f67d5ab7e3c236583980b922d9 ) + rom ( name "Yggdra Union - We'll Never Fight Alone (Europe).gba" size 33554432 crc 2931d6a8 sha1 7b65074cb5d75d8f12692a21e2be77fa963f10e2 ) ) game ( @@ -20268,6 +20148,12 @@ game ( rom ( name "Youkaidou (Japan).gba" size 8388608 crc 2a4a92b4 sha1 ed6578bb6a4f201ae5b269df5ce842158a34a421 ) ) +game ( + name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" + description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" + rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta).gba" size 16777216 crc 8cbfa66b sha1 d3906650386872a94b83c417ecef2369ece5b978 ) +) + game ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA)" @@ -20280,12 +20166,6 @@ game ( rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (Europe) (En,Fr,De,Es,It).gba" size 8388608 crc 208d77ec sha1 66dc426b71195c11761f7ce58ffef231e8e227b1 ) ) -game ( - name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" - description "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta)" - rom ( name "Yu Yu Hakusho - Ghostfiles - Spirit Detective (USA) (Beta).gba" size 16777216 crc 8cbfa66b sha1 d3906650386872a94b83c417ecef2369ece5b978 ) -) - game ( name "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" description "Yu Yu Hakusho - Ghostfiles - Tournament Tactics (USA, Europe)" @@ -20343,7 +20223,7 @@ game ( 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 sha1 1d33877dcc5ec94cc0d68460163208c7ebfb6ad3 ) + rom ( name "Yu-Gi-Oh! - Reshef of Destruction (Europe) (En,Fr,De,Es,It).gba" size 16777216 crc 460e073f sha1 1d33877dcc5ec94cc0d68460163208c7ebfb6ad3 flags verified ) ) game ( @@ -20721,7 +20601,7 @@ game ( clrmamepro ( name "Nintendo - Game Boy Advance (Multiboot)" description "Nintendo - Game Boy Advance (Multiboot)" - version 20220808-164416 + version 20240221-035028 author "Arctic Circle System, C. V. Reynolds, chillerecke, DeriLoko3, Hiccup, hking0036, niemand, norkmetnoil577, omonim2007, relax" homepage No-Intro url "https://www.no-intro.org" @@ -21311,8 +21191,8 @@ game ( clrmamepro ( name "Nintendo - Game Boy Advance (Video)" description "Nintendo - Game Boy Advance (Video)" - version 20230804-201325 - author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, relax, SonGoku, xuom2" + version 20240727-194101 + author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, Psychofox11, psykopat, relax, SonGoku, xuom2" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -21364,18 +21244,18 @@ game ( 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) (Rev 5)" - description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" - rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5).gba" size 33554432 crc 1baf372d sha1 86f257c7b8d8feaee0a7e7dd5f5ba48053fd633e 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 sha1 5f17d2ec1a3ba1d605d486b6f6abcde6d82df767 ) ) +game ( + name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + description "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5)" + rom ( name "Game Boy Advance Video - Cartoon Network Collection - Special Edition (USA) (Rev 5).gba" size 33554432 crc 1baf372d sha1 86f257c7b8d8feaee0a7e7dd5f5ba48053fd633e flags verified ) +) + game ( name "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" description "Game Boy Advance Video - Cartoon Network Collection - Volume 1 (USA, Europe)" @@ -21460,18 +21340,18 @@ game ( 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 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 ) -) - 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)" @@ -21490,18 +21370,18 @@ game ( 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 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 ) -) - 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 ) +) + game ( name "Game Boy Advance Video - Sonic X - Volume 1 (USA)" description "Game Boy Advance Video - Sonic X - Volume 1 (USA)" @@ -21574,23 +21454,1203 @@ game ( 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 (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 sha1 8fb43e5018cf2d4b1a2aa2d1693862ce248ab6b0 ) -) - 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 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 sha1 8fb43e5018cf2d4b1a2aa2d1693862ce248ab6b0 flags verified ) +) + +clrmamepro ( + name "Nintendo - Game Boy Advance (Aftermarket)" + description "Nintendo - Game Boy Advance (Aftermarket)" + version 20240807-214821 + author "aci68, Arctic Circle System, Aringon, Bent, BigFred, bikerspade, C. V. Reynolds, chillerecke, DeadSkullzJr, Densetsu, DeriLoko3, einstein95, ElBarto, Enker, FakeShemp, Flashfire42, fuzzball, Gefflon, Hiccup, hking0036, hydr0x, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, Larsenv, Lesserkuma, Madeline, MeguCocoa, Money_114, NESBrew12, niemand, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Prominos, Psychofox11, psykopat, rarenight, relax, RetroGamer, Rifu, sCZther, SonGoku, Tauwasser, Tescu, togemet2, ufocrossing, Vallaine01, Whovian9369, xprism, xuom2, zg" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl)" + description "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl)" + rom ( name "2-in-1 - Smickeonn the Game + Smickeonn the Game Deluxe (World) (Demo) (Aftermarket) (Unl).gba" size 1648884 crc 8ad5b73f sha1 eb85e372f15299cde6fefa8a2967e7e2886c9c56 ) +) + +game ( + name "2048 Pool (World) (Aftermarket) (Unl)" + description "2048 Pool (World) (Aftermarket) (Unl)" + rom ( name "2048 Pool (World) (Aftermarket) (Unl).gba" size 203440 crc 9df6ae4f sha1 c93a9cf3502237b474e70de8dee274901ee7ecb2 ) +) + +game ( + name "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl)" + description "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Advanced Ghost Wranglin' (World) (Demo) (Aftermarket) (Unl).gba" size 354992 crc 739eb5ce sha1 9cf53301404407aae24ac7735006f594ca0fe969 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Aftermarket) (Unl).gba" size 1710888 crc 3346891f sha1 270c426705df767a4ad2dc69d039842442f779b2 flags verified ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (2021-02-28) (Patreon) (Aftermarket) (Unl).gba" size 1729120 crc a354d555 sha1 d7cd0ab9d622187d4ce55bf0c7f14a24ee781710 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.95) (Itch.io) (Aftermarket) (Unl).gba" size 1775856 crc 41ea5b0b sha1 e351bc6a9046ec002fc2dfdee061047908bd4350 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Retro-Bit Generations) (Aftermarket) (Unl).gba" size 1775660 crc a234813c sha1 ad904624bf198a164ba580eea326cd30fffebac8 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Demo) (Aftermarket) (Unl).gba" size 597104 crc 0a9098b4 sha1 0992fb6f38e49426adc834fb3831748a1caa1bc0 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v2.0) (Demo) (Aftermarket) (Unl).gba" size 811840 crc 63c1cc2c sha1 faca8225ee20b8e5edb14e005af77b63c6f51446 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.91) (Aftermarket) (Unl).gba" size 1714000 crc eebb016f sha1 008a9d06f78bccc540ca4ece4d1982de76f95901 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.92) (Aftermarket) (Unl).gba" size 1710624 crc ba271987 sha1 04f1e79e79e894d8f45ed1ea2ff5aa67053f0ab3 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl).gba" size 1710624 crc df7108e3 sha1 bd267fd7e762acb8cd595e54bfd51a139864759e ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" + description "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.93) (Aftermarket) (Unl) (Alt).gba" size 1714000 crc 54ff2e56 sha1 0386315fc140db2a43a6f927c04de658bd800da9 ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (v0.94) (Aftermarket) (Unl).gba" size 1710952 crc cb4e2768 sha1 a7297cf4ecffc1f93f86edde68e1ff42e8099f3b ) +) + +game ( + name "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl)" + description "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl)" + rom ( name "Anguna - Warriors of Virtue (World) (Evercade) (Aftermarket) (Unl).gba" size 1693656 crc 7d8c00d3 sha1 9fffd28c933ac88a441a2e262156c66a3a763829 ) +) + +game ( + name "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" + description "Apotris (World) (v3.4.5) (Aftermarket) (Unl)" + rom ( name "Apotris (World) (v3.4.5) (Aftermarket) (Unl).gba" size 4194304 crc 55ae4312 sha1 fb7142bcc30f71f187cc51b7fcbc5a3958374c6c ) +) + +game ( + name "Armadillo Run (World) (Demo) (Aftermarket) (Unl)" + description "Armadillo Run (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Armadillo Run (World) (Demo) (Aftermarket) (Unl).gba" size 1260068 crc 5151babd sha1 dfb706257d598a5ae845ddf6485e59a88c16d210 ) +) + +game ( + name "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Attack on Voxelburg (World) (Demo) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 827676 crc 941c1fe0 sha1 cb3823420a6e2399db7fa4805fefd1b5366c778e ) +) + +game ( + name "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl)" + description "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Battery Chad - Shock the World (World) (Demo) (Aftermarket) (Unl).gba" size 609400 crc e0a4bc38 sha1 3274c915fb78d10541efa69dfbb8f9391f974ffe ) +) + +game ( + name "Blender Bros. (World) (Aftermarket) (Unl)" + description "Blender Bros. (World) (Aftermarket) (Unl)" + rom ( name "Blender Bros. (World) (Aftermarket) (Unl).gba" size 8388608 crc 440f2f06 sha1 8f9ca62306b7ab56d8da45673d7b7d0eb4c349c5 ) +) + +game ( + name "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl)" + description "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Blind Jump (World) (En,Ja,Fr,It,Ru) (v2021.11.20.0) (Proto) (Aftermarket) (Unl).gba" size 16565008 crc 2342e91e sha1 2e5758789f7e109839ea302424c385c1247eab38 ) +) + +game ( + name "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl)" + description "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl)" + rom ( name "Blood Drive (World) (GBA Jam Week) (Aftermarket) (Unl).gba" size 1523780 crc 3444a7ae sha1 12a3c114563684fdca4a4ee1b3fea43ceaf226c0 ) +) + +game ( + name "Broken Circle (World) (En,It) (Aftermarket) (Unl)" + description "Broken Circle (World) (En,It) (Aftermarket) (Unl)" + rom ( name "Broken Circle (World) (En,It) (Aftermarket) (Unl).gba" size 16777216 crc 3212c09b sha1 e04a71dbe7b640cc53e81f447856e60666e64aa3 ) +) + +game ( + name "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl)" + description "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl)" + rom ( name "Brush Rush (World) (Proto) (GBA WinterJam 2023) (Aftermarket) (Unl).gba" size 371136 crc afdf2c03 sha1 d36f7bd6d0420597ba0f12f746f8ec8a628b3658 ) +) + +game ( + name "Butano Fighter (World) (Aftermarket) (Unl)" + description "Butano Fighter (World) (Aftermarket) (Unl)" + rom ( name "Butano Fighter (World) (Aftermarket) (Unl).gba" size 3482456 crc 3c31501c sha1 36efe397badf199c0339222dc825013c06b86423 ) +) + +game ( + name "Cat's Curse (World) (Aftermarket) (Unl)" + description "Cat's Curse (World) (Aftermarket) (Unl)" + rom ( name "Cat's Curse (World) (Aftermarket) (Unl).gba" size 353052 crc a35d87de sha1 4a149baad17840948c2d4ffdf068bfaf1116a024 ) +) + +game ( + name "CCCP (World) (Aftermarket) (Unl)" + description "CCCP (World) (Aftermarket) (Unl)" + rom ( name "CCCP (World) (Aftermarket) (Unl).gba" size 499440 crc ad634c54 sha1 324f0375e3f4f89455122e2663b831917013bfc3 ) +) + +game ( + name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.0) (Aftermarket) (Unl).gba" size 5416932 crc f79b0d53 sha1 756f02396a150698e695ad4afd24445e2af70576 ) +) + +game ( + name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.1) (Aftermarket) (Unl).gba" size 5418248 crc f5d36ad2 sha1 95a86dff641b11b4c2ed0d0fe8152c33b462d927 ) +) + +game ( + name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" + description "Celeste Classic (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Celeste Classic (World) (v1.2) (Aftermarket) (Unl).gba" size 5418424 crc ff0e8ada sha1 08512605e5c02e81a72e24c2c8d4959d8e84e1f4 ) +) + +game ( + name "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl)" + description "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl)" + rom ( name "Codename Hacker (World) (En,Fr) (Aftermarket) (Unl).gba" size 4058684 crc 1ccfbe29 sha1 fbc6a366f773204b031b589aab4125e15a70dc9b ) +) + +game ( + name "Collie Defense (World) (Demo) (Aftermarket) (Unl)" + description "Collie Defense (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Collie Defense (World) (Demo) (Aftermarket) (Unl).gba" size 3714268 crc 08feb1ed sha1 4dce7b29bca3f8588cccb548c698d5d2ba53e188 ) +) + +game ( + name "DCPR (World) (Demo) (Aftermarket) (Unl)" + description "DCPR (World) (Demo) (Aftermarket) (Unl)" + rom ( name "DCPR (World) (Demo) (Aftermarket) (Unl).gba" size 107512 crc 6c27348a sha1 43d11a2e42aa56fa8851bb00a5467211ac195feb ) +) + +game ( + name "Donsol (World) (Aftermarket) (Unl)" + description "Donsol (World) (Aftermarket) (Unl)" + rom ( name "Donsol (World) (Aftermarket) (Unl).gba" size 52520 crc aec144b3 sha1 751675b0d77c341f2265b0edd38858b0dbdb7b50 ) +) + +game ( + name "Drawing a Leviathan (World) (Aftermarket) (Unl)" + description "Drawing a Leviathan (World) (Aftermarket) (Unl)" + rom ( name "Drawing a Leviathan (World) (Aftermarket) (Unl).gba" size 9437768 crc 1eb0f64d sha1 745636d636b44a67ad078dae5416636fa58236ab ) +) + +game ( + name "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl)" + description "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl)" + rom ( name "Eliminator GBA (World) (v0.91) (Proto) (Aftermarket) (Unl).gba" size 747872 crc 637dc1aa sha1 13a4d5c2c647945cbbf17423afd45a25c4057527 ) +) + +game ( + name "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl)" + description "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl)" + rom ( name "Elite AGB (World) (v1.4.1) (Aftermarket) (Unl).gba" size 960088 crc 28985872 sha1 803095500e47772452433144f2cd7630d515a41b ) +) + +game ( + name "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl)" + description "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl)" + rom ( name "Elite AGB (World) (v0.5.2) (Beta) (Aftermarket) (Unl).gba" size 327360 crc f00c939f sha1 ce5a236608c629c99d4ec7b35e3ccaf211e6bb60 ) +) + +game ( + name "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Feline (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1504920 crc 09b777ea sha1 34b5aff6a7a3d752027ea1d2fd53e03bb8964529 ) +) + +game ( + name "Flappy Bird (World) (Aftermarket) (Unl)" + description "Flappy Bird (World) (Aftermarket) (Unl)" + rom ( name "Flappy Bird (World) (Aftermarket) (Unl).gba" size 575204 crc 4d099541 sha1 55f611567e7ac2ad8f96529f4d7eac70ad283601 ) +) + +game ( + name "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl)" + description "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl)" + rom ( name "GBA Tactics (World) (Proto) (NEO Coding Compo 2006) (Aftermarket) (Unl).gba" size 251816 crc 81b449a6 sha1 803834d8843a6689fe43c77921eaaea6bdaf6ed4 ) +) + +game ( + name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" + description "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl)" + rom ( name "Glacia Dungeon (World) (En,Es,Ru,Ro) (v1.5.2) (Aftermarket) (Unl).gba" size 1210608 crc ab5ae65b sha1 e35037ff9cc24f8a7043d9a9d378e86d2ef80f9b ) +) + +game ( + name "Goldrunner (World) (Aftermarket) (Unl)" + description "Goldrunner (World) (Aftermarket) (Unl)" + rom ( name "Goldrunner (World) (Aftermarket) (Unl).gba" size 527040 crc 53f4cac1 sha1 517a400150a6ebca126b0a95aa3497c637cc8161 ) +) + +game ( + name "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl)" + description "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy (World) (En,Ja,Fr,De,Es,Pt-BR,Zh,Ar) (Evercade) (Aftermarket) (Unl).gba" size 32524164 crc ebb81069 sha1 273bae3d794f2b5a6bea637f67f7d5163ae4bb62 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13224124 crc 19ba7d80 sha1 1bf95f8730ecdfa6665b85bea8764f42a88e8e3d ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13219728 crc d4621e3e sha1 5bd59fac58c5f9a375216e9d1cf85fa5262f21f7 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13225068 crc 21512022 sha1 8832d38f787f3e1da620fcae7514d7387445ccf2 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223944 crc c1811c9b sha1 9d413bce82708df137215a2968306a5196b1638b ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13269108 crc 3360e114 sha1 50186922ff77714b9ac638948b464cdbf80ab5fb ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13223696 crc 3477ef15 sha1 4b447de09a23fbfdaa6d640824f8ceb5bbe56fab ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.6) (Demo) (Aftermarket) (Unl).gba" size 13250016 crc a4054c2b sha1 c3cd833b9bdf87a8481c9b05251bba782bc3527e ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (En) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220676 crc ab179d6e sha1 2ad1c4840f2f6c2138ed44b1a7aa36071c227a0a ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Fr) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221620 crc 3aa591f1 sha1 2548615eeaecd7498e32d02b5c758b713ada27f4 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (De) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13221368 crc d02cdb6a sha1 1e579e15bdc8dc1def99bcb3c30acfc185e0476b ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Es) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220496 crc 906717a5 sha1 31857a9ab4daa537322f80faa77482a4b8120483 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Pt) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13220252 crc d12372bd sha1 89ea5ea41133419c317fd28e7c7f172f5bb53ec3 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ja) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13216280 crc d3c8dffd sha1 c41c0596a4c52b0e26bb9ffe5c9f7f1c064e0be6 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Zh) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13265660 crc 119f9ddc sha1 d6c23ff47b21a7bf2f8238ac916aeea3866042b5 ) +) + +game ( + name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + description "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl)" + rom ( name "Goodboy Galaxy - Chapter Zero (World) (Ar) (v1.0.7) (Demo) (Aftermarket) (Unl).gba" size 13246576 crc b14cd1b4 sha1 0d15bd0584148b1658f7d47a2dda604a936ea166 ) +) + +game ( + name "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl)" + description "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "Google Dino Advance (World) (v1.0.1) (Aftermarket) (Unl).gba" size 109072 crc 6534185e sha1 33cc0afc7fbac8948deb75c66b8e097c1d05b2e3 ) +) + +game ( + name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.2.0) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.2.0) (Aftermarket) (Unl).gba" size 6639328 crc 78b81bbc sha1 fb090890bd767a22afe07b3323dd0992d698c906 ) +) + +game ( + name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.4.2) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.4.2) (Aftermarket) (Unl).gba" size 6937384 crc 9fa9f00f sha1 005f4dc0d615d36d32bbe36e9cc9007b22be2ecd ) +) + +game ( + name "Green Memories (World) (v1.4.4) (Aftermarket) (Unl)" + description "Green Memories (World) (v1.4.4) (Aftermarket) (Unl)" + rom ( name "Green Memories (World) (v1.4.4) (Aftermarket) (Unl).gba" size 6937812 crc 702b46c6 sha1 61f8ff01247e45888b8fd5da791176ff2c88f7f5 ) +) + +game ( + name "Hero Core (World) (Aftermarket) (Unl)" + description "Hero Core (World) (Aftermarket) (Unl)" + rom ( name "Hero Core (World) (Aftermarket) (Unl).gba" size 23642396 crc a58bfa21 sha1 fa96ba52c2573add583cb051b387f6bbb3edf02e ) +) + +game ( + name "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Hero Core (World) (v0.1.2) (Beta) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 22209300 crc 0a3fcad6 sha1 3b7b91c474a225d96118c4a4263007218a8ee2de ) +) + +game ( + name "Hexa Virus (World) (Aftermarket) (Unl)" + description "Hexa Virus (World) (Aftermarket) (Unl)" + rom ( name "Hexa Virus (World) (Aftermarket) (Unl).gba" size 1414244 crc 92243509 sha1 358640dc9972dd839d0b527177e05d030ec12d79 ) +) + +game ( + name "Hexes (World) (Aftermarket) (Unl)" + description "Hexes (World) (Aftermarket) (Unl)" + rom ( name "Hexes (World) (Aftermarket) (Unl).gba" size 10436680 crc d8d17420 sha1 d5686671caa7ec17b811476c982f81147073f0ed ) +) + +game ( + name "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + description "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + rom ( name "Holy Hell (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl).gba" size 5956804 crc 09e21865 sha1 98db9220dffb07fc14a729931e7197a678d92d21 ) +) + +game ( + name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (v1.2) (Aftermarket) (Unl).gba" size 10592124 crc a9014760 sha1 2430c6c0784912ad2f0b51e633bf577f087f189f ) +) + +game ( + name "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Inheritors of the Oubliette (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 25516708 crc 965a1a75 sha1 ae23cfba1f53a9bbde025490f3d7bdf52c3970e4 ) +) + +game ( + name "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl)" + description "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl)" + rom ( name "Inky and the Alien Aquarium (World) (Demo 1) (Aftermarket) (Unl).gba" size 3145728 crc 7ee7ae7f sha1 73d870fad3caa86b6f659e13b57eddac80db2f37 ) +) + +game ( + name "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl)" + description "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl)" + rom ( name "Inky and the Alien Aquarium (World) (Demo 2) (Aftermarket) (Unl).gba" size 3145728 crc 36f8ba9c sha1 3c05e1b3f40d9c16b85b05315472267b94e76471 ) +) + +game ( + name "Iridion 3D (USA) (Aftermarket) (Unl)" + description "Iridion 3D (USA) (Aftermarket) (Unl)" + rom ( name "Iridion 3D (USA) (Aftermarket) (Unl).gba" size 4194304 crc 4c7ebe42 sha1 6f1c77ab88351d2d50da412e4788fc7ca8a6714d ) +) + +game ( + name "Iridion II (USA) (Aftermarket) (Unl)" + description "Iridion II (USA) (Aftermarket) (Unl)" + rom ( name "Iridion II (USA) (Aftermarket) (Unl).gba" size 8388608 crc b371f070 sha1 cc788b38a047ff5ec8c445ce11efcd1852ad7c4d ) +) + +game ( + name "Join 4 Together (World) (Proto) (Aftermarket) (Unl)" + description "Join 4 Together (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Join 4 Together (World) (Proto) (Aftermarket) (Unl).gba" size 1048576 crc 97d3c875 sha1 f9ffabd386d4d76d09e147f87f73de2638f875bb ) +) + +game ( + name "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + description "Luggage Retrieval Officer (World) (Aftermarket) (Unl)" + rom ( name "Luggage Retrieval Officer (World) (Aftermarket) (Unl).gba" size 3336260 crc 5aa30d90 sha1 84c9b2d50c8af74b8b04f88af367d9fac1a24ef6 ) +) + +game ( + name "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl)" + description "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl)" + rom ( name "Magic & Legend - Time Knights (World) (Beta) (Aftermarket) (Unl).gba" size 533996 crc 17af9e42 sha1 616342e07fa4c18a21e6b5de46b032c93bbbf34d ) +) + +game ( + name "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl)" + description "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl)" + rom ( name "Mandarin 2, The - Limoncello's Revenge (World) (Aftermarket) (Unl).gba" size 213684 crc cc2cb6a8 sha1 1937d06c2282152d6a9748c0e741c41c09583b77 ) +) + +game ( + name "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "MazezaM (World) (v1.1) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 569944 crc f7bc9db0 sha1 4517fbb7c44e9e93b0f5e89661e5cf979c624658 ) +) + +game ( + name "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "MazezaM (World) (v1.0) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 569704 crc 7c200ed5 sha1 46053717cf638c428ce92186e6a51a4a08e15ffd ) +) + +game ( + name "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl)" + description "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Metal Warrior 4 - Agents of Metal (World) (v1.3) (Aftermarket) (Unl).gba" size 524288 crc 7ec3485e sha1 729592141bc160ead0af51d4322c7f9f17da0b82 ) +) + +game ( + name "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl)" + description "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Metal Warrior 4 - Agents of Metal (World) (v1.1) (Aftermarket) (Unl).gba" size 524288 crc 5be69b8d sha1 5252dd4b67b56f591e9f8559d328433d5cf08f31 ) +) + +game ( + name "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.0) (Aftermarket) (Unl).gba" size 131072 crc e852c9e9 sha1 06faa5be11978666db6995d8fce40ce2c3641ce8 ) +) + +game ( + name "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.1) (Aftermarket) (Unl).gba" size 131072 crc 07595773 sha1 fee5cfa5b9e1f3383780432772f29764ac0fc443 ) +) + +game ( + name "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.2) (Aftermarket) (Unl).gba" size 131072 crc 37e7ee7d sha1 dc7faa4952986d5c5f0e3b32203936cd717f97eb ) +) + +game ( + name "Minicraft (World) (v1.3) (Aftermarket) (Unl)" + description "Minicraft (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Minicraft (World) (v1.3) (Aftermarket) (Unl).gba" size 131072 crc cc48e03a sha1 7fe080bf9cc110aa78ce7248ff92ff3185083247 ) +) + +game ( + name "Misfortune Advance (World) (Aftermarket) (Unl)" + description "Misfortune Advance (World) (Aftermarket) (Unl)" + rom ( name "Misfortune Advance (World) (Aftermarket) (Unl).gba" size 5125100 crc 18f2166d sha1 68e215025ac963220f16ea3c100e51698f97c4eb ) +) + +game ( + name "Mooncat's Trio (World) (Aftermarket) (Unl)" + description "Mooncat's Trio (World) (Aftermarket) (Unl)" + rom ( name "Mooncat's Trio (World) (Aftermarket) (Unl).gba" size 1175680 crc b05d5339 sha1 890de7d73723d235d9762e4866d569d3554d1480 flags verified ) +) + +game ( + name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" + description "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl)" + rom ( name "Mooncat's Trio (World) (Beta) (Aftermarket) (Unl).gba" size 504220 crc cd3328ee sha1 c3ea5247f32c428bbcfd5c087218fc56779e3106 ) +) + +game ( + name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" + description "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl)" + rom ( name "Nekketsu Monogatari Advance (Japan) (Demo) (Aftermarket) (Unl).gba" size 508972 crc 55a0734d sha1 79d6977803cd7ee6b1c97ee149cc1bc037c50fb2 ) +) + +game ( + name "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl)" + description "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Notebook Adventure (World) (v1.3) (Aftermarket) (Unl).gba" size 476392 crc cc110502 sha1 b730e401214fb348edcd2908cc9842e720f908d1 ) +) + +game ( + name "notenogram (World) (v1.1) (Aftermarket) (Unl)" + description "notenogram (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "notenogram (World) (v1.1) (Aftermarket) (Unl).gba" size 807876 crc 28108d5e sha1 426a19598624132356ff5d63a48eb874f19ead6b ) +) + +game ( + name "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl)" + description "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "notenogram (World) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 784216 crc 3b936e97 sha1 fb2fadad0d41979df75e49ff09b67fa42b54fc79 ) +) + +game ( + name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + description "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl)" + rom ( name "Ping-Pong Diplomacy Advance (World) (Aftermarket) (Unl).gba" size 1048576 crc 9ec140d3 sha1 9e19e8f97e8619a4755c3ceb482fa3e2ad5a4529 ) +) + +game ( + name "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Pipe Spin (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 3126100 crc 09d723e2 sha1 d4b4b99e644ca1d8202147a8c7ae0309a6f07e74 ) +) + +game ( + name "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + description "Pocket Meat (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Pocket Meat (World) (Proto) (Aftermarket) (Unl).gba" size 861952 crc 0b029da3 sha1 9958d9a66742cc00e234a96c311b2acec40f69d1 ) +) + +game ( + name "Powder (World) (v1.18) (Aftermarket) (Unl)" + description "Powder (World) (v1.18) (Aftermarket) (Unl)" + rom ( name "Powder (World) (v1.18) (Aftermarket) (Unl).gba" size 2278832 crc 44ea10fa sha1 3e0addefc22440c76b0eed06c91bc855f59838bf ) +) + +game ( + name "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Powerpig (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 2308528 crc 318f1504 sha1 af5e459df42d5317ce552bdb3062fcff53a9da8e ) +) + +game ( + name "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 4238368 crc 7edb6e6e sha1 62c9b12c3790a7c1a28edd2043ef61706357ed41 ) +) + +game ( + name "Rick Dangerous (World) (Aftermarket) (Unl)" + description "Rick Dangerous (World) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous (World) (Aftermarket) (Unl).gba" size 4237460 crc 53d4f7c5 sha1 ed5a9eb155388f19c28a7f5069d32532a5c9a494 ) +) + +game ( + name "Rick Dangerous 2 (World) (Aftermarket) (Unl)" + description "Rick Dangerous 2 (World) (Aftermarket) (Unl)" + rom ( name "Rick Dangerous 2 (World) (Aftermarket) (Unl).gba" size 4934608 crc 65a8d986 sha1 5dd0cff0f112c43ee44db642b4bfdb38ca6355b7 ) +) + +game ( + name "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl)" + description "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl)" + rom ( name "Rushed Hack Job, A (World) (GBA Jam 2022) (Aftermarket) (Unl).gba" size 332724 crc 730a5dd6 sha1 d8e03f4b1a12cf7a26813fb07aae2c4b503e2970 ) +) + +game ( + name "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl)" + description "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl)" + rom ( name "Shadow - A Parable (World) (Audio) (Aftermarket) (Unl).gba" size 1352899 crc 3178488f sha1 dd90e7d76b751a0e748aae83777d449d963b774b ) +) + +game ( + name "Shoot for the Moon (World) (Aftermarket) (Unl)" + description "Shoot for the Moon (World) (Aftermarket) (Unl)" + rom ( name "Shoot for the Moon (World) (Aftermarket) (Unl).gba" size 7374924 crc f3bd4f90 sha1 cf99dd8670a3af704b6994898fa521667aba09a6 ) +) + +game ( + name "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl)" + description "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl)" + rom ( name "Sips (World) (GBA WinterJam 2023) (Aftermarket) (Unl).gba" size 6235380 crc 5c1fb22d sha1 bb725df7226307d55df04365f85e5698b199c3c9 ) +) + +game ( + name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.5.0) (Proto) (Aftermarket) (Unl).gba" size 15887876 crc c798529d sha1 ea4a6494bcec25757f657c69550c91190e46cebd ) +) + +game ( + name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.15.0) (Proto) (Aftermarket) (Unl).gba" size 15894868 crc af572de8 sha1 997bf192369d48433a7c35187c7e1d0b5fcc16e0 ) +) + +game ( + name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.5.26.0) (Proto) (Aftermarket) (Unl).gba" size 15900084 crc df05edff sha1 1328d17668480b4e9bea338662532ace332c74a9 ) +) + +game ( + name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2023.8.1.1) (Proto) (Aftermarket) (Unl).gba" size 16075456 crc d271c516 sha1 0dbdf16b23afb70229eff2de269fd5d73659d745 ) +) + +game ( + name "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl)" + description "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Skyland (World) (v2024.5.24.0) (Proto) (Aftermarket) (Unl).gba" size 16250380 crc 4cfb40d2 sha1 d9936c4a776ce61ede6241a018683e3efc0fe12b ) +) + +game ( + name "Spout GBA (World) (Aftermarket) (Unl)" + description "Spout GBA (World) (Aftermarket) (Unl)" + rom ( name "Spout GBA (World) (Aftermarket) (Unl).gba" size 752448 crc ab42f086 sha1 87654f792d847bb8f642c0fc754eb70419a57859 ) +) + +game ( + name "Tiger Rescue (World) (Aftermarket) (Unl)" + description "Tiger Rescue (World) (Aftermarket) (Unl)" + rom ( name "Tiger Rescue (World) (Aftermarket) (Unl).gba" size 1575852 crc 34e118e5 sha1 8cc652cb0aee8649643386c8ffcc77fe6e5b0126 ) +) + +game ( + name "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Toadally Awesome (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 964504 crc fa6f976c sha1 098f9e2ba7ba15225768eae3585591b9b09ef2d6 ) +) + +game ( + name "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl)" + description "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl)" + rom ( name "Toadally Awesome (World) (GBA Jam 2021) (Unlocked) (Aftermarket) (Unl).gba" size 964520 crc 11044eb3 sha1 ac83f9815f4bf3a9c6690c4437d7f2256b36dd40 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Aftermarket) (Unl).gba" size 16239516 crc ce85ba07 sha1 b09b600bfc222c2d92829d8883feab700b013953 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16229600 crc bd57344d sha1 a2fcfe94c9b8b0feff31c1245c8b033222c9f668 ) +) + +game ( + name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Fr) (v1.1) (Solid State Version) (Aftermarket) (Unl).gba" size 16204024 crc fa43669e sha1 a57392fa7cee61913b20a840fe8b2ee27f11d808 ) +) + +game ( + name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + description "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (En) (v1.1) (Kickstarter Edition) (Aftermarket) (Unl).gba" size 16777216 crc ff5d64ab sha1 645ab8d4dacb6666d8eb549d491f77d8cd63ce97 ) +) + +game ( + name "Tremblay Island (World) (Aftermarket) (Unl)" + description "Tremblay Island (World) (Aftermarket) (Unl)" + rom ( name "Tremblay Island (World) (Aftermarket) (Unl).gba" size 16225608 crc 95503690 sha1 634ea6be3df5ebd85c9c60871e34fc3c72ae5140 ) +) + +game ( + name "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl)" + description "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl)" + rom ( name "Tristam Island (World) (v9) (Digital) (Aftermarket) (Unl).gba" size 286184 crc 4baa947c sha1 4a90a81991d38ce08ded5da017d0567ecd00c1df flags verified ) +) + +game ( + name "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl)" + description "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "uCity Advance (World) (v1.0.1) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1925124 crc a6e47443 sha1 c3e8f7fe01e05eda8bdb52a35db0d6dc92554e42 ) +) + +game ( + name "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl)" + description "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "Varooom 3D (World) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 7957428 crc 3f127891 sha1 cc7e45a680f9a8701fe35a64c764d5e106bd9096 ) +) + +game ( + name "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + description "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl)" + rom ( name "Waimanu - Grinding Blocks Adventure (World) (NEO Coding Compo 2013) (Aftermarket) (Unl).gba" size 1739504 crc 0fe153c5 sha1 c4ce156b04fb257875bc5f539f3d64accbc08451 ) +) + +game ( + name "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + description "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl)" + rom ( name "Werewolf Tale, A (World) (Proto) (NEO Coding Compo 2012) (Aftermarket) (Unl).gba" size 7359860 crc fa1a22d3 sha1 631fa1b513e1e4a45a5a60b10b7822b47832b866 ) +) + +game ( + name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.0) (Aftermarket) (Unl).gba" size 1449956 crc 4ffa611d sha1 89bbeb3fbce1533acf2f2113642ebe2a4f9f79a8 ) +) + +game ( + name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + description "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "With the Last Moonbeam (World) (v1.0.1) (Aftermarket) (Unl).gba" size 1449956 crc 27055186 sha1 b9ce91d55870e07434509f6e2e91c2f90b4afc97 ) +) + +game ( + name "World Reborn (USA) (Aftermarket) (Unl)" + description "World Reborn (USA) (Aftermarket) (Unl)" + rom ( name "World Reborn (USA) (Aftermarket) (Unl).gba" size 4194304 crc eefb32ff sha1 c7ec2f8d7d3dec40a893cdfe2a41a8ed43ed71c4 ) +) + +game ( + name "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl)" + description "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl)" + rom ( name "xniq (World) (Proto) (GBA Jam 2021) (Aftermarket) (Unl).gba" size 1436448 crc ddb5205d sha1 47dabc2d526aefc41cc82eeec315c986e3a9b8bc ) +) + +clrmamepro ( + name "Nintendo - Game Boy Advance (Video) (Aftermarket)" + description "Nintendo - Game Boy Advance (Video) (Aftermarket)" + version 20240727-194101 + author "BigFred, C. V. Reynolds, DeadSkullzJr, Hiccup, kazumi213, omonim2007, Psychofox11, psykopat, relax, SonGoku, xuom2" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "Dinosaur Office (World) (Aftermarket) (Unl)" + description "Dinosaur Office (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office (World) (Aftermarket) (Unl).gba" size 15237120 crc d8aae820 sha1 24feb8a0f36428461be8ecbb7add65f43dc1366e ) +) + +game ( + name "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Bring Your Child to Work Day (World) (Aftermarket) (Unl).gba" size 12222464 crc 3de24b84 sha1 63938be2d2e357b9644de8dc452f6f4195911618 ) +) + +game ( + name "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Computer Problems (World) (Aftermarket) (Unl).gba" size 15990784 crc 8a05677f sha1 664c1568e601bf6e51920bca85d096aa6e06f5e2 ) +) + +game ( + name "Dinosaur Office - Gym (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Gym (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Gym (World) (Aftermarket) (Unl).gba" size 12419072 crc 9dc8f035 sha1 062fcb78d9f9058ff9427f123fbb36db77fca20b ) +) + +game ( + name "Dinosaur Office - Office Party (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Office Party (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Office Party (World) (Aftermarket) (Unl).gba" size 12484608 crc 34c1df88 sha1 9ee6ca14c78a7e1949d8af9d52e6bfa4d09b7f9f ) +) + +game ( + name "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Office Romance (World) (Aftermarket) (Unl).gba" size 13828096 crc c202e426 sha1 4a66f3db5bde55a33f4b9ca55ba231f806c8d2b9 ) +) + +game ( + name "Dinosaur Office - Team Building (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Team Building (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Team Building (World) (Aftermarket) (Unl).gba" size 17334272 crc 9cd0566e sha1 9dc93f4c8d25a0e5d52deb8c7edf656b8f0c059d ) +) + +game ( + name "Dinosaur Office - Traffic (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Traffic (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Traffic (World) (Aftermarket) (Unl).gba" size 13107200 crc 96d90be9 sha1 879d9c7f0951235607cedb9c8fd85e4fc9a1d452 ) +) + +game ( + name "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl)" + description "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl)" + rom ( name "Dinosaur Office - Viral Videos (World) (Aftermarket) (Unl).gba" size 13139968 crc e7338b7c sha1 e6f089034f30757f8dce2eb6568e8f5d2d122d49 ) +) + +game ( + name "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl)" + description "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - A Sharkwork Orange (World) (Aftermarket) (Unl).gba" size 31129600 crc 4feab397 sha1 0bb061759804b46f201c39ccf9e7722a4407909e ) +) + +game ( + name "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Chariots of Fur (World) (Aftermarket) (Unl).gba" size 30998528 crc 5ea13d5a sha1 7022193f78fcb89988483cca1bacb8e66182ac55 ) +) + +game ( + name "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eek Space-9 (World) (Aftermarket) (Unl).gba" size 30801920 crc cfbb43d3 sha1 1b056d1449282c08eae0ed49ffc33f56346304fe ) +) + +game ( + name "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eek's Funny Thing That He Does (World) (Aftermarket) (Unl).gba" size 31064064 crc 3773b28d sha1 b13c1d3ae7f993deee10542390ac416b6c5cd1c6 ) +) + +game ( + name "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eekscaliber (World) (Aftermarket) (Unl).gba" size 31227904 crc ed5792d4 sha1 2a903b53a371ef4132291452f5d192dace6dc5e8 ) +) + +game ( + name "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eekstremely Dull (World) (Aftermarket) (Unl).gba" size 31162368 crc 28f73fe4 sha1 3ea9bfa0d937150574affdb8de271cf7873ab042 ) +) + +game ( + name "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Eeksy Rider (World) (Aftermarket) (Unl).gba" size 31096832 crc ec1f5d37 sha1 1359f5e802862b0a6f01e37fd5843a5b12edb7d4 ) +) + +game ( + name "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Fatal Eektraction (World) (Aftermarket) (Unl).gba" size 31096832 crc 494997c3 sha1 52e63ca7e162fe3a0296709b924b0dc4b19ce693 ) +) + +game ( + name "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Honey I Shrunk the Cat (World) (Aftermarket) (Unl).gba" size 15597568 crc 8bae90ef sha1 8ee80c6e4f54081c6b796983ab51d8c03e36c2d0 ) +) + +game ( + name "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Natural Bored Kittens (World) (Aftermarket) (Unl).gba" size 31129600 crc 941da25e sha1 8fa3d5d5f305ac32653527860caf153c97d20a24 ) +) + +game ( + name "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl)" + description "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - OutbrEek (World) (Aftermarket) (Unl).gba" size 30834688 crc 4fea7a72 sha1 344cdff52d4820932c3ba8ad5c57c91d61d93751 ) +) + +game ( + name "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Rock-Eek 6 (World) (Aftermarket) (Unl).gba" size 31096832 crc 7a05eb25 sha1 6b3789fd599bf7d30788be38872f5832cb5edfaa ) +) + +game ( + name "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Shark Doggy Dog (World) (Aftermarket) (Unl).gba" size 30965760 crc f8f2e313 sha1 f169a86d11602d84181fd0161bc7ec6747d5c750 ) +) + +game ( + name "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl)" + description "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - Shark Therapy (World) (Aftermarket) (Unl).gba" size 30998528 crc 81bc6107 sha1 9cca9b282e9441364e5acd7379c251674165eb13 ) +) + +game ( + name "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl)" + description "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl)" + rom ( name "Eek! The Cat - The Sound of MusEek (World) (Aftermarket) (Unl).gba" size 31129600 crc 923aafde sha1 1f1071ba3a6e056357c04f653cc48d2333a6bff1 ) +) + +game ( + name "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl)" + description "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl)" + rom ( name "GBA Groove - LoFi Lullabies (World) (Aftermarket) (Unl).gba" size 33128448 crc ff858ea8 sha1 e42166ed389ba80a38b91019b80b00fdca3252bd ) +) + +game ( + name "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 1 (World) (v2.0) (Aftermarket) (Unl).gba" size 33095680 crc a29a4d08 sha1 5c5ba15aef8cf86fbfee102dd3d667c09a024215 ) +) + +game ( + name "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 2 (World) (v2.0) (Aftermarket) (Unl).gba" size 33292288 crc d30b0a69 sha1 1d0f5640c62823100802a9d99991c81321fd6a7e ) +) + +game ( + name "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 3 (World) (v2.0) (Aftermarket) (Unl).gba" size 33226752 crc 5514a608 sha1 0b942ca93b86a61710e437995fbe9b051b49f33b ) +) + +game ( + name "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 4 (World) (v2.0) (Aftermarket) (Unl).gba" size 33226752 crc 996086fb sha1 cdae6017134b235c4b939c3718fef5c68c932046 ) +) + +game ( + name "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl)" + description "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - High Quality - Part 5 (World) (v2.1) (Aftermarket) (Unl).gba" size 33062912 crc 30394a33 sha1 677e3fbd22eac9661365f798e141844628869f09 ) +) + +game ( + name "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl)" + description "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - Low Quality - Part 1 (World) (Aftermarket) (Unl).gba" size 33456128 crc ec98d515 sha1 02d89347e83d030168916b1d5b5cb39f436564cf ) +) + +game ( + name "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl)" + description "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl)" + rom ( name "Legend of Lofi - Low Quality - Part 2 (World) (Aftermarket) (Unl).gba" size 33488896 crc 9a3ad572 sha1 90a4fefd48cc5024b88591a29a79c5a720593dcf ) +) + +game ( + name "Lizard of Aaaahs (World) (Aftermarket) (Unl)" + description "Lizard of Aaaahs (World) (Aftermarket) (Unl)" + rom ( name "Lizard of Aaaahs (World) (Aftermarket) (Unl).gba" size 30801920 crc 45d496d3 sha1 65b0a763932517d504abb0e39e9db316b2500c0a ) +) + +game ( + name "Lofi Radio (World) (Aftermarket) (Unl)" + description "Lofi Radio (World) (Aftermarket) (Unl)" + rom ( name "Lofi Radio (World) (Aftermarket) (Unl).gba" size 30965760 crc 4643636f sha1 7657efc85a8414a2d2065549e66bc0e0804a0153 ) +) + +game ( + name "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl)" + description "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl)" + rom ( name "Popeye The Sailor Meets Ali Baba's Forty Thieves (World) (Aftermarket) (Unl).gba" size 25067520 crc 3d2b7e9a sha1 7ed0b27ce1537610d62e3265ee1d8e7aa09ac649 ) +) + +game ( + name "Sleepy Time (World) (Aftermarket) (Unl)" + description "Sleepy Time (World) (Aftermarket) (Unl)" + rom ( name "Sleepy Time (World) (Aftermarket) (Unl).gba" size 33554432 crc b4a8e893 sha1 ba0a790b18de15009d711474aa25f29875e7f9fd ) +) + +game ( + name "Sonic Boom - Aim Low (World) (Aftermarket) (Unl)" + description "Sonic Boom - Aim Low (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Aim Low (World) (Aftermarket) (Unl).gba" size 32899072 crc a4b992a4 sha1 321716a5cc8035d2f3c834db70e21024b26e01ec ) +) + +game ( + name "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl)" + description "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Anything You Can Do, I Can Do Worse-er (World) (Aftermarket) (Unl).gba" size 32669696 crc 3e19389e sha1 bd9e8e22ddde7426d8eb77772480c822a099044f ) +) + +game ( + name "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl)" + description "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Blue with Envy (World) (Aftermarket) (Unl).gba" size 33488896 crc c847a712 sha1 44c4d7a6ba6b3bea7f452f22ec7c419cf6cf6965 ) +) + +game ( + name "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl)" + description "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Cabin Fever (World) (Aftermarket) (Unl).gba" size 32145408 crc 6a916ed9 sha1 e422c79d1b85942fcd9bae26105151c4e8a8352c ) +) + +game ( + name "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl)" + description "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Curse of the Cross Eyed Moose (World) (Aftermarket) (Unl).gba" size 32636928 crc 751a7c3c sha1 393a023540a261e14ab96ee341505fd6852e5040 ) +) + +game ( + name "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl)" + description "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Double Doomsday (World) (Aftermarket) (Unl).gba" size 33095680 crc e43df55f sha1 b0f7feb5f1b012ce4a486e6ad1331d83372a52e8 ) +) + +game ( + name "Sonic Boom - Eggheads (World) (Aftermarket) (Unl)" + description "Sonic Boom - Eggheads (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Eggheads (World) (Aftermarket) (Unl).gba" size 32964608 crc 7be59036 sha1 6afd6a0e39a792422767f40d96d28683fe3f010b ) +) + +game ( + name "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl)" + description "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Fortress of Squalitude (World) (Aftermarket) (Unl).gba" size 32964608 crc 2732961a sha1 db37f535660f66d947ccd2fdb05631d6c3b53157 ) +) + +game ( + name "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl)" + description "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Guilt Tripping (World) (Aftermarket) (Unl).gba" size 33095680 crc eb433ebc sha1 29648e120e9fd97f9c8b279b29246f165df3b9e6 ) +) + +game ( + name "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl)" + description "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - It Takes a Village to Defeat a Hedgehog (World) (Aftermarket) (Unl).gba" size 33062912 crc 087a17bf sha1 5cfd8eb8d832d21d64fc150bcc6d26b52da86911 ) +) + +game ( + name "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl)" + description "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Let's Play Musical Friends (World) (Aftermarket) (Unl).gba" size 33226752 crc 4f7e8a97 sha1 ad7d4f4833878ccc7055e65efbcb62fba20cd340 ) +) + +game ( + name "Sonic Boom - Nutwork (World) (Aftermarket) (Unl)" + description "Sonic Boom - Nutwork (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - Nutwork (World) (Aftermarket) (Unl).gba" size 32768000 crc ed3ead6a sha1 f89d6acee3095419d2eda71c1d79e73ba3dcf5e4 ) +) + +game ( + name "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Evil Dr. Orbot (World) (Aftermarket) (Unl).gba" size 33095680 crc e8c0b3b3 sha1 175126d3946e61295993982cb04758a5761233b1 ) +) + +game ( + name "Sonic Boom - The Meteor (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Meteor (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Meteor (World) (Aftermarket) (Unl).gba" size 32931840 crc d3c8e3bc sha1 84a91ed46f4e055ef075b4e110091dd1510c6bab ) +) + +game ( + name "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl)" + description "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl)" + rom ( name "Sonic Boom - The Sidekick (World) (Aftermarket) (Unl).gba" size 32964608 crc bca89ca3 sha1 93d24392e31fa7fa1b017eae2efbbb3d198739b7 ) +) + +game ( + name "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 1 - Fire Sale (World) (Aftermarket) (Unl).gba" size 31522816 crc 5af74124 sha1 c715e8adff312d3ade93185d6cebcb2d493cc41e ) +) + +game ( + name "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 10 - Rock TV (World) (Aftermarket) (Unl).gba" size 30179328 crc ccb80716 sha1 3f05bfc29688ab70cc728bbe609d5b976730490e ) +) + +game ( + name "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 11 - The Yoshi Shuffle (World) (Aftermarket) (Unl).gba" size 31129600 crc 733bb9b0 sha1 45875207d24653aa81c2bdd60bde639783c5c387 ) +) + +game ( + name "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 12 - A Little Learning (World) (Aftermarket) (Unl).gba" size 31227904 crc dd8717c1 sha1 26fcf34d2fd9f87f287d14fdeda9d8e234306db5 ) +) + +game ( + name "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 13 - Mama Luigi (World) (Aftermarket) (Unl).gba" size 32112640 crc 3d2bf1b0 sha1 4a897d3de60f1bd3991803196f5b96c5916f9e8c ) +) + +game ( + name "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 2 - The Wheel Thing (World) (Aftermarket) (Unl).gba" size 32145408 crc 9c5140d6 sha1 30b6b51d60ba9213e5c472bf52070eab98b43c74 ) +) + +game ( + name "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 3 - Send in the Clown (World) (Aftermarket) (Unl).gba" size 32112640 crc 88888a8c sha1 26c791180a1b35d8ab9cf7947d8db6c0367d7eb9 ) +) + +game ( + name "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 4 - Ghosts 'R' Us (World) (Aftermarket) (Unl).gba" size 32079872 crc ca0d9b45 sha1 a15fb94a371d783f78c069038c350e569ea9c370 ) +) + +game ( + name "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 5 - The Night Before Cave Christmas (World) (Aftermarket) (Unl).gba" size 31981568 crc 564582fa sha1 ce8b3589a67dcd930d2e437efa0bf754f438cfa7 ) +) + +game ( + name "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 6 - King Scoopa Koopa (World) (Aftermarket) (Unl).gba" size 32112640 crc edcb04de sha1 1e8e89daf7faed9660f2dc3b6aa113df6de527c0 ) +) + +game ( + name "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 7 - Born to Ride (World) (Aftermarket) (Unl).gba" size 32145408 crc 0044466e sha1 105f0d0a500ea542f87b10b7c671b6c93e312f4a ) +) + +game ( + name "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 8 - Party Line (World) (Aftermarket) (Unl).gba" size 28672000 crc ed103f04 sha1 df5e947880b634482081ee82f79f37d5ff7d009c ) +) + +game ( + name "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl)" + description "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl)" + rom ( name "Super Mario World - Episode 9 - Gopher Bash (World) (Aftermarket) (Unl).gba" size 31031296 crc 3a8f46ad sha1 160895e7953a3323647c0c9d2d00eeff17b57db5 ) +) + clrmamepro ( name "Nintendo - Game Boy" description "Nintendo - Game Boy" - version 20240106-192522 - author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" + version 20240809-004429 + author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, psykopat, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -21630,12 +22690,6 @@ game ( rom ( name "10-Pin Bowling (USA) (Proto).gb" size 131072 crc 9a024415 sha1 952d154dd2c6189ef4b786ae37bd7887c8ca9037 ) ) -game ( - name "14 Juillet (World) (Fr) (Aftermarket) (Unl)" - description "14 Juillet (World) (Fr) (Aftermarket) (Unl)" - rom ( name "14 Juillet (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 7b66bee4 sha1 02f387457a779cbd2f493e52743cd32c169c098e ) -) - 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)" @@ -21739,9 +22793,9 @@ game ( ) game ( - name "Action Replay Pro (World)" - description "Action Replay Pro (World)" - rom ( name "Action Replay Pro (World).gb" size 16384 crc 2ea05daa sha1 e947b9264092168950ad1ce23bbe3d8ccfed765e ) + name "Action Replay Pro (World) (Unl)" + description "Action Replay Pro (World) (Unl)" + rom ( name "Action Replay Pro (World) (Unl).gb" size 16384 crc 2ea05daa sha1 e947b9264092168950ad1ce23bbe3d8ccfed765e ) ) game ( @@ -21768,12 +22822,6 @@ game ( rom ( name "Addams Family, The - Pugsley's Scavenger Hunt (USA, Europe).gb" size 131072 crc 7e054a88 sha1 f9020e3d104cb5c5347e28f45ed9e24e6c0ebddd flags verified ) ) -game ( - name "Adulting! (World) (v2.0) (Aftermarket) (Unl)" - description "Adulting! (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a flags verified ) -) - game ( name "Adventure Island (USA, Europe)" description "Adventure Island (USA, Europe)" @@ -21948,12 +22996,6 @@ game ( rom ( name "Alleyway (World).gb" size 32768 crc 5cc01586 sha1 0cf2b8d0428f389f5361f67a0cd1ace05a1c75cc flags verified ) ) -game ( - name "Alphamax (World) (Aftermarket) (Unl)" - description "Alphamax (World) (Aftermarket) (Unl)" - rom ( name "Alphamax (World) (Aftermarket) (Unl).gb" size 131072 crc 8b493b41 sha1 798dda34d04a06dcee32f44f8a4a045caf734927 ) -) - game ( name "Altered Space - A 3-D Alien Adventure (Europe)" description "Altered Space - A 3-D Alien Adventure (Europe)" @@ -21978,6 +23020,12 @@ game ( rom ( name "Amazing Penguin (USA, Europe).gb" size 65536 crc 3011d5ca sha1 84cc6452823eb05ee38679aec86e3cc6e4a50e6f ) ) +game ( + name "Amazing Penguin (World) (Limited Run Games)" + description "Amazing Penguin (World) (Limited Run Games)" + rom ( name "Amazing Penguin (World) (Limited Run Games).gb" size 65536 crc 82d4664c sha1 01f11e0746a511b35b2c873d6a190f6e10204676 ) +) + game ( name "Amazing Spider-Man, The (USA, Europe)" description "Amazing Spider-Man, The (USA, Europe)" @@ -22116,30 +23164,6 @@ game ( rom ( name "Aretha III (Japan).gb" size 262144 crc 430d3d6b sha1 f57ff26d31283c88cc4c414b18ef6f182d07da9d ) ) -game ( - name "Art School Pocket (World) (En) (Aftermarket) (Unl)" - description "Art School Pocket (World) (En) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (En) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) -) - -game ( - name "Art School Pocket (World) (Es) (Aftermarket) (Unl)" - description "Art School Pocket (World) (Es) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (Es) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) -) - -game ( - name "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" - description "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) -) - -game ( - name "Art School Pocket (World) (De) (Aftermarket) (Unl)" - description "Art School Pocket (World) (De) (Aftermarket) (Unl)" - rom ( name "Art School Pocket (World) (De) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) -) - game ( name "Asmik-kun World 2 (Japan)" description "Asmik-kun World 2 (Japan)" @@ -22200,30 +23224,12 @@ game ( rom ( name "Asteroids (USA, Europe) (Beta).gb" size 32768 crc eb31e472 sha1 28f4e2a076bfe5f7a77f695332705ea0085fccfb ) ) -game ( - name "Asteroids Chasers (World) (Aftermarket) (Unl)" - description "Asteroids Chasers (World) (Aftermarket) (Unl)" - rom ( name "Asteroids Chasers (World) (Aftermarket) (Unl).gb" size 131072 crc 58d8b1b8 sha1 f93a4e6788eaf0231a6ca269cca297f0d45ec830 flags verified ) -) - game ( name "Astro Rabby (Japan)" description "Astro Rabby (Japan)" rom ( name "Astro Rabby (Japan).gb" size 65536 crc 61e48eef sha1 3e53fd25f350c78a29e0642ee6de80208930d469 ) ) -game ( - name "Astro-Jump (World) (Aftermarket) (Unl)" - description "Astro-Jump (World) (Aftermarket) (Unl)" - rom ( name "Astro-Jump (World) (Aftermarket) (Unl).gb" size 262144 crc c35a3b39 sha1 1bcb4be684626ce061aad105701548fa3a77e254 ) -) - -game ( - name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc afc128f2 sha1 956be9371990b18e351f2e10848b2ea8bb70c2b7 ) -) - game ( name "Atomic Punk (USA)" description "Atomic Punk (USA)" @@ -22242,12 +23248,6 @@ game ( rom ( name "Attack of the Killer Tomatoes (USA, Europe).gb" size 131072 crc b5b38860 sha1 cbbba5d4f80f2b4ab3e882ceb4f79c293a17904f flags verified ) ) -game ( - name "Auto Zone (World) (Aftermarket) (Unl)" - description "Auto Zone (World) (Aftermarket) (Unl)" - rom ( name "Auto Zone (World) (Aftermarket) (Unl).gb" size 524288 crc cee73c14 sha1 3070ec215014633dac5dbbb487aade2e2993c049 ) -) - game ( name "Avenging Spirit (USA, Europe)" description "Avenging Spirit (USA, Europe)" @@ -22621,9 +23621,9 @@ game ( ) game ( - name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" - description "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" - rom ( name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 32768 crc bf922249 sha1 187782720d4f7c0986a0d916b0c7efa2c488612e ) + name "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl)" + description "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl)" + rom ( name "Binary Monsters II - Adventure of Hell (Taiwan) (En) (Unl).gb" size 131072 crc 3bf1e911 sha1 5a7ea252cc344f239e48eee0eba6a9ba97d799ea ) ) game ( @@ -22650,12 +23650,6 @@ game ( rom ( name "Bionic Commando (USA).gb" size 262144 crc 41dbb5fb sha1 e0ef47568a017ccdd3dbe0db5d7654822b4e5ce1 ) ) -game ( - name "Birdie Bartender (World) (Aftermarket) (Unl)" - description "Birdie Bartender (World) (Aftermarket) (Unl)" - rom ( name "Birdie Bartender (World) (Aftermarket) (Unl).gb" size 262144 crc 0bf2a1c8 sha1 aa1325fc7160b84745b076de9b976a1b368da50e ) -) - game ( name "Bishoujo Senshi Sailor Moon (Japan)" description "Bishoujo Senshi Sailor Moon (Japan)" @@ -22674,12 +23668,6 @@ game ( rom ( name "Black Bass - Lure Fishing (USA).gb" size 262144 crc 2db3dace sha1 d9524ac9f7788172a55cc8ceb6e199f8a12e033d ) ) -game ( - name "Black Castle (World) (Aftermarket) (Unl)" - description "Black Castle (World) (Aftermarket) (Unl)" - rom ( name "Black Castle (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) -) - game ( name "Blade Warrior (Europe) (Proto)" description "Blade Warrior (Europe) (Proto)" @@ -22716,24 +23704,12 @@ game ( rom ( name "Blaster Master Jr. (Europe).gb" size 131072 crc e9f9016f sha1 6a6deae1942e7cf048ce35d18e9540363c226727 ) ) -game ( - name "Blitz Bomber (World) (Aftermarket) (Unl)" - description "Blitz Bomber (World) (Aftermarket) (Unl)" - rom ( name "Blitz Bomber (World) (Aftermarket) (Unl).gb" size 262144 crc 5e9956de sha1 b72cbc6bfa6ceef940f49c9c82024071c6f82b90 ) -) - 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 sha1 7540fe9af69d8c7d48f50c2d5fe6d3ce07421f74 ) ) -game ( - name "Blockade (World) (Aftermarket) (Unl)" - description "Blockade (World) (Aftermarket) (Unl)" - rom ( name "Blockade (World) (Aftermarket) (Unl).gb" size 262144 crc b8cfab16 sha1 9e753048a0eb036ac17c08f5a64d860abd1aaaf5 ) -) - game ( name "Blodia (Japan)" description "Blodia (Japan)" @@ -22890,18 +23866,6 @@ game ( rom ( name "Boomer's Adventure in ASMIK World (USA).gb" size 65536 crc 105bc1c0 sha1 3d8a6fcc644290c9d88fe2918bfa6007ee811de8 flags verified ) ) -game ( - name "Bork Paw Kisses (World) (Aftermarket) (Unl)" - description "Bork Paw Kisses (World) (Aftermarket) (Unl)" - rom ( name "Bork Paw Kisses (World) (Aftermarket) (Unl).gb" size 262144 crc c29f0d35 sha1 8f1efe6982d2b4ebc1fbeb3ade68dd9b9aabb7a6 ) -) - -game ( - name "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" - description "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" - rom ( name "Borruga - Neo Pinball (World) (Aftermarket) (Unl).gb" size 32768 crc 2bb55ca5 sha1 269f12091d5ab87362a2cb2cf5484f14bfcbd537 flags verified ) -) - game ( name "Bouken! Puzzle Road (Japan)" description "Bouken! Puzzle Road (Japan)" @@ -22920,24 +23884,6 @@ game ( rom ( name "Boulder Dash (Japan).gb" size 65536 crc b5b3f85b sha1 f5a4a5ccda4f559ce85567c4b68f758216aee2d4 ) ) -game ( - name "Bounce (World) (v1.1) (Aftermarket) (Unl)" - description "Bounce (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Bounce (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 827f2bd5 sha1 e9abf64de3faeb48151003ac8bb77dea61e838b5 ) -) - -game ( - name "Bouncing Ball, The (World) (Aftermarket)" - description "Bouncing Ball, The (World) (Aftermarket)" - rom ( name "Bouncing Ball, The (World) (Aftermarket).gb" size 65536 crc 42ddf53e sha1 5d331f2e66d7d3f4b4b0fcbaf6ab4b1a0147db3e ) -) - -game ( - name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" - description "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" - rom ( name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl).gb" size 262144 crc 98222a4a sha1 0bdb8ad04469a329c8cee2fb0c55da35f7752042 ) -) - game ( name "Boxing (Japan)" description "Boxing (Japan)" @@ -22981,9 +23927,9 @@ game ( ) 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 sha1 225c25d94854f509611b8c0b4b415daf48d51310 ) + name "Brain Drain (Japan) (En) (SGB Enhanced)" + description "Brain Drain (Japan) (En) (SGB Enhanced)" + rom ( name "Brain Drain (Japan) (En) (SGB Enhanced).gb" size 131072 crc e558aacd sha1 225c25d94854f509611b8c0b4b415daf48d51310 ) ) game ( @@ -23058,12 +24004,6 @@ game ( rom ( name "Bubsy II (USA).gb" size 262144 crc 600a6ad5 sha1 1ac9bf5043caf428994bca3e80158ca697e94c58 ) ) -game ( - name "Bug Bites! (World) (Aftermarket) (Unl)" - description "Bug Bites! (World) (Aftermarket) (Unl)" - rom ( name "Bug Bites! (World) (Aftermarket) (Unl).gb" size 262144 crc bb473d7a sha1 8d601612ac262e4548d8b8f6ac19a04cb92ecfb7 ) -) - game ( name "Bugs Bunny Collection (Japan) (SGB Enhanced)" description "Bugs Bunny Collection (Japan) (SGB Enhanced)" @@ -23148,12 +24088,6 @@ game ( rom ( name "Buster Bros. (USA).gb" size 131072 crc b4245ca3 sha1 0d1692ff60ef1f6a97bbfd2bf8c1548f1f7439ed ) ) -game ( - name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" - description "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" - rom ( name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl).gb" size 1048576 crc d0ed199c sha1 a1cbaacdf32cb8fb9a9c59fcb624c729e0ca17bf ) -) - game ( name "Cadillac II (Japan)" description "Cadillac II (Japan)" @@ -23175,7 +24109,7 @@ game ( game ( name "Caesars Palace (USA)" description "Caesars Palace (USA)" - rom ( name "Caesars Palace (USA).gb" size 131072 crc d9f901a9 sha1 c1ed80f33fc3603edaba1bdf5c317f1a205da3dc ) + rom ( name "Caesars Palace (USA).gb" size 131072 crc d9f901a9 sha1 c1ed80f33fc3603edaba1bdf5c317f1a205da3dc flags verified ) ) game ( @@ -23286,12 +24220,6 @@ game ( rom ( name "Castle Quest (Europe) (Beta).gb" size 131072 crc 8a5636ea sha1 356c8510b0647e56a558aba9d5dc4cc9d3ccd94c ) ) -game ( - name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 3c492b31 sha1 0861af0039dab4b4f5bce747c6fcd586eced401a ) -) - game ( name "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" description "Castlevania - The Adventure (USA) (Castlevania Anniversary Collection)" @@ -23328,12 +24256,6 @@ game ( 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 sha1 171e4d54f22f8dc137d12828fcc2da9874c56970 ) -) - game ( name "Catrap (USA) (Beta)" description "Catrap (USA) (Beta)" @@ -23341,9 +24263,9 @@ game ( ) game ( - name "Cave Fighter (World) (Aftermarket) (Unl)" - description "Cave Fighter (World) (Aftermarket) (Unl)" - rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gb" size 262144 crc e8f91f6a sha1 290048717d0a8cabb3cc591161339550eb53c161 ) + name "Catrap (USA)" + description "Catrap (USA)" + rom ( name "Catrap (USA).gb" size 32768 crc adb96150 sha1 171e4d54f22f8dc137d12828fcc2da9874c56970 ) ) game ( @@ -23394,18 +24316,6 @@ game ( rom ( name "Chase H.Q. (USA, Europe).gb" size 131072 crc 67a45d19 sha1 cbcd6254b1b0227ba6aa8d95c979abb7fe8e4d38 flags verified ) ) -game ( - name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" - description "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 3e20c1a8 sha1 f76645a2830fcc733b7392a52112df628f0b7a4a ) -) - -game ( - name "Cherry Rescue! (World) (Aftermarket) (Unl)" - description "Cherry Rescue! (World) (Aftermarket) (Unl)" - rom ( name "Cherry Rescue! (World) (Aftermarket) (Unl).gb" size 524288 crc ba65812a sha1 740dba1827c730cc5d8bf67495bcede3a5352643 ) -) - game ( name "Chessmaster, The (Europe)" description "Chessmaster, The (Europe)" @@ -23526,42 +24436,12 @@ game ( rom ( name "Chousoku Spinner (Japan) (SGB Enhanced).gb" size 524288 crc b4fa9cf2 sha1 057a3251bbb7eb4e04b01f786bd2986af5eabc58 ) ) -game ( - name "Christmas Carols (World) (Aftermarket) (Unl)" - description "Christmas Carols (World) (Aftermarket) (Unl)" - rom ( name "Christmas Carols (World) (Aftermarket) (Unl).gb" size 262144 crc a00bb310 sha1 e19b0a698d8194467d57c00664f00f9898ee5368 ) -) - game ( name "Chuck Rock (USA, Europe)" description "Chuck Rock (USA, Europe)" rom ( name "Chuck Rock (USA, Europe).gb" size 131072 crc c5951d9e sha1 601453f98ba7d92ebe71f3e86952a584cbea090c ) ) -game ( - name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 2165f2e4 sha1 f8e5020298183c3f47836da3890b6bb398e2ecab ) -) - -game ( - name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 6afee818 sha1 602709c8655febb42899881a8ef598fb4b3da0c9 ) -) - -game ( - name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl).gb" size 1048576 crc 225ce296 sha1 45aebfe4e7f5382a4b31c3db270b75d2c458d1b2 ) -) - -game ( - name "Ciao Nonna (World) (Aftermarket) (Unl)" - description "Ciao Nonna (World) (Aftermarket) (Unl)" - rom ( name "Ciao Nonna (World) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) -) - game ( name "Cliffhanger (USA, Europe)" description "Cliffhanger (USA, Europe)" @@ -23580,12 +24460,6 @@ game ( rom ( name "College Slam (USA).gb" size 524288 crc a549a572 sha1 84dc6269fbe4ee4c157f940b0a9630412e099cc6 ) ) -game ( - name "Commando (World) (Aftermarket) (Unl)" - description "Commando (World) (Aftermarket) (Unl)" - rom ( name "Commando (World) (Aftermarket) (Unl).gb" size 262144 crc 48173941 sha1 c861858e9f2cf7470e739c26ae9f17d3834ce464 ) -) - game ( name "Contra (World) (Contra Anniversary Collection)" description "Contra (World) (Contra Anniversary Collection)" @@ -23646,12 +24520,6 @@ game ( rom ( name "Cool World (USA, Europe).gb" size 131072 crc a193c0d0 sha1 1919495cc83c4126c90d6cfa2e14427b6364da3a flags verified ) ) -game ( - name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" - description "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" - rom ( name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl).gb" size 262144 crc fd304687 sha1 7df11ec2946099d49dd62928118b6d76703dc57c ) -) - game ( name "Cosmo Tank (Japan) (Beta)" description "Cosmo Tank (Japan) (Beta)" @@ -23676,18 +24544,6 @@ game ( rom ( name "Cosmo Tank (USA).gb" size 131072 crc 2e767d25 sha1 48a8f5c50a237f11c8e18efd03a5282f493312bc ) ) -game ( - name "Coucou (World) (Aftermarket) (Unl)" - description "Coucou (World) (Aftermarket) (Unl)" - rom ( name "Coucou (World) (Aftermarket) (Unl).gb" size 32768 crc e6aabd72 sha1 5283268e3640e2924d00aea3b12b2d3930bef43c ) -) - -game ( - name "Counting Sheep (World) (Aftermarket) (Unl)" - description "Counting Sheep (World) (Aftermarket) (Unl)" - rom ( name "Counting Sheep (World) (Aftermarket) (Unl).GB" size 65536 crc 6e97c837 sha1 e7e251ad86fa00803837cf871de62d3f100c83ce ) -) - game ( name "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" description "Crayon Shin-chan - Ora no Gokigen Collection (Japan) (SGB Enhanced)" @@ -23736,12 +24592,6 @@ game ( rom ( name "Cult Master - Ultraman ni Miserarete (Japan).gb" size 262144 crc c3eb82ef sha1 f0e63a0a4e7b576c7460e810eb6f50d4c5b68769 ) ) -game ( - name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gb" size 262144 crc 10838580 sha1 c740bc995adf2bb638bb125a36edc416558fd4c6 ) -) - game ( name "CutThroat Island (Japan) (En) (Proto)" description "CutThroat Island (Japan) (En) (Proto)" @@ -23754,12 +24604,6 @@ game ( rom ( name "CutThroat Island (USA, Europe).gb" size 262144 crc eebdd360 sha1 5e99ea51b383cdcd53874eb027ebd59d2a3156b9 flags verified ) ) -game ( - name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" - description "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" - rom ( name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl).gb" size 1048576 crc e3a78253 sha1 45c9c6a7a4ec985146a4a616a49dba45decc6d3e ) -) - game ( name "Cyraid (USA)" description "Cyraid (USA)" @@ -23814,18 +24658,6 @@ game ( rom ( name "Daisenryaku (Japan).gb" size 131072 crc c8f80d90 sha1 79e724619d21ebb3cd5de5438535a7ee25009de0 ) ) -game ( - name "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" - description "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Dangan GB (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) -) - -game ( - name "Dangan GB (World) (Aftermarket) (Unl)" - description "Dangan GB (World) (Aftermarket) (Unl)" - rom ( name "Dangan GB (World) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) -) - game ( name "Darkman (USA, Europe)" description "Darkman (USA, Europe)" @@ -23863,9 +24695,9 @@ game ( ) game ( - name "Dash (World) (Aftermarket) (Unl)" - description "Dash (World) (Aftermarket) (Unl)" - rom ( name "Dash (World) (Aftermarket) (Unl).gb" size 262144 crc 73868683 sha1 c1ffe7c25a34d65ed166293bc7d2b48b65ca922b ) + name "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games)" + description "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games)" + rom ( name "David Crane's The Rescue of Princess Blobette (World) (Limited Run Games).gb" size 65536 crc 0c24923e sha1 e1f391102aba5ea75572b04180b31bcaaa47e593 ) ) game ( @@ -23898,36 +24730,12 @@ game ( rom ( name "Dead Heat Scramble (USA).gb" size 65536 crc 9e3e3656 sha1 71e560dd2b5f5c4f4dcca0837c74bb1b843a15aa ) ) -game ( - name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl).gb" size 1048576 crc 7da95971 sha1 23cff594ef4b0bb21883b422940526c7fe81f1fd flags verified ) -) - -game ( - name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl).gb" size 1048576 crc 9e2bf649 sha1 3feeba5c438880f70cdfdc4ea7e29f77e645e9be flags verified ) -) - -game ( - name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" - description "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" - rom ( name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl).gb" size 1048576 crc 818a7db7 sha1 43a93dc6f7bef002271e583edaeaf2e7162b8af4 ) -) - game ( name "Death Track (Europe) (Proto)" description "Death Track (Europe) (Proto)" rom ( name "Death Track (Europe) (Proto).gb" size 524288 crc c495a707 sha1 abc95b27be454405a6a22fb9e048537d1df60d75 ) ) -game ( - name "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" - description "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Deep Forest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 3ddf177d sha1 517302d20cb5140975e6cd1b3c495786b6390aaf ) -) - game ( name "Dennis (Europe) (Beta) (1993-09-13)" description "Dennis (Europe) (Beta) (1993-09-13)" @@ -23970,12 +24778,6 @@ game ( rom ( name "Diablo (USA) (Proto).gb" size 131072 crc aaaad0b6 sha1 8982410ac627618628a8b823c0608cc8b5653f41 ) ) -game ( - name "DiaMaze (World) (Aftermarket) (Unl)" - description "DiaMaze (World) (Aftermarket) (Unl)" - rom ( name "DiaMaze (World) (Aftermarket) (Unl).gb" size 262144 crc 956fa901 sha1 f41b98ac4669920ffede1736ddbd9e1f62d4cb0d ) -) - game ( name "Dick Tracy (USA)" description "Dick Tracy (USA)" @@ -23994,12 +24796,6 @@ game ( rom ( name "Dig Dug (USA).gb" size 131072 crc 6c742478 sha1 951753904389332412d4b0a80b48d7ac61a494fc ) ) -game ( - name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" - description "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" - rom ( name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc b230b782 sha1 f1796dcbfb6f0f5e01c60222c376cc1c46945806 ) -) - game ( name "Dino Breeder (Japan) (SGB Enhanced)" description "Dino Breeder (Japan) (SGB Enhanced)" @@ -24018,12 +24814,6 @@ game ( rom ( name "Dino Breeder 2 (Japan) (SGB Enhanced).gb" size 524288 crc 05a3ab7a sha1 ac4b1fe0e917298d81725d7a9bdf46c285502ac7 flags verified ) ) -game ( - name "Dino's Offline Adventure (World) (Aftermarket) (Unl)" - description "Dino's Offline Adventure (World) (Aftermarket) (Unl)" - rom ( name "Dino's Offline Adventure (World) (Aftermarket) (Unl).gb" size 32768 crc d6bd0e6a sha1 6d11c145606f8e7ab25b2b07c299e36c8b442d23 ) -) - game ( name "Dirty Racing (Europe) (Proto)" description "Dirty Racing (Europe) (Proto)" @@ -24036,42 +24826,6 @@ game ( rom ( name "Dirty Racing (Japan).gb" size 131072 crc 43af45b1 sha1 5b58b4d02987ce3a16774bc4a6707d12ac404c1c ) ) -game ( - name "DMG Deals Damage (World) (Aftermarket) (Unl)" - description "DMG Deals Damage (World) (Aftermarket) (Unl)" - rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 flags verified ) -) - -game ( - name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) -) - -game ( - name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) -) - -game ( - name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) -) - -game ( - name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" - description "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl).gb" size 1048576 crc e393d4aa sha1 d45dfcab4a76b62ea1e10730d01f755e12137484 ) -) - -game ( - name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" - description "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" - rom ( name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) -) - game ( name "Doctor GB Card 16M Loader (World) (Unl)" description "Doctor GB Card 16M Loader (World) (Unl)" @@ -24102,18 +24856,6 @@ game ( rom ( name "Dodge Boy (Japan).gb" size 131072 crc f58dc358 sha1 b48eb2bdc34588847728936491dadda67394f9b7 ) ) -game ( - name "Dog's Muck Island (World) (Aftermarket) (Unl)" - description "Dog's Muck Island (World) (Aftermarket) (Unl)" - rom ( name "Dog's Muck Island (World) (Aftermarket) (Unl).gb" size 262144 crc 79a7a06c sha1 eb4cea3b9db770bf3b586578af1ad7427d88ee8e ) -) - -game ( - name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" - description "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 83247308 sha1 4579eaa45e2bf8f17f4dc99bdfb0b98270b871f5 ) -) - game ( name "Donkey Kong (Japan, USA) (En) (SGB Enhanced)" description "Donkey Kong (Japan, USA) (En) (SGB Enhanced)" @@ -24384,12 +25126,6 @@ game ( rom ( name "Dragon Ball Z 3 (USA) (SGB Enhanced) (Unl).gb" size 1048576 crc 71b8ea17 sha1 c43eb3906f77dda5fee94a0fce0b6d783461238c ) ) -game ( - name "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" - description "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Dragon Battle (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc c1e1e52c sha1 c5ac56e266c421a1c5b82de46859a44f75d03359 ) -) - game ( name "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" description "Dragon Slayer Gaiden - Nemuri no Oukan (Japan)" @@ -24426,18 +25162,6 @@ game ( rom ( name "Dragon's Lair - The Legend (USA).gb" size 131072 crc 7a38b5c3 sha1 4e947908fde7ef9892c59021c6eea0607771f6d2 ) ) -game ( - name "Dragonborne (World) (Aftermarket) (Unl)" - description "Dragonborne (World) (Aftermarket) (Unl)" - rom ( name "Dragonborne (World) (Aftermarket) (Unl).gb" size 2097152 crc 0ae28712 sha1 e3cd09069ee59ed3f7915a79af0667de4ebd7d50 ) -) - -game ( - name "Dragonborne (World) (Demo) (Aftermarket) (Unl)" - description "Dragonborne (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Dragonborne (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc eda66890 sha1 3a5bcd9daa830842da60d8ebf35fa7036a259d76 ) -) - game ( name "DragonHeart (France)" description "DragonHeart (France)" @@ -24564,12 +25288,6 @@ game ( rom ( name "Eddie's Puzzle Time (USA) (Proto).gb" size 65536 crc f2600f02 sha1 cd2695295831737d0f8a7eb825bbfe870b9c0bfd ) ) -game ( - name "Elden Ring GB (World) (Aftermarket) (Unl)" - description "Elden Ring GB (World) (Aftermarket) (Unl)" - rom ( name "Elden Ring GB (World) (Aftermarket) (Unl).gb" size 524288 crc e7a420f3 sha1 2e0bec6acf1a94ae3f2f6cf2040323862933d95a ) -) - game ( name "Elevator Action (Japan)" description "Elevator Action (Japan)" @@ -24630,12 +25348,6 @@ game ( rom ( name "F-15 Strike Eagle II (USA, Europe) (Beta) (July, 1992).gb" size 131072 crc d80bdbba sha1 298c07ef596ab3a3c4a320b2f2d7e2c0dbaf764d ) ) -game ( - name "F-Zero - Project (World) (Aftermarket) (Unl)" - description "F-Zero - Project (World) (Aftermarket) (Unl)" - rom ( name "F-Zero - Project (World) (Aftermarket) (Unl).gb" size 1048576 crc 4c707059 sha1 5b823ee17691d286a45f0667cddd59ccaaab5d8b ) -) - game ( name "F1 Boy (Japan)" description "F1 Boy (Japan)" @@ -24660,12 +25372,6 @@ game ( rom ( name "Faceball 2000 (USA).gb" size 131072 crc 7d890cd0 sha1 b0bd15bace04e0a3eb89773f231ac3a532181a0a flags verified ) ) -game ( - name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" - description "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" - rom ( name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 4f04cdfc sha1 591980cb5e17104d826c2a915f53bfc8a21affca ) -) - game ( name "Family Jockey (Japan)" description "Family Jockey (Japan)" @@ -24696,12 +25402,6 @@ game ( rom ( name "Famista 3 (Japan).gb" size 262144 crc bdc4ccc3 sha1 ac4b03e11e2ba135d0427c8b1da7de57c006b4a6 ) ) -game ( - name "Farm, The (World) (Aftermarket) (Unl)" - description "Farm, The (World) (Aftermarket) (Unl)" - rom ( name "Farm, The (World) (Aftermarket) (Unl).gb" size 524288 crc fbc1b5e8 sha1 d0fe06920f7e771d76507f60881904370ffbc145 ) -) - game ( name "Fastest Lap (USA)" description "Fastest Lap (USA)" @@ -24834,24 +25534,12 @@ game ( rom ( name "Final Fantasy Legend, The (USA).gb" size 131072 crc 8046148f sha1 901dfc83c72e172d35a376835807fc788444a9bb flags verified ) ) -game ( - name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" - description "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" - rom ( name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc 6cfb4669 sha1 339fd673509a5ac8f25426af25b4ccc96e8d2880 ) -) - game ( name "Final Reverse (Japan)" description "Final Reverse (Japan)" rom ( name "Final Reverse (Japan).gb" size 65536 crc e94a6942 sha1 e4b08e702f3b6c575b31dbd62615619126e03af5 ) ) -game ( - name "Finders Keepers (World) (Aftermarket) (Unl)" - description "Finders Keepers (World) (Aftermarket) (Unl)" - rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gb" size 524288 crc 6a98ac61 sha1 e40dd804388df8c08d3890d79eeafd8542cc8805 ) -) - game ( name "Fire Fighter (Europe)" description "Fire Fighter (Europe)" @@ -24924,12 +25612,6 @@ game ( rom ( name "Flipull - An Exciting Cube Game (Japan).gb" size 32768 crc 198f147d sha1 090c88ae19892c35608f4fa844a6e9efcbe23893 ) ) -game ( - name "Fly O'Clock (World) (Aftermarket) (Unl)" - description "Fly O'Clock (World) (Aftermarket) (Unl)" - rom ( name "Fly O'Clock (World) (Aftermarket) (Unl).gb" size 32768 crc 93df7f55 sha1 83dc8498bdbabc14a8f81a715c9da19970c1f0b9 ) -) - game ( name "Football International (Europe)" description "Football International (Europe)" @@ -25014,30 +25696,12 @@ game ( 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 "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" - description "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" - rom ( name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl).gb" size 32768 crc 36e2ca02 sha1 fd985703b296dd0bf74225c72155ea9e51dd6853 ) -) - 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 ) ) -game ( - name "G-Man (World) (Aftermarket) (Unl)" - description "G-Man (World) (Aftermarket) (Unl)" - rom ( name "G-Man (World) (Aftermarket) (Unl).gb" size 524288 crc 7296da69 sha1 fdc9933d46a063575c175453b1da8042fd28b135 ) -) - -game ( - name "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" - description "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" - rom ( name "G-ZERO (World) (v2.6) (Aftermarket) (Unl).gb" size 65536 crc 7dd0c878 sha1 929d25a612308614ac3ac2ee5a19a9cd4a9968d6 ) -) - game ( name "Galaga & Galaxian (Japan) (SGB Enhanced)" description "Galaga & Galaxian (Japan) (SGB Enhanced)" @@ -25059,7 +25723,7 @@ game ( game ( 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 ) + rom ( name "Game & Watch Gallery (USA) (Rev 1) (SGB Enhanced).gb" size 262144 crc 9e6cdc96 sha1 4e4da0ed89c2baaed64600f7eaca90aeeadc084e flags verified ) ) game ( @@ -25182,12 +25846,6 @@ game ( rom ( name "Game of Harmony, The (USA).gb" size 32768 crc b0074acb sha1 b0bc752e3ad25fcb83d8ca04a82a0f5e35381db2 ) ) -game ( - name "GameBoy WORDLE (World) (Aftermarket) (Unl)" - description "GameBoy WORDLE (World) (Aftermarket) (Unl)" - rom ( name "GameBoy WORDLE (World) (Aftermarket) (Unl).gb" size 32768 crc cc971c0f sha1 ba93939b93ab3f3aa5f7aa451d50d9b89220adbc ) -) - game ( name "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" description "Gamera - Daikaijuu Kuuchuu Kessen (Japan) (SGB Enhanced)" @@ -25326,18 +25984,6 @@ game ( rom ( name "Gem Gem (Japan).gb" size 65536 crc a64a8710 sha1 90a29d7a56f64b596cda1c64c8998b63d12c321e ) ) -game ( - name "Genesis (World) (Aftermarket) (Unl)" - description "Genesis (World) (Aftermarket) (Unl)" - rom ( name "Genesis (World) (Aftermarket) (Unl).gb" size 65536 crc 74b3ec78 sha1 ca43f82d73ba0b3e43ec17f6bc6761c09ca23626 ) -) - -game ( - name "Genesis II (World) (Demo) (Aftermarket) (Unl)" - description "Genesis II (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Genesis II (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc d7aec1cc sha1 9700ea1278850df004ded7553253cfdd354f4ada ) -) - game ( name "Genjin Collection (Japan) (SGB Enhanced)" description "Genjin Collection (Japan) (SGB Enhanced)" @@ -25374,12 +26020,6 @@ game ( rom ( name "Getaway, The - High Speed II (USA).gb" size 262144 crc 8f2bf517 sha1 a0ca7187b55135150f348d44544d3a6e6d51394e ) ) -game ( - name "Ghost Town (World) (Aftermarket) (Unl)" - description "Ghost Town (World) (Aftermarket) (Unl)" - rom ( name "Ghost Town (World) (Aftermarket) (Unl).gb" size 262144 crc 2d27cdf2 sha1 af526273cdaa6423b92d0484fb27af56fe355a5d ) -) - game ( name "Ghostbusters II (USA, Europe) (Beta)" description "Ghostbusters II (USA, Europe) (Beta)" @@ -25410,18 +26050,6 @@ game ( rom ( name "Ginga - Card & Puzzle Collection (Japan) (En,Ja).gb" size 65536 crc 87d0637b sha1 14f4f14caee081dceadb9d31ae26fd8968c432ea ) ) -game ( - name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" - description "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" - rom ( name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4b19366d sha1 77f3b561bf28a81f38dbedc351752e10ff4c23dc ) -) - -game ( - name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" - description "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" - rom ( name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 3f34ff66 sha1 a0bff49b6917186d27dc24773da0674a18a6212c ) -) - game ( name "Gluecksrad (Germany)" description "Gluecksrad (Germany)" @@ -25788,24 +26416,6 @@ game ( rom ( name "Gremlins 2 - The New Batch (World).gb" size 131072 crc 3579e297 sha1 0cb722d9d4e349bea1b1afa85d8d3b93f2dc2aad flags verified ) ) -game ( - name "Gun Law (World) (Aftermarket) (Unl)" - description "Gun Law (World) (Aftermarket) (Unl)" - rom ( name "Gun Law (World) (Aftermarket) (Unl).gb" size 262144 crc b0d53211 sha1 ef6e3d287e99bd61861a333165c92b306238a45f ) -) - -game ( - name "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" - description "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Gunman Clive (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) -) - -game ( - name "Gunship (World) (Aftermarket) (Unl)" - description "Gunship (World) (Aftermarket) (Unl)" - rom ( name "Gunship (World) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) -) - game ( name "HAL Wrestling (USA)" description "HAL Wrestling (USA)" @@ -25830,12 +26440,6 @@ game ( rom ( name "Hammerin' Harry - Ghost Building Company (USA) (Proto).gb" size 262144 crc 6c4d0377 sha1 c5f73b09f001fc4d7eaa40ffee00234ca6a41a41 ) ) -game ( - name "Harbour Attack (World) (Aftermarket) (Unl)" - description "Harbour Attack (World) (Aftermarket) (Unl)" - rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 4018ebf7 sha1 5bbbe727ebc6a489f1a498d067e4f05d0d69b60f ) -) - game ( name "Harvest Moon GB (USA) (SGB Enhanced)" description "Harvest Moon GB (USA) (SGB Enhanced)" @@ -25860,12 +26464,6 @@ game ( rom ( name "Head On (Japan).gb" size 65536 crc 78830daf sha1 76261091adb7def20a4f76aa6c062c60c6d9761c ) ) -game ( - name "Heart Knight (World) (Aftermarket) (Unl)" - description "Heart Knight (World) (Aftermarket) (Unl)" - rom ( name "Heart Knight (World) (Aftermarket) (Unl).gb" size 32768 crc c7ecac73 sha1 dedcab41f58c58834e3534e877c494669a0d8952 ) -) - game ( name "Heavyweight Championship Boxing (USA)" description "Heavyweight Championship Boxing (USA)" @@ -25908,12 +26506,6 @@ game ( rom ( name "Hercules (USA, Europe) (SGB Enhanced).gb" size 524288 crc 00a9001e sha1 215cceaccd4a33a2da6205f33a2803ff4004e2b1 flags verified ) ) -game ( - name "Hermano (World) (v1.1) (Aftermarket) (Unl)" - description "Hermano (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Hermano (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 74a0419b sha1 c42cfe91a1ec593a76291e031c47137bd794ffda ) -) - game ( name "Hero Shuugou!! Pinball Party (Japan)" description "Hero Shuugou!! Pinball Party (Japan)" @@ -26082,12 +26674,6 @@ game ( rom ( name "Hudson Hawk (Europe) (Proto).gb" size 131072 crc d4cd525d sha1 07c6a49f7c340d3cc78ca688eb1591853255a6c6 ) ) -game ( - name "Hugo (World) (Aftermarket) (Unl)" - description "Hugo (World) (Aftermarket) (Unl)" - rom ( name "Hugo (World) (Aftermarket) (Unl).gb" size 262144 crc 8cc87f60 sha1 53fac2774b29a32501788e1eac65db23bf5c7b8f ) -) - game ( name "Hugo (Europe) (SGB Enhanced)" description "Hugo (Europe) (SGB Enhanced)" @@ -26160,12 +26746,6 @@ game ( rom ( name "Hyper Lode Runner (Japan) (En) (Possible Proto).gb" size 32768 crc 3fc21b74 sha1 37d0f2cbac0f95af8b22dea0c882612681ec5cc8 ) ) -game ( - name "If (World) (Aftermarket) (Unl)" - description "If (World) (Aftermarket) (Unl)" - rom ( name "If (World) (Aftermarket) (Unl).gb" size 1048576 crc be7e4454 sha1 c11d8dc9ce96133f679678b07822a82f985e16f9 ) -) - game ( name "Ikari no Yousai (Japan)" description "Ikari no Yousai (Japan)" @@ -26178,12 +26758,6 @@ game ( rom ( name "Ikari no Yousai 2 (Japan).gb" size 131072 crc 6d4fd9aa sha1 ae437d4fb39d7438fc9eb98c91820aa2b5161b4f ) ) -game ( - name "Impossible Gameboy (World) (Aftermarket) (Unl)" - description "Impossible Gameboy (World) (Aftermarket) (Unl)" - rom ( name "Impossible Gameboy (World) (Aftermarket) (Unl).gb" size 131072 crc ab65b738 sha1 d31cedd6227b23cf3d8ef81c73f133ab0b57e4f4 ) -) - game ( name "In Your Face (USA)" description "In Your Face (USA)" @@ -26268,24 +26842,12 @@ game ( rom ( name "Initial D Gaiden (Japan) (SGB Enhanced).gb" size 262144 crc 6cc56612 sha1 1b3c4c1c4dfca46a009eb2e5cd45b343d7ee6681 ) ) -game ( - name "Interblocked (World) (Aftermarket) (Unl)" - description "Interblocked (World) (Aftermarket) (Unl)" - rom ( name "Interblocked (World) (Aftermarket) (Unl).gb" size 262144 crc 5c208855 sha1 8e46486533a3de9ee87cc07bf8efaf818752a61a ) -) - 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 sha1 13f2fc0945fb7a90f4d87d8c4e310dec9af6b792 ) ) -game ( - name "Into the Blue (World) (Aftermarket) (Unl)" - description "Into the Blue (World) (Aftermarket) (Unl)" - rom ( name "Into the Blue (World) (Aftermarket) (Unl).gb" size 131072 crc 7714e96e sha1 5ac7a349bb37c8767c9db264ed8ae7b7647fa8ea ) -) - game ( name "Ippatsu Gyakuten! DX Bakenou (Japan)" description "Ippatsu Gyakuten! DX Bakenou (Japan)" @@ -26346,12 +26908,6 @@ game ( rom ( name "J.League Winning Goal (Japan).gb" size 131072 crc adb46f9c sha1 b8630f06e8b9682e667b7b1f2139162e2f022561 ) ) -game ( - name "Jabberwocky (World) (Aftermarket) (Unl)" - description "Jabberwocky (World) (Aftermarket) (Unl)" - rom ( name "Jabberwocky (World) (Aftermarket) (Unl).gb" size 1048576 crc cfc51717 sha1 b4e447f2197688c740a45dce27879a62c742fb96 ) -) - game ( name "Jack Nicklaus Golf (France)" description "Jack Nicklaus Golf (France)" @@ -26376,12 +26932,6 @@ game ( rom ( name "James Bond 007 (USA, Europe) (SGB Enhanced).gb" size 524288 crc ca3bc3ce sha1 e03754173a5d62cb9da7d2306bc41b0e23e3d519 flags verified ) ) -game ( - name "Jane in the Jungle (World) (Aftermarket) (Unl)" - description "Jane in the Jungle (World) (Aftermarket) (Unl)" - rom ( name "Jane in the Jungle (World) (Aftermarket) (Unl).gb" size 262144 crc c68e751a sha1 dfc65dcf700a26b273d705b7cfececbc44b80587 ) -) - game ( name "Jankenman (Japan)" description "Jankenman (Japan)" @@ -26466,12 +27016,6 @@ game ( rom ( name "Jet Pak Man (Europe) (Proto).gb" size 32768 crc e40dfc1b sha1 0080f76961164810d6c0543d951a465cfa1cab54 ) ) -game ( - name "Jet Set Willy (World) (Aftermarket) (Unl)" - description "Jet Set Willy (World) (Aftermarket) (Unl)" - rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gb" size 262144 crc 1686d7ed sha1 0e594224506fd087e36c66bb66905d4c91b02461 ) -) - game ( name "Jetsons, The - Robot Panic (USA, Europe)" description "Jetsons, The - Robot Panic (USA, Europe)" @@ -26550,12 +27094,6 @@ game ( rom ( name "Joe & Mac - Caveman Ninja (Europe) (En,Fr,De,Es,It,Nl,Sv) (Beta).gb" size 262144 crc 381c62ee sha1 979e36765291153b82025b1f036c08fe9c23cfa5 ) ) -game ( - name "Joe Blade 2 (World) (Aftermarket) (Unl)" - description "Joe Blade 2 (World) (Aftermarket) (Unl)" - rom ( name "Joe Blade 2 (World) (Aftermarket) (Unl).gb" size 524288 crc 09f75c70 sha1 f001dffcd16be670c36a98dd9136f6f9fbf5b85d ) -) - game ( name "John Madden Football (USA) (Proto 2) (SGB Enhanced)" description "John Madden Football (USA) (Proto 2) (SGB Enhanced)" @@ -26772,12 +27310,6 @@ game ( rom ( name "Kenyuu Densetsu Yaiba (Japan).gb" size 262144 crc cc19768e sha1 c2b71ceee21f66f462df18233f7622d8ec95fcca ) ) -game ( - name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" - description "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" - rom ( name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl).gb" size 1048576 crc 986bfd75 sha1 6d15b5bc33d7c7771ba62d56ae7f25fa081bc564 ) -) - game ( name "Kick Attack (Japan) (Proto)" description "Kick Attack (Japan) (Proto)" @@ -27078,12 +27610,6 @@ game ( rom ( name "Krusty's Fun House (USA, Europe).gb" size 131072 crc 1cedb141 sha1 e61039c52c053a8ae1bdfffa3f694934569bb570 flags verified ) ) -game ( - name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" - description "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" - rom ( name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 0610049a sha1 a6fbe1a524547bebabc5e6b3baff1dff8f13dbd0 ) -) - 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)" @@ -27138,36 +27664,12 @@ game ( rom ( name "Lasama Chuanqi - Story of Lasama (Taiwan) (Unl) (Alt).gb" size 65536 crc 997fa9eb sha1 ded742d50ed553ffea524d7deec628c354c74cc4 ) ) -game ( - name "Laser Squad Alter (World) (Aftermarket) (Unl)" - description "Laser Squad Alter (World) (Aftermarket) (Unl)" - rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gb" size 1048576 crc a39b3a5a sha1 1620e585e77a2457cffde82453bec0c7a04e07cf ) -) - 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 sha1 010eb2cbab987ec242cd0792c789a07c00106f48 ) ) -game ( - name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 2c430576 sha1 0e290b387a45b6ea85c6d49bf18bce3ce94951b7 ) -) - -game ( - name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 5cf1a6f9 sha1 9fac1324e863f719674219eb41e45f1f745c67a9 ) -) - -game ( - name "Lawn Mower Land (World) (Aftermarket) (Unl)" - description "Lawn Mower Land (World) (Aftermarket) (Unl)" - rom ( name "Lawn Mower Land (World) (Aftermarket) (Unl).gb" size 32768 crc 11c62e39 sha1 1d6aa817ebf2a7e5d22285b906540272b67169da ) -) - game ( name "Lawnmower Man, The (USA) (Proto 1) (1993-10-11) (Not For Resale)" description "Lawnmower Man, The (USA) (Proto 1) (1993-10-11) (Not For Resale)" @@ -27192,12 +27694,6 @@ game ( rom ( name "Lazlos' Leap (USA).gb" size 65536 crc 31fb404b sha1 c111470fcdadf191cf843e50c8f3d3dbb995a5c5 ) ) -game ( - name "Leak, The (World) (Aftermarket) (Unl)" - description "Leak, The (World) (Aftermarket) (Unl)" - rom ( name "Leak, The (World) (Aftermarket) (Unl).GB" size 65536 crc ba3cfeae sha1 98de2d8be75e6d9cb4e87afe14b1380c033de797 ) -) - game ( name "Learn and Play - Blackjack & Solitaire (USA) (1994-08-09) (Proto)" description "Learn and Play - Blackjack & Solitaire (USA) (1994-08-09) (Proto)" @@ -27228,6 +27724,12 @@ game ( rom ( name "Legend of the River King GB (Australia) (SGB Enhanced).gb" size 524288 crc 51627213 sha1 87274e8c0d2daaac2e0dda94651c35d6a0617c0f ) ) +game ( + name "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced)" + description "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced)" + rom ( name "Legend of the Sea King GB (USA) (Proto) (SGB Enhanced).gb" size 1048576 crc a45ef889 sha1 26bebc2394b5da850be55e409b9efcb4d2d29d87 ) +) + game ( name "Legend of Zelda, The - Link's Awakening (Canada) (Fr)" description "Legend of Zelda, The - Link's Awakening (Canada) (Fr)" @@ -27277,9 +27779,9 @@ game ( ) game ( - name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" - description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-17).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) + name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" + description "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (Germany) (Proto) (1998-11-16).gb" size 524288 crc f7c59f5c sha1 d1a10a3f129bf060f16d1fb5f991ef6e2f28b97c ) ) game ( @@ -27318,12 +27820,6 @@ game ( 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 sha1 8b4621471b376a6262fbed70c1191416ab3be915 ) -) - game ( name "Lethal Weapon (USA, Europe) (Beta)" description "Lethal Weapon (USA, Europe) (Beta)" @@ -27331,15 +27827,9 @@ game ( ) game ( - name "Life's Too Short (World) (Aftermarket) (Unl)" - description "Life's Too Short (World) (Aftermarket) (Unl)" - rom ( name "Life's Too Short (World) (Aftermarket) (Unl).gb" size 262144 crc 458174cc sha1 7b704cd999cbeeb9991d675e2b1e67a906fa766d ) -) - -game ( - name "Linea, La (World) (Aftermarket) (Unl)" - description "Linea, La (World) (Aftermarket) (Unl)" - rom ( name "Linea, La (World) (Aftermarket) (Unl).gb" size 262144 crc c8750c01 sha1 00348fec54b5d3ebb762484bdcc015881bb9e95b ) + name "Lethal Weapon (USA, Europe)" + description "Lethal Weapon (USA, Europe)" + rom ( name "Lethal Weapon (USA, Europe).gb" size 131072 crc 1f8d207c sha1 8b4621471b376a6262fbed70c1191416ab3be915 ) ) game ( @@ -27403,57 +27893,9 @@ game ( ) game ( - name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc 9c4f03fd sha1 288cb53b4782df4409ee683e9aa11b4dd2a3a53e ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc e5988949 sha1 08d033c7ef20fd4d24d1f07b3ebb177fb9b78673 ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc 59568248 sha1 6571db155f6f25eeeec86d28b105bf8fef156322 ) -) - -game ( - name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc a26345b8 sha1 641110cb187657fd15ea254440e1c74ab4a88856 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc d70f1d25 sha1 02e2fb6cbc5cff05ed775c9e1cd9acc07fa2e036 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc ae07c093 sha1 9f40b8719b3fdd2f7e6c59a4f616e9eb712d538d ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc 34671dc6 sha1 377d22d54e6e1fa4fcd4b4576d5886774f9f6c97 ) -) - -game ( - name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc a8fb0d7a sha1 26803ba3413c7c52a8a58393f63472bc87ec3c6b ) -) - -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 sha1 643cbd566d35ce8dbe0f24627e4862c09805a04c flags verified ) + name "Lock n' Chase (World)" + description "Lock n' Chase (World)" + rom ( name "Lock n' Chase (World).gb" size 65536 crc dab91c7a sha1 643cbd566d35ce8dbe0f24627e4862c09805a04c flags verified ) ) game ( @@ -27528,12 +27970,6 @@ game ( rom ( name "Lucle (Japan, Europe) (En).gb" size 524288 crc a3d5c8d7 sha1 2fef16fac95ec4ffd252e9974eccfce538e5f797 ) ) -game ( - name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" - description "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" - rom ( name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl).gb" size 524288 crc 1a5106a2 sha1 f56c1b324b8c1e17da86e40c5e9a887ec19b0c80 ) -) - game ( name "Lunar Chase (USA) (Proto 1)" description "Lunar Chase (USA) (Proto 1)" @@ -27558,18 +27994,6 @@ game ( rom ( name "Mach Go Go Go (Japan) (SGB Enhanced).gb" size 262144 crc 016d230b sha1 baea8b49ce2402c5c094ddae0320a382c0d95d86 ) ) -game ( - name "Machine, The (World) (Aftermarket) (Unl)" - description "Machine, The (World) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (Aftermarket) (Unl).gb" size 2097152 crc b06036a9 sha1 50c5d1eb7c8946ac2d7e2c566b1ea4a9b0d58e90 ) -) - -game ( - name "Mad Monster (World) (Aftermarket) (Unl)" - description "Mad Monster (World) (Aftermarket) (Unl)" - rom ( name "Mad Monster (World) (Aftermarket) (Unl).gb" size 524288 crc c3fd371c sha1 9f4bea7ca7d26080110f54392314c60761236638 ) -) - game ( name "Madden 95 (USA, Europe) (SGB Enhanced)" description "Madden 95 (USA, Europe) (SGB Enhanced)" @@ -27618,18 +28042,6 @@ game ( rom ( name "Magical Taruruuto-kun 2 - Raibaa Zone Panic!! (Japan).gb" size 131072 crc 0aad5217 sha1 3be6c6b8cec80a0fe0f6edbbe40496f4d077c750 ) ) -game ( - name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" - description "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" - rom ( name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 76fcbc30 sha1 7a759372bd013dcdb59c9131a2908085fc04d648 ) -) - -game ( - name "Magipanels (World) (Aftermarket) (Unl)" - description "Magipanels (World) (Aftermarket) (Unl)" - rom ( name "Magipanels (World) (Aftermarket) (Unl).gb" size 131072 crc 0b66561b sha1 c9513f6769098f2185f632f87386788f0f0b6ad8 ) -) - game ( name "Magnetic Soccer (Europe)" description "Magnetic Soccer (Europe)" @@ -27666,12 +28078,6 @@ game ( rom ( name "Makaimura Gaiden - The Demon Darkness (Japan).gb" size 262144 crc cfa358de sha1 961d05e91288d7ad1f2e6a1c996059d7ab96fe98 ) ) -game ( - name "Make Way (World) (Aftermarket) (Unl)" - description "Make Way (World) (Aftermarket) (Unl)" - rom ( name "Make Way (World) (Aftermarket) (Unl).gb" size 1048576 crc edeee5a8 sha1 19fd02e9318ed81ec968a2fca31ea0c3d8d94a7b ) -) - game ( name "Malibu Beach Volleyball (USA)" description "Malibu Beach Volleyball (USA)" @@ -27738,30 +28144,12 @@ game ( rom ( name "Marmalade Boy (Japan) (SGB Enhanced).gb" size 262144 crc 0f3ff7da sha1 60125690b7a354ff8e72f497c8a88ecd691e7e4b ) ) -game ( - name "Marron Helps a Friend (World) (Aftermarket) (Unl)" - description "Marron Helps a Friend (World) (Aftermarket) (Unl)" - rom ( name "Marron Helps a Friend (World) (Aftermarket) (Unl).gb" size 1048576 crc 08a3a987 sha1 adcd56fa3eba93edd20be25ae5cb349070cd0323 flags verified ) -) - game ( name "Maru's Mission (USA)" description "Maru's Mission (USA)" rom ( name "Maru's Mission (USA).gb" size 131072 crc 6e4f1eb3 sha1 91446b1cc6dbf3b98b81f13e35ffe7bfaaa027aa flags verified ) ) -game ( - name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" - description "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" - rom ( name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl).gb" size 262144 crc dccaeb60 sha1 1e4fc83bfe9c9063975a3862770e4afee3f947a4 ) -) - -game ( - name "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" - description "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" - rom ( name "Marzipan Beef Reverser (World) (Aftermarket) (Unl).gb" size 131072 crc 4c3e0d15 sha1 6cbfb0390ee555718b5b0c3a5437b7d3d4ee0008 ) -) - game ( name "Masakari Densetsu - Kintarou Action Hen (Japan)" description "Masakari Densetsu - Kintarou Action Hen (Japan)" @@ -27979,9 +28367,9 @@ game ( ) game ( - name "Meteorite (World) (Aftermarket) (Unl)" - description "Meteorite (World) (Aftermarket) (Unl)" - rom ( name "Meteorite (World) (Aftermarket) (Unl).gb" size 262144 crc 50cf593d sha1 0e88a47faf3273f87c1ead7f789faeb06d5333f3 ) + name "Metal Masters (World) (Limited Run Games)" + description "Metal Masters (World) (Limited Run Games)" + rom ( name "Metal Masters (World) (Limited Run Games).gb" size 131072 crc 7de862fa sha1 9d4896a198904365ebc348c557b7c15f87b5e3c5 ) ) game ( @@ -28350,12 +28738,6 @@ game ( rom ( name "Missile Command (USA, Europe).gb" size 32768 crc 3a6cd4d8 sha1 ed529062ae3d1feb4defbf54c2cc759211e3aeaa flags verified ) ) -game ( - name "Mission Mars (World) (Aftermarket) (Unl)" - description "Mission Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) -) - game ( name "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" description "Mofa Qiu - Magic Ball (Taiwan) (Multicart Rip) (Unl)" @@ -28434,12 +28816,6 @@ game ( rom ( name "Momotarou Dentetsu jr. - Zenkoku Ramen Meguri no Maki (Japan) (SGB Enhanced).gb" size 524288 crc 218265b3 sha1 30edf17fc9ddd9db7613c8f78b0ebc340cc89eb0 ) ) -game ( - name "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" - description "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" - rom ( name "Mona and the Witch's Hat (World) (Aftermarket) (Unl).gb" size 65536 crc 32ed7f4a sha1 625d3664d99dee075021b03ea6ff074ae2e49204 ) -) - game ( name "Monde Perdu, Le - Jurassic Park (France) (En) (SGB Enhanced)" description "Monde Perdu, Le - Jurassic Park (France) (En) (SGB Enhanced)" @@ -28530,12 +28906,6 @@ game ( rom ( name "Montezuma's Return! (Europe) (En,Fr,De,Es,It).gb" size 262144 crc e7ac155b sha1 a6b90cc58aeb5b44ef674c503a55a58278b1b6fa flags verified ) ) -game ( - name "Monty on the Run (World) (Aftermarket) (Unl)" - description "Monty on the Run (World) (Aftermarket) (Unl)" - rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gb" size 524288 crc e2ebb406 sha1 41ac5993fbff58be0712b554aae5e4367b68677b ) -) - game ( name "Mortal Kombat (USA, Europe) (Beta)" description "Mortal Kombat (USA, Europe) (Beta)" @@ -28680,24 +29050,12 @@ game ( rom ( name "Mulan (USA) (SGB Enhanced).gb" size 524288 crc bfcf71a1 sha1 7832fcc373ff752e757550079519b39583665c82 ) ) -game ( - name "Muncher (World) (Aftermarket) (Unl)" - description "Muncher (World) (Aftermarket) (Unl)" - rom ( name "Muncher (World) (Aftermarket) (Unl).gb" size 262144 crc 444d3d5e sha1 c3e09aff66c7e395bf95a1864963fbe979d5cb9b ) -) - game ( name "MVP Baseball (Japan)" description "MVP Baseball (Japan)" rom ( name "MVP Baseball (Japan).gb" size 262144 crc 38c126aa sha1 f0d921d13689d2afe7838eee127bf670439c8d8d ) ) -game ( - name "Mysterium (USA) (Beta)" - description "Mysterium (USA) (Beta)" - rom ( name "Mysterium (USA) (Beta).gb" size 131072 crc 004c1af7 sha1 82e058a7608a04a2837d0d8fe810270f804b43f3 ) -) - game ( name "Mysterium (Japan)" description "Mysterium (Japan)" @@ -28711,21 +29069,9 @@ game ( ) game ( - name "Mystic Quest (Europe)" - description "Mystic Quest (Europe)" - 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 sha1 b52d82248849f1ead9bf22954b3cbf7bf8e02907 flags verified ) -) - -game ( - name "Mystic Quest (Germany)" - description "Mystic Quest (Germany)" - rom ( name "Mystic Quest (Germany).gb" size 262144 crc 0351b9a6 sha1 7cb65cb314e3f26b92549ddc7f4fc275186c6170 flags verified ) + name "Mysterium (USA) (Beta)" + description "Mysterium (USA) (Beta)" + rom ( name "Mysterium (USA) (Beta).gb" size 131072 crc 004c1af7 sha1 82e058a7608a04a2837d0d8fe810270f804b43f3 ) ) game ( @@ -28746,6 +29092,24 @@ game ( rom ( name "Mystic Quest (World) (De) (Collection of Mana).gb" size 262144 crc a9d7e152 sha1 69235c3494ea650db3b66d6393264f03f0022194 flags verified ) ) +game ( + name "Mystic Quest (Europe)" + description "Mystic Quest (Europe)" + 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 sha1 b52d82248849f1ead9bf22954b3cbf7bf8e02907 flags verified ) +) + +game ( + name "Mystic Quest (Germany)" + description "Mystic Quest (Germany)" + 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)" @@ -28914,24 +29278,6 @@ game ( rom ( name "Nekketsu! Beach Volley Da yo Kunio-kun (Japan) (SGB Enhanced).gb" size 262144 crc abfb84df sha1 d3ad43c40c21d9825b4879dbf28ca58835da658a ) ) -game ( - name "Neko Can Dream (World) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Aftermarket) (Unl).gb" size 2097152 crc 6e76ef25 sha1 55686fde78d17d00adfc831eca2c699274a82273 ) -) - -game ( - name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc a0ad7a18 sha1 5fb1a09e04cf1704b059468de8855dfa7e23043b ) -) - -game ( - name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" - description "Neko Can Dream (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Neko Can Dream (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc dc011d07 sha1 43312b149355d20944e8a366584c69e5cb3be868 ) -) - game ( name "Nekojara Monogatari (Japan)" description "Nekojara Monogatari (Japan)" @@ -29262,60 +29608,18 @@ game ( rom ( name "Noobow (Japan).gb" size 262144 crc 8bbcc8bb sha1 b571d9051e3a9f1a55533b4f43941cae907aedff ) ) -game ( - name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" - description "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl).gb" size 262144 crc d6166c62 sha1 fa2198c5308a15195adbda004f09646589860d11 ) -) - -game ( - name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc 42b47080 sha1 08484b0f98e72d6577d9b7cde8c49908012d1fc5 ) -) - -game ( - name "Oblique Strategies (World) (Aftermarket) (Unl)" - description "Oblique Strategies (World) (Aftermarket) (Unl)" - rom ( name "Oblique Strategies (World) (Aftermarket) (Unl).gb" size 524288 crc 30eca8d3 sha1 6a09aabf30e2ebab2e31ae845cd2e8796c84797f ) -) - game ( name "Oddworld Adventures (USA, Europe)" description "Oddworld Adventures (USA, Europe)" rom ( name "Oddworld Adventures (USA, Europe).gb" size 524288 crc 6510c0e2 sha1 be3f69371b6959dab34014cb1d3672f4f3377c3a flags verified ) ) -game ( - name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl).gb" size 524288 crc d3eba01d sha1 8cf234bbcb68ca2b676a4ccec89814b0cbce1c07 ) -) - -game ( - name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 71f34822 sha1 f24da97f44d280f27f8ebe3acdc33fea758d2255 ) -) - -game ( - name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" - description "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" - rom ( name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 76baab68 sha1 cd76da35541535dd244ad60d10eb998f7692f07a ) -) - 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 sha1 5e13eeb635b41589689fc1b495ee077125b7e8c1 ) ) -game ( - name "Olympic Skier (World) (Aftermarket) (Unl)" - description "Olympic Skier (World) (Aftermarket) (Unl)" - rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gb" size 524288 crc 93174431 sha1 7bcdf10533f8fe053e22534c4962ed4b1a5cf2e2 ) -) - game ( name "Olympic Summer Games (USA, Europe) (SGB Enhanced)" description "Olympic Summer Games (USA, Europe) (SGB Enhanced)" @@ -29424,12 +29728,6 @@ game ( rom ( name "Out of Gas (USA).gb" size 131072 crc 1b67e8b1 sha1 770ac35c0780cf432235593bd5674e72edd6cf7d ) ) -game ( - name "Out on a Limb (World) (Aftermarket) (Unl)" - description "Out on a Limb (World) (Aftermarket) (Unl)" - rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gb" size 262144 crc be197f87 sha1 2ddc2378539316cf7a10e2cf8b562f17e1cf7a6a ) -) - game ( name "Outburst (Japan) (Demo)" description "Outburst (Japan) (Demo)" @@ -29661,7 +29959,7 @@ game ( game ( name "Pang (Europe)" description "Pang (Europe)" - rom ( name "Pang (Europe).gb" size 131072 crc ea9615b4 sha1 7ca64a45ea6a68770658ae39ef21c41f806988c5 ) + rom ( name "Pang (Europe).gb" size 131072 crc ea9615b4 sha1 7ca64a45ea6a68770658ae39ef21c41f806988c5 flags verified ) ) game ( @@ -29670,12 +29968,6 @@ game ( rom ( name "Pang (Europe) (Beta).gb" size 131072 crc 54d2754a sha1 b57d436d8a83f2fb1e42bad3150893ef8ffab0d4 ) ) -game ( - name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" - description "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl).gb" size 524288 crc ce707b9a sha1 b5757b268a09d9085d469eda0676991f7361ad8c ) -) - game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" @@ -29694,12 +29986,6 @@ game ( rom ( name "Parasol Henbee (Japan).gb" size 65536 crc ae97ec53 sha1 8f319d3d1929d953934e32ce900249ecf6b55fbd ) ) -game ( - name "Parasol Islands (World) (Aftermarket) (Unl)" - description "Parasol Islands (World) (Aftermarket) (Unl)" - rom ( name "Parasol Islands (World) (Aftermarket) (Unl).gb" size 1048576 crc b1d79c80 sha1 381f76af67f77e575beae2f45aefd21f079709e6 ) -) - game ( name "Parasol Stars - Rainbow Islands II (Europe)" description "Parasol Stars - Rainbow Islands II (Europe)" @@ -29754,18 +30040,6 @@ game ( rom ( name "Penta Dragon (Japan).gb" size 262144 crc 1e2efaee sha1 fd75d43258e79f14d104fb4756e219141882c837 ) ) -game ( - name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" - description "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" - rom ( name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl).gb" size 262144 crc 9b4bacaa sha1 09b0691f6823c54f1515dd3b66f135ac45a7dbc3 ) -) - -game ( - name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" - description "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" - rom ( name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl).gb" size 262144 crc 1e8b2a29 sha1 a25dfc43408080ac116479fa55c9e7320e5cc82a ) -) - game ( name "PGA European Tour (USA, Europe) (SGB Enhanced)" description "PGA European Tour (USA, Europe) (SGB Enhanced)" @@ -29796,18 +30070,6 @@ game ( rom ( name "Philip & Marlowe in Bloomland (USA) (Proto).gb" size 131072 crc 32bae420 sha1 2f9e5cee29d0d578b2642ce8637f02fc567aebc5 ) ) -game ( - name "Phobos Dere .GB (World) (Aftermarket) (Unl)" - description "Phobos Dere .GB (World) (Aftermarket) (Unl)" - rom ( name "Phobos Dere .GB (World) (Aftermarket) (Unl).gb" size 1048576 crc ae97f4f8 sha1 e541505078ee5e7e5c897b4621cc693ce71e35ba flags verified ) -) - -game ( - name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" - description "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" - rom ( name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 58362b86 sha1 b4cc3c3735bc134e34b97e08ed24c57aef5c5ccf flags verified ) -) - game ( name "Picross 2 (Japan) (SGB Enhanced)" description "Picross 2 (Japan) (SGB Enhanced)" @@ -29862,18 +30124,6 @@ game ( rom ( name "Pinball Mania (Europe).gb" size 262144 crc edc8d122 sha1 0541161b4b93fffc3c75708aca86ea0873747ced ) ) -game ( - name "Pineapple Kid (World) (Aftermarket) (Unl)" - description "Pineapple Kid (World) (Aftermarket) (Unl)" - rom ( name "Pineapple Kid (World) (Aftermarket) (Unl).gb" size 131072 crc 9541488b sha1 fd574b5d407f3654db3227900a8ed7eff4fe48ae ) -) - -game ( - name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" - description "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 9d9102d9 sha1 105e78f740d6bc517ef0079f867e9fdce8d012d2 ) -) - game ( name "Pingu - Sekai de 1ban Genki na Penguin (Japan)" description "Pingu - Sekai de 1ban Genki na Penguin (Japan)" @@ -29916,28 +30166,10 @@ game ( rom ( name "Pitman (Japan).gb" size 32768 crc a0b68136 sha1 a698d4bccd69d2ca51cb48877bde5d1f83d4317f ) ) -game ( - name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" - description "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" - rom ( name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) -) - -game ( - name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" - description "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl).gb" size 524288 crc 60c84f2e sha1 c39ec5e6a9a0be0970b56e788c3f60e9821dbbd3 ) -) - game ( name "Play Action Football (USA)" description "Play Action Football (USA)" - rom ( name "Play Action Football (USA).gb" size 131072 crc 983caf46 sha1 dc2981baf1bb4d0a65ec45fb22d44a5ca4c06254 ) -) - -game ( - name "Pluto's Corner (World) (Aftermarket) (Unl)" - description "Pluto's Corner (World) (Aftermarket) (Unl)" - rom ( name "Pluto's Corner (World) (Aftermarket) (Unl).gb" size 65536 crc 21fc06b3 sha1 94e4a442205079d85d5ca37042eaec555f7f49db ) + rom ( name "Play Action Football (USA).gb" size 131072 crc 983caf46 sha1 dc2981baf1bb4d0a65ec45fb22d44a5ca4c06254 flags verified ) ) game ( @@ -30141,7 +30373,7 @@ game ( game ( name "Pocket Sonar (Japan)" description "Pocket Sonar (Japan)" - rom ( name "Pocket Sonar (Japan).gb" size 524288 crc d68c9f79 sha1 788cdf148431b82b5308c68b3e45b133a7074196 ) + rom ( name "Pocket Sonar (Japan).gb" size 524288 crc d68c9f79 sha1 788cdf148431b82b5308c68b3e45b133a7074196 flags verified ) ) game ( @@ -30150,12 +30382,6 @@ game ( rom ( name "Pocket Stadium (Japan).gb" size 65536 crc c7bd9228 sha1 7ba422f2b48ff09673f7f1a258be6ecc1ff6a8d7 ) ) -game ( - name "Pogo Pete (World) (Aftermarket) (Unl)" - description "Pogo Pete (World) (Aftermarket) (Unl)" - rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gb" size 262144 crc 185ce1d5 sha1 74021e84c1d095b2401302e26352e810dbc432d8 ) -) - game ( name "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" description "Pokemon - Blaue Edition (Germany) (SGB Enhanced)" @@ -30219,7 +30445,7 @@ game ( 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 sha1 47faa910d0e073c600665bf9c83b6bd17babdf8a ) + rom ( name "Pokemon - Version Bleue (France) (SGB Enhanced).gb" size 1048576 crc 50e2fc1d sha1 47faa910d0e073c600665bf9c83b6bd17babdf8a flags verified ) ) game ( @@ -30336,12 +30562,6 @@ game ( rom ( name "Pop'n TwinBee (Europe).gb" size 131072 crc d07db274 sha1 0206230b55c15a8c18fbb85f852967e44b33a0a4 ) ) -game ( - name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" - description "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) -) - game ( name "Popeye (Japan)" description "Popeye (Japan)" @@ -30396,24 +30616,6 @@ game ( rom ( name "Populous Gaiden (Japan).gb" size 131072 crc f327167e sha1 fde1789eb253309cae80faf4fe7241c6f9d72f29 ) ) -game ( - name "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" - description "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.0.3) (Aftermarket) (Unl).gb" size 65536 crc 6c57e55e sha1 143f31656a5007f65b19d6e32967698bb8f72a66 ) -) - -game ( - name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" - description "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) -) - -game ( - name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" - description "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 801f097b sha1 5da110a88799765707e027bcedec0875a637509b ) -) - game ( name "Power Mission (Japan)" description "Power Mission (Japan)" @@ -30624,18 +30826,6 @@ game ( rom ( name "Purikura Pocket 3 - Talent Debut Daisakusen (Japan) (Rev 1) (SGB Enhanced) (NP).gb" size 1048576 crc 458dd05d sha1 7779a103a7ae3e382c8ffa3a6830160af36bb3b4 ) ) -game ( - name "Purple Turtles (World) (Aftermarket) (Unl)" - description "Purple Turtles (World) (Aftermarket) (Unl)" - rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gb" size 262144 crc f7041a97 sha1 d2d7eff063104c8f205c192a902a53092c0b5f4a ) -) - -game ( - name "Pushingo (World) (Aftermarket) (Unl)" - description "Pushingo (World) (Aftermarket) (Unl)" - rom ( name "Pushingo (World) (Aftermarket) (Unl).gb" size 262144 crc a8541ed0 sha1 1ac1e22b191a95fdfa00c34ccba7387c991c827b ) -) - game ( name "Puyo Puyo (Japan) (SGB Enhanced)" description "Puyo Puyo (Japan) (SGB Enhanced)" @@ -30732,12 +30922,6 @@ game ( rom ( name "Quarth (USA, Europe).gb" size 65536 crc bfb112ad sha1 89448b17700a6016a3f81de09a15e097c060d103 flags verified ) ) -game ( - name "Quick Draw (World) (Aftermarket) (Unl)" - description "Quick Draw (World) (Aftermarket) (Unl)" - rom ( name "Quick Draw (World) (Aftermarket) (Unl).gb" size 262144 crc 7704671f sha1 75f96ce54ed8739d58153780e9b573a65f1c5880 ) -) - game ( name "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" description "Quiz Nihon Mukashibanashi - Athena no Hatena (Japan)" @@ -30822,12 +31006,6 @@ game ( rom ( name "Radar Mission (USA, Europe).gb" size 131072 crc 581da9c9 sha1 5ab5998a84eebc769f75c482cb0a5586ed97e888 ) ) -game ( - name "Raffles (World) (Aftermarket) (Unl)" - description "Raffles (World) (Aftermarket) (Unl)" - rom ( name "Raffles (World) (Aftermarket) (Unl).gb" size 262144 crc 0b400a91 sha1 aadfe3fd0720696547b73b272354b592b96f98f7 ) -) - game ( name "Raging Fighter (USA, Europe)" description "Raging Fighter (USA, Europe)" @@ -30894,12 +31072,6 @@ game ( rom ( name "Red October o Oe! (Japan).gb" size 131072 crc c2e7be35 sha1 48d5f02a126c32423569065f31d2c5695e39fd2f ) ) -game ( - name "Remute - Living Electronics (World) (Aftermarket) (Unl)" - description "Remute - Living Electronics (World) (Aftermarket) (Unl)" - rom ( name "Remute - Living Electronics (World) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 flags verified ) -) - game ( name "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" description "Ren & Stimpy Show, The - Space Cadet Adventures (USA)" @@ -30930,30 +31102,6 @@ game ( rom ( name "Reservoir Rat (Europe) (En,Fr,De,Es,It).gb" size 262144 crc 2d33e175 sha1 08dad9ac1f045d1c9e403c4ea1368aee991e0094 ) ) -game ( - name "Retroid (World) (Aftermarket) (Unl)" - description "Retroid (World) (Aftermarket) (Unl)" - rom ( name "Retroid (World) (Aftermarket) (Unl).gb" size 262144 crc 9f759f25 sha1 4c7323d6a10852fe416c7bd581d6ffdd2d473bb5 ) -) - -game ( - name "Rewind Time (World) (Aftermarket) (Unl)" - description "Rewind Time (World) (Aftermarket) (Unl)" - rom ( name "Rewind Time (World) (Aftermarket) (Unl).gb" size 262144 crc d8ad184a sha1 903ef8074e58a52bc98dcb9e3f2c88b52fc1335b ) -) - -game ( - name "Rhythm Land (World) (Aftermarket) (Unl)" - description "Rhythm Land (World) (Aftermarket) (Unl)" - rom ( name "Rhythm Land (World) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) -) - -game ( - name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" - description "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" - rom ( name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl).gb" size 131072 crc fbf98400 sha1 1b831806d32e1ec35bc94a84384c6989433a274d ) -) - game ( name "Riddick Bowe Boxing (Europe)" description "Riddick Bowe Boxing (Europe)" @@ -30972,12 +31120,6 @@ game ( rom ( name "Riddick Bowe Boxing (USA) (Beta).gb" size 131072 crc a07512a6 sha1 69685eaffa523bf199be0c540d9eb561bb27d584 ) ) -game ( - name "Rig Attack (World) (Aftermarket) (Unl)" - description "Rig Attack (World) (Aftermarket) (Unl)" - rom ( name "Rig Attack (World) (Aftermarket) (Unl).gb" size 262144 crc dea8749d sha1 6f0fbac6b6c2e8f2d8df0a0a0e2f0c947e37b39a ) -) - game ( name "Ring Rage (Japan)" description "Ring Rage (Japan)" @@ -31008,12 +31150,6 @@ game ( rom ( name "Roadster (Japan).gb" size 131072 crc 04453e78 sha1 685c31496de738c27160d1f75408da6b95daaae8 ) ) -game ( - name "Robby's Day Out (World) (Aftermarket) (Unl)" - description "Robby's Day Out (World) (Aftermarket) (Unl)" - rom ( name "Robby's Day Out (World) (Aftermarket) (Unl).gb" size 262144 crc c3c89cd9 sha1 9d38b69ab9a4ff7bf387c88f2afed410d450f2e0 ) -) - game ( name "Robin Hood - Prince of Thieves (Europe)" description "Robin Hood - Prince of Thieves (Europe)" @@ -31170,18 +31306,6 @@ game ( rom ( name "Rolan's Curse II (USA).gb" size 131072 crc 2754f360 sha1 7632e23853dd2579012489f75bd370473f0f2c46 flags verified ) ) -game ( - name "Roommate Simulator (World) (Aftermarket) (Unl)" - description "Roommate Simulator (World) (Aftermarket) (Unl)" - rom ( name "Roommate Simulator (World) (Aftermarket) (Unl).gb" size 131072 crc 3c95b1aa sha1 d5c99106c3bd4d46aeb75f513fd4314c19c734b2 ) -) - -game ( - name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" - description "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" - rom ( name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 51d09337 sha1 9e935cca00cb4c3aad7b1dfce9fe59f5d913bdff ) -) - game ( name "Rubble Saver (Japan)" description "Rubble Saver (Japan)" @@ -31230,24 +31354,6 @@ game ( rom ( name "Sa-Ga 3 - Jikuu no Hasha (World) (Ja) (Collection of SaGa).gb" size 262144 crc dc4f4e34 sha1 8125677ee63e9abb4b956ed0bee18fae3e04193b ) ) -game ( - name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" - description "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 6669f0be sha1 25bcf936e8dadb10d288473989891e4f2ec6c605 ) -) - -game ( - name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" - description "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl).gb" size 2097152 crc 1c4b7eb0 sha1 5cd15f4629fdbcfd6f752d89be755d5ac02b9435 ) -) - -game ( - name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" - description "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 03f2dd1a sha1 78fe9c7cd6d0d7f1157c8c7716642d17c4b80303 ) -) - game ( name "Sagaia (Japan)" description "Sagaia (Japan)" @@ -31272,12 +31378,6 @@ game ( rom ( name "Sakigake!! Otoko Juku - Meioutou Kessen (Japan).gb" size 131072 crc 2f0f7f63 sha1 c731f8be269d74748ae54fe5ce5faea89a825e0f ) ) -game ( - name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" - description "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" - rom ( name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) -) - game ( name "Same Game (Japan) (SGB Enhanced)" description "Same Game (Japan) (SGB Enhanced)" @@ -31392,12 +31492,6 @@ game ( rom ( name "Sea Battle (Europe) (En,Fr,De,Es).gb" size 131072 crc ba091b91 sha1 560d62b96a1b9820e3fd953f76e33b4f5fdc9e2f ) ) -game ( - name "Sea King GB (USA) (Proto) (SGB Enhanced)" - description "Sea King GB (USA) (Proto) (SGB Enhanced)" - rom ( name "Sea King GB (USA) (Proto) (SGB Enhanced).gb" size 1048576 crc a45ef889 sha1 26bebc2394b5da850be55e409b9efcb4d2d29d87 ) -) - game ( name "seaQuest DSV (USA, Europe) (SGB Enhanced)" description "seaQuest DSV (USA, Europe) (SGB Enhanced)" @@ -31464,12 +31558,6 @@ game ( rom ( name "Serpent (USA).gb" size 32768 crc 74d466d7 sha1 3122b3c12c2580c3a81d70c5648f767bf3590aaf flags verified ) ) -game ( - name "Severen (World) (Demo) (Aftermarket) (Unl)" - description "Severen (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Severen (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 642f2244 sha1 d9692aa569820db3f38458819cba21846a2e06f4 ) -) - game ( name "Shadow Warriors (Europe)" description "Shadow Warriors (Europe)" @@ -31500,30 +31588,12 @@ game ( rom ( name "Shanghai Pocket (Japan) (SGB Enhanced).gb" size 262144 crc 6b8eff2c sha1 82fe97442aa625fd36cf865d82f78b07108ede7f ) ) -game ( - name "Shapeshifter, The (World) (Aftermarket) (Unl)" - description "Shapeshifter, The (World) (Aftermarket) (Unl)" - rom ( name "Shapeshifter, The (World) (Aftermarket) (Unl).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) -) - 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 sha1 5e9e68d9235cf8149232b85fd6080ba8796cb85e ) ) -game ( - name "Shark Attack (World) (Aftermarket) (Unl)" - description "Shark Attack (World) (Aftermarket) (Unl)" - rom ( name "Shark Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 3032025a sha1 6cc65bb719af53128bb04c9ee7c6abbf4ff1c3cf ) -) - -game ( - name "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" - description "Sheep it Up (World) (Digital) (Aftermarket) (Unl)" - rom ( name "Sheep it Up (World) (Digital) (Aftermarket) (Unl).gb" size 32768 crc fa6de2e4 sha1 9ad365ed7d4e07041c0147831a9bb1c496ea0bc8 ) -) - game ( name "Shikinjou (Japan)" description "Shikinjou (Japan)" @@ -31590,24 +31660,6 @@ game ( rom ( name "Shisenshou - Match-Mania (Japan).gb" size 32768 crc 0cdd8b04 sha1 6e84a906f9e1ce43272db84c63f1b037096ac34f flags verified ) ) -game ( - name "Shock Lobster (World) (Aftermarket) (Unl)" - description "Shock Lobster (World) (Aftermarket) (Unl)" - rom ( name "Shock Lobster (World) (Aftermarket) (Unl).gb" size 32768 crc 7a0622e6 sha1 10c1816724cd6e332d2a5aeed4e546e7bd764ebf ) -) - -game ( - name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" - description "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl).gb" size 32768 crc 8f244e86 sha1 7b8c8a9ec4758c6880598b9d508bc5805293dd87 ) -) - -game ( - name "Shootris (World) (Aftermarket) (Unl)" - description "Shootris (World) (Aftermarket) (Unl)" - rom ( name "Shootris (World) (Aftermarket) (Unl).gb" size 262144 crc 50180f64 sha1 5d978e6fc4bd5d9717d022360122458e95fffc29 ) -) - game ( name "Shougi (Japan)" description "Shougi (Japan)" @@ -31692,12 +31744,6 @@ game ( rom ( name "Skate or Die - Tour de Thrash (USA).gb" size 131072 crc 02b77c09 sha1 6e1610450da0c836983a1c310524639fefcc304f ) ) -game ( - name "Sloth Story (World) (Aftermarket) (Unl)" - description "Sloth Story (World) (Aftermarket) (Unl)" - rom ( name "Sloth Story (World) (Aftermarket) (Unl).gb" size 262144 crc c873f232 sha1 369d2afec4ffb59d4f3a59ee684c5bfec0b34ff8 ) -) - game ( name "Small Soldiers (USA, Europe) (SGB Enhanced)" description "Small Soldiers (USA, Europe) (SGB Enhanced)" @@ -31734,24 +31780,6 @@ game ( rom ( name "Smurfs, The (USA, Europe) (En,Fr,De) (Rev 1) (SGB Enhanced).gb" size 131072 crc 8b5bcde7 sha1 a0d6a85331fb034f68f05629a5ff85e13adab205 flags verified ) ) -game ( - name "Snail, The (World) (v1.3) (Aftermarket) (Unl)" - description "Snail, The (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Snail, The (World) (v1.3) (Aftermarket) (Unl).gb" size 262144 crc 422a7b44 sha1 776f7578d747f935ebccda93d6487ffa4dc4bce3 ) -) - -game ( - name "Snakebird (World) (Aftermarket) (Unl)" - description "Snakebird (World) (Aftermarket) (Unl)" - rom ( name "Snakebird (World) (Aftermarket) (Unl).gb" size 131072 crc 4627f98e sha1 99cc82279d65b86b4366bf61db9bf67a78e051dc ) -) - -game ( - name "Snaky Pocket (World) (Aftermarket) (Unl)" - description "Snaky Pocket (World) (Aftermarket) (Unl)" - rom ( name "Snaky Pocket (World) (Aftermarket) (Unl).gb" size 32768 crc 7209370d sha1 f5eab31a499f33b3ae1f7b5b006dcca1df3ac2b9 ) -) - game ( name "Sneaky Snakes (USA, Europe)" description "Sneaky Snakes (USA, Europe)" @@ -31807,9 +31835,15 @@ game ( ) game ( - name "Soccer Boy (Japan)" - description "Soccer Boy (Japan)" - rom ( name "Soccer Boy (Japan).gb" size 65536 crc 23f64e82 sha1 7554b42d1c38508fd615828c96ab58ea8f41de4d ) + name "Soccer Boy (Japan) (En)" + description "Soccer Boy (Japan) (En)" + rom ( name "Soccer Boy (Japan) (En).gb" size 65536 crc 23f64e82 sha1 7554b42d1c38508fd615828c96ab58ea8f41de4d ) +) + +game ( + name "Soccer Boy (Japan) (En) (Beta)" + description "Soccer Boy (Japan) (En) (Beta)" + rom ( name "Soccer Boy (Japan) (En) (Beta).gb" size 65536 crc a46f98d1 sha1 22db7c6096f285222aefbfe413efa1d21de59731 ) ) game ( @@ -31860,24 +31894,6 @@ game ( rom ( name "Solomon's Club (USA).gb" size 65536 crc cea9622a sha1 36abf2be4a16df8e9fe30307cbd8cb949a9b9bdb ) ) -game ( - name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" - description "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 665ad70a sha1 c5b6eb610caa2213d8db7ab204bad44d60f7d63a ) -) - -game ( - name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" - description "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl).gb" size 262144 crc feed93e0 sha1 721d78d4ef167acfcc00baf909db4c94d522d681 ) -) - -game ( - name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" - description "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" - rom ( name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl).gb" size 262144 crc 6547e5c8 sha1 53a42f45b7ed368d7af9d41f2442fe463c26e545 ) -) - game ( name "Sonic 6 (USA) (Pirate)" description "Sonic 6 (USA) (Pirate)" @@ -31938,12 +31954,6 @@ game ( rom ( name "Space Invaders (Europe) (Beta) (SGB Enhanced).gb" size 131072 crc 2d03dc38 sha1 6a2af41de10dbf6496b18963d904cc41d04bb970 ) ) -game ( - name "Space Trouble (World) (Proto) (Aftermarket) (Unl)" - description "Space Trouble (World) (Proto) (Aftermarket) (Unl)" - rom ( name "Space Trouble (World) (Proto) (Aftermarket) (Unl).gb" size 524288 crc f015931c sha1 ec7bc27387d4d2ac01127bc24e1adf45b6ebc936 ) -) - game ( name "Spanky's Quest (Europe)" description "Spanky's Quest (Europe)" @@ -32010,12 +32020,6 @@ game ( rom ( name "Spider-Man 3 - Invasion of the Spider-Slayers (USA, Europe) (Beta 2) (1993-04-11).gb" size 131072 crc bf2d1f10 sha1 34740dc60663ef33c42573a26e7b207f2cfe4a16 ) ) -game ( - name "Spiky Harold (World) (Aftermarket) (Unl)" - description "Spiky Harold (World) (Aftermarket) (Unl)" - rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gb" size 524288 crc 2ac1b945 sha1 b8f37a64524bde4c2b6e9a1938ed6e5c0a5aad7c ) -) - game ( name "Spirit of F-1, The (Europe)" description "Spirit of F-1, The (Europe)" @@ -32202,6 +32206,12 @@ game ( rom ( name "Star Wars (USA, Europe) (Rev 1).gb" size 131072 crc 5d8deb5b sha1 f6563f526fc786c8666d75dfba9e6d42d787ea89 flags verified ) ) +game ( + name "Star Wars (World) (Limited Run Games)" + description "Star Wars (World) (Limited Run Games)" + rom ( name "Star Wars (World) (Limited Run Games).gb" size 131072 crc 08838397 sha1 02bfb690ce171214bfee900069192e0daafc010d ) +) + game ( name "Star Wars - The Empire Strikes Back (USA, Europe)" description "Star Wars - The Empire Strikes Back (USA, Europe)" @@ -32215,9 +32225,9 @@ game ( ) game ( - name "Stardiver (World) (Aftermarket) (Unl)" - description "Stardiver (World) (Aftermarket) (Unl)" - rom ( name "Stardiver (World) (Aftermarket) (Unl).gb" size 1048576 crc 25ff97f7 sha1 d609b8de2c7a61b7281fec5c761e3504aa4d94e9 ) + name "Star Wars - The Empire Strikes Back (World) (Limited Run Games)" + description "Star Wars - The Empire Strikes Back (World) (Limited Run Games)" + rom ( name "Star Wars - The Empire Strikes Back (World) (Limited Run Games).gb" size 131072 crc 799e4ae8 sha1 dc819b082f671699ac189a49075854d8ff7a2b8f ) ) game ( @@ -32238,6 +32248,12 @@ game ( rom ( name "StarHawk (Europe).gb" size 131072 crc e032e502 sha1 4c22e06cb98119923126f6500568ce9f136a33c5 flags verified ) ) +game ( + name "StarHawk (World) (Limited Run Games)" + description "StarHawk (World) (Limited Run Games)" + rom ( name "StarHawk (World) (Limited Run Games).gb" size 131072 crc 00da50e2 sha1 bf64c1b1071bd243417b6c29fd8a4dd559d3f63a ) +) + game ( name "Stop That Roach! (USA)" description "Stop That Roach! (USA)" @@ -32400,12 +32416,6 @@ game ( rom ( name "Super Chinese Land 3 (Japan) (SGB Enhanced).gb" size 262144 crc e01caf0b sha1 6d8ef3fdd1702d629c679636698e1d483fc3723b flags verified ) ) -game ( - name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" - description "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" - rom ( name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl).gb" size 262144 crc 51946e8d sha1 cac4917d56da02cf88ba68e0c5189a18c2c234ac ) -) - game ( name "Super Donkey Kong 3 (Taiwan) (Unl)" description "Super Donkey Kong 3 (Taiwan) (Unl)" @@ -32598,12 +32608,6 @@ game ( rom ( name "Superman (USA, Europe) (SGB Enhanced).gb" size 131072 crc 358e0091 sha1 3a987cb4ba6f33717ea70d7388ec1dfe6ab934e8 flags verified ) ) -game ( - name "Sushi Gun (World) (Aftermarket) (Unl)" - description "Sushi Gun (World) (Aftermarket) (Unl)" - rom ( name "Sushi Gun (World) (Aftermarket) (Unl).gb" size 262144 crc a9d405d6 sha1 c075856939d4fe3cd250083b527b3e09be70052d ) -) - game ( name "Sutte Hakkun (Japan) (Proto) (SGB Enhanced)" description "Sutte Hakkun (Japan) (Proto) (SGB Enhanced)" @@ -32628,12 +32632,6 @@ game ( rom ( name "Swamp Thing (USA, Europe).gb" size 131072 crc 76ae62c8 sha1 1ff322b5f44d21c951dcdf8d062d99ffa65827e3 flags verified ) ) -game ( - name "Swaplatformer (World) (Aftermarket) (Unl)" - description "Swaplatformer (World) (Aftermarket) (Unl)" - rom ( name "Swaplatformer (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) -) - game ( name "Sword of Hope II, The (USA)" description "Sword of Hope II, The (USA)" @@ -32694,6 +32692,12 @@ game ( rom ( name "Tail 'Gator (USA, Europe).gb" size 65536 crc c5acce7c sha1 ed5f1110a9db4c48d26d53af0973e8b46fe7e4e1 ) ) +game ( + name "Tail 'Gator (World) (Limited Run Games)" + description "Tail 'Gator (World) (Limited Run Games)" + rom ( name "Tail 'Gator (World) (Limited Run Games).gb" size 65536 crc e35cd748 sha1 203f6e20e4d44792c727fe78aaa65e354d014175 ) +) + game ( name "Taito Chase H.Q. (Japan)" description "Taito Chase H.Q. (Japan)" @@ -32730,12 +32734,6 @@ game ( rom ( name "Takahashi Meijin no Bouken-jima III (Japan).gb" size 262144 crc f8fc0b41 sha1 e3fe857a1b7f00a6f7862d7dd401063f98fd0cb6 ) ) -game ( - name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" - description "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 5898c134 sha1 bd3468395deb0009b190d0b5d487962ae65adbee ) -) - game ( name "Takeda Nobuhiro no Ace Striker (Japan)" description "Takeda Nobuhiro no Ace Striker (Japan)" @@ -32808,12 +32806,6 @@ game ( rom ( name "Taz-Mania 2 (USA).gb" size 131072 crc 4ccb65e0 sha1 60116a304e85f04209dc7eb64d9649dc41c963f6 ) ) -game ( - name "Tech and Blood (World) (Aftermarket) (Unl)" - description "Tech and Blood (World) (Aftermarket) (Unl)" - rom ( name "Tech and Blood (World) (Aftermarket) (Unl).gb" size 262144 crc 3da2a358 sha1 40a00fce49b16cb36793df30e5156e5bf3e47778 ) -) - game ( name "Tecmo Bowl (USA)" description "Tecmo Bowl (USA)" @@ -33066,24 +33058,6 @@ game ( rom ( name "Tetris Plus (USA, Europe) (SGB Enhanced).gb" size 262144 crc dafc3bff sha1 dfab75ab6bdc0765ba9a5d33a93ffdb114a49cbf flags verified ) ) -game ( - name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" - description "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" - rom ( name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) -) - -game ( - name "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" - description "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" - rom ( name "Thin Ice Rescue, The (World) (Aftermarket) (Unl).gb" size 32768 crc 3e0483d6 sha1 b789ced0fe26785e7bce765a9d6ee783f9d967d8 ) -) - -game ( - name "TimberMan (World) (Aftermarket) (Unl)" - description "TimberMan (World) (Aftermarket) (Unl)" - rom ( name "TimberMan (World) (Aftermarket) (Unl).gb" size 32768 crc e0b8459c sha1 e3f4b4c4816cc0dda2885519f1386385e6a5e817 ) -) - game ( name "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" description "Tintin - Prisoners of the Sun (Europe) (En,Fr,De)" @@ -33174,12 +33148,6 @@ game ( rom ( name "Titus the Fox (USA, Europe).gb" size 262144 crc 814fa146 sha1 ba0037aeb21de0bbba3f9294a7861d90aefa5008 flags verified ) ) -game ( - name "Tobu Tobu Girl (World) (Aftermarket) (Unl)" - description "Tobu Tobu Girl (World) (Aftermarket) (Unl)" - rom ( name "Tobu Tobu Girl (World) (Aftermarket) (Unl).gb" size 262144 crc ed12be6c sha1 8a8f3c1f21f903ea5a7df8fc8b0a6aa5a602e150 ) -) - game ( name "Tokio Senki - Eiyuu Retsuden (Japan)" description "Tokio Senki - Eiyuu Retsuden (Japan)" @@ -33342,36 +33310,12 @@ game ( rom ( name "Trappers Tengoku - Spy vs Spy (Japan).gb" size 131072 crc afefd085 sha1 c9eb687f6de7b821255fdd0cbf14f68ad789f97f ) ) -game ( - name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl).gb" size 2097152 crc 15afd765 sha1 c12e603492f8bcfffd28dd4733c7bc445c507642 ) -) - -game ( - name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl).gb" size 2097152 crc e1bdf67f sha1 ba492778121622b5288d4188edc344aa41aa6803 ) -) - -game ( - name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl).gb" size 1048576 crc 42bb7dab sha1 70fded7ce1edc54de85b020460f779feb9bdbc01 ) -) - game ( name "Trax (USA, Europe)" description "Trax (USA, Europe)" rom ( name "Trax (USA, Europe).gb" size 131072 crc 4a38be7d sha1 3f3a31ed7e47319c5815dd6e31ca27a52377423c flags verified ) ) -game ( - name "Treasure Island (World) (Aftermarket) (Unl)" - description "Treasure Island (World) (Aftermarket) (Unl)" - rom ( name "Treasure Island (World) (Aftermarket) (Unl).gb" size 262144 crc cbdec393 sha1 adeaba2723d286d143e0987f51ce9c8ad2f5e839 ) -) - game ( name "Trip World (Europe)" description "Trip World (Europe)" @@ -33384,6 +33328,12 @@ game ( rom ( name "Trip World (Japan).gb" size 262144 crc 11568e64 sha1 ac19d49906e72aaebeffa9ab7106eb346a5efa07 ) ) +game ( + name "Trip World (World) (Limited Run Games)" + description "Trip World (World) (Limited Run Games)" + rom ( name "Trip World (World) (Limited Run Games).gb" size 262144 crc ec67f1e6 sha1 16bb82fa8708cbd159388c55e702b9fb9ed5a41f ) +) + game ( name "TripleA (USA) (Proto)" description "TripleA (USA) (Proto)" @@ -33654,12 +33604,6 @@ game ( rom ( name "V-Rally - Championship Edition (Europe) (En,Fr,De).gb" size 262144 crc d149652b sha1 67d2a6e41b6a1d8372808535ac8c8222d7c53480 flags verified ) ) -game ( - name "Vampire Night Shift (World) (Aftermarket) (Unl)" - description "Vampire Night Shift (World) (Aftermarket) (Unl)" - rom ( name "Vampire Night Shift (World) (Aftermarket) (Unl).gb" size 262144 crc 88acbc1a sha1 ef617803c2cdb14cfe3b3b2111aa239a3744e29e ) -) - game ( name "Vattle Giuce (Japan)" description "Vattle Giuce (Japan)" @@ -33714,12 +33658,6 @@ game ( rom ( name "VS Battler (Japan).gb" size 65536 crc 20ae389a sha1 5f99c7767cbbf5ad9164805214875d7054f49f14 ) ) -game ( - name "Waifu Clicker (World) (Aftermarket) (Unl)" - description "Waifu Clicker (World) (Aftermarket) (Unl)" - rom ( name "Waifu Clicker (World) (Aftermarket) (Unl).gb" size 65536 crc 155f85dc sha1 bb571ed69c3a33e45ba33fbb03a066ba98ae0b20 ) -) - game ( name "Wario Blast Featuring Bomberman! (USA, Europe) (SGB Enhanced)" description "Wario Blast Featuring Bomberman! (USA, Europe) (SGB Enhanced)" @@ -33780,16 +33718,10 @@ game ( rom ( name "Welcome Nakayoshi Park (Japan).gb" size 262144 crc f6e2baae sha1 8779a1557ba0de3c5c8b770413f30bd31717b2ef ) ) -game ( - name "What Friends Are For (World) (Aftermarket) (Unl)" - description "What Friends Are For (World) (Aftermarket) (Unl)" - rom ( name "What Friends Are For (World) (Aftermarket) (Unl).gb" size 262144 crc cbed3dd6 sha1 58538084a964f779c2f756fbe732656f3f7bef66 ) -) - game ( name "Wheel of Fortune (USA)" description "Wheel of Fortune (USA)" - rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408fe48 sha1 43de94eda492bfabbdc6e232af9cbd9df080dfd5 ) + rom ( name "Wheel of Fortune (USA).gb" size 131072 crc 8408fe48 sha1 43de94eda492bfabbdc6e232af9cbd9df080dfd5 flags verified ) ) game ( @@ -33822,12 +33754,6 @@ game ( rom ( name "Wily & Right no Rockboard - That's Paradise (Japan) (Proto).gb" size 262144 crc af84dc97 sha1 cc917f113c5cdd1afc3340feb8bf2094d0902cec ) ) -game ( - name "Windows93 Adventure (World) (Aftermarket) (Unl)" - description "Windows93 Adventure (World) (Aftermarket) (Unl)" - rom ( name "Windows93 Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc e1ad0b6f sha1 3ad7327f6f94976c3d12054cf6deb2666ba9fa66 ) -) - game ( name "Winner's Horse (Japan)" description "Winner's Horse (Japan)" @@ -33852,12 +33778,6 @@ game ( rom ( name "Winter Olympic Games (USA) (Rev 1) (Beta).gb" size 131072 crc 1510305e sha1 6f66dc2ab6f302251591a1252be12367a8e8dfe4 ) ) -game ( - name "Wizard of Wor (World) (Aftermarket) (Unl)" - description "Wizard of Wor (World) (Aftermarket) (Unl)" - rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gb" size 524288 crc bfb1563e sha1 108eefa154412e3422dce4e63bf34f5826ec1baa ) -) - game ( name "Wizardry Gaiden I - Joou no Junan (Japan)" description "Wizardry Gaiden I - Joou no Junan (Japan)" @@ -33882,12 +33802,6 @@ game ( rom ( name "Wizards & Warriors X - The Fortress of Fear (USA, Europe).gb" size 65536 crc 104eb503 sha1 22a514056e58263dc08602778bc3bf2c0ca6e681 flags verified ) ) -game ( - name "Woolball's Backyard (World) (Aftermarket) (Unl)" - description "Woolball's Backyard (World) (Aftermarket) (Unl)" - rom ( name "Woolball's Backyard (World) (Aftermarket) (Unl).gb" size 65536 crc 69e26eb6 sha1 28795c4b829440549b3ac2afe3282d85a439f7d7 ) -) - game ( name "Wordtris (USA)" description "Wordtris (USA)" @@ -34104,6 +34018,12 @@ game ( rom ( name "Xin Nushen Zhuansheng Waizhuan - Zuihou de Shengjing (Taiwan) (Pirate).gb" size 524288 crc 2298585c sha1 f33091c0bfd840e0ce4c4f99c463cfb92f823a64 ) ) +game ( + name "Xin Shuma Baobei Huang (China) (Pirate)" + description "Xin Shuma Baobei Huang (China) (Pirate)" + rom ( name "Xin Shuma Baobei Huang (China) (Pirate).gb" size 2097152 crc 86869520 sha1 b341efb4831b0fe066fd035ba9f7f876efa3cd50 ) +) + game ( name "Yakuman (Japan)" description "Yakuman (Japan)" @@ -34122,18 +34042,6 @@ game ( rom ( name "Yannick Noah Tennis (France) (En).gb" size 65536 crc 402d4d47 sha1 5bc39c44da587a89bef7478617c402855a1b5b24 flags verified ) ) -game ( - name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" - description "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) -) - -game ( - name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" - description "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) -) - game ( name "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" description "Yelu Wangzi (Prince Yeh Rude) (Taiwan) (En) (Unl)" @@ -34224,30 +34132,12 @@ game ( rom ( name "Yu-Gi-Oh! Duel Monsters (Japan) (SGB Enhanced).gb" size 1048576 crc 8875ec54 sha1 07ae4a6437f00f6af462bf84fd0ac1cf345c8365 flags verified ) ) -game ( - name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" - description "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" - rom ( name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl).gb" size 524288 crc 8a667058 sha1 e765d6915f543a5a65e8be440b3f29eb674a5448 ) -) - -game ( - name "Zagan Warrior (World) (Aftermarket) (Unl)" - description "Zagan Warrior (World) (Aftermarket) (Unl)" - rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gb" size 262144 crc 97fe7a94 sha1 88f76297a4ccf0e3a5ba16ca15237c88346c134a ) -) - game ( name "ZAS (Europe) (Proto)" description "ZAS (Europe) (Proto)" rom ( name "ZAS (Europe) (Proto).gb" size 131072 crc ae282077 sha1 a480d3a205f4c6fe7da41637180459fb2cff9139 ) ) -game ( - name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" - description "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" - rom ( name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl).gb" size 524288 crc f86c2766 sha1 ee86a28cf271be43739e406135e4d8bd4edf7686 ) -) - game ( name "Zelda no Densetsu - Yume o Miru Shima (Japan)" description "Zelda no Densetsu - Yume o Miru Shima (Japan)" @@ -34266,12 +34156,6 @@ game ( rom ( name "Zelda no Densetsu - Yume o Miru Shima (Japan) (Rev 1) (Demo) (Special Version).gb" size 524288 crc bcc0199a sha1 5fc7b8185096c4203536e0d8a302064e63511086 ) ) -game ( - name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" - description "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" - rom ( name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl).gb" size 2097152 crc 0b10adaf sha1 12f9ba0a4673dd2f59ba38e636332333a199dea5 ) -) - game ( name "Zen - Intergalactic Ninja (Europe)" description "Zen - Intergalactic Ninja (Europe)" @@ -34333,9 +34217,9 @@ game ( ) game ( - name "Zoop (Japan)" - description "Zoop (Japan)" - rom ( name "Zoop (Japan).gb" size 65536 crc 10e1a10c sha1 89a74970761700d591c2affc47c9306f49d22ba8 ) + name "Zoop (Japan) (En)" + description "Zoop (Japan) (En)" + rom ( name "Zoop (Japan) (En).gb" size 65536 crc 10e1a10c sha1 89a74970761700d591c2affc47c9306f49d22ba8 ) ) game ( @@ -34362,11 +34246,1573 @@ game ( rom ( name "Zuigao Jimi (Top Secret) (Taiwan) (Unl).gb" size 65536 crc 46402abe sha1 7afcc6dd82bb236f1ebe01c9b5ccad4d713ccbcf ) ) +clrmamepro ( + name "Nintendo - Game Boy (Aftermarket)" + description "Nintendo - Game Boy (Aftermarket)" + version 20240809-004429 + author "aci68, akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, BitLooter, buckwheat, C. V. Reynolds, chillerecke, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, ElBarto, foxe, fuzzball, Gefflon, Hiccup, hking0036, InternalLoss, Jack, jimmsu, Just001Kim, kazumi213, leekindo, Lesserkuma, Madeline, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, Powerpuff, PPLToast, Psychofox11, psykopat, rarenight, relax, RetroUprising, rpg2813, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, xNo, xprism, xuom2" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + description "14 Juillet (World) (Fr) (Aftermarket) (Unl)" + rom ( name "14 Juillet (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 7b66bee4 sha1 02f387457a779cbd2f493e52743cd32c169c098e ) +) + +game ( + name "Adulting! (World) (v2.0) (Aftermarket) (Unl)" + description "Adulting! (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Adulting! (World) (v2.0) (Aftermarket) (Unl).gb" size 524288 crc e56d1244 sha1 d107bd8bf32d0d94a988466885fe1a44aae32c9a flags verified ) +) + +game ( + name "Alley (World) (Aftermarket) (Unl)" + description "Alley (World) (Aftermarket) (Unl)" + rom ( name "Alley (World) (Aftermarket) (Unl).gb" size 32768 crc 2a26f8dd sha1 34bc4f54c0577f55bd40ce1155b6cc74a72ec4e2 ) +) + +game ( + name "Alphamax (World) (Aftermarket) (Unl)" + description "Alphamax (World) (Aftermarket) (Unl)" + rom ( name "Alphamax (World) (Aftermarket) (Unl).gb" size 131072 crc 8b493b41 sha1 798dda34d04a06dcee32f44f8a4a045caf734927 ) +) + +game ( + name "Anctrayl (World) (Aftermarket) (Unl)" + description "Anctrayl (World) (Aftermarket) (Unl)" + rom ( name "Anctrayl (World) (Aftermarket) (Unl).gb" size 65536 crc c6eca93a sha1 403a40761eec80cf7938bcae3a6deeaf17838311 ) +) + +game ( + name "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl)" + description "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl)" + rom ( name "Another Push Game (World) (v1.07) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 8c40cbc9 sha1 6b84d7322d30e9c06a4fdac0050f2c22babaaa7d ) +) + +game ( + name "Aqua (World) (v1.1) (Aftermarket) (Unl)" + description "Aqua (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Aqua (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc f9ad0e12 sha1 cb5871dc5bca8b6fd5888b9d3a591fbfe082c11d ) +) + +game ( + name "Aqua (World) (v1.0) (Aftermarket) (Unl)" + description "Aqua (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Aqua (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc 561aa835 sha1 311728bfcc1c4f51842f9da5022187e749e35045 ) +) + +game ( + name "Art School Pocket (World) (En) (Aftermarket) (Unl)" + description "Art School Pocket (World) (En) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (En) (Aftermarket) (Unl).gb" size 1048576 crc b4eab528 sha1 c482cfc6ec40b1f33c4ba48ecdc45fef4730b653 ) +) + +game ( + name "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Es) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Es) (Aftermarket) (Unl).gb" size 1048576 crc 240067df sha1 c8a75895c87b11f9493f629c19c54d0c607505bd ) +) + +game ( + name "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + description "Art School Pocket (World) (Fr) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (Fr) (Aftermarket) (Unl).gb" size 1048576 crc 49a5b74d sha1 73ecffaee185eb2caf1db385d04b863676c777fb ) +) + +game ( + name "Art School Pocket (World) (De) (Aftermarket) (Unl)" + description "Art School Pocket (World) (De) (Aftermarket) (Unl)" + rom ( name "Art School Pocket (World) (De) (Aftermarket) (Unl).gb" size 1048576 crc 82b73e5b sha1 7772e2b9d5e722e54d19fc6283ccb1fa5d19b641 ) +) + +game ( + name "Asteroids Chasers (World) (Aftermarket) (Unl)" + description "Asteroids Chasers (World) (Aftermarket) (Unl)" + rom ( name "Asteroids Chasers (World) (Aftermarket) (Unl).gb" size 131072 crc 58d8b1b8 sha1 f93a4e6788eaf0231a6ca269cca297f0d45ec830 flags verified ) +) + +game ( + name "Astro-Jump (World) (Aftermarket) (Unl)" + description "Astro-Jump (World) (Aftermarket) (Unl)" + rom ( name "Astro-Jump (World) (Aftermarket) (Unl).gb" size 262144 crc c35a3b39 sha1 1bcb4be684626ce061aad105701548fa3a77e254 ) +) + +game ( + name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Athletic World (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc afc128f2 sha1 956be9371990b18e351f2e10848b2ea8bb70c2b7 ) +) + +game ( + name "Auto Zone (World) (Aftermarket) (Unl)" + description "Auto Zone (World) (Aftermarket) (Unl)" + rom ( name "Auto Zone (World) (Aftermarket) (Unl).gb" size 524288 crc cee73c14 sha1 3070ec215014633dac5dbbb487aade2e2993c049 ) +) + +game ( + name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + description "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl)" + rom ( name "Binding of Isaac, The - Game Boy Edition (World) (Aftermarket) (Unl).gb" size 32768 crc bf922249 sha1 187782720d4f7c0986a0d916b0c7efa2c488612e ) +) + +game ( + name "Birdie Bartender (World) (Aftermarket) (Unl)" + description "Birdie Bartender (World) (Aftermarket) (Unl)" + rom ( name "Birdie Bartender (World) (Aftermarket) (Unl).gb" size 262144 crc 0bf2a1c8 sha1 aa1325fc7160b84745b076de9b976a1b368da50e ) +) + +game ( + name "Black Castle (World) (Aftermarket) (Unl)" + description "Black Castle (World) (Aftermarket) (Unl)" + rom ( name "Black Castle (World) (Aftermarket) (Unl).gb" size 65536 crc 10f577c7 sha1 45d979be572bb820835d2ecd4e990cd1eadbf5a6 ) +) + +game ( + name "Blitz Bomber (World) (Aftermarket) (Unl)" + description "Blitz Bomber (World) (Aftermarket) (Unl)" + rom ( name "Blitz Bomber (World) (Aftermarket) (Unl).gb" size 262144 crc 5e9956de sha1 b72cbc6bfa6ceef940f49c9c82024071c6f82b90 ) +) + +game ( + name "Blockade (World) (Aftermarket) (Unl)" + description "Blockade (World) (Aftermarket) (Unl)" + rom ( name "Blockade (World) (Aftermarket) (Unl).gb" size 262144 crc b8cfab16 sha1 9e753048a0eb036ac17c08f5a64d860abd1aaaf5 ) +) + +game ( + name "Bork Paw Kisses (World) (Aftermarket) (Unl)" + description "Bork Paw Kisses (World) (Aftermarket) (Unl)" + rom ( name "Bork Paw Kisses (World) (Aftermarket) (Unl).gb" size 262144 crc c29f0d35 sha1 8f1efe6982d2b4ebc1fbeb3ade68dd9b9aabb7a6 ) +) + +game ( + name "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + description "Borruga - Neo Pinball (World) (Aftermarket) (Unl)" + rom ( name "Borruga - Neo Pinball (World) (Aftermarket) (Unl).gb" size 32768 crc 2bb55ca5 sha1 269f12091d5ab87362a2cb2cf5484f14bfcbd537 flags verified ) +) + +game ( + name "Bounce (World) (v1.1) (Aftermarket) (Unl)" + description "Bounce (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Bounce (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 827f2bd5 sha1 e9abf64de3faeb48151003ac8bb77dea61e838b5 ) +) + +game ( + name "Bouncing Ball, The (World) (Aftermarket) (Unl)" + description "Bouncing Ball, The (World) (Aftermarket) (Unl)" + rom ( name "Bouncing Ball, The (World) (Aftermarket) (Unl).gb" size 65536 crc 42ddf53e sha1 5d331f2e66d7d3f4b4b0fcbaf6ab4b1a0147db3e ) +) + +game ( + name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + description "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl)" + rom ( name "Bourgogne Game Show 2022 (World) (Aftermarket) (Unl).gb" size 262144 crc 98222a4a sha1 0bdb8ad04469a329c8cee2fb0c55da35f7752042 ) +) + +game ( + name "Breakout Lava-Lamp (World) (Aftermarket) (Unl)" + description "Breakout Lava-Lamp (World) (Aftermarket) (Unl)" + rom ( name "Breakout Lava-Lamp (World) (Aftermarket) (Unl).gb" size 32768 crc 7fbe9fb7 sha1 9de08cdb4cdab58c79e0f2bdaef8b8bb736b9c50 ) +) + +game ( + name "Brimstone (World) (Demo) (Aftermarket) (Unl)" + description "Brimstone (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Brimstone (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc f18f44a6 sha1 f193af733f6dfdf8d4403be1d9caa67d7e6f3c37 ) +) + +game ( + name "Bug Bites! (World) (Aftermarket) (Unl)" + description "Bug Bites! (World) (Aftermarket) (Unl)" + rom ( name "Bug Bites! (World) (Aftermarket) (Unl).gb" size 262144 crc bb473d7a sha1 8d601612ac262e4548d8b8f6ac19a04cb92ecfb7 ) +) + +game ( + name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" + description "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl)" + rom ( name "Busty Bunny the Bounty Babe (World) (v1.02) (Aftermarket) (Unl).gb" size 1048576 crc d0ed199c sha1 a1cbaacdf32cb8fb9a9c59fcb624c729e0ca17bf ) +) + +game ( + name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Castledark (World) (v2.0) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 3c492b31 sha1 0861af0039dab4b4f5bce747c6fcd586eced401a ) +) + +game ( + name "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl)" + description "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl)" + rom ( name "Cat and His Boy, A (World) (En,Es) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 11043693 sha1 4db27714c7af6041d5af3cf550e78d7235394afa ) +) + +game ( + name "Cave Fighter (World) (Aftermarket) (Unl)" + description "Cave Fighter (World) (Aftermarket) (Unl)" + rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gb" size 262144 crc e8f91f6a sha1 290048717d0a8cabb3cc591161339550eb53c161 ) +) + +game ( + name "Cel Story (World) (Aftermarket) (Unl)" + description "Cel Story (World) (Aftermarket) (Unl)" + rom ( name "Cel Story (World) (Aftermarket) (Unl).gb" size 524288 crc 8a456b61 sha1 730627b2298806e4f7e02dceffaa0f0edfc316f0 ) +) + +game ( + name "Cel Story (World) (Demo) (Aftermarket) (Unl)" + description "Cel Story (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Cel Story (World) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 92a9b588 sha1 70ab2b72b26c1d1cacc13d377984b969ddf44965 ) +) + +game ( + name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + description "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Cheesy Town (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 3e20c1a8 sha1 f76645a2830fcc733b7392a52112df628f0b7a4a ) +) + +game ( + name "Cherry Rescue! (World) (Aftermarket) (Unl)" + description "Cherry Rescue! (World) (Aftermarket) (Unl)" + rom ( name "Cherry Rescue! (World) (Aftermarket) (Unl).gb" size 524288 crc ba65812a sha1 740dba1827c730cc5d8bf67495bcede3a5352643 ) +) + +game ( + name "Christmas Carols (World) (Aftermarket) (Unl)" + description "Christmas Carols (World) (Aftermarket) (Unl)" + rom ( name "Christmas Carols (World) (Aftermarket) (Unl).gb" size 262144 crc a00bb310 sha1 e19b0a698d8194467d57c00664f00f9898ee5368 ) +) + +game ( + name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 2165f2e4 sha1 f8e5020298183c3f47836da3890b6bb398e2ecab ) +) + +game ( + name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 6afee818 sha1 602709c8655febb42899881a8ef598fb4b3da0c9 ) +) + +game ( + name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (v2.1) (Aftermarket) (Unl).gb" size 1048576 crc 225ce296 sha1 45aebfe4e7f5382a4b31c3db270b75d2c458d1b2 ) +) + +game ( + name "Ciao Nonna (World) (Aftermarket) (Unl)" + description "Ciao Nonna (World) (Aftermarket) (Unl)" + rom ( name "Ciao Nonna (World) (Aftermarket) (Unl).gb" size 1048576 crc dd7576d6 sha1 0556eb6160fdca6e7959bba1a619b8e34d974375 ) +) + +game ( + name "Coat Man (World) (Aftermarket) (Unl)" + description "Coat Man (World) (Aftermarket) (Unl)" + rom ( name "Coat Man (World) (Aftermarket) (Unl).gb" size 262144 crc db882ef2 sha1 242f4b3e04fe00b514544c5ef14288d13b5faf2c ) +) + +game ( + name "Commando (World) (Aftermarket) (Unl)" + description "Commando (World) (Aftermarket) (Unl)" + rom ( name "Commando (World) (Aftermarket) (Unl).gb" size 262144 crc 48173941 sha1 c861858e9f2cf7470e739c26ae9f17d3834ce464 ) +) + +game ( + name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" + description "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl)" + rom ( name "Cosmic Courier - Trapped in Limbo (World) (Aftermarket) (Unl).gb" size 262144 crc fd304687 sha1 7df11ec2946099d49dd62928118b6d76703dc57c ) +) + +game ( + name "Coucou (World) (Aftermarket) (Unl)" + description "Coucou (World) (Aftermarket) (Unl)" + rom ( name "Coucou (World) (Aftermarket) (Unl).gb" size 32768 crc e6aabd72 sha1 5283268e3640e2924d00aea3b12b2d3930bef43c ) +) + +game ( + name "Counting Sheep (World) (Aftermarket) (Unl)" + description "Counting Sheep (World) (Aftermarket) (Unl)" + rom ( name "Counting Sheep (World) (Aftermarket) (Unl).GB" size 65536 crc 6e97c837 sha1 e7e251ad86fa00803837cf871de62d3f100c83ce ) +) + +game ( + name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gb" size 262144 crc 10838580 sha1 c740bc995adf2bb638bb125a36edc416558fd4c6 ) +) + +game ( + name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + description "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl)" + rom ( name "Cyber Dreamscape Battle-Deckers 2199 (World) (Aftermarket) (Unl).gb" size 1048576 crc e3a78253 sha1 45c9c6a7a4ec985146a4a616a49dba45decc6d3e ) +) + +game ( + name "Cyberlice (World) (Proto) (Aftermarket) (Unl)" + description "Cyberlice (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Cyberlice (World) (Proto) (Aftermarket) (Unl).gb" size 131072 crc 7e443267 sha1 220219db1870c3c0a562319aab9f1316b2863689 ) +) + +game ( + name "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + description "Dangan GB (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 5359d6db sha1 10029774046dabec2d8c0533caf94091f6e19071 ) +) + +game ( + name "Dangan GB (World) (Aftermarket) (Unl)" + description "Dangan GB (World) (Aftermarket) (Unl)" + rom ( name "Dangan GB (World) (Aftermarket) (Unl).gb" size 262144 crc daa59c9c sha1 8375d845fcfe4c236cd68f3d56a290f8c7b76c06 ) +) + +game ( + name "Dash (World) (Aftermarket) (Unl)" + description "Dash (World) (Aftermarket) (Unl)" + rom ( name "Dash (World) (Aftermarket) (Unl).gb" size 262144 crc 73868683 sha1 c1ffe7c25a34d65ed166293bc7d2b48b65ca922b ) +) + +game ( + name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.3.8) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.3.8) (Aftermarket) (Unl).gb" size 1048576 crc 7da95971 sha1 23cff594ef4b0bb21883b422940526c7fe81f1fd flags verified ) +) + +game ( + name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.2.5) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.2.5) (Aftermarket) (Unl).gb" size 1048576 crc 9e2bf649 sha1 3feeba5c438880f70cdfdc4ea7e29f77e645e9be flags verified ) +) + +game ( + name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + description "Deadeus (World) (v1.1.0) (Aftermarket) (Unl)" + rom ( name "Deadeus (World) (v1.1.0) (Aftermarket) (Unl).gb" size 1048576 crc 818a7db7 sha1 43a93dc6f7bef002271e583edaeaf2e7162b8af4 ) +) + +game ( + name "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" + description "Deep Forest (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Deep Forest (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 3ddf177d sha1 517302d20cb5140975e6cd1b3c495786b6390aaf ) +) + +game ( + name "DiaMaze (World) (Aftermarket) (Unl)" + description "DiaMaze (World) (Aftermarket) (Unl)" + rom ( name "DiaMaze (World) (Aftermarket) (Unl).gb" size 262144 crc 956fa901 sha1 f41b98ac4669920ffede1736ddbd9e1f62d4cb0d ) +) + +game ( + name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + description "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl)" + rom ( name "Dijon Gameboy (World) (En,Fr) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc b230b782 sha1 f1796dcbfb6f0f5e01c60222c376cc1c46945806 ) +) + +game ( + name "Dino's Offline Adventure (World) (Aftermarket) (Unl)" + description "Dino's Offline Adventure (World) (Aftermarket) (Unl)" + rom ( name "Dino's Offline Adventure (World) (Aftermarket) (Unl).gb" size 32768 crc d6bd0e6a sha1 6d11c145606f8e7ab25b2b07c299e36c8b442d23 ) +) + +game ( + name "DMG Deals Damage (World) (Aftermarket) (Unl)" + description "DMG Deals Damage (World) (Aftermarket) (Unl)" + rom ( name "DMG Deals Damage (World) (Aftermarket) (Unl).gb" size 32768 crc 250e0cbd sha1 a15539199e4b6bd2a71d1ac0e7c61ae4f19a65e7 flags verified ) +) + +game ( + name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc f339fa82 sha1 bdbc082017bdf2e4caa84e7d00dad9707727e9d4 ) +) + +game ( + name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Aftermarket) (Unl).gb" size 1048576 crc cfb44d68 sha1 6dde71bbec8b807af5132d1ef2e99c6bb6af3a1c ) +) + +game ( + name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.4) (Web) (Aftermarket) (Unl).gb" size 1048576 crc 62e0c3a2 sha1 e1b516e472e0c681b4ad1c7f4aeda55c91e7f340 ) +) + +game ( + name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" + description "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (Fr) (v1.4.2) (Aftermarket) (Unl).gb" size 1048576 crc e393d4aa sha1 d45dfcab4a76b62ea1e10730d01f755e12137484 ) +) + +game ( + name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + description "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl)" + rom ( name "Do I Pass (World) (En) (v1.5) (Aftermarket) (Unl).gb" size 1048576 crc 3890e0a4 sha1 6998e1bbf2ccb9db3d661ddac2d7edf7571d0af7 ) +) + +game ( + name "Dog's Muck Island (World) (Aftermarket) (Unl)" + description "Dog's Muck Island (World) (Aftermarket) (Unl)" + rom ( name "Dog's Muck Island (World) (Aftermarket) (Unl).gb" size 262144 crc 79a7a06c sha1 eb4cea3b9db770bf3b586578af1ad7427d88ee8e ) +) + +game ( + name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + description "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Don't Call Me Mama But Yes I Am Your Mama (World) (v2.0) (Aftermarket) (Unl).gb" size 1048576 crc 83247308 sha1 4579eaa45e2bf8f17f4dc99bdfb0b98270b871f5 ) +) + +game ( + name "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + description "Dragon Battle (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dragon Battle (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc c1e1e52c sha1 c5ac56e266c421a1c5b82de46859a44f75d03359 ) +) + +game ( + name "Dragonborne (World) (Aftermarket) (Unl)" + description "Dragonborne (World) (Aftermarket) (Unl)" + rom ( name "Dragonborne (World) (Aftermarket) (Unl).gb" size 2097152 crc 0ae28712 sha1 e3cd09069ee59ed3f7915a79af0667de4ebd7d50 ) +) + +game ( + name "Dragonborne (World) (Demo) (Aftermarket) (Unl)" + description "Dragonborne (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dragonborne (World) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc eda66890 sha1 3a5bcd9daa830842da60d8ebf35fa7036a259d76 ) +) + +game ( + name "Duck (World) (Aftermarket) (Unl)" + description "Duck (World) (Aftermarket) (Unl)" + rom ( name "Duck (World) (Aftermarket) (Unl).gb" size 32768 crc 583691fd sha1 f7eccfb9ade282423db6122882adcef6fbf3e955 ) +) + +game ( + name "Elden Ring GB (World) (Aftermarket) (Unl)" + description "Elden Ring GB (World) (Aftermarket) (Unl)" + rom ( name "Elden Ring GB (World) (Aftermarket) (Unl).gb" size 524288 crc e7a420f3 sha1 2e0bec6acf1a94ae3f2f6cf2040323862933d95a ) +) + +game ( + name "ever - Lucid Space Program (World) (Aftermarket) (Unl)" + description "ever - Lucid Space Program (World) (Aftermarket) (Unl)" + rom ( name "ever - Lucid Space Program (World) (Aftermarket) (Unl).gb" size 262144 crc a5006140 sha1 051a1b8739c820424fad5103b64e578dd9a5b841 ) +) + +game ( + name "F-Zero - Project (World) (Aftermarket) (Unl)" + description "F-Zero - Project (World) (Aftermarket) (Unl)" + rom ( name "F-Zero - Project (World) (Aftermarket) (Unl).gb" size 1048576 crc 4c707059 sha1 5b823ee17691d286a45f0667cddd59ccaaab5d8b ) +) + +game ( + name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + description "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl)" + rom ( name "Fairy-chan (World) (v0.1.4) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 4f04cdfc sha1 591980cb5e17104d826c2a915f53bfc8a21affca ) +) + +game ( + name "Farm, The (World) (Aftermarket) (Unl)" + description "Farm, The (World) (Aftermarket) (Unl)" + rom ( name "Farm, The (World) (Aftermarket) (Unl).gb" size 524288 crc fbc1b5e8 sha1 d0fe06920f7e771d76507f60881904370ffbc145 ) +) + +game ( + name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + description "Final Fantasy XI Adventure (World) (Aftermarket) (Unl)" + rom ( name "Final Fantasy XI Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc 6cfb4669 sha1 339fd673509a5ac8f25426af25b4ccc96e8d2880 ) +) + +game ( + name "Finders Keepers (World) (Aftermarket) (Unl)" + description "Finders Keepers (World) (Aftermarket) (Unl)" + rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gb" size 524288 crc 6a98ac61 sha1 e40dd804388df8c08d3890d79eeafd8542cc8805 ) +) + +game ( + name "FlappyBird GB (World) (Aftermarket) (Unl)" + description "FlappyBird GB (World) (Aftermarket) (Unl)" + rom ( name "FlappyBird GB (World) (Aftermarket) (Unl).gb" size 131072 crc 51aa9cc2 sha1 8f2b803fdd737c9885b96d11622008f706061e00 ) +) + +game ( + name "Fly O'Clock (World) (Aftermarket) (Unl)" + description "Fly O'Clock (World) (Aftermarket) (Unl)" + rom ( name "Fly O'Clock (World) (Aftermarket) (Unl).gb" size 32768 crc 93df7f55 sha1 83dc8498bdbabc14a8f81a715c9da19970c1f0b9 ) +) + +game ( + name "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl)" + description "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Footballer of the Year (World) (v1.1) (Aftermarket) (Unl).gb" size 1048576 crc 6e6ce1bb sha1 44166b7e6e8411ae61f37c7a78e90acaae66bcc5 ) +) + +game ( + name "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl)" + description "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Footballer of the Year (World) (v1.0) (Aftermarket) (Unl).gb" size 1048576 crc 91faa9b1 sha1 b7542729c8665a1a2af47f58fc59cc90f66fd77d ) +) + +game ( + name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + description "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl)" + rom ( name "Fydo's Magic Tiles (World) (2022-09-01) (Aftermarket) (Unl).gb" size 32768 crc 36e2ca02 sha1 fd985703b296dd0bf74225c72155ea9e51dd6853 ) +) + +game ( + name "G-Man (World) (Aftermarket) (Unl)" + description "G-Man (World) (Aftermarket) (Unl)" + rom ( name "G-Man (World) (Aftermarket) (Unl).gb" size 524288 crc 7296da69 sha1 fdc9933d46a063575c175453b1da8042fd28b135 ) +) + +game ( + name "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" + description "G-ZERO (World) (v2.6) (Aftermarket) (Unl)" + rom ( name "G-ZERO (World) (v2.6) (Aftermarket) (Unl).gb" size 65536 crc 7dd0c878 sha1 929d25a612308614ac3ac2ee5a19a9cd4a9968d6 ) +) + +game ( + name "GameBoy WORDLE (World) (Aftermarket) (Unl)" + description "GameBoy WORDLE (World) (Aftermarket) (Unl)" + rom ( name "GameBoy WORDLE (World) (Aftermarket) (Unl).gb" size 32768 crc cc971c0f sha1 ba93939b93ab3f3aa5f7aa451d50d9b89220adbc ) +) + +game ( + name "Genesis (World) (Aftermarket) (Unl)" + description "Genesis (World) (Aftermarket) (Unl)" + rom ( name "Genesis (World) (Aftermarket) (Unl).gb" size 65536 crc 74b3ec78 sha1 ca43f82d73ba0b3e43ec17f6bc6761c09ca23626 ) +) + +game ( + name "Genesis II (World) (Demo) (Aftermarket) (Unl)" + description "Genesis II (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Genesis II (World) (Demo) (Aftermarket) (Unl).gb" size 262144 crc d7aec1cc sha1 9700ea1278850df004ded7553253cfdd354f4ada ) +) + +game ( + name "Ghost Town (World) (Aftermarket) (Unl)" + description "Ghost Town (World) (Aftermarket) (Unl)" + rom ( name "Ghost Town (World) (Aftermarket) (Unl).gb" size 262144 crc 2d27cdf2 sha1 af526273cdaa6423b92d0484fb27af56fe355a5d ) +) + +game ( + name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.1) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4b19366d sha1 77f3b561bf28a81f38dbedc351752e10ff4c23dc ) +) + +game ( + name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + description "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl)" + rom ( name "Glory Hunters - Chapter 1 (World) (v0.2) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 3f34ff66 sha1 a0bff49b6917186d27dc24773da0674a18a6212c ) +) + +game ( + name "Great Detention Getaway, The (World) (Aftermarket) (Unl)" + description "Great Detention Getaway, The (World) (Aftermarket) (Unl)" + rom ( name "Great Detention Getaway, The (World) (Aftermarket) (Unl).gb" size 131072 crc 13b72ee4 sha1 efc3208cb99f9fb213875acd7b9b6c2e633b696a ) +) + +game ( + name "Gun Law (World) (Aftermarket) (Unl)" + description "Gun Law (World) (Aftermarket) (Unl)" + rom ( name "Gun Law (World) (Aftermarket) (Unl).gb" size 262144 crc b0d53211 sha1 ef6e3d287e99bd61861a333165c92b306238a45f ) +) + +game ( + name "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + description "Gunman Clive (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Gunman Clive (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc 11f5fded sha1 ec03763db2c0d754e2eb7e98384ed92fc8aeeb1d ) +) + +game ( + name "Gunship (World) (Aftermarket) (Unl)" + description "Gunship (World) (Aftermarket) (Unl)" + rom ( name "Gunship (World) (Aftermarket) (Unl).gb" size 131072 crc bd31eef8 sha1 a801977c3746799cfb4d8bdfd679e45cccd3b719 ) +) + +game ( + name "Harbour Attack (World) (Aftermarket) (Unl)" + description "Harbour Attack (World) (Aftermarket) (Unl)" + rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 4018ebf7 sha1 5bbbe727ebc6a489f1a498d067e4f05d0d69b60f ) +) + +game ( + name "Heart Knight (World) (Aftermarket) (Unl)" + description "Heart Knight (World) (Aftermarket) (Unl)" + rom ( name "Heart Knight (World) (Aftermarket) (Unl).gb" size 32768 crc c7ecac73 sha1 dedcab41f58c58834e3534e877c494669a0d8952 ) +) + +game ( + name "Hermano (World) (v1.1) (Aftermarket) (Unl)" + description "Hermano (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Hermano (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 74a0419b sha1 c42cfe91a1ec593a76291e031c47137bd794ffda ) +) + +game ( + name "Hugo (World) (Aftermarket) (Unl)" + description "Hugo (World) (Aftermarket) (Unl)" + rom ( name "Hugo (World) (Aftermarket) (Unl).gb" size 262144 crc 8cc87f60 sha1 53fac2774b29a32501788e1eac65db23bf5c7b8f ) +) + +game ( + name "If (World) (Aftermarket) (Unl)" + description "If (World) (Aftermarket) (Unl)" + rom ( name "If (World) (Aftermarket) (Unl).gb" size 1048576 crc be7e4454 sha1 c11d8dc9ce96133f679678b07822a82f985e16f9 ) +) + +game ( + name "Impossible Gameboy (World) (Aftermarket) (Unl)" + description "Impossible Gameboy (World) (Aftermarket) (Unl)" + rom ( name "Impossible Gameboy (World) (Aftermarket) (Unl).gb" size 131072 crc ab65b738 sha1 d31cedd6227b23cf3d8ef81c73f133ab0b57e4f4 ) +) + +game ( + name "Interblocked (World) (Aftermarket) (Unl)" + description "Interblocked (World) (Aftermarket) (Unl)" + rom ( name "Interblocked (World) (Aftermarket) (Unl).gb" size 262144 crc 5c208855 sha1 8e46486533a3de9ee87cc07bf8efaf818752a61a ) +) + +game ( + name "Into the Blue (World) (Aftermarket) (Unl)" + description "Into the Blue (World) (Aftermarket) (Unl)" + rom ( name "Into the Blue (World) (Aftermarket) (Unl).gb" size 131072 crc 7714e96e sha1 5ac7a349bb37c8767c9db264ed8ae7b7647fa8ea ) +) + +game ( + name "Island, The (World) (Demo) (Aftermarket) (Unl)" + description "Island, The (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Island, The (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc d6a43a64 sha1 38419c50713b4e403b80f1da151a3e9d0654d47c ) +) + +game ( + name "Jabberwocky (World) (Aftermarket) (Unl)" + description "Jabberwocky (World) (Aftermarket) (Unl)" + rom ( name "Jabberwocky (World) (Aftermarket) (Unl).gb" size 1048576 crc cfc51717 sha1 b4e447f2197688c740a45dce27879a62c742fb96 ) +) + +game ( + name "Jane in the Jungle (World) (Aftermarket) (Unl)" + description "Jane in the Jungle (World) (Aftermarket) (Unl)" + rom ( name "Jane in the Jungle (World) (Aftermarket) (Unl).gb" size 262144 crc c68e751a sha1 dfc65dcf700a26b273d705b7cfececbc44b80587 ) +) + +game ( + name "Jet Set Willy (World) (Aftermarket) (Unl)" + description "Jet Set Willy (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gb" size 262144 crc 1686d7ed sha1 0e594224506fd087e36c66bb66905d4c91b02461 ) +) + +game ( + name "Joe Blade 2 (World) (Aftermarket) (Unl)" + description "Joe Blade 2 (World) (Aftermarket) (Unl)" + rom ( name "Joe Blade 2 (World) (Aftermarket) (Unl).gb" size 524288 crc 09f75c70 sha1 f001dffcd16be670c36a98dd9136f6f9fbf5b85d ) +) + +game ( + name "Jumpy (World) (Aftermarket) (Unl)" + description "Jumpy (World) (Aftermarket) (Unl)" + rom ( name "Jumpy (World) (Aftermarket) (Unl).gb" size 262144 crc 70f9af24 sha1 29152d8874c2a048f71e0be86aa9ee2d77996fb6 ) +) + +game ( + name "Just Fishing (World) (Aftermarket) (Unl)" + description "Just Fishing (World) (Aftermarket) (Unl)" + rom ( name "Just Fishing (World) (Aftermarket) (Unl).gb" size 131072 crc c0f675fc sha1 3591b258afb94e0b4d9e095ecf702fc4de3061e3 ) +) + +game ( + name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" + description "Kenzie's Birthday Dash (World) (Aftermarket) (Unl)" + rom ( name "Kenzie's Birthday Dash (World) (Aftermarket) (Unl).gb" size 1048576 crc 986bfd75 sha1 6d15b5bc33d7c7771ba62d56ae7f25fa081bc564 ) +) + +game ( + name "Kitten's Getaway (World) (Es) (Aftermarket) (Unl)" + description "Kitten's Getaway (World) (Es) (Aftermarket) (Unl)" + rom ( name "Kitten's Getaway (World) (Es) (Aftermarket) (Unl).gb" size 262144 crc e621c535 sha1 a9e71e4a27e633e1649a131150c5811483b441d6 ) +) + +game ( + name "Krezber (World) (Aftermarket) (Unl)" + description "Krezber (World) (Aftermarket) (Unl)" + rom ( name "Krezber (World) (Aftermarket) (Unl).gb" size 65536 crc 27bddf77 sha1 2f4cffafc411b6895bf365b0773c4fa5d2ef7be3 ) +) + +game ( + name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + description "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl)" + rom ( name "Kudzu (World) (v0.96) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 0610049a sha1 a6fbe1a524547bebabc5e6b3baff1dff8f13dbd0 ) +) + +game ( + name "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl)" + description "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl)" + rom ( name "Kudzu (World) (v1.1c) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc 4462ff70 sha1 18a2a762d7b994865c845ac2aa0a0cf7655af74e flags verified ) +) + +game ( + name "Laser Squad Alter (World) (Aftermarket) (Unl)" + description "Laser Squad Alter (World) (Aftermarket) (Unl)" + rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gb" size 1048576 crc a39b3a5a sha1 1620e585e77a2457cffde82453bec0c7a04e07cf ) +) + +game ( + name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 2c430576 sha1 0e290b387a45b6ea85c6d49bf18bce3ce94951b7 ) +) + +game ( + name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.1.1) (Demo) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 5cf1a6f9 sha1 9fac1324e863f719674219eb41e45f1f745c67a9 ) +) + +game ( + name "Lawn Mower Land (World) (Aftermarket) (Unl)" + description "Lawn Mower Land (World) (Aftermarket) (Unl)" + rom ( name "Lawn Mower Land (World) (Aftermarket) (Unl).gb" size 32768 crc 11c62e39 sha1 1d6aa817ebf2a7e5d22285b906540272b67169da ) +) + +game ( + name "Leak, The (World) (Aftermarket) (Unl)" + description "Leak, The (World) (Aftermarket) (Unl)" + rom ( name "Leak, The (World) (Aftermarket) (Unl).GB" size 65536 crc ba3cfeae sha1 98de2d8be75e6d9cb4e87afe14b1380c033de797 ) +) + +game ( + name "Life's Too Short (World) (Aftermarket) (Unl)" + description "Life's Too Short (World) (Aftermarket) (Unl)" + rom ( name "Life's Too Short (World) (Aftermarket) (Unl).gb" size 262144 crc 458174cc sha1 7b704cd999cbeeb9991d675e2b1e67a906fa766d ) +) + +game ( + name "Linea, La (World) (Aftermarket) (Unl)" + description "Linea, La (World) (Aftermarket) (Unl)" + rom ( name "Linea, La (World) (Aftermarket) (Unl).gb" size 262144 crc c8750c01 sha1 00348fec54b5d3ebb762484bdcc015881bb9e95b ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc 9c4f03fd sha1 288cb53b4782df4409ee683e9aa11b4dd2a3a53e ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc e5988949 sha1 08d033c7ef20fd4d24d1f07b3ebb177fb9b78673 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 524288 crc 59568248 sha1 6571db155f6f25eeeec86d28b105bf8fef156322 ) +) + +game ( + name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 524288 crc a26345b8 sha1 641110cb187657fd15ea254440e1c74ab4a88856 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc d70f1d25 sha1 02e2fb6cbc5cff05ed775c9e1cd9acc07fa2e036 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Batteryless) (Aftermarket) (Unl).gb" size 131072 crc ae07c093 sha1 9f40b8719b3fdd2f7e6c59a4f616e9eb712d538d ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC3) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc 34671dc6 sha1 377d22d54e6e1fa4fcd4b4576d5886774f9f6c97 ) +) + +game ( + name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + description "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Little Tales of Alexandria, The - Mr Meows Dance Party! (World) (MBC5) (SGB Enhanced) (Aftermarket) (Unl).gb" size 131072 crc a8fb0d7a sha1 26803ba3413c7c52a8a58393f63472bc87ec3c6b ) +) + +game ( + name "Lost Knight (World) (Proto) (Aftermarket) (Unl)" + description "Lost Knight (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Lost Knight (World) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 5ddcc941 sha1 ca9003ead7ee153faf087a83c4bdef1d409c597b ) +) + +game ( + name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" + description "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl)" + rom ( name "Lucy and the Gem Dungeon (World) (Aftermarket) (Unl).gb" size 524288 crc 1a5106a2 sha1 f56c1b324b8c1e17da86e40c5e9a887ec19b0c80 ) +) + +game ( + name "Machine, The (World) (v1.0) (Aftermarket) (Unl)" + description "Machine, The (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (v1.0) (Aftermarket) (Unl).gb" size 2097152 crc b06036a9 sha1 50c5d1eb7c8946ac2d7e2c566b1ea4a9b0d58e90 ) +) + +game ( + name "Mad Monster (World) (Aftermarket) (Unl)" + description "Mad Monster (World) (Aftermarket) (Unl)" + rom ( name "Mad Monster (World) (Aftermarket) (Unl).gb" size 524288 crc c3fd371c sha1 9f4bea7ca7d26080110f54392314c60761236638 ) +) + +game ( + name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" + description "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl)" + rom ( name "Magipanels (World) (2022-02-09) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 76fcbc30 sha1 7a759372bd013dcdb59c9131a2908085fc04d648 ) +) + +game ( + name "Magipanels (World) (Aftermarket) (Unl)" + description "Magipanels (World) (Aftermarket) (Unl)" + rom ( name "Magipanels (World) (Aftermarket) (Unl).gb" size 131072 crc 0b66561b sha1 c9513f6769098f2185f632f87386788f0f0b6ad8 ) +) + +game ( + name "Mai Nurse (World) (v1.01) (Aftermarket) (Unl)" + description "Mai Nurse (World) (v1.01) (Aftermarket) (Unl)" + rom ( name "Mai Nurse (World) (v1.01) (Aftermarket) (Unl).gb" size 131072 crc 20d562b2 sha1 2d3b1dac701b518f9e5109dbc5e7d2bc8420dec3 ) +) + +game ( + name "Make Way (World) (Aftermarket) (Unl)" + description "Make Way (World) (Aftermarket) (Unl)" + rom ( name "Make Way (World) (Aftermarket) (Unl).gb" size 1048576 crc edeee5a8 sha1 19fd02e9318ed81ec968a2fca31ea0c3d8d94a7b ) +) + +game ( + name "Marron Helps a Friend (World) (Aftermarket) (Unl)" + description "Marron Helps a Friend (World) (Aftermarket) (Unl)" + rom ( name "Marron Helps a Friend (World) (Aftermarket) (Unl).gb" size 1048576 crc 08a3a987 sha1 adcd56fa3eba93edd20be25ae5cb349070cd0323 flags verified ) +) + +game ( + name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (v2.0) (Aftermarket) (Unl).gb" size 262144 crc dccaeb60 sha1 1e4fc83bfe9c9063975a3862770e4afee3f947a4 ) +) + +game ( + name "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + description "Marzipan Beef Reverser (World) (Aftermarket) (Unl)" + rom ( name "Marzipan Beef Reverser (World) (Aftermarket) (Unl).gb" size 131072 crc 4c3e0d15 sha1 6cbfb0390ee555718b5b0c3a5437b7d3d4ee0008 ) +) + +game ( + name "Meteorite (World) (Aftermarket) (Unl)" + description "Meteorite (World) (Aftermarket) (Unl)" + rom ( name "Meteorite (World) (Aftermarket) (Unl).gb" size 262144 crc 50cf593d sha1 0e88a47faf3273f87c1ead7f789faeb06d5333f3 ) +) + +game ( + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gb" size 262144 crc cb3a9ab8 sha1 31625a90b61d28ac782909ed8b00b3a48df7742e ) +) + +game ( + name "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" + description "Mona and the Witch's Hat (World) (Aftermarket) (Unl)" + rom ( name "Mona and the Witch's Hat (World) (Aftermarket) (Unl).gb" size 65536 crc 32ed7f4a sha1 625d3664d99dee075021b03ea6ff074ae2e49204 ) +) + +game ( + name "Monty on the Run (World) (Aftermarket) (Unl)" + description "Monty on the Run (World) (Aftermarket) (Unl)" + rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gb" size 524288 crc e2ebb406 sha1 41ac5993fbff58be0712b554aae5e4367b68677b ) +) + +game ( + name "Muncher (World) (Aftermarket) (Unl)" + description "Muncher (World) (Aftermarket) (Unl)" + rom ( name "Muncher (World) (Aftermarket) (Unl).gb" size 262144 crc 444d3d5e sha1 c3e09aff66c7e395bf95a1864963fbe979d5cb9b ) +) + +game ( + name "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl)" + description "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "My Husband is a WITCH (World) (v1.1) (Aftermarket) (Unl).gb" size 262144 crc 68801328 sha1 3b45dc8b655b688832a6b217c5cbc93a7a9f70cd ) +) + +game ( + name "My World (World) (Aftermarket) (Unl)" + description "My World (World) (Aftermarket) (Unl)" + rom ( name "My World (World) (Aftermarket) (Unl).gb" size 131072 crc 530b2edd sha1 ae29a721e6d1894e2faf736384737da7676e4fbc ) +) + +game ( + name "Neko Can Dream (World) (En) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (En) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (En) (Aftermarket) (Unl).gb" size 2097152 crc 6e76ef25 sha1 55686fde78d17d00adfc831eca2c699274a82273 ) +) + +game ( + name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (Ja) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc a0ad7a18 sha1 5fb1a09e04cf1704b059468de8855dfa7e23043b ) +) + +game ( + name "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl)" + description "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Neko Can Dream (World) (En) (Demo) (Aftermarket) (Unl).gb" size 2097152 crc dc011d07 sha1 43312b149355d20944e8a366584c69e5cb3be868 ) +) + +game ( + name "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Nocptern (World) (v1.0) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 118da307 sha1 33174a7727f6a1cc7c94b598ed6e9a4c2d1d410c ) +) + +game ( + name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (Alpha A) (Aftermarket) (Unl).gb" size 262144 crc d6166c62 sha1 fa2198c5308a15195adbda004f09646589860d11 ) +) + +game ( + name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - Betrayed (World) (v0.1.1) (Beta) (Aftermarket) (Unl).gb" size 1048576 crc 42b47080 sha1 08484b0f98e72d6577d9b7cde8c49908012d1fc5 ) +) + +game ( + name "Oblique Strategies (World) (Aftermarket) (Unl)" + description "Oblique Strategies (World) (Aftermarket) (Unl)" + rom ( name "Oblique Strategies (World) (Aftermarket) (Unl).gb" size 524288 crc 30eca8d3 sha1 6a09aabf30e2ebab2e31ae845cd2e8796c84797f ) +) + +game ( + name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Es) (Demo) (Aftermarket) (Unl).gb" size 524288 crc d3eba01d sha1 8cf234bbcb68ca2b676a4ccec89814b0cbce1c07 ) +) + +game ( + name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (En) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 71f34822 sha1 f24da97f44d280f27f8ebe3acdc33fea758d2255 ) +) + +game ( + name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + description "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl)" + rom ( name "Oiopolis (World) (Ca) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 76baab68 sha1 cd76da35541535dd244ad60d10eb998f7692f07a ) +) + +game ( + name "Olympic Skier (World) (Aftermarket) (Unl)" + description "Olympic Skier (World) (Aftermarket) (Unl)" + rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gb" size 524288 crc 93174431 sha1 7bcdf10533f8fe053e22534c4962ed4b1a5cf2e2 ) +) + +game ( + name "Opossum a la Mode (World) (Aftermarket) (Unl)" + description "Opossum a la Mode (World) (Aftermarket) (Unl)" + rom ( name "Opossum a la Mode (World) (Aftermarket) (Unl).gb" size 262144 crc 810477a9 sha1 3b6fb1311313687afebc4fb51f1b4befb5f47e1e ) +) + +game ( + name "Out on a Limb (World) (Aftermarket) (Unl)" + description "Out on a Limb (World) (Aftermarket) (Unl)" + rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gb" size 262144 crc be197f87 sha1 2ddc2378539316cf7a10e2cf8b562f17e1cf7a6a ) +) + +game ( + name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" + description "Panty Hunty (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Panty Hunty (World) (v1.4) (Aftermarket) (Unl).gb" size 524288 crc ce707b9a sha1 b5757b268a09d9085d469eda0676991f7361ad8c ) +) + +game ( + name "Parasol Islands (World) (Aftermarket) (Unl)" + description "Parasol Islands (World) (Aftermarket) (Unl)" + rom ( name "Parasol Islands (World) (Aftermarket) (Unl).gb" size 1048576 crc b1d79c80 sha1 381f76af67f77e575beae2f45aefd21f079709e6 ) +) + +game ( + name "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.2) (Aftermarket) (Unl).gb" size 32768 crc 866ac302 sha1 fa94f4d06eae2c49bbf1a654a8f658783dc6c28c ) +) + +game ( + name "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc 1bc5f8aa sha1 bf5601202eeca5b892ae4f3db7a4019cdb3bc99a ) +) + +game ( + name "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl)" + description "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Penguin Migrants (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc f6f681fa sha1 57b9cc41fc6d1e7cecf8ba2a1613d1fd126d97ad ) +) + +game ( + name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" + description "Perfect Blend (World) (v0.9) (Aftermarket) (Unl)" + rom ( name "Perfect Blend (World) (v0.9) (Aftermarket) (Unl).gb" size 262144 crc 9b4bacaa sha1 09b0691f6823c54f1515dd3b66f135ac45a7dbc3 ) +) + +game ( + name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" + description "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl)" + rom ( name "Perfect Blend (World) (v0.9) (Bugfix) (Aftermarket) (Unl).gb" size 262144 crc 1e8b2a29 sha1 a25dfc43408080ac116479fa55c9e7320e5cc82a ) +) + +game ( + name "Phobos Dere .GB (World) (Aftermarket) (Unl)" + description "Phobos Dere .GB (World) (Aftermarket) (Unl)" + rom ( name "Phobos Dere .GB (World) (Aftermarket) (Unl).gb" size 1048576 crc ae97f4f8 sha1 e541505078ee5e7e5c897b4621cc693ce71e35ba flags verified ) +) + +game ( + name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" + description "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl)" + rom ( name "Phobos Dere .GB (World) (2022-03-06) (Demo) (Aftermarket) (Unl).gb" size 262144 crc 58362b86 sha1 b4cc3c3735bc134e34b97e08ed24c57aef5c5ccf flags verified ) +) + +game ( + name "Pineapple Kid (World) (Aftermarket) (Unl)" + description "Pineapple Kid (World) (Aftermarket) (Unl)" + rom ( name "Pineapple Kid (World) (Aftermarket) (Unl).gb" size 131072 crc 9541488b sha1 fd574b5d407f3654db3227900a8ed7eff4fe48ae ) +) + +game ( + name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + description "Pineapple Kid (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Pineapple Kid (World) (Demo) (Aftermarket) (Unl).gb" size 131072 crc 9d9102d9 sha1 105e78f740d6bc517ef0079f867e9fdce8d012d2 ) +) + +game ( + name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + description "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl)" + rom ( name "Pixel Who - The Lost Legions (World) (Aftermarket) (Unl).gb" size 1048576 crc f41cf2a7 sha1 c07378c774602060f1f93f18fbfd3f0d552fe2d2 ) +) + +game ( + name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" + description "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Plants Eat My Zombies (World) (v1.1) (Aftermarket) (Unl).gb" size 524288 crc 60c84f2e sha1 c39ec5e6a9a0be0970b56e788c3f60e9821dbbd3 ) +) + +game ( + name "Pluto's Corner (World) (Aftermarket) (Unl)" + description "Pluto's Corner (World) (Aftermarket) (Unl)" + rom ( name "Pluto's Corner (World) (Aftermarket) (Unl).gb" size 65536 crc 21fc06b3 sha1 94e4a442205079d85d5ca37042eaec555f7f49db ) +) + +game ( + name "Pogo Pete (World) (Aftermarket) (Unl)" + description "Pogo Pete (World) (Aftermarket) (Unl)" + rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gb" size 262144 crc 185ce1d5 sha1 74021e84c1d095b2401302e26352e810dbc432d8 ) +) + +game ( + name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + description "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Popcorn Caravan (World) (Demo) (Aftermarket) (Unl).gb" size 65536 crc ead528f9 sha1 909d3421747d211a2dc70918d2c952db953e49b2 ) +) + +game ( + name "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" + description "Porklike (World) (v1.0.3) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.0.3) (Aftermarket) (Unl).gb" size 65536 crc 6c57e55e sha1 143f31656a5007f65b19d6e32967698bb8f72a66 ) +) + +game ( + name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.0.9) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 7aaa853a sha1 0868bffd52b2bdc5601ab6cf1e25f40924ca643d ) +) + +game ( + name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + description "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Porklike (World) (v1.05) (SGB Enhanced) (Aftermarket) (Unl).gb" size 65536 crc 801f097b sha1 5da110a88799765707e027bcedec0875a637509b ) +) + +game ( + name "Pull of the Void (World) (Aftermarket) (Unl)" + description "Pull of the Void (World) (Aftermarket) (Unl)" + rom ( name "Pull of the Void (World) (Aftermarket) (Unl).gb" size 262144 crc 69bfac8c sha1 df10665c8e79c587103d3de686b0261807819caf ) +) + +game ( + name "Purple Turtles (World) (Aftermarket) (Unl)" + description "Purple Turtles (World) (Aftermarket) (Unl)" + rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gb" size 262144 crc f7041a97 sha1 d2d7eff063104c8f205c192a902a53092c0b5f4a ) +) + +game ( + name "Pushingo (World) (Aftermarket) (Unl)" + description "Pushingo (World) (Aftermarket) (Unl)" + rom ( name "Pushingo (World) (Aftermarket) (Unl).gb" size 262144 crc a8541ed0 sha1 1ac1e22b191a95fdfa00c34ccba7387c991c827b ) +) + +game ( + name "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl)" + description "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl)" + rom ( name "Pyro la Chronoflamme (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 2abc6b14 sha1 a13e1f09e9d3921e544c3fc17daebbadc93921b7 ) +) + +game ( + name "Quick Draw (World) (Aftermarket) (Unl)" + description "Quick Draw (World) (Aftermarket) (Unl)" + rom ( name "Quick Draw (World) (Aftermarket) (Unl).gb" size 262144 crc 7704671f sha1 75f96ce54ed8739d58153780e9b573a65f1c5880 ) +) + +game ( + name "radioRealm (World) (Ja) (Aftermarket) (Unl)" + description "radioRealm (World) (Ja) (Aftermarket) (Unl)" + rom ( name "radioRealm (World) (Ja) (Aftermarket) (Unl).gb" size 131072 crc 71375a39 sha1 489c8835c36a08f1d76a0653bf6ede3bbf53043f ) +) + +game ( + name "Raffles (World) (Aftermarket) (Unl)" + description "Raffles (World) (Aftermarket) (Unl)" + rom ( name "Raffles (World) (Aftermarket) (Unl).gb" size 262144 crc 0b400a91 sha1 aadfe3fd0720696547b73b272354b592b96f98f7 ) +) + +game ( + name "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl)" + description "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl)" + rom ( name "Remute - Living Electronics (World) (Album) (Aftermarket) (Unl).gb" size 2097152 crc 1ced0a62 sha1 bc4bf12344d3b9d028a7013c84b94aea515be196 flags verified ) +) + +game ( + name "Retroid (World) (Aftermarket) (Unl)" + description "Retroid (World) (Aftermarket) (Unl)" + rom ( name "Retroid (World) (Aftermarket) (Unl).gb" size 262144 crc 9f759f25 sha1 4c7323d6a10852fe416c7bd581d6ffdd2d473bb5 ) +) + +game ( + name "Rewind Time (World) (Aftermarket) (Unl)" + description "Rewind Time (World) (Aftermarket) (Unl)" + rom ( name "Rewind Time (World) (Aftermarket) (Unl).gb" size 262144 crc d8ad184a sha1 903ef8074e58a52bc98dcb9e3f2c88b52fc1335b ) +) + +game ( + name "Rhythm Land (World) (Aftermarket) (Unl)" + description "Rhythm Land (World) (Aftermarket) (Unl)" + rom ( name "Rhythm Land (World) (Aftermarket) (Unl).gb" size 131072 crc 4312c7ff sha1 c79f26ce187edea18cf92be8340ec0a0c8beec87 ) +) + +game ( + name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" + description "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl)" + rom ( name "Rhythm Land (World) (v1.0.1) (Aftermarket) (Unl).gb" size 131072 crc fbf98400 sha1 1b831806d32e1ec35bc94a84384c6989433a274d ) +) + +game ( + name "Rig Attack (World) (Aftermarket) (Unl)" + description "Rig Attack (World) (Aftermarket) (Unl)" + rom ( name "Rig Attack (World) (Aftermarket) (Unl).gb" size 262144 crc dea8749d sha1 6f0fbac6b6c2e8f2d8df0a0a0e2f0c947e37b39a ) +) + +game ( + name "Robby's Day Out (World) (Aftermarket) (Unl)" + description "Robby's Day Out (World) (Aftermarket) (Unl)" + rom ( name "Robby's Day Out (World) (Aftermarket) (Unl).gb" size 262144 crc c3c89cd9 sha1 9d38b69ab9a4ff7bf387c88f2afed410d450f2e0 ) +) + +game ( + name "Roommate Simulator (World) (Aftermarket) (Unl)" + description "Roommate Simulator (World) (Aftermarket) (Unl)" + rom ( name "Roommate Simulator (World) (Aftermarket) (Unl).gb" size 131072 crc 3c95b1aa sha1 d5c99106c3bd4d46aeb75f513fd4314c19c734b2 ) +) + +game ( + name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + description "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl)" + rom ( name "Rosa Cupiditatis (World) (2023-05-17) (Demo) (Aftermarket) (Unl).gb" size 524288 crc 51d09337 sha1 9e935cca00cb4c3aad7b1dfce9fe59f5d913bdff ) +) + +game ( + name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.3) (Aftermarket) (Unl).gb" size 2097152 crc 6669f0be sha1 25bcf936e8dadb10d288473989891e4f2ec6c605 ) +) + +game ( + name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + description "Sacred Meat (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Sacred Meat (World) (v1.1) (Aftermarket) (Unl).gb" size 2097152 crc 1c4b7eb0 sha1 5cd15f4629fdbcfd6f752d89be755d5ac02b9435 ) +) + +game ( + name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Safe File (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 262144 crc 03f2dd1a sha1 78fe9c7cd6d0d7f1157c8c7716642d17c4b80303 ) +) + +game ( + name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + description "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl)" + rom ( name "Sam Mallard - The Case of the Missing Swan (World) (SGB Enhanced) (Aftermarket) (Unl).gb" size 1048576 crc 994a2edd sha1 0132f0311d8478d4f45b3b8e2728698570091d69 ) +) + +game ( + name "Severen (World) (Demo) (Aftermarket) (Unl)" + description "Severen (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Severen (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 642f2244 sha1 d9692aa569820db3f38458819cba21846a2e06f4 ) +) + +game ( + name "Shapeshifter, The (World) (Aftermarket) (Unl)" + description "Shapeshifter, The (World) (Aftermarket) (Unl)" + rom ( name "Shapeshifter, The (World) (Aftermarket) (Unl).gb" size 1048576 crc ef735794 sha1 179e69199f19b403b4c1a9675a3ee431ee570797 ) +) + +game ( + name "Shark Attack (World) (Aftermarket) (Unl)" + description "Shark Attack (World) (Aftermarket) (Unl)" + rom ( name "Shark Attack (World) (Aftermarket) (Unl).gb" size 262144 crc 3032025a sha1 6cc65bb719af53128bb04c9ee7c6abbf4ff1c3cf ) +) + +game ( + name "Sheep It Up (World) (Digital) (Aftermarket) (Unl)" + description "Sheep It Up (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Sheep It Up (World) (Digital) (Aftermarket) (Unl).gb" size 32768 crc fa6de2e4 sha1 9ad365ed7d4e07041c0147831a9bb1c496ea0bc8 ) +) + +game ( + name "Shock Lobster (World) (Aftermarket) (Unl)" + description "Shock Lobster (World) (Aftermarket) (Unl)" + rom ( name "Shock Lobster (World) (Aftermarket) (Unl).gb" size 32768 crc 7a0622e6 sha1 10c1816724cd6e332d2a5aeed4e546e7bd764ebf ) +) + +game ( + name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" + description "Shock Lobster (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Shock Lobster (World) (v1.3) (Aftermarket) (Unl).gb" size 32768 crc 8f244e86 sha1 7b8c8a9ec4758c6880598b9d508bc5805293dd87 ) +) + +game ( + name "Shootris (World) (Aftermarket) (Unl)" + description "Shootris (World) (Aftermarket) (Unl)" + rom ( name "Shootris (World) (Aftermarket) (Unl).gb" size 262144 crc 50180f64 sha1 5d978e6fc4bd5d9717d022360122458e95fffc29 ) +) + +game ( + name "Sloth Story (World) (Aftermarket) (Unl)" + description "Sloth Story (World) (Aftermarket) (Unl)" + rom ( name "Sloth Story (World) (Aftermarket) (Unl).gb" size 262144 crc c873f232 sha1 369d2afec4ffb59d4f3a59ee684c5bfec0b34ff8 ) +) + +game ( + name "Slurpee Cycle (World) (Aftermarket) (Unl)" + description "Slurpee Cycle (World) (Aftermarket) (Unl)" + rom ( name "Slurpee Cycle (World) (Aftermarket) (Unl).gb" size 131072 crc 8985031a sha1 1addff376e2734513406eca69a9c6679965faba9 ) +) + +game ( + name "Smickeonn - The Game (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game (World) (Aftermarket) (Unl).gb" size 524288 crc 93041fca sha1 e0981231d10aa8ea64eeaec1ff90210adf42ae05 ) +) + +game ( + name "Smickeonn 2 - The Game (World) (Aftermarket) (Unl)" + description "Smickeonn 2 - The Game (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn 2 - The Game (World) (Aftermarket) (Unl).gb" size 1048576 crc cd99b998 sha1 ac6b35af80c98ca5822e540a725b64a8c6dd5069 ) +) + +game ( + name "Snail, The (World) (v1.3) (Aftermarket) (Unl)" + description "Snail, The (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Snail, The (World) (v1.3) (Aftermarket) (Unl).gb" size 262144 crc 422a7b44 sha1 776f7578d747f935ebccda93d6487ffa4dc4bce3 ) +) + +game ( + name "Snakebird (World) (Aftermarket) (Unl)" + description "Snakebird (World) (Aftermarket) (Unl)" + rom ( name "Snakebird (World) (Aftermarket) (Unl).gb" size 131072 crc 4627f98e sha1 99cc82279d65b86b4366bf61db9bf67a78e051dc ) +) + +game ( + name "Snaky Pocket (World) (Aftermarket) (Unl)" + description "Snaky Pocket (World) (Aftermarket) (Unl)" + rom ( name "Snaky Pocket (World) (Aftermarket) (Unl).gb" size 32768 crc 7209370d sha1 f5eab31a499f33b3ae1f7b5b006dcca1df3ac2b9 ) +) + +game ( + name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + description "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Gala of Battle (World) (En,Ja) (Aftermarket) (Unl).gb" size 262144 crc 665ad70a sha1 c5b6eb610caa2213d8db7ab204bad44d60f7d63a ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-05-20) (Aftermarket) (Unl).gb" size 262144 crc feed93e0 sha1 721d78d4ef167acfcc00baf909db4c94d522d681 ) +) + +game ( + name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + description "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl)" + rom ( name "Song of Morus - Ghostly Night (World) (2023-06-08) (Aftermarket) (Unl).gb" size 262144 crc 6547e5c8 sha1 53a42f45b7ed368d7af9d41f2442fe463c26e545 ) +) + +game ( + name "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + description "Space Trouble (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Space Trouble (World) (Proto) (Aftermarket) (Unl).gb" size 524288 crc f015931c sha1 ec7bc27387d4d2ac01127bc24e1adf45b6ebc936 ) +) + +game ( + name "Spiky Harold (World) (Aftermarket) (Unl)" + description "Spiky Harold (World) (Aftermarket) (Unl)" + rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gb" size 524288 crc 2ac1b945 sha1 b8f37a64524bde4c2b6e9a1938ed6e5c0a5aad7c ) +) + +game ( + name "Star Catcher (World) (Aftermarket) (Unl)" + description "Star Catcher (World) (Aftermarket) (Unl)" + rom ( name "Star Catcher (World) (Aftermarket) (Unl).gb" size 131072 crc a14dffef sha1 22a2693db5266238751ba3ae2b8ea634bfbe78aa ) +) + +game ( + name "Stardiver (World) (Aftermarket) (Unl)" + description "Stardiver (World) (Aftermarket) (Unl)" + rom ( name "Stardiver (World) (Aftermarket) (Unl).gb" size 1048576 crc 25ff97f7 sha1 d609b8de2c7a61b7281fec5c761e3504aa4d94e9 ) +) + +game ( + name "Stick Man Guy (World) (Aftermarket) (Unl)" + description "Stick Man Guy (World) (Aftermarket) (Unl)" + rom ( name "Stick Man Guy (World) (Aftermarket) (Unl).gb" size 262144 crc 3a61fefc sha1 2f7351579e09ef29e067a69dfa3556448626d68e ) +) + +game ( + name "Super Connard (World) (Fr) (Aftermarket) (Unl)" + description "Super Connard (World) (Fr) (Aftermarket) (Unl)" + rom ( name "Super Connard (World) (Fr) (Aftermarket) (Unl).gb" size 32768 crc 9aaf301a sha1 6f4bf6c8206cc95cf17bea6739aa942034c2a230 ) +) + +game ( + name "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl)" + description "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl)" + rom ( name "Super Connard (World) (Fr) (Digital) (Aftermarket) (Unl).gb" size 32768 crc 7ebd22cd sha1 24264376aeee13d7f9b9424553f7fa4ba4b3b116 ) +) + +game ( + name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" + description "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl)" + rom ( name "Super Covid Go Get Biscuits Adventure (World) (Aftermarket) (Unl).gb" size 262144 crc 51946e8d sha1 cac4917d56da02cf88ba68e0c5189a18c2c234ac ) +) + +game ( + name "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl)" + description "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Super Hard Bouncer (World) (v1.1) (Aftermarket) (Unl).gb" size 32768 crc a653f726 sha1 09c242a4c0752f251388026df7ed4baab5a8c56f ) +) + +game ( + name "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl)" + description "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Super Hard Bouncer (World) (v1.0) (Aftermarket) (Unl).gb" size 32768 crc 6308019a sha1 549c2624767633d6898ab9623eadb9579ec2779b ) +) + +game ( + name "Sushi Gun (World) (Aftermarket) (Unl)" + description "Sushi Gun (World) (Aftermarket) (Unl)" + rom ( name "Sushi Gun (World) (Aftermarket) (Unl).gb" size 262144 crc a9d405d6 sha1 c075856939d4fe3cd250083b527b3e09be70052d ) +) + +game ( + name "Swaplatformer (World) (Aftermarket) (Unl)" + description "Swaplatformer (World) (Aftermarket) (Unl)" + rom ( name "Swaplatformer (World) (Aftermarket) (Unl).gb" size 1048576 crc babe7935 sha1 3df0c37862b7c391a0d091a55db0d305341529c2 ) +) + +game ( + name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + description "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Take It Racing 2 (World) (Demo) (Aftermarket) (Unl).gb" size 1048576 crc 5898c134 sha1 bd3468395deb0009b190d0b5d487962ae65adbee ) +) + +game ( + name "Tech and Blood (World) (Aftermarket) (Unl)" + description "Tech and Blood (World) (Aftermarket) (Unl)" + rom ( name "Tech and Blood (World) (Aftermarket) (Unl).gb" size 262144 crc 3da2a358 sha1 40a00fce49b16cb36793df30e5156e5bf3e47778 ) +) + +game ( + name "The Light, The Fire (World) (Aftermarket) (Unl)" + description "The Light, The Fire (World) (Aftermarket) (Unl)" + rom ( name "The Light, The Fire (World) (Aftermarket) (Unl).gb" size 524288 crc b6a19823 sha1 d98e03602699f8602689f006e1f55f0c549b3cb7 ) +) + +game ( + name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + description "There's Nothing to Do in This Town (World) (Aftermarket) (Unl)" + rom ( name "There's Nothing to Do in This Town (World) (Aftermarket) (Unl).gb" size 1048576 crc 173b549a sha1 e000fbecda9ea6bbbd0c0370cf8c3faaa54bf64e ) +) + +game ( + name "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" + description "Thin Ice Rescue, The (World) (Aftermarket) (Unl)" + rom ( name "Thin Ice Rescue, The (World) (Aftermarket) (Unl).gb" size 32768 crc 3e0483d6 sha1 b789ced0fe26785e7bce765a9d6ee783f9d967d8 ) +) + +game ( + name "TimberMan (World) (Aftermarket) (Unl)" + description "TimberMan (World) (Aftermarket) (Unl)" + rom ( name "TimberMan (World) (Aftermarket) (Unl).gb" size 32768 crc e0b8459c sha1 e3f4b4c4816cc0dda2885519f1386385e6a5e817 ) +) + +game ( + name "Tobu Tobu Girl (World) (Aftermarket) (Unl)" + description "Tobu Tobu Girl (World) (Aftermarket) (Unl)" + rom ( name "Tobu Tobu Girl (World) (Aftermarket) (Unl).gb" size 262144 crc ed12be6c sha1 8a8f3c1f21f903ea5a7df8fc8b0a6aa5a602e150 ) +) + +game ( + name "Touch the Cat (World) (Aftermarket) (Unl)" + description "Touch the Cat (World) (Aftermarket) (Unl)" + rom ( name "Touch the Cat (World) (Aftermarket) (Unl).gb" size 131072 crc 351fd00a sha1 9dc7b51a44aec9055924596c161972f366caf067 ) +) + +game ( + name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2021-12-09) (Aftermarket) (Unl).gb" size 2097152 crc 15afd765 sha1 c12e603492f8bcfffd28dd4733c7bc445c507642 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-06-18) (Aftermarket) (Unl).gb" size 2097152 crc e1bdf67f sha1 ba492778121622b5288d4188edc344aa41aa6803 ) +) + +game ( + name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2022-03-13) (Aftermarket) (Unl).gb" size 1048576 crc 42bb7dab sha1 70fded7ce1edc54de85b020460f779feb9bdbc01 ) +) + +game ( + name "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl)" + description "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl)" + rom ( name "Traumatarium - Penitent (World) (2024-01-12) (Proto) (Aftermarket) (Unl).gb" size 4194304 crc 805f8257 sha1 a28d68f59b7ab3a6c95d5efc35c22ab9d7a74d31 ) +) + +game ( + name "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl)" + description "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Traumatarium - Penitent (World) (Demo) (Aftermarket) (Unl).gb" size 4194304 crc 7d368277 sha1 efc91ca2873ff8f1733036e298950033d3456927 ) +) + +game ( + name "Treasure Island (World) (Aftermarket) (Unl)" + description "Treasure Island (World) (Aftermarket) (Unl)" + rom ( name "Treasure Island (World) (Aftermarket) (Unl).gb" size 262144 crc cbdec393 sha1 adeaba2723d286d143e0987f51ce9c8ad2f5e839 ) +) + +game ( + name "Vampire Night Shift (World) (Aftermarket) (Unl)" + description "Vampire Night Shift (World) (Aftermarket) (Unl)" + rom ( name "Vampire Night Shift (World) (Aftermarket) (Unl).gb" size 262144 crc 88acbc1a sha1 ef617803c2cdb14cfe3b3b2111aa239a3744e29e ) +) + +game ( + name "Waifu Clicker (World) (Aftermarket) (Unl)" + description "Waifu Clicker (World) (Aftermarket) (Unl)" + rom ( name "Waifu Clicker (World) (Aftermarket) (Unl).gb" size 65536 crc 155f85dc sha1 bb571ed69c3a33e45ba33fbb03a066ba98ae0b20 ) +) + +game ( + name "What Friends Are For (World) (Aftermarket) (Unl)" + description "What Friends Are For (World) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (Aftermarket) (Unl).gb" size 262144 crc cbed3dd6 sha1 58538084a964f779c2f756fbe732656f3f7bef66 ) +) + +game ( + name "Windows93 Adventure (World) (Aftermarket) (Unl)" + description "Windows93 Adventure (World) (Aftermarket) (Unl)" + rom ( name "Windows93 Adventure (World) (Aftermarket) (Unl).gb" size 1048576 crc e1ad0b6f sha1 3ad7327f6f94976c3d12054cf6deb2666ba9fa66 ) +) + +game ( + name "Witchscape (World) (Proto) (Aftermarket) (Unl)" + description "Witchscape (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Witchscape (World) (Proto) (Aftermarket) (Unl).gb" size 262144 crc 2b2fcea0 sha1 8440a578567aa40c646d01c990317f9d12c444e5 ) +) + +game ( + name "Wizard of Wor (World) (Aftermarket) (Unl)" + description "Wizard of Wor (World) (Aftermarket) (Unl)" + rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gb" size 524288 crc bfb1563e sha1 108eefa154412e3422dce4e63bf34f5826ec1baa ) +) + +game ( + name "Woolball's Backyard (World) (Aftermarket) (Unl)" + description "Woolball's Backyard (World) (Aftermarket) (Unl)" + rom ( name "Woolball's Backyard (World) (Aftermarket) (Unl).gb" size 65536 crc 69e26eb6 sha1 28795c4b829440549b3ac2afe3282d85a439f7d7 ) +) + +game ( + name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc 4e463a1a sha1 5d84f53f38aa24f54a6f897ca69ffc5d978805af ) +) + +game ( + name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + description "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Fr) (Proto) (Aftermarket) (Unl).gb" size 1048576 crc fbc50ee8 sha1 52c27e64fb37412c97a53d5dde52c3803fd1e4f7 ) +) + +game ( + name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" + description "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Yuuto Ichika Makes Friends (World) (En,Ja) (Aftermarket) (Unl).gb" size 524288 crc 8a667058 sha1 e765d6915f543a5a65e8be440b3f29eb674a5448 ) +) + +game ( + name "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl)" + description "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl)" + rom ( name "Yvonne Goes to Carbonic (World) (v4.2) (Aftermarket) (Unl).gb" size 262144 crc d46cd738 sha1 b5e8f7b572a47aa191462bb4f980813ad6634ae0 ) +) + +game ( + name "Zagan Warrior (World) (Aftermarket) (Unl)" + description "Zagan Warrior (World) (Aftermarket) (Unl)" + rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gb" size 262144 crc 97fe7a94 sha1 88f76297a4ccf0e3a5ba16ca15237c88346c134a ) +) + +game ( + name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + description "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Zelda - Majora's Mask (World) (v1.1) (Demo) (Aftermarket) (Unl).gb" size 524288 crc f86c2766 sha1 ee86a28cf271be43739e406135e4d8bd4edf7686 ) +) + +game ( + name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + description "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl)" + rom ( name "Zelda's Adventure (World) (v1.3.0) (Aftermarket) (Unl).gb" size 2097152 crc 0b10adaf sha1 12f9ba0a4673dd2f59ba38e636332333a199dea5 ) +) + clrmamepro ( name "Nintendo - Game Boy Color" description "Nintendo - Game Boy Color" - version 20240107-011427 - author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, halftheisland, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" + version 20240810-021134 + author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, psykopat, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" homepage No-Intro url "https://www.no-intro.org" forcenodump required @@ -34466,18 +35912,6 @@ game ( rom ( name "1942 (USA, Europe).gbc" size 1048576 crc 87431672 sha1 d960e951b18d07e79d046313df49c18313664224 ) ) -game ( - name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 2edc4684 sha1 a00b40a3f31bd875f4a0376d22099c3822c9ef98 ) -) - -game ( - name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ff0a848b sha1 837cbb4cf3a92266833099fa06b95edfcdb1865f ) -) - game ( name "2001 Fatal Fury (Taiwan) (En) (Unl)" description "2001 Fatal Fury (Taiwan) (En) (Unl)" @@ -34562,12 +35996,6 @@ game ( rom ( name "2003 Shuma Baolong - Gedou Ban (Taiwan) (Unl).gbc" size 2097152 crc 1219eec6 sha1 4a722c10e3893e04c67a66d0aea401d6d220ec7e ) ) -game ( - name "2123 (World) (Aftermarket) (Unl)" - description "2123 (World) (Aftermarket) (Unl)" - rom ( name "2123 (World) (Aftermarket) (Unl).gbc" size 262144 crc 22836942 sha1 eb9a2aff6485962f1a7773b7138f3c4208fa36e4 ) -) - game ( name "23 in 1 (Taiwan) (Unl)" description "23 in 1 (Taiwan) (Unl)" @@ -34610,12 +36038,6 @@ game ( rom ( name "3D Pool Allstars (USA) (En,Fr,Es) (Proto).gbc" size 1048576 crc 245de3e2 sha1 f7289c3eed275286d0fb3dc7097098276b746786 ) ) -game ( - name "3D Quasars (World) (Aftermarket) (Unl)" - description "3D Quasars (World) (Aftermarket) (Unl)" - rom ( name "3D Quasars (World) (Aftermarket) (Unl).gbc" size 262144 crc 1fd94e67 sha1 3f32226538d8c7f0c866c4b73e9f828265f2bb5b ) -) - 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)" @@ -34652,12 +36074,6 @@ game ( rom ( name "720 Degrees (USA, Europe) (GB Compatible).gbc" size 1048576 crc e633841f sha1 78c0117c8ee32cfa605ac34eedf707cc535b3987 flags verified ) ) -game ( - name "Aardvark (World) (Aftermarket) (Unl)" - description "Aardvark (World) (Aftermarket) (Unl)" - rom ( name "Aardvark (World) (Aftermarket) (Unl).gbc" size 262144 crc 270d45b9 sha1 34a8d00af6be9083409e6fccd0825c6f185d135d flags verified ) -) - game ( name "Absolute X (Europe) (Proto)" description "Absolute X (Europe) (Proto)" @@ -34682,54 +36098,12 @@ game ( rom ( name "Action Replay Xtreme - Special Edition for Pokemon Crystal (Europe) (Unl).gbc" size 131072 crc c288e400 sha1 0280b05885fe5aca8c1884a16bd01513b99f4dc2 flags verified ) ) -game ( - name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" - description "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) -) - -game ( - name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" - description "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adventures in Carnal Hell, The (World) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9f81e7a0 sha1 895148bc0a3b6f9ec59bebae43413d1f4eafd21a ) -) - -game ( - name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" - description "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Adventures in Carnal Hell, The (World) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a5d0d1ec sha1 bc6367f77c235640cea5a1230cee253c99f846e5 ) -) - 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 sha1 7919c5e6aa8d040b1f7953345b376d999cf22b18 ) ) -game ( - name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" - description "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f689b91e sha1 e55e427819916bb02189efe3883fb1dab3d80d35 ) -) - -game ( - name "Agency (World) (Aftermarket) (Unl)" - description "Agency (World) (Aftermarket) (Unl)" - rom ( name "Agency (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0d1bb2f7 sha1 5266589244fab2e9ff047af9f72641cda91e1d90 ) -) - -game ( - name "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) -) - -game ( - name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) -) - game ( name "AirForce Delta (Japan)" description "AirForce Delta (Japan)" @@ -34779,15 +36153,9 @@ game ( ) game ( - name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" - description "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) -) - -game ( - name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" - description "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" - rom ( name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible).gbc" size 1048576 crc 952b94e5 sha1 50f99b0fc5c2f5edc2e76ba973cc42fb0a1a02c8 ) + name "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible)" + description "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible)" + rom ( name "All Star Tennis '99 (USA) (Proto) (1999-09-13) (GB Compatible).gbc" size 1048576 crc e1b17e76 sha1 239e79281faacf7df2abfb527e6e2adfb58b0bc3 ) ) game ( @@ -34802,6 +36170,12 @@ game ( rom ( name "All Star Tennis 2000 (Europe) (AZTX) (Proto) (GB Compatible).gbc" size 1048576 crc deff8dfb sha1 c9db40e3e348668fe6fc41d031263acbe9041a67 ) ) +game ( + name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" + description "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible)" + rom ( name "All Star Tennis 2000 (Europe) (AZTP) (GB Compatible).gbc" size 1048576 crc 952b94e5 sha1 50f99b0fc5c2f5edc2e76ba973cc42fb0a1a02c8 ) +) + game ( name "All-Star Baseball 2000 (USA, Europe)" description "All-Star Baseball 2000 (USA, Europe)" @@ -34814,12 +36188,6 @@ game ( rom ( name "All-Star Baseball 2001 (USA).gbc" size 1048576 crc bc562466 sha1 f702df64d368b763187a5b1263a60fb3e842962b ) ) -game ( - name "Alley Cat (World) (Aftermarket) (Unl)" - description "Alley Cat (World) (Aftermarket) (Unl)" - rom ( name "Alley Cat (World) (Aftermarket) (Unl).gbc" size 262144 crc edb3ac37 sha1 a9aa1ecad6b67a6e5096fb1c10e39899c00a96a0 ) -) - game ( name "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl) (Beta)" description "Alone in the Dark - The New Nightmare (Europe) (En,Fr,De,Es,It,Nl) (Beta)" @@ -34880,12 +36248,6 @@ game ( rom ( name "Animorphs (USA).gbc" size 1048576 crc b4f293cc sha1 b3e5b34d5e97c49720861fabb6a29d557029279c ) ) -game ( - name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) -) - game ( name "Anpfiff - Der RTL Fussball-Manager (Germany)" description "Anpfiff - Der RTL Fussball-Manager (Germany)" @@ -34901,7 +36263,7 @@ game ( game ( 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 ) + rom ( name "Antz (USA) (En,Fr,Es) (GB Compatible).gbc" size 1048576 crc dc0be439 sha1 85684d5891e4ec0f9fdf61b644bdf0ffbf1ba219 flags verified ) ) game ( @@ -34928,24 +36290,12 @@ game ( rom ( name "Antz World Sportz (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc 67c7f85c sha1 d8ddf04baad3beadedf85847964f986ba89bc5ee ) ) -game ( - name "Apollo Mission (World) (Aftermarket) (Unl)" - description "Apollo Mission (World) (Aftermarket) (Unl)" - rom ( name "Apollo Mission (World) (Aftermarket) (Unl).gbc" size 262144 crc bec9d9a2 sha1 b2bcc61bcf269c0f5c0ce2a6e0bb1c7015dc9ff9 ) -) - game ( 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 ) ) -game ( - name "Arena 3000 (World) (Aftermarket) (Unl)" - description "Arena 3000 (World) (Aftermarket) (Unl)" - rom ( name "Arena 3000 (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c17c15c sha1 007d23f73f68de01c250ec3d07403679137851ff ) -) - game ( name "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" description "Arle no Bouken - Mahou no Jewel (Japan) (SGB Enhanced) (GB Compatible)" @@ -35018,18 +36368,6 @@ game ( rom ( name "Asteroids (USA, Europe) (GB Compatible).gbc" size 1048576 crc 89d5d936 sha1 026f031e1bb787a4390e7873227dcb52a069a6e0 flags verified ) ) -game ( - name "Astro Plumber (World) (Aftermarket) (Unl)" - description "Astro Plumber (World) (Aftermarket) (Unl)" - rom ( name "Astro Plumber (World) (Aftermarket) (Unl).gbc" size 262144 crc d746db41 sha1 bf46ab2a3a1ffc3b712b9ae5cfa05441781ac9e4 ) -) - -game ( - name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" - description "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) -) - game ( name "Atlantis - The Lost Empire (Europe) (En,Es,It)" description "Atlantis - The Lost Empire (Europe) (En,Es,It)" @@ -35048,12 +36386,6 @@ game ( rom ( name "Atlantis - The Lost Empire (USA, Europe).gbc" size 2097152 crc d594d24b sha1 ab5dd8efa36b33ce9aa090b3d990e8fc8828f7e2 ) ) -game ( - name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 0d60b100 sha1 9cc1a5140b96ad072d36151f5d99ff6eb699e605 ) -) - game ( name "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" description "Atsumete Asobu Kuma no Pooh-san - Mori no Takaramono (Japan)" @@ -35114,18 +36446,6 @@ game ( rom ( name "Austin Powers Episode IV (Europe) (En,Fr,De,Es,It) (Proto).gbc" size 2097152 crc f038cda7 sha1 937df6944709732d8d372ad5f629a665ffd12eac ) ) -game ( - name "Auto Zone (World) (Aftermarket) (Unl)" - description "Auto Zone (World) (Aftermarket) (Unl)" - rom ( name "Auto Zone (World) (Aftermarket) (Unl).gbc" size 524288 crc 2a86d386 sha1 83a37fb5c5d82e0ff06bb22b63761af996e4ad61 ) -) - -game ( - name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" - description "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) -) - game ( name "Aventures de Buzz l'Eclair, Les (France)" description "Aventures de Buzz l'Eclair, Les (France)" @@ -35186,12 +36506,6 @@ game ( rom ( name "Back to Earth 3D (Europe) (Demo).gbc" size 262144 crc d4255616 sha1 716722ed8756b656bba00cbff116f883e629cfd2 ) ) -game ( - name "Back to Nature (World) (Aftermarket) (Unl)" - description "Back to Nature (World) (Aftermarket) (Unl)" - rom ( name "Back to Nature (World) (Aftermarket) (Unl).gbc" size 262144 crc 861f9a63 sha1 3f4a6cd105d4c8af0312bef482c08784bbbfb0eb ) -) - game ( name "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" description "Backgammon (Europe) (En,Fr,De,Es) (GB Compatible)" @@ -35258,12 +36572,6 @@ game ( rom ( name "Balloon Fight GB (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 262144 crc d2af64ce sha1 dbaa1bf9061de0f052704d6a33892341a38f2152 ) ) -game ( - name "Bandits at Zero (World) (Aftermarket) (Unl)" - description "Bandits at Zero (World) (Aftermarket) (Unl)" - rom ( name "Bandits at Zero (World) (Aftermarket) (Unl).gbc" size 524288 crc c70f413e sha1 c885e109fbb53445db9618c6768c2259e6135921 ) -) - game ( name "Barbie - Aventura Submarina (Spain) (GB Compatible)" description "Barbie - Aventura Submarina (Spain) (GB Compatible)" @@ -35390,12 +36698,6 @@ game ( rom ( name "Battle Fishers (Japan).gbc" size 2097152 crc c99cf3c5 sha1 25d063b151c2d45a14d6952196490615b7e341c5 ) ) -game ( - name "Battle Star (World) (Aftermarket) (Unl)" - description "Battle Star (World) (Aftermarket) (Unl)" - rom ( name "Battle Star (World) (Aftermarket) (Unl).gbc" size 524288 crc b2fd062f sha1 ac4206129704e31386c9c0a1c961a148398f0ba3 ) -) - game ( name "Battleship (USA, Europe) (GB Compatible)" description "Battleship (USA, Europe) (GB Compatible)" @@ -35468,12 +36770,6 @@ game ( rom ( name "Benjamin Bluemchen - Ein verrueckter Tag im Zoo (Germany).gbc" size 2097152 crc 51972995 sha1 560fc8468ed559a72087f630eff015ffb8de22ca ) ) -game ( - name "Berks (World) (Aftermarket) (Unl)" - description "Berks (World) (Aftermarket) (Unl)" - rom ( name "Berks (World) (Aftermarket) (Unl).gbc" size 262144 crc 10ded9ab sha1 8b4c282cf973cdd9926a69ae1d8fcbaf79f8552b ) -) - game ( name "Beyblade - Fighting Tournament (Japan)" description "Beyblade - Fighting Tournament (Japan)" @@ -35492,12 +36788,6 @@ game ( rom ( name "Bibi und Tina - Fohlen Felix in Gefahr (Germany).gbc" size 1048576 crc 8874acd4 sha1 59843ced1e9cbcb02c6acbb8f533ec77b314882c flags verified ) ) -game ( - name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" - description "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 65536 crc b0401d96 sha1 ee5f2db597bb2fa06efe4a279a887b97bf23cac6 ) -) - game ( name "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" description "Bikkuriman 2000 - Charging Card GB (Japan) (SGB Enhanced) (GB Compatible)" @@ -35552,18 +36842,6 @@ game ( rom ( name "Bionic Commando - Elite Forces (USA, Australia).gbc" size 2097152 crc a663cf31 sha1 33c28a2183f8b95cc2d8e0b6a0b005bfc230f1fc flags verified ) ) -game ( - name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0d464785 sha1 790b9d231f6e66027e76264ef646c7a7cb9c878c ) -) - -game ( - name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - description "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 936443e2 sha1 b874c45d4866d5ef0c0d9837502ae42dd0ea3787 ) -) - game ( name "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" description "Black Bass - Lure Fishing (USA, Europe) (GB Compatible)" @@ -35576,12 +36854,6 @@ game ( rom ( name "Black Onyx, The (Japan).gbc" size 1048576 crc 582fe338 sha1 b0f009023a25e575b59e55dec07cda2826f48b65 ) ) -game ( - name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" - description "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) -) - game ( name "Blade (USA, Europe)" description "Blade (USA, Europe)" @@ -35594,18 +36866,6 @@ game ( rom ( name "Blaster Master - Enemy Below (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2f91e17c sha1 8b2e83d7f2b7d72d5cc1ac81c28c2173ad2fc9ba ) ) -game ( - name "Blaze (World) (Aftermarket) (Unl)" - description "Blaze (World) (Aftermarket) (Unl)" - rom ( name "Blaze (World) (Aftermarket) (Unl).gbc" size 262144 crc 7d2519c7 sha1 f9b1422a91cc1f3a55526ef8ba81b7a8297fc55e ) -) - -game ( - name "Blinky's Revenge (World) (Aftermarket) (Unl)" - description "Blinky's Revenge (World) (Aftermarket) (Unl)" - rom ( name "Blinky's Revenge (World) (Aftermarket) (Unl).gbc" size 262144 crc 2d2f9c2b sha1 1c39cc02396c74e7b0b282ead510e94c77ff7f1e ) -) - game ( name "Blue's Clues - Blue's Alphabet Book (USA) (Rev 1) (Proto)" description "Blue's Clues - Blue's Alphabet Book (USA) (Rev 1) (Proto)" @@ -35618,12 +36878,6 @@ game ( rom ( name "Blue's Clues - Blue's Alphabet Book (USA).gbc" size 1048576 crc 748d1345 sha1 f703b54746cb2ef08deba2518ce7b7a3836142aa ) ) -game ( - name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 440a2260 sha1 8472981264122ea588d991628c51020545779926 ) -) - game ( name "Boarder Zone (USA)" description "Boarder Zone (USA)" @@ -35660,12 +36914,6 @@ game ( rom ( name "Bob the Builder - Fix it Fun! (USA).gbc" size 1048576 crc 93fa37bd sha1 68bd9a1932d4e5333ab5b4dfe0d28f126e5d470f ) ) -game ( - name "Boing! (World) (Aftermarket) (Unl)" - description "Boing! (World) (Aftermarket) (Unl)" - rom ( name "Boing! (World) (Aftermarket) (Unl).gbc" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) -) - game ( name "Boku no Camp-jou (Japan)" description "Boku no Camp-jou (Japan)" @@ -35690,12 +36938,6 @@ game ( rom ( name "Bokujou Monogatari 3 GB - Boy Meets Girl (Japan) (Rev 1).gbc" size 2097152 crc 75af0e84 sha1 acb2e549fb7d107d20507af88c36f40234f74958 flags verified ) ) -game ( - name "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" - description "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" - rom ( name "Bomb Runner 1-2 (World) (Aftermarket) (Unl).gbc" size 262144 crc d4c95ac0 sha1 3d020eb6e118b431899d79ce4a7bda9bc571c3a0 ) -) - game ( name "Bomberman Max - Ain Version (Japan)" description "Bomberman Max - Ain Version (Japan)" @@ -35762,18 +37004,6 @@ game ( rom ( name "Bomberman Selection (Korea) (Beta 1).gbc" size 1048576 crc 005ad4b7 sha1 206a19a48a35bcff18d5872b85ba4e8963827cb3 ) ) -game ( - name "Booty (World) (Aftermarket) (Unl)" - description "Booty (World) (Aftermarket) (Unl)" - rom ( name "Booty (World) (Aftermarket) (Unl).gbc" size 262144 crc ef6c39c8 sha1 3c487ddc03d935b583e186d1cc395966ef490412 ) -) - -game ( - name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) -) - game ( name "Bouken! Dondoko Shima (Japan)" description "Bouken! Dondoko Shima (Japan)" @@ -35786,36 +37016,12 @@ game ( rom ( name "Bounced! (Europe) (Proto).gbc" size 1048576 crc 3948aee9 sha1 06d2d0eaea07d7a41834d4c9a5dfdbdda6889be9 ) ) -game ( - name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" - description "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee1c2e1d sha1 b95dfdf10820671ab5f734ed7180cbf1967ca277 ) -) - 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 sha1 952b9e16a938b986a6216b8db6d62f71c4f853fa flags verified ) ) -game ( - name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" - description "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" - rom ( name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl).gbc" size 524288 crc 437a2973 sha1 9c219e2c489f5140314e89fbdc0bb387e1f1eed0 ) -) - -game ( - name "Bubble Trouble (World) (Aftermarket) (Unl)" - description "Bubble Trouble (World) (Aftermarket) (Unl)" - rom ( name "Bubble Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc 3374918b sha1 892388f81f7815ea3bca17632a6a9a33a6edafac ) -) - -game ( - name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" - description "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc e3f64fec sha1 51e302fd27d579c9a4e8109e6ea4af3275d475dd ) -) - game ( name "Buffy the Vampire Slayer (USA, Europe)" description "Buffy the Vampire Slayer (USA, Europe)" @@ -35900,12 +37106,6 @@ game ( rom ( name "Burger Paradise International (Japan).gbc" size 1048576 crc 9092b0eb sha1 71072a7f0165769649bce8c31c36f67bb0e02963 ) ) -game ( - name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" - description "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a5d6cd6a sha1 7464af8e6d9d0a4b11f510d22789a6830cd4c272 ) -) - game ( name "Bust-A-Move 4 (USA, Europe) (GB Compatible)" description "Bust-A-Move 4 (USA, Europe) (GB Compatible)" @@ -35942,18 +37142,6 @@ game ( rom ( name "Caise Gedou 29 in 1 Diannao Huamian Xuan Game (Taiwan) (Unl).gbc" size 2097152 crc 78c0e5bc sha1 358e628e680bc63227940ca6d76217d14fcd3409 flags verified ) ) -game ( - name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52da152b sha1 1bb4a376c03af67ca1e8426375fe1a644499d9ae ) -) - -game ( - name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" - description "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" - rom ( name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 1f2823cb sha1 8906832db7816be01ed37728f6e5a23e981e7e38 ) -) - game ( name "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" description "Cannon Fodder (Europe) (En,Fr,De,Es,It) (Beta)" @@ -35972,6 +37160,12 @@ game ( rom ( name "Cannon Fodder (USA) (En,Fr,De,Es,It).gbc" size 4194304 crc 26f8e1a0 sha1 cc601984a2b52b44cf135e42bcac1bec44b7a6a3 ) ) +game ( + name "Capcom Fight 2003 (Hong Kong) (En) (Unl)" + description "Capcom Fight 2003 (Hong Kong) (En) (Unl)" + rom ( name "Capcom Fight 2003 (Hong Kong) (En) (Unl).gbc" size 2097152 crc 2f8ac081 sha1 3b7a16d1a5d91118960cfadcc41eecaa36097bac ) +) + game ( name "Capcom vs SNK - Millennium Fight 2001 (Taiwan) (En) (Unl)" description "Capcom vs SNK - Millennium Fight 2001 (Taiwan) (En) (Unl)" @@ -36020,12 +37214,6 @@ game ( rom ( name "Cardcaptor Sakura - Tomoeda Shougakkou Daiundoukai (Japan).gbc" size 2097152 crc f78f7998 sha1 1809154979b289750b572a61da1dc93b1b76360f ) ) -game ( - name "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cargo (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a65d66f4 sha1 83c35ad553bde5ce3a6af418d7f8ad1fbe73b0f6 ) -) - 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)" @@ -36098,12 +37286,6 @@ game ( rom ( name "Casper (USA).gbc" size 1048576 crc c775d653 sha1 82ac50380c3ed39fad13cc0bbe35e6457806a294 ) ) -game ( - name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) -) - game ( name "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" description "Caterpillar Construction Zone (USA, Europe) (GB Compatible)" @@ -36140,18 +37322,6 @@ game ( rom ( name "Catz (USA).gbc" size 1048576 crc 769a2c5a sha1 5c3c9a4d85a92779c7e8304f2c122296f62f9a9c ) ) -game ( - name "Cave Fighter (World) (Aftermarket) (Unl)" - description "Cave Fighter (World) (Aftermarket) (Unl)" - rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gbc" size 262144 crc 6f4641f0 sha1 05b441e3542452b1724017d20e2db602d0997773 ) -) - -game ( - name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" - description "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc defb3151 sha1 94770d13bd9b1b52224fe753f94ec580e1b4017c ) -) - game ( name "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Centipede (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -36230,12 +37400,6 @@ game ( rom ( name "Chase H.Q. - Secret Police (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 7c7fdefc sha1 030b45eb8929c1512826f288e4ba035e0083505c ) ) -game ( - name "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" - description "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" - rom ( name "Chase the Chuck Wagon (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c3d653c sha1 27b462be532a37c15798eba0fd48154eff596753 ) -) - game ( name "Checkmate (Japan) (En,Ja) (GB Compatible)" description "Checkmate (Japan) (En,Ja) (GB Compatible)" @@ -36254,12 +37418,6 @@ game ( rom ( name "Chessmaster (USA, Europe) (GB Compatible).gbc" size 1048576 crc 1c13dbb0 sha1 84930fa75eccc34a8e9fb6a0387791d437d1a442 flags verified ) ) -game ( - name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 490a874a sha1 92567a6a58739a38e0d7b35d1327ccb999527fa0 ) -) - game ( name "Chi to Ase to Namida no Koukou Yakyuu (Japan)" description "Chi to Ase to Namida no Koukou Yakyuu (Japan)" @@ -36290,24 +37448,12 @@ game ( rom ( name "Chongwu Xiao Jingling - Jiejin Ta Zhi Wang (Taiwan) (Unl).gbc" size 1048576 crc 620e785d sha1 74da832c2eeb27a4260fe6f42514539473f48b11 ) ) -game ( - name "Chopper War (World) (Aftermarket) (Unl)" - description "Chopper War (World) (Aftermarket) (Unl)" - rom ( name "Chopper War (World) (Aftermarket) (Unl).gbc" size 524288 crc eb0f4f3e sha1 26970bb0753e792aaeb328e0f88d650acd413a9d ) -) - game ( 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 ) ) -game ( - name "Choro-Q (World) (Aftermarket) (Unl)" - description "Choro-Q (World) (Aftermarket) (Unl)" - rom ( name "Choro-Q (World) (Aftermarket) (Unl).gbc" size 262144 crc e40e99bd sha1 8534c4fe58aef32b8cfd4812fa1f2c1094e6b129 ) -) - game ( name "Chuanshuo (Taiwan) (Unl)" description "Chuanshuo (Taiwan) (Unl)" @@ -36326,18 +37472,6 @@ game ( rom ( name "Classic Bubble Bobble (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc c1b22246 sha1 6e3739c0538467c220750f2e8d474433692bac09 ) ) -game ( - name "Climb It (World) (Aftermarket) (Unl)" - description "Climb It (World) (Aftermarket) (Unl)" - rom ( name "Climb It (World) (Aftermarket) (Unl).gbc" size 262144 crc e7210290 sha1 19f3b825eada3eda3135350bd0ddca6a20a5281f ) -) - -game ( - name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a flags verified ) -) - game ( name "Colin McRae Rally (Europe)" description "Colin McRae Rally (Europe)" @@ -36362,24 +37496,12 @@ game ( rom ( name "Commander Keen (USA, Europe).gbc" size 1048576 crc 4af4cc9c sha1 a00b7bdaaedeb67ad7e7555139301c8b4c92edea flags verified ) ) -game ( - name "Commando (World) (Aftermarket) (Unl)" - description "Commando (World) (Aftermarket) (Unl)" - rom ( name "Commando (World) (Aftermarket) (Unl).gbc" size 262144 crc 5381b103 sha1 414bb6bdc1ed5647707d7d49f194c387d4098f00 ) -) - game ( 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 "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" - description "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) -) - game ( name "Cool Bricks (Europe) (En,Fr,De,Es,It)" description "Cool Bricks (Europe) (En,Fr,De,Es,It)" @@ -36392,24 +37514,6 @@ game ( rom ( name "Cool Hand (Europe) (En,Fr,De) (GB Compatible).gbc" size 524288 crc e6c91fb8 sha1 d116a77c501d5e553d1490993f8c0a9a92c3ea0c ) ) -game ( - name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) -) - -game ( - name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" - description "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" - rom ( name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 1780b904 sha1 fcbe2c2389e6c51a38eb17eb80ffb2e51955c7f2 ) -) - -game ( - name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" - description "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" - rom ( name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc e983a31f sha1 1d811dd440572243f9e95527d970f3ffa91ddbdf ) -) - game ( name "Crazy Bikers (Europe)" description "Crazy Bikers (Europe)" @@ -36428,12 +37532,6 @@ game ( rom ( name "Crazy Climber (USA) (Proto 1) (2000-09-22).gbc" size 131072 crc 748fa8b4 sha1 eb0eaed85cf5a72e0461eebbad38227bd018a999 ) ) -game ( - name "Crazy Golf (World) (Aftermarket) (Unl)" - description "Crazy Golf (World) (Aftermarket) (Unl)" - rom ( name "Crazy Golf (World) (Aftermarket) (Unl).gbc" size 262144 crc f7fe3d01 sha1 b06f47a713b66efa9133be43653c7c4cb5ebc93c ) -) - game ( name "Croc (USA, Europe)" description "Croc (USA, Europe)" @@ -36443,7 +37541,7 @@ game ( game ( name "Croc 2 (USA, Europe)" description "Croc 2 (USA, Europe)" - rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc c1d60129 sha1 fa29d6c4239405b12b320bb6e8a65ca2083a4b1c ) + rom ( name "Croc 2 (USA, Europe).gbc" size 1048576 crc c1d60129 sha1 fa29d6c4239405b12b320bb6e8a65ca2083a4b1c flags verified ) ) game ( @@ -36488,12 +37586,6 @@ game ( rom ( name "Cubix - Robots for Everyone - Race 'n Robots (USA) (En,Fr,De,Es,It).gbc" size 1048576 crc 9f883b0f sha1 d62b85c664e0a42c84e56b939a201fe90d05a360 ) ) -game ( - name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" - rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gbc" size 262144 crc 30204c4e sha1 d6fb35f3bdd44429f88c10551692e1adf14356ab ) -) - game ( name "CyberTiger (USA, Europe)" description "CyberTiger (USA, Europe)" @@ -36572,36 +37664,6 @@ game ( 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 "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl).gbc" size 262144 crc 502385c4 sha1 3a310be21d5cc077da6eb8e3afa99ccff2eda84e ) -) - -game ( - name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc a504b906 sha1 4634631f2c0b4a618aeefc114e5b8e4ba9c7ee04 ) -) - -game ( - name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl).gbc" size 262144 crc a9714871 sha1 7d5b22d1c528603007e340f9d3562c1e53f10796 ) -) - -game ( - name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" - description "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl).gbc" size 262144 crc 26d3fe7a sha1 36c9649d4e99fdcaa4cf590963d0c49a3cf8084e ) -) - -game ( - name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" - description "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d34b719a sha1 446ca937d3e54ce33a49d1fff4692b3b906b539e ) -) - game ( name "Dance Dance Revolution GB (Japan)" description "Dance Dance Revolution GB (Japan)" @@ -36632,12 +37694,6 @@ game ( rom ( name "Dancing Furby (Japan) (GB Compatible).gbc" size 1048576 crc 3263f692 sha1 f3f7e37d64eef74d65456bae490e0a0b25897ac0 ) ) -game ( - name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) -) - game ( name "Data-Navi Pro Yakyuu (Japan)" description "Data-Navi Pro Yakyuu (Japan)" @@ -36671,25 +37727,7 @@ game ( 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 ) -) - -game ( - name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) -) - -game ( - name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" - description "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" - rom ( name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl).gbc" size 262144 crc 57ca8f69 sha1 8992f14f02bd37e11cb05511c17fff3d253ccf25 ) -) - -game ( - name "Days Without (World) (Aftermarket) (Unl)" - description "Days Without (World) (Aftermarket) (Unl)" - rom ( name "Days Without (World) (Aftermarket) (Unl).gbc" size 262144 crc 437b4921 sha1 cb21c1bca18d750ecde91dc3adb6b599c2ad75fa ) + 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 ( @@ -36704,24 +37742,12 @@ game ( rom ( name "Dear Daniel no Sweet Adventure - Kitty-chan o Sagashite (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 0fd34427 sha1 8598594285f0342b3d93c447b475fadd4722c6cb ) ) -game ( - name "Death Race 16 (World) (Aftermarket) (Unl)" - description "Death Race 16 (World) (Aftermarket) (Unl)" - rom ( name "Death Race 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b9488ec sha1 56b8a2d7117b12ff5e709e6a258f9a0b3b0ebe24 ) -) - game ( name "Deer Hunter (USA)" description "Deer Hunter (USA)" rom ( name "Deer Hunter (USA).gbc" size 1048576 crc 40a715fb sha1 87a012e82f2361760ae337b30e9d41ef2245419a ) ) -game ( - name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7cff943e sha1 065b5325d44cb0e40f7b7803d707b8c1ea9ea5b2 ) -) - game ( name "Deja Vu I & II (Japan)" description "Deja Vu I & II (Japan)" @@ -36785,13 +37811,7 @@ game ( 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 sha1 db107af55df07fb8c771c712b05d6aebb175e3c5 ) -) - -game ( - name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" - description "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c6b965b9 sha1 ac43f43bdcfc0347f24a0a70de213a4b701d8155 ) + rom ( name "Dexter's Laboratory - Robot Rampage (USA, Europe).gbc" size 1048576 crc d24d6601 sha1 db107af55df07fb8c771c712b05d6aebb175e3c5 flags verified ) ) game ( @@ -36806,6 +37826,12 @@ game ( rom ( name "Digimon 02 4 (Taiwan) (En) (Unl).gbc" size 1048576 crc a90061e9 sha1 0c8280e5349dda05fdd27bb1eb68a1be2f3d5c04 ) ) +game ( + name "Digimon 02 5 (USA) (Unl)" + description "Digimon 02 5 (USA) (Unl)" + rom ( name "Digimon 02 5 (USA) (Unl).gbc" size 1048576 crc 0bcbe728 sha1 f868fecce3bdec242937b93549f4861a0f481065 ) +) + game ( name "Digimon 2 (Taiwan) (En) (Unl)" description "Digimon 2 (Taiwan) (En) (Unl)" @@ -36842,6 +37868,12 @@ game ( rom ( name "Digimon Pocket (Taiwan) (En) (Unl).gbc" size 524288 crc 6791b106 sha1 87750928d5f005e67e51e4d08a6d82351effc7b2 ) ) +game ( + name "Digimon Pocket (Taiwan) (Zh) (Unl)" + description "Digimon Pocket (Taiwan) (Zh) (Unl)" + rom ( name "Digimon Pocket (Taiwan) (Zh) (Unl).gbc" size 524288 crc 6d39574e sha1 9560dac8eb9d676aeb5f2d92fbb0228cb4ec27cc ) +) + game ( name "Digimon Saphire (USA) (Unl)" description "Digimon Saphire (USA) (Unl)" @@ -36890,18 +37922,6 @@ game ( rom ( name "Dinosaur'us (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc f4609fe3 sha1 d0caf4b5172651aee2bbe38efdae084ce3d7a7ff ) ) -game ( - name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" - description "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) -) - -game ( - name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" - description "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7c0f52cc sha1 8bc16b70838f9245b7e37c6dbe57159b294fbf81 ) -) - game ( name "Diva Starz (Europe)" description "Diva Starz (Europe)" @@ -36926,12 +37946,6 @@ game ( rom ( name "Diva Starz - Mall Mania (USA).gbc" size 1048576 crc ebe0ecd6 sha1 1d0edb87404409f1e4c124503be4cc59165c01da ) ) -game ( - name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" - description "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f4ff5eb0 sha1 6b421505acc626a34bb9306a3d88e1964a4502f3 ) -) - game ( name "Dogz (Europe)" description "Dogz (Europe)" @@ -36962,24 +37976,6 @@ game ( rom ( name "Dokidoki Densetsu - Mahoujin Guruguru (Japan).gbc" size 4194304 crc 83e47a1a sha1 1b4627699b45af36a42e75c1a217b40fb5bec4ba ) ) -game ( - name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) -) - -game ( - name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) -) - -game ( - name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) -) - game ( name "Donald Duck - Daisy o Sukue! (Japan)" description "Donald Duck - Daisy o Sukue! (Japan)" @@ -37088,12 +38084,6 @@ game ( rom ( name "Doraemon no Study Boy - Kuku Game (Japan).gbc" size 1048576 crc a8a353d8 sha1 9b5c8b89b6e69d3803fbd43b2fe5130ad6d2f50b ) ) -game ( - name "Dork's Dilemma (World) (Aftermarket) (Unl)" - description "Dork's Dilemma (World) (Aftermarket) (Unl)" - rom ( name "Dork's Dilemma (World) (Aftermarket) (Unl).gbc" size 524288 crc 77b8b43b sha1 bd525f97cc316fed3f6271ed0929414df4c0389c ) -) - game ( name "Doug - La Grande Aventure (France)" description "Doug - La Grande Aventure (France)" @@ -37118,12 +38108,6 @@ game ( rom ( name "Doug's Big Game (Europe).gbc" size 1048576 crc b6ffbcca sha1 e9c207bb9b03b5762afd53c8f5295703cc1474b1 ) ) -game ( - name "Downer (World) (GB Compatible) (Aftermarket) (Unl)" - description "Downer (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Downer (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7a1c9a9f sha1 70044dca1282f4445fe05305586ecc69f4e52304 ) -) - game ( name "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" description "Dr. Rin ni Kiitemite! - Koi no Rin Fuusui (Japan)" @@ -37133,7 +38117,7 @@ game ( 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 sha1 815f252f761e0fd3f29b7acf32b2360264aefab1 ) + rom ( name "Dracula - Crazy Vampire (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 2f7aef51 sha1 815f252f761e0fd3f29b7acf32b2360264aefab1 flags verified ) ) game ( @@ -37145,13 +38129,7 @@ game ( game ( name "Dragon Ball - Final Bout (Taiwan) (Unl)" description "Dragon Ball - Final Bout (Taiwan) (Unl)" - rom ( name "Dragon Ball - Final Bout (Taiwan) (Unl).gbc" size 1048576 crc d9849157 sha1 51ebe1a27e8295340f996d2841c5cc6e2bc9f548 ) -) - -game ( - name "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl)" - description "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl)" - rom ( name "Dragon Ball Z - 2002 Fighting (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8fa35740 sha1 008a559635c9d351d9f68b3a1ac0c687521821cf ) + rom ( name "Dragon Ball - Final Bout (Taiwan) (Unl).gbc" size 1048576 crc 039079bd sha1 682b1be82eccb9044fc61af689c39d07fa325fec ) ) game ( @@ -37406,24 +38384,6 @@ game ( rom ( name "Dragon's Lair (USA, Europe) (En,Ja,Fr,De,Es,Zh).gbc" size 4194304 crc bf076ca5 sha1 15fb0865314e43a83910d52cca7307502aab29fc ) ) -game ( - name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 9f30b891 sha1 9974d28975a2d8e1e41ce8f32351c6eef144919d ) -) - -game ( - name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonyhm (World) (v1.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 96f9b7c0 sha1 2b74d076cabff92e5935d922e8f37202a723aaf0 flags verified ) -) - -game ( - name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dragonyhm (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc cad7369d sha1 0058096f8fcbb2774f908811aaa0b1ee54111493 ) -) - game ( name "Driver (Europe) (En,Fr,De,Es,It)" description "Driver (Europe) (En,Fr,De,Es,It)" @@ -37484,12 +38444,6 @@ game ( rom ( name "Dukes of Hazzard, The - Racing for Home (USA).gbc" size 2097152 crc fb08dceb sha1 6a39dfbce8b86db84615cdb5fb24012cbbac7b36 ) ) -game ( - 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 "Dungeon Savior (Japan) (Rev 1) (Proto) (SGB Enhanced) (GB Compatible)" description "Dungeon Savior (Japan) (Rev 1) (Proto) (SGB Enhanced) (GB Compatible)" @@ -37497,15 +38451,9 @@ game ( ) game ( - name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7c41cef6 sha1 e2df238887da0b6cf79513c7799ad707740eae30 ) -) - -game ( - name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc abb154db sha1 f3b456d6318bee05150403efa5a933996e1d744a ) + 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 ( @@ -37562,6 +38510,12 @@ game ( rom ( name "E.T. - The Extra-Terrestrial and the Cosmic Garden (USA).gbc" size 1048576 crc 32c87958 sha1 da71b581f7415b6535ac4af2e8fccd2040c54215 ) ) +game ( + name "e'Fighter HOT (Taiwan) (En) (Unl)" + description "e'Fighter HOT (Taiwan) (En) (Unl)" + rom ( name "e'Fighter HOT (Taiwan) (En) (Unl).gbc" size 1048576 crc 8fa2539d sha1 93a3716f8f41b89bee795af6e8f6fdddfcd8acf1 ) +) + game ( name "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" description "Earthworm Jim - Menace 2 the Galaxy (USA, Europe) (GB Compatible)" @@ -37574,6 +38528,12 @@ game ( rom ( name "ECW Hardcore Revolution (USA, Europe).gbc" size 1048576 crc 484eba10 sha1 c337d0480e84f5e2b7e28b13c3667b8cf92d9649 ) ) +game ( + name "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl)" + description "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl)" + rom ( name "Elang 2003 - Mark of the Wolfs (Taiwan) (En) (Unl).gbc" size 1048576 crc 50a1e9a9 sha1 4a3ac88b7be532d5fd5c4d9e500532e96441a966 ) +) + game ( name "Elang Chuanshuo - Shiji Zhi Zhan (Taiwan) (Unl)" description "Elang Chuanshuo - Shiji Zhi Zhan (Taiwan) (Unl)" @@ -37586,12 +38546,6 @@ game ( rom ( name "Elemental Fighter (USA) (Proto).gbc" size 262144 crc 03fc3d03 sha1 92cce7614474d3f9ed9e3fdbd2e2bb434e074565 ) ) -game ( - name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc bffec2e1 sha1 a25cc6ee07e524f9a7121786bd0e513a1c6c2a8d ) -) - game ( name "Elevator Action EX (Europe) (En,Fr,De,Es,It)" description "Elevator Action EX (Europe) (En,Fr,De,Es,It)" @@ -37646,12 +38600,6 @@ game ( rom ( name "Emperor's New Groove, The (USA).gbc" size 2097152 crc 6ebad539 sha1 ba663289bd5d9d09bc8b9ac2c1d38293dcba9c02 ) ) -game ( - name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9ca3cf6c sha1 d3f4d21bf543431672268b476802693b2da9b6b9 ) -) - game ( name "Equestriad 2001 (Europe) (Proto)" description "Equestriad 2001 (Europe) (Proto)" @@ -37706,24 +38654,6 @@ game ( rom ( name "Evel Knievel (USA) (GB Compatible).gbc" size 2097152 crc 51e951b5 sha1 24cac6ab0151b33d2b1fd06ee01931802fb98267 flags verified ) ) -game ( - name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" - description "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f222b03b sha1 c14f008cfc182f35fe670e14b57052ae4f8d1c60 ) -) - -game ( - name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" - description "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 050caa5e sha1 e4b61c220b046e2287272f9b1bef85ad2d835fe3 ) -) - -game ( - name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" - description "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" - rom ( name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 20fe84af sha1 18056b5b032955099c606651f26164de131e54a6 ) -) - game ( name "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" description "Extreme Ghostbusters (Europe) (En,Fr,De,Es,It,Pt)" @@ -37838,54 +38768,18 @@ game ( 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 "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc bdaf8f3f sha1 d1ed0fb4d926f4c337399ca342644f89cf00790a ) -) - -game ( - name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e61c1dc2 sha1 d7a88a68ec65d9cf3f9521fc9ad9d3f4b51bac5d ) -) - -game ( - name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 63c6c960 sha1 b62ec7a341ea9a0bfe8f0b014da971b73606a86e ) -) - -game ( - name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - description "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc de373eba sha1 dbf2228017515b407ed9f4a9b3bf01bc2a5f7b0f ) -) - -game ( - name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" - description "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc 701847f5 sha1 aba3fecd55c0cee7fbe49506b367b7e94b56b81c ) -) - -game ( - name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" - description "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc f87760b3 sha1 ea0dd170812d1bcc38de1cabe12a372cd2178c95 ) -) - -game ( - name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" - description "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" - rom ( name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate).gbc" size 524288 crc 7bec6553 sha1 bdcadc0f98d8c9061cbe83c53a047719280b6e09 ) -) - game ( name "Fellowship of the Rings (Taiwan) (En) (Unl)" description "Fellowship of the Rings (Taiwan) (En) (Unl)" rom ( name "Fellowship of the Rings (Taiwan) (En) (Unl).gbc" size 524288 crc 4bcc59dc sha1 837232bd2eeb50b276049d0908f8ed4dc7efbcfe ) ) +game ( + name "Fellowship of the Rings (China) (En) (Unl)" + description "Fellowship of the Rings (China) (En) (Unl)" + rom ( name "Fellowship of the Rings (China) (En) (Unl).gbc" size 524288 crc 759f07bd sha1 83fec0fb02fdeda160a0de610acdf7446e373022 ) +) + game ( name "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" description "Feng Kuang A Gei III - Chaoji Zhadan Ren (Taiwan) (Unl)" @@ -37928,42 +38822,6 @@ game ( rom ( name "FIFA 2000 (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e6bc2e8c sha1 c40dd26a6d600818eca960bade3afa374a19bc12 ) ) -game ( - name "Fillo - Crystal Version (World) (Aftermarket) (Unl)" - description "Fillo - Crystal Version (World) (Aftermarket) (Unl)" - rom ( name "Fillo - Crystal Version (World) (Aftermarket) (Unl).gbc" size 524288 crc 88bb855c sha1 2ffc4199d94f8b29b3f84b7bdb2694154a0bd285 ) -) - -game ( - name "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" - description "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Find Out (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5f8b660e sha1 3605a96f6713157a88e4d88989d2e2f11b9db42f ) -) - -game ( - name "Finders Keepers (World) (Aftermarket) (Unl)" - description "Finders Keepers (World) (Aftermarket) (Unl)" - rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gbc" size 524288 crc 4cfa0cfd sha1 db002f4a2500a9dc98a9ac7c263293d6e4a72cf1 ) -) - -game ( - name "Fire Ant (World) (Aftermarket) (Unl)" - description "Fire Ant (World) (Aftermarket) (Unl)" - rom ( name "Fire Ant (World) (Aftermarket) (Unl).gbc" size 262144 crc 154cc020 sha1 b58ed66838db34fc7f8475ccb670267119d623a5 ) -) - -game ( - name "Fireman Fred (World) (Aftermarket) (Unl)" - description "Fireman Fred (World) (Aftermarket) (Unl)" - rom ( name "Fireman Fred (World) (Aftermarket) (Unl).gbc" size 524288 crc 563d9ca7 sha1 e62a9c6b6a39f0cb662fdb07b72669355b706f57 ) -) - -game ( - name "Firemen (World) (Aftermarket) (Unl)" - description "Firemen (World) (Aftermarket) (Unl)" - rom ( name "Firemen (World) (Aftermarket) (Unl).gbc" size 262144 crc 7299401f sha1 84c68614334578f866cfa929df736377f04f5d04 ) -) - game ( name "Fish Files, The (Europe) (En,Fr,De,Es,It)" description "Fish Files, The (Europe) (En,Fr,De,Es,It)" @@ -37977,21 +38835,9 @@ game ( ) game ( - name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" - description "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc c8014615 sha1 7221f5e53f6027183301d06e258c6cb417007b8c ) -) - -game ( - name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - description "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 flags verified ) -) - -game ( - name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - description "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) + name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + description "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It)" + rom ( name "Flintstones, The - Burgertime in Bedrock (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc a5b09726 sha1 2f7fb1afedd6c9657715b45397dc5492e40dfe45 flags verified ) ) game ( @@ -38006,30 +38852,12 @@ game ( 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)" - 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 sha1 3d538b78ef5f1238f47531c069921056b00e33b3 ) ) -game ( - name "Flooder (World) (Aftermarket) (Unl)" - description "Flooder (World) (Aftermarket) (Unl)" - rom ( name "Flooder (World) (Aftermarket) (Unl).gbc" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) -) - -game ( - name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" - description "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" - rom ( name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl).gbc" size 32768 crc cdda76f8 sha1 e5eec8efc032aa5bce1826f7b6b8790c61c96e06 ) -) - game ( name "Floracy (Europe) (Proto) (2000-10-10)" description "Floracy (Europe) (Proto) (2000-10-10)" @@ -38043,15 +38871,9 @@ game ( ) game ( - name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) -) - -game ( - name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) + name "Formula One 2000 (USA)" + description "Formula One 2000 (USA)" + rom ( name "Formula One 2000 (USA).gbc" size 1048576 crc 703c057f sha1 7a38195842e536581fdcea42e4ebe50967581736 ) ) game ( @@ -38060,12 +38882,6 @@ game ( rom ( name "Formula One 2000 (Europe) (En,Fr,De,Es,It) (Proto).gbc" size 1048576 crc e689bf16 sha1 7aa7073b7b494522f7cfcd268aa066b7fe52c671 ) ) -game ( - name "Formula One 2000 (USA)" - description "Formula One 2000 (USA)" - 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)" @@ -38078,24 +38894,6 @@ game ( rom ( name "Freestyle Scooter (Europe).gbc" size 1048576 crc ee79117d sha1 cf6ae174584bbfb5ae30478841114443adc00245 ) ) -game ( - name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" - description "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) -) - -game ( - name "Friendly Fire (World) (Aftermarket) (Unl)" - description "Friendly Fire (World) (Aftermarket) (Unl)" - rom ( name "Friendly Fire (World) (Aftermarket) (Unl).gbc" size 262144 crc 5c6dca2b sha1 8f8085010e28aa8bdb312d086b0002b706742282 ) -) - -game ( - name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d8be10d6 sha1 d09f4d2f799ac2e2731be0171625846d28d0f57e ) -) - game ( name "Frogger (USA) (Rev 2) (GB Compatible)" description "Frogger (USA) (Rev 2) (GB Compatible)" @@ -38132,12 +38930,6 @@ game ( rom ( name "Frogger 2 (USA) (Rev 1).gbc" size 1048576 crc e3227b7d sha1 0d5028ca6fcc10df46d11cd4b56e5add1dc5e63e ) ) -game ( - name "From Below Pocket (World) (Aftermarket) (Unl)" - description "From Below Pocket (World) (Aftermarket) (Unl)" - rom ( name "From Below Pocket (World) (Aftermarket) (Unl).gbc" size 131072 crc 35ad9b5a sha1 c0e072bfb88c84dc68b2eded1f9c088d75ffa5ed ) -) - game ( name "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" description "From TV Animation One Piece - Maboroshi no Grand Line Boukenki! (Japan) (Beta 1) (SGB Enhanced) (GB Compatible)" @@ -38180,12 +38972,6 @@ game ( rom ( name "Front Row (Japan).gbc" size 1048576 crc 6eea9243 sha1 64c8a9459d7c80e297774dab7775b5edf59432cc ) ) -game ( - name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" - description "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 85edfba4 sha1 8a95571a32c5a23bd6be4edf6429f630d7a1a15a ) -) - game ( name "Full Time Soccer (Europe) (Unl)" description "Full Time Soccer (Europe) (Unl)" @@ -38198,12 +38984,6 @@ game ( rom ( name "Full Time Soccer & Hang Time Basketball (Europe) (Unl).gbc" size 524288 crc 0634c196 sha1 aefb746984b3450b90bbfaa5de21a252685ddabb ) ) -game ( - name "Fury (World) (Aftermarket) (Unl)" - description "Fury (World) (Aftermarket) (Unl)" - rom ( name "Fury (World) (Aftermarket) (Unl).gbc" size 262144 crc 7217c41d sha1 ef532b587eb438f1a39a77086ac0b8bbae23a16d ) -) - game ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" description "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (AFMJ)" @@ -38216,18 +38996,6 @@ game ( rom ( name "Fushigi no Dungeon - Fuurai no Shiren GB 2 - Sabaku no Majou (Japan) (BFWJ).gbc" size 4194304 crc f3c20fbe sha1 d9c490af97c08ac7053bbb9f7ae06d3501035127 flags verified ) ) -game ( - name "G-Man (World) (Aftermarket) (Unl)" - description "G-Man (World) (Aftermarket) (Unl)" - rom ( name "G-Man (World) (Aftermarket) (Unl).gbc" size 524288 crc ff3beab1 sha1 cb9486ca9a6ad3903662963aa966145257ef92a6 ) -) - -game ( - name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a flags verified ) -) - game ( name "Gaiamaster Duel - Card Attackers (Japan)" description "Gaiamaster Duel - Card Attackers (Japan)" @@ -38276,12 +39044,6 @@ game ( 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 Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) -) - game ( name "Game Boy Color (World) (Demo) (Kiosk)" description "Game Boy Color (World) (Demo) (Kiosk)" @@ -38336,18 +39098,6 @@ game ( rom ( name "Game Conveni 21 (Japan) (GB Compatible).gbc" size 1048576 crc 994314b3 sha1 6803617abc46db83dbec08d10e03b9f9297f260e ) ) -game ( - name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 96721e5d sha1 90fad94433a5b0dbcf73f4a2d4ebb75d7ab065c4 ) -) - -game ( - name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a02d2ae2 sha1 7eb6865c5c265193763ec0bf751d26964e870120 ) -) - game ( name "Games Frenzy (Europe) (En,Fr,De)" description "Games Frenzy (Europe) (En,Fr,De)" @@ -38415,81 +39165,39 @@ game ( ) game ( - name "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" - description "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" - rom ( name "GB Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 131072 crc ec823cc1 sha1 0781eaecb7fd25c068e396b5eb02c6231baf6ea3 ) + name "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" + description "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP)" + rom ( name "GB-Memory Multi Menu (Japan) (SGB Enhanced, GB Compatible) (NP).gbc" size 131072 crc ec823cc1 sha1 0781eaecb7fd25c068e396b5eb02c6231baf6ea3 ) ) game ( - name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt 2).gbc" size 1048576 crc 7afae089 sha1 b33c9f5012cc1a1a8c7ac9d95a183fd28d9bf9f3 ) ) game ( - name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl) (Alt).gbc" size 1048576 crc c0ac1b50 sha1 4dcef6fcfe009e17da0bb13e50e7410a3f586e23 ) ) game ( - name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) + name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl)" + description "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl)" + rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (En) (Unl).gbc" size 1048576 crc 1b1c6f68 sha1 fd06c62b42878e8094e610b180c1848c785f67e9 ) ) game ( - name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) + name "Gedou Jian Shen KF (Taiwan) (En) (Unl)" + description "Gedou Jian Shen KF (Taiwan) (En) (Unl)" + rom ( name "Gedou Jian Shen KF (Taiwan) (En) (Unl).gbc" size 1048576 crc 190702b3 sha1 be03f86ef0c6df8c6741fe1298496670fcc682cf ) ) game ( - name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) -) - -game ( - name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) -) - -game ( - name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) -) - -game ( - name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) -) - -game ( - name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) -) - -game ( - name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) -) - -game ( - name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" - description "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt)" - rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl) (Alt).gbc" size 1048576 crc c0ac1b50 sha1 4dcef6fcfe009e17da0bb13e50e7410a3f586e23 ) -) - -game ( - name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl)" - description "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl)" - rom ( name "Gedou Jian Shen - Soul Falchion (Taiwan) (Unl).gbc" size 1048576 crc 1b1c6f68 sha1 fd06c62b42878e8094e610b180c1848c785f67e9 ) + name "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl)" + description "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl)" + rom ( name "Gedou Qi Long Qiu 2002 (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8fa35740 sha1 008a559635c9d351d9f68b3a1ac0c687521821cf ) ) game ( @@ -38552,30 +39260,6 @@ game ( rom ( name "Gex 3 - Deep Pocket Gecko (USA).gbc" size 2097152 crc 85a98c7d sha1 0da71536a3e92dd537c7067ec1014a262dbc3837 ) ) -game ( - name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc 4aa9a9c2 sha1 ac697bc27a126c1389e6bef94a2c83404e8819f2 ) -) - -game ( - name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 32e2ea48 sha1 ee11d5397316b69eee5ae3023de08c3b919c93df ) -) - -game ( - name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" - description "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ea87ad5d sha1 433e25df1421e77cdc807296e1ed662d9e43d685 ) -) - -game ( - name "Ghost Town (World) (Aftermarket) (Unl)" - description "Ghost Town (World) (Aftermarket) (Unl)" - rom ( name "Ghost Town (World) (Aftermarket) (Unl).gbc" size 262144 crc 52efcc35 sha1 1a4a7846d6c87f0bd8b267aa6a8aa98e797fedf8 ) -) - game ( name "Ghosts'n Goblins (USA, Europe) (GB Compatible)" description "Ghosts'n Goblins (USA, Europe) (GB Compatible)" @@ -38630,12 +39314,6 @@ game ( rom ( name "Gobs of Games (USA) (En,Fr,De).gbc" size 1048576 crc 2e61c391 sha1 89695361ccbca372662f6634678a40ea676076a7 ) ) -game ( - name "Gods of the Universe (World) (Aftermarket) (Unl)" - description "Gods of the Universe (World) (Aftermarket) (Unl)" - rom ( name "Gods of the Universe (World) (Aftermarket) (Unl).gbc" size 262144 crc 27b87354 sha1 74eb8cd698097290b93fb08d9b19486d05411877 ) -) - game ( name "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" description "Godzilla - The Series (Europe) (En,Fr,De) (GB Compatible)" @@ -38720,12 +39398,6 @@ game ( rom ( name "Goraku Ou Tango! (Japan) (GB Compatible).gbc" size 1048576 crc 81fb43e1 sha1 1d49232763c1422a00cbb893d0f900c44a2ccf54 ) ) -game ( - name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) -) - game ( name "Grand Casino (Japan) (Proto)" description "Grand Casino (Japan) (Proto)" @@ -38774,24 +39446,6 @@ game ( rom ( name "Granduel - Shinki Dungeon no Hihou (Japan) (Sample).gbc" size 2097152 crc 7122136d sha1 534fc9ae5800eb935460f145e1bbc57f77ab2555 ) ) -game ( - name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a5ad3c0b sha1 1cf0cf6d1da5c5337856ecc0a60d2e9fb3c98f58 ) -) - -game ( - name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" - description "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b29fc03f sha1 2f979202a4bf4f98f3026a7548a8b6c7008806bf ) -) - -game ( - name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" - description "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a0e998e1 sha1 ab656383e9aaaa2991aa344bdc8f21370f0eda36 ) -) - game ( name "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" description "Great Battle Pocket, The (Japan) (SGB Enhanced) (GB Compatible)" @@ -38828,54 +39482,6 @@ game ( rom ( name "Gremlins - Unleashed (Europe) (En,Fr,De,Es,It,Pt) (Beta).gbc" size 1048576 crc c38d52e7 sha1 675623b58fa0d307355c77d7a4783af7927681e9 ) ) -game ( - name "Grimace's Birthday (World) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (Aftermarket) (Unl).gbc" size 1048576 crc 7f4386e9 sha1 d6358d100ea65d34d95588f800635b64927baf82 ) -) - -game ( - name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl).gbc" size 1048576 crc 7744f551 sha1 035b7417e03c4e264a90212f2a3811012f03c2a2 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc 9dee42fe sha1 071fa179df96950c3c92b0abbe32092b1816ec40 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc 9baa5f46 sha1 d247c03119ac14f97fdeeaa6bf0defa98e35fa17 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc ab41a9ef sha1 d8e727745e285f5e467f5eccbfd30ee175bafc2e flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl).gbc" size 1048576 crc f8e8e1f3 sha1 a3fdfe3981e800fa7c73ff989bc06426f668c331 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl).gbc" size 1048576 crc a7b59d7b sha1 295fdc3218d1699dea6d5832d068b721fccf9bd4 flags verified ) -) - -game ( - name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" - description "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" - rom ( name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc f3879ef0 sha1 27d7ee2f31bf575185711217c3cc9e08cbc5928a flags verified ) -) - game ( name "Grinch (Japan)" description "Grinch (Japan)" @@ -38906,24 +39512,6 @@ game ( rom ( name "Guiwu Zhe 2 (Taiwan) (Unl).gbc" size 2097152 crc 955bc6ad sha1 5fe41ac064f4b4d4476ef4177a2f4d69fae1a933 ) ) -game ( - name "Gun Law (World) (Aftermarket) (Unl)" - description "Gun Law (World) (Aftermarket) (Unl)" - rom ( name "Gun Law (World) (Aftermarket) (Unl).gbc" size 262144 crc 3a0b6823 sha1 c49f7e0a5055f836528a7bc0cb6f45f221c76475 ) -) - -game ( - name "Gunslinger (World) (Aftermarket) (Unl)" - description "Gunslinger (World) (Aftermarket) (Unl)" - rom ( name "Gunslinger (World) (Aftermarket) (Unl).gbc" size 262144 crc 0dfd765f sha1 8410ef1558649f9badc71629827ba1500510d221 ) -) - -game ( - name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" - description "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" - rom ( name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl).gbc" size 524288 crc 2d9b59bf sha1 d89fe1cd97d1ef2c457aa90b1c00e7b473c57270 ) -) - game ( name "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" description "Guruguru Garakutas (Japan) (SGB Enhanced) (GB Compatible)" @@ -38942,12 +39530,6 @@ game ( rom ( name "Gute Zeiten Schlechte Zeiten Quiz (Germany) (GB Compatible).gbc" size 1048576 crc 5f13a2d4 sha1 611d8ab71bdeb6b0fd292118676e85e940d11bd4 ) ) -game ( - name "Guzzler (World) (Aftermarket) (Unl)" - description "Guzzler (World) (Aftermarket) (Unl)" - rom ( name "Guzzler (World) (Aftermarket) (Unl).gbc" size 524288 crc 3684abd0 sha1 e36cd02fe2b697901843c4cbf6d83da8a9b7b923 ) -) - game ( name "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" description "Gyouten Ningen Batseelor - Doctor Guy no Yabou (Japan)" @@ -38978,12 +39560,6 @@ game ( rom ( name "Halloween Racer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 1048576 crc 70f3b431 sha1 15bf27a7847817fbbb9cb7729b8046a6d70164c5 ) ) -game ( - name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" - description "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c7297c31 sha1 c38cc0e80a2e04693e3a86574c03f23f3e472c88 flags verified ) -) - game ( name "Hamster Club (Japan) (GB Compatible)" description "Hamster Club (Japan) (GB Compatible)" @@ -39098,12 +39674,6 @@ game ( rom ( name "Hang Time Basketball (Europe) (Unl).gbc" size 262144 crc 3207b7d9 sha1 340201c045c020be6de3504fdecbce1ff07a2139 ) ) -game ( - name "Harbour Attack (World) (Aftermarket) (Unl)" - description "Harbour Attack (World) (Aftermarket) (Unl)" - rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc 7455782e sha1 1d0b3779007ba8f34e11b189552955dbf5c75a28 ) -) - game ( name "Harley-Davidson Motor Cycles - Race Across America (USA)" description "Harley-Davidson Motor Cycles - Race Across America (USA)" @@ -39200,30 +39770,6 @@ game ( rom ( name "Harvest Moon GBC (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc ab5738a1 sha1 d407b9c20c5381f46ec460858539a5b6f559e04f ) ) -game ( - name "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" - description "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Haunted (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 4b3670bd sha1 f245b8e21716a400769488b852f15d276f3549a6 ) -) - -game ( - name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" - description "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) -) - -game ( - name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6e484d6a sha1 7282ef5cc2354345c8832b4dde66a559de74f73f ) -) - -game ( - name "Heebie Jeebies (World) (Aftermarket) (Unl)" - description "Heebie Jeebies (World) (Aftermarket) (Unl)" - rom ( name "Heebie Jeebies (World) (Aftermarket) (Unl).gbc" size 262144 crc 73762d53 sha1 d427f18cb854e1387d93c19b88cb7193975e6472 ) -) - game ( name "Hejin Zhuangbei II (Taiwan) (Unl)" description "Hejin Zhuangbei II (Taiwan) (Unl)" @@ -39320,31 +39866,6 @@ game ( rom ( name "Hexcite - The Shapes of Victory (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 84084e5f sha1 bb00ff88af717b45e08ef421ac77e0546870b1f4 flags verified ) ) -game ( - name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" - description "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Hidden Gems (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6f430dda sha1 e0cfe038063b1cd601a5f1b5af047efc705a7aaa ) -) - -game ( - name "High Noon (World) (Aftermarket) (Unl)" - description "High Noon (World) (Aftermarket) (Unl)" - rom ( name "High Noon (World) (Aftermarket) (Unl).gbc" size 262144 crc 1d00e48d sha1 21d5e871ed009a674659344d3d768fb2389c0d04 ) -) - -game ( - name "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" - description "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" - rom ( name "Hime's Quest (World) (Digital) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) -) - -game ( - name "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" - description "Hime's Quest (World) (Cart) (Aftermarket) (Unl)" - rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl).gbc" size 2097152 crc 546f578a sha1 ff90ca3ec7fb5d02865ae3cfd807ad3541dd21fc ) - rom ( name "Hime's Quest (World) (Cart) (Aftermarket) (Unl) (Factory Save).sav" size 32768 crc d5ed60c7 sha1 8d6c2e9da87837ba16bbd07247a91a0c3050d2fe ) -) - game ( name "Hiryuu no Ken - Retsuden GB (Japan)" description "Hiryuu no Ken - Retsuden GB (Japan)" @@ -39405,12 +39926,6 @@ game ( rom ( name "Honkaku Yonin Uchi Mahjong - Mahjong Ou (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 8ed4bbba sha1 222487f14aaaa8f0bb536a09238e63ac95636208 ) ) -game ( - name "Host, The (World) (Aftermarket) (Unl)" - description "Host, The (World) (Aftermarket) (Unl)" - rom ( name "Host, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 5f783000 sha1 05cc1f1e52167c6985ebb0a3e67af1fc2fbff93c ) -) - game ( name "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" description "Hot Wheels - Stunt Track Driver (USA, Europe) (SGB Enhanced) (GB Compatible)" @@ -39429,12 +39944,6 @@ game ( rom ( name "Hoyle Casino (USA).gbc" size 1048576 crc 413473b0 sha1 827efa6d7b56e919b95ae52c451be2a40d870822 ) ) -game ( - name "Hugo (World) (Aftermarket) (Unl)" - description "Hugo (World) (Aftermarket) (Unl)" - rom ( name "Hugo (World) (Aftermarket) (Unl).gbc" size 524288 crc 6581c78a sha1 390d2665f34ceaa5e34cc9f8f7c26d9e7583a92b ) -) - 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)" @@ -39507,12 +40016,6 @@ game ( rom ( name "Indiana Jones and the Infernal Machine (USA, Europe) (En,Fr,De).gbc" size 1048576 crc 7fff1142 sha1 6d568438aa3b9b67c55aded582cec136b15c46d7 flags verified ) ) -game ( - name "Infall (World) (Aftermarket) (Unl)" - description "Infall (World) (Aftermarket) (Unl)" - rom ( name "Infall (World) (Aftermarket) (Unl).gbc" size 131072 crc d9d90319 sha1 aafaf33fa43c7f0fd65cc8af03a42df25361fc74 ) -) - game ( name "Infinity (USA) (Proto) (2001-03-22)" description "Infinity (USA) (Proto) (2001-03-22)" @@ -39537,12 +40040,6 @@ game ( rom ( name "Inspector Gadget - Operation Madkactus (USA).gbc" size 1048576 crc 1af0b489 sha1 b0fa81a35e605948df3b7f1fcb5893bab99d9d6a ) ) -game ( - name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fea1cdb9 sha1 ac10ca63f15ca78af9f7d0eabb85eef8733aef50 ) -) - game ( name "International Karate 2000 (Europe)" description "International Karate 2000 (Europe)" @@ -39597,12 +40094,6 @@ game ( rom ( name "International Track & Field - Summer Games (Europe).gbc" size 1048576 crc d826c75f sha1 53e158cb23fa79026345dae775d9f020218f8bb2 ) ) -game ( - name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d6c1c1ac sha1 d722e95155455cf146a97222ccbc2237bea86509 ) -) - game ( name "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" description "It's a World Rally (Japan) (SGB Enhanced) (GB Compatible)" @@ -39669,12 +40160,6 @@ game ( rom ( name "Jay und die Spielzeugdiebe (Germany).gbc" size 1048576 crc 73f4f6da sha1 dd01d68bab2d3615f173e4c9c94da56248fab580 ) ) -game ( - name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" - description "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9e97ac30 sha1 c07237d0f9c13b36ac2fcc5324b6e81122b0e189 ) -) - game ( name "Jeff Gordon XS Racing (USA) (GB Compatible)" description "Jeff Gordon XS Racing (USA) (GB Compatible)" @@ -39699,12 +40184,6 @@ game ( rom ( name "Jet de Go! - Let's Go by Airliner (Japan).gbc" size 2097152 crc 20c4ccf6 sha1 97bf75afa0089ddb342ea7046b7cd113ba2c6fec ) ) -game ( - name "Jet Set Willy (World) (Aftermarket) (Unl)" - description "Jet Set Willy (World) (Aftermarket) (Unl)" - rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gbc" size 262144 crc 659295ee sha1 bcb5a0e4566572aeb6cddea0897903ba207dc54f ) -) - game ( name "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" description "Jibaku-kun - Rei no Itsuki no Kajitsu (Japan) (Proto)" @@ -39807,18 +40286,6 @@ game ( 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 "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8884d532 sha1 a41195443613fb4414d8536b1f3494677f6f253d ) -) - -game ( - name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" - description "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 570a8043 sha1 1ccbf555412a417135acea0b7b185a7f795a89da ) -) - game ( name "Juedui Wuli (Taiwan) (Unl)" description "Juedui Wuli (Taiwan) (Unl)" @@ -40041,12 +40508,6 @@ game ( rom ( name "Ken Griffey Jr.'s Slugfest (USA).gbc" size 1048576 crc 1e64d19c sha1 2362bdd8c26f30adb871259ce2d909ac6d505e36 ) ) -game ( - name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6a5abba1 sha1 0b3deef7a27201e81b4d39bc0bd10ff7ec73e380 ) -) - game ( 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)" @@ -40065,12 +40526,6 @@ game ( rom ( name "Kikansha Thomas - Sodor-tou no Nakama-tachi (Japan).gbc" size 1048576 crc 223bb19c sha1 8abd4406ec19bfecd6d675285fa73ef2d5ea622e ) ) -game ( - name "Kikstart (World) (Aftermarket) (Unl)" - description "Kikstart (World) (Aftermarket) (Unl)" - rom ( name "Kikstart (World) (Aftermarket) (Unl).gbc" size 524288 crc 9a9f483b sha1 bc472506f73f0c1a3f0a610c0136b324b7635c7f ) -) - game ( 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)" @@ -40167,12 +40622,6 @@ game ( rom ( name "Klustar (Japan) (Proto 1) (1998-10-01) (GB Compatible).gbc" size 131072 crc f9c6e0a5 sha1 4990b427f1b85ceca9646b3edfa921ed160a55a9 ) ) -game ( - name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f19d5e86 sha1 0f0e01a143182a9784c80a882ac206d02d8679d7 ) -) - game ( name "Knockout Kings (USA, Europe)" description "Knockout Kings (USA, Europe)" @@ -40257,6 +40706,12 @@ game ( rom ( name "Koto Battle - Tengai no Moribito (Japan).gbc" size 2097152 crc 430eb1e1 sha1 ac30025352026b34a0d9ccede82862f6e04aaf00 ) ) +game ( + name "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate)" + description "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate)" + rom ( name "Koudai Guaishou - Da Jihe (Taiwan) (Ja) (Pirate).gbc" size 2097152 crc a96e26c4 sha1 69d345f0da430d0b1c5f4edd086f244ddcf49c78 ) +) + game ( name "Koudai Guaishou - Dongzuo Pian (Taiwan) (En) (Unl)" description "Koudai Guaishou - Dongzuo Pian (Taiwan) (En) (Unl)" @@ -40330,27 +40785,15 @@ game ( ) game ( - name "Laser Squad Alter (World) (Aftermarket) (Unl)" - description "Laser Squad Alter (World) (Aftermarket) (Unl)" - rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) ) game ( - name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4a58315b sha1 5a234e33f7429b48f4374b5989e6df4d20352b4c ) -) - -game ( - name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c405584 sha1 3ee043ba17f46a6afbbba8ac05f35d093b817fbc ) -) - -game ( - name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9a134100 sha1 75b5188a5b8a720ff08894379147c7870ac8825d ) + name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" + rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) ) game ( @@ -40365,42 +40808,12 @@ game ( rom ( name "Laura (USA).gbc" size 1048576 crc e2bff286 sha1 3fe3eb99ee818c94e9a07e19640af6a2aad33903 ) ) -game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Beta).gbc" size 1048576 crc f90a3dae sha1 772539821e4b703259b2e2ad535d74a03fa22760 ) -) - -game ( - name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - description "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto)" - rom ( name "Laura (Europe) (En,Fr,De,Es,It,Nl,Sv,Da) (Rev 1) (Proto).gbc" size 1048576 crc cf8e2371 sha1 f7b19c1501d325dd8ee219ccae2eaca130a5a21b ) -) - 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 sha1 cb4847cd63c8cc52f04bf4d86d54954be3d8fc1a ) ) -game ( - name "Leaper (World) (Aftermarket) (Unl)" - description "Leaper (World) (Aftermarket) (Unl)" - rom ( name "Leaper (World) (Aftermarket) (Unl).gbc" size 524288 crc ed8cd385 sha1 425db2916263121f4aee91a8cab6286e39364f87 ) -) - -game ( - name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 953e25d1 sha1 018c7cada41e693a02b9c596d307b0aa9207eef4 ) -) - -game ( - name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1096252a sha1 c22cc79b25a05afad66e769dc0365b7c25f1bb85 ) -) - game ( name "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" description "Legend of the River King 2 (Europe) (SGB Enhanced) (GB Compatible)" @@ -40434,7 +40847,7 @@ game ( game ( 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 ) + 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 ( @@ -40480,9 +40893,9 @@ game ( ) game ( - name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" - description "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" - rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 8afd751e sha1 797925a26eb39656aea60e10c8e9dd986b515b53 ) + name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + description "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible)" + rom ( name "Legend of Zelda, The - Link's Awakening DX (France) (Rev 1) (Beta) (1999-09-22) (SGB Enhanced) (GB Compatible).gbc" size 1015808 crc 8afd751e sha1 797925a26eb39656aea60e10c8e9dd986b515b53 ) ) game ( @@ -40641,24 +41054,6 @@ game ( rom ( name "Lemmings VS (Japan).gbc" size 4194304 crc 947d45ae sha1 2ebb428a53acbcbc215f37bb263e44d94f547473 ) ) -game ( - name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" - description "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a91a698f sha1 26f38b3908c086b3e349324da32bc37213975030 ) -) - -game ( - name "Liberator (World) (Aftermarket) (Unl)" - description "Liberator (World) (Aftermarket) (Unl)" - rom ( name "Liberator (World) (Aftermarket) (Unl).gbc" size 262144 crc ebe70d3d sha1 e3afce5a2357732ed15d7f3c0900f7b48113efdc ) -) - -game ( - name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" - description "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b8dd8409 sha1 281abb583ec0039e2c981c2e95f7a92002da081b ) -) - game ( name "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" description "Lil' Monster (USA) (SGB Enhanced) (GB Compatible)" @@ -40707,12 +41102,6 @@ game ( rom ( name "LNF Stars 2001 (France).gbc" size 1048576 crc f8bf3ee7 sha1 07a0e1c0ddde6371dbaf25fd016bdc77c0eca090 ) ) -game ( - name "Loco-coco (World) (Aftermarket) (Unl)" - description "Loco-coco (World) (Aftermarket) (Unl)" - rom ( name "Loco-coco (World) (Aftermarket) (Unl).gbc" size 262144 crc f6b9fe4e sha1 8a8972ff3e208280a746a2015a20f67248180a1c ) -) - game ( name "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" description "Lode Runner - Domudomu Dan no Yabou (Japan) (GB Compatible)" @@ -40953,24 +41342,18 @@ game ( rom ( name "Luke Yingxiong 2 - Zook Hero 2 (Taiwan) (Unl).gbc" size 524288 crc 59822b31 sha1 4bf85d9641e3b842a917474dcb49a8b7f282711b ) ) +game ( + name "Luke Yingxiong Chuan 3 (Taiwan) (Unl)" + description "Luke Yingxiong Chuan 3 (Taiwan) (Unl)" + rom ( name "Luke Yingxiong Chuan 3 (Taiwan) (Unl).gbc" size 4194304 crc bd0e7c73 sha1 a095388a2ba13f0f846bbf4ee86ef25e49327c67 ) +) + game ( name "Luke Yingxiong Z (Taiwan) (Unl)" description "Luke Yingxiong Z (Taiwan) (Unl)" rom ( name "Luke Yingxiong Z (Taiwan) (Unl).gbc" size 1048576 crc 8ced0c21 sha1 271097c99be5f60fbdb561875d006a622093fe70 ) ) -game ( - name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" - description "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" - rom ( name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) -) - -game ( - name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" - description "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" - rom ( name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl).gbc" size 262144 crc de5d5c0b sha1 5f038ef3657d3fbfb3be6917b24c3f933363ad4c ) -) - game ( name "Luoke Yingxiong EXE5 (Taiwan) (Unl)" description "Luoke Yingxiong EXE5 (Taiwan) (Unl)" @@ -41001,18 +41384,6 @@ game ( rom ( name "M&M's Minis Madness (USA) (Sample).gbc" size 1048576 crc 83293b1b sha1 2a0d0b7aa3b96b05bc020da496f2ce08e8fac190 ) ) -game ( - name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) -) - -game ( - name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) -) - game ( name "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" description "Macross 7 - Ginga no Heart o Furuwasero!! (Japan)" @@ -41055,12 +41426,6 @@ game ( rom ( name "Magi-Nation - Keeper's Quest (USA) (Proto).gbc" size 1048576 crc 89de57b7 sha1 7c6b427810be2f0d7496ccb5eff2226d3ed1194e ) ) -game ( - name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" - description "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c276843d sha1 852697a2952d2e7375b73aba877ebc17aa4f4179 ) -) - game ( name "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" description "Magical Chase GB - Minarai Mahoutsukai Kenja no Tani e (Japan)" @@ -41070,7 +41435,7 @@ game ( 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 sha1 8ef276f9c6a64d7cec527bcba8d1b7223de0e01c ) + rom ( name "Magical Drop (Europe) (En,Fr,De).gbc" size 1048576 crc ea9ee203 sha1 8ef276f9c6a64d7cec527bcba8d1b7223de0e01c flags verified ) ) game ( @@ -41103,12 +41468,6 @@ game ( rom ( name "Magical Tetris Challenge (USA).gbc" size 1048576 crc f53cf66c sha1 7cdb0bf463ad87ec8a68a564c3f03dbc890edd7e ) ) -game ( - name "Magician's Curse, The (World) (Aftermarket) (Unl)" - description "Magician's Curse, The (World) (Aftermarket) (Unl)" - rom ( name "Magician's Curse, The (World) (Aftermarket) (Unl).gbc" size 524288 crc f2b1967e sha1 3b5f97f9a0b4d63a3795695b0bda6e969de8e051 ) -) - game ( name "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" description "Mahjong Joou (Japan) (SGB Enhanced) (GB Compatible)" @@ -41289,12 +41648,6 @@ game ( rom ( name "Maya the Bee & Her Friends (Europe) (En,Fr,De) (GB Compatible).gbc" size 1048576 crc 983b1d26 sha1 522d7f33fd39bd00f48208743fb2246ef0bd3ff1 ) ) -game ( - name "Mayhem (World) (Aftermarket) (Unl)" - description "Mayhem (World) (Aftermarket) (Unl)" - rom ( name "Mayhem (World) (Aftermarket) (Unl).gbc" size 262144 crc 4d739ad7 sha1 9f141728a74432820f47cc24d230dc56d6ac099b ) -) - game ( name "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" description "McDonald's Monogatari - Honobono Tenchou Ikusei Game (Japan)" @@ -41427,28 +41780,10 @@ game ( rom ( name "Meitantei Conan - Norowareta Kouro (Japan) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc cabdd802 sha1 0858a619d716b0191713734d506d9f113f0d1c62 ) ) -game ( - name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) -) - -game ( - name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 949c6ab9 sha1 34269af4db6c37b92fdc7f7f914c282174603ba8 ) -) - -game ( - name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 50618f4b sha1 c8d74af4746313800df3a23c1ad01f931e0e2eca flags verified ) -) - game ( 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 ) + rom ( name "Men in Black - The Series (USA, Europe) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 65b8b343 sha1 7ceb1c82bdd185546c3dd5d2653788d74d811f7a flags verified ) ) game ( @@ -41511,12 +41846,6 @@ game ( rom ( name "Metamode (Japan).gbc" size 2097152 crc a76eed5b sha1 1c1d74c810b90cf4d2ee32859eaea569a5b45c3f ) ) -game ( - name "Meteorite (World) (Aftermarket) (Unl)" - description "Meteorite (World) (Aftermarket) (Unl)" - rom ( name "Meteorite (World) (Aftermarket) (Unl).gbc" size 131072 crc fafbcebf sha1 25a81d916f1ed80a2bca2fe7a555433f06d025e3 ) -) - game ( name "Mia Hamm Soccer Shootout (USA)" description "Mia Hamm Soccer Shootout (USA)" @@ -41595,18 +41924,6 @@ game ( rom ( name "Microsoft Pinball Arcade (Europe).gbc" size 1048576 crc 4eb7db14 sha1 f2874f0f3023d96edbdb94e5c0dc181d8baa3efb flags verified ) ) -game ( - name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" - description "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) -) - -game ( - name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" - description "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 177f0b6e sha1 e5fdb741d870de25affdc841c07eaa3000da25f5 ) -) - game ( name "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" description "Midway Presents Arcade Hits - Joust & Defender (USA, Europe) (GB Compatible)" @@ -41655,12 +41972,6 @@ game ( rom ( name "Minnie & Friends - Yume no Kuni o Sagashite (Japan).gbc" size 2097152 crc d47ae577 sha1 146f336d16d165590d09f41f44ba52a81816a033 flags verified ) ) -game ( - name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 854f4297 sha1 a1a44ce8052f06349df3cbdf9a6d976609213d68 ) -) - game ( name "Missile Command (Europe)" description "Missile Command (Europe)" @@ -41670,7 +41981,7 @@ game ( 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 sha1 7bd68586df8754cbc81b2dcbb6e2b5de43f812e8 ) + rom ( name "Missile Command (USA) (Rumble Version).gbc" size 1048576 crc 47543c51 sha1 7bd68586df8754cbc81b2dcbb6e2b5de43f812e8 flags verified ) ) game ( @@ -41697,12 +42008,6 @@ game ( rom ( name "Mission Bravo (USA) (Proto).gbc" size 1048576 crc b8fc72b6 sha1 2833855bb2b9fde988f8efcac3e357ef9f0f4f50 ) ) -game ( - name "Mission Mars (World) (Aftermarket) (Unl)" - description "Mission Mars (World) (Aftermarket) (Unl)" - rom ( name "Mission Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) -) - game ( name "Mizuki Shigeru no Shin Youkaiden (Japan)" description "Mizuki Shigeru no Shin Youkaiden (Japan)" @@ -41745,18 +42050,6 @@ game ( rom ( name "Momotarou Densetsu 1-2 (Japan).gbc" size 2097152 crc da7fb08f sha1 acffa3417c85be574aa28432e29e1d40f28a565b flags verified ) ) -game ( - name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 39480c79 sha1 4348a7903e538e5367f2a60718f43cbeeccf96df ) -) - -game ( - name "Monkey Magic (World) (Aftermarket) (Unl)" - description "Monkey Magic (World) (Aftermarket) (Unl)" - rom ( name "Monkey Magic (World) (Aftermarket) (Unl).gbc" size 262144 crc c9c68715 sha1 bf5dc5593334fe1114461065a2b7284d28b31462 ) -) - game ( name "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" description "Monkey Puncher (Europe) (SGB Enhanced) (GB Compatible)" @@ -41859,12 +42152,6 @@ game ( rom ( name "Montezuma's Return! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc de04772f sha1 616bb04e0254ef2ba9e1ea629493efdcc37d807c ) ) -game ( - name "Monty on the Run (World) (Aftermarket) (Unl)" - description "Monty on the Run (World) (Aftermarket) (Unl)" - rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gbc" size 524288 crc fd1066ac sha1 8390175e6be4731d9afa91715d7f8dd11693bb69 ) -) - game ( name "Moomin no Daibouken (Japan) (Beta)" description "Moomin no Daibouken (Japan) (Beta)" @@ -41919,18 +42206,6 @@ game ( rom ( name "Motocross Maniacs 2 (USA).gbc" size 1048576 crc 17d27fa9 sha1 5a0e7a9a71a88ee79529531274eb3696cf0fa42c ) ) -game ( - name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) -) - -game ( - name "Mr. Angry (World) (Aftermarket) (Unl)" - description "Mr. Angry (World) (Aftermarket) (Unl)" - rom ( name "Mr. Angry (World) (Aftermarket) (Unl).gbc" size 524288 crc b85e63a5 sha1 127ad5315e2bce37614a1e9f8605798e68718926 ) -) - game ( name "Mr. Driller (Europe)" description "Mr. Driller (Europe)" @@ -41970,7 +42245,7 @@ game ( 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 ) + rom ( name "Ms. Pac-Man - Special Color Edition (USA) (SGB Enhanced) (GB Compatible).gbc" size 524288 crc 103e212d sha1 a468f7ad011c1b42ea3144e65607694493e7e4a7 flags verified ) ) game ( @@ -42003,12 +42278,6 @@ game ( rom ( name "Muchang Wuyu GB 6 (Taiwan) (Unl).gbc" size 2097152 crc 416e6efa sha1 86b2de0fc2806f3d13145e2c0296389ec0897a6a ) ) -game ( - name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" - description "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) -) - game ( name "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" description "Mummy Returns, The (Europe) (En,Fr,De,Es,It)" @@ -42033,36 +42302,12 @@ game ( rom ( name "Mummy, The (USA).gbc" size 1048576 crc c6ba9f27 sha1 35b10f392d514bce858c8c64f9c489500466d0ff ) ) -game ( - name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" - description "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" - rom ( name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl).gbc" size 524288 crc ec4f9d49 sha1 357db81755f1f0eb732367dd4090c446eb226ddf ) -) - -game ( - name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" - description "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" - rom ( name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl).gbc" size 524288 crc 1ba7d27f sha1 d4c4be65ba469369cd90aaa733d0a8e8af6bcdc1 ) -) - 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 sha1 2a7f422bf9af9aff126e47ede8b5ceec0630eb08 ) ) -game ( - name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9bff7b15 sha1 1f3aac8a3725cd1d0968529afc1c2031372d8ed1 ) -) - -game ( - name "My Friendly Little Island (World) (Aftermarket) (Unl)" - description "My Friendly Little Island (World) (Aftermarket) (Unl)" - rom ( name "My Friendly Little Island (World) (Aftermarket) (Unl).gbc" size 1048576 crc f6bf0584 sha1 81d724ad696084283712145adfef15769648b045 ) -) - game ( name "Mythri (USA) (Proto 1) (2000-08-02)" description "Mythri (USA) (Proto 1) (2000-08-02)" @@ -42156,7 +42401,7 @@ game ( game ( name "NASCAR 2000 (USA, Europe)" description "NASCAR 2000 (USA, Europe)" - rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54d90a4c sha1 37d3ffb5ae9bcf4c1cab7cece0a19d6b0b45c3a2 ) + rom ( name "NASCAR 2000 (USA, Europe).gbc" size 1048576 crc 54d90a4c sha1 37d3ffb5ae9bcf4c1cab7cece0a19d6b0b45c3a2 flags verified ) ) game ( @@ -42225,6 +42470,24 @@ game ( rom ( name "NBA Jam 2001 (USA, Europe).gbc" size 1048576 crc 3aa75f1c sha1 b1f7230dcccaecb7ae9b2a0e786effac2fc24497 flags verified ) ) +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-02-07).gbc" size 131072 crc 594ee678 sha1 5d8ae5937a374fe4e36fe5303e3ad3757ee9675c ) +) + +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-05-05).gbc" size 1048576 crc 926b47d1 sha1 ddbb720be9dd573728f897abe77569d42dae7baf ) +) + +game ( + name "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26)" + description "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26)" + rom ( name "NBA Jam 2001 (USA, Europe) (Beta) (2000-09-26).gbc" size 1048576 crc 0d5506ae sha1 2859d6ad2af7ff3333ad0d3750a1fd4b3088d47d ) +) + game ( name "NBA Jam 99 (USA, Europe) (GB Compatible)" description "NBA Jam 99 (USA, Europe) (GB Compatible)" @@ -42249,24 +42512,6 @@ game ( rom ( name "NBA Show Time - NBA on NBC (USA) (Rev 1) (Proto).gbc" size 1048576 crc 8bc9be45 sha1 fd4bb16f306e309834e276ed768e8e2ed402e138 ) ) -game ( - name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" - description "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) -) - -game ( - name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 53cf930c sha1 bd3272ca7ead64da3f68f774661a560add433b94 ) -) - -game ( - name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" - description "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 705b150f sha1 6258cf6ad167c9ae86609a8e620face1674a7ea7 ) -) - game ( name "Net de Get - Minigame @ 100 (Japan)" description "Net de Get - Minigame @ 100 (Japan)" @@ -42318,7 +42563,7 @@ game ( game ( 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 ) + rom ( name "NFL Blitz (USA, Europe) (Rev 1) (GB Compatible).gbc" size 524288 crc 107d734b sha1 66b69cba0705f0670759f01cfd586a50c47c7c89 flags verified ) ) game ( @@ -42363,12 +42608,6 @@ game ( rom ( name "Ninja JaJaMaru - The Great World Adventure DX (USA, Europe) (Ninja JaJaMaru Retro Collection) (Switch).gbc" size 262144 crc b5af4ca5 sha1 73efaca14c998dd6790e08f2ce2b6f73e7909ce4 flags verified ) ) -game ( - name "Ninja Master (World) (Aftermarket) (Unl)" - description "Ninja Master (World) (Aftermarket) (Unl)" - rom ( name "Ninja Master (World) (Aftermarket) (Unl).gbc" size 262144 crc bc550b84 sha1 0def135723ac40e4981c88f8888afbd40a15bb40 ) -) - game ( name "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" description "Nintama Rantarou - Ninjutsu Gakuen ni Nyuugaku Shiyou no Dan (Japan)" @@ -42405,12 +42644,6 @@ game ( rom ( name "NSYNC - Get to the Show (USA).gbc" size 1048576 crc f770878b sha1 23b031d03a139c4d963099070b0b290f5f806a6d ) ) -game ( - name "Number Builder (World) (Aftermarket) (Unl)" - description "Number Builder (World) (Aftermarket) (Unl)" - rom ( name "Number Builder (World) (Aftermarket) (Unl).gbc" size 262144 crc b8609d43 sha1 92952b752f50af889db891acc9eed8436ac6b87e ) -) - game ( name "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" description "Nushi Tsuri Adventure - Kite no Bouken (Japan) (Rumble Version)" @@ -42423,66 +42656,6 @@ game ( rom ( name "Nv Wang Gedou 2000 (Taiwan) (Unl).gbc" size 2097152 crc e1668b49 sha1 37516139aa317a16440379c1dc00bdfc4c1e607a flags verified ) ) -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e983e8d1 sha1 fc2a58d49327c88c895ae6681bde57e1a2687974 flags verified ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 581efe4d sha1 125bb0564ee17f8e55046a1c25e53ee9a4254303 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e26ddbbb sha1 853115369b8ca583d038d00c1dde59b6a74b73a2 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 1e8ac5b9 sha1 99c11bef7feb17a9e7212cf9b6593478f671bc32 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f5df28c2 sha1 7b511444e1eb86fffcf93599a78e0e2c44aecc8a ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl).gbc" size 2097152 crc 63bddc68 sha1 fab777e607bd8aba70eb65829143039dbe6ac08e ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 1f1af42a sha1 ddcdbfa716d716e1b7bb258caaaa7b76d041b5a9 ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" - description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt).gbc" size 524288 crc 834a8021 sha1 d5af2bf38eda4c181993e992764788003509ebfd ) -) - -game ( - name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 42d9c38c sha1 ae719190cf2f433c359bc425775710f4aa67e860 ) -) - 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)" @@ -42495,24 +42668,6 @@ game ( rom ( name "O'Leary Manager 2000 (Europe) (En,Fr,De,Es,It,Nl,Ca).gbc" size 1048576 crc 3485761a sha1 724aa0f905d7a6e7b9b2b01a477f424ac95eadf9 ) ) -game ( - name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c055ef9 sha1 d4fa4e02753a9fe539f70d0927ba5bf9caa02d3c ) -) - -game ( - name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" - description "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7ed58128 sha1 e543c39f8e55b1788476b94028a54fc2fc9c7ea0 ) -) - -game ( - 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 "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" description "Oddworld Adventures 2 (USA) (En,Fr,De,Es,It) (GB Compatible)" @@ -42520,9 +42675,9 @@ game ( ) game ( - name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" - description "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) + 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 ( @@ -42555,24 +42710,6 @@ game ( rom ( name "Ojarumaru - Tsukiyo ga Ike no Takaramono (Japan) (GB Compatible).gbc" size 2097152 crc ed7461d2 sha1 66d87a06d4d951e7695df73f53793a462509e4d0 ) ) -game ( - name "Olympic Skier (World) (Aftermarket) (Unl)" - description "Olympic Skier (World) (Aftermarket) (Unl)" - rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gbc" size 524288 crc 5e81cef7 sha1 a7a552a9eb984098a67e063c2eca907eec000fc1 ) -) - -game ( - name "One Day (World) (GB Compatible) (Aftermarket) (Unl)" - description "One Day (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "One Day (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fd52acc7 sha1 bdb5590b61791b89e9afa871d32648d7a66ce1f4 ) -) - -game ( - name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" - description "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7348bb32 sha1 e63e06d602473206b21138f5322acf86b5b6b9b8 ) -) - game ( name "Original Moorhuhn Jagd, Die (Germany)" description "Original Moorhuhn Jagd, Die (Germany)" @@ -42609,12 +42746,6 @@ game ( rom ( name "Ou Dorobou Jing - Devil Version (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 2a39a874 sha1 71797aa125b88614182ce3d0f8252d6ed8cfa08e ) ) -game ( - name "Out on a Limb (World) (Aftermarket) (Unl)" - description "Out on a Limb (World) (Aftermarket) (Unl)" - rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gbc" size 262144 crc a6671528 sha1 f21cb71adcea1029151930eb98c4e9b446e4cfee ) -) - game ( 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)" @@ -42651,42 +42782,12 @@ game ( rom ( name "Pachipachi Pachisurou - New Pulsar Hen (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 1e443d1b sha1 969d5352c15e3e5daa891edcda91bd48a8380308 ) ) -game ( - name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c6e83f41 sha1 44b117d94a80617a77abbdcc76d9d69b66efe56b ) -) - -game ( - name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - description "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 69483f81 sha1 4d162c9637a20cfc7c92e6ea7a61fad0ed22137a ) -) - -game ( - name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" - description "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" - rom ( name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 262144 crc 0db301c2 sha1 58ec8f209ed6e33adfb253014ea69ae1ee53c145 ) -) - -game ( - name "Pact, The (World) (Aftermarket) (Unl)" - description "Pact, The (World) (Aftermarket) (Unl)" - rom ( name "Pact, The (World) (Aftermarket) (Unl).gbc" size 262144 crc 304df19a sha1 97af064f9063cd353e55ac0e1f6d1ca8b4a6d2b9 ) -) - game ( name "Painter (Europe) (Unl)" description "Painter (Europe) (Unl)" rom ( name "Painter (Europe) (Unl).gbc" size 262144 crc f4801f21 sha1 78db482d1d12b4556b6a5b995ce37a2435236a06 ) ) -game ( - name "Panik!16 (World) (Aftermarket) (Unl)" - description "Panik!16 (World) (Aftermarket) (Unl)" - rom ( name "Panik!16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b31122d sha1 98d74fd64e4f7e835f1101b05816b8938a34a416 ) -) - game ( name "Paperboy (USA, Europe)" description "Paperboy (USA, Europe)" @@ -42729,12 +42830,6 @@ game ( rom ( name "Peugeot - Orbital Diagnostic System (Unknown) (Alt) (Unl) [b].gbc" size 32768 crc 424912fe sha1 bd5735021e4593ec07082e6197e683496d0ecf0b flags baddump ) ) -game ( - name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" - description "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) -) - game ( name "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" description "Phantom Zona (Japan) (SGB Enhanced) (GB Compatible)" @@ -42759,24 +42854,6 @@ game ( rom ( name "Piecrust (World) (Unl).gbc" size 32768 crc f39c8119 sha1 b01cad9652bf1c65151dd8d2bd21251a9cf44d43 ) ) -game ( - name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pilgrim's Peril (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c2bafdc sha1 d38f3f5e491dbaed84e88099987712449db9b33d ) -) - -game ( - name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) -) - -game ( - name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" - description "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1601d6fa sha1 87b4edf0398f0154d7556e3cd96f97b19e699a40 ) -) - game ( name "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" description "Pitfall - Beyond the Jungle (USA, Europe) (GB Compatible)" @@ -42807,12 +42884,6 @@ game ( rom ( name "Player Manager 2001 (Europe) (En,Fr).gbc" size 1048576 crc 375c35e0 sha1 6e21a85257361be76914f418409124c5bc315429 ) ) -game ( - name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 29415ff7 sha1 89b3fd633e8cef3b8523b1ef2a0072db2d7416d7 ) -) - game ( name "Pocket Billiards - Funk the 9 Ball (Japan)" description "Pocket Billiards - Funk the 9 Ball (Japan)" @@ -43053,12 +43124,6 @@ game ( rom ( name "Pocket Soccer (Europe) (En,Fr,De,Es,It,Pt).gbc" size 2097152 crc e8f5824f sha1 4d06ea937a02a8f458186a9382994b09a97481a4 ) ) -game ( - name "Pogo Pete (World) (Aftermarket) (Unl)" - description "Pogo Pete (World) (Aftermarket) (Unl)" - rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gbc" size 262144 crc 3001ed1b sha1 f9dab150843c2b8f300d36b1dd53dd1a22b481a3 ) -) - game ( name "Pokemon - Crystal Version (Australia)" description "Pokemon - Crystal Version (Australia)" @@ -43113,6 +43178,18 @@ game ( rom ( name "Pokemon - Kristall-Edition (Germany).gbc" size 2097152 crc 616d85de sha1 accb584293ba056152f1fd908439b019017ff2fe ) ) +game ( + name "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate)" + description "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate)" + rom ( name "Pokemon - La Version Esmeralda - Special Pikachu Edition (Spain) (Pirate).gbc" size 524288 crc 0d009399 sha1 9e953c1acccd3527a555cf4ba25da38adf99755c ) +) + +game ( + name "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl)" + description "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon - Mewtwo Strikes Back (Taiwan) (Zh) (Unl).gbc" size 524288 crc 2930fa45 sha1 382a257199720d970f58e94cd4102acb809dec07 ) +) + game ( name "Pokemon - Mewtwo Strikes Back (Taiwan) (En) (Unl)" description "Pokemon - Mewtwo Strikes Back (Taiwan) (En) (Unl)" @@ -43146,19 +43223,19 @@ game ( 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 ) + rom ( name "Pokemon - Version Argent (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc e0c216ea sha1 a4a7e8079b7a53e4d9ef43382bbb1090b9d45d1a flags verified ) ) game ( name "Pokemon - Version Cristal (France)" description "Pokemon - Version Cristal (France)" - rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878b2aa7 sha1 c055992b16b7399c687647725cdd1f4f13a2f75c ) + rom ( name "Pokemon - Version Cristal (France).gbc" size 2097152 crc 878b2aa7 sha1 c055992b16b7399c687647725cdd1f4f13a2f75c flags verified ) ) game ( 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 ) + rom ( name "Pokemon - Version Or (France) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc 37a70702 sha1 c147c0d8c2b71b7628a7233436f5c052b5b17081 flags verified ) ) game ( @@ -43209,6 +43286,12 @@ game ( rom ( name "Pokemon Diamond (Taiwan) (En) (Unl).gbc" size 524288 crc 1b5bef4b sha1 433e7991b706baedf59af8b91bc142ba2f72112f ) ) +game ( + name "Pokemon Diamond (Taiwan) (Zh) (Unl)" + description "Pokemon Diamond (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Diamond (Taiwan) (Zh) (Unl).gbc" size 524288 crc 7309551a sha1 3fb38a7f49e13f5bfce0cd1983d9006b30f68930 ) +) + game ( name "Pokemon Gold (Taiwan) (En) (Unl)" description "Pokemon Gold (Taiwan) (En) (Unl)" @@ -43227,6 +43310,12 @@ game ( rom ( name "Pokemon Jade (Taiwan) (En) (Pirate).gbc" size 2097152 crc aa07f269 sha1 994a205d7c0b55f45715a65b23ec31258e43652f ) ) +game ( + name "Pokemon Jade (Taiwan) (Zh) (Unl)" + description "Pokemon Jade (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Jade (Taiwan) (Zh) (Unl).gbc" size 524288 crc b9ffd78c sha1 c46c3a9e221da8d41a9eb1a84765368d975dfaa1 ) +) + game ( name "Pokemon Jade Version - Special Pikachu Edition (USA) (Pirate)" description "Pokemon Jade Version - Special Pikachu Edition (USA) (Pirate)" @@ -43275,6 +43364,36 @@ game ( rom ( name "Pokemon Puzzle Challenge (USA, Australia).gbc" size 2097152 crc d06bba96 sha1 bbf952412250ae511b3b862566e424ce6a672f99 flags verified ) ) +game ( + name "Pokemon Ruby (Taiwan) (Unl)" + description "Pokemon Ruby (Taiwan) (Unl)" + rom ( name "Pokemon Ruby (Taiwan) (Unl).gbc" size 524288 crc 7a2fc378 sha1 1f9e62faa85e9058bec16be8b6c14223bb3ac15b ) +) + +game ( + name "Pokemon Sapphire (Taiwan) (En) (Unl)" + description "Pokemon Sapphire (Taiwan) (En) (Unl)" + rom ( name "Pokemon Sapphire (Taiwan) (En) (Unl).gbc" size 524288 crc 8077dd95 sha1 2e3a28e02d5bfe259d9367d1205daa52912a1f8f ) +) + +game ( + name "Pokemon Sapphire (Taiwan) (Zh) (Unl)" + description "Pokemon Sapphire (Taiwan) (Zh) (Unl)" + rom ( name "Pokemon Sapphire (Taiwan) (Zh) (Unl).gbc" size 524288 crc f3c1c00c sha1 75639d4dbe72d044002f768d5dbbd08caf003fdc ) +) + +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 ) +) + game ( 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)" @@ -43293,18 +43412,6 @@ game ( 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 ) -) - game ( name "Pokemon Vision Jade (Taiwan) (De) (Unl)" description "Pokemon Vision Jade (Taiwan) (De) (Unl)" @@ -43312,15 +43419,9 @@ game ( ) game ( - name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" - description "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" - rom ( name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 42298fd8 sha1 90c535bf70e2ca7b91af67b8f08865f423c3034f ) -) - -game ( - name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" - description "Pokettohiro! (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Pokettohiro! (World) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc b9e724ef sha1 28a01fd6ea95a146008435c5bc27b51b607bb86b ) + name "Polaris SnoCross (USA) (Beta) (Rumble Version)" + description "Polaris SnoCross (USA) (Beta) (Rumble Version)" + rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) ) game ( @@ -43329,12 +43430,6 @@ game ( rom ( name "Polaris SnoCross (USA) (Rumble Version).gbc" size 1048576 crc dd8b189e sha1 e893808fe227a1608c0604382d6a0340ec704c3b flags verified ) ) -game ( - name "Polaris SnoCross (USA) (Beta) (Rumble Version)" - description "Polaris SnoCross (USA) (Beta) (Rumble Version)" - rom ( name "Polaris SnoCross (USA) (Beta) (Rumble Version).gbc" size 1048576 crc 673623c4 sha1 4176ef1f9fd37156a4cac37a2d146ed2deeb5a7b ) -) - game ( name "Pong - The Next Level (USA, Europe)" description "Pong - The Next Level (USA, Europe)" @@ -43389,54 +43484,6 @@ game ( rom ( name "Portal Runner (USA).gbc" size 1048576 crc 913ac306 sha1 a8347366f15c0e454fa253bad5b4053d2a9613aa ) ) -game ( - name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 50393a65 sha1 2c2c6ed8be7a13bf279e435c5984f175c8affcad ) -) - -game ( - name "Postie (World) (GB Compatible) (Aftermarket) (Unl)" - description "Postie (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Postie (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff6bbc83 sha1 3ff236972d1e344eb50e696db3cc090f2b5d28b1 ) -) - -game ( - name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6da19041 sha1 eb581935ad9223d723fdbc8339c03436df051947 ) -) - -game ( - name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" - description "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d0d8386d sha1 fbddf81a1663388ff0efeeb9051e68e0c323c839 ) -) - -game ( - name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) -) - -game ( - name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) -) - -game ( - name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) -) - -game ( - name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" - description "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b01c4ff1 sha1 898dbf10550af7e39b8f7a0818a78083ae40f4fe ) -) - game ( name "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" description "Power Pro Kun Pocket (Japan) (SGB Enhanced) (GB Compatible)" @@ -43599,18 +43646,6 @@ game ( rom ( name "Prince of Persia (Japan) (Proto).gbc" size 1048576 crc d7dbbe1e sha1 6fd97e1f75570e7568b3dc4ab28834813afb4484 ) ) -game ( - name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" - description "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a86cada1 sha1 b02096c489c0f36582061d6eb62beb17e8294b61 ) -) - -game ( - name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" - description "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e171f327 sha1 b03df48f48529ac1be79699d6f34f324adcfb436 ) -) - game ( name "Pro Darts (USA)" description "Pro Darts (USA)" @@ -43665,12 +43700,6 @@ game ( rom ( name "Project S-11 (USA).gbc" size 524288 crc 20cee2e8 sha1 cbedd34a0c6a2f4e58d05f0bb6d54f7cbcda815c ) ) -game ( - name "Proof of Destruction (World) (Aftermarket) (Unl)" - description "Proof of Destruction (World) (Aftermarket) (Unl)" - rom ( name "Proof of Destruction (World) (Aftermarket) (Unl).gbc" size 262144 crc fa528f88 sha1 5062f16346c31cae1b13e469cb610ce84d4eecb2 ) -) - game ( name "Puchi Carat (USA) (Proto 2) (SGB Enhanced) (GB Compatible)" description "Puchi Carat (USA) (Proto 2) (SGB Enhanced) (GB Compatible)" @@ -43707,12 +43736,6 @@ game ( rom ( name "Pumuckls Abenteuer im Geisterschloss (Germany).gbc" size 1048576 crc 87fcec24 sha1 0fe14ef81b11c854f080e804c5d3cb14601b2794 ) ) -game ( - name "Purple Turtles (World) (Aftermarket) (Unl)" - description "Purple Turtles (World) (Aftermarket) (Unl)" - rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gbc" size 262144 crc 471277df sha1 a73cb69d1fb42f45f3649c4d1b4775e98fe35b78 ) -) - game ( name "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" description "Puyo Puyo Gaiden - Puyo Wars (Japan) (SGB Enhanced) (GB Compatible)" @@ -43803,12 +43826,6 @@ game ( rom ( name "Quan Ba Tianxia (Taiwan) (Unl).gbc" size 4194304 crc 2c922ed6 sha1 c19eb98a9745d2c2ce9e4dba3f17ae0b3dee0f49 ) ) -game ( - name "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" - description "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Quartet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) -) - game ( name "Quest - Brian's Journey (USA) (GB Compatible)" description "Quest - Brian's Journey (USA) (GB Compatible)" @@ -43821,12 +43838,6 @@ game ( rom ( name "Quest - Fantasy Challenge (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 98285775 sha1 86812b2cd4304dc7ee2dd3faf16737b0414aaffb ) ) -game ( - name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Quest Arrest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) -) - game ( 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)" @@ -43881,12 +43892,6 @@ game ( rom ( name "Radikal Bikers (Europe) (En,Fr,De,Es) (Proto).gbc" size 2097152 crc 81e25d37 sha1 f16aa29669b15153a63ad92388768e38aa18fbf8 ) ) -game ( - name "Raffles (World) (Aftermarket) (Unl)" - description "Raffles (World) (Aftermarket) (Unl)" - rom ( name "Raffles (World) (Aftermarket) (Unl).gbc" size 262144 crc e41d6472 sha1 4b5eb518ff52c235c674e0695fdde2b8b01f58fa ) -) - game ( name "Rainbow Islands (Europe) (En,Fr,De,Es,It)" description "Rainbow Islands (Europe) (En,Fr,De,Es,It)" @@ -43935,12 +43940,6 @@ game ( rom ( name "Rats! (USA) (En,Es) (GB Compatible).gbc" size 524288 crc 17635ad1 sha1 5e423dfab8221b69a641d2e535ebfe1e3759a2e4 ) ) -game ( - name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" - description "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 09196a32 sha1 8218ad22b29fb32c66430a17a97775dd30b2f34b flags verified ) -) - game ( name "Rayman (Europe) (En,Fr,De,Es,It,Nl)" description "Rayman (Europe) (En,Fr,De,Es,It,Nl)" @@ -44025,24 +44024,6 @@ game ( rom ( name "Remen Gaoxiao - Shuma Guaishou III (Taiwan) (Unl).gbc" size 524288 crc 9f64fb1c sha1 b8d6910c8b5c1cab044c61679bbbc4f213648f56 ) ) -game ( - name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc e92034d8 sha1 14b9614cea9be7d5c6e12aece692582ba2ca2b75 flags verified ) -) - -game ( - name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 3a1b1d83 sha1 4dda0cce6907de94eeae3f11a40238c3f5155ca7 ) -) - -game ( - name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 flags verified ) -) - game ( name "Rescue Heroes - Fire Frenzy (USA)" description "Rescue Heroes - Fire Frenzy (USA)" @@ -44085,18 +44066,6 @@ game ( rom ( name "Resident Evil Gaiden (USA).gbc" size 2097152 crc f8c5021b sha1 a302cddc085d65ca778153e2a591bd648ce963c9 ) ) -game ( - name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" - description "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 8bd98942 sha1 3a5dbafa829e57089de8cfc93c806f7ee023ff1b ) -) - -game ( - name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c761189c sha1 f7f18d83218b66b9d1cd7267d6d4acfd4eded6c7 ) -) - game ( name "Return of the Ninja (Europe)" description "Return of the Ninja (Europe)" @@ -44109,6 +44078,12 @@ game ( rom ( name "Return of the Ninja (USA).gbc" size 1048576 crc a07da702 sha1 e33352f0ac19d28983ebed0758d022861473ec0e ) ) +game ( + name "Return of the Ninja (World) (Limited Run Games)" + description "Return of the Ninja (World) (Limited Run Games)" + rom ( name "Return of the Ninja (World) (Limited Run Games).gbc" size 1048576 crc df445c4a sha1 d73049119fbc163183fdb95e9b299ca4d1d4e8e3 ) +) + game ( name "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" description "Revelations - The Demon Slayer (USA) (SGB Enhanced) (GB Compatible)" @@ -44121,24 +44096,12 @@ game ( rom ( name "Rhino Rumble (USA, Europe).gbc" size 1048576 crc 73160e05 sha1 2caf47c20d8632e47c4426dd3564e76415139973 flags verified ) ) -game ( - name "Rig Attack (World) (Aftermarket) (Unl)" - description "Rig Attack (World) (Aftermarket) (Unl)" - rom ( name "Rig Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc d013d775 sha1 90bfd921c986abff4555b761cedc90ec36c43fff ) -) - game ( 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 ) ) -game ( - name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" - description "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae3f980b sha1 67f63517eacfea22922d07be0efc5fc8f8b8a1d2 ) -) - game ( name "Road Champs - BXS Stunt Biking (USA, Europe)" description "Road Champs - BXS Stunt Biking (USA, Europe)" @@ -44160,7 +44123,7 @@ game ( game ( 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 ) + rom ( name "Roadsters (USA) (En,Fr,De,Es,It,Nl) (GB Compatible).gbc" size 1048576 crc 38b022be sha1 ede737e99108be29daf94fee8e10f5dd770731bb flags verified ) ) game ( @@ -44175,18 +44138,6 @@ game ( rom ( name "Robin Hood (Europe) (En,Fr,De,Es,It,Nl).gbc" size 1048576 crc d4f84329 sha1 fe0c42e949bc41f070b22dd24e643aa42b007667 ) ) -game ( - name "Robin to the Rescue (World) (Aftermarket) (Unl)" - description "Robin to the Rescue (World) (Aftermarket) (Unl)" - rom ( name "Robin to the Rescue (World) (Aftermarket) (Unl).gbc" size 262144 crc 9cd52c18 sha1 ef3bea9ed0de41e311b5f15fccbb0f451848d56c ) -) - -game ( - name "Robo Knight (World) (Aftermarket) (Unl)" - description "Robo Knight (World) (Aftermarket) (Unl)" - rom ( name "Robo Knight (World) (Aftermarket) (Unl).gbc" size 524288 crc 8d4507f0 sha1 6012f9a3ae6201e363f46a75e0100552ecb91335 ) -) - game ( name "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" description "RoboCop (Europe) (En,Fr,De,Es,It,Nl)" @@ -44253,12 +44204,6 @@ game ( rom ( name "Rocket Power - La Glisse de l'Extreme (France).gbc" size 1048576 crc c9a7aa7b sha1 b6b9b7b2fb2ff11d41c6531fe21bfd5aa89f7ab4 ) ) -game ( - name "Rockman (World) (Aftermarket) (Unl)" - description "Rockman (World) (Aftermarket) (Unl)" - rom ( name "Rockman (World) (Aftermarket) (Unl).gbc" size 262144 crc 490b5676 sha1 6f78200acb6698e268e26c1912d64a002cbd3d89 ) -) - game ( name "Rockman 3 (Taiwan) (Unl)" description "Rockman 3 (Taiwan) (Unl)" @@ -44272,9 +44217,9 @@ game ( ) game ( - name "Rockman DX8 (Taiwan) (En) (Unl)" - description "Rockman DX8 (Taiwan) (En) (Unl)" - rom ( name "Rockman DX8 (Taiwan) (En) (Unl).gbc" size 1048576 crc 4c6c9eaf sha1 1274bb7d5570f4f1101dff1d13d9b5665deaa3da ) + name "Rockman DX8 (China) (En) (Unl)" + description "Rockman DX8 (China) (En) (Unl)" + rom ( name "Rockman DX8 (China) (En) (Unl).gbc" size 1048576 crc 4c6c9eaf sha1 1274bb7d5570f4f1101dff1d13d9b5665deaa3da ) ) game ( @@ -44379,30 +44324,6 @@ game ( rom ( name "RPG Tsukuru GB (Japan) (Rev 1) (Possible Proto) (NP).gbc" size 2097152 crc 57f82031 sha1 f4c36b3cbb13d3cbaaa81e97b0636c4515ce501e ) ) -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b2547aa6 sha1 981a464d6e1c9e5ac59549845b41dae4817ed3b8 ) -) - -game ( - name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" - description "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c18f82cb sha1 bd8cd5822dcc61f7eb0cf2584c9a5b5a94bde14a ) -) - game ( name "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" description "Rugrats - Time Travelers (USA, Europe) (GB Compatible)" @@ -44457,28 +44378,10 @@ game ( rom ( name "Runelords (USA) (Proto).gbc" size 4194304 crc 392af730 sha1 2bdcf8208cd0530c75195fd23f2f7839a3480bff ) ) -game ( - name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" - description "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" - rom ( name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 2097152 crc 96b1ceec sha1 771135edfbc64f7332a9cbd0d72af7a9d0d71f82 ) -) - -game ( - name "RunieStory (World) (Aftermarket) (Unl)" - description "RunieStory (World) (Aftermarket) (Unl)" - rom ( name "RunieStory (World) (Aftermarket) (Unl).gbc" size 2097152 crc 2249b449 sha1 0f6a391d7e05f66092a98e411069fab8e3f24221 ) -) - -game ( - name "Runner (World) (Aftermarket) (Unl)" - description "Runner (World) (Aftermarket) (Unl)" - rom ( name "Runner (World) (Aftermarket) (Unl).gbc" size 262144 crc 4cd8ccb2 sha1 da735d415ed463a953bac45f4793342bd9be2e96 ) -) - 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 ) + rom ( name "Saban's Power Rangers - Lightspeed Rescue (USA, Europe).gbc" size 1048576 crc 99869172 sha1 e7d0f2f21cdcda49516f682092d0b2017e82d379 flags verified ) ) game ( @@ -44523,18 +44426,6 @@ game ( rom ( name "Sakura Taisen GB 2 - Thunderbolt Sakusen (Japan).gbc" size 4194304 crc 47636a2c sha1 13092603ea1d54264bc48f02c2796947badb462c ) ) -game ( - name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" - description "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) -) - -game ( - name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" - description "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 40dc168d sha1 af25acc86f0eef4ce72199383b96fcb4c9f0115e ) -) - game ( name "Samurai Kid (Japan)" description "Samurai Kid (Japan)" @@ -44565,10 +44456,16 @@ game ( rom ( name "Sangokushi - Game Boy Ban 2 (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc e787b44c sha1 ec6089ff2cfcb17faf6a8ea9a4171869b3c7289b ) ) +game ( + name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt)" + description "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt)" + rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl) (Alt).gbc" size 1048576 crc 728255e5 sha1 d9a978c6b4745d964128eb0eced022337849467c ) +) + game ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl)" description "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl)" - rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl).gbc" size 1048576 crc 728255e5 sha1 d9a978c6b4745d964128eb0eced022337849467c ) + rom ( name "Sanguozhi - Aoshi Tianxia (Taiwan) (Unl).gbc" size 1048576 crc 48d2607f sha1 8ee81543442932b87349eef3a9287a923cec827c ) ) game ( @@ -44607,12 +44504,6 @@ game ( rom ( name "Santa Claus Junior (Europe).gbc" size 1048576 crc a744df64 sha1 ab74474cd63a2c74bf9617907270d26b5d183b89 ) ) -game ( - name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" - description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) -) - game ( name "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" description "Saru Puncher (Japan) (SGB Enhanced) (GB Compatible)" @@ -44823,6 +44714,12 @@ game ( rom ( name "Shantae (USA) (Beta).gbc" size 4194304 crc 3b4d6c50 sha1 141dc57955e84d51f0099c0709a0626d43ab8fa7 ) ) +game ( + name "Shantae (World) (Limited Run Games)" + description "Shantae (World) (Limited Run Games)" + rom ( name "Shantae (World) (Limited Run Games).gbc" size 4194304 crc 96d2774e sha1 71bc428f2746df2a2c6238e14f594d3e5c8da131 ) +) + game ( name "Shantae (World) (Switch)" description "Shantae (World) (Switch)" @@ -44847,12 +44744,6 @@ game ( rom ( name "Shaoling Legend - Hero, the Saver (Taiwan) (En) (Unl).gbc" size 2097152 crc a321ff7d sha1 b1194edd0962c50cf909262004a102f01f556723 ) ) -game ( - name "Shark Attack (World) (Aftermarket) (Unl)" - description "Shark Attack (World) (Aftermarket) (Unl)" - rom ( name "Shark Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc cf80a2ba sha1 291f453a185f836fcafbd7e41945a409638980c0 ) -) - game ( name "Shaun Palmer's Pro Snowboarder (USA, Australia)" description "Shaun Palmer's Pro Snowboarder (USA, Australia)" @@ -44890,9 +44781,21 @@ game ( ) game ( - name "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl)" - description "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl)" - rom ( name "Shi Mian Maifu - Fengyun Pian (Taiwan) (Unl).gbc" size 1048576 crc a5f686c3 sha1 68798ac090df9f5fb1ea9c409adf3dc639bc9842 ) + name "Shi Mian Maifu - Fengyun Pian (China) (Unl)" + description "Shi Mian Maifu - Fengyun Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Fengyun Pian (China) (Unl).gbc" size 1048576 crc a5f686c3 sha1 68798ac090df9f5fb1ea9c409adf3dc639bc9842 ) +) + +game ( + name "Shi Mian Maifu - Tianlong Pian (China) (Unl)" + description "Shi Mian Maifu - Tianlong Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Tianlong Pian (China) (Unl).gbc" size 1048576 crc 605cd86e sha1 b457bafb6b55a82920743d52284918ac74f35852 ) +) + +game ( + name "Shi Mian Maifu - Yingxiong Pian (China) (Unl)" + description "Shi Mian Maifu - Yingxiong Pian (China) (Unl)" + rom ( name "Shi Mian Maifu - Yingxiong Pian (China) (Unl).gbc" size 1048576 crc 2382b3d7 sha1 72077d32c2ab84b6bb1e4ad59bc8c88dbcf1da77 ) ) game ( @@ -45070,9 +44973,9 @@ game ( ) game ( - name "Shuma Baolong 02 5 (China) (Unl)" - description "Shuma Baolong 02 5 (China) (Unl)" - rom ( name "Shuma Baolong 02 5 (China) (Unl).gbc" size 1048576 crc 5ba9f8b5 sha1 c441fcbdb343e0c3c76803aa55ceb728158a8948 ) + name "Shuma Baolong 02 5 (Taiwan) (Unl)" + description "Shuma Baolong 02 5 (Taiwan) (Unl)" + rom ( name "Shuma Baolong 02 5 (Taiwan) (Unl).gbc" size 1048576 crc 5ba9f8b5 sha1 c441fcbdb343e0c3c76803aa55ceb728158a8948 ) ) game ( @@ -45105,72 +45008,12 @@ game ( rom ( name "Shutokou Racing, The (Japan) (SGB Enhanced) (GB Compatible).gbc" size 131072 crc 36e781cd sha1 0f29818190ea9ce8c242b648ba64d50cc5408e5a ) ) -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 599132ec sha1 762087df0e5820f1e50da2a22f9ee3b8d16c3e49 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5370b1bf sha1 966e2d79ab4930039c3d6c43fdbb8cdc068ba347 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 16f34bcc sha1 c34e744b9120e3a1b2b054d3708e4ab594726c5a ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 31ce3f27 sha1 c33d685d5ea5cd6cd954af3bc9ee92719b9578b1 ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc d54b53cb sha1 08948befa0227b795d00fe60e9eede6a1f56597b ) -) - -game ( - name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 314be6b5 sha1 37978f85ae92e7d9a53611659513fd360f57a5b1 ) -) - -game ( - name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" - description "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" - rom ( name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 7ebcdd4e sha1 b99f43719155cafbc3dbd7df0ade281c3c7ba171 ) -) - 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 sha1 a5be079336e48552e53706f0380f35829d91b3c0 ) ) -game ( - name "Skelby (World) (Aftermarket) (Unl)" - description "Skelby (World) (Aftermarket) (Unl)" - rom ( name "Skelby (World) (Aftermarket) (Unl).gbc" size 524288 crc 6ec6c18c sha1 887555aa7e2e61b68a21020237b7d508bb71aded ) -) - -game ( - name "Skycon (World) (Aftermarket) (Unl)" - description "Skycon (World) (Aftermarket) (Unl)" - rom ( name "Skycon (World) (Aftermarket) (Unl).gbc" size 524288 crc 195dbc30 sha1 df29ece6c5f5b14840663495230135dd79c5163a ) -) - -game ( - name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" - description "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) -) - game ( name "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" description "Smurfs Nightmare, The (Europe) (En,Fr,De,Es)" @@ -45183,18 +45026,6 @@ game ( rom ( name "Smurfs Nightmare, The (USA).gbc" size 1048576 crc b50cafe4 sha1 1d0d3512f32176b7035f9c2a77d4636b1d08b349 ) ) -game ( - name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) -) - -game ( - name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6cf39388 sha1 9cf5a1d3e8119303a1f4b04b8f4d8b683aee699e ) -) - game ( name "Snobow Champion (Japan)" description "Snobow Champion (Japan)" @@ -45225,12 +45056,6 @@ game ( rom ( name "Snoopy Tennis (Europe) (En,Fr,De,Es,It,Nl) (Beta).gbc" size 1048576 crc 49db04a6 sha1 03adc2731945bc86588fffedfee2050a00679ce6 ) ) -game ( - name "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" - description "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Snooze (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) -) - 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)" @@ -45255,12 +45080,6 @@ game ( rom ( name "Soccer Manager (Europe) (En,Fr,De,Es).gbc" size 1048576 crc 237ecef9 sha1 353eb6aaf40a78ebf1bca9298726d068a5986efa ) ) -game ( - name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" - description "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" - rom ( name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 9e864f1c sha1 ce5dc23c04ff18dfac2367e53d241e81c4bbc3a3 ) -) - game ( name "Solomon (Japan)" description "Solomon (Japan)" @@ -45381,12 +45200,6 @@ game ( rom ( name "Spawn (USA).gbc" size 2097152 crc 72fcb0ad sha1 4f816eec1b5dc79928ade9f3a3c687b8aa5b2f87 ) ) -game ( - name "Spectipede (World) (Aftermarket) (Unl)" - description "Spectipede (World) (Aftermarket) (Unl)" - rom ( name "Spectipede (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c33f76e sha1 834a450d9ceb78b9d89d551300d4d0ea08cd8a6a ) -) - game ( name "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" description "Speedy Gonzales - Aztec Adventure (USA, Europe) (GB Compatible)" @@ -45420,7 +45233,7 @@ game ( 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 sha1 22c63fa198df68edb9cbe22e35cbd307174c9eb9 ) + rom ( name "Spider-Man 2 - The Sinister Six (USA, Europe).gbc" size 1048576 crc a7faaccf sha1 22c63fa198df68edb9cbe22e35cbd307174c9eb9 flags verified ) ) game ( @@ -45429,12 +45242,6 @@ game ( rom ( name "Spider-Man 3 - Movie Version (USA) (Unl).gbc" size 2097152 crc 2c0d43a9 sha1 8a6b6a1300db59b86ddf87599cfc8edd2e52e2b0 ) ) -game ( - name "Spiky Harold (World) (Aftermarket) (Unl)" - description "Spiky Harold (World) (Aftermarket) (Unl)" - rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gbc" size 262144 crc 7e9eda35 sha1 486d294b8cf226876581d543e3a08018321bc402 ) -) - game ( 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)" @@ -45495,12 +45302,6 @@ game ( rom ( name "Star Heritage (Europe) (Proto) (Password Version).gbc" size 1048576 crc b39b4532 sha1 6eb2c27e2eedb22b4055ded87fce0621d460fe5b ) ) -game ( - name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" - description "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 29320841 sha1 890fda255106ea64bac4973e2e9f4b31bb925d35 ) -) - game ( name "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" description "Star Ocean - Blue Sphere (Japan) (SGB Enhanced) (GB Compatible)" @@ -45537,36 +45338,12 @@ game ( rom ( name "Star Wars Episode I - Racer (USA, Europe) (Rumble Version).gbc" size 2097152 crc 0ebc5758 sha1 c0613d654a4382f0c50fd4d389d3a6aeef4d5207 flags verified ) ) -game ( - name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" - description "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) -) - -game ( - name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" - description "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ce90a95b sha1 75457c5affd0c126f2c916e857950b5cde46a95e ) -) - -game ( - name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" - description "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3a04b44 sha1 b16f21b46dfe4e6ce0368e3c5a3fae397274ebbf ) -) - game ( name "Startled 911 (Taiwan) (En) (Unl)" description "Startled 911 (Taiwan) (En) (Unl)" rom ( name "Startled 911 (Taiwan) (En) (Unl).gbc" size 2097152 crc 7273a4f4 sha1 14154ba420826a406890079d7cc0b420a042e34f ) ) -game ( - name "Stellar Wars (World) (Aftermarket) (Unl)" - description "Stellar Wars (World) (Aftermarket) (Unl)" - rom ( name "Stellar Wars (World) (Aftermarket) (Unl).gbc" size 262144 crc e0b96256 sha1 ba2d10a2a5f3f073aea11e26ae5c53c9cf7866f8 ) -) - game ( name "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" description "Stranded Kids (Europe) (En,Fr,De) (SGB Enhanced) (GB Compatible)" @@ -45615,18 +45392,6 @@ game ( rom ( name "Stuart Little - The Journey Home (USA, Europe).gbc" size 1048576 crc eb273887 sha1 d3c31e41709c54af328787036db1b98997f508ea ) ) -game ( - name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" - description "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2dc3fdae sha1 a551d904c4af661bd4b6e88063cb5541900117b0 ) -) - -game ( - name "Suicide Run (World) (Aftermarket) (Unl)" - description "Suicide Run (World) (Aftermarket) (Unl)" - rom ( name "Suicide Run (World) (Aftermarket) (Unl).gbc" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) -) - game ( name "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" description "Super 16 in 1 (Taiwan) (En) (Sachen) (Unl)" @@ -45675,18 +45440,18 @@ game ( rom ( name "Super Breakout! (USA) (GB Compatible).gbc" size 1048576 crc 52f51cb5 sha1 8c795b6d8ebc3a796821a6b2879f3e5cebf9215c ) ) -game ( - name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c47330e2 sha1 6151286e93b2e2fb92f583371e650e36ab91aaf7 ) -) - 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 sha1 0296d0a60933c798b21399195789d10eb319872f ) ) +game ( + name "Super Color 26-in-1 (Taiwan) (Unl)" + description "Super Color 26-in-1 (Taiwan) (Unl)" + rom ( name "Super Color 26-in-1 (Taiwan) (Unl).gbc" size 4194304 crc 71e9a5d9 sha1 0f8657e4583389a23d61d8d0bd7fe322bcaabf6b ) +) + game ( name "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" description "Super Doll Licca-chan - Kisekae Daisakusen (Japan)" @@ -45729,42 +45494,6 @@ game ( rom ( name "Super Gals! Kotobuki Ran 2 - Miracle Getting (Japan).gbc" size 4194304 crc e77fa0f2 sha1 a724c6dd33b84ae9120d041fc49d66692c798dd0 ) ) -game ( - name "Super Gran (World) (Aftermarket) (Unl)" - description "Super Gran (World) (Aftermarket) (Unl)" - rom ( name "Super Gran (World) (Aftermarket) (Unl).gbc" size 262144 crc 98ee2e8a sha1 5afe9c7ab1b9d86048a570e7a37a0c244cb84e43 ) -) - -game ( - name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" - description "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl).gbc" size 524288 crc 8e1f6bb0 sha1 27522a35211b0f015fa9550c2520f1da1c346886 ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl).gbc" size 524288 crc f9731ee2 sha1 23855b95d04a6c7c6d2ce7977bb31dbe6c0e68a0 ) -) - -game ( - name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" - description "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" - rom ( name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) -) - -game ( - name "Super JetPak DX (World) (GB Compatible) (Aftermarket)" - description "Super JetPak DX (World) (GB Compatible) (Aftermarket)" - rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c flags verified ) -) - game ( name "Super Mario Bros. Deluxe (Japan) (NP)" description "Super Mario Bros. Deluxe (Japan) (NP)" @@ -45951,18 +45680,6 @@ game ( rom ( name "SWiV (Europe) (En,Fr,De,Es,It).gbc" size 1048576 crc 44d30b7a sha1 7e037008eabf01fa647cdfb0d5c88766a6f77423 ) ) -game ( - name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" - description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) -) - -game ( - name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - description "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b2b5dc4b sha1 aaa66863b2e68865359d1c0db2047bab6f64f9ee ) -) - game ( 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)" @@ -46029,6 +45746,12 @@ game ( rom ( name "Taikong Zhanshi DX3 - Zuizhong Huanxiang (Taiwan) (Unl).gbc" size 2097152 crc ddf36a27 sha1 0a62b484c5730a3a1f8b32cc2ed97af128d2130c ) ) +game ( + name "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl)" + description "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl)" + rom ( name "Taikong Zhanshi X - Fantasy War (Taiwan) (Unl).gbc" size 1048576 crc 09fedecc sha1 c4fd2de9cf8d75de069abadf165252dac5712691 ) +) + game ( name "Taisen Tsume Shougi (Japan) (NP) (GB Compatible)" description "Taisen Tsume Shougi (Japan) (NP) (GB Compatible)" @@ -46047,36 +45770,18 @@ game ( 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 Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" - description "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) -) - game ( 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 "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" - description "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" - rom ( name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl).gbc" size 262144 crc 257d9201 sha1 d78e0b03a3915531e780057c4ad7ed2b3f849825 ) -) - game ( 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 ) ) -game ( - name "Tank Attack (World) (Aftermarket) (Unl)" - description "Tank Attack (World) (Aftermarket) (Unl)" - rom ( name "Tank Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c77dc518 sha1 4751a6999f4dbe7e66b997372588f6bd15e4d9d0 ) -) - game ( name "Tarzan (France)" description "Tarzan (France)" @@ -46131,18 +45836,6 @@ game ( rom ( name "Taxi 3 (France).gbc" size 1048576 crc 2838996f sha1 e43817c673d47b7587f542dcc9f74190c63629ff ) ) -game ( - name "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-13) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) -) - -game ( - name "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" - description "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" - rom ( name "Tazz (World) (2022-10-17) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) -) - game ( name "Tech Deck Skateboarding (USA, Europe)" description "Tech Deck Skateboarding (USA, Europe)" @@ -46299,18 +45992,6 @@ game ( rom ( name "Tintin au Tibet (Europe) (En,Fr,De,Es,It,Nl,Sv).gbc" size 1048576 crc 6832f38a sha1 eef17d4a827efab90c03083edb0bee534cd64188 ) ) -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) -) - -game ( - name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) -) - 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)" @@ -46335,12 +46016,6 @@ game ( rom ( name "Tiny Toon Adventures - Dizzy's Candy Quest (USA) (Proto).gbc" size 1048576 crc 23bb87a5 sha1 4eb0359a278173ae6c12e9452a7a2a9573a58c77 ) ) -game ( - name "Tir Na Nog (World) (Aftermarket) (Unl)" - description "Tir Na Nog (World) (Aftermarket) (Unl)" - rom ( name "Tir Na Nog (World) (Aftermarket) (Unl).gbc" size 1048576 crc 44524c90 sha1 ac712228460e9d4268f90ec4cf9ac2137fa667c4 ) -) - game ( name "Titi - Le Tour du Monde en 80 Chats (France)" description "Titi - Le Tour du Monde en 80 Chats (France)" @@ -46365,12 +46040,6 @@ game ( rom ( name "TNN Outdoors Fishing Champ (USA) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 00a14d18 sha1 acfe7c9edd20f7d6b155deebc9428703edf28978 ) ) -game ( - name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - description "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 16650a8b sha1 fe6eef70d48dda741f7ad3b6cc5e753e8cd13239 ) -) - game ( name "TOCA Touring Car Championship (USA, Europe)" description "TOCA Touring Car Championship (USA, Europe)" @@ -46479,12 +46148,6 @@ game ( rom ( name "Tomb Raider 2 (Taiwan) (Unl).gbc" size 4194304 crc 717a5d19 sha1 5b9325b6e322a806677c6ea37a0054381609b99e ) ) -game ( - name "Tomte Trouble (World) (Aftermarket) (Unl)" - description "Tomte Trouble (World) (Aftermarket) (Unl)" - rom ( name "Tomte Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc a43d6b82 sha1 99730fe00703d655b1c806f49c9e3c2fb3dec58e flags verified ) -) - game ( name "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" description "Tonic Trouble (Europe) (En,Fr,De,Es,It,Nl)" @@ -46518,7 +46181,7 @@ game ( 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 sha1 6a86b7172c53a8e67f3d72f953116991640f6e71 ) + rom ( name "Tonka Raceway (USA) (Rumble Version).gbc" size 1048576 crc a5af4b28 sha1 6a86b7172c53a8e67f3d72f953116991640f6e71 flags verified ) ) game ( @@ -46653,12 +46316,6 @@ game ( rom ( name "Tottoko Hamutarou 2 - Hamu-chan Zu Daishuugou Dechu (Japan).gbc" size 2097152 crc f1fbcf84 sha1 adb1d5242a62d41c6e435b31082685ea4eec651a flags verified ) ) -game ( - name "Tower of Evil (World) (Aftermarket) (Unl)" - description "Tower of Evil (World) (Aftermarket) (Unl)" - rom ( name "Tower of Evil (World) (Aftermarket) (Unl).gbc" size 524288 crc aeb6e36f sha1 e9a6a007e935afb522c67d355e0354b0fb9af3c6 ) -) - game ( name "Towers - Lord Baniff's Deceit (USA, Europe)" description "Towers - Lord Baniff's Deceit (USA, Europe)" @@ -46713,18 +46370,6 @@ game ( rom ( name "Trade & Battle Card Hero (Japan) (Rev 1) (3DS Virtual Console) (SGB Enhanced) (GB Compatible).gbc" size 2097152 crc d98a877d sha1 c6c1e0365166b53d25a1f84bc380948a9661df30 ) ) -game ( - name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" - description "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b0a32d51 sha1 4c0d639722d1cd8393e008d174b8f7266d089ead ) -) - -game ( - name "Treasure Island Color (World) (Aftermarket) (Unl)" - description "Treasure Island Color (World) (Aftermarket) (Unl)" - rom ( name "Treasure Island Color (World) (Aftermarket) (Unl).gbc" size 262144 crc 4ab0eb5a sha1 3ebddd4e1f5b3a87726ef34a5b7d36de8c722f36 ) -) - game ( name "Trick Boarder (Europe)" description "Trick Boarder (Europe)" @@ -46743,6 +46388,12 @@ game ( rom ( name "Trickboarder GP (Japan).gbc" size 1048576 crc 31740097 sha1 263d8612ecdf651115df6f896737b8c498c970c0 ) ) +game ( + name "Trip World DX (World) (Limited Run Games)" + description "Trip World DX (World) (Limited Run Games)" + rom ( name "Trip World DX (World) (Limited Run Games).gbc" size 524288 crc af17b3eb sha1 6871dd15e2081432ab4c7727f88491f7bbd95099 flags verified ) +) + game ( name "Triple Play 2001 (USA, Europe)" description "Triple Play 2001 (USA, Europe)" @@ -46755,12 +46406,6 @@ game ( rom ( name "Trouballs (USA).gbc" size 524288 crc 260eed04 sha1 dc4d0f608354e7cc32df7501dbacf8c50d70e728 ) ) -game ( - name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" - description "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) -) - game ( name "True Color 25 in 1 (Taiwan) (Unl)" description "True Color 25 in 1 (Taiwan) (Unl)" @@ -46815,24 +46460,12 @@ game ( rom ( name "Turok 3 - Shadow of Oblivion (USA, Europe) (En,Fr,De,Es).gbc" size 1048576 crc 6d48765e sha1 4b240f6b8e3648f2cbafa2fd6ee4e5b508950122 flags verified ) ) -game ( - name "Tutti Frutti (World) (Aftermarket) (Unl)" - description "Tutti Frutti (World) (Aftermarket) (Unl)" - rom ( name "Tutti Frutti (World) (Aftermarket) (Unl).gbc" size 262144 crc ca377ca6 sha1 53d97b93b9d190de40ed2d81e18b4cbe44f99a23 ) -) - game ( name "Tutty (Europe) (Demo)" description "Tutty (Europe) (Demo)" rom ( name "Tutty (Europe) (Demo).gbc" size 131072 crc c4655f0a sha1 51883c4cc1469987483f993e3904da22690faeb9 ) ) -game ( - name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - description "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 01239312 sha1 4f21c3539ef40a7630581fe50533371e0d1a1ba9 ) -) - game ( name "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" description "Tweenies - Doodles' Bones (Europe) (En,De,Es,It)" @@ -46869,36 +46502,12 @@ game ( rom ( name "Tweety's High-Flying Adventure (USA).gbc" size 1048576 crc 4e226396 sha1 9702aeea4a92625d2c19aa7f606b589cb7531613 ) ) -game ( - name "Tycoon Tex (World) (Aftermarket) (Unl)" - description "Tycoon Tex (World) (Aftermarket) (Unl)" - rom ( name "Tycoon Tex (World) (Aftermarket) (Unl).gbc" size 262144 crc fa8436ba sha1 d37bcd93d647ac7efb761c539785a4ef570cdcc8 ) -) - -game ( - name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" - description "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" - rom ( name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl).gbc" size 2097152 crc 8067298a sha1 e44280161ca9d482fae08de844ccc9754abf68b0 ) -) - -game ( - name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" - description "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" - rom ( name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0ce45101 sha1 f61677146ef67b026c636742f0109b8c478d0942 ) -) - game ( name "Tyrannosaurus Tex (USA) (Proto)" description "Tyrannosaurus Tex (USA) (Proto)" rom ( name "Tyrannosaurus Tex (USA) (Proto).gbc" size 2097152 crc 1bd4e588 sha1 e2fcc7fcc643f9d7fc61acce6c5ed1f8abc13fa0 ) ) -game ( - name "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" - description "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" - rom ( name "Tyrannosaurus Tex (World) (Aftermarket) (Unl).gbc" size 2097152 crc e90504c1 sha1 7e41e92f92ff06101e48dee758420f1bd3959013 ) -) - game ( name "Tyrian 2000 (USA) (Proto) (GB Compatible)" description "Tyrian 2000 (USA) (Proto) (GB Compatible)" @@ -46953,24 +46562,6 @@ game ( rom ( name "Ultimate Surfing (USA).gbc" size 1048576 crc e84df1f0 sha1 264c19ab212d938839306f7e8230d5caee3cf3e7 ) ) -game ( - name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - description "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) -) - -game ( - name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) -) - -game ( - name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" - description "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 36e4ff4c sha1 b5c9b5f07e31729678637d883b2564c1448b0e57 ) -) - game ( name "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" description "Uno (Europe) (En,Fr,De,Es,It,Nl) (GB Compatible)" @@ -46983,12 +46574,6 @@ game ( rom ( name "Uno (USA) (GB Compatible).gbc" size 1048576 crc f026d509 sha1 20868148461618d1195570775b183a065781ce35 ) ) -game ( - name "UXB (World) (Aftermarket) (Unl)" - description "UXB (World) (Aftermarket) (Unl)" - rom ( name "UXB (World) (Aftermarket) (Unl).gbc" size 262144 crc dd42be4c sha1 6ef7abb689b1c75f613ed253644fbb0f377b7a95 ) -) - game ( name "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" description "V-Rally - Championship Edition (Europe) (En,Fr,De,Es)" @@ -47007,12 +46592,6 @@ game ( rom ( name "V-Rally - Edition 99 (USA) (En,Fr,Es).gbc" size 1048576 crc da300c6c sha1 638266c9d2d16486c2ed00510176112071b05e2c ) ) -game ( - name "Varmit (World) (Aftermarket) (Unl)" - description "Varmit (World) (Aftermarket) (Unl)" - rom ( name "Varmit (World) (Aftermarket) (Unl).gbc" size 2097152 crc e4827006 sha1 b61876c714c47f62a77304b79f6e34b8d0e7f8a2 ) -) - game ( name "Vegas Games (Europe) (En,Fr,De)" description "Vegas Games (Europe) (En,Fr,De)" @@ -47055,24 +46634,12 @@ game ( rom ( name "Visiteurs, Les (France) (GB Compatible).gbc" size 1048576 crc d843f898 sha1 307b5d80fd7def049d446bf3406ec8d57dfee93d ) ) -game ( - name "VOX (World) (Aftermarket) (Unl)" - description "VOX (World) (Aftermarket) (Unl)" - rom ( name "VOX (World) (Aftermarket) (Unl).gbc" size 262144 crc 346561fb sha1 54a03c77653a19eb1b0d8a6ac82f498f83f35ef2 ) -) - game ( name "VR Sports - Powerboat Racing (USA) (Proto)" description "VR Sports - Powerboat Racing (USA) (Proto)" rom ( name "VR Sports - Powerboat Racing (USA) (Proto).gbc" size 1048576 crc cff671f1 sha1 1c77f032cdd373bfa108ea82c463f8f9f6874c71 ) ) -game ( - name "Wacky Painter (World) (Aftermarket) (Unl)" - description "Wacky Painter (World) (Aftermarket) (Unl)" - rom ( name "Wacky Painter (World) (Aftermarket) (Unl).gbc" size 262144 crc 09daa18d sha1 5425dc675101d63bea03b1c8f46f86fe200ad392 ) -) - game ( name "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" description "Wacky Races (Europe) (En,Fr,De,Es,It,Nl)" @@ -47139,24 +46706,6 @@ game ( rom ( name "Warlocked (USA).gbc" size 2097152 crc cfa0df0f sha1 2f9c05f74476368bd6dbba7d675e7870cf8ca27c flags verified ) ) -game ( - name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) -) - -game ( - name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" - description "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) -) - game ( name "Warriors of Might and Magic (USA) (En,Fr,De)" description "Warriors of Might and Magic (USA) (En,Fr,De)" @@ -47199,30 +46748,6 @@ game ( rom ( name "Watashi no Restaurant (Japan) (Beta 3).gbc" size 1048576 crc a0ed2859 sha1 343bf8ebb6fa3ce89501f7c4c219fb7e864c38a3 ) ) -game ( - name "Water Grandprix (World) (Aftermarket) (Unl)" - description "Water Grandprix (World) (Aftermarket) (Unl)" - rom ( name "Water Grandprix (World) (Aftermarket) (Unl).gbc" size 262144 crc 82f54e7e sha1 4029e003870b2afb78a3644e24397d80fc5a3210 ) -) - -game ( - name "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc ef202121 sha1 a11f931b18ba42f48a91e817b7117fa0e3e79518 ) -) - -game ( - name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 75591760 sha1 e04b01ada17e6924503029cd09a107b7f5d06f17 ) -) - -game ( - name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - description "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc f8402dc5 sha1 6feb4178589e87c6267683078201f0630cca23d6 ) -) - game ( name "WCW Mayhem (USA, Europe)" description "WCW Mayhem (USA, Europe)" @@ -47271,24 +46796,6 @@ game ( rom ( name "Wetrix GB (Japan) (SGB Enhanced) (GB Compatible).gbc" size 1048576 crc 6215c5b3 sha1 92944052b6e4448abf0103f085998662e0140825 ) ) -game ( - name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - description "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 776fc18e sha1 5c4a227c0b2f53e4a349e482c5ba87cb83404f8e ) -) - -game ( - name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" - description "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) -) - -game ( - name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" - description "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl).GBC" size 65536 crc 28114b89 sha1 05b90f0a7e92d42b3008c749d5edeab2a2eae973 ) -) - game ( name "Who Wants to Be a Millionaire - 2nd Edition (USA)" description "Who Wants to Be a Millionaire - 2nd Edition (USA)" @@ -47301,18 +46808,6 @@ game ( rom ( name "Wild Thornberrys, The - Rambler (USA).gbc" size 1048576 crc 0e1465cb sha1 0e806f0e6c1a41e764683850a3c15a80ac7fc9a5 ) ) -game ( - name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 04e04980 sha1 574cf911d6d8f73699203cd6db42ceec777f7f93 ) -) - -game ( - name "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" - description "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Wing Warriors (World) (En,Fr,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 7328cfb6 sha1 039874148f27ffe533de4ef086f29e724a3217a9 ) -) - game ( name "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" description "Wings of Fury (Europe) (En,Fr,De) (GB Compatible)" @@ -47334,13 +46829,7 @@ game ( 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 sha1 5ff68bc5ec735d090b24aab79a787f77f26afb08 ) -) - -game ( - name "Wizard of Wor (World) (Aftermarket) (Unl)" - description "Wizard of Wor (World) (Aftermarket) (Unl)" - rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gbc" size 524288 crc 492a9529 sha1 a391646d259a39e7026574145e0a2bacf5f6937b ) + rom ( name "Winnie the Pooh - Adventures in the 100 Acre Wood (USA).gbc" size 2097152 crc 066a2196 sha1 5ff68bc5ec735d090b24aab79a787f77f26afb08 flags verified ) ) game ( @@ -47409,12 +46898,6 @@ game ( rom ( name "Woody Woodpecker Racing (USA).gbc" size 1048576 crc 0424cf43 sha1 be98d0a54aedcf59cddc111c72db66105aea1375 ) ) -game ( - name "World Cup (World) (Aftermarket) (Unl)" - description "World Cup (World) (Aftermarket) (Unl)" - rom ( name "World Cup (World) (Aftermarket) (Unl).gbc" size 262144 crc 56b3ab5f sha1 075890510b3ef205ca50ebbbcf7c0a0c56032cb9 ) -) - game ( name "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" description "World Soccer GB 2 (Japan) (SGB Enhanced) (GB Compatible)" @@ -47445,10 +46928,16 @@ game ( rom ( name "Worms Armageddon (Europe) (Beta).gbc" size 1048576 crc 66fda365 sha1 b0b14b13ec7cffb04efbf0dcdd93a2eea679ea0c ) ) +game ( + name "Worms Armageddon (World) (Limited Run Games)" + description "Worms Armageddon (World) (Limited Run Games)" + rom ( name "Worms Armageddon (World) (Limited Run Games).gbc" size 1048576 crc 626dfadb sha1 5fce1d1b6a7cfa994808d473602f569537dc0231 ) +) + game ( name "WWF Attitude (USA, Europe)" description "WWF Attitude (USA, Europe)" - rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc d5fdf68a sha1 d5c37eabe3311666123b22f44a973c06d96bfce0 ) + rom ( name "WWF Attitude (USA, Europe).gbc" size 1048576 crc d5fdf68a sha1 d5c37eabe3311666123b22f44a973c06d96bfce0 flags verified ) ) game ( @@ -47589,6 +47078,12 @@ game ( rom ( name "Xtreme Sports (World) (Switch).gbc" size 4194304 crc c0437e08 sha1 5da3ad1c5354f29a74c571c2b598da96213afbe1 flags verified ) ) +game ( + name "Xtreme Sports (World) (Limited Run Games)" + description "Xtreme Sports (World) (Limited Run Games)" + rom ( name "Xtreme Sports (World) (Limited Run Games).gbc" size 4194304 crc b8a3ecdd sha1 7ec1e0e88f4827c421dc91cff03ad7932bd652f5 ) +) + game ( name "Xtreme Wheels (Europe)" description "Xtreme Wheels (Europe)" @@ -47607,12 +47102,6 @@ game ( rom ( name "Xtreme Wheels (Japan) (Possible Proto) (NP).gbc" size 1048576 crc 30132ab8 sha1 a9f67640d20771e64b1474144fcca9beebdde85d ) ) -game ( - name "Xzap (World) (Aftermarket) (Unl)" - description "Xzap (World) (Aftermarket) (Unl)" - rom ( name "Xzap (World) (Aftermarket) (Unl).gbc" size 262144 crc 68ceec9c sha1 35ae73d3ec93c95fdad9a358ccc34bcfc12445b1 ) -) - game ( name "Yakouchuu GB (Japan)" description "Yakouchuu GB (Japan)" @@ -47625,24 +47114,6 @@ game ( rom ( name "Yars' Revenge (USA, Europe) (GB Compatible).gbc" size 1048576 crc d6a26444 sha1 45fb176d539ae4a65af1f6340a9bd398dd7956d2 ) ) -game ( - name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b304833d sha1 c2be46b8230bfcf509d031902c9bf144de97ef58 ) -) - -game ( - name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) -) - -game ( - name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" - description "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" - rom ( name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) -) - game ( name "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" description "Yin Ban Zhongwen RPG Zhanlve + Dongzuo + Yizhi 12 in 1 (Taiwan) (Unl)" @@ -47793,22 +47264,10 @@ game ( rom ( name "Yuenan Zhanyi X - Shenru Dihou (Taiwan) (Unl).gbc" size 2097152 crc 602951a6 sha1 6703e9f68b989c976e93bd2eb63f884ceaff63f1 ) ) -game ( - name "Zagan Warrior (World) (Aftermarket) (Unl)" - description "Zagan Warrior (World) (Aftermarket) (Unl)" - rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gbc" size 262144 crc e770f71a sha1 99d9267946e7bf26942a8276863ba50ef0b8f90e ) -) - -game ( - name "Zap'em (World) (Aftermarket) (Unl)" - description "Zap'em (World) (Aftermarket) (Unl)" - rom ( name "Zap'em (World) (Aftermarket) (Unl).gbc" size 262144 crc 66f17c5e sha1 63d44c8c2492dc32bcf632feb2d994e9af25fc97 ) -) - 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 sha1 9b6c536b403c62af102e3800658c9dec258be249 ) + rom ( name "Zebco Fishing! (USA) (Rumble Version).gbc" size 1048576 crc 3cc6b1f9 sha1 9b6c536b403c62af102e3800658c9dec258be249 flags verified ) ) game ( @@ -47961,12 +47420,6 @@ game ( rom ( name "Zen-Nihon Shounen Soccer Taikai - Mezase Nihon Ichi! (Japan).gbc" size 2097152 crc efad8b34 sha1 bffe5fdb803f0872d1c0de9d152eb626c5b36147 ) ) -game ( - name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" - description "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" - rom ( name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc db0951d3 sha1 7b74c658f24894659cfda1fc3c7775fd9f7b6013 ) -) - game ( name "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" description "Zhen Sanguo Wushuang 2 - Shin Sangokumusou (Taiwan) (Unl)" @@ -47979,12 +47432,24 @@ game ( rom ( name "Zhihuan Wang - Shoubu Qu (Taiwan) (Zh) (Unl).gbc" size 2097152 crc 8160b3f5 sha1 97d7e0d05205b02c6cb69e68978a3f0fd2e3fde0 ) ) +game ( + name "Zhihuan Wang 2 (China) (Zh) (Unl)" + description "Zhihuan Wang 2 (China) (Zh) (Unl)" + rom ( name "Zhihuan Wang 2 (China) (Zh) (Unl).gbc" size 524288 crc e6748d1f sha1 108c318a859b39e88d15b2e3dc4d26002286305f ) +) + game ( name "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl)" description "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl)" rom ( name "Zhizhu Xia III - Dianying Ban (Taiwan) (Unl).gbc" size 2097152 crc d311efcc sha1 9eb0c468d5f898ef7b4d6ff74d7ff497b8c7818d ) ) +game ( + name "Zhong Zhuang Ji Bing (China) (Pirate)" + description "Zhong Zhuang Ji Bing (China) (Pirate)" + rom ( name "Zhong Zhuang Ji Bing (China) (Pirate).gbc" size 2097152 crc ad626c50 sha1 c3b3d8d43495ded5e4aff1b9416fe4d43b8e7453 ) +) + game ( name "Zidane - Football Generation (Europe) (En,Fr,De,Es,It)" description "Zidane - Football Generation (Europe) (En,Fr,De,Es,It)" @@ -48003,12 +47468,6 @@ game ( rom ( name "Zoboomafoo - Playtime in Zobooland (USA).gbc" size 1048576 crc 38d91885 sha1 a85a113bc266325f807f110daaf30feeea4b2738 ) ) -game ( - name "Zodiac (World) (Aftermarket) (Unl)" - description "Zodiac (World) (Aftermarket) (Unl)" - rom ( name "Zodiac (World) (Aftermarket) (Unl).gbc" size 262144 crc c4d86c05 sha1 73bd9e6e3bede8de489680ba84129e8fd17abbc0 ) -) - game ( name "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" description "Zoids - Jashin Fukkatsu! Genobreaker Hen (Japan) (SGB Enhanced) (GB Compatible)" @@ -48033,6 +47492,3200 @@ game ( rom ( name "Zok Zok Heroes (Japan).gbc" size 2097152 crc c09f9e1b sha1 91ab908fddebd926e7db8d61295a40955b2adc39 ) ) +game ( + name "Zook Z (USA) (Unl)" + description "Zook Z (USA) (Unl)" + rom ( name "Zook Z (USA) (Unl).gbc" size 1048576 crc a7b09e70 sha1 243cc40cfc6bcbd3b6106870773a72edff079904 ) +) + +clrmamepro ( + name "Nintendo - Game Boy Color (Aftermarket)" + description "Nintendo - Game Boy Color (Aftermarket)" + version 20240810-021134 + author "akubi, Arctic Circle System, Aringon, baldjared, Bent, BigFred, bikerspade, BitLooter, C. V. Reynolds, chillerecke, coraz, darthcloud, DeadSkullzJr, Densetsu, DeriLoko3, Flashfire42, foxe, fuzzball, Gefflon, gordonj, Hiccup, hking0036, InternalLoss, Just001Kim, kazumi213, Lesserkuma, Madeline, Money_114, NESBrew12, NGEfreak, nnssxx, norkmetnoil577, NovaAurora, omonim2007, PPLToast, Psychofox11, psykopat, rarenight, relax, Rifu, sCZther, SonGoku, Tauwasser, togemet2, UnlockerPT, Whovian9369, xprism, xuom2, zg" + homepage No-Intro + url "https://www.no-intro.org" + forcenodump required +) + +emulator ( + name "datafile" +) + +game ( + name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 2edc4684 sha1 a00b40a3f31bd875f4a0376d22099c3822c9ef98 ) +) + +game ( + name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "20 Second Platformer, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ff0a848b sha1 837cbb4cf3a92266833099fa06b95edfcdb1865f ) +) + +game ( + name "2123 (World) (Aftermarket) (Unl)" + description "2123 (World) (Aftermarket) (Unl)" + rom ( name "2123 (World) (Aftermarket) (Unl).gbc" size 262144 crc 22836942 sha1 eb9a2aff6485962f1a7773b7138f3c4208fa36e4 ) +) + +game ( + name "3D Quasars (World) (Aftermarket) (Unl)" + description "3D Quasars (World) (Aftermarket) (Unl)" + rom ( name "3D Quasars (World) (Aftermarket) (Unl).gbc" size 262144 crc 1fd94e67 sha1 3f32226538d8c7f0c866c4b73e9f828265f2bb5b ) +) + +game ( + name "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl)" + description "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "5 Minutes until Goodbye (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 48f0b5f2 sha1 fcb0161c637cd3d0f1ae66d032917f94aea11047 ) +) + +game ( + name "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl)" + description "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "60 Minutes til Rot (World) (v1.6b) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9a10228a sha1 43ee50322e45c533fe67972db9a9d56f91a6a99b ) +) + +game ( + name "Aardvark (World) (Aftermarket) (Unl)" + description "Aardvark (World) (Aftermarket) (Unl)" + rom ( name "Aardvark (World) (Aftermarket) (Unl).gbc" size 262144 crc 270d45b9 sha1 34a8d00af6be9083409e6fccd0825c6f185d135d flags verified ) +) + +game ( + name "Ack Ack Attack (World) (Aftermarket) (Unl)" + description "Ack Ack Attack (World) (Aftermarket) (Unl)" + rom ( name "Ack Ack Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c5bedd2e sha1 2a5c7cfb58ccb233a4e688f007ff1436c6c9a208 ) +) + +game ( + name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adulting! Soundtrack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 1b5b9e64 sha1 c5dad32be800c36814a0f9b940e99b5eada34150 ) +) + +game ( + name "Adventure (World) (Aftermarket) (Unl)" + description "Adventure (World) (Aftermarket) (Unl)" + rom ( name "Adventure (World) (Aftermarket) (Unl).gbc" size 262144 crc c23d33c9 sha1 d579a1753d7875413f9e0022285b5741665e4abc ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (En) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9f81e7a0 sha1 895148bc0a3b6f9ec59bebae43413d1f4eafd21a ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a5d0d1ec sha1 bc6367f77c235640cea5a1230cee253c99f846e5 ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Ja) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c9b424f sha1 7bd924752dca6fd772f6df9360117bd4b006ad88 ) +) + +game ( + name "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + description "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Adventures in Carnal Hell, The (World) (Es) (v1.02) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 2f758976 sha1 2aa834c26a06771d53ce35bb0b5b1b9c87e9e2ce ) +) + +game ( + name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + description "AF+ER (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "AF+ER (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f689b91e sha1 e55e427819916bb02189efe3883fb1dab3d80d35 ) +) + +game ( + name "Agency (World) (Aftermarket) (Unl)" + description "Agency (World) (Aftermarket) (Unl)" + rom ( name "Agency (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0d1bb2f7 sha1 5266589244fab2e9ff047af9f72641cda91e1d90 ) +) + +game ( + name "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31b6e3fa sha1 11b3ce59c4eb86cee05873eb473dbf262cf986bd ) +) + +game ( + name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Agent B (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae767ad7 sha1 1a332aac66b24381f16819d1145fd4a917f2e0f3 ) +) + +game ( + name "Airwolf 16 (World) (Aftermarket) (Unl)" + description "Airwolf 16 (World) (Aftermarket) (Unl)" + rom ( name "Airwolf 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 6ecfd234 sha1 968355e655492a9aa5c36faacac9d34b289132bd ) +) + +game ( + name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + description "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "All Humans Must Die! (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b4d50eed sha1 f4513fc525cbcfa4a2804b55ce20c809e01d1c87 ) +) + +game ( + name "Alley Cat (World) (Aftermarket) (Unl)" + description "Alley Cat (World) (Aftermarket) (Unl)" + rom ( name "Alley Cat (World) (Aftermarket) (Unl).gbc" size 262144 crc edb3ac37 sha1 a9aa1ecad6b67a6e5096fb1c10e39899c00a96a0 ) +) + +game ( + name "Android Nim (World) (Aftermarket) (Unl)" + description "Android Nim (World) (Aftermarket) (Unl)" + rom ( name "Android Nim (World) (Aftermarket) (Unl).gbc" size 262144 crc bd1e0cd7 sha1 efe551c498f6fdb3089a5b453b043fb61246e777 ) +) + +game ( + name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Another Adventure (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc dfcd02ef sha1 041473b2381dd9e11b3cbda5858f9841324327af ) +) + +game ( + name "Apollo Mission (World) (Aftermarket) (Unl)" + description "Apollo Mission (World) (Aftermarket) (Unl)" + rom ( name "Apollo Mission (World) (Aftermarket) (Unl).gbc" size 262144 crc bec9d9a2 sha1 b2bcc61bcf269c0f5c0ce2a6e0bb1c7015dc9ff9 ) +) + +game ( + name "Arena 3000 (World) (Aftermarket) (Unl)" + description "Arena 3000 (World) (Aftermarket) (Unl)" + rom ( name "Arena 3000 (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c17c15c sha1 007d23f73f68de01c250ec3d07403679137851ff ) +) + +game ( + name "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl)" + description "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Astral Possession (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 788043b5 sha1 0d5e4098b62e93c68108cfd5b767d45241ec6963 ) +) + +game ( + name "Astro Plumber (World) (Aftermarket) (Unl)" + description "Astro Plumber (World) (Aftermarket) (Unl)" + rom ( name "Astro Plumber (World) (Aftermarket) (Unl).gbc" size 262144 crc d746db41 sha1 bf46ab2a3a1ffc3b712b9ae5cfa05441781ac9e4 ) +) + +game ( + name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + description "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Astro-Jump - The Sequel (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc e6a96130 sha1 2cd0ef086c4b89497d9497a17d871a6568a9e2d3 ) +) + +game ( + name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Atop the Witch's Tower (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 0d60b100 sha1 9cc1a5140b96ad072d36151f5d99ff6eb699e605 ) +) + +game ( + name "Auto Zone (World) (Aftermarket) (Unl)" + description "Auto Zone (World) (Aftermarket) (Unl)" + rom ( name "Auto Zone (World) (Aftermarket) (Unl).gbc" size 524288 crc 2a86d386 sha1 83a37fb5c5d82e0ff06bb22b63761af996e4ad61 ) +) + +game ( + name "Autobahn (World) (Aftermarket) (Unl)" + description "Autobahn (World) (Aftermarket) (Unl)" + rom ( name "Autobahn (World) (Aftermarket) (Unl).gbc" size 262144 crc d2fee5f1 sha1 6de35bd07f46720372ede9b5175399f2055e593d ) +) + +game ( + name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + description "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Autumn With You, An (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc eac459fa sha1 68a5520be76c52a4936ad1756ea274667f2ac0e3 ) +) + +game ( + name "Back to Nature (World) (Aftermarket) (Unl)" + description "Back to Nature (World) (Aftermarket) (Unl)" + rom ( name "Back to Nature (World) (Aftermarket) (Unl).gbc" size 262144 crc 861f9a63 sha1 3f4a6cd105d4c8af0312bef482c08784bbbfb0eb ) +) + +game ( + name "Bandits at Zero (World) (Aftermarket) (Unl)" + description "Bandits at Zero (World) (Aftermarket) (Unl)" + rom ( name "Bandits at Zero (World) (Aftermarket) (Unl).gbc" size 524288 crc c70f413e sha1 c885e109fbb53445db9618c6768c2259e6135921 ) +) + +game ( + name "Basketbrawl (World) (Aftermarket) (Unl)" + description "Basketbrawl (World) (Aftermarket) (Unl)" + rom ( name "Basketbrawl (World) (Aftermarket) (Unl).gbc" size 1048576 crc 51efcd7b sha1 3c626d9fec2eb252a50c5022be46525103560fde ) +) + +game ( + name "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl)" + description "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl)" + rom ( name "Basketbrawl - Deluxe Edition (World) (Aftermarket) (Unl).gbc" size 1048576 crc 3da834f2 sha1 a627c03f958bc13b11e1832b6ab53fe298167ebc ) +) + +game ( + name "Battle Star (World) (Aftermarket) (Unl)" + description "Battle Star (World) (Aftermarket) (Unl)" + rom ( name "Battle Star (World) (Aftermarket) (Unl).gbc" size 524288 crc b2fd062f sha1 ac4206129704e31386c9c0a1c961a148398f0ba3 ) +) + +game ( + name "Berks (World) (Aftermarket) (Unl)" + description "Berks (World) (Aftermarket) (Unl)" + rom ( name "Berks (World) (Aftermarket) (Unl).gbc" size 262144 crc 10ded9ab sha1 8b4c282cf973cdd9926a69ae1d8fcbaf79f8552b ) +) + +game ( + name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "BIG2SMALL (World) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 65536 crc b0401d96 sha1 ee5f2db597bb2fa06efe4a279a887b97bf23cac6 ) +) + +game ( + name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0d464785 sha1 790b9d231f6e66027e76264ef646c7a7cb9c878c ) +) + +game ( + name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bitterroot (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 936443e2 sha1 b874c45d4866d5ef0c0d9837502ae42dd0ea3787 ) +) + +game ( + name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + description "Black Tape (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Black Tape (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 45c5f990 sha1 ec8c467e955d69b2084805f11a954e0d90855461 ) +) + +game ( + name "Blaze (World) (Aftermarket) (Unl)" + description "Blaze (World) (Aftermarket) (Unl)" + rom ( name "Blaze (World) (Aftermarket) (Unl).gbc" size 262144 crc 7d2519c7 sha1 f9b1422a91cc1f3a55526ef8ba81b7a8297fc55e ) +) + +game ( + name "Blinky's Revenge (World) (Aftermarket) (Unl)" + description "Blinky's Revenge (World) (Aftermarket) (Unl)" + rom ( name "Blinky's Revenge (World) (Aftermarket) (Unl).gbc" size 262144 crc 2d2f9c2b sha1 1c39cc02396c74e7b0b282ead510e94c77ff7f1e ) +) + +game ( + name "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Block Droppin' (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7e8ec278 sha1 6e8577c68402888a3244f153909a959f701eca0e ) +) + +game ( + name "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Block Droppin' (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 5a0f9578 sha1 37743ac843330cfc8350e67238fdd395174ca1d4 ) +) + +game ( + name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Board (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 440a2260 sha1 8472981264122ea588d991628c51020545779926 ) +) + +game ( + name "Boing! (World) (Aftermarket) (Unl)" + description "Boing! (World) (Aftermarket) (Unl)" + rom ( name "Boing! (World) (Aftermarket) (Unl).gbc" size 2097152 crc 91961796 sha1 09fde4065941784bab4cf8f624a0398049ed4add ) +) + +game ( + name "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + description "Bomb Runner 1-2 (World) (Aftermarket) (Unl)" + rom ( name "Bomb Runner 1-2 (World) (Aftermarket) (Unl).gbc" size 262144 crc d4c95ac0 sha1 3d020eb6e118b431899d79ce4a7bda9bc571c3a0 ) +) + +game ( + name "Booga-Boo (World) (Aftermarket) (Unl)" + description "Booga-Boo (World) (Aftermarket) (Unl)" + rom ( name "Booga-Boo (World) (Aftermarket) (Unl).gbc" size 262144 crc 7fa7fe54 sha1 00323df5a855f1499810dfe959a58d105daf6871 ) +) + +game ( + name "Booty (World) (Aftermarket) (Unl)" + description "Booty (World) (Aftermarket) (Unl)" + rom ( name "Booty (World) (Aftermarket) (Unl).gbc" size 262144 crc ef6c39c8 sha1 3c487ddc03d935b583e186d1cc395966ef490412 ) +) + +game ( + name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Borbo's Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e92ce3d4 sha1 1ddf864188dfd741ccda0b0715e75e162d212605 ) +) + +game ( + name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + description "Boxed In (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Boxed In (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee1c2e1d sha1 b95dfdf10820671ab5f734ed7180cbf1967ca277 ) +) + +game ( + name "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Boxing Master (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d1fc5295 sha1 cd336de23457b30cf7a5bf6ae62e8c606507a5a5 ) +) + +game ( + name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + description "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl)" + rom ( name "Bub-O Escape - Tournament Edition (World) (Aftermarket) (Unl).gbc" size 524288 crc 437a2973 sha1 9c219e2c489f5140314e89fbdc0bb387e1f1eed0 ) +) + +game ( + name "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bubble Frog (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 0fd51f93 sha1 e4894fd9392a9e1c42d432bc73681ca5bccfe9a8 ) +) + +game ( + name "Bubble Trouble (World) (Aftermarket) (Unl)" + description "Bubble Trouble (World) (Aftermarket) (Unl)" + rom ( name "Bubble Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc 3374918b sha1 892388f81f7815ea3bca17632a6a9a33a6edafac ) +) + +game ( + name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bubblegum Attack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc e3f64fec sha1 51e302fd27d579c9a4e8109e6ea4af3275d475dd ) +) + +game ( + name "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bug Byte (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc ee41d61b sha1 68f5712ca543c9f02b731e6dc8ec042fc790f839 ) +) + +game ( + name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + description "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Buried Behind the Cabin (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a5d6cd6a sha1 7464af8e6d9d0a4b11f510d22789a6830cd4c272 ) +) + +game ( + name "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl)" + description "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Bygone Choices (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc dbaec8ec sha1 699b752e8a4a21b7f814f59e35260e0b82fc6795 ) +) + +game ( + name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cancer Culture VS The Illuminati (World) (2023-05-03) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52da152b sha1 1bb4a376c03af67ca1e8426375fe1a644499d9ae ) +) + +game ( + name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + description "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl)" + rom ( name "Candy Quest (World) (v2) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 1f2823cb sha1 8906832db7816be01ed37728f6e5a23e981e7e38 ) +) + +game ( + name "Canoe Slalom (World) (Aftermarket) (Unl)" + description "Canoe Slalom (World) (Aftermarket) (Unl)" + rom ( name "Canoe Slalom (World) (Aftermarket) (Unl).gbc" size 262144 crc 38ce9e68 sha1 9fc025682ea0f19f975aa492dd51c5710d8b04a7 ) +) + +game ( + name "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl)" + description "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl)" + rom ( name "Cappimon (World) (v1.1) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc ee6da010 sha1 a9d24cc03a6892035eaa448fea9c54ba16569b2d ) +) + +game ( + name "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Cappimon (World) (v1.0) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc 46201a19 sha1 c641e81c551158a2cf3a43403ddb384a7d76bab4 ) +) + +game ( + name "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b4719bab sha1 5e952ffe5136fd818d8663047f195f20dad9c3f6 ) +) + +game ( + name "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 10854c85 sha1 7c4cdccc471ccf925a9ccf258c3e862681c3d1e9 ) +) + +game ( + name "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Capybara Quest (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 0795de60 sha1 7bed040a4bd916d04a9b251d14c89c9c1361cf09 ) +) + +game ( + name "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl)" + description "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Capybara Village (World) (v1.1) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc b761bac5 sha1 9c299efb05516075a67516875ecfe47a32d04ef0 ) +) + +game ( + name "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl)" + description "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl)" + rom ( name "Capybara Village (World) (v1.0) (Proto) (Cozy Spring Jam) (Aftermarket) (Unl).gbc" size 524288 crc 44deeab3 sha1 057ade8edd41efbfb168ad709e95222c7c0118fa ) +) + +game ( + name "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cargo (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cargo (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a65d66f4 sha1 83c35ad553bde5ce3a6af418d7f8ad1fbe73b0f6 ) +) + +game ( + name "Castlevania - Demon Castle (World) (Aftermarket) (Unl)" + description "Castlevania - Demon Castle (World) (Aftermarket) (Unl)" + rom ( name "Castlevania - Demon Castle (World) (Aftermarket) (Unl).gbc" size 4194304 crc af20c186 sha1 8b593ebcb4c30f7709ca97ec977e8680df9b5fb7 ) +) + +game ( + name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cat Boy's Stellar Journey (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 280937cc sha1 9ec53942f0136076b6468671562764e1ab9dee3b ) +) + +game ( + name "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cat Jumper (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc cde77e9d sha1 1acc8a49751cd45a84e53a435ddeed0357b87894 ) +) + +game ( + name "Cave Fighter (World) (Aftermarket) (Unl)" + description "Cave Fighter (World) (Aftermarket) (Unl)" + rom ( name "Cave Fighter (World) (Aftermarket) (Unl).gbc" size 262144 crc 6f4641f0 sha1 05b441e3542452b1724017d20e2db602d0997773 ) +) + +game ( + name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + description "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cave Hunter (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc defb3151 sha1 94770d13bd9b1b52224fe753f94ec580e1b4017c ) +) + +game ( + name "Cavelon (World) (Aftermarket) (Unl)" + description "Cavelon (World) (Aftermarket) (Unl)" + rom ( name "Cavelon (World) (Aftermarket) (Unl).gbc" size 262144 crc 9fdd01f6 sha1 ff40729d06a6ce91446347b4bd69deaa6ba7d8b4 ) +) + +game ( + name "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + description "Chase the Chuck Wagon (World) (Aftermarket) (Unl)" + rom ( name "Chase the Chuck Wagon (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c3d653c sha1 27b462be532a37c15798eba0fd48154eff596753 ) +) + +game ( + name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chester's Big Ol' Day (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 490a874a sha1 92567a6a58739a38e0d7b35d1327ccb999527fa0 ) +) + +game ( + name "Chopper War (World) (Aftermarket) (Unl)" + description "Chopper War (World) (Aftermarket) (Unl)" + rom ( name "Chopper War (World) (Aftermarket) (Unl).gbc" size 524288 crc eb0f4f3e sha1 26970bb0753e792aaeb328e0f88d650acd413a9d ) +) + +game ( + name "Choro-Q (World) (Aftermarket) (Unl)" + description "Choro-Q (World) (Aftermarket) (Unl)" + rom ( name "Choro-Q (World) (Aftermarket) (Unl).gbc" size 262144 crc e40e99bd sha1 8534c4fe58aef32b8cfd4812fa1f2c1094e6b129 ) +) + +game ( + name "Chromanoids (World) (v1.1) (Aftermarket) (Unl)" + description "Chromanoids (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Chromanoids (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 05d5d28f sha1 2885e9bfeca429a261f0871e31fdd3c5e682bd33 ) +) + +game ( + name "Chromanoids (World) (v1.0) (Aftermarket) (Unl)" + description "Chromanoids (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Chromanoids (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc 50c4585f sha1 2d1dc090806463a6ff8c2fc17c32061a9e731d6f ) +) + +game ( + name "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chrome and Blood (World) (v1.02) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c3f27d7 sha1 cda9b333b019dbe460f2a5cebe71c0cae258d7cd ) +) + +game ( + name "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chrome and Blood (World) (v1.00) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 15cb5c58 sha1 a0d441f71caed08a52a41813d74031f13fd49d49 ) +) + +game ( + name "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Chumbles Bumbles (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0ff2779c sha1 976790e64ce929a48a756cd1df46f325a7819f31 ) +) + +game ( + name "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Church of Pastor Chuck (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b9ca1669 sha1 d86af4b9288df8dc175a4c5647bc010328aab257 ) +) + +game ( + name "Climb It (World) (Aftermarket) (Unl)" + description "Climb It (World) (Aftermarket) (Unl)" + rom ( name "Climb It (World) (Aftermarket) (Unl).gbc" size 262144 crc e7210290 sha1 19f3b825eada3eda3135350bd0ddca6a20a5281f ) +) + +game ( + name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Clockmaker's Tale, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c4b00adb sha1 07e4254c7f74b9d4caa6a1231558b2430dff163a flags verified ) +) + +game ( + name "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl)" + description "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Closet Monsters (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 57b5d189 sha1 42e8694bb746df0b61662238d81369b15e26e6de ) +) + +game ( + name "Cold Nights (World) (Aftermarket) (Unl)" + description "Cold Nights (World) (Aftermarket) (Unl)" + rom ( name "Cold Nights (World) (Aftermarket) (Unl).gbc" size 524288 crc cdca8a46 sha1 5a2222da34e7cf9166502f9a6bea13a713744e89 ) +) + +game ( + name "Commando (World) (Aftermarket) (Unl)" + description "Commando (World) (Aftermarket) (Unl)" + rom ( name "Commando (World) (Aftermarket) (Unl).gbc" size 262144 crc 5381b103 sha1 414bb6bdc1ed5647707d7d49f194c387d4098f00 ) +) + +game ( + name "Cookie Monster Munch (World) (Aftermarket) (Unl)" + description "Cookie Monster Munch (World) (Aftermarket) (Unl)" + rom ( name "Cookie Monster Munch (World) (Aftermarket) (Unl).gbc" size 262144 crc 420db35c sha1 0584d434503040f3922595250c9b311f62483e70 ) +) + +game ( + name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + description "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cookie's Bakery (World) (v1.0.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c53ace00 sha1 02fdc52bc934b80aa41520d92cf0340753d8f668 ) +) + +game ( + name "Cops and Robbers (World) (Aftermarket) (Unl)" + description "Cops and Robbers (World) (Aftermarket) (Unl)" + rom ( name "Cops and Robbers (World) (Aftermarket) (Unl).gbc" size 262144 crc 3c185eca sha1 8f8bbd15c0ab85345f3a3ae7e737e596311c19a1 ) +) + +game ( + name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Coria and the Sunken City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc fe1bdae6 sha1 00d86bbdbc228ff3ea0684984a261cadbed5fb0a ) +) + +game ( + name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En) (v0.24) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 1780b904 sha1 fcbe2c2389e6c51a38eb17eb80ffb2e51955c7f2 ) +) + +game ( + name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En,Es) (v0.47) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc e983a31f sha1 1d811dd440572243f9e95527d970f3ffa91ddbdf ) +) + +game ( + name "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl)" + description "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl)" + rom ( name "Cosmo Knight ZiON (World) (En,Es) (v2.38) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 936752aa sha1 68e31afa8bc49f8b5e7ba9d978896539669cf3d1 ) +) + +game ( + name "Crazy Golf (World) (Aftermarket) (Unl)" + description "Crazy Golf (World) (Aftermarket) (Unl)" + rom ( name "Crazy Golf (World) (Aftermarket) (Unl).gbc" size 262144 crc f7fe3d01 sha1 b06f47a713b66efa9133be43653c7c4cb5ebc93c ) +) + +game ( + name "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Crest RPG (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c28f1ec5 sha1 2dd0b6a18e265653d382414de009ec8f154880da ) +) + +game ( + name "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + description "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cult of Blood, The (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5064aa20 sha1 2700521c7ff492fb015cc8dd453672a5989b80a7 ) +) + +game ( + name "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + description "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Cult of Blood, The (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 9015c454 sha1 60b41b89cc9bce22ea06595ee332c3c1549db935 ) +) + +game ( + name "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl)" + description "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert Enters the Tombs of Doom (World) (Aftermarket) (Unl).gbc" size 524288 crc 149a2951 sha1 2e7d760cd0836599bbc4222c66dddb4643183f07 ) +) + +game ( + name "Cuthbert in Space (World) (Aftermarket) (Unl)" + description "Cuthbert in Space (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in Space (World) (Aftermarket) (Unl).gbc" size 262144 crc c64000f3 sha1 6818167c491863cb19c2308c177203e38e0338d9 ) +) + +game ( + name "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + description "Cuthbert in the Cooler (World) (Aftermarket) (Unl)" + rom ( name "Cuthbert in the Cooler (World) (Aftermarket) (Unl).gbc" size 262144 crc 30204c4e sha1 d6fb35f3bdd44429f88c10551692e1adf14356ab ) +) + +game ( + name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2.1) (Aftermarket) (Unl).gbc" size 262144 crc 502385c4 sha1 3a310be21d5cc077da6eb8e3afa99ccff2eda84e ) +) + +game ( + name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc a504b906 sha1 4634631f2c0b4a618aeefc114e5b8e4ba9c7ee04 ) +) + +game ( + name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.1.1) (Aftermarket) (Unl).gbc" size 262144 crc a9714871 sha1 7d5b22d1c528603007e340f9d3562c1e53f10796 ) +) + +game ( + name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + description "Daisu-ki (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Daisu-ki (World) (v1.2) (Aftermarket) (Unl).gbc" size 262144 crc 26d3fe7a sha1 36c9649d4e99fdcaa4cf590963d0c49a3cf8084e ) +) + +game ( + name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + description "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Daisu-ki - Jam Edition (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d34b719a sha1 446ca937d3e54ce33a49d1fff4692b3b906b539e ) +) + +game ( + name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dark Winter Wander, A (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc df19aa9f sha1 412f18ba08f2f2a2afbf3bfb5281e360d7aba31d ) +) + +game ( + name "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Darklite (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 98a264a8 sha1 4cbd2cc8779698deb61f39ca255c6f45db7bd3b9 ) +) + +game ( + name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dawn Will Come (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bb64f51c sha1 1611ddfdb9af72f20ddeca4133d8eebd0f14e424 ) +) + +game ( + name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + description "Days Without (World) (Multiple Endings) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Multiple Endings) (Aftermarket) (Unl).gbc" size 262144 crc 57ca8f69 sha1 8992f14f02bd37e11cb05511c17fff3d253ccf25 ) +) + +game ( + name "Days Without (World) (Aftermarket) (Unl)" + description "Days Without (World) (Aftermarket) (Unl)" + rom ( name "Days Without (World) (Aftermarket) (Unl).gbc" size 262144 crc 437b4921 sha1 cb21c1bca18d750ecde91dc3adb6b599c2ad75fa ) +) + +game ( + name "Death Race 16 (World) (Aftermarket) (Unl)" + description "Death Race 16 (World) (Aftermarket) (Unl)" + rom ( name "Death Race 16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b9488ec sha1 56b8a2d7117b12ff5e709e6a258f9a0b3b0ebe24 ) +) + +game ( + name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Deisanebe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7cff943e sha1 065b5325d44cb0e40f7b7803d707b8c1ea9ea5b2 ) +) + +game ( + name "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Descent (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7d3ce321 sha1 1a42289186a7722a8ccdbd35bcd704f832dc3c04 ) +) + +game ( + name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + description "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dia de Sol Noite de Lua (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c6b965b9 sha1 ac43f43bdcfc0347f24a0a70de213a4b701d8155 ) +) + +game ( + name "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + description "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dicee! (World) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b7f0a85f sha1 6911854fe18000b0fe6015863240d0664d914547 ) +) + +game ( + name "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dicee! (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 08b37ad8 sha1 27e7a34d44640162a4aec02e28b93d295d78180b ) +) + +game ( + name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ef349515 sha1 06fe25086432c82f1e4b4c44473dd5b487a8af05 ) +) + +game ( + name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + description "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Disco Elysium - Game Boy Edition (World) (No Music) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7c0f52cc sha1 8bc16b70838f9245b7e37c6dbe57159b294fbf81 ) +) + +game ( + name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + description "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Diver 94 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f4ff5eb0 sha1 6b421505acc626a34bb9306a3d88e1964a4502f3 ) +) + +game ( + name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 52cf7153 sha1 74e6246405dd52d4c5c2eabc417946550c637164 ) +) + +game ( + name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8ca9dbe0 sha1 cf6eaac37c4ae1b3cfc4ed8d2ce73a143635b525 ) +) + +game ( + name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Don't Forget About Me (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 3d87efd8 sha1 83201c43e9fc89f4393678ade8c6107b4cfdb628 ) +) + +game ( + name "Dork's Dilemma (World) (Aftermarket) (Unl)" + description "Dork's Dilemma (World) (Aftermarket) (Unl)" + rom ( name "Dork's Dilemma (World) (Aftermarket) (Unl).gbc" size 524288 crc 77b8b43b sha1 bd525f97cc316fed3f6271ed0929414df4c0389c ) +) + +game ( + name "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + description "Downer (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Downer (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7a1c9a9f sha1 70044dca1282f4445fe05305586ecc69f4e52304 ) +) + +game ( + name "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl)" + description "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Dracula - Dark Reign (World) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 4cfb1db2 sha1 6052c794b2c30a0538f57af0ab5253c626c860c5 ) +) + +game ( + name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonborne DX (World) (v1.0.2) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 9f30b891 sha1 9974d28975a2d8e1e41ce8f32351c6eef144919d ) +) + +game ( + name "Dragonmaster (World) (Aftermarket) (Unl)" + description "Dragonmaster (World) (Aftermarket) (Unl)" + rom ( name "Dragonmaster (World) (Aftermarket) (Unl).gbc" size 262144 crc 4aaf9f58 sha1 6400de1108f1c3e5fca15de47f62299bfc66a938 ) +) + +game ( + name "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.0.0) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc 96f9b7c0 sha1 2b74d076cabff92e5935d922e8f37202a723aaf0 flags verified ) +) + +game ( + name "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dragonyhm (World) (v1.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 4194304 crc cad7369d sha1 0058096f8fcbb2774f908811aaa0b1ee54111493 ) +) + +game ( + name "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dungeon Crystal (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 028a6e47 sha1 3fb673067aee3c50b65f0f8316bfff46a76c19bb ) +) + +game ( + name "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dungeon Crystal (World) (v1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0eaeeca3 sha1 0b452000a244cd9757c4bb158d997785a13b0d1e ) +) + +game ( + name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7c41cef6 sha1 e2df238887da0b6cf79513c7799ad707740eae30 ) +) + +game ( + name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Dusky Dungeon (World) (v0.2.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc abb154db sha1 f3b456d6318bee05150403efa5a933996e1d744a ) +) + +game ( + name "Egbert (World) (Aftermarket) (Unl)" + description "Egbert (World) (Aftermarket) (Unl)" + rom ( name "Egbert (World) (Aftermarket) (Unl).gbc" size 262144 crc a0e904fc sha1 ead756b54b2c1462708b4509ac35503f04e482cf ) +) + +game ( + name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Elementaria - Orientational Waltz (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc bffec2e1 sha1 a25cc6ee07e524f9a7121786bd0e513a1c6c2a8d ) +) + +game ( + name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Empire of Dreams, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9ca3cf6c sha1 d3f4d21bf543431672268b476802693b2da9b6b9 ) +) + +game ( + name "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Escape from Vostok (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5d19bbcb sha1 6bb0ddd2b05d0ae6c7d2538f68f4b587901c29fd ) +) + +game ( + name "Everlasting Summer (World) (Proto) (Aftermarket) (Unl)" + description "Everlasting Summer (World) (Proto) (Aftermarket) (Unl)" + rom ( name "Everlasting Summer (World) (Proto) (Aftermarket) (Unl).gbc" size 262144 crc e45f6923 sha1 a4d7b12c71faf37a6703ded4d8a39844cf4f0395 ) +) + +game ( + name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + description "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Expiration Date (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f222b03b sha1 c14f008cfc182f35fe670e14b57052ae4f8d1c60 ) +) + +game ( + name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" + description "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Expiration Date (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 050caa5e sha1 e4b61c220b046e2287272f9b1bef85ad2d835fe3 ) +) + +game ( + name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" + description "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl)" + rom ( name "Exploits of Fingers Malone, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 20fe84af sha1 18056b5b032955099c606651f26164de131e54a6 ) +) + +game ( + name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc bdaf8f3f sha1 d1ed0fb4d926f4c337399ca342644f89cf00790a ) +) + +game ( + name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Far After (World) (v1.01) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e61c1dc2 sha1 d7a88a68ec65d9cf3f9521fc9ad9d3f4b51bac5d flags verified ) +) + +game ( + name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 63c6c960 sha1 b62ec7a341ea9a0bfe8f0b014da971b73606a86e ) +) + +game ( + name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Featherless Cake Delivery (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc de373eba sha1 dbf2228017515b407ed9f4a9b3bf01bc2a5f7b0f ) +) + +game ( + name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc 701847f5 sha1 aba3fecd55c0cee7fbe49506b367b7e94b56b81c ) +) + +game ( + name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + description "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Feed IT Souls (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc f87760b3 sha1 ea0dd170812d1bcc38de1cabe12a372cd2178c95 ) +) + +game ( + name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + description "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate)" + rom ( name "Feed The Monster (World) (GB Compatible) (Aftermarket) (Pirate).gbc" size 524288 crc 7bec6553 sha1 bdcadc0f98d8c9061cbe83c53a047719280b6e09 ) +) + +game ( + name "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + description "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fighter on the Path of Glory (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 38f208f3 sha1 a4034a72dfacfe33fc924ab689f9a9303656c43d ) +) + +game ( + name "Fillo - Crystal Version (World) (Aftermarket) (Unl)" + description "Fillo - Crystal Version (World) (Aftermarket) (Unl)" + rom ( name "Fillo - Crystal Version (World) (Aftermarket) (Unl).gbc" size 524288 crc 88bb855c sha1 2ffc4199d94f8b29b3f84b7bdb2694154a0bd285 ) +) + +game ( + name "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" + description "Find Out (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Find Out (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5f8b660e sha1 3605a96f6713157a88e4d88989d2e2f11b9db42f ) +) + +game ( + name "Finders Keepers (World) (Aftermarket) (Unl)" + description "Finders Keepers (World) (Aftermarket) (Unl)" + rom ( name "Finders Keepers (World) (Aftermarket) (Unl).gbc" size 524288 crc 4cfa0cfd sha1 db002f4a2500a9dc98a9ac7c263293d6e4a72cf1 ) +) + +game ( + name "Fire Ant (World) (Aftermarket) (Unl)" + description "Fire Ant (World) (Aftermarket) (Unl)" + rom ( name "Fire Ant (World) (Aftermarket) (Unl).gbc" size 262144 crc 154cc020 sha1 b58ed66838db34fc7f8475ccb670267119d623a5 ) +) + +game ( + name "Fireman Fred (World) (Aftermarket) (Unl)" + description "Fireman Fred (World) (Aftermarket) (Unl)" + rom ( name "Fireman Fred (World) (Aftermarket) (Unl).gbc" size 524288 crc 563d9ca7 sha1 e62a9c6b6a39f0cb662fdb07b72669355b706f57 ) +) + +game ( + name "Firemen (World) (Aftermarket) (Unl)" + description "Firemen (World) (Aftermarket) (Unl)" + rom ( name "Firemen (World) (Aftermarket) (Unl).gbc" size 262144 crc 7299401f sha1 84c68614334578f866cfa929df736377f04f5d04 ) +) + +game ( + name "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fishing for Asteroids (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc aae310ed sha1 b874c82fe582ee34b93cd4f6dcfc16e6fe991efe ) +) + +game ( + name "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl)" + description "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fishing for Asteroids (World) (v1.0) (Mini Jam 153) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc efbefb4b sha1 966f3f17b7acf5a60212d300c62fd5a4e50047ae ) +) + +game ( + name "Fishnet Burn (World) (Demo) (Aftermarket) (Unl)" + description "Fishnet Burn (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Fishnet Burn (World) (Demo) (Aftermarket) (Unl).gbc" size 262144 crc a317673d sha1 3b28ba3bbcb2c387976e98a47650426131823c56 ) +) + +game ( + name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" + description "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fix It Felix Jr. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc c8014615 sha1 7221f5e53f6027183301d06e258c6cb417007b8c ) +) + +game ( + name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fix My Heart (World) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 507f9ea2 sha1 28ad64e379dc60d6e1c2617e073f6361c0feb475 flags verified ) +) + +game ( + name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Flashin' (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc fcc05ec4 sha1 64d31f34e189b3af08bf0c659a93f71dbf83ef71 ) +) + +game ( + name "Flooder (World) (Aftermarket) (Unl)" + description "Flooder (World) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Aftermarket) (Unl).gbc" size 32768 crc 253dcbe0 sha1 8fdcd8b02604ac5259fb6aa80e5ba67a03c861fb ) +) + +game ( + name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + description "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl)" + rom ( name "Flooder (World) (Anniversary Edition) (Aftermarket) (Unl).gbc" size 32768 crc cdda76f8 sha1 e5eec8efc032aa5bce1826f7b6b8790c61c96e06 ) +) + +game ( + name "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl)" + description "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Foal's Creek (World) (v1.06) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 40027de8 sha1 6d4152d0db5c7fdc2d3271ffc9195494e637c85a ) +) + +game ( + name "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl)" + description "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Foal's Creek (World) (v1.05) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c0db789e sha1 025e83abce412435c41e77dc7ecc606af96f874b ) +) + +game ( + name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fa2d92a1 sha1 24f02d116aafb7b55d6cfd6d263b7595986af843 ) +) + +game ( + name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Forest of Fallen Knights (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4c21e563 sha1 f6f84f1a44d41fa7d26a9195ddf791fae53dfcdf ) +) + +game ( + name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + description "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friday the 13th - The GB Game (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 7543586a sha1 397821751ac6464582f61566f3a7c731a46b24ba ) +) + +game ( + name "Friendly Fire (World) (Aftermarket) (Unl)" + description "Friendly Fire (World) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (Aftermarket) (Unl).gbc" size 262144 crc 5c6dca2b sha1 8f8085010e28aa8bdb312d086b0002b706742282 ) +) + +game ( + name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Friendly Fire (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc d8be10d6 sha1 d09f4d2f799ac2e2731be0171625846d28d0f57e ) +) + +game ( + name "From Below Pocket (World) (Aftermarket) (Unl)" + description "From Below Pocket (World) (Aftermarket) (Unl)" + rom ( name "From Below Pocket (World) (Aftermarket) (Unl).gbc" size 131072 crc 35ad9b5a sha1 c0e072bfb88c84dc68b2eded1f9c088d75ffa5ed ) +) + +game ( + name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + description "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Fugazim (World) (Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 85edfba4 sha1 8a95571a32c5a23bd6be4edf6429f630d7a1a15a ) +) + +game ( + name "Fury (World) (Aftermarket) (Unl)" + description "Fury (World) (Aftermarket) (Unl)" + rom ( name "Fury (World) (Aftermarket) (Unl).gbc" size 262144 crc 7217c41d sha1 ef532b587eb438f1a39a77086ac0b8bbae23a16d ) +) + +game ( + name "G-Man (World) (Aftermarket) (Unl)" + description "G-Man (World) (Aftermarket) (Unl)" + rom ( name "G-Man (World) (Aftermarket) (Unl).gbc" size 524288 crc ff3beab1 sha1 cb9486ca9a6ad3903662963aa966145257ef92a6 ) +) + +game ( + name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "G.B Corp. (World) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc fd2e40f4 sha1 e442316132506ff223a9e5f33d874b71ec09d71a flags verified ) +) + +game ( + name "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery - Mystery Show (World) (v1.4) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc aba1f99a sha1 8278abbe74202537bdc42f2e00875a12e77c9115 ) +) + +game ( + name "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery - Mystery Show (World) (v1.2) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3629b4a sha1 649678adc47eeb1386a90084ddb2fbf99b08ca4c ) +) + +game ( + name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Game Boy Camera Gallery 2022, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc f1948966 sha1 14849ab5831c71949ec3a1fe7657050057d2cf29 ) +) + +game ( + name "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl)" + description "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Game with The Cerulean Blob, The (World) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc be05262e sha1 9fff6703a876d19027f8d8c590d1223d0e931420 ) +) + +game ( + name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gamer Boy Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 96721e5d sha1 90fad94433a5b0dbcf73f4a2d4ebb75d7ab065c4 ) +) + +game ( + name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gamer Boy Mission (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a02d2ae2 sha1 7eb6865c5c265193763ec0bf751d26964e870120 ) +) + +game ( + name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Pt-BR) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f20c0097 sha1 691af25434a09931a302ced52c757d28b9b06619 ) +) + +game ( + name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Ca) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 164999eb sha1 197d3d194d4cb6cae9a358f7fb53d6de649e7c5f ) +) + +game ( + name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (De) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 60b075d1 sha1 0a66254b2327b48657de64d6102ac05f1e8700e7 ) +) + +game ( + name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 1a169897 sha1 0636b968e8e24fe7c1910f61db6e94fa84824494 ) +) + +game ( + name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Fr) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 593965ff sha1 75d566045a680aaed4d40b83b6418cbfab5b4422 ) +) + +game ( + name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (It) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc d81ab567 sha1 1dfd3c4508ffb6598662bcf1b16ec109a9282dd5 ) +) + +game ( + name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Kw) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc f795689c sha1 9a332127182e8155d1a3dc53e1382a6c9dde6aeb ) +) + +game ( + name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Es-XL) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 660ed37b sha1 0792fbef010cac21c12cbcb8b3c85b3af30faec4 ) +) + +game ( + name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (Nl) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 6dc4faaa sha1 7617083f9b13b2f95bdf1b0b327ffb4f8ccbe3c9 ) +) + +game ( + name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "GB-Wordyl (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 8780e125 sha1 7163bfbaa2cae2f9d41c472128f69a4fa5879180 ) +) + +game ( + name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc 4aa9a9c2 sha1 ac697bc27a126c1389e6bef94a2c83404e8819f2 ) +) + +game ( + name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 32e2ea48 sha1 ee11d5397316b69eee5ae3023de08c3b919c93df ) +) + +game ( + name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + description "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ghost of the Arcade (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ea87ad5d sha1 433e25df1421e77cdc807296e1ed662d9e43d685 ) +) + +game ( + name "Ghost Town (World) (Aftermarket) (Unl)" + description "Ghost Town (World) (Aftermarket) (Unl)" + rom ( name "Ghost Town (World) (Aftermarket) (Unl).gbc" size 262144 crc 52efcc35 sha1 1a4a7846d6c87f0bd8b267aa6a8aa98e797fedf8 ) +) + +game ( + name "Gods of the Universe (World) (Aftermarket) (Unl)" + description "Gods of the Universe (World) (Aftermarket) (Unl)" + rom ( name "Gods of the Universe (World) (Aftermarket) (Unl).gbc" size 262144 crc 27b87354 sha1 74eb8cd698097290b93fb08d9b19486d05411877 ) +) + +game ( + name "Gopher (World) (Aftermarket) (Unl)" + description "Gopher (World) (Aftermarket) (Unl)" + rom ( name "Gopher (World) (Aftermarket) (Unl).gbc" size 262144 crc 22802c30 sha1 e629199b6bd492bd5efa77c0d4d467e053d44877 ) +) + +game ( + name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gorf the Ghost Saves Halloween (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ab10cec6 sha1 9dcaa6824fab806683737bdf1c76609c68c451a5 ) +) + +game ( + name "GPC Rally (World) (v1.1) (Aftermarket) (Unl)" + description "GPC Rally (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "GPC Rally (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 2ed2487c sha1 a711bbb2d7dc2b0c377ecd7b20f4862330961b51 ) +) + +game ( + name "GPC Rally (World) (v1.0) (Aftermarket) (Unl)" + description "GPC Rally (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "GPC Rally (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc 3b15bdb8 sha1 b6500b0250d8358644e41e26ed8fb92c5b24535d ) +) + +game ( + name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a5ad3c0b sha1 1cf0cf6d1da5c5337856ecc0a60d2e9fb3c98f58 ) +) + +game ( + name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + description "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Grave Encounter, A (World) (v1.21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b29fc03f sha1 2f979202a4bf4f98f3026a7548a8b6c7008806bf ) +) + +game ( + name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + description "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Gravitorque (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc a0e998e1 sha1 ab656383e9aaaa2991aa344bdc8f21370f0eda36 ) +) + +game ( + name "Gridtrap (World) (Aftermarket) (Unl)" + description "Gridtrap (World) (Aftermarket) (Unl)" + rom ( name "Gridtrap (World) (Aftermarket) (Unl).gbc" size 262144 crc 5a5453f6 sha1 b43d05eddcd1ab2d5934dd2a722f145a3084c4ad ) +) + +game ( + name "Grimace's Birthday (World) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (Aftermarket) (Unl).gbc" size 1048576 crc 7f4386e9 sha1 d6358d100ea65d34d95588f800635b64927baf82 ) +) + +game ( + name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.1) (Aftermarket) (Unl).gbc" size 1048576 crc 7744f551 sha1 035b7417e03c4e264a90212f2a3811012f03c2a2 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc 9dee42fe sha1 071fa179df96950c3c92b0abbe32092b1816ec40 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.4) (Aftermarket) (Unl).gbc" size 1048576 crc 9baa5f46 sha1 d247c03119ac14f97fdeeaa6bf0defa98e35fa17 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc ab41a9ef sha1 d8e727745e285f5e467f5eccbfd30ee175bafc2e flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.5) (Aftermarket) (Unl).gbc" size 1048576 crc f8e8e1f3 sha1 a3fdfe3981e800fa7c73ff989bc06426f668c331 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.6) (Aftermarket) (Unl).gbc" size 1048576 crc a7b59d7b sha1 295fdc3218d1699dea6d5832d068b721fccf9bd4 flags verified ) +) + +game ( + name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + description "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl)" + rom ( name "Grimace's Birthday (World) (v1.7) (Aftermarket) (Unl).gbc" size 1048576 crc f3879ef0 sha1 27d7ee2f31bf575185711217c3cc9e08cbc5928a flags verified ) +) + +game ( + name "Gun Law (World) (Aftermarket) (Unl)" + description "Gun Law (World) (Aftermarket) (Unl)" + rom ( name "Gun Law (World) (Aftermarket) (Unl).gbc" size 262144 crc 3a0b6823 sha1 c49f7e0a5055f836528a7bc0cb6f45f221c76475 ) +) + +game ( + name "Gunslinger (World) (Aftermarket) (Unl)" + description "Gunslinger (World) (Aftermarket) (Unl)" + rom ( name "Gunslinger (World) (Aftermarket) (Unl).gbc" size 262144 crc 0dfd765f sha1 8410ef1558649f9badc71629827ba1500510d221 ) +) + +game ( + name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + description "Gunther the Monster and His Friends (World) (Aftermarket) (Unl)" + rom ( name "Gunther the Monster and His Friends (World) (Aftermarket) (Unl).gbc" size 524288 crc 2d9b59bf sha1 d89fe1cd97d1ef2c457aa90b1c00e7b473c57270 ) +) + +game ( + name "Guzzler (World) (Aftermarket) (Unl)" + description "Guzzler (World) (Aftermarket) (Unl)" + rom ( name "Guzzler (World) (Aftermarket) (Unl).gbc" size 524288 crc 3684abd0 sha1 e36cd02fe2b697901843c4cbf6d83da8a9b7b923 ) +) + +game ( + name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + description "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Halo - Combat Devolved (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c7297c31 sha1 c38cc0e80a2e04693e3a86574c03f23f3e472c88 flags verified ) +) + +game ( + name "Harbour Attack (World) (Aftermarket) (Unl)" + description "Harbour Attack (World) (Aftermarket) (Unl)" + rom ( name "Harbour Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc 7455782e sha1 1d0b3779007ba8f34e11b189552955dbf5c75a28 ) +) + +game ( + name "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hat Boy (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 81d24d61 sha1 7265cad6c8e253d3cf6d1f0dcb218316f10ca091 ) +) + +game ( + name "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + description "Haunted (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Haunted (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 4b3670bd sha1 f245b8e21716a400769488b852f15d276f3549a6 ) +) + +game ( + name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 287afc75 sha1 42ccc76883c041bc5c6c25a2e61ccc939c14811f ) +) + +game ( + name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hauntsfield (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6e484d6a sha1 7282ef5cc2354345c8832b4dde66a559de74f73f ) +) + +game ( + name "Heebie Jeebies (World) (Aftermarket) (Unl)" + description "Heebie Jeebies (World) (Aftermarket) (Unl)" + rom ( name "Heebie Jeebies (World) (Aftermarket) (Unl).gbc" size 262144 crc 73762d53 sha1 d427f18cb854e1387d93c19b88cb7193975e6472 ) +) + +game ( + name "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + description "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hidden Gems (World) (GB Compo 2023) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6f430dda sha1 e0cfe038063b1cd601a5f1b5af047efc705a7aaa ) +) + +game ( + name "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hidden Gems (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7296d7e0 sha1 ae0fd7bcda2a3d7c1c342157ecb801ba8e380b5f ) +) + +game ( + name "High Noon (World) (Aftermarket) (Unl)" + description "High Noon (World) (Aftermarket) (Unl)" + rom ( name "High Noon (World) (Aftermarket) (Unl).gbc" size 262144 crc 1d00e48d sha1 21d5e871ed009a674659344d3d768fb2389c0d04 ) +) + +game ( + name "Hightail (World) (Demo 4F) (Aftermarket) (Unl)" + description "Hightail (World) (Demo 4F) (Aftermarket) (Unl)" + rom ( name "Hightail (World) (Demo 4F) (Aftermarket) (Unl).gbc" size 524288 crc f199c768 sha1 c794f30bedc69aa4d3567ab8f06f4ad651d5be24 ) +) + +game ( + name "Hightail (World) (Demo 4A) (Aftermarket) (Unl)" + description "Hightail (World) (Demo 4A) (Aftermarket) (Unl)" + rom ( name "Hightail (World) (Demo 4A) (Aftermarket) (Unl).gbc" size 262144 crc 8f01efcb sha1 bbf1f2af7594862f94b72f2f5a7be54040aa8569 ) +) + +game ( + name "Hime's Quest (World) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Aftermarket) (Unl).gbc" size 2097152 crc 546f578a sha1 ff90ca3ec7fb5d02865ae3cfd807ad3541dd21fc ) +) + +game ( + name "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + description "Hime's Quest (World) (Digital) (Aftermarket) (Unl)" + rom ( name "Hime's Quest (World) (Digital) (Aftermarket) (Unl).gbc" size 2097152 crc de5c21c2 sha1 7b6672c46c23aaa282bd4fded0713c6dfae2eb66 ) +) + +game ( + name "Hopp It (World) (Aftermarket) (Unl)" + description "Hopp It (World) (Aftermarket) (Unl)" + rom ( name "Hopp It (World) (Aftermarket) (Unl).gbc" size 262144 crc 675fbae3 sha1 cc10828f99675068eb79310b629f1365540b2979 ) +) + +game ( + name "Host, The (World) (Aftermarket) (Unl)" + description "Host, The (World) (Aftermarket) (Unl)" + rom ( name "Host, The (World) (Aftermarket) (Unl).gbc" size 524288 crc 5f783000 sha1 05cc1f1e52167c6985ebb0a3e67af1fc2fbff93c ) +) + +game ( + name "Hugo (World) (Aftermarket) (Unl)" + description "Hugo (World) (Aftermarket) (Unl)" + rom ( name "Hugo (World) (Aftermarket) (Unl).gbc" size 524288 crc 6581c78a sha1 390d2665f34ceaa5e34cc9f8f7c26d9e7583a92b ) +) + +game ( + name "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl)" + description "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl)" + rom ( name "Hunt the Gwumbus (World) (v2.1) (Aftermarket) (Unl).gbc" size 524288 crc 956f1e5d sha1 66769e2feb53ad70503849f271146c6f830bc2fe ) +) + +game ( + name "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hunter in the Lost Forest (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc feac2611 sha1 1b10f2ec15d25584da2f2c123ecc97df7f7a0af0 ) +) + +game ( + name "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + description "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Hunter in the Lost Forest (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ee633b7b sha1 6fc0ab0c6dffc8925ceb538ffc78cc70cd4ac0e4 ) +) + +game ( + name "Infall (World) (Aftermarket) (Unl)" + description "Infall (World) (Aftermarket) (Unl)" + rom ( name "Infall (World) (Aftermarket) (Unl).gbc" size 131072 crc d9d90319 sha1 aafaf33fa43c7f0fd65cc8af03a42df25361fc74 ) +) + +game ( + name "Inscryption (World) (v0.5) (Aftermarket) (Unl)" + description "Inscryption (World) (v0.5) (Aftermarket) (Unl)" + rom ( name "Inscryption (World) (v0.5) (Aftermarket) (Unl).gbc" size 524288 crc ae0a1c16 sha1 480ce539500d814fd3822fed7525c21027ac361b ) +) + +game ( + name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Inspector Waffles Early Days (World) (v1.0.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fea1cdb9 sha1 ac10ca63f15ca78af9f7d0eabb85eef8733aef50 ) +) + +game ( + name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Iron Cor - Stainless (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d6c1c1ac sha1 d722e95155455cf146a97222ccbc2237bea86509 ) +) + +game ( + name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + description "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Jayro's Game Boy Test Cartridge (World) (v1.18) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 9e97ac30 sha1 c07237d0f9c13b36ac2fcc5324b6e81122b0e189 ) +) + +game ( + name "Jet Set Willy (World) (Aftermarket) (Unl)" + description "Jet Set Willy (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy (World) (Aftermarket) (Unl).gbc" size 262144 crc 659295ee sha1 bcb5a0e4566572aeb6cddea0897903ba207dc54f ) +) + +game ( + name "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl)" + description "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl)" + rom ( name "Jet Set Willy II - The Final Frontier (World) (Aftermarket) (Unl).gbc" size 524288 crc 8a4c58fa sha1 2e5b5a943b9f449bccb968b52ebc3dc8a4b3cb83 ) +) + +game ( + name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 8884d532 sha1 a41195443613fb4414d8536b1f3494677f6f253d ) +) + +game ( + name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + description "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Judy's Adventure (World) (v11.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 570a8043 sha1 1ccbf555412a417135acea0b7b185a7f795a89da ) +) + +game ( + name "Junior Maths 2 (World) (Aftermarket) (Unl)" + description "Junior Maths 2 (World) (Aftermarket) (Unl)" + rom ( name "Junior Maths 2 (World) (Aftermarket) (Unl).gbc" size 262144 crc 72c67d63 sha1 648273123a1bb64cd7fda7f611bb9cf53a5b0214 ) +) + +game ( + name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Kero Kero Cowboy (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6a5abba1 sha1 0b3deef7a27201e81b4d39bc0bd10ff7ec73e380 ) +) + +game ( + name "Kikstart (World) (Aftermarket) (Unl)" + description "Kikstart (World) (Aftermarket) (Unl)" + rom ( name "Kikstart (World) (Aftermarket) (Unl).gbc" size 524288 crc 9a9f483b sha1 bc472506f73f0c1a3f0a610c0136b324b7635c7f ) +) + +game ( + name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Knit-Wit (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f19d5e86 sha1 0f0e01a143182a9784c80a882ac206d02d8679d7 ) +) + +game ( + name "KnockOut (World) (Aftermarket) (Unl)" + description "KnockOut (World) (Aftermarket) (Unl)" + rom ( name "KnockOut (World) (Aftermarket) (Unl).gbc" size 131072 crc a060e59f sha1 164e078fce73674e3a5ad1cfd9e881813ce7a210 ) +) + +game ( + name "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl)" + description "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl)" + rom ( name "Larion's Tinker Toys (World) (Proto 2) (Aftermarket) (Unl).gbc" size 262144 crc fe421365 sha1 545551a382899d3689e2a501ccaccf500b9291df ) +) + +game ( + name "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl)" + description "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl)" + rom ( name "Larion's Tinker Toys (World) (Proto 1) (Aftermarket) (Unl).gbc" size 262144 crc 317d6e20 sha1 1867920232b32cf95eedfd47d9935e2d482c567d ) +) + +game ( + name "Laser Squad Alter (World) (Aftermarket) (Unl)" + description "Laser Squad Alter (World) (Aftermarket) (Unl)" + rom ( name "Laser Squad Alter (World) (Aftermarket) (Unl).gbc" size 1048576 crc 32f24248 sha1 26f4efe636214e72ec724f8887ca79fbc8abad80 ) +) + +game ( + name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v1.0.1) (Demo) (Kickstarter) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4a58315b sha1 5a234e33f7429b48f4374b5989e6df4d20352b4c ) +) + +game ( + name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.0) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 5c405584 sha1 3ee043ba17f46a6afbbba8ac05f35d093b817fbc ) +) + +game ( + name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Last Crown Warriors (World) (v2.1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9a134100 sha1 75b5188a5b8a720ff08894379147c7870ac8825d ) +) + +game ( + name "Leaper (World) (Aftermarket) (Unl)" + description "Leaper (World) (Aftermarket) (Unl)" + rom ( name "Leaper (World) (Aftermarket) (Unl).gbc" size 524288 crc ed8cd385 sha1 425db2916263121f4aee91a8cab6286e39364f87 ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc e8f402e2 sha1 16633011144af9519037672f67f42c9a9459bb65 ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 67f5a155 sha1 9f25aaf58f440cc62992b3268d239399fb5b377b ) +) + +game ( + name "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lee Carvallo's Putting Challenge II (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 915b7710 sha1 10d60a8d381b547e622e84859ee6ae7f19995818 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-15) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 953e25d1 sha1 018c7cada41e693a02b9c596d307b0aa9207eef4 ) +) + +game ( + name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Legacy of Verintia (World) (2023-05-31) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1096252a sha1 c22cc79b25a05afad66e769dc0365b7c25f1bb85 ) +) + +game ( + name "Legend of Carrot (World) (Aftermarket) (Unl)" + description "Legend of Carrot (World) (Aftermarket) (Unl)" + rom ( name "Legend of Carrot (World) (Aftermarket) (Unl).gbc" size 131072 crc 965a02af sha1 fa404e1b2b4544b4969c14ec41f81e87304234c8 ) +) + +game ( + name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + description "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Let's Bee Friends (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a91a698f sha1 26f38b3908c086b3e349324da32bc37213975030 ) +) + +game ( + name "Liberator (World) (Aftermarket) (Unl)" + description "Liberator (World) (Aftermarket) (Unl)" + rom ( name "Liberator (World) (Aftermarket) (Unl).gbc" size 262144 crc ebe70d3d sha1 e3afce5a2357732ed15d7f3c0900f7b48113efdc ) +) + +game ( + name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + description "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Lightseeker (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b8dd8409 sha1 281abb583ec0039e2c981c2e95f7a92002da081b ) +) + +game ( + name "Loco-coco (World) (Aftermarket) (Unl)" + description "Loco-coco (World) (Aftermarket) (Unl)" + rom ( name "Loco-coco (World) (Aftermarket) (Unl).gbc" size 262144 crc f6b9fe4e sha1 8a8972ff3e208280a746a2015a20f67248180a1c ) +) + +game ( + name "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Love is Dead (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc dd537a3b sha1 f3e44fea9faed10c0aebaf11dd2f7821076a7315 ) +) + +game ( + name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2021-12-30) (Aftermarket) (Unl).gbc" size 262144 crc 9edd066c sha1 4d43a38e8b5df41309f5b6ec13e4829db739d980 ) +) + +game ( + name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + description "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl)" + rom ( name "Lunar Docking (World) (2022-08-07) (Aftermarket) (Unl).gbc" size 262144 crc de5d5c0b sha1 5f038ef3657d3fbfb3be6917b24c3f933363ad4c ) +) + +game ( + name "Lunatic Tower (World) (Aftermarket) (Unl)" + description "Lunatic Tower (World) (Aftermarket) (Unl)" + rom ( name "Lunatic Tower (World) (Aftermarket) (Unl).gbc" size 524288 crc 6edacbb3 sha1 ee706a5f6272bda950a5d80ffc071453a9880fb6 ) +) + +game ( + name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (v1.1) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f55a9d95 sha1 2b22fbd76e11e6e45053b1e6989de303e3033c9e ) +) + +game ( + name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Machine, The (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5662865e sha1 a5ac99a4087bd5ea45417e5b4a7c9af10433911a ) +) + +game ( + name "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mage and the Grimoire of Beast (World) (En) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4197bfd5 sha1 83f15e10963a2991636a382168aa035c7f340b3c ) +) + +game ( + name "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mage and the Grimoire of Beast (World) (Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6d8126b4 sha1 89d7df077818f000fef3c59429a6deb1a423aa03 ) +) + +game ( + name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + description "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Magic & Legend - Time Knights (World) (Demo) (The Retro Room) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c276843d sha1 852697a2952d2e7375b73aba877ebc17aa4f4179 ) +) + +game ( + name "Magician's Curse, The (World) (Aftermarket) (Unl)" + description "Magician's Curse, The (World) (Aftermarket) (Unl)" + rom ( name "Magician's Curse, The (World) (Aftermarket) (Unl).gbc" size 524288 crc f2b1967e sha1 3b5f97f9a0b4d63a3795695b0bda6e969de8e051 ) +) + +game ( + name "Mayhem (World) (Aftermarket) (Unl)" + description "Mayhem (World) (Aftermarket) (Unl)" + rom ( name "Mayhem (World) (Aftermarket) (Unl).gbc" size 262144 crc 4d739ad7 sha1 9f141728a74432820f47cc24d230dc56d6ac099b ) +) + +game ( + name "Meiji Jingu (World) (Aftermarket) (Unl)" + description "Meiji Jingu (World) (Aftermarket) (Unl)" + rom ( name "Meiji Jingu (World) (Aftermarket) (Unl).gbc" size 262144 crc 56905954 sha1 9656d278857f6cfa08b8820409b665306c3d18aa ) +) + +game ( + name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f614bdff sha1 7e46c193f6566f620acf20ead3a1fca1d677c221 ) +) + +game ( + name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Melanie and the Magic Forest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 949c6ab9 sha1 34269af4db6c37b92fdc7f7f914c282174603ba8 ) +) + +game ( + name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Memory Mania Challenge (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 50618f4b sha1 c8d74af4746313800df3a23c1ad01f931e0e2eca flags verified ) +) + +game ( + name "Meteorite (World) (Aftermarket) (Unl)" + description "Meteorite (World) (Aftermarket) (Unl)" + rom ( name "Meteorite (World) (Aftermarket) (Unl).gbc" size 131072 crc fafbcebf sha1 25a81d916f1ed80a2bca2fe7a555433f06d025e3 ) +) + +game ( + name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-05-28) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f9a5ed4e sha1 8b3e18287d5adf3b5a711e28a896f843927f22a2 ) +) + +game ( + name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + description "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Midterm Moments (World) (2022-06-15) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 177f0b6e sha1 e5fdb741d870de25affdc841c07eaa3000da25f5 ) +) + +game ( + name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mirror Between Us, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 854f4297 sha1 a1a44ce8052f06349df3cbdf9a6d976609213d68 ) +) + +game ( + name "Mission Mars (World) (Aftermarket) (Unl)" + description "Mission Mars (World) (Aftermarket) (Unl)" + rom ( name "Mission Mars (World) (Aftermarket) (Unl).gbc" size 262144 crc f651fcf4 sha1 479c70dd9c63cdcad99ca44720a9e0e2582df119 ) +) + +game ( + name "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl)" + description "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl)" + rom ( name "Mob Creche Parallel Game (World) (En,Ja) (Aftermarket) (Unl).gbc" size 262144 crc e138c5a5 sha1 9446639471efe21304c0c09c9540010941ae3f9f ) +) + +game ( + name "Mommy (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mommy (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mommy (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5d644d24 sha1 3bc152e2899d54d6c400e2e0a114e0aa67a56a69 ) +) + +game ( + name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mona and the Witch's Hat Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 39480c79 sha1 4348a7903e538e5367f2a60718f43cbeeccf96df ) +) + +game ( + name "Monkey Magic (World) (Aftermarket) (Unl)" + description "Monkey Magic (World) (Aftermarket) (Unl)" + rom ( name "Monkey Magic (World) (Aftermarket) (Unl).gbc" size 262144 crc c9c68715 sha1 bf5dc5593334fe1114461065a2b7284d28b31462 ) +) + +game ( + name "Monty on the Run (World) (Aftermarket) (Unl)" + description "Monty on the Run (World) (Aftermarket) (Unl)" + rom ( name "Monty on the Run (World) (Aftermarket) (Unl).gbc" size 524288 crc fd1066ac sha1 8390175e6be4731d9afa91715d7f8dd11693bb69 ) +) + +game ( + name "Mount Vesuvius (World) (Aftermarket) (Unl)" + description "Mount Vesuvius (World) (Aftermarket) (Unl)" + rom ( name "Mount Vesuvius (World) (Aftermarket) (Unl).gbc" size 262144 crc 1292ecfb sha1 dd71a1a7282a8a68c70d705d8eab8b2bd73132e3 ) +) + +game ( + name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + description "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mountain Climber (World) (En,Es) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 362a84ba sha1 b4b3afa2379a07acab6965ae8fcf6d2ba82d6d7e ) +) + +game ( + name "Mr. Angry (World) (Aftermarket) (Unl)" + description "Mr. Angry (World) (Aftermarket) (Unl)" + rom ( name "Mr. Angry (World) (Aftermarket) (Unl).gbc" size 524288 crc b85e63a5 sha1 127ad5315e2bce37614a1e9f8605798e68718926 ) +) + +game ( + name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + description "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Mud Warriors (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 846afc79 sha1 dae84fbc60839da29878714cd845c3704b915323 ) +) + +game ( + name "Munch It (World) (Aftermarket) (Unl)" + description "Munch It (World) (Aftermarket) (Unl)" + rom ( name "Munch It (World) (Aftermarket) (Unl).gbc" size 262144 crc 3d7ce6c7 sha1 55b390866d0922685bd1f42e8ee7310f021fa0dc ) +) + +game ( + name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-27) (Aftermarket) (Unl).gbc" size 524288 crc ec4f9d49 sha1 357db81755f1f0eb732367dd4090c446eb226ddf ) +) + +game ( + name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + description "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl)" + rom ( name "Musical Notes (World) (2023-05-19) (Aftermarket) (Unl).gbc" size 524288 crc 1ba7d27f sha1 d4c4be65ba469369cd90aaa733d0a8e8af6bcdc1 ) +) + +game ( + name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9bff7b15 sha1 1f3aac8a3725cd1d0968529afc1c2031372d8ed1 ) +) + +game ( + name "My Friendly Little Island (World) (Aftermarket) (Unl)" + description "My Friendly Little Island (World) (Aftermarket) (Unl)" + rom ( name "My Friendly Little Island (World) (Aftermarket) (Unl).gbc" size 1048576 crc f6bf0584 sha1 81d724ad696084283712145adfef15769648b045 ) +) + +game ( + name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neclaus' Quest (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc eedefa0c sha1 e63c16fe987fe655408be66198366a0147ac607c ) +) + +game ( + name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neclaus' Quest (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 53cf930c sha1 bd3272ca7ead64da3f68f774661a560add433b94 ) +) + +game ( + name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + description "Neighbor (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neighbor (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 705b150f sha1 6258cf6ad167c9ae86609a8e620face1674a7ea7 ) +) + +game ( + name "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Neonsomnia (World) (v0.1) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 394ce9cb sha1 3d24808bf0bb1a06212a48309d8affe5d26eeeba ) +) + +game ( + name "Nightmare Hamlet (World) (Aftermarket) (Unl)" + description "Nightmare Hamlet (World) (Aftermarket) (Unl)" + rom ( name "Nightmare Hamlet (World) (Aftermarket) (Unl).gbc" size 131072 crc 574bf5b6 sha1 05d043816bb4eb9cc57b369ab5f966b610ba5c2f ) +) + +game ( + name "Ninja Master (World) (Aftermarket) (Unl)" + description "Ninja Master (World) (Aftermarket) (Unl)" + rom ( name "Ninja Master (World) (Aftermarket) (Unl).gbc" size 262144 crc bc550b84 sha1 0def135723ac40e4981c88f8888afbd40a15bb40 ) +) + +game ( + name "Number Builder (World) (Aftermarket) (Unl)" + description "Number Builder (World) (Aftermarket) (Unl)" + rom ( name "Number Builder (World) (Aftermarket) (Unl).gbc" size 262144 crc b8609d43 sha1 92952b752f50af889db891acc9eed8436ac6b87e ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.6) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e983e8d1 sha1 fc2a58d49327c88c895ae6681bde57e1a2687974 flags verified ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc ef42955e sha1 485b4d672d9edda40f9191f5f5cc223046000e67 flags verified ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.1) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 581efe4d sha1 125bb0564ee17f8e55046a1c25e53ee9a4254303 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.3) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc e26ddbbb sha1 853115369b8ca583d038d00c1dde59b6a74b73a2 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.2.5) (Beta) (Aftermarket) (Unl).gbc" size 1048576 crc 1e8ac5b9 sha1 99c11bef7feb17a9e7212cf9b6593478f671bc32 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (Free Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f5df28c2 sha1 7b511444e1eb86fffcf93599a78e0e2c44aecc8a ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (Rev 1) (Free Version) (Aftermarket) (Unl).gbc" size 2097152 crc 63bddc68 sha1 fab777e607bd8aba70eb65829143039dbe6ac08e ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.0) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 1f1af42a sha1 ddcdbfa716d716e1b7bb258caaaa7b76d041b5a9 ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + description "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.2) (Beta) (GB Compatible) (Aftermarket) (Unl) (Alt).gbc" size 524288 crc 834a8021 sha1 d5af2bf38eda4c181993e992764788003509ebfd ) +) + +game ( + name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Nyghtmare - The Ninth King (World) (v0.1.9) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 42d9c38c sha1 ae719190cf2f433c359bc425775710f4aa67e860 ) +) + +game ( + name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c055ef9 sha1 d4fa4e02753a9fe539f70d0927ba5bf9caa02d3c ) +) + +game ( + name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + description "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Octopus Stressus (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 7ed58128 sha1 e543c39f8e55b1788476b94028a54fc2fc9c7ea0 ) +) + +game ( + name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + description "Office Combat (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Office Combat (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 9742276d sha1 cd8f18d6e5fabaa130a42e5618e29c5ff26f6a93 ) +) + +game ( + name "Olympic Skier (World) (Aftermarket) (Unl)" + description "Olympic Skier (World) (Aftermarket) (Unl)" + rom ( name "Olympic Skier (World) (Aftermarket) (Unl).gbc" size 524288 crc 5e81cef7 sha1 a7a552a9eb984098a67e063c2eca907eec000fc1 ) +) + +game ( + name "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + description "One Day (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "One Day (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fd52acc7 sha1 bdb5590b61791b89e9afa871d32648d7a66ce1f4 ) +) + +game ( + name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" + description "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Opossum Country (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 7348bb32 sha1 e63e06d602473206b21138f5322acf86b5b6b9b8 ) +) + +game ( + name "Out on a Limb (World) (Aftermarket) (Unl)" + description "Out on a Limb (World) (Aftermarket) (Unl)" + rom ( name "Out on a Limb (World) (Aftermarket) (Unl).gbc" size 262144 crc a6671528 sha1 f21cb71adcea1029151930eb98c4e9b446e4cfee ) +) + +game ( + name "Outta Time (World) (Aftermarket) (Unl)" + description "Outta Time (World) (Aftermarket) (Unl)" + rom ( name "Outta Time (World) (Aftermarket) (Unl).gbc" size 262144 crc 18522ba7 sha1 e9ef4c1d24e42ba7920bf8e7d72f804f058b93c6 ) +) + +game ( + name "Outward (World) (Aftermarket) (Unl)" + description "Outward (World) (Aftermarket) (Unl)" + rom ( name "Outward (World) (Aftermarket) (Unl).gbc" size 131072 crc c554bf64 sha1 6cfb29fed8ce82384d9051424a4b55673c182c8f ) +) + +game ( + name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c6e83f41 sha1 44b117d94a80617a77abbdcc76d9d69b66efe56b ) +) + +game ( + name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + description "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pacifist, The (World) (GB Showdown) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 69483f81 sha1 4d162c9637a20cfc7c92e6ea7a61fad0ed22137a ) +) + +game ( + name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + description "Pact, The (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 262144 crc 0db301c2 sha1 58ec8f209ed6e33adfb253014ea69ae1ee53c145 ) +) + +game ( + name "Pact, The (World) (Aftermarket) (Unl)" + description "Pact, The (World) (Aftermarket) (Unl)" + rom ( name "Pact, The (World) (Aftermarket) (Unl).gbc" size 262144 crc 304df19a sha1 97af064f9063cd353e55ac0e1f6d1ca8b4a6d2b9 ) +) + +game ( + name "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl)" + description "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Paku Paku GB (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 62b5a15f sha1 2b85528aef01cb5caab4cff898c2bc66e211b3bf ) +) + +game ( + name "Pancho (World) (Aftermarket) (Unl)" + description "Pancho (World) (Aftermarket) (Unl)" + rom ( name "Pancho (World) (Aftermarket) (Unl).gbc" size 524288 crc d32d46c5 sha1 2f46974e6d92f5deb277818d95426a4507b3701d ) +) + +game ( + name "Panik!16 (World) (Aftermarket) (Unl)" + description "Panik!16 (World) (Aftermarket) (Unl)" + rom ( name "Panik!16 (World) (Aftermarket) (Unl).gbc" size 262144 crc 7b31122d sha1 98d74fd64e4f7e835f1101b05816b8938a34a416 ) +) + +game ( + name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + description "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Phantom Fright (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 154cb547 sha1 3b217c595e6a5b115dc7130123a321049cf01d22 ) +) + +game ( + name "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + description "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pilgrim's Peril (World) (Demo 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 3c2bafdc sha1 d38f3f5e491dbaed84e88099987712449db9b33d ) +) + +game ( + name "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + description "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pilgrim's Peril (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc cdded15b sha1 2b85eb77ab2dcea4f645abcc1a66dbce54a6ebaa ) +) + +game ( + name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pine Creek (World) (En-US,Es-MX,Pt-BR) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 189aa999 sha1 2cf46a36502eaf22ac9572fe1136d369fcbe9e46 ) +) + +game ( + name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" + description "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pinecone Pizza Party (World) (Prototype) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1601d6fa sha1 87b4edf0398f0154d7556e3cd96f97b19e699a40 ) +) + +game ( + name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "PlayTime (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 29415ff7 sha1 89b3fd633e8cef3b8523b1ef2a0072db2d7416d7 ) +) + +game ( + name "Pogo Pete (World) (Aftermarket) (Unl)" + description "Pogo Pete (World) (Aftermarket) (Unl)" + rom ( name "Pogo Pete (World) (Aftermarket) (Unl).gbc" size 262144 crc 3001ed1b sha1 f9dab150843c2b8f300d36b1dd53dd1a22b481a3 ) +) + +game ( + name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v2.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc 42298fd8 sha1 90c535bf70e2ca7b91af67b8f08865f423c3034f ) +) + +game ( + name "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v1.0) (Demo) (Aftermarket) (Unl).gbc" size 1048576 crc b9e724ef sha1 28a01fd6ea95a146008435c5bc27b51b607bb86b ) +) + +game ( + name "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl)" + description "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl)" + rom ( name "Pokettohiro! (World) (v3.0) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc b9b4e3c0 sha1 a8ba9c09ef0889640e41d79838bcd98b7bc4e5d4 ) +) + +game ( + name "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl)" + description "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Pomape Castle (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9350c71d sha1 a0f449e270b72de56bfea151b5ac271c0c7e3c93 ) +) + +game ( + name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 50393a65 sha1 2c2c6ed8be7a13bf279e435c5984f175c8affcad ) +) + +game ( + name "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + description "Postie (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Postie (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff6bbc83 sha1 3ff236972d1e344eb50e696db3cc090f2b5d28b1 ) +) + +game ( + name "Postman Pat's Trail Game (World) (Aftermarket) (Unl)" + description "Postman Pat's Trail Game (World) (Aftermarket) (Unl)" + rom ( name "Postman Pat's Trail Game (World) (Aftermarket) (Unl).gbc" size 262144 crc ad31b512 sha1 135977fe71677e3c49450e2c6ff63105d10dfaac ) +) + +game ( + name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-27) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 6da19041 sha1 eb581935ad9223d723fdbc8339c03436df051947 ) +) + +game ( + name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + description "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Potbound (World) (2022-09-26) (Proto) (GBJam 10) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc d0d8386d sha1 fbddf81a1663388ff0efeeb9051e68e0c323c839 ) +) + +game ( + name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (En) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f0191467 sha1 3876f1aa896759f427ad2dc88a48788817e60c06 flags verified ) +) + +game ( + name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Ja) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e8f68acc sha1 156d315b7a2a035d5cd429fb8c7e051e67e83c93 flags verified ) +) + +game ( + name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "POWA! (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 592b6097 sha1 874d5e4ffc7d36259bef6ec6a86a1de8289b8d54 ) +) + +game ( + name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Power Ball - Monster's Quest (World) (v1.04) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b01c4ff1 sha1 898dbf10550af7e39b8f7a0818a78083ae40f4fe ) +) + +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-04) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a86cada1 sha1 b02096c489c0f36582061d6eb62beb17e8294b61 ) +) + +game ( + name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + description "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Princess Poffin and the Spider Invasion! (World) (2023-06-06) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e171f327 sha1 b03df48f48529ac1be79699d6f34f324adcfb436 ) +) + +game ( + name "Proof of Destruction (World) (Aftermarket) (Unl)" + description "Proof of Destruction (World) (Aftermarket) (Unl)" + rom ( name "Proof of Destruction (World) (Aftermarket) (Unl).gbc" size 262144 crc fa528f88 sha1 5062f16346c31cae1b13e469cb610ce84d4eecb2 ) +) + +game ( + name "Purple Turtles (World) (Aftermarket) (Unl)" + description "Purple Turtles (World) (Aftermarket) (Unl)" + rom ( name "Purple Turtles (World) (Aftermarket) (Unl).gbc" size 262144 crc 471277df sha1 a73cb69d1fb42f45f3649c4d1b4775e98fe35b78 ) +) + +game ( + name "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + description "Quartet (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quartet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc 46743216 sha1 bf866b438a602af386f8fad02727b4084edf6047 ) +) + +game ( + name "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl)" + description "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quest Arrest (World) (v1.1) (Digital) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9ac546d5 sha1 25b3a21135bfc7587c096b10f4a20d8b3095d721 ) +) + +game ( + name "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Quest of the MX-129 Wizard (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 776ab9fd sha1 65d98bae58e5e4f723b1ec838ad4e1f2036c4468 ) +) + +game ( + name "Raffles (World) (Aftermarket) (Unl)" + description "Raffles (World) (Aftermarket) (Unl)" + rom ( name "Raffles (World) (Aftermarket) (Unl).gbc" size 262144 crc e41d6472 sha1 4b5eb518ff52c235c674e0695fdde2b8b01f58fa ) +) + +game ( + name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" + description "Ravenia (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ravenia (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 09196a32 sha1 8218ad22b29fb32c66430a17a97775dd30b2f34b flags verified ) +) + +game ( + name "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl)" + description "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Remi's Pizzaria (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f7a4fcfb sha1 fdc8c8a1bab2dfcfe3e43175e830382fe63d5c7d ) +) + +game ( + name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (GB Compo 2021) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc e92034d8 sha1 14b9614cea9be7d5c6e12aece692582ba2ca2b75 flags verified ) +) + +game ( + name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (v0.1.023) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 3a1b1d83 sha1 4dda0cce6907de94eeae3f11a40238c3f5155ca7 ) +) + +game ( + name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + description "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Repugnant Bounty (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc f8c7f180 sha1 07674d42f5d4efaec14750ae56d8f28c4b54c020 flags verified ) +) + +game ( + name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 8bd98942 sha1 3a5dbafa829e57089de8cfc93c806f7ee023ff1b ) +) + +game ( + name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Retro Quiz Tower (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c761189c sha1 f7f18d83218b66b9d1cd7267d6d4acfd4eded6c7 ) +) + +game ( + name "Rig Attack (World) (Aftermarket) (Unl)" + description "Rig Attack (World) (Aftermarket) (Unl)" + rom ( name "Rig Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc d013d775 sha1 90bfd921c986abff4555b761cedc90ec36c43fff ) +) + +game ( + name "Ripjack (World) (GB Compatible) (Aftermarket) (Unl)" + description "Ripjack (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ripjack (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 218b54ec sha1 624cb4afcabd03f4f2f4bea95f9998a6a04ae42b ) +) + +game ( + name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + description "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "River Styx Round-Up (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ae3f980b sha1 67f63517eacfea22922d07be0efc5fc8f8b8a1d2 ) +) + +game ( + name "Robin to the Rescue (World) (Aftermarket) (Unl)" + description "Robin to the Rescue (World) (Aftermarket) (Unl)" + rom ( name "Robin to the Rescue (World) (Aftermarket) (Unl).gbc" size 262144 crc 9cd52c18 sha1 ef3bea9ed0de41e311b5f15fccbb0f451848d56c ) +) + +game ( + name "Robo Knight (World) (Aftermarket) (Unl)" + description "Robo Knight (World) (Aftermarket) (Unl)" + rom ( name "Robo Knight (World) (Aftermarket) (Unl).gbc" size 524288 crc 8d4507f0 sha1 6012f9a3ae6201e363f46a75e0100552ecb91335 ) +) + +game ( + name "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl)" + description "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Rockets Vs Cars (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc eaae6f3e sha1 446e688f42e886c51c74719b93a326ae5b56920d ) +) + +game ( + name "Rockman (World) (Aftermarket) (Unl)" + description "Rockman (World) (Aftermarket) (Unl)" + rom ( name "Rockman (World) (Aftermarket) (Unl).gbc" size 262144 crc 490b5676 sha1 6f78200acb6698e268e26c1912d64a002cbd3d89 ) +) + +game ( + name "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Rootin' Tootin' Cowboy Wizard Lizards (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1fcdc59e sha1 e741ac0918ce14df473600d34836f744c2507fa0 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a46baa15 sha1 87dd5a6ccb5db59dae09f1953062420977ad2d92 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 5602ca84 sha1 49d692796a6d0f3dcfc988648b446c0934f0e794 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (Beta 3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b2547aa6 sha1 981a464d6e1c9e5ac59549845b41dae4817ed3b8 ) +) + +game ( + name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" + description "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruby & Rusty Save the Crows (World) (v2.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c18f82cb sha1 bd8cd5822dcc61f7eb0cf2584c9a5b5a94bde14a ) +) + +game ( + name "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ruin Run (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ddbfb0ce sha1 fb4730afe4e10529015513cc1dec8889c00cb373 ) +) + +game ( + name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + description "RunieStory (World) (GB Showdown) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (GB Showdown) (Aftermarket) (Unl).gbc" size 2097152 crc 96b1ceec sha1 771135edfbc64f7332a9cbd0d72af7a9d0d71f82 ) +) + +game ( + name "RunieStory (World) (Aftermarket) (Unl)" + description "RunieStory (World) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (Aftermarket) (Unl).gbc" size 2097152 crc 2249b449 sha1 0f6a391d7e05f66092a98e411069fab8e3f24221 ) +) + +game ( + name "RunieStory (World) (v1.1) (Aftermarket) (Unl)" + description "RunieStory (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "RunieStory (World) (v1.1) (Aftermarket) (Unl).gbc" size 2097152 crc dd81f722 sha1 f2ad05b15a4ed1611b0d5b52525d16a5f00867bc ) +) + +game ( + name "RunieStory (World) (Aftermarket) (Unl) (Alt)" + description "RunieStory (World) (Aftermarket) (Unl) (Alt)" + rom ( name "RunieStory (World) (Aftermarket) (Unl) (Alt).gbc" size 2097152 crc 367c802d sha1 b9ec81a8c71ea13b553b478535071715a2ab07d9 ) +) + +game ( + name "Runner (World) (Aftermarket) (Unl)" + description "Runner (World) (Aftermarket) (Unl)" + rom ( name "Runner (World) (Aftermarket) (Unl).gbc" size 262144 crc 4cd8ccb2 sha1 da735d415ed463a953bac45f4793342bd9be2e96 ) +) + +game ( + name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-16) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 4e4af60b sha1 ab8d49a99d02eb5c97d75f62dfb3720eec2b5abd ) +) + +game ( + name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + description "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sam the Optimistic Hedgehog (World) (2023-01-21) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 40dc168d sha1 af25acc86f0eef4ce72199383b96fcb4c9f0115e ) +) + +game ( + name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + description "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sapphire Hotel - The Little Tales of (World) (v1.2) (Demo) (MBC5) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc db928e22 sha1 e175d35e6112c347ecd1e0a379e98f430823ba94 ) +) + +game ( + name "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl)" + description "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl)" + rom ( name "Sergio Kidd (World) (En,Es) (v2.013) (Aftermarket) (Unl).gbc" size 1048576 crc e23bc705 sha1 986708b9cb96c56e3592030d45dc5433d3aa63c5 ) +) + +game ( + name "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl)" + description "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl)" + rom ( name "Sergio Kidd (World) (En,Es) (v1.995) (Aftermarket) (Unl).gbc" size 1048576 crc 1d871322 sha1 e57357be09657bc42e5ccee937edcf1653468402 ) +) + +game ( + name "Shark Attack (World) (Aftermarket) (Unl)" + description "Shark Attack (World) (Aftermarket) (Unl)" + rom ( name "Shark Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc cf80a2ba sha1 291f453a185f836fcafbd7e41945a409638980c0 ) +) + +game ( + name "Shoot It (World) (Aftermarket) (Unl)" + description "Shoot It (World) (Aftermarket) (Unl)" + rom ( name "Shoot It (World) (Aftermarket) (Unl).gbc" size 262144 crc 54afa0ff sha1 f3c574e274d1531e3f53511da0d57751e989a665 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-09) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 599132ec sha1 762087df0e5820f1e50da2a22f9ee3b8d16c3e49 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-04-16) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5370b1bf sha1 966e2d79ab4930039c3d6c43fdbb8cdc068ba347 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-08-24) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 16f34bcc sha1 c34e744b9120e3a1b2b054d3708e4ab594726c5a ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-09-13) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 31ce3f27 sha1 c33d685d5ea5cd6cd954af3bc9ee92719b9578b1 ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-11-07) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc d54b53cb sha1 08948befa0227b795d00fe60e9eede6a1f56597b ) +) + +game ( + name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - 20th Anniversary Demake (World) (2021-12-03) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 314be6b5 sha1 37978f85ae92e7d9a53611659513fd360f57a5b1 ) +) + +game ( + name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + description "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl)" + rom ( name "Silent Hill 2 - Born From a Wish (World) (2023-10-03) (Demo) (Aftermarket) (Unl).gbc" size 524288 crc 7ebcdd4e sha1 b99f43719155cafbc3dbd7df0ade281c3c7ba171 ) +) + +game ( + name "Sir Knight (World) (Aftermarket) (Unl)" + description "Sir Knight (World) (Aftermarket) (Unl)" + rom ( name "Sir Knight (World) (Aftermarket) (Unl).gbc" size 262144 crc 8c31c136 sha1 d8be26e0688301a76def8f5fbc246a9c9005862e ) +) + +game ( + name "Skelby (World) (Aftermarket) (Unl)" + description "Skelby (World) (Aftermarket) (Unl)" + rom ( name "Skelby (World) (Aftermarket) (Unl).gbc" size 524288 crc 6ec6c18c sha1 887555aa7e2e61b68a21020237b7d508bb71aded ) +) + +game ( + name "Skull Nightmare (World) (Aftermarket) (Unl)" + description "Skull Nightmare (World) (Aftermarket) (Unl)" + rom ( name "Skull Nightmare (World) (Aftermarket) (Unl).gbc" size 131072 crc c36941d3 sha1 49f03694965f79688aef724308c83988e71fd374 ) +) + +game ( + name "Skycon (World) (Aftermarket) (Unl)" + description "Skycon (World) (Aftermarket) (Unl)" + rom ( name "Skycon (World) (Aftermarket) (Unl).gbc" size 524288 crc 195dbc30 sha1 df29ece6c5f5b14840663495230135dd79c5163a ) +) + +game ( + name "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl)" + description "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Slime Dungeon (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 3967fb31 sha1 926e584b8952aba86761b430daedc5b91177e408 ) +) + +game ( + name "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Slime's Adventure (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 61b14549 sha1 87b84c85bb32a1d0874053cdf749f8391a275324 ) +) + +game ( + name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + description "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Sludge & Sorcery (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc c906c5af sha1 0e0d472b282e3ea590e0f126baf633ef0d9298fa ) +) + +game ( + name "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game 2 - Virtual Boy Edition (World) (Aftermarket) (Unl).gbc" size 1048576 crc 71ed0db8 sha1 e7b39b17e3e8e7ac1cf2e0b179e2c14874533835 ) +) + +game ( + name "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl)" + description "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game Boy Adventure (World) (Aftermarket) (Unl).gbc" size 1048576 crc 96efbfb9 sha1 3900ab947af4c582cd34cec7f2977219115d65e4 ) +) + +game ( + name "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Smickeonn - The Game Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 02bb005e sha1 0c1bf424968530a70ecbe382d002fc6bd629962c ) +) + +game ( + name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 1aecd096 sha1 8ce256d963a55badf71fd45047c173a74d76a92c ) +) + +game ( + name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snail DX, The (World) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 6cf39388 sha1 9cf5a1d3e8119303a1f4b04b8f4d8b683aee699e ) +) + +game ( + name "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + description "Snooze (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Snooze (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc b246095f sha1 b7fdcc006c9c06dd391ee26d44b278d9d3793f6d ) +) + +game ( + name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + description "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl)" + rom ( name "Sofia the Witch - Curse of the Monster Moon (World) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc 9e864f1c sha1 ce5dc23c04ff18dfac2367e53d241e81c4bbc3a3 ) +) + +game ( + name "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Space Fleet (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc d9244730 sha1 6987a43315abca95b85d84c278a6b1ae5dea185a ) +) + +game ( + name "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Space War (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c54f07e1 sha1 de6107573654309805bbb0ac86a748311ae70d4e ) +) + +game ( + name "Spectipede (World) (Aftermarket) (Unl)" + description "Spectipede (World) (Aftermarket) (Unl)" + rom ( name "Spectipede (World) (Aftermarket) (Unl).gbc" size 262144 crc 9c33f76e sha1 834a450d9ceb78b9d89d551300d4d0ea08cd8a6a ) +) + +game ( + name "Spiky Harold (World) (Aftermarket) (Unl)" + description "Spiky Harold (World) (Aftermarket) (Unl)" + rom ( name "Spiky Harold (World) (Aftermarket) (Unl).gbc" size 262144 crc 7e9eda35 sha1 486d294b8cf226876581d543e3a08018321bc402 ) +) + +game ( + name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + description "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Star Hunt (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 29320841 sha1 890fda255106ea64bac4973e2e9f4b31bb925d35 ) +) + +game ( + name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + description "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "StarFox - Grounded (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 82658661 sha1 dd45b0e3f346ce33668d49092b29a44597686061 ) +) + +game ( + name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc ce90a95b sha1 75457c5affd0c126f2c916e857950b5cde46a95e ) +) + +game ( + name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + description "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stars of Zureon (World) (Proto 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b3a04b44 sha1 b16f21b46dfe4e6ce0368e3c5a3fae397274ebbf ) +) + +game ( + name "Starseed (World) (GB Compatible) (Aftermarket) (Unl)" + description "Starseed (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Starseed (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc e21ff9e0 sha1 3479e222263814374a557870034bc215aea3408d ) +) + +game ( + name "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl)" + description "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Starseed 2 (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc dd4528d2 sha1 43a02f79fd5da23cfeccc13aa5970265f428dddc ) +) + +game ( + name "Stellar Wars (World) (Aftermarket) (Unl)" + description "Stellar Wars (World) (Aftermarket) (Unl)" + rom ( name "Stellar Wars (World) (Aftermarket) (Unl).gbc" size 262144 crc e0b96256 sha1 ba2d10a2a5f3f073aea11e26ae5c53c9cf7866f8 ) +) + +game ( + name "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratacombo (World) (v1.2) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 43c70a69 sha1 9931a9e3a0e4a0edcd336acfb433713991a50ad2 ) +) + +game ( + name "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratacombo (World) (v1.0) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 06575da1 sha1 3c621c921d7995acb88754634328de8ec32b444b ) +) + +game ( + name "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl)" + description "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Stratagem Hero (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc ff118db9 sha1 f89ff66e8e593729ed9605b0107ed6d12d9b858d ) +) + +game ( + name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" + description "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Suicide Run (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2dc3fdae sha1 a551d904c4af661bd4b6e88063cb5541900117b0 ) +) + +game ( + name "Suicide Run (World) (Aftermarket) (Unl)" + description "Suicide Run (World) (Aftermarket) (Unl)" + rom ( name "Suicide Run (World) (Aftermarket) (Unl).gbc" size 262144 crc d29ab1aa sha1 df373f58e51155e32fb81825a9082150f6d263c8 ) +) + +game ( + name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Bunny Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc c47330e2 sha1 6151286e93b2e2fb92f583371e650e36ab91aaf7 ) +) + +game ( + name "Super Gran (World) (Aftermarket) (Unl)" + description "Super Gran (World) (Aftermarket) (Unl)" + rom ( name "Super Gran (World) (Aftermarket) (Unl).gbc" size 262144 crc 98ee2e8a sha1 5afe9c7ab1b9d86048a570e7a37a0c244cb84e43 ) +) + +game ( + name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super Impostor Bros. (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a38d702f sha1 301f93da4e5b0cd8dc3f1bf3e66e38176b8a909b ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.2) (Aftermarket) (Unl).gbc" size 524288 crc 8e1f6bb0 sha1 27522a35211b0f015fa9550c2520f1da1c346886 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (v2.3) (Aftermarket) (Unl).gbc" size 524288 crc f9731ee2 sha1 23855b95d04a6c7c6d2ce7977bb31dbe6c0e68a0 ) +) + +game ( + name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + description "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl)" + rom ( name "Super Jacked Up Tomato Face Johnson (World) (Jam Version) (Aftermarket) (Unl).gbc" size 524288 crc 87956ddf sha1 b23320d5d3fde2a55b301f7bea324833c31c32d5 ) +) + +game ( + name "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl)" + description "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Super JetPak DX (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 22def6f9 sha1 e7438db01fbbdeea2404dbf3d093370421ec4e1c flags verified ) +) + +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 64921bb1 sha1 b36ec89e0299c19767cc5c6467fa3664abbc3017 ) +) + +game ( + name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + description "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordbird Song - The Iron Owl Tower (World) (v3.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b2b5dc4b sha1 aaa66863b2e68865359d1c0db2047bab6f64f9ee ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc f2762fb0 sha1 b4d33ac2e410a55d27edb2abe6fc2268ca18ae26 ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (En,Ja) (v1.00) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc bc3a78de sha1 54f9f0caa96edac7d336d85548e099a4e5110bdd ) +) + +game ( + name "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + description "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Swordsman on the Eternal Journey (World) (It) (v1.01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 4a733a47 sha1 a45a31e6491a5d8a9288dc64823d7266060681b3 ) +) + +game ( + name "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Take Your Medicine (World) (En,Pt) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 31a6b0ff sha1 baa07cfb71e42487eb57490c5b6cdec72e6893f7 ) +) + +game ( + name "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Take Your Medicine (World) (En,Pt) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 255f67de sha1 8c973fafc9576e57a7714bda6425d30cdf7edd2c ) +) + +game ( + name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + description "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tales of Monsterland (World) (v2.83) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc a685f89a sha1 15a709d4300464b03ede4d774ce69cfb699c0fcf ) +) + +game ( + name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + description "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl)" + rom ( name "Tamarindo's Freaking Dinner DX (World) (Aftermarket) (Unl).gbc" size 262144 crc 257d9201 sha1 d78e0b03a3915531e780057c4ad7ed2b3f849825 ) +) + +game ( + name "Tank Attack (World) (Aftermarket) (Unl)" + description "Tank Attack (World) (Aftermarket) (Unl)" + rom ( name "Tank Attack (World) (Aftermarket) (Unl).gbc" size 262144 crc c77dc518 sha1 4751a6999f4dbe7e66b997372588f6bd15e4d9d0 ) +) + +game ( + name "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-13) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-13) (Aftermarket) (Unl).gbc" size 262144 crc 1d97b754 sha1 39226ed715ae8d94f9187c3e5e8a849eac92ca26 ) +) + +game ( + name "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + description "Tazz (World) (2022-10-17) (Aftermarket) (Unl)" + rom ( name "Tazz (World) (2022-10-17) (Aftermarket) (Unl).gbc" size 262144 crc 6fb0ba23 sha1 543118e54b166ea2b8b5979f8468cc2f5662161f ) +) + +game ( + name "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiledentity (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 678383d3 sha1 a97c2b31ce138e81e0bfabee89aa58426d41e0a9 ) +) + +game ( + name "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + description "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiledentity (World) (v1.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc a9a24479 sha1 59b1d66807141ca42809189544e1104bd8d0454b ) +) + +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.4) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc af13e718 sha1 307e51664db2101755b6c617f3d81ee58676c485 ) +) + +game ( + name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tiny Grasshopper Goes Away (World) (En,Hu) (v1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 0518f5aa sha1 85e5cd0cf7a6cc4a5946c93fa8665235a686e554 ) +) + +game ( + name "Tir Na Nog (World) (Aftermarket) (Unl)" + description "Tir Na Nog (World) (Aftermarket) (Unl)" + rom ( name "Tir Na Nog (World) (Aftermarket) (Unl).gbc" size 1048576 crc 44524c90 sha1 ac712228460e9d4268f90ec4cf9ac2137fa667c4 ) +) + +game ( + name "To The Stars (World) (GB Compatible) (Aftermarket) (Unl)" + description "To The Stars (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "To The Stars (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2e1ca159 sha1 fb8269ff0377ac755b95e8e1ed935ad00d4476ee ) +) + +game ( + name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + description "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tobu Tobu Girl Deluxe (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 16650a8b sha1 fe6eef70d48dda741f7ad3b6cc5e753e8cd13239 ) +) + +game ( + name "Tomte Trouble (World) (Aftermarket) (Unl)" + description "Tomte Trouble (World) (Aftermarket) (Unl)" + rom ( name "Tomte Trouble (World) (Aftermarket) (Unl).gbc" size 262144 crc a43d6b82 sha1 99730fe00703d655b1c806f49c9e3c2fb3dec58e flags verified ) +) + +game ( + name "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + description "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tools of Nexaura (World) (v0.4) (Demo) (SGB Enhanced) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 50707e43 sha1 4a50327514554f075178f4d6342a4497d3122f31 ) +) + +game ( + name "Tower of Evil (World) (Aftermarket) (Unl)" + description "Tower of Evil (World) (Aftermarket) (Unl)" + rom ( name "Tower of Evil (World) (Aftermarket) (Unl).gbc" size 524288 crc aeb6e36f sha1 e9a6a007e935afb522c67d355e0354b0fb9af3c6 ) +) + +game ( + name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + description "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Traumatarium (World) (Demo) (2023-06-01) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b0a32d51 sha1 4c0d639722d1cd8393e008d174b8f7266d089ead ) +) + +game ( + name "Treasure Island Color (World) (Aftermarket) (Unl)" + description "Treasure Island Color (World) (Aftermarket) (Unl)" + rom ( name "Treasure Island Color (World) (Aftermarket) (Unl).gbc" size 262144 crc 4ab0eb5a sha1 3ebddd4e1f5b3a87726ef34a5b7d36de8c722f36 ) +) + +game ( + name "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl)" + description "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Tristam Island (World) (v1.6) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc f6449829 sha1 5f1a11c4de8635fd5247ebb7f26273a40048567e flags verified ) +) + +game ( + name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + description "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Trouble City - Pocket Mission (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 4b9143ad sha1 0e51e398d44aaad74a7c622f7818b56a3b34db56 ) +) + +game ( + name "Tutti Frutti (World) (Aftermarket) (Unl)" + description "Tutti Frutti (World) (Aftermarket) (Unl)" + rom ( name "Tutti Frutti (World) (Aftermarket) (Unl).gbc" size 262144 crc ca377ca6 sha1 53d97b93b9d190de40ed2d81e18b4cbe44f99a23 ) +) + +game ( + name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + description "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "TV-Chan's Great Escape! (World) (Proto) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 01239312 sha1 4f21c3539ef40a7630581fe50533371e0d1a1ba9 ) +) + +game ( + name "Tycoon Tex (World) (Aftermarket) (Unl)" + description "Tycoon Tex (World) (Aftermarket) (Unl)" + rom ( name "Tycoon Tex (World) (Aftermarket) (Unl).gbc" size 262144 crc fa8436ba sha1 d37bcd93d647ac7efb761c539785a4ef570cdcc8 ) +) + +game ( + name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics (World) (Aftermarket) (Unl).gbc" size 2097152 crc 8067298a sha1 e44280161ca9d482fae08de844ccc9754abf68b0 ) +) + +game ( + name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + description "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl)" + rom ( name "Tynesoft Commodore 16 Classics II (World) (Aftermarket) (Unl).gbc" size 1048576 crc 0ce45101 sha1 f61677146ef67b026c636742f0109b8c478d0942 ) +) + +game ( + name "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" + description "Tyrannosaurus Tex (World) (Aftermarket) (Unl)" + rom ( name "Tyrannosaurus Tex (World) (Aftermarket) (Unl).gbc" size 2097152 crc e90504c1 sha1 7e41e92f92ff06101e48dee758420f1bd3959013 ) +) + +game ( + name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unearthed (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc 29bb9238 sha1 39fbfb220e9be0120090f770249049b3f3583f64 ) +) + +game ( + name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Ungrateful Son, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 977b54f4 sha1 016dde406896d827dcad682d40b52d0e9eeefa88 ) +) + +game ( + name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + description "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Unholy Friend (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 36e4ff4c sha1 b5c9b5f07e31729678637d883b2564c1448b0e57 ) +) + +game ( + name "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl)" + description "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Usurper Ghoul (World) (v1.9) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fc94dbf3 sha1 5be7317929c81780f478f745111f8f45798da866 ) +) + +game ( + name "UXB (World) (Aftermarket) (Unl)" + description "UXB (World) (Aftermarket) (Unl)" + rom ( name "UXB (World) (Aftermarket) (Unl).gbc" size 262144 crc dd42be4c sha1 6ef7abb689b1c75f613ed253644fbb0f377b7a95 ) +) + +game ( + name "Varmit (World) (Aftermarket) (Unl)" + description "Varmit (World) (Aftermarket) (Unl)" + rom ( name "Varmit (World) (Aftermarket) (Unl).gbc" size 2097152 crc e4827006 sha1 b61876c714c47f62a77304b79f6e34b8d0e7f8a2 ) +) + +game ( + name "Vixen (World) (Aftermarket) (Unl)" + description "Vixen (World) (Aftermarket) (Unl)" + rom ( name "Vixen (World) (Aftermarket) (Unl).gbc" size 524288 crc 0c347734 sha1 90f251f8f481f157de5b3efe3c8e3356ed1314b4 ) +) + +game ( + name "VOX (World) (Aftermarket) (Unl)" + description "VOX (World) (Aftermarket) (Unl)" + rom ( name "VOX (World) (Aftermarket) (Unl).gbc" size 262144 crc 346561fb sha1 54a03c77653a19eb1b0d8a6ac82f498f83f35ef2 ) +) + +game ( + name "Wacky Painter (World) (Aftermarket) (Unl)" + description "Wacky Painter (World) (Aftermarket) (Unl)" + rom ( name "Wacky Painter (World) (Aftermarket) (Unl).gbc" size 262144 crc 09daa18d sha1 5425dc675101d63bea03b1c8f46f86fe200ad392 ) +) + +game ( + name "Walaki (World) (Hu) (Aftermarket) (Unl)" + description "Walaki (World) (Hu) (Aftermarket) (Unl)" + rom ( name "Walaki (World) (Hu) (Aftermarket) (Unl).gbc" size 262144 crc 254875ac sha1 388d6c339b8d62db18e540f59a2930af4088ca7e ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 1bfe1bf9 sha1 fae12dbbb75ae024e96a7ee21ad4077fdb5ed9a1 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc a381c914 sha1 adf37c5d2f706743b2a4946378df49ed19212039 ) +) + +game ( + name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + description "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Warp Coin Catastrophe, The (World) (v1.1.2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 5519c167 sha1 04a53af6a77b884af91f8047d70fc0331bf23913 ) +) + +game ( + name "Water Grandprix (World) (Aftermarket) (Unl)" + description "Water Grandprix (World) (Aftermarket) (Unl)" + rom ( name "Water Grandprix (World) (Aftermarket) (Unl).gbc" size 262144 crc 82f54e7e sha1 4029e003870b2afb78a3644e24397d80fc5a3210 ) +) + +game ( + name "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 32768 crc ef202121 sha1 a11f931b18ba42f48a91e817b7117fa0e3e79518 ) +) + +game ( + name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (Batteryless Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 75591760 sha1 e04b01ada17e6924503029cd09a107b7f5d06f17 ) +) + +game ( + name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + description "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Waternet (World) (Batteryless Generic Save Flash Cartridge Version) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc f8402dc5 sha1 6feb4178589e87c6267683078201f0630cca23d6 ) +) + +game ( + name "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl)" + description "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl)" + rom ( name "Wayfarer Boo - Pushing Through (World) (v1.1) (Aftermarket) (Unl).gbc" size 262144 crc 903d1b1a sha1 12b8a0bdadd503f6114fcf28a43652d5d69749f4 ) +) + +game ( + name "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl)" + description "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl)" + rom ( name "Wayfarer Boo - Pushing Through (World) (v1.0) (Aftermarket) (Unl).gbc" size 262144 crc b5d0ab10 sha1 7451a93a3a2f17b5187883ad2b59c4dda99a2ac7 ) +) + +game ( + name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + description "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What Friends Are For (World) (v2.0) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 776fc18e sha1 5c4a227c0b2f53e4a349e482c5ba87cb83404f8e ) +) + +game ( + name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + description "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "What's Updog (World) (2022-11-23) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 2c3d5cbf sha1 a235c0915ac2b826eeb5884d0eccd321236fdb0c ) +) + +game ( + name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" + description "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Where's My Cake (World) (GB Compatible) (Aftermarket) (Unl).GBC" size 65536 crc 28114b89 sha1 05b90f0a7e92d42b3008c749d5edeab2a2eae973 ) +) + +game ( + name "Who Dares Wins II (World) (Aftermarket) (Unl)" + description "Who Dares Wins II (World) (Aftermarket) (Unl)" + rom ( name "Who Dares Wins II (World) (Aftermarket) (Unl).gbc" size 262144 crc d12ea4bd sha1 cd91248bc0efd4fd3f182eda4559b1d6b720e3d9 ) +) + +game ( + name "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl)" + description "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl)" + rom ( name "Wicked Plague (World) (v0.1.2) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc 80e43cec sha1 dee4f074029352efb3e6683e0c31c9350bdb8199 ) +) + +game ( + name "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl)" + description "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl)" + rom ( name "Wicked Plague (World) (v0.1.1) (Proto) (Aftermarket) (Unl).gbc" size 524288 crc 4029708f sha1 2279270c9a0d28934c5b5efda9c047ab27ffccb8 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 04e04980 sha1 574cf911d6d8f73699203cd6db42ceec777f7f93 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (EGS) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 7328cfb6 sha1 039874148f27ffe533de4ef086f29e724a3217a9 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Beta 1) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 6bc9de3d sha1 12d55dad39a9663083f9ad176563576a5cc44069 ) +) + +game ( + name "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl)" + description "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wing Warriors (World) (En,Fr,Es) (Kitmaker) (GB Compatible) (Aftermarket) (Unl).gbc" size 131072 crc 5179988b sha1 20e8daa159ceddace966afd3cd19eae71bb3bf6f ) +) + +game ( + name "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + description "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Witches and Butchers (World) (Demo 2) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 321aecca sha1 90541cd5b08f6030b5b2fe4f1e0ac7c0b616e01e ) +) + +game ( + name "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + description "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Witches and Butchers (World) (Demo 4) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 9b53a90f sha1 77210d3c0825d913f4aebf09a10897a84ca23881 ) +) + +game ( + name "Wizard of Wor (World) (Aftermarket) (Unl)" + description "Wizard of Wor (World) (Aftermarket) (Unl)" + rom ( name "Wizard of Wor (World) (Aftermarket) (Unl).gbc" size 524288 crc 492a9529 sha1 a391646d259a39e7026574145e0a2bacf5f6937b ) +) + +game ( + name "Wolf Pack (World) (Aftermarket) (Unl)" + description "Wolf Pack (World) (Aftermarket) (Unl)" + rom ( name "Wolf Pack (World) (Aftermarket) (Unl).gbc" size 262144 crc ae35b80b sha1 56b20f0ab63a1459c1271e4cd062e8f92f7d10a4 ) +) + +game ( + name "World Cup (World) (Aftermarket) (Unl)" + description "World Cup (World) (Aftermarket) (Unl)" + rom ( name "World Cup (World) (Aftermarket) (Unl).gbc" size 262144 crc 56b3ab5f sha1 075890510b3ef205ca50ebbbcf7c0a0c56032cb9 ) +) + +game ( + name "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Wrestling Thunder City (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc 4fc94f1c sha1 3c5e6ec96c1110ef9c21a8d92cc24c0c721fddd3 ) +) + +game ( + name "Xzap (World) (Aftermarket) (Unl)" + description "Xzap (World) (Aftermarket) (Unl)" + rom ( name "Xzap (World) (Aftermarket) (Unl).gbc" size 262144 crc 68ceec9c sha1 35ae73d3ec93c95fdad9a358ccc34bcfc12445b1 ) +) + +game ( + name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En,Fr,Pt) (GB Compatible) (Aftermarket) (Unl).gbc" size 2097152 crc b304833d sha1 c2be46b8230bfcf509d031902c9bf144de97ef58 ) +) + +game ( + name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (En) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc f15351c8 sha1 a78ff2eef780287bbdc37df122cfc1c504526662 ) +) + +game ( + name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + description "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Year After, The (World) (Pt) (Beta) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc b70c1c7f sha1 ce25cdf6a6264586423e76e34dc42779d39a1cb1 ) +) + +game ( + name "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "YiYa - The Digital Pet Game (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc b2c84c00 sha1 8bf1843102bc5a8577a8d0b44a16e46ade14bd16 ) +) + +game ( + name "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "YiYa - The Digital Pet Game DX (World) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc 21e80905 sha1 b372eb9d049c962392868d7abfcb7b7e4ab2d40f ) +) + +game ( + name "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + description "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Yurivania - Uhaul of the Night (World) (v1.5) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc c5447011 sha1 8197ed0ac5591893b7d04ed3f02529f120daab7e ) +) + +game ( + name "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + description "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Yurivania 0 - Soul Night Prelude (World) (v1.3) (GB Compatible) (Aftermarket) (Unl).gbc" size 262144 crc 8cdf4b90 sha1 9df6bf7c2babc47cc9e461d16a7ab1a24d898003 ) +) + +game ( + name "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl)" + description "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl)" + rom ( name "Yurivania II - Josette's Quest (World) (v1.3) (Aftermarket) (Unl).gbc" size 1048576 crc b80d7525 sha1 05c7256bf9f12f60f453a0627d813904c8713378 ) +) + +game ( + name "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl)" + description "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl)" + rom ( name "Yurivania II - Josette's Quest (World) (v1.2) (Aftermarket) (Unl).gbc" size 1048576 crc c3a76413 sha1 6b6dac77795148d7eba6f7c8fa1c65a6d1e404c3 ) +) + +game ( + name "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl)" + description "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl)" + rom ( name "Yurivania III - Circle of the Polycule (World) (v1.4) (Aftermarket) (Unl).gbc" size 2097152 crc 439b087f sha1 91178b5ba17e891060badf0c7681e6a76052de97 ) +) + +game ( + name "Zagan Warrior (World) (Aftermarket) (Unl)" + description "Zagan Warrior (World) (Aftermarket) (Unl)" + rom ( name "Zagan Warrior (World) (Aftermarket) (Unl).gbc" size 262144 crc e770f71a sha1 99d9267946e7bf26942a8276863ba50ef0b8f90e ) +) + +game ( + name "Zap'em (World) (Aftermarket) (Unl)" + description "Zap'em (World) (Aftermarket) (Unl)" + rom ( name "Zap'em (World) (Aftermarket) (Unl).gbc" size 262144 crc 66f17c5e sha1 63d44c8c2492dc32bcf632feb2d994e9af25fc97 ) +) + +game ( + name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + description "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl)" + rom ( name "Zephyr's Pass (World) (v1.02) (Demo) (Aftermarket) (Unl).gbc" size 2097152 crc db0951d3 sha1 7b74c658f24894659cfda1fc3c7775fd9f7b6013 ) +) + +game ( + name "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl)" + description "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Zippy The Pinecone (World) (GB Compatible) (Aftermarket) (Unl).gbc" size 1048576 crc d1854d92 sha1 ba5f1a020f39ecd29669fc38ca4b23dd4f3dc061 ) +) + +game ( + name "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl)" + description "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl)" + rom ( name "Zippy The Pinecone (World) (v2.7) (Demo) (GB Compatible) (Aftermarket) (Unl).gbc" size 524288 crc fc555c4d sha1 ad3e95a917c4572c150b4b7cc49d17f1b20a0408 ) +) + +game ( + name "Zodiac (World) (Aftermarket) (Unl)" + description "Zodiac (World) (Aftermarket) (Unl)" + rom ( name "Zodiac (World) (Aftermarket) (Unl).gbc" size 262144 crc c4d86c05 sha1 73bd9e6e3bede8de489680ba84129e8fd17abbc0 ) +) + game ( name "Zone Control (World) (Aftermarket) (Unl)" description "Zone Control (World) (Aftermarket) (Unl)" @@ -48040,8 +50693,8 @@ game ( ) game ( - name "Zook Z (USA) (Unl)" - description "Zook Z (USA) (Unl)" - rom ( name "Zook Z (USA) (Unl).gbc" size 1048576 crc a7b09e70 sha1 243cc40cfc6bcbd3b6106870773a72edff079904 ) + name "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl)" + description "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl)" + rom ( name "Zork + Harris (World) (v0.0.1.0) (Proto) (Aftermarket) (Unl).gbc" size 262144 crc 38282614 sha1 2507cfd5414c45b8a2f9839552d6115730da6bf8 ) ) From 8ab2681bca4052b9c53fb8d255e42d28a9095821 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 10 Aug 2024 21:23:00 -0700 Subject: [PATCH 124/148] Core: Expose more ROM information from the API --- CHANGES | 1 + include/mgba/core/core.h | 3 +- include/mgba/core/interface.h | 8 +++++ include/mgba/internal/gb/gb.h | 3 +- include/mgba/internal/gba/gba.h | 3 +- src/core/library.c | 7 +++-- src/core/scripting.c | 12 ++++---- src/gb/core.c | 11 ++----- src/gb/gb.c | 37 +++++++++-------------- src/gba/core.c | 11 ++----- src/gba/gba.c | 33 ++++++++++---------- src/platform/qt/BattleChipView.cpp | 13 ++++---- src/platform/qt/CoreController.cpp | 6 ++-- src/platform/qt/GBAOverride.cpp | 6 ++-- src/platform/qt/ROMInfo.cpp | 14 ++++----- src/platform/qt/ROMInfo.ui | 48 +++++++++++++++++++++++++----- src/platform/qt/ReportView.cpp | 15 +++++----- src/platform/test/perf-main.c | 7 ++--- 18 files changed, 129 insertions(+), 109 deletions(-) diff --git a/CHANGES b/CHANGES index 9af2528d9..c2617c316 100644 --- a/CHANGES +++ b/CHANGES @@ -49,6 +49,7 @@ Misc: - Qt: Handle multiple save game files for disparate games separately (fixes mgba.io/i/2887) - Qt: Remove maligned double-click-to-fullscreen shortcut (closes mgba.io/i/2632) - Qt: Pass logging context through to video proxy thread (fixes mgba.io/i/3095) + - Qt: Show maker code and game version in ROM info - Scripting: Add `callbacks:oneshot` for single-call callbacks - Switch: Add bilinear filtering option (closes mgba.io/i/3111) - Vita: Add imc0 and xmc0 mount point support diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 97f256c82..18295ed13 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -119,8 +119,7 @@ struct mCore { int32_t (*frameCycles)(const struct mCore*); int32_t (*frequency)(const struct mCore*); - void (*getGameTitle)(const struct mCore*, char* title); - void (*getGameCode)(const struct mCore*, char* title); + void (*getGameInfo)(const struct mCore*, struct mGameInfo* info); void (*setPeripheral)(struct mCore*, int type, void*); void* (*getPeripheral)(struct mCore*, int type); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 3e6261e9c..2f4e299dd 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -22,6 +22,14 @@ enum mCoreFeature { mCORE_FEATURE_OPENGL = 1, }; +struct mGameInfo { + char title[17]; + char system[4]; + char code[5]; + char maker[3]; + uint8_t version; +}; + struct mCoreCallbacks { void* context; void (*videoFrameStarted)(void* context); diff --git a/include/mgba/internal/gb/gb.h b/include/mgba/internal/gb/gb.h index 08068ec58..64579d3c1 100644 --- a/include/mgba/internal/gb/gb.h +++ b/include/mgba/internal/gb/gb.h @@ -190,8 +190,7 @@ void GBSavedataUnmask(struct GB* gb); struct Patch; void GBApplyPatch(struct GB* gb, struct Patch* patch); -void GBGetGameTitle(const struct GB* gba, char* out); -void GBGetGameCode(const struct GB* gba, char* out); +void GBGetGameInfo(const struct GB* gba, struct mGameInfo* info); void GBTestKeypadIRQ(struct GB* gb); diff --git a/include/mgba/internal/gba/gba.h b/include/mgba/internal/gba/gba.h index cc340d760..ea9d69961 100644 --- a/include/mgba/internal/gba/gba.h +++ b/include/mgba/internal/gba/gba.h @@ -182,8 +182,7 @@ void GBAUnloadMB(struct GBA* gba); bool GBALoadNull(struct GBA* gba); -void GBAGetGameCode(const struct GBA* gba, char* out); -void GBAGetGameTitle(const struct GBA* gba, char* out); +void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info); void GBATestKeypadIRQ(struct GBA* gba); diff --git a/src/core/library.c b/src/core/library.c index 44148f7f5..1c92a0cbc 100644 --- a/src/core/library.c +++ b/src/core/library.c @@ -6,6 +6,7 @@ #include #include +#include #include #ifdef USE_SQLITE3 @@ -291,8 +292,10 @@ bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const cha core->init(core); core->loadROM(core, vf); - core->getGameTitle(core, entry.internalTitle); - core->getGameCode(core, entry.internalCode); + struct mGameInfo info; + core->getGameInfo(core, &info); + snprintf(entry.internalCode, sizeof(entry.internalCode), "%s-%s", info.system, info.code); + strlcpy(entry.internalTitle, info.title, sizeof(entry.internalTitle)); core->checksum(core, &entry.crc32, mCHECKSUM_CRC32); entry.platform = core->platform(core); entry.title = NULL; diff --git a/src/core/scripting.c b/src/core/scripting.c index ea0af459d..064027d45 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -332,15 +332,15 @@ mSCRIPT_DEFINE_STRUCT(mScriptMemoryDomain) mSCRIPT_DEFINE_END; static struct mScriptValue* _mScriptCoreGetGameTitle(const struct mCore* core) { - char title[32] = {0}; - core->getGameTitle(core, title); - return mScriptStringCreateFromASCII(title); + struct mGameInfo info; + core->getGameInfo(core, &info); + return mScriptStringCreateFromASCII(info.title); } static struct mScriptValue* _mScriptCoreGetGameCode(const struct mCore* core) { - char code[16] = {0}; - core->getGameCode(core, code); - return mScriptStringCreateFromASCII(code); + struct mGameInfo info; + core->getGameInfo(core, &info); + return mScriptStringCreateFromASCII(info.code); } static struct mScriptValue* _mScriptCoreChecksum(const struct mCore* core, int t) { diff --git a/src/gb/core.c b/src/gb/core.c index 4e8351fc6..ed8dda1e5 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -781,12 +781,8 @@ static int32_t _GBCoreFrequency(const struct mCore* core) { return DMG_SM83_FREQUENCY; } -static void _GBCoreGetGameTitle(const struct mCore* core, char* title) { - GBGetGameTitle(core->board, title); -} - -static void _GBCoreGetGameCode(const struct mCore* core, char* title) { - GBGetGameCode(core->board, title); +static void _GBCoreGetGameInfo(const struct mCore* core, struct mGameInfo* info) { + GBGetGameInfo(core->board, info); } static void _GBCoreSetPeripheral(struct mCore* core, int type, void* periph) { @@ -1332,8 +1328,7 @@ struct mCore* GBCoreCreate(void) { core->frameCounter = _GBCoreFrameCounter; core->frameCycles = _GBCoreFrameCycles; core->frequency = _GBCoreFrequency; - core->getGameTitle = _GBCoreGetGameTitle; - core->getGameCode = _GBCoreGetGameCode; + core->getGameInfo = _GBCoreGetGameInfo; core->setPeripheral = _GBCoreSetPeripheral; core->getPeripheral = _GBCoreGetPeripheral; core->busRead8 = _GBCoreBusRead8; diff --git a/src/gb/gb.c b/src/gb/gb.c index c6198ed58..ea0a4d7df 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include const uint32_t CGB_SM83_FREQUENCY = 0x800000; @@ -1116,38 +1117,28 @@ bool GBIsROM(struct VFile* vf) { return false; } -void GBGetGameTitle(const struct GB* gb, char* out) { +void GBGetGameInfo(const struct GB* gb, struct mGameInfo* info) { + memset(info, 0, sizeof(*info)); const struct GBCartridge* cart = NULL; if (gb->memory.rom) { cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; } - if (!cart) { - return; - } - if (cart->oldLicensee != 0x33) { - memcpy(out, cart->titleLong, 16); - } else { - memcpy(out, cart->titleShort, 11); - } -} -void GBGetGameCode(const struct GB* gb, char* out) { - memset(out, 0, 8); - const struct GBCartridge* cart = NULL; - if (gb->memory.rom) { - cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; - } - if (!cart) { - return; - } if (cart->cgb == 0xC0) { - memcpy(out, "CGB-????", 8); + strlcpy(info->system, "CGB", sizeof(info->system)); } else { - memcpy(out, "DMG-????", 8); + strlcpy(info->system, "DMG", sizeof(info->system)); } - if (cart->oldLicensee == 0x33) { - memcpy(&out[4], cart->maker, 4); + + if (cart->oldLicensee != 0x33) { + memcpy(info->title, cart->titleLong, 16); + snprintf(info->maker, sizeof(info->maker), "%02X", cart->oldLicensee); + } else { + memcpy(info->title, cart->titleShort, 11); + memcpy(info->code, cart->maker, 4); + memcpy(info->maker, &cart->licensee, 2); } + info->version = cart->version; } void GBFrameStarted(struct GB* gb) { diff --git a/src/gba/core.c b/src/gba/core.c index 1f39afea6..b39a5f401 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -870,12 +870,8 @@ static int32_t _GBACoreFrequency(const struct mCore* core) { return GBA_ARM7TDMI_FREQUENCY; } -static void _GBACoreGetGameTitle(const struct mCore* core, char* title) { - GBAGetGameTitle(core->board, title); -} - -static void _GBACoreGetGameCode(const struct mCore* core, char* title) { - GBAGetGameCode(core->board, title); +static void _GBACoreGetGameInfo(const struct mCore* core, struct mGameInfo* info) { + GBAGetGameInfo(core->board, info); } static void _GBACoreSetPeripheral(struct mCore* core, int type, void* periph) { @@ -1550,8 +1546,7 @@ struct mCore* GBACoreCreate(void) { core->frameCounter = _GBACoreFrameCounter; core->frameCycles = _GBACoreFrameCycles; core->frequency = _GBACoreFrequency; - core->getGameTitle = _GBACoreGetGameTitle; - core->getGameCode = _GBACoreGetGameCode; + core->getGameInfo = _GBACoreGetGameInfo; core->setPeripheral = _GBACoreSetPeripheral; core->getPeripheral = _GBACoreGetPeripheral; core->busRead8 = _GBACoreBusRead8; diff --git a/src/gba/gba.c b/src/gba/gba.c index 2d10f5cc9..f9c4dad5d 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifdef USE_ELF @@ -849,26 +850,24 @@ bool GBAIsBIOS(struct VFile* vf) { return true; } -void GBAGetGameCode(const struct GBA* gba, char* out) { - memset(out, 0, 8); - if (!gba->memory.rom) { - return; - } - - memcpy(out, "AGB-", 4); - memcpy(&out[4], &((struct GBACartridge*) gba->memory.rom)->id, 4); -} - -void GBAGetGameTitle(const struct GBA* gba, char* out) { +void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info) { + memset(info, 0, sizeof(*info)); + strlcpy(info->system, "AGB", sizeof(info->system)); + struct GBACartridge* cart = NULL; if (gba->memory.rom) { - memcpy(out, &((struct GBACartridge*) gba->memory.rom)->title, 12); - return; + cart = (struct GBACartridge*) gba->memory.rom; + } else if (gba->isPristine && gba->memory.wram) { + cart = (struct GBACartridge*) gba->memory.wram; } - if (gba->isPristine && gba->memory.wram) { - memcpy(out, &((struct GBACartridge*) gba->memory.wram)->title, 12); - return; + + if (cart) { + memcpy(info->title, &cart->title, 12); + memcpy(info->code, &cart->id, 4); + memcpy(info->maker, &cart->maker, 2); + info->version = cart->version; + } else { + strlcpy(info->title, "(BIOS)", 12); } - strncpy(out, "(BIOS)", 12); } void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) { diff --git a/src/platform/qt/BattleChipView.cpp b/src/platform/qt/BattleChipView.cpp index d72f78c41..f7d6eb4c7 100644 --- a/src/platform/qt/BattleChipView.cpp +++ b/src/platform/qt/BattleChipView.cpp @@ -30,12 +30,11 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_ui.setupUi(this); m_ui.chipList->setModel(&m_model); - char title[9]; CoreController::Interrupter interrupter(m_controller); mCore* core = m_controller->thread()->core; - title[8] = '\0'; - core->getGameCode(core, title); - QString qtitle(title); + mGameInfo info; + core->getGameInfo(core, &info); + QString qtitle(info.title); #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) int size = QFontMetrics(QFont()).height() / ((int) ceil(devicePixelRatioF()) * 12); @@ -101,11 +100,11 @@ BattleChipView::BattleChipView(std::shared_ptr controller, Windo m_controller->attachBattleChipGate(); setFlavor(4); - if (qtitle.startsWith("AGB-B4B") || qtitle.startsWith("AGB-B4W") || qtitle.startsWith("AGB-BR4") || qtitle.startsWith("AGB-BZ3")) { + if (qtitle.startsWith("B4B") || qtitle.startsWith("B4W") || qtitle.startsWith("BR4") || qtitle.startsWith("BZ3")) { m_ui.gateBattleChip->setChecked(true); - } else if (qtitle.startsWith("AGB-BRB") || qtitle.startsWith("AGB-BRK")) { + } else if (qtitle.startsWith("BRB") || qtitle.startsWith("BRK")) { m_ui.gateProgress->setChecked(true); - } else if (qtitle.startsWith("AGB-BR5") || qtitle.startsWith("AGB-BR6")) { + } else if (qtitle.startsWith("BR5") || qtitle.startsWith("BR6")) { m_ui.gateBeastLink->setChecked(true); } diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 02cd4db4c..519ce45fb 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -1318,9 +1318,9 @@ void CoreController::updateROMInfo() { mCore* core = m_threadContext.core; core->checksum(core, &m_crc32, mCHECKSUM_CRC32); - char gameTitle[17] = { '\0' }; - core->getGameTitle(core, gameTitle); - m_internalTitle = QLatin1String(gameTitle); + mGameInfo info; + core->getGameInfo(core, &info); + m_internalTitle = QLatin1String(info.title); #ifdef USE_SQLITE3 if (db && m_crc32 && NoIntroDBLookupGameByCRC(db, m_crc32, &game)) { diff --git a/src/platform/qt/GBAOverride.cpp b/src/platform/qt/GBAOverride.cpp index 57fb2048e..dbf627268 100644 --- a/src/platform/qt/GBAOverride.cpp +++ b/src/platform/qt/GBAOverride.cpp @@ -14,9 +14,9 @@ void GBAOverride::identify(const struct mCore* core) { if (core->platform(core) != mPLATFORM_GBA) { return; } - char gameId[8]; - core->getGameCode(core, gameId); - memcpy(override.id, &gameId[4], 4); + mGameInfo info; + core->getGameInfo(core, &info); + memcpy(override.id, info.code, 4); } void GBAOverride::save(struct Configuration* config) const { diff --git a/src/platform/qt/ROMInfo.cpp b/src/platform/qt/ROMInfo.cpp index 473918f26..9f2537439 100644 --- a/src/platform/qt/ROMInfo.cpp +++ b/src/platform/qt/ROMInfo.cpp @@ -27,16 +27,16 @@ ROMInfo::ROMInfo(std::shared_ptr controller, QWidget* parent) CoreController::Interrupter interrupter(controller); mCore* core = controller->thread()->core; - char title[17] = {}; - core->getGameTitle(core, title); - m_ui.title->setText(QLatin1String(title)); - title[8] = '\0'; - core->getGameCode(core, title); - if (title[0]) { - m_ui.id->setText(QLatin1String(title)); + mGameInfo info; + core->getGameInfo(core, &info); + m_ui.title->setText(QLatin1String(info.title)); + if (info.code[0]) { + m_ui.id->setText(QLatin1String(info.code)); } else { m_ui.id->setText(tr("(unknown)")); } + m_ui.maker->setText(QLatin1String(info.maker)); + m_ui.version->setText(QString::number(info.version)); core->checksum(core, &crc32, mCHECKSUM_CRC32); diff --git a/src/platform/qt/ROMInfo.ui b/src/platform/qt/ROMInfo.ui index 727cff032..655d4810f 100644 --- a/src/platform/qt/ROMInfo.ui +++ b/src/platform/qt/ROMInfo.ui @@ -6,8 +6,8 @@ 0 0 - 236 - 146 + 178 + 198 @@ -75,13 +75,47 @@ + + + Maker Code: + + + + + + + {MAKER} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Revision: + + + + + + + {VERSION} + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + File size: - + {SIZE} @@ -91,14 +125,14 @@ - + CRC32: - + {CRC} @@ -108,14 +142,14 @@ - + Save file: - + {SAVEFILE} diff --git a/src/platform/qt/ReportView.cpp b/src/platform/qt/ReportView.cpp index 04944ef5c..9843cae76 100644 --- a/src/platform/qt/ReportView.cpp +++ b/src/platform/qt/ReportView.cpp @@ -497,17 +497,16 @@ void ReportView::addROMInfo(QStringList& report, CoreController* controller) { report << QString("Currently paused: %1").arg(yesNo[controller->isPaused()]); mCore* core = controller->thread()->core; - char title[17] = {}; - core->getGameTitle(core, title); - report << QString("Internal title: %1").arg(QLatin1String(title)); - - title[8] = '\0'; - core->getGameCode(core, title); - if (title[0]) { - report << QString("Game code: %1").arg(QLatin1String(title)); + struct mGameInfo info; + core->getGameInfo(core, &info); + report << QString("Internal title: %1").arg(QLatin1String(info.title)); + if (info.code[0]) { + report << QString("Game code: %1").arg(QLatin1String(info.code)); } else { report << QString("Invalid game code"); } + report << QString("Game maker: %1").arg(QLatin1String(info.maker)); + report << QString("Game version: %1").arg(info.version); uint32_t crc32 = 0; core->checksum(core, &crc32, mCHECKSUM_CRC32); diff --git a/src/platform/test/perf-main.c b/src/platform/test/perf-main.c index 38d50b30c..26a3715eb 100644 --- a/src/platform/test/perf-main.c +++ b/src/platform/test/perf-main.c @@ -196,8 +196,6 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc } // TODO: Put back debugger - char gameCode[9] = { 0 }; - core->init(core); if (!perfOpts->noVideo) { core->setVideoBuffer(core, _outputBuffer, 256); @@ -226,7 +224,8 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc mCoreLoadStateNamed(core, _savestate, 0); } - core->getGameCode(core, gameCode); + struct mGameInfo info; + core->getGameInfo(core, &info); int frames = perfOpts->frames; if (!frames) { @@ -255,7 +254,7 @@ bool _mPerfRunCore(const char* fname, const struct mArguments* args, const struc } else { rendererName = "software"; } - snprintf(buffer, sizeof(buffer), "%s,%i,%" PRIu64 ",%s\n", gameCode, frames, duration, rendererName); + snprintf(buffer, sizeof(buffer), "%s-%s,%i,%" PRIu64 ",%s\n", info.system, info.code, frames, duration, rendererName); printf("%s", buffer); if (_socket != INVALID_SOCKET) { SocketSend(_socket, buffer, strlen(buffer)); From b12858e97498c2ee4719db5672c0e4843c98c421 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 11 Aug 2024 20:04:35 -0700 Subject: [PATCH 125/148] GBA: Fix getting game info for multiboot ROMs --- CHANGES | 1 + src/gba/gba.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index c2617c316..0adab6673 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Other fixes: - GB: Fix uninitialized save data when loading undersized temporary saves - GB, GBA Core: Fix memory leak if reloading debug symbols - GB Serialize: Prevent loading invalid states where LY >= 144 in modes other than 1 + - GBA: Fix getting game info for multiboot ROMs - GBA Audio: Fix crash if audio FIFOs and timers get out of sync - GBA Audio: Fix crash in audio subsampling if timing lockstep breaks - GBA Core: Fix loading symbols from ELF files if the file doesn't end with .elf diff --git a/src/gba/gba.c b/src/gba/gba.c index f9c4dad5d..ce7e3478e 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -408,10 +408,14 @@ bool GBALoadMB(struct GBA* gba, struct VFile* vf) { gba->mbVf = vf; vf->seek(vf, 0, SEEK_SET); memset(gba->memory.wram, 0, GBA_SIZE_EWRAM); - vf->read(vf, gba->memory.wram, GBA_SIZE_EWRAM); + off_t read = vf->read(vf, gba->memory.wram, GBA_SIZE_EWRAM); + if (read < 0) { + return false; + } if (gba->cpu && gba->memory.activeRegion == GBA_REGION_IWRAM) { gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); } + gba->romCrc32 = doCrc32(gba->memory.wram, read); return true; } @@ -856,7 +860,7 @@ void GBAGetGameInfo(const struct GBA* gba, struct mGameInfo* info) { struct GBACartridge* cart = NULL; if (gba->memory.rom) { cart = (struct GBACartridge*) gba->memory.rom; - } else if (gba->isPristine && gba->memory.wram) { + } else if (gba->mbVf && gba->memory.wram) { cart = (struct GBACartridge*) gba->memory.wram; } From 17cf2e6237f11c802f3d7baa051c44cd7c63ea2c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 11 Aug 2024 23:22:13 -0700 Subject: [PATCH 126/148] No-Intro: Index database on MD5 and SHA1 too --- src/feature/sqlite3/no-intro.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index 649364de6..f79f98a9d 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -47,7 +47,9 @@ struct NoIntroDB* NoIntroDBLoad(const char* path) { "flags INTEGER DEFAULT 0," "gid INTEGER NOT NULL REFERENCES games(gid) ON DELETE CASCADE" ");\n" - "CREATE INDEX IF NOT EXISTS crc32 ON roms (crc32);"; + "CREATE INDEX IF NOT EXISTS crc32 ON roms (crc32);\n" + "CREATE INDEX IF NOT EXISTS md5 ON roms (md5);\n" + "CREATE INDEX IF NOT EXISTS sha1 ON roms (sha1);\n"; if (sqlite3_exec(db->db, createTables, NULL, NULL, NULL)) { goto error; } From dfab80127764acfb3b6e1895a5a2ca890d084fcf Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 12 Aug 2024 16:08:36 -0700 Subject: [PATCH 127/148] No-Intro: Prevent database from being downgraded --- src/feature/sqlite3/no-intro.c | 35 +++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/feature/sqlite3/no-intro.c b/src/feature/sqlite3/no-intro.c index f79f98a9d..463a2fe5e 100644 --- a/src/feature/sqlite3/no-intro.c +++ b/src/feature/sqlite3/no-intro.c @@ -72,6 +72,7 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { sqlite3_stmt* gamedbTable = NULL; sqlite3_stmt* gamedbDrop = NULL; + sqlite3_stmt* gamedbSelect = NULL; sqlite3_stmt* gameTable = NULL; sqlite3_stmt* romTable = NULL; char* fieldName = NULL; @@ -91,6 +92,11 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { return false; } + static const char selectGamedb[] = "SELECT * FROM gamedb WHERE name = ? AND version >= ?;"; + if (sqlite3_prepare_v2(db->db, selectGamedb, -1, &gamedbSelect, NULL)) { + return false; + } + static const char insertGame[] = "INSERT INTO games (dbid, name) VALUES (?, ?);"; if (sqlite3_prepare_v2(db->db, insertGame, -1, &gameTable, NULL)) { return false; @@ -161,18 +167,24 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { break; case ')': if (currentDb < 0 && dbType && dbVersion) { - sqlite3_clear_bindings(gamedbDrop); - sqlite3_reset(gamedbDrop); - sqlite3_bind_text(gamedbDrop, 1, dbType, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(gamedbDrop, 2, dbVersion, -1, SQLITE_TRANSIENT); - sqlite3_step(gamedbDrop); + sqlite3_clear_bindings(gamedbSelect); + sqlite3_reset(gamedbSelect); + sqlite3_bind_text(gamedbSelect, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbSelect, 2, dbVersion, -1, SQLITE_TRANSIENT); + if (sqlite3_step(gamedbSelect) != SQLITE_ROW) { + sqlite3_clear_bindings(gamedbDrop); + sqlite3_reset(gamedbDrop); + sqlite3_bind_text(gamedbDrop, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbDrop, 2, dbVersion, -1, SQLITE_TRANSIENT); + sqlite3_step(gamedbDrop); - sqlite3_clear_bindings(gamedbTable); - sqlite3_reset(gamedbTable); - sqlite3_bind_text(gamedbTable, 1, dbType, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(gamedbTable, 2, dbVersion, -1, SQLITE_TRANSIENT); - if (sqlite3_step(gamedbTable) == SQLITE_DONE) { - currentDb = sqlite3_last_insert_rowid(db->db); + sqlite3_clear_bindings(gamedbTable); + sqlite3_reset(gamedbTable); + sqlite3_bind_text(gamedbTable, 1, dbType, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(gamedbTable, 2, dbVersion, -1, SQLITE_TRANSIENT); + if (sqlite3_step(gamedbTable) == SQLITE_DONE) { + currentDb = sqlite3_last_insert_rowid(db->db); + } } free((void*) dbType); free((void*) dbVersion); @@ -272,6 +284,7 @@ bool NoIntroDBLoadClrMamePro(struct NoIntroDB* db, struct VFile* vf) { sqlite3_finalize(gamedbTable); sqlite3_finalize(gamedbDrop); + sqlite3_finalize(gamedbSelect); sqlite3_finalize(gameTable); sqlite3_finalize(romTable); From cd22c140f07c273026b403f74f98a4716b973bd0 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 13 Aug 2024 00:16:42 -0700 Subject: [PATCH 128/148] GB: Fix potential null pointer deref --- src/gb/gb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index ea0a4d7df..282fc45c1 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1119,11 +1119,11 @@ bool GBIsROM(struct VFile* vf) { void GBGetGameInfo(const struct GB* gb, struct mGameInfo* info) { memset(info, 0, sizeof(*info)); - const struct GBCartridge* cart = NULL; - if (gb->memory.rom) { - cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; + if (!gb->memory.rom) { + return; } + const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100]; if (cart->cgb == 0xC0) { strlcpy(info->system, "CGB", sizeof(info->system)); } else { From e91da0f423f2ac0ac7641fdda622569b256c0e99 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 13 Aug 2024 18:38:07 -0700 Subject: [PATCH 129/148] Scripting: Expose currentCycle in debugger builds The global time is only maintained in debugger builds for performance reasons. While it can be reconstructed on GBA, this is not the case on GB, so limit it to debugger builds only. --- src/core/scripting.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/scripting.c b/src/core/scripting.c index 064027d45..a00d5cbdc 100644 --- a/src/core/scripting.c +++ b/src/core/scripting.c @@ -938,6 +938,10 @@ static bool _mScriptCoreAdapterClearBreakpoint(struct mScriptCoreAdapter* adapte } return true; } + +uint64_t _mScriptCoreAdapterCurrentCycle(struct mScriptCoreAdapter* adapter) { + return mTimingGlobalTime(adapter->core->timing); +} #endif static void _mScriptCoreAdapterDeinit(struct mScriptCoreAdapter* adapter) { @@ -1085,6 +1089,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write16, _mScriptCoreAdap mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptCoreAdapter, write32, _mScriptCoreAdapterWrite32, 2, U32, address, U32, value); #ifdef ENABLE_DEBUGGERS +mSCRIPT_DECLARE_STRUCT_METHOD(mScriptCoreAdapter, U64, currentCycle, _mScriptCoreAdapterCurrentCycle, 0); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setBreakpoint, _mScriptCoreAdapterSetBreakpoint, 3, WRAPPER, callback, U32, address, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setWatchpoint, _mScriptCoreAdapterSetWatchpoint, 4, WRAPPER, callback, U32, address, S32, type, S32, segment); mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mScriptCoreAdapter, S64, setRangeWatchpoint, _mScriptCoreAdapterSetRangeWatchpoint, 5, WRAPPER, callback, U32, minAddress, U32, maxAddress, S32, type, S32, segment); @@ -1150,6 +1155,8 @@ mSCRIPT_DEFINE_STRUCT(mScriptCoreAdapter) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write16) mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, write32) #ifdef ENABLE_DEBUGGERS + mSCRIPT_DEFINE_DOCSTRING("Get the current execution cycle") + mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, currentCycle) mSCRIPT_DEFINE_DOCSTRING("Set a breakpoint at a given address") mSCRIPT_DEFINE_STRUCT_METHOD(mScriptCoreAdapter, setBreakpoint) mSCRIPT_DEFINE_DOCSTRING("Clear a breakpoint or watchpoint for a given id returned by a previous call") From eaee4228bad46a23f2f6805437d239d2b41e5373 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 16 Aug 2024 02:32:44 -0700 Subject: [PATCH 130/148] GBA Video: Improve emulation of window start/end conditions (fixes #1945) --- CHANGES | 1 + .../internal/gba/renderers/video-software.h | 2 + src/gba/renderers/video-software.c | 82 ++++++++++--------- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/CHANGES b/CHANGES index 0adab6673..3aef9e246 100644 --- a/CHANGES +++ b/CHANGES @@ -19,6 +19,7 @@ Emulation fixes: - GBA Serialize: Fix some minor save state edge cases - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) + - GBA Video: Improve emulation of window start/end conditions (fixes mgba.io/i/1945) Other fixes: - Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963) - Debugger: Fix writing to specific segment in command-line debugger diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index 969ffed64..d03c52374 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -118,6 +118,7 @@ struct GBAVideoSoftwareRenderer { struct WindowControl control; int16_t offsetX; int16_t offsetY; + bool on; } winN[2]; struct WindowControl winout; @@ -142,6 +143,7 @@ struct GBAVideoSoftwareRenderer { struct ScanlineCache { uint16_t io[GBA_REG(SOUND1CNT_LO)]; int32_t scale[2][2]; + bool windowOn[2]; } cache[GBA_VIDEO_VERTICAL_PIXELS]; int nextY; diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 6c78c08e0..7eba88ba3 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -35,14 +35,15 @@ 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 GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* renderer, int y); +static void GBAVideoSoftwareRendererStepWindow(struct GBAVideoSoftwareRenderer* renderer, int y); +static void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* renderer); static void GBAVideoSoftwareRendererPostprocessBuffer(struct GBAVideoSoftwareRenderer* renderer); static int GBAVideoSoftwareRendererPreprocessSpriteLayer(struct GBAVideoSoftwareRenderer* renderer, int y); static void _updatePalettes(struct GBAVideoSoftwareRenderer* renderer); static void _updateFlags(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* bg); -static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y); +static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { @@ -343,28 +344,10 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender case GBA_REG_WIN0V: softwareRenderer->winN[0].v.end = value; softwareRenderer->winN[0].v.start = value >> 8; - 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 > 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 GBA_REG_WIN1V: softwareRenderer->winN[1].v.end = value; softwareRenderer->winN[1].v.start = value >> 8; - 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 > 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; case GBA_REG_WININ: value &= 0x3F3F; @@ -432,17 +415,7 @@ static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* render memset(softwareRenderer->scanlineDirty, 0xFFFFFFFF, sizeof(softwareRenderer->scanlineDirty)); } -static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win, int y) { - if (win->v.end >= win->v.start) { - if (y >= win->v.end + win->offsetY) { - return; - } - if (y < win->v.start + win->offsetY) { - return; - } - } else if (y >= win->v.end + win->offsetY && y < win->v.start + win->offsetY) { - return; - } +static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win) { 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; @@ -585,6 +558,14 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render softwareRenderer->cache[y].scale[1][0] = softwareRenderer->bg[3].sx; softwareRenderer->cache[y].scale[1][1] = softwareRenderer->bg[3].sy; + GBAVideoSoftwareRendererStepWindow(softwareRenderer, y); + if (softwareRenderer->cache[y].windowOn[0] != softwareRenderer->winN[0].on || + softwareRenderer->cache[y].windowOn[1] != softwareRenderer->winN[1].on) { + dirty = true; + } + softwareRenderer->cache[y].windowOn[0] = softwareRenderer->winN[0].on; + softwareRenderer->cache[y].windowOn[1] = softwareRenderer->winN[1].on; + if (!dirty) { if (GBARegisterDISPCNTGetMode(softwareRenderer->dispcnt) != 0) { if (softwareRenderer->bg[2].enabled == ENABLED_MAX) { @@ -610,7 +591,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render return; } - GBAVideoSoftwareRendererPreprocessBuffer(softwareRenderer, y); + GBAVideoSoftwareRendererPreprocessBuffer(softwareRenderer); softwareRenderer->spriteCyclesRemaining = GBARegisterDISPCNTIsHblankIntervalFree(softwareRenderer->dispcnt) ? OBJ_HBLANK_FREE_LENGTH : OBJ_LENGTH; int spriteLayers = GBAVideoSoftwareRendererPreprocessSpriteLayer(softwareRenderer, y); @@ -747,6 +728,20 @@ static void GBAVideoSoftwareRendererFinishFrame(struct GBAVideoRenderer* rendere if (softwareRenderer->bg[3].enabled > 0) { softwareRenderer->bg[3].enabled = ENABLED_MAX; } + + int i; + for (i = 0; i < 2; ++i) { + struct WindowN* win = &softwareRenderer->winN[i]; + if (win->v.end >= GBA_VIDEO_VERTICAL_PIXELS && win->v.end < VIDEO_VERTICAL_TOTAL_PIXELS) { + win->on = false; + } + + if (win->v.start >= GBA_VIDEO_VERTICAL_PIXELS && + win->v.start < VIDEO_VERTICAL_TOTAL_PIXELS && + win->v.start > win->v.end) { + win->on = true; + } + } } static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) { @@ -855,7 +850,20 @@ static void GBAVideoSoftwareRendererWriteBLDCNT(struct GBAVideoSoftwareRenderer* } } -void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* softwareRenderer, int y) { +void GBAVideoSoftwareRendererStepWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, int y) { + int i; + for (i = 0; i < 2; ++i) { + struct WindowN* win = &softwareRenderer->winN[i]; + if (y == win->v.start + win->offsetY) { + win->on = true; + } + if (y == win->v.end + win->offsetY) { + win->on = false; + } + } +} + +void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* softwareRenderer) { int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; x += 4) { softwareRenderer->spriteLayer[x] = FLAG_UNWRITTEN; @@ -868,11 +876,11 @@ void GBAVideoSoftwareRendererPreprocessBuffer(struct GBAVideoSoftwareRenderer* s softwareRenderer->nWindows = 1; if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) || GBARegisterDISPCNTIsObjwinEnable(softwareRenderer->dispcnt)) { softwareRenderer->windows[0].control = softwareRenderer->winout; - if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[1]) { - _breakWindow(softwareRenderer, &softwareRenderer->winN[1], y); + if (GBARegisterDISPCNTIsWin1Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[1] && softwareRenderer->winN[1].on) { + _breakWindow(softwareRenderer, &softwareRenderer->winN[1]); } - if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[0]) { - _breakWindow(softwareRenderer, &softwareRenderer->winN[0], y); + if (GBARegisterDISPCNTIsWin0Enable(softwareRenderer->dispcnt) && !softwareRenderer->d.disableWIN[0] && softwareRenderer->winN[0].on) { + _breakWindow(softwareRenderer, &softwareRenderer->winN[0]); } } else { softwareRenderer->windows[0].control.packed = 0xFF; From ecfdff23382c16d6772d6be89f69afafcb3491b2 Mon Sep 17 00:00:00 2001 From: anthonydo8196 Date: Mon, 19 Aug 2024 20:58:47 -0500 Subject: [PATCH 131/148] Add load most recent script menu option (#3266) --- .gitignore | Bin 323 -> 454 bytes src/platform/qt/scripting/ScriptingView.cpp | 15 ++++++++++++++- src/platform/qt/scripting/ScriptingView.h | 2 ++ src/platform/qt/scripting/ScriptingView.ui | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fedbc461f4689076caf4b0cd451a299043c4fcdf..e9e3b3956726efab97169a7e106d812bb3e0b72f 100644 GIT binary patch literal 454 zcmZWl!EVDK4D~ru{sF1CN+tV-RoYIIs!cmr1l-0gfe4eVz3kg((qudAfS=#9{V;6Q zD+Wwt)rmZEU2XNqn6{F97s6jdf#GiJs;)Nbc_idur#z`vMEY8x|HzV2S%TbH%-}9qN3`3x9bmIoCcgX9{Q57mi`6f6DHMgp7HW zZR`gbItunCxK(bnE!K}+ZFG{^UM@UR;B36tGpno4aLC$WK|8aW-Huo@~+JTMIZY7SbdWk}K= Oq=O{a;>WXFnfw82-g}Jz literal 323 zcmYLF!EVDK488j+ka~+$vTsize)|l`v;%(jv;BCmGq0Gi zkT)la$k5rDv2@TqH0A50ak_heoq3)q1{0{Dmt06^`=L@B>^tb~!vB+hdQK(6JselectionModel(), &QItemSelectionModel::currentChanged, this, &ScriptingView::selectBuffer); connect(m_ui.load, &QAction::triggered, this, &ScriptingView::load); + connect(m_ui.loadMostRecent, &QAction::triggered, this, &ScriptingView::loadMostRecent); connect(m_ui.reset, &QAction::triggered, controller, &ScriptingController::reset); m_mruFiles = m_config->getMRU(ConfigController::MRU::Script); @@ -66,6 +67,10 @@ void ScriptingView::load() { } } +void ScriptingView::loadMostRecent() { + m_controller->loadFile(m_mruFiles.at(0)); +} + void ScriptingView::controllerReset() { selectBuffer(QModelIndex()); } @@ -105,7 +110,15 @@ void ScriptingView::updateMRU() { m_ui.mru->clear(); for (const auto& fname : m_mruFiles) { m_ui.mru->addAction(fname, [this, fname]() { - m_controller->loadFile(fname); + if (m_controller->loadFile(fname)) { + appendMRU(fname); + } }); } + checkEmptyMRU(); } + + +void ScriptingView::checkEmptyMRU() { + m_ui.loadMostRecent->setEnabled(!m_mruFiles.isEmpty()); +} \ No newline at end of file diff --git a/src/platform/qt/scripting/ScriptingView.h b/src/platform/qt/scripting/ScriptingView.h index 1f90a3f19..a62bd2314 100644 --- a/src/platform/qt/scripting/ScriptingView.h +++ b/src/platform/qt/scripting/ScriptingView.h @@ -22,6 +22,7 @@ public: private slots: void submitRepl(); void load(); + void loadMostRecent(); void controllerReset(); void selectBuffer(const QModelIndex& current, const QModelIndex& = QModelIndex()); @@ -31,6 +32,7 @@ private: void appendMRU(const QString&); void updateMRU(); + void checkEmptyMRU(); Ui::ScriptingView m_ui; diff --git a/src/platform/qt/scripting/ScriptingView.ui b/src/platform/qt/scripting/ScriptingView.ui index 8b97449b0..4d55a8707 100644 --- a/src/platform/qt/scripting/ScriptingView.ui +++ b/src/platform/qt/scripting/ScriptingView.ui @@ -98,6 +98,7 @@ + @@ -108,6 +109,11 @@ Load script... + + + + &Load most recent + From 84dd69ff86aaaccf85b33f83a26f18203a4a0b4f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 25 Aug 2024 02:32:04 -0700 Subject: [PATCH 132/148] Util: Add UIntList predefined vector --- include/mgba-util/vector.h | 1 + src/util/vector.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/mgba-util/vector.h b/include/mgba-util/vector.h index 8c0f11e45..c837379e2 100644 --- a/include/mgba-util/vector.h +++ b/include/mgba-util/vector.h @@ -112,6 +112,7 @@ CXX_GUARD_START } \ DECLARE_VECTOR(IntList, int); +DECLARE_VECTOR(UIntList, unsigned); DECLARE_VECTOR(SInt8List, int8_t); DECLARE_VECTOR(SInt16List, int16_t); DECLARE_VECTOR(SInt32List, int32_t); diff --git a/src/util/vector.c b/src/util/vector.c index 28750a1b4..f84838a16 100644 --- a/src/util/vector.c +++ b/src/util/vector.c @@ -6,6 +6,7 @@ #include DEFINE_VECTOR(IntList, int); +DEFINE_VECTOR(UIntList, unsigned); DEFINE_VECTOR(SInt8List, int8_t); DEFINE_VECTOR(SInt16List, int16_t); DEFINE_VECTOR(SInt32List, int32_t); From c06a376b2e2f5f9023a6edec1ec20df3ab532c1d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 31 Aug 2024 05:14:54 -0700 Subject: [PATCH 133/148] Core: Switch video log state load/store to use mCore*State functions --- src/feature/video-logger.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 978700864..adcbea276 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -511,9 +511,13 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { #endif if (core) { - context->initialStateSize = core->stateSize(core); + struct VFile* vf = VFileMemChunk(NULL, core->stateSize(core)); + mCoreSaveStateNamed(core, vf, 0); + context->initialStateSize = vf->size(vf); context->initialState = anonymousMemoryMap(context->initialStateSize); - core->saveState(core, context->initialState); + vf->seek(vf, 0, SEEK_SET); + vf->write(vf, context->initialState, context->initialStateSize); + vf->close(vf); core->startVideoLog(core, context); } @@ -763,15 +767,15 @@ void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext* contex void mVideoLogContextRewind(struct mVideoLogContext* context, struct mCore* core) { _readHeader(context); if (core) { - size_t size = core->stateSize(core); - if (size <= context->initialStateSize) { - core->loadState(core, context->initialState); + struct VFile* vf; + if (context->initialStateSize < core->stateSize(core)) { + vf = VFileMemChunk(NULL, core->stateSize(core)); + vf->write(vf, context->initialState, context->initialStateSize); } else { - void* extendedState = anonymousMemoryMap(size); - memcpy(extendedState, context->initialState, context->initialStateSize); - core->loadState(core, extendedState); - mappedMemoryFree(extendedState, size); + vf = VFileFromConstMemory(context->initialState, context->initialStateSize); } + mCoreLoadStateNamed(core, vf, 0); + vf->close(vf); } off_t pointer = context->backing->seek(context->backing, 0, SEEK_CUR); From 3a6657bd88ec04744896e4704a5c40baf1067b75 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 00:55:29 -0700 Subject: [PATCH 134/148] Core: Add stubs for loading/saving subsystem extra state --- include/mgba/core/core.h | 2 ++ include/mgba/core/serialize.h | 2 ++ src/core/serialize.c | 3 +++ src/gb/core.c | 14 ++++++++++++++ src/gba/core.c | 14 ++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 18295ed13..04bca4689 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -109,6 +109,8 @@ struct mCore { size_t (*stateSize)(struct mCore*); bool (*loadState)(struct mCore*, const void* state); bool (*saveState)(struct mCore*, void* state); + bool (*loadExtraState)(struct mCore*, const struct mStateExtdata*); + bool (*saveExtraState)(struct mCore*, struct mStateExtdata*); void (*setKeys)(struct mCore*, uint32_t keys); void (*addKeys)(struct mCore*, uint32_t keys); diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index ee9de69a1..e7b114271 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -17,6 +17,8 @@ enum mStateExtdataTag { EXTDATA_CHEATS = 3, EXTDATA_RTC = 4, EXTDATA_SCREENSHOT_DIMENSIONS = 5, + EXTDATA_SUBSYSTEM_START = 0x40, + EXTDATA_SUBSYSTEM_MAX = 0x7F, EXTDATA_META_TIME = 0x101, EXTDATA_META_CREATOR = 0x102, EXTDATA_MAX diff --git a/src/core/serialize.c b/src/core/serialize.c index b721cdafa..e42457470 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -371,6 +371,7 @@ bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags) { mStateExtdataInit(&extdata); size_t stateSize = core->stateSize(core); + core->saveExtraState(core, &extdata); if (flags & SAVESTATE_METADATA) { uint64_t* creationUsec = malloc(sizeof(*creationUsec)); if (creationUsec) { @@ -528,6 +529,8 @@ bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags) { bool success = core->loadState(core, state); mappedMemoryFree(state, core->stateSize(core)); + core->loadExtraState(core, &extdata); + unsigned width, height; core->currentVideoSize(core, &width, &height); diff --git a/src/gb/core.c b/src/gb/core.c index ed8dda1e5..17a474ed1 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -743,6 +743,18 @@ static bool _GBCoreSaveState(struct mCore* core, void* state) { return true; } +static bool _GBCoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + +static bool _GBCoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + static void _GBCoreSetKeys(struct mCore* core, uint32_t keys) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->keys = keys; @@ -1321,6 +1333,8 @@ struct mCore* GBCoreCreate(void) { core->stateSize = _GBCoreStateSize; core->loadState = _GBCoreLoadState; core->saveState = _GBCoreSaveState; + core->loadExtraState = _GBCoreLoadExtraState; + core->saveExtraState = _GBCoreSaveExtraState; core->setKeys = _GBCoreSetKeys; core->addKeys = _GBCoreAddKeys; core->clearKeys = _GBCoreClearKeys; diff --git a/src/gba/core.c b/src/gba/core.c index b39a5f401..904d85c20 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -832,6 +832,18 @@ static bool _GBACoreSaveState(struct mCore* core, void* state) { return true; } +static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + +static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { + UNUSED(core); + UNUSED(extdata); + return true; +} + static void _GBACoreSetKeys(struct mCore* core, uint32_t keys) { struct GBA* gba = core->board; gba->keysActive = keys; @@ -1539,6 +1551,8 @@ struct mCore* GBACoreCreate(void) { core->stateSize = _GBACoreStateSize; core->loadState = _GBACoreLoadState; core->saveState = _GBACoreSaveState; + core->loadExtraState = _GBACoreLoadExtraState; + core->saveExtraState = _GBACoreSaveExtraState; core->setKeys = _GBACoreSetKeys; core->addKeys = _GBACoreAddKeys; core->clearKeys = _GBACoreClearKeys; From 59b561b8c01d988d267c2ffc371733b899a81a78 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:28:05 -0700 Subject: [PATCH 135/148] Core: mStateExtdataGet const correctness --- include/mgba/core/serialize.h | 2 +- src/core/serialize.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mgba/core/serialize.h b/include/mgba/core/serialize.h index e7b114271..177a7871a 100644 --- a/include/mgba/core/serialize.h +++ b/include/mgba/core/serialize.h @@ -44,7 +44,7 @@ struct mStateExtdata { void mStateExtdataInit(struct mStateExtdata*); void mStateExtdataDeinit(struct mStateExtdata*); void mStateExtdataPut(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); -bool mStateExtdataGet(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); +bool mStateExtdataGet(const struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*); struct VFile; bool mStateExtdataSerialize(struct mStateExtdata* extdata, struct VFile* vf); diff --git a/src/core/serialize.c b/src/core/serialize.c index e42457470..203ed809a 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -57,7 +57,7 @@ void mStateExtdataPut(struct mStateExtdata* extdata, enum mStateExtdataTag tag, extdata->data[tag] = *item; } -bool mStateExtdataGet(struct mStateExtdata* extdata, enum mStateExtdataTag tag, struct mStateExtdataItem* item) { +bool mStateExtdataGet(const struct mStateExtdata* extdata, enum mStateExtdataTag tag, struct mStateExtdataItem* item) { if (tag == EXTDATA_NONE || tag >= EXTDATA_MAX) { return false; } From da553d191f005e7a921dc1067b973e3d516b7d81 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:36:07 -0700 Subject: [PATCH 136/148] Core: Extdata should not have a size < 0 --- src/core/serialize.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/serialize.c b/src/core/serialize.c index 203ed809a..4f7c07a4a 100644 --- a/src/core/serialize.c +++ b/src/core/serialize.c @@ -131,6 +131,9 @@ bool mStateExtdataDeserialize(struct mStateExtdata* extdata, struct VFile* vf) { if (vf->seek(vf, header.offset, SEEK_SET) < 0) { return false; } + if (header.size <= 0) { + continue; + } struct mStateExtdataItem item = { .data = malloc(header.size), .size = header.size, From a5ea157c9a73aca2247f34c2e9ed461ec2861c2f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 1 Sep 2024 01:56:52 -0700 Subject: [PATCH 137/148] GBA Video: Add stubs for saving/loading extra data out of the video renderers --- include/mgba/feature/video-logger.h | 6 ++++ include/mgba/internal/gba/serialize.h | 5 +++ include/mgba/internal/gba/video.h | 4 +++ src/gba/core.c | 41 ++++++++++++++++++++--- src/gba/extra/proxy.c | 47 +++++++++++++++++++++++++++ src/gba/renderers/gl.c | 29 +++++++++++++++++ src/gba/renderers/video-software.c | 30 ++++++++++++++++- 7 files changed, 156 insertions(+), 6 deletions(-) diff --git a/include/mgba/feature/video-logger.h b/include/mgba/feature/video-logger.h index cf50dd58e..373ea8069 100644 --- a/include/mgba/feature/video-logger.h +++ b/include/mgba/feature/video-logger.h @@ -35,6 +35,8 @@ enum mVideoLoggerEvent { LOGGER_EVENT_DEINIT, LOGGER_EVENT_RESET, LOGGER_EVENT_GET_PIXELS, + LOGGER_EVENT_LOAD_STATE, + LOGGER_EVENT_SAVE_STATE, }; enum mVideoLoggerInjectionPoint { @@ -85,6 +87,10 @@ struct mVideoLogger { const void* pixelBuffer; size_t pixelStride; + + void* stateBuffer; + size_t stateSize; + bool stateStatus; }; void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly); diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index b31fd0f5a..9bd21821a 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -285,6 +285,11 @@ DECL_BIT(GBASerializedMiscFlags, IrqPending, 2); DECL_BIT(GBASerializedMiscFlags, Blocked, 3); DECL_BITS(GBASerializedMiscFlags, KeyIRQKeys, 4, 11); +enum { + GBA_SUBSYSTEM_VIDEO_RENDERER = 0, + GBA_SUBSYSTEM_MAX, +}; + struct GBASerializedState { uint32_t versionMagic; uint32_t biosChecksum; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index b29b3d607..924772660 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -182,6 +182,10 @@ struct GBAVideoRenderer { void (*reset)(struct GBAVideoRenderer* renderer); void (*deinit)(struct GBAVideoRenderer* renderer); + uint32_t (*rendererId)(const struct GBAVideoRenderer* renderer); + bool (*loadState)(struct GBAVideoRenderer* renderer, const void* state, size_t size); + void (*saveState)(struct GBAVideoRenderer* renderer, void** state, size_t* size); + uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); void (*writeVRAM)(struct GBAVideoRenderer* renderer, uint32_t address); void (*writePalette)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); diff --git a/src/gba/core.c b/src/gba/core.c index 904d85c20..e9cf2b81c 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -833,14 +834,44 @@ static bool _GBACoreSaveState(struct mCore* core, void* state) { } static bool _GBACoreLoadExtraState(struct mCore* core, const struct mStateExtdata* extdata) { - UNUSED(core); - UNUSED(extdata); - return true; + struct GBA* gba = core->board; + struct mStateExtdataItem item; + bool ok = true; + if (mStateExtdataGet(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_VIDEO_RENDERER, &item)) { + if ((uint32_t) item.size > sizeof(uint32_t)) { + uint32_t type; + LOAD_32(type, 0, item.data); + if (type == gba->video.renderer->rendererId(gba->video.renderer)) { + ok = gba->video.renderer->loadState(gba->video.renderer, + (void*) ((uintptr_t) item.data + sizeof(uint32_t)), + item.size - sizeof(type)); + } + } else if (item.data) { + ok = false; + } + } + return ok; } static bool _GBACoreSaveExtraState(struct mCore* core, struct mStateExtdata* extdata) { - UNUSED(core); - UNUSED(extdata); + struct GBA* gba = core->board; + void* buffer = NULL; + size_t size = 0; + gba->video.renderer->saveState(gba->video.renderer, &buffer, &size); + if (size > 0 && buffer) { + struct mStateExtdataItem item; + item.size = size + sizeof(uint32_t); + item.data = malloc(item.size); + item.clean = free; + uint32_t type = gba->video.renderer->rendererId(gba->video.renderer); + STORE_32(type, 0, item.data); + memcpy((void*) ((uintptr_t) item.data + sizeof(uint32_t)), buffer, size); + mStateExtdataPut(extdata, EXTDATA_SUBSYSTEM_START + GBA_SUBSYSTEM_VIDEO_RENDERER, &item); + } + if (buffer) { + free(buffer); + } + return true; } diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 7842bef1f..0847e1f4a 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -13,6 +13,9 @@ static void GBAVideoProxyRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer); static void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoProxyRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoProxyRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoProxyRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); static uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); static void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -27,9 +30,13 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoProxyRendererInit; renderer->d.reset = GBAVideoProxyRendererReset; renderer->d.deinit = GBAVideoProxyRendererDeinit; + renderer->d.rendererId = GBAVideoProxyRendererId; + renderer->d.loadState = GBAVideoProxyRendererLoadState; + renderer->d.saveState = GBAVideoProxyRendererSaveState; renderer->d.writeVideoRegister = GBAVideoProxyRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoProxyRendererWriteVRAM; renderer->d.writeOAM = GBAVideoProxyRendererWriteOAM; @@ -172,6 +179,11 @@ void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) { mVideoLoggerRendererDeinit(proxyRenderer->logger); } +uint32_t GBAVideoProxyRendererId(const struct GBAVideoRenderer* renderer) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + return proxyRenderer->backend->rendererId(proxyRenderer->backend); +} + static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) { struct GBAVideoProxyRenderer* proxyRenderer = logger->context; switch (event) { @@ -189,6 +201,12 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve case LOGGER_EVENT_GET_PIXELS: proxyRenderer->backend->getPixels(proxyRenderer->backend, &logger->pixelStride, &logger->pixelBuffer); break; + case LOGGER_EVENT_LOAD_STATE: + logger->stateStatus = proxyRenderer->backend->loadState(proxyRenderer->backend, logger->stateBuffer, logger->stateSize); + break; + case LOGGER_EVENT_SAVE_STATE: + proxyRenderer->backend->saveState(proxyRenderer->backend, &logger->stateBuffer, &logger->stateSize); + break; } } @@ -279,6 +297,35 @@ uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* render return value; } +bool GBAVideoProxyRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->wait(proxyRenderer->logger); + proxyRenderer->logger->stateBuffer = (void*) state; + proxyRenderer->logger->stateSize = size; + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_LOAD_STATE); + proxyRenderer->logger->stateBuffer = NULL; + proxyRenderer->logger->stateSize = 0; + return proxyRenderer->logger->stateStatus; + } else { + return proxyRenderer->backend->loadState(proxyRenderer->backend, state, size); + } +} + +void GBAVideoProxyRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->wait(proxyRenderer->logger); + proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_SAVE_STATE); + *state = proxyRenderer->logger->stateBuffer; + *size = proxyRenderer->logger->stateSize; + proxyRenderer->logger->stateBuffer = NULL; + proxyRenderer->logger->stateSize = 0; + } else { + proxyRenderer->backend->saveState(proxyRenderer->backend, state, size); + } +} + void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; mVideoLoggerRendererWriteVRAM(proxyRenderer->logger, address); diff --git a/src/gba/renderers/gl.c b/src/gba/renderers/gl.c index afc9c54ac..24fb092c7 100644 --- a/src/gba/renderers/gl.c +++ b/src/gba/renderers/gl.c @@ -13,9 +13,14 @@ #include #include +#define OPENGL_MAGIC 0x6E726C67 + static void GBAVideoGLRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoGLRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoGLRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoGLRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); 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); @@ -656,9 +661,13 @@ static const GLint _vertices[] = { }; void GBAVideoGLRendererCreate(struct GBAVideoGLRenderer* renderer) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoGLRendererInit; renderer->d.reset = GBAVideoGLRendererReset; renderer->d.deinit = GBAVideoGLRendererDeinit; + renderer->d.rendererId = GBAVideoGLRendererId; + renderer->d.loadState = GBAVideoGLRendererLoadState; + renderer->d.saveState = GBAVideoGLRendererSaveState; renderer->d.writeVideoRegister = GBAVideoGLRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoGLRendererWriteVRAM; renderer->d.writeOAM = GBAVideoGLRendererWriteOAM; @@ -953,6 +962,26 @@ void GBAVideoGLRendererReset(struct GBAVideoRenderer* renderer) { } } +static uint32_t GBAVideoGLRendererId(const struct GBAVideoRenderer* renderer) { + UNUSED(renderer); + return OPENGL_MAGIC; +} + +static bool GBAVideoGLRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + UNUSED(renderer); + UNUSED(state); + UNUSED(size); + // TODO + return false; +} + +static void GBAVideoGLRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + UNUSED(renderer); + *state = NULL; + *size = 0; + // TODO +} + void GBAVideoGLRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) { struct GBAVideoGLRenderer* glRenderer = (struct GBAVideoGLRenderer*) renderer; if (renderer->cache) { diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 7eba88ba3..41f092937 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -14,10 +14,14 @@ #define DIRTY_SCANLINE(R, Y) R->scanlineDirty[Y >> 5] |= (1U << (Y & 0x1F)) #define CLEAN_SCANLINE(R, Y) R->scanlineDirty[Y >> 5] &= ~(1U << (Y & 0x1F)) +#define SOFTWARE_MAGIC 0x6E727773 static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer); static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer); +static uint32_t GBAVideoSoftwareRendererId(const struct GBAVideoRenderer* renderer); +static bool GBAVideoSoftwareRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size); +static void GBAVideoSoftwareRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size); static void GBAVideoSoftwareRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address); static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value); @@ -47,9 +51,13 @@ static void _breakWindow(struct GBAVideoSoftwareRenderer* softwareRenderer, stru static void _breakWindowInner(struct GBAVideoSoftwareRenderer* softwareRenderer, struct WindowN* win); void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoSoftwareRendererInit; renderer->d.reset = GBAVideoSoftwareRendererReset; renderer->d.deinit = GBAVideoSoftwareRendererDeinit; + renderer->d.rendererId = GBAVideoSoftwareRendererId; + renderer->d.loadState = GBAVideoSoftwareRendererLoadState; + renderer->d.saveState = GBAVideoSoftwareRendererSaveState; renderer->d.writeVideoRegister = GBAVideoSoftwareRendererWriteVideoRegister; renderer->d.writeVRAM = GBAVideoSoftwareRendererWriteVRAM; renderer->d.writeOAM = GBAVideoSoftwareRendererWriteOAM; @@ -79,7 +87,7 @@ void GBAVideoSoftwareRendererCreate(struct GBAVideoSoftwareRenderer* renderer) { renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->temporaryBuffer = 0; + renderer->temporaryBuffer = NULL; } static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) { @@ -155,6 +163,26 @@ static void GBAVideoSoftwareRendererDeinit(struct GBAVideoRenderer* renderer) { UNUSED(softwareRenderer); } +static uint32_t GBAVideoSoftwareRendererId(const struct GBAVideoRenderer* renderer) { + UNUSED(renderer); + return SOFTWARE_MAGIC; +} + +static bool GBAVideoSoftwareRendererLoadState(struct GBAVideoRenderer* renderer, const void* state, size_t size) { + UNUSED(renderer); + UNUSED(state); + UNUSED(size); + // TODO + return false; +} + +static void GBAVideoSoftwareRendererSaveState(struct GBAVideoRenderer* renderer, void** state, size_t* size) { + UNUSED(renderer); + *state = NULL; + *size = 0; + // TODO +} + static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; if (renderer->cache) { From 3a07834226d271ad15dd54476c0940e49e5b4ed2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 21:13:56 -0700 Subject: [PATCH 138/148] Test: Allow extdata fuzzing --- src/platform/test/fuzz-main.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/platform/test/fuzz-main.c b/src/platform/test/fuzz-main.c index af3bcf083..143edaba1 100644 --- a/src/platform/test/fuzz-main.c +++ b/src/platform/test/fuzz-main.c @@ -109,7 +109,7 @@ int main(int argc, char** argv) { } if (fuzzOpts.ssOverlay) { overlayOffset = fuzzOpts.overlayOffset; - if (overlayOffset < core->stateSize(core)) { + if (overlayOffset <= core->stateSize(core)) { savestateOverlay = VFileOpen(fuzzOpts.ssOverlay, O_RDONLY); } free(fuzzOpts.ssOverlay); @@ -137,19 +137,25 @@ int main(int argc, char** argv) { if (savestate) { if (!savestateOverlay) { - mCoreLoadStateNamed(core, savestate, 0); + mCoreLoadStateNamed(core, savestate, SAVESTATE_ALL); } else { - size_t size = core->stateSize(core); - uint8_t* state = malloc(size); - savestate->read(savestate, state, size); - savestateOverlay->read(savestateOverlay, state + overlayOffset, size - overlayOffset); - core->loadState(core, state); - free(state); + size_t size = savestate->size(savestate); + void* mapped = savestate->map(savestate, size, MAP_READ); + struct VFile* newState = VFileMemChunk(mapped, size); + savestate->unmap(savestate, mapped, size); + newState->seek(newState, overlayOffset, SEEK_SET); + uint8_t buffer[2048]; + int read; + while ((read = savestateOverlay->read(savestateOverlay, buffer, sizeof(buffer))) > 0) { + newState->write(newState, buffer, read); + } savestateOverlay->close(savestateOverlay); - savestateOverlay = 0; + savestateOverlay = NULL; + mCoreLoadStateNamed(core, newState, SAVESTATE_ALL); + newState->close(newState); } savestate->close(savestate); - savestate = 0; + savestate = NULL; } _fuzzRunloop(core, fuzzOpts.frames); From ae6cc33a5e6d2c0339d2ef586a6d186f4bc860ca Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 21:33:09 -0700 Subject: [PATCH 139/148] Core: Improve future-proofing of struct initialization --- src/core/interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/interface.c b/src/core/interface.c index e5b7f8378..10d3433ab 100644 --- a/src/core/interface.c +++ b/src/core/interface.c @@ -101,9 +101,9 @@ static bool _rtcGenericDeserialize(struct mRTCSource* source, const struct mStat } void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core) { + memset(rtc, 0, sizeof(*rtc)); rtc->p = core; rtc->override = RTC_NO_OVERRIDE; - rtc->value = 0; rtc->d.sample = _rtcGenericSample; rtc->d.unixTime = _rtcGenericCallback; rtc->d.serialize = _rtcGenericSerialize; @@ -143,10 +143,8 @@ static void mRumbleIntegratorIntegrate(struct mRumble* rumble, uint32_t period) } void mRumbleIntegratorInit(struct mRumbleIntegrator* integrator) { + memset(integrator, 0, sizeof(*integrator)); integrator->d.reset = mRumbleIntegratorReset; integrator->d.setRumble = mRumbleIntegratorSetRumble; integrator->d.integrate = mRumbleIntegratorIntegrate; - - integrator->state = false; - integrator->timeOn = 0; } From b072cb40cb073a4bb6fdf38535d457c1a66865fc Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 23:24:04 -0700 Subject: [PATCH 140/148] Core: Fix video proxy renderer creation and improve API --- include/mgba/internal/gb/renderers/proxy.h | 2 +- include/mgba/internal/gba/renderers/proxy.h | 2 +- src/gb/core.c | 16 +++++++-------- src/gb/extra/proxy.c | 16 ++++++++------- src/gba/core.c | 22 ++++++++++----------- src/gba/extra/proxy.c | 17 ++++++++-------- 6 files changed, 38 insertions(+), 37 deletions(-) diff --git a/include/mgba/internal/gb/renderers/proxy.h b/include/mgba/internal/gb/renderers/proxy.h index ca3b59f29..b7db8d00f 100644 --- a/include/mgba/internal/gb/renderers/proxy.h +++ b/include/mgba/internal/gb/renderers/proxy.h @@ -20,7 +20,7 @@ struct GBVideoProxyRenderer { enum GBModel model; }; -void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend); +void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend, struct mVideoLogger* logger); void GBVideoProxyRendererShim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer); void GBVideoProxyRendererUnshim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer); diff --git a/include/mgba/internal/gba/renderers/proxy.h b/include/mgba/internal/gba/renderers/proxy.h index c1044c77e..6cb58d092 100644 --- a/include/mgba/internal/gba/renderers/proxy.h +++ b/include/mgba/internal/gba/renderers/proxy.h @@ -19,7 +19,7 @@ struct GBAVideoProxyRenderer { struct mVideoLogger* logger; }; -void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend); +void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, struct mVideoLogger* logger); void GBAVideoProxyRendererShim(struct GBAVideo* video, struct GBAVideoProxyRenderer* renderer); void GBAVideoProxyRendererUnshim(struct GBAVideo* video, struct GBAVideoProxyRenderer* renderer); diff --git a/src/gb/core.c b/src/gb/core.c index 17a474ed1..020bf8523 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -1266,12 +1266,12 @@ static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* co gbcore->logContext = context; int channelId = mVideoLoggerAddChannel(context); - gbcore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbcore->proxyRenderer.logger, false); - mVideoLoggerAttachChannel(gbcore->proxyRenderer.logger, context, channelId); - gbcore->proxyRenderer.logger->block = false; + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, false); + mVideoLoggerAttachChannel(logger, context, channelId); + logger->block = false; - GBVideoProxyRendererCreate(&gbcore->proxyRenderer, &gbcore->renderer.d); + GBVideoProxyRendererCreate(&gbcore->proxyRenderer, &gbcore->renderer.d, logger); GBVideoProxyRendererShim(&gb->video, &gbcore->proxyRenderer); } @@ -1405,9 +1405,9 @@ static bool _GBVLPInit(struct mCore* core) { if (!_GBCoreInit(core)) { return false; } - gbcore->proxyRenderer.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbcore->proxyRenderer.logger, true); - GBVideoProxyRendererCreate(&gbcore->proxyRenderer, NULL); + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, true); + GBVideoProxyRendererCreate(&gbcore->proxyRenderer, NULL, logger); memset(&gbcore->logCallbacks, 0, sizeof(gbcore->logCallbacks)); gbcore->logCallbacks.videoFrameStarted = _GBVLPStartFrameCallback; gbcore->logCallbacks.context = core; diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index 54d46eef3..ba36c0090 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -29,7 +29,8 @@ static void GBVideoProxyRendererPutPixels(struct GBVideoRenderer* renderer, size static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); -void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend) { +void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend, struct mVideoLogger* logger) { + memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBVideoProxyRendererInit; renderer->d.deinit = GBVideoProxyRendererDeinit; renderer->d.writeVideoRegister = GBVideoProxyRendererWriteVideoRegister; @@ -57,12 +58,13 @@ void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GB renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->logger->context = renderer; - renderer->logger->parsePacket = _parsePacket; - renderer->logger->vramBlock = _vramBlock; - renderer->logger->paletteSize = 0; - renderer->logger->vramSize = GB_SIZE_VRAM; - renderer->logger->oamSize = GB_SIZE_OAM; + renderer->logger = logger; + logger->context = renderer; + logger->parsePacket = _parsePacket; + logger->vramBlock = _vramBlock; + logger->paletteSize = 0; + logger->vramSize = GB_SIZE_VRAM; + logger->oamSize = GB_SIZE_OAM; renderer->backend = backend; } diff --git a/src/gba/core.c b/src/gba/core.c index e9cf2b81c..ea6adfdf3 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -470,8 +470,7 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c #endif #ifndef MINIMAL_CORE if (renderer && core->videoLogger) { - gbacore->proxyRenderer.logger = core->videoLogger; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); + GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer, core->videoLogger); renderer = &gbacore->proxyRenderer.d; } #endif @@ -712,8 +711,7 @@ static void _GBACoreReset(struct mCore* core) { #endif #ifndef MINIMAL_CORE if (renderer && core->videoLogger) { - gbacore->proxyRenderer.logger = core->videoLogger; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); + GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer, core->videoLogger); renderer = &gbacore->proxyRenderer.d; } #endif @@ -1516,12 +1514,12 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c state->cpu.gprs[ARM_PC] = GBA_BASE_EWRAM; int channelId = mVideoLoggerAddChannel(context); - gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->vlProxy.logger, false); - mVideoLoggerAttachChannel(gbacore->vlProxy.logger, context, channelId); - gbacore->vlProxy.logger->block = false; + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, false); + mVideoLoggerAttachChannel(logger, context, channelId); + logger->block = false; - GBAVideoProxyRendererCreate(&gbacore->vlProxy, gba->video.renderer); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, gba->video.renderer, logger); GBAVideoProxyRendererShim(&gba->video, &gbacore->vlProxy); } @@ -1654,9 +1652,9 @@ static bool _GBAVLPInit(struct mCore* core) { if (!_GBACoreInit(core)) { return false; } - gbacore->vlProxy.logger = malloc(sizeof(struct mVideoLogger)); - mVideoLoggerRendererCreate(gbacore->vlProxy.logger, true); - GBAVideoProxyRendererCreate(&gbacore->vlProxy, NULL); + struct mVideoLogger* logger = malloc(sizeof(*logger)); + mVideoLoggerRendererCreate(logger, true); + GBAVideoProxyRendererCreate(&gbacore->vlProxy, NULL, logger); memset(&gbacore->logCallbacks, 0, sizeof(gbacore->logCallbacks)); gbacore->logCallbacks.videoFrameStarted = _GBAVLPStartFrameCallback; gbacore->logCallbacks.context = core; diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 0847e1f4a..ee611247b 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -29,7 +29,7 @@ static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent eve static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet); static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address); -void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend) { +void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, struct mVideoLogger* logger) { memset(renderer, 0, sizeof(*renderer)); renderer->d.init = GBAVideoProxyRendererInit; renderer->d.reset = GBAVideoProxyRendererReset; @@ -66,13 +66,14 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct renderer->d.highlightColor = M_COLOR_WHITE; renderer->d.highlightAmount = 0; - renderer->logger->context = renderer; - renderer->logger->parsePacket = _parsePacket; - renderer->logger->handleEvent = _handleEvent; - renderer->logger->vramBlock = _vramBlock; - renderer->logger->paletteSize = GBA_SIZE_PALETTE_RAM; - renderer->logger->vramSize = GBA_SIZE_VRAM; - renderer->logger->oamSize = GBA_SIZE_OAM; + renderer->logger = logger; + logger->context = renderer; + logger->parsePacket = _parsePacket; + logger->handleEvent = _handleEvent; + logger->vramBlock = _vramBlock; + logger->paletteSize = GBA_SIZE_PALETTE_RAM; + logger->vramSize = GBA_SIZE_VRAM; + logger->oamSize = GBA_SIZE_OAM; renderer->backend = backend; } From 1c85dba0df52d7329b3aaa78a84338866d833124 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 23:22:06 -0700 Subject: [PATCH 141/148] Core: Fix creating mVL contexts dropping the savestate --- src/feature/video-logger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index adcbea276..4044a4928 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -516,7 +516,7 @@ struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core) { context->initialStateSize = vf->size(vf); context->initialState = anonymousMemoryMap(context->initialStateSize); vf->seek(vf, 0, SEEK_SET); - vf->write(vf, context->initialState, context->initialStateSize); + vf->read(vf, context->initialState, context->initialStateSize); vf->close(vf); core->startVideoLog(core, context); } From a6914b2ddb865bb3e67250cd22cbdc307085284e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 6 Sep 2024 22:43:42 -0700 Subject: [PATCH 142/148] Util: Rename color_t to avoid namespace conflicts --- include/mgba-util/image.h | 12 ++--- include/mgba/core/bitmap-cache.h | 8 +-- include/mgba/core/cache-set.h | 2 +- include/mgba/core/core.h | 2 +- include/mgba/core/interface.h | 2 +- include/mgba/core/map-cache.h | 4 +- include/mgba/core/tile-cache.h | 14 +++--- include/mgba/internal/gb/renderers/software.h | 4 +- include/mgba/internal/gb/video.h | 2 +- .../internal/gba/renderers/video-software.h | 10 ++-- include/mgba/internal/gba/video.h | 2 +- src/core/bitmap-cache.c | 14 +++--- src/core/cache-set.c | 2 +- src/core/map-cache.c | 50 +++++++++---------- src/core/test/scripting.c | 2 +- src/core/tile-cache.c | 30 +++++------ src/feature/ffmpeg/ffmpeg-decoder.c | 2 +- src/feature/ffmpeg/ffmpeg-encoder.c | 4 +- src/feature/gui/gui-runner.c | 2 +- src/feature/gui/gui-runner.h | 4 +- src/gb/core.c | 2 +- src/gb/gb.c | 2 +- src/gb/renderers/software.c | 8 +-- src/gba/core.c | 2 +- src/gba/gba.c | 2 +- src/gba/renderers/software-bg.c | 2 +- src/gba/renderers/software-mode0.c | 2 +- src/gba/renderers/software-obj.c | 4 +- src/gba/renderers/software-private.h | 4 +- src/gba/renderers/video-software.c | 8 +-- src/platform/3ds/main.c | 18 +++---- src/platform/libretro/libretro.c | 4 +- src/platform/psp2/psp2-context.h | 2 +- src/platform/python/mgba/image.py | 4 +- src/platform/python/mgba/tile.py | 4 +- src/platform/qt/AssetTile.cpp | 6 +-- src/platform/qt/AssetView.cpp | 2 +- src/platform/qt/CoreController.cpp | 20 ++++---- src/platform/qt/CoreController.h | 2 +- src/platform/qt/DisplayQt.cpp | 2 +- src/platform/qt/FrameView.cpp | 2 +- src/platform/qt/ObjView.cpp | 4 +- src/platform/qt/TilePainter.cpp | 2 +- src/platform/qt/TilePainter.h | 2 +- src/platform/qt/TileView.cpp | 10 ++-- src/platform/sdl/main.h | 2 +- src/platform/switch/main.c | 4 +- src/platform/test/cinema-main.c | 2 +- 48 files changed, 150 insertions(+), 150 deletions(-) diff --git a/include/mgba-util/image.h b/include/mgba-util/image.h index 681e0a3a6..dd135a0b4 100644 --- a/include/mgba-util/image.h +++ b/include/mgba-util/image.h @@ -11,10 +11,10 @@ CXX_GUARD_START #ifdef COLOR_16_BIT -typedef uint16_t color_t; +typedef uint16_t mColor; #define BYTES_PER_PIXEL 2 #else -typedef uint32_t color_t; +typedef uint32_t mColor; #define BYTES_PER_PIXEL 4 #endif @@ -210,18 +210,18 @@ static inline bool mColorFormatHasAlpha(enum mColorFormat format) { return false; } -static inline color_t mColorFrom555(uint16_t value) { +static inline mColor mColorFrom555(uint16_t value) { #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 - color_t color = 0; + mColor color = 0; color |= (value & 0x001F) << 11; color |= (value & 0x03E0) << 1; color |= (value & 0x7C00) >> 10; #else - color_t color = value; + mColor color = value; #endif #else - color_t color = M_RGB5_TO_BGR8(value); + mColor color = M_RGB5_TO_BGR8(value); color |= (color >> 5) & 0x070707; #endif return color; diff --git a/include/mgba/core/bitmap-cache.h b/include/mgba/core/bitmap-cache.h index d8bd416e9..1529fddc2 100644 --- a/include/mgba/core/bitmap-cache.h +++ b/include/mgba/core/bitmap-cache.h @@ -29,13 +29,13 @@ struct mBitmapCacheEntry { }; struct mBitmapCache { - color_t* cache; + mColor* cache; struct mBitmapCacheEntry* status; uint32_t globalPaletteVersion; uint8_t* vram; - color_t* palette; + mColor* palette; uint32_t bitsSize; uint32_t bitsStart[2]; @@ -53,11 +53,11 @@ 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 mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, mColor 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); +const mColor* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y); CXX_GUARD_END diff --git a/include/mgba/core/cache-set.h b/include/mgba/core/cache-set.h index 5749c0e64..627a647c7 100644 --- a/include/mgba/core/cache-set.h +++ b/include/mgba/core/cache-set.h @@ -31,7 +31,7 @@ void mCacheSetDeinit(struct mCacheSet*); void mCacheSetAssignVRAM(struct mCacheSet*, void* vram); void mCacheSetWriteVRAM(struct mCacheSet*, uint32_t address); -void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, color_t color); +void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, mColor color); CXX_GUARD_END diff --git a/include/mgba/core/core.h b/include/mgba/core/core.h index 04bca4689..e8c5df7bc 100644 --- a/include/mgba/core/core.h +++ b/include/mgba/core/core.h @@ -73,7 +73,7 @@ struct mCore { unsigned (*videoScale)(const struct mCore*); size_t (*screenRegions)(const struct mCore*, const struct mCoreScreenRegion**); - void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride); + void (*setVideoBuffer)(struct mCore*, mColor* buffer, size_t stride); void (*setVideoGLTex)(struct mCore*, unsigned texid); void (*getPixels)(struct mCore*, const void** buffer, size_t* stride); diff --git a/include/mgba/core/interface.h b/include/mgba/core/interface.h index 2f4e299dd..597387753 100644 --- a/include/mgba/core/interface.h +++ b/include/mgba/core/interface.h @@ -47,7 +47,7 @@ DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks); struct mAVStream { void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height); void (*audioRateChanged)(struct mAVStream*, unsigned rate); - void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride); + void (*postVideoFrame)(struct mAVStream*, const mColor* buffer, size_t stride); void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right); void (*postAudioBuffer)(struct mAVStream*, struct mAudioBuffer*); }; diff --git a/include/mgba/core/map-cache.h b/include/mgba/core/map-cache.h index 349fc1663..29f17866c 100644 --- a/include/mgba/core/map-cache.h +++ b/include/mgba/core/map-cache.h @@ -44,7 +44,7 @@ struct mMapCacheEntry { struct mTileCache; struct mTileCacheEntry; struct mMapCache { - color_t* cache; + mColor* cache; struct mTileCache* tileCache; struct mMapCacheEntry* status; @@ -75,7 +75,7 @@ bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* en void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y); void mMapCacheCleanRow(struct mMapCache* cache, unsigned y); -const color_t* mMapCacheGetRow(struct mMapCache* cache, unsigned y); +const mColor* mMapCacheGetRow(struct mMapCache* cache, unsigned y); CXX_GUARD_END diff --git a/include/mgba/core/tile-cache.h b/include/mgba/core/tile-cache.h index f8600b3ad..24458b011 100644 --- a/include/mgba/core/tile-cache.h +++ b/include/mgba/core/tile-cache.h @@ -29,7 +29,7 @@ struct mTileCacheEntry { }; struct mTileCache { - color_t* cache; + mColor* cache; struct mTileCacheEntry* status; uint32_t* globalPaletteVersion; @@ -39,8 +39,8 @@ struct mTileCache { unsigned bpp; uint16_t* vram; - color_t* palette; - color_t temporaryTile[64]; + mColor* palette; + mColor temporaryTile[64]; mTileCacheConfiguration config; mTileCacheSystemInfo sysConfig; @@ -51,11 +51,11 @@ void mTileCacheDeinit(struct mTileCache* cache); void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config); void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config, uint32_t tileBase, uint32_t paletteBase); void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address); -void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color); +void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, mColor color); -const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId); -const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId); -const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId); +const mColor* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId); +const mColor* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId); +const mColor* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId); const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId); CXX_GUARD_END diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index c61f2270d..4ca4c1c1f 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -22,13 +22,13 @@ struct GBVideoRendererSprite { struct GBVideoSoftwareRenderer { struct GBVideoRenderer d; - color_t* outputBuffer; + mColor* outputBuffer; int outputBufferStride; // TODO: Implement the pixel FIFO uint16_t row[GB_VIDEO_HORIZONTAL_PIXELS + 8]; - color_t palette[192]; + mColor palette[192]; uint8_t lookup[192]; uint32_t* temporaryBuffer; diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index c9b179739..fc0f650ca 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -109,7 +109,7 @@ struct GBVideoRenderer { bool highlightBG; bool highlightOBJ[GB_VIDEO_MAX_OBJ]; bool highlightWIN; - color_t highlightColor; + mColor highlightColor; uint8_t highlightAmount; }; diff --git a/include/mgba/internal/gba/renderers/video-software.h b/include/mgba/internal/gba/renderers/video-software.h index d03c52374..d9a012fa8 100644 --- a/include/mgba/internal/gba/renderers/video-software.h +++ b/include/mgba/internal/gba/renderers/video-software.h @@ -82,7 +82,7 @@ struct Window { struct GBAVideoSoftwareRenderer { struct GBAVideoRenderer d; - color_t* outputBuffer; + mColor* outputBuffer; int outputBufferStride; uint32_t* temporaryBuffer; @@ -100,10 +100,10 @@ struct GBAVideoSoftwareRenderer { unsigned target2Bd; bool blendDirty; enum GBAVideoBlendEffect blendEffect; - color_t normalPalette[512]; - color_t variantPalette[512]; - color_t highlightPalette[512]; - color_t highlightVariantPalette[512]; + mColor normalPalette[512]; + mColor variantPalette[512]; + mColor highlightPalette[512]; + mColor highlightVariantPalette[512]; uint16_t blda; uint16_t bldb; diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 924772660..5fc68eb59 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -208,7 +208,7 @@ struct GBAVideoRenderer { bool highlightBG[4]; bool highlightOBJ[128]; - color_t highlightColor; + mColor highlightColor; uint8_t highlightAmount; }; diff --git a/src/core/bitmap-cache.c b/src/core/bitmap-cache.c index 6cb14eaf0..f42da90c5 100644 --- a/src/core/bitmap-cache.c +++ b/src/core/bitmap-cache.c @@ -20,7 +20,7 @@ void mBitmapCacheInit(struct mBitmapCache* cache) { static void _freeCache(struct mBitmapCache* cache) { size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); if (cache->cache) { - mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + mappedMemoryFree(cache->cache, mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(mColor)); cache->cache = NULL; } if (cache->status) { @@ -39,10 +39,10 @@ static void _redoCacheSize(struct mBitmapCache* cache) { } size_t size = mBitmapCacheSystemInfoGetHeight(cache->sysConfig) * mBitmapCacheSystemInfoGetBuffers(cache->sysConfig); - cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(color_t)); + cache->cache = anonymousMemoryMap(mBitmapCacheSystemInfoGetWidth(cache->sysConfig) * size * sizeof(mColor)); cache->status = anonymousMemoryMap(size * sizeof(*cache->status)); if (mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { - cache->palette = calloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))), sizeof(color_t)); + cache->palette = calloc((1 << (1 << mBitmapCacheSystemInfoGetEntryBPP(cache->sysConfig))), sizeof(mColor)); } else { cache->palette = NULL; } @@ -101,7 +101,7 @@ void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address) { } } -void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color) { +void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, mColor color) { if (!mBitmapCacheSystemInfoIsUsesPalette(cache->sysConfig)) { return; } @@ -122,7 +122,7 @@ uint32_t _lookupEntry15(void* vram, uint32_t 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)]; + mColor* 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 = { @@ -181,7 +181,7 @@ bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheE 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)]; +const mColor* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y) { + mColor* row = &cache->cache[(cache->buffer * mBitmapCacheSystemInfoGetHeight(cache->sysConfig) + y) * mBitmapCacheSystemInfoGetWidth(cache->sysConfig)]; return row; } diff --git a/src/core/cache-set.c b/src/core/cache-set.c index 04d42a233..098844bd9 100644 --- a/src/core/cache-set.c +++ b/src/core/cache-set.c @@ -72,7 +72,7 @@ void mCacheSetWriteVRAM(struct mCacheSet* cache, uint32_t address) { } } -void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, color_t color) { +void mCacheSetWritePalette(struct mCacheSet* cache, uint32_t entry, mColor color) { size_t i; for (i = 0; i < mBitmapCacheSetSize(&cache->bitmaps); ++i) { mBitmapCacheWritePalette(mBitmapCacheSetGetPointer(&cache->bitmaps, i), entry, color); diff --git a/src/core/map-cache.c b/src/core/map-cache.c index d51800780..5668d82f3 100644 --- a/src/core/map-cache.c +++ b/src/core/map-cache.c @@ -18,7 +18,7 @@ void mMapCacheInit(struct mMapCache* cache) { static void _freeCache(struct mMapCache* cache) { size_t tiles = (1 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig)) * (1 << mMapCacheSystemInfoGetTilesHigh(cache->sysConfig)); if (cache->cache) { - mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles); + mappedMemoryFree(cache->cache, 8 * 8 * sizeof(mColor) * tiles); cache->cache = NULL; } if (cache->status) { @@ -33,7 +33,7 @@ static void _redoCacheSize(struct mMapCache* cache) { } size_t tiles = mMapCacheTileCount(cache); - cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles); + cache->cache = anonymousMemoryMap(8 * 8 * sizeof(mColor) * tiles); cache->status = anonymousMemoryMap(tiles * sizeof(*cache->status)); } @@ -87,19 +87,19 @@ void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address) { } } -static inline void _cleanTile(struct mMapCache* cache, const color_t* tile, color_t* mapOut, const struct mMapCacheEntry* status) { +static inline void _cleanTile(struct mMapCache* cache, const mColor* tile, mColor* mapOut, const struct mMapCacheEntry* status) { size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); int x, y; switch (mMapCacheEntryFlagsGetMirror(status->flags)) { case 0: - memcpy(mapOut, tile, sizeof(color_t) * 8); - memcpy(&mapOut[stride], &tile[0x08], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 2], &tile[0x10], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 3], &tile[0x18], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 4], &tile[0x20], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 5], &tile[0x28], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 6], &tile[0x30], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 7], &tile[0x38], sizeof(color_t) * 8); + memcpy(mapOut, tile, sizeof(mColor) * 8); + memcpy(&mapOut[stride], &tile[0x08], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 2], &tile[0x10], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 3], &tile[0x18], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 4], &tile[0x20], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 5], &tile[0x28], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 6], &tile[0x30], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 7], &tile[0x38], sizeof(mColor) * 8); break; case 1: for (y = 0; y < 8; ++y) { @@ -109,14 +109,14 @@ static inline void _cleanTile(struct mMapCache* cache, const color_t* tile, colo } break; case 2: - memcpy(&mapOut[stride * 7], tile, sizeof(color_t) * 8); - memcpy(&mapOut[stride * 6], &tile[0x08], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 5], &tile[0x10], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 4], &tile[0x18], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 3], &tile[0x20], sizeof(color_t) * 8); - memcpy(&mapOut[stride * 2], &tile[0x28], sizeof(color_t) * 8); - memcpy(&mapOut[stride], &tile[0x30], sizeof(color_t) * 8); - memcpy(mapOut, &tile[0x38], sizeof(color_t) * 8); + memcpy(&mapOut[stride * 7], tile, sizeof(mColor) * 8); + memcpy(&mapOut[stride * 6], &tile[0x08], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 5], &tile[0x10], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 4], &tile[0x18], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 3], &tile[0x20], sizeof(mColor) * 8); + memcpy(&mapOut[stride * 2], &tile[0x28], sizeof(mColor) * 8); + memcpy(&mapOut[stride], &tile[0x30], sizeof(mColor) * 8); + memcpy(mapOut, &tile[0x38], sizeof(mColor) * 8); break; case 3: for (y = 0; y < 8; ++y) { @@ -146,7 +146,7 @@ uint32_t mMapCacheTileId(struct mMapCache* cache, unsigned x, unsigned y) { void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y) { size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; - const color_t* tile = NULL; + const mColor* tile = NULL; if (!mMapCacheEntryFlagsIsVramClean(status->flags)) { status->flags = mMapCacheEntryFlagsFillVramClean(status->flags); cache->mapParser(cache, status, &cache->vram[cache->mapStart + (location << mMapCacheSystemInfoGetMapAlign(cache->sysConfig))]); @@ -164,7 +164,7 @@ void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, u } size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); - color_t* mapOut = &cache->cache[(y * stride + x) * 8]; + mColor* mapOut = &cache->cache[(y * stride + x) * 8]; _cleanTile(cache, tile, mapOut, status); entry[location] = *status; } @@ -173,7 +173,7 @@ bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* en size_t location = mMapCacheTileId(cache, x, y); struct mMapCacheEntry* status = &cache->status[location]; int paletteId = mMapCacheEntryFlagsGetPaletteId(status->flags); - const color_t* tile = NULL; + const mColor* tile = NULL; if (mMapCacheEntryFlagsIsVramClean(status->flags) && memcmp(status, &entry[location], sizeof(*entry)) == 0) { unsigned tileId = status->tileId + cache->tileStart; if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { @@ -207,13 +207,13 @@ void mMapCacheCleanRow(struct mMapCache* cache, unsigned y) { if (tileId >= mTileCacheSystemInfoGetMaxTiles(cache->tileCache->sysConfig)) { tileId = 0; } - const color_t* tile = mTileCacheGetTile(cache->tileCache, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); - color_t* mapOut = &cache->cache[(y * stride + x) * 8]; + const mColor* tile = mTileCacheGetTile(cache->tileCache, tileId, mMapCacheEntryFlagsGetPaletteId(status->flags)); + mColor* mapOut = &cache->cache[(y * stride + x) * 8]; _cleanTile(cache, tile, mapOut, status); } } -const color_t* mMapCacheGetRow(struct mMapCache* cache, unsigned y) { +const mColor* mMapCacheGetRow(struct mMapCache* cache, unsigned y) { size_t stride = 8 << mMapCacheSystemInfoGetTilesWide(cache->sysConfig); return &cache->cache[y * stride]; } diff --git a/src/core/test/scripting.c b/src/core/test/scripting.c index e66f2a722..63927effe 100644 --- a/src/core/test/scripting.c +++ b/src/core/test/scripting.c @@ -312,7 +312,7 @@ M_TEST_DEFINE(logging) { M_TEST_DEFINE(screenshot) { SETUP_LUA; CREATE_CORE; - color_t* buffer = malloc(240 * 160 * sizeof(color_t)); + mColor* buffer = malloc(240 * 160 * sizeof(mColor)); core->setVideoBuffer(core, buffer, 240); core->reset(core); core->runFrame(core); diff --git a/src/core/tile-cache.c b/src/core/tile-cache.c index d9f68066c..26ea86416 100644 --- a/src/core/tile-cache.c +++ b/src/core/tile-cache.c @@ -20,7 +20,7 @@ static void _freeCache(struct mTileCache* cache) { unsigned size = 1 << mTileCacheSystemInfoGetPaletteCount(cache->sysConfig); unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); if (cache->cache) { - mappedMemoryFree(cache->cache, 8 * 8 * sizeof(color_t) * tiles * size); + mappedMemoryFree(cache->cache, 8 * 8 * sizeof(mColor) * tiles * size); cache->cache = NULL; } if (cache->status) { @@ -44,7 +44,7 @@ static void _redoCacheSize(struct mTileCache* cache) { size = 1 << size; cache->entriesPerTile = size; unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); - cache->cache = anonymousMemoryMap(8 * 8 * sizeof(color_t) * tiles * size); + cache->cache = anonymousMemoryMap(8 * 8 * sizeof(mColor) * tiles * size); cache->status = anonymousMemoryMap(tiles * size * sizeof(*cache->status)); cache->globalPaletteVersion = calloc(size, sizeof(*cache->globalPaletteVersion)); cache->palette = calloc(size * bpp, sizeof(*cache->palette)); @@ -89,7 +89,7 @@ void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address) { } } -void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color) { +void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, mColor color) { if (entry < cache->paletteBase) { return; } @@ -103,10 +103,10 @@ void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t co ++cache->globalPaletteVersion[entry]; } -static void _regenerateTile4(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile4(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint8_t* start = (uint8_t*) &cache->vram[tileId << 3]; paletteId <<= 2; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint8_t tileDataLower = start[0]; @@ -133,10 +133,10 @@ static void _regenerateTile4(struct mTileCache* cache, color_t* tile, unsigned t } } -static void _regenerateTile16(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile16(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 4]; paletteId <<= 4; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint32_t line = *start; @@ -162,10 +162,10 @@ static void _regenerateTile16(struct mTileCache* cache, color_t* tile, unsigned } } -static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned tileId, unsigned paletteId) { +static void _regenerateTile256(struct mTileCache* cache, mColor* tile, unsigned tileId, unsigned paletteId) { uint32_t* start = (uint32_t*) &cache->vram[tileId << 5]; paletteId <<= 8; - color_t* palette = &cache->palette[paletteId]; + mColor* palette = &cache->palette[paletteId]; int i; for (i = 0; i < 8; ++i) { uint32_t line = *start; @@ -194,7 +194,7 @@ static void _regenerateTile256(struct mTileCache* cache, color_t* tile, unsigned } } -static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { +static inline mColor* _tileLookup(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { if (mTileCacheConfigurationIsShouldStore(cache->config)) { unsigned tiles = mTileCacheSystemInfoGetMaxTiles(cache->sysConfig); mASSERT(tileId < tiles); @@ -205,7 +205,7 @@ static inline color_t* _tileLookup(struct mTileCache* cache, unsigned tileId, un } } -const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { +const mColor* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId) { unsigned count = cache->entriesPerTile; unsigned bpp = cache->bpp; struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId]; @@ -215,7 +215,7 @@ const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsi .vramClean = 1, .paletteId = paletteId }; - color_t* tile = _tileLookup(cache, tileId, paletteId); + mColor* tile = _tileLookup(cache, tileId, paletteId); if (!mTileCacheConfigurationIsShouldStore(cache->config) || memcmp(status, &desiredStatus, sizeof(*status))) { switch (bpp) { case 0: @@ -235,7 +235,7 @@ const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsi return tile; } -const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) { +const mColor* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId) { unsigned count = cache->entriesPerTile; unsigned bpp = cache->bpp; struct mTileCacheEntry* status = &cache->status[tileId * count + paletteId]; @@ -245,7 +245,7 @@ const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCa .vramClean = 1, .paletteId = paletteId }; - color_t* tile = NULL; + mColor* tile = NULL; if (memcmp(status, &desiredStatus, sizeof(*status))) { tile = _tileLookup(cache, tileId, paletteId); switch (bpp) { @@ -270,7 +270,7 @@ const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCa return tile; } -const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) { +const mColor* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId) { return &cache->palette[paletteId << (1 << cache->bpp)]; } diff --git a/src/feature/ffmpeg/ffmpeg-decoder.c b/src/feature/ffmpeg/ffmpeg-decoder.c index daa47fbf2..09539ca61 100644 --- a/src/feature/ffmpeg/ffmpeg-decoder.c +++ b/src/feature/ffmpeg/ffmpeg-decoder.c @@ -190,7 +190,7 @@ bool FFmpegDecoderRead(struct FFmpegDecoder* decoder) { } int stride = decoder->width * BYTES_PER_PIXEL; sws_scale(decoder->scaleContext, (const uint8_t* const*) decoder->videoFrame->data, decoder->videoFrame->linesize, 0, decoder->videoFrame->height, &decoder->pixels, &stride); - decoder->out->postVideoFrame(decoder->out, (const color_t*) decoder->pixels, decoder->width); + decoder->out->postVideoFrame(decoder->out, (const mColor*) decoder->pixels, decoder->width); } } } diff --git a/src/feature/ffmpeg/ffmpeg-encoder.c b/src/feature/ffmpeg/ffmpeg-encoder.c index 220ce4d86..5ee54a5e8 100644 --- a/src/feature/ffmpeg/ffmpeg-encoder.c +++ b/src/feature/ffmpeg/ffmpeg-encoder.c @@ -34,7 +34,7 @@ #endif #include -static void _ffmpegPostVideoFrame(struct mAVStream*, const color_t* pixels, size_t stride); +static void _ffmpegPostVideoFrame(struct mAVStream*, const mColor* pixels, size_t stride); static void _ffmpegPostAudioFrame(struct mAVStream*, int16_t left, int16_t right); static void _ffmpegSetVideoDimensions(struct mAVStream*, unsigned width, unsigned height); static void _ffmpegSetAudioRate(struct mAVStream*, unsigned rate); @@ -784,7 +784,7 @@ bool _ffmpegWriteAudioFrame(struct FFmpegEncoder* encoder, struct AVFrame* audio return gotData; } -void _ffmpegPostVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) { +void _ffmpegPostVideoFrame(struct mAVStream* stream, const mColor* pixels, size_t stride) { struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream; if (!encoder->context || !encoder->videoCodec) { return; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index b3ce21ad9..035522f02 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -123,7 +123,7 @@ static void _drawState(struct GUIBackground* background, void* id) { struct mGUIBackground* gbaBackground = (struct mGUIBackground*) background; unsigned stateId = ((uint32_t) id) >> 16; if (gbaBackground->p->drawScreenshot) { - color_t* pixels = gbaBackground->image; + mColor* pixels = gbaBackground->image; if (pixels && gbaBackground->screenshotId == (stateId | SCREENSHOT_VALID)) { gbaBackground->p->drawScreenshot(gbaBackground->p, pixels, gbaBackground->w, gbaBackground->h, true); return; diff --git a/src/feature/gui/gui-runner.h b/src/feature/gui/gui-runner.h index 334ef57d9..e65ced52f 100644 --- a/src/feature/gui/gui-runner.h +++ b/src/feature/gui/gui-runner.h @@ -31,7 +31,7 @@ struct mGUIBackground { struct GUIBackground d; struct mGUIRunner* p; - color_t* image; + mColor* image; size_t imageSize; uint16_t w; uint16_t h; @@ -86,7 +86,7 @@ struct mGUIRunner { void (*gameUnloaded)(struct mGUIRunner*); void (*prepareForFrame)(struct mGUIRunner*); void (*drawFrame)(struct mGUIRunner*, bool faded); - void (*drawScreenshot)(struct mGUIRunner*, const color_t* pixels, unsigned width, unsigned height, bool faded); + void (*drawScreenshot)(struct mGUIRunner*, const mColor* pixels, unsigned width, unsigned height, bool faded); void (*paused)(struct mGUIRunner*); void (*unpaused)(struct mGUIRunner*); void (*incrementScreenMode)(struct mGUIRunner*); diff --git a/src/gb/core.c b/src/gb/core.c index 020bf8523..2bfea28ef 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -407,7 +407,7 @@ static size_t _GBCoreScreenRegions(const struct mCore* core, const struct mCoreS } } -static void _GBCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { +static void _GBCoreSetVideoBuffer(struct mCore* core, mColor* buffer, size_t stride) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->renderer.outputBuffer = buffer; gbcore->renderer.outputBufferStride = stride; diff --git a/src/gb/gb.c b/src/gb/gb.c index 282fc45c1..67dea55b8 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -1173,7 +1173,7 @@ void GBFrameEnded(struct GB* gb) { // TODO: Move to common code if (gb->stream && gb->stream->postVideoFrame) { - const color_t* pixels; + const mColor* pixels; size_t stride; gb->video.renderer->getPixels(gb->video.renderer, &stride, (const void**) &pixels); gb->stream->postVideoFrame(gb->stream, pixels, stride); diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index d157920fa..76a0c55da 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -44,7 +44,7 @@ static void _clearScreen(struct GBVideoSoftwareRenderer* renderer) { } int y; for (y = 0; y < GB_VIDEO_VERTICAL_PIXELS; ++y) { - color_t* row = &renderer->outputBuffer[renderer->outputBufferStride * y + sgbOffset]; + mColor* row = &renderer->outputBuffer[renderer->outputBufferStride * y + sgbOffset]; int x; for (x = 0; x < GB_VIDEO_HORIZONTAL_PIXELS; x += 4) { row[x + 0] = renderer->palette[0]; @@ -492,7 +492,7 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; - color_t color = mColorFrom555(value); + mColor color = mColorFrom555(value); if (softwareRenderer->model & GB_MODEL_SGB) { if (index >= PAL_SGB_BORDER && !(index & 0xF)) { color = softwareRenderer->palette[0]; @@ -668,7 +668,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i if (softwareRenderer->model & GB_MODEL_SGB && softwareRenderer->sgbBorders) { sgbOffset = softwareRenderer->outputBufferStride * 40 + 48; } - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y + sgbOffset]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y + sgbOffset]; int x = startX; int p = 0; switch (softwareRenderer->d.sgbRenderMode) { @@ -1161,7 +1161,7 @@ static void GBVideoSoftwareRendererPutPixels(struct GBVideoRenderer* renderer, s struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; // TODO: Share with GBAVideoSoftwareRendererGetPixels - const color_t* colorPixels = pixels; + const mColor* colorPixels = pixels; unsigned i; for (i = 0; i < GB_VIDEO_VERTICAL_PIXELS; ++i) { memmove(&softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * i], &colorPixels[stride * i], GB_VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); diff --git a/src/gba/core.c b/src/gba/core.c index ea6adfdf3..a6939406e 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -525,7 +525,7 @@ static size_t _GBACoreScreenRegions(const struct mCore* core, const struct mCore return 1; } -static void _GBACoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) { +static void _GBACoreSetVideoBuffer(struct mCore* core, mColor* buffer, size_t stride) { struct GBACore* gbacore = (struct GBACore*) core; gbacore->renderer.outputBuffer = buffer; gbacore->renderer.outputBufferStride = stride; diff --git a/src/gba/gba.c b/src/gba/gba.c index ce7e3478e..aab2cd3ec 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -980,7 +980,7 @@ void GBAFrameEnded(struct GBA* gba) { } if (gba->stream && gba->stream->postVideoFrame) { - const color_t* pixels; + const mColor* pixels; size_t stride; gba->video.renderer->getPixels(gba->video.renderer, &stride, (const void**) &pixels); gba->stream->postVideoFrame(gba->stream, pixels, stride); diff --git a/src/gba/renderers/software-bg.c b/src/gba/renderers/software-bg.c index 7d50b5088..6fa199b0d 100644 --- a/src/gba/renderers/software-bg.c +++ b/src/gba/renderers/software-bg.c @@ -173,7 +173,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode4(struct GBAVideoSoftwareRenderer if (!objwinSlowPath) { _compositeBlendNoObjwin(renderer, pixel, palette[color] | flags, current); } else if (background->objwinForceEnable || (!(current & FLAG_OBJWIN)) == background->objwinOnly) { - color_t* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; + mColor* currentPalette = (current & FLAG_OBJWIN) ? objwinPalette : palette; unsigned mergedFlags = flags; if (current & FLAG_OBJWIN) { mergedFlags = objwinFlags; diff --git a/src/gba/renderers/software-mode0.c b/src/gba/renderers/software-mode0.c index aa1d63924..4aada17b0 100644 --- a/src/gba/renderers/software-mode0.c +++ b/src/gba/renderers/software-mode0.c @@ -512,7 +512,7 @@ void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer uint32_t screenBase; uint32_t charBase; - color_t* palette = renderer->normalPalette; + mColor* palette = renderer->normalPalette; if (renderer->d.highlightAmount && background->highlight) { palette = renderer->highlightPalette; } diff --git a/src/gba/renderers/software-obj.c b/src/gba/renderers/software-obj.c index 3b44d86a5..4152685c6 100644 --- a/src/gba/renderers/software-obj.c +++ b/src/gba/renderers/software-obj.c @@ -182,11 +182,11 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re } } - color_t* palette = &renderer->normalPalette[0x100]; + mColor* palette = &renderer->normalPalette[0x100]; if (renderer->d.highlightAmount && renderer->d.highlightOBJ[index]) { palette = &renderer->highlightPalette[0x100]; } - color_t* objwinPalette = palette; + mColor* objwinPalette = palette; if (variant) { palette = &renderer->variantPalette[0x100]; diff --git a/src/gba/renderers/software-private.h b/src/gba/renderers/software-private.h index 8a195534b..4f7e9f8d6 100644 --- a/src/gba/renderers/software-private.h +++ b/src/gba/renderers/software-private.h @@ -155,7 +155,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re // TODO: Remove UNUSEDs after implementing OBJWIN for modes 3 - 5 #define PREPARE_OBJWIN \ int objwinSlowPath = GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt); \ - color_t* objwinPalette = renderer->normalPalette; \ + mColor* objwinPalette = renderer->normalPalette; \ if (renderer->d.highlightAmount && background->highlight) { \ objwinPalette = renderer->highlightPalette; \ } \ @@ -194,7 +194,7 @@ static inline void _compositeNoBlendNoObjwin(struct GBAVideoSoftwareRenderer* re uint32_t flags = background->flags; \ uint32_t objwinFlags = background->objwinFlags; \ bool variant = background->variant; \ - color_t* palette = renderer->normalPalette; \ + mColor* palette = renderer->normalPalette; \ if (renderer->d.highlightAmount && background->highlight) { \ palette = renderer->highlightPalette; \ } \ diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c index 41f092937..83550bcfa 100644 --- a/src/gba/renderers/video-software.c +++ b/src/gba/renderers/video-software.c @@ -97,7 +97,7 @@ static void GBAVideoSoftwareRendererInit(struct GBAVideoRenderer* renderer) { int y; for (y = 0; y < GBA_VIDEO_VERTICAL_PIXELS; ++y) { - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { row[x] = M_COLOR_WHITE; @@ -422,7 +422,7 @@ static void GBAVideoSoftwareRendererWriteOAM(struct GBAVideoRenderer* renderer, static void GBAVideoSoftwareRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; - color_t color = mColorFrom555(value); + mColor color = mColorFrom555(value); softwareRenderer->normalPalette[address >> 1] = color; if (softwareRenderer->blendEffect == BLEND_BRIGHTEN) { softwareRenderer->variantPalette[address >> 1] = _brighten(color, softwareRenderer->bldy); @@ -610,7 +610,7 @@ static void GBAVideoSoftwareRendererDrawScanline(struct GBAVideoRenderer* render CLEAN_SCANLINE(softwareRenderer, y); - color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; + mColor* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y]; if (GBARegisterDISPCNTIsForcedBlank(softwareRenderer->dispcnt)) { int x; for (x = 0; x < GBA_VIDEO_HORIZONTAL_PIXELS; ++x) { @@ -781,7 +781,7 @@ static void GBAVideoSoftwareRendererGetPixels(struct GBAVideoRenderer* renderer, static void GBAVideoSoftwareRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) { struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer; - const color_t* colorPixels = pixels; + const mColor* colorPixels = pixels; unsigned i; 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/platform/3ds/main.c b/src/platform/3ds/main.c index de6575eff..2d7f80d15 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -85,8 +85,8 @@ static enum { } hasSound; // TODO: Move into context -static color_t* outputBuffer = NULL; -static color_t* screenshotBuffer = NULL; +static mColor* outputBuffer = NULL; +static mColor* screenshotBuffer = NULL; static struct mAVStream stream; static int16_t* audioLeft = 0; static size_t audioPos = 0; @@ -293,7 +293,7 @@ static void _setup(struct mGUIRunner* runner) { _map3DSKey(&runner->core->inputMap, KEY_L, GBA_KEY_L); _map3DSKey(&runner->core->inputMap, KEY_R, GBA_KEY_R); - memset(outputBuffer, 0, 256 * 224 * sizeof(color_t)); + memset(outputBuffer, 0, 256 * 224 * sizeof(mColor)); runner->core->setVideoBuffer(runner->core, outputBuffer, 256); unsigned mode; @@ -615,19 +615,19 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { _drawTex(runner->core, faded, interframeBlending); } -static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { +static void _drawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded) { C3D_Tex* tex = &outputTexture[activeOutputTexture]; if (!screenshotBuffer) { - screenshotBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); + screenshotBuffer = linearMemAlign(256 * 224 * sizeof(mColor), 0x80); } unsigned y; for (y = 0; y < height; ++y) { - memcpy(&screenshotBuffer[y * 256], &pixels[y * width], width * sizeof(color_t)); - memset(&screenshotBuffer[y * 256 + width], 0, (256 - width) * sizeof(color_t)); + memcpy(&screenshotBuffer[y * 256], &pixels[y * width], width * sizeof(mColor)); + memset(&screenshotBuffer[y * 256 + width], 0, (256 - width) * sizeof(mColor)); } - GSPGPU_FlushDataCache(screenshotBuffer, 256 * height * sizeof(color_t)); + GSPGPU_FlushDataCache(screenshotBuffer, 256 * height * sizeof(mColor)); C3D_SyncDisplayTransfer( (u32*) screenshotBuffer, GX_BUFFER_DIM(256, height), tex->data, GX_BUFFER_DIM(256, 256), @@ -917,7 +917,7 @@ int main(int argc, char* argv[]) { _cleanup(); return 1; } - outputBuffer = linearMemAlign(256 * 224 * sizeof(color_t), 0x80); + outputBuffer = linearMemAlign(256 * 224 * sizeof(mColor), 0x80); struct mGUIRunner runner = { .params = { diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 88743b63e..232c4e6eb 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -37,7 +37,7 @@ #define VIDEO_WIDTH_MAX 256 #define VIDEO_HEIGHT_MAX 224 -#define VIDEO_BUFF_SIZE (VIDEO_WIDTH_MAX * VIDEO_HEIGHT_MAX * sizeof(color_t)) +#define VIDEO_BUFF_SIZE (VIDEO_WIDTH_MAX * VIDEO_HEIGHT_MAX * sizeof(mColor)) static retro_environment_t environCallback; static retro_video_refresh_t videoCallback; @@ -66,7 +66,7 @@ static int32_t _readTiltY(struct mRotationSource* source); static int32_t _readGyroZ(struct mRotationSource* source); static struct mCore* core; -static color_t* outputBuffer = NULL; +static mColor* outputBuffer = NULL; static int16_t *audioSampleBuffer = NULL; static size_t audioSampleBufferSize; static float audioSamplesPerFrameAvg; diff --git a/src/platform/psp2/psp2-context.h b/src/platform/psp2/psp2-context.h index 2c9a47e09..316dbd434 100644 --- a/src/platform/psp2/psp2-context.h +++ b/src/platform/psp2/psp2-context.h @@ -22,7 +22,7 @@ void mPSP2Paused(struct mGUIRunner* runner); void mPSP2Unpaused(struct mGUIRunner* runner); void mPSP2Swap(struct mGUIRunner* runner); void mPSP2Draw(struct mGUIRunner* runner, bool faded); -void mPSP2DrawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded); +void mPSP2DrawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded); void mPSP2IncrementScreenMode(struct mGUIRunner* runner); void mPSP2SetFrameLimiter(struct mGUIRunner* runner, bool limit); uint16_t mPSP2PollInput(struct mGUIRunner* runner); diff --git a/src/platform/python/mgba/image.py b/src/platform/python/mgba/image.py index 3b6679524..a67801021 100644 --- a/src/platform/python/mgba/image.py +++ b/src/platform/python/mgba/image.py @@ -23,7 +23,7 @@ class Image: def constitute(self): if self.stride <= 0: self.stride = self.width - self.buffer = ffi.new("color_t[{}]".format(self.stride * self.height)) + self.buffer = ffi.new("mColor[{}]".format(self.stride * self.height)) def save_png(self, fileobj): png_file = png.PNG(fileobj, mode=png.MODE_RGBA if self.alpha else png.MODE_RGB) @@ -65,7 +65,7 @@ def u32_to_u16(color): return abgr -if ffi.sizeof("color_t") == 2: +if ffi.sizeof("mColor") == 2: def color_to_u16(color): return color diff --git a/src/platform/python/mgba/tile.py b/src/platform/python/mgba/tile.py index 48812930c..5a9e5d713 100644 --- a/src/platform/python/mgba/tile.py +++ b/src/platform/python/mgba/tile.py @@ -18,7 +18,7 @@ class Tile: def composite(self, i, x, y): for iy in range(8): - ffi.memmove(ffi.addressof(i.buffer, x + (iy + y) * i.stride), ffi.addressof(self.buffer, iy * 8), 8 * ffi.sizeof("color_t")) + ffi.memmove(ffi.addressof(i.buffer, x + (iy + y) * i.stride), ffi.addressof(self.buffer, iy * 8), 8 * ffi.sizeof("mColor")) class CacheSet: @@ -55,7 +55,7 @@ class MapView: if not y & 7: lib.mMapCacheCleanRow(self.cache, y >> 3) row = lib.mMapCacheGetRow(self.cache, y) - ffi.memmove(ffi.addressof(i.buffer, i.stride * y), row, self.width * 8 * ffi.sizeof("color_t")) + ffi.memmove(ffi.addressof(i.buffer, i.stride * y), row, self.width * 8 * ffi.sizeof("mColor")) return i diff --git a/src/platform/qt/AssetTile.cpp b/src/platform/qt/AssetTile.cpp index 78db4ccd9..2661c9fde 100644 --- a/src/platform/qt/AssetTile.cpp +++ b/src/platform/qt/AssetTile.cpp @@ -86,7 +86,7 @@ void AssetTile::selectIndex(int index) { return; } m_index = index; - const color_t* data; + const mColor* data; mTileCache* tileCache = m_tileCaches[index >= m_boundary]; unsigned bpp = 8 << tileCache->bpp; @@ -130,10 +130,10 @@ void AssetTile::setFlip(bool h, bool v) { } void AssetTile::selectColor(int index) { - const color_t* data; + const mColor* data; mTileCache* tileCache = m_tileCaches[m_index >= m_boundary]; data = mTileCacheGetTile(tileCache, m_index >= m_boundary ? m_index - m_boundary : m_index, m_paletteId); - color_t color = data[index]; + mColor color = data[index]; m_ui.color->setColor(0, color); m_ui.color->update(); diff --git a/src/platform/qt/AssetView.cpp b/src/platform/qt/AssetView.cpp index c648982c6..17b745100 100644 --- a/src/platform/qt/AssetView.cpp +++ b/src/platform/qt/AssetView.cpp @@ -135,7 +135,7 @@ QImage AssetView::compositeMap(int map, QVector* mapStatus) { QImage AssetView::compositeObj(const ObjInfo& objInfo) { mTileCache* tileCache = mTileCacheSetGetPointer(&m_cacheSet->tiles, objInfo.paletteSet); unsigned maxTiles = mTileCacheSystemInfoGetMaxTiles(tileCache->sysConfig); - const color_t* rawPalette = mTileCacheGetPalette(tileCache, objInfo.paletteId); + const mColor* rawPalette = mTileCacheGetPalette(tileCache, objInfo.paletteId); unsigned colors = 1 << objInfo.bits; QVector palette; diff --git a/src/platform/qt/CoreController.cpp b/src/platform/qt/CoreController.cpp index 519ce45fb..08b96bd81 100644 --- a/src/platform/qt/CoreController.cpp +++ b/src/platform/qt/CoreController.cpp @@ -97,7 +97,7 @@ CoreController::CoreController(mCore* core, QObject* parent) controller->m_frameCounter = -1; if (!controller->m_hwaccel) { - 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()); } QString message(tr("Reset r%1-%2 %3").arg(gitRevision).arg(QLatin1String(gitCommitShort)).arg(controller->m_crc32, 8, 16, QLatin1Char('0'))); @@ -236,12 +236,12 @@ void CoreController::setPath(const QString& path, const QString& base) { m_baseDirectory = base; } -const color_t* CoreController::drawContext() { +const mColor* CoreController::drawContext() { if (m_hwaccel) { return nullptr; } QMutexLocker locker(&m_bufferMutex); - return reinterpret_cast(m_completeBuffer.constData()); + return reinterpret_cast(m_completeBuffer.constData()); } QImage CoreController::getPixels() { @@ -307,14 +307,14 @@ void CoreController::loadConfig(ConfigController* config) { m_preload = config->getOption("preload").toInt(); QSize sizeBefore = screenDimensions(); - m_activeBuffer.resize(256 * 224 * sizeof(color_t)); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeBefore.width()); + m_activeBuffer.resize(256 * 224 * sizeof(mColor)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeBefore.width()); mCoreLoadForeignConfig(m_threadContext.core, config->config()); QSize sizeAfter = screenDimensions(); - m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(color_t)); - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); + m_activeBuffer.resize(sizeAfter.width() * sizeAfter.height() * sizeof(mColor)); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), sizeAfter.width()); if (hasStarted()) { updateFastForward(); @@ -461,11 +461,11 @@ void CoreController::setLogger(LogController* logger) { void CoreController::start() { QSize size(screenDimensions()); - m_activeBuffer.resize(size.width() * size.height() * sizeof(color_t)); + m_activeBuffer.resize(size.width() * size.height() * sizeof(mColor)); 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) { mCoreAutoloadPatch(m_threadContext.core); @@ -1194,7 +1194,7 @@ void CoreController::setFramebufferHandle(int fb) { if (hasStarted()) { m_threadContext.core->reloadConfigOption(m_threadContext.core, "hwaccelVideo", NULL); if (!m_hwaccel) { - m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), screenDimensions().width()); + m_threadContext.core->setVideoBuffer(m_threadContext.core, reinterpret_cast(m_activeBuffer.data()), screenDimensions().width()); } } } diff --git a/src/platform/qt/CoreController.h b/src/platform/qt/CoreController.h index 684d864d0..57eb9ffe0 100644 --- a/src/platform/qt/CoreController.h +++ b/src/platform/qt/CoreController.h @@ -87,7 +87,7 @@ public: QString baseDirectory() const { return m_baseDirectory; } QString savePath() const { return m_savePath; } - const color_t* drawContext(); + const mColor* drawContext(); QImage getPixels(); bool isPaused(); diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 3723a8445..b71147c43 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -78,7 +78,7 @@ void DisplayQt::filter(bool filter) { void DisplayQt::framePosted() { update(); - const color_t* buffer = m_context->drawContext(); + const mColor* buffer = m_context->drawContext(); if (const_cast(m_layers[VIDEO_LAYER_IMAGE]).bits() == reinterpret_cast(buffer)) { return; } diff --git a/src/platform/qt/FrameView.cpp b/src/platform/qt/FrameView.cpp index ada077d74..245ebf4bb 100644 --- a/src/platform/qt/FrameView.cpp +++ b/src/platform/qt/FrameView.cpp @@ -574,7 +574,7 @@ void FrameView::newVl() { unsigned width, height; m_vl->baseVideoSize(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->setVideoBuffer(m_vl, reinterpret_cast(m_framebuffer.bits()), width); m_vl->reset(m_vl); } diff --git a/src/platform/qt/ObjView.cpp b/src/platform/qt/ObjView.cpp index f4482aba6..a29c621fb 100644 --- a/src/platform/qt/ObjView.cpp +++ b/src/platform/qt/ObjView.cpp @@ -138,7 +138,7 @@ void ObjView::updateTilesGBA(bool force) { for (unsigned y = 0; y < newInfo.height; ++y) { for (unsigned x = 0; x < newInfo.width; ++x, ++i, ++tile, ++tileBase) { if (tile < maxTiles) { - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, newInfo.paletteId); + const mColor* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[16 * tileBase], tile, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -233,7 +233,7 @@ void ObjView::updateTilesGB(bool force) { m_ui.tile->setPalette(newInfo.paletteId); for (unsigned y = 0; y < newInfo.height; ++y, ++i) { unsigned t = tile + i; - const color_t* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, newInfo.paletteId); + const mColor* data = mTileCacheGetTileIfDirty(tileCache, &m_tileStatus[8 * t], t, newInfo.paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { diff --git a/src/platform/qt/TilePainter.cpp b/src/platform/qt/TilePainter.cpp index fcb62d420..b8c8075e6 100644 --- a/src/platform/qt/TilePainter.cpp +++ b/src/platform/qt/TilePainter.cpp @@ -62,7 +62,7 @@ void TilePainter::clearTile(int index) { update(r); } -void TilePainter::setTile(int index, const color_t* data) { +void TilePainter::setTile(int index, const mColor* data) { QPainter painter(&m_backing); int w = width() / m_size; int x = index % w; diff --git a/src/platform/qt/TilePainter.h b/src/platform/qt/TilePainter.h index 5ef4b0555..f1f4a86e0 100644 --- a/src/platform/qt/TilePainter.h +++ b/src/platform/qt/TilePainter.h @@ -23,7 +23,7 @@ public: public slots: void clearTile(int index); - void setTile(int index, const color_t*); + void setTile(int index, const mColor*); void setTileCount(int tiles); void setTileMagnification(int mag); diff --git a/src/platform/qt/TileView.cpp b/src/platform/qt/TileView.cpp index 7d8d1a71e..dbfc15531 100644 --- a/src/platform/qt/TileView.cpp +++ b/src/platform/qt/TileView.cpp @@ -142,7 +142,7 @@ void TileView::updateTilesGBA(bool force) { objOffset = 0; cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 1); for (int i = 0; i < 1024; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, 0); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -153,7 +153,7 @@ void TileView::updateTilesGBA(bool force) { if (!m_ui.tilesBg->isChecked()) { cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 3); for (int i = 1024; i < 1536; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 1024, 0); if (data) { m_ui.tiles->setTile(i - objOffset, data); } else if (force) { @@ -175,7 +175,7 @@ void TileView::updateTilesGBA(bool force) { objOffset = 0; cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); for (int i = 0; i < 2048; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i, m_paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { @@ -186,7 +186,7 @@ void TileView::updateTilesGBA(bool force) { if (!m_ui.tilesBg->isChecked()) { cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 2); for (int i = 2048; i < 3072; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[16 * i], i - 2048, m_paletteId); if (data) { m_ui.tiles->setTile(i - objOffset, data); } else if (force) { @@ -205,7 +205,7 @@ void TileView::updateTilesGB(bool force) { m_ui.tiles->setTileCount(count); mTileCache* cache = mTileCacheSetGetPointer(&m_cacheSet->tiles, 0); for (int i = 0; i < count; ++i) { - const color_t* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId); + const mColor* data = mTileCacheGetTileIfDirty(cache, &m_tileStatus[8 * i], i, m_paletteId); if (data) { m_ui.tiles->setTile(i, data); } else if (force) { diff --git a/src/platform/sdl/main.h b/src/platform/sdl/main.h index 43701b3c2..8c2f517d7 100644 --- a/src/platform/sdl/main.h +++ b/src/platform/sdl/main.h @@ -30,7 +30,7 @@ CXX_GUARD_START struct mCore; struct mSDLRenderer { struct mCore* core; - color_t* outputBuffer; + mColor* outputBuffer; struct mSDLAudio audio; struct mSDLEvents events; diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index c829ab9b0..1f61cc279 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -79,7 +79,7 @@ static GLuint oldTex; static GLuint screenshotTex; static struct GUIFont* font; -static color_t* frameBuffer; +static mColor* frameBuffer; static struct mAVStream stream; static struct mSwitchRumble { struct mRumbleIntegrator d; @@ -517,7 +517,7 @@ static void _drawFrame(struct mGUIRunner* runner, bool faded) { hidSendVibrationValues(vibrationDeviceHandles, values, 4); } -static void _drawScreenshot(struct mGUIRunner* runner, const color_t* pixels, unsigned width, unsigned height, bool faded) { +static void _drawScreenshot(struct mGUIRunner* runner, const mColor* pixels, unsigned width, unsigned height, bool faded) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, screenshotTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); diff --git a/src/platform/test/cinema-main.c b/src/platform/test/cinema-main.c index a990b5599..cc1bad862 100644 --- a/src/platform/test/cinema-main.c +++ b/src/platform/test/cinema-main.c @@ -684,7 +684,7 @@ static void _cinemaDimensionsChanged(struct mAVStream* stream, unsigned width, u } } -static void _cinemaVideoFrame(struct mAVStream* stream, const color_t* pixels, size_t stride) { +static void _cinemaVideoFrame(struct mAVStream* stream, const mColor* pixels, size_t stride) { struct CInemaStream* cistream = (struct CInemaStream*) stream; cistream->image->stride = stride; size_t bufferSize = cistream->image->stride * cistream->image->height * BYTES_PER_PIXEL; From bb8a6e05f9fb440efdf2121f08448814d6a7ed1f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 15 Sep 2024 03:18:16 -0700 Subject: [PATCH 143/148] GBA Memory: Add support for palette RAM, VRAM, and OAM to GBAPatch8 --- src/gba/memory.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/gba/memory.c b/src/gba/memory.c index 1ddd2eb99..09d3e7a74 100644 --- a/src/gba/memory.c +++ b/src/gba/memory.c @@ -1350,10 +1350,22 @@ void GBAPatch16(struct ARMCore* cpu, uint32_t address, int16_t value, int16_t* o } } +#define MUNGE8 \ + if (address & 1) { \ + oldValue = alignedValue >> 8; \ + alignedValue &= 0xFF; \ + alignedValue |= value << 8; \ + } else { \ + oldValue = alignedValue; \ + alignedValue &= 0xFF00; \ + alignedValue |= (uint8_t) value; \ + } + void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) { struct GBA* gba = (struct GBA*) cpu->master; struct GBAMemory* memory = &gba->memory; int8_t oldValue = -1; + int16_t alignedValue; switch (address >> BASE_OFFSET) { case GBA_REGION_EWRAM: @@ -1368,13 +1380,29 @@ void GBAPatch8(struct ARMCore* cpu, uint32_t address, int8_t value, int8_t* old) mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); break; case GBA_REGION_PALETTE_RAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + LOAD_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette); + MUNGE8; + STORE_16(alignedValue, address & (GBA_SIZE_PALETTE_RAM - 2), gba->video.palette); + gba->video.renderer->writePalette(gba->video.renderer, address & (GBA_SIZE_PALETTE_RAM - 2), alignedValue); break; case GBA_REGION_VRAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + if ((address & 0x0001FFFF) < GBA_SIZE_VRAM) { + LOAD_16(alignedValue, address & 0x0001FFFE, gba->video.vram); + MUNGE8; + STORE_16(alignedValue, address & 0x0001FFFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x0001FFFE); + } else { + LOAD_16(alignedValue, address & 0x00017FFE, gba->video.vram); + MUNGE8; + STORE_16(alignedValue, address & 0x00017FFE, gba->video.vram); + gba->video.renderer->writeVRAM(gba->video.renderer, address & 0x00017FFE); + } break; case GBA_REGION_OAM: - mLOG(GBA_MEM, STUB, "Unimplemented memory Patch8: 0x%08X", address); + LOAD_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw); + MUNGE8; + STORE_16(alignedValue, address & (GBA_SIZE_OAM - 2), gba->video.oam.raw); + gba->video.renderer->writeOAM(gba->video.renderer, (address & (GBA_SIZE_OAM - 2)) >> 1); break; case GBA_REGION_ROM0: case GBA_REGION_ROM0_EX: From 3ad4e62b0248e1930c2d338810a272e7cc47d7d6 Mon Sep 17 00:00:00 2001 From: Hexaae Date: Wed, 17 Apr 2024 07:12:31 +0000 Subject: [PATCH 144/148] Qt: Update translation (Italian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/it/ --- src/platform/qt/ts/mgba-it.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/platform/qt/ts/mgba-it.ts b/src/platform/qt/ts/mgba-it.ts index 12a018db7..6c2d16d4f 100644 --- a/src/platform/qt/ts/mgba-it.ts +++ b/src/platform/qt/ts/mgba-it.ts @@ -6,22 +6,22 @@ Game Boy Advance ROMs (%1) - ROM per Game Boy Advance (%1) + ROM per Game Boy Advance (%1) Game Boy ROMs (%1) - ROM per Game Boy (%1) + ROM per Game Boy (%1) All ROMs (%1) - Tutte le ROM (%1) + Tutte le ROM (%1) %1 Video Logs (*.mvl) - %1 log Video (*.mvl) + %1 log Video (*.mvl) @@ -561,7 +561,7 @@ Dimensione del download: %3 Background - Sfondo + Sfondo @@ -591,7 +591,7 @@ Dimensione del download: %3 Browse - Sfoglia + Sfoglia @@ -4759,12 +4759,12 @@ Dimensione del download: %3 Select image - Seleziona immagine + Seleziona immagine Image file (*.png *.jpg *.jpeg) - File immagine (*.png *.jpg *.jpeg) + File immagine (*.png *.jpg *.jpeg) @@ -4784,7 +4784,7 @@ Dimensione del download: %3 Less than an hour ago - Meno di un ora fa + Meno di un'ora fa @@ -4815,7 +4815,7 @@ Dimensione del download: %3 Gameplay - Gameplay + In gioco @@ -5555,7 +5555,7 @@ Dimensione del download: %3 by %1 - per %1 + di %1 @@ -6771,17 +6771,17 @@ Dimensione del download: %3 Super (L) - Super (L) + Super (L) Super (R) - Super (R) + Super (R) Menu - Menu + Menu From e4973a98d8dfd103d189d5363c7db24fc4da233b Mon Sep 17 00:00:00 2001 From: Milihraim Date: Tue, 7 May 2024 13:53:56 +0000 Subject: [PATCH 145/148] Qt: Update translation (Russian) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/ru/ --- src/platform/qt/ts/mgba-ru.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/ts/mgba-ru.ts b/src/platform/qt/ts/mgba-ru.ts index 17147a467..574a66861 100644 --- a/src/platform/qt/ts/mgba-ru.ts +++ b/src/platform/qt/ts/mgba-ru.ts @@ -5141,7 +5141,7 @@ Download size: %3 Rewind speed: - + Скорость перемотки: @@ -5231,7 +5231,7 @@ Download size: %3 Language - + Язык @@ -5322,7 +5322,7 @@ Download size: %3 Fast forward speed: - Скорость перемотки: + Скорость перемотки (ускр.): From a60448d7bcde4d720c8e98b84b27c4fb8c502de9 Mon Sep 17 00:00:00 2001 From: Evrins Hu Date: Sat, 11 May 2024 01:20:53 +0000 Subject: [PATCH 146/148] Qt: Update translation (Chinese (Simplified)) Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/zh_Hans/ --- src/platform/qt/ts/mgba-zh_CN.ts | 104 +++++++++++++++---------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/platform/qt/ts/mgba-zh_CN.ts b/src/platform/qt/ts/mgba-zh_CN.ts index 6992a6280..4e570c196 100644 --- a/src/platform/qt/ts/mgba-zh_CN.ts +++ b/src/platform/qt/ts/mgba-zh_CN.ts @@ -6,22 +6,22 @@ Game Boy Advance ROMs (%1) - Game Boy Advance ROM (%1) + Game Boy Advance ROMs (%1) Game Boy ROMs (%1) - Game Boy ROM (%1) + Game Boy ROMs (%1) All ROMs (%1) - 所有 ROM (%1) + 所有 ROMs (%1) %1 Video Logs (*.mvl) - %1 视频日志 (*.mvl) + %1 视频日志 (*.mvl) @@ -530,12 +530,12 @@ Download size: %3 3DS - + 3DS Vita - + Vita @@ -561,7 +561,7 @@ Download size: %3 Background - 背景 + 背景 @@ -591,7 +591,7 @@ Download size: %3 Browse - 浏览 + 浏览 @@ -631,12 +631,12 @@ Download size: %3 3DS - + 3DS Vita - + Vita @@ -716,7 +716,7 @@ Download size: %3 Image files (*.png *.jpg *.bmp) - + 图像文件 (*.png *.jpg *.bmp) @@ -975,37 +975,37 @@ Download size: %3 Game Boy (DMG) - + Game Boy (DMG) Game Boy Pocket (MGB) - + Game Boy Pocket (MGB) Super Game Boy (SGB) - + Super Game Boy (SGB) Super Game Boy 2 (SGB) - + Super Game Boy 2 (SGB) Game Boy Color (CGB) - + Game Boy Color (CGB) Game Boy Advance (AGB) - + Game Boy Advance (AGB) Super Game Boy Color (SGB + CGB) - + Super Game Boy Color (SGB + CGB) @@ -1015,27 +1015,27 @@ Download size: %3 MBC1 - + MBC1 MBC2 - + MBC2 MBC3 - + MBC3 MBC3 + RTC - + MBC3 + 实时时钟 MBC5 - + MBC5 @@ -1045,7 +1045,7 @@ Download size: %3 MBC6 - + MBC6 @@ -1055,17 +1055,17 @@ Download size: %3 MMM01 - + MMM01 HuC-1 - + HuC-1 HuC-3 - + HuC-3 @@ -1080,17 +1080,17 @@ Download size: %3 Wisdom Tree - + Wisdom Tree NT (old 1) - + NT (旧 1) NT (old 2) - + NT (旧 2) @@ -1105,32 +1105,32 @@ Download size: %3 BBD - + BBD Hitek - + Hitek GGB-81 - + GGB-81 Li Cheng - + Li Cheng Sachen (MMC1) - + Sachen (MMC1) Sachen (MMC2) - + Sachen (MMC2) @@ -3752,17 +3752,17 @@ Download size: %3 Trying to detach a multiplayer player that's not attached - + 尝试断开与未连接的多人玩家的连接 Trying to get player ID for a multiplayer player that's not attached - + 尝试获取未连接的多人玩家的 ID Trying to get save ID for a multiplayer player that's not attached - + 尝试获取未连接的多人玩家的存档 ID @@ -4310,7 +4310,7 @@ Download size: %3 Save file: - + 保存文件: @@ -4759,12 +4759,12 @@ Download size: %3 Select image - 选择图片 + 选择图片 Image file (*.png *.jpg *.jpeg) - 图像文件(*.png *.jpg *.jpeg) + 图像文件(*.png *.jpg *.jpeg) @@ -5247,7 +5247,7 @@ Download size: %3 Custom border: - + 自定义边框: @@ -5283,7 +5283,7 @@ Download size: %3 Rewind speed: - + 倒带速度: @@ -5879,7 +5879,7 @@ Download size: %3 WavPack - + WavPack @@ -6099,7 +6099,7 @@ Download size: %3 %1 - %2 (%3 fps) - %4 - + %1 - %2 (%3 fps) - %4 @@ -6401,12 +6401,12 @@ Download size: %3 Increase fast forward speed - + 加快快进速度 Decrease fast forward speed - + 降低快进速度 @@ -6744,7 +6744,7 @@ Download size: %3 %1 kiB - + %1 千字节 @@ -6769,17 +6769,17 @@ Download size: %3 Super (L) - Super(L) + Super (L) Super (R) - Super(R) + Super (R) Menu - 菜单 + 菜单 From 9d9cb7450f083ec6beb8af5344f3ca71471f1b00 Mon Sep 17 00:00:00 2001 From: Imre Kristoffer Eilertsen Date: Sun, 9 Jun 2024 07:14:59 +0000 Subject: [PATCH 147/148] =?UTF-8?q?Qt:=20Update=20translation=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Translation: mGBA/Qt Translate-URL: https://hosted.weblate.org/projects/mgba/mgba-qt/nb_NO/ --- src/platform/qt/ts/mgba-nb_NO.ts | 243 ++++++++++++++++--------------- 1 file changed, 122 insertions(+), 121 deletions(-) diff --git a/src/platform/qt/ts/mgba-nb_NO.ts b/src/platform/qt/ts/mgba-nb_NO.ts index 4a97f0c60..6c06c2fe6 100644 --- a/src/platform/qt/ts/mgba-nb_NO.ts +++ b/src/platform/qt/ts/mgba-nb_NO.ts @@ -6,12 +6,12 @@ Game Boy Advance ROMs (%1) - + Game Boy Advance ROM-filer (%1) Game Boy ROMs (%1) - + Game Boy ROM-filer (%1) @@ -21,7 +21,7 @@ %1 Video Logs (*.mvl) - + %1-videologger (*.mvl) @@ -34,7 +34,7 @@ <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/">Nettside</a> • <a href="https://forums.mgba.io/">Forum / støtte</a> • <a href="https://patreon.com/mgba">Doner</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Kildekode</a> + <a href="https://mgba.io/">Nettside</a> • <a href="https://forums.mgba.io/">Forum / støtte</a> • <a href="https://patreon.com/mgba">Doner</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Kildekode</a> @@ -70,7 +70,8 @@ Game Boy Advance er et registrert varemerke tilhørende Nintendo Co., Ltd. An update to %1 is available. - + En oppdatering til %1 er tilgjengelig. + @@ -101,12 +102,12 @@ Nedlastningsstørrelse: %3 Downloading failed. Please update manually. - + Nedlastingen mislyktes. Vennligst oppdater manuelt. Downloading done. Press OK to restart %1 and install the update. - + Nedlastingen er fullført. Trykk OK for å starte %1 på nytt og installere oppdateringen. @@ -137,7 +138,7 @@ Nedlastningsstørrelse: %3 Open in archive... - Åpne i arkiv … + Åpne i arkiv … @@ -244,7 +245,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -313,7 +314,7 @@ Nedlastningsstørrelse: %3 (untitled) - + (uten tittel) @@ -346,7 +347,7 @@ Nedlastningsstørrelse: %3 Code type - + Kodetype @@ -373,7 +374,7 @@ Nedlastningsstørrelse: %3 Select cheats file - Velg juksekodefil + Velg juksekodefil @@ -397,7 +398,7 @@ Nedlastningsstørrelse: %3 Reset the game? - + Vil du starte spillet på nytt? @@ -532,7 +533,7 @@ Nedlastningsstørrelse: %3 Vita - + Vita @@ -545,7 +546,7 @@ Nedlastningsstørrelse: %3 Banner - + Plakat @@ -588,7 +589,7 @@ Nedlastningsstørrelse: %3 Browse - + Bla @@ -761,7 +762,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -781,7 +782,7 @@ Nedlastningsstørrelse: %3 Objwin - + Objwin @@ -817,12 +818,12 @@ Nedlastningsstørrelse: %3 Clear Button - + Tøm knapper Clear Analog - + Tøm analoge @@ -832,7 +833,7 @@ Nedlastningsstørrelse: %3 Set all - + Sett alle @@ -860,7 +861,7 @@ Nedlastningsstørrelse: %3 Standard GDB - + Standard GDB @@ -1082,27 +1083,27 @@ Nedlastningsstørrelse: %3 NT (old 1) - + NT (gammel 1) NT (old 2) - + NT (gammel 2) NT (new) - + NT (ny) Pokémon Jade/Diamond - + Pokémon Jade/Diamond BBD - + BBD @@ -1122,12 +1123,12 @@ Nedlastningsstørrelse: %3 Sachen (MMC1) - + Sachen (MMC1) Sachen (MMC2) - + Sachen (MMC2) @@ -1212,22 +1213,22 @@ Nedlastningsstørrelse: %3 Enable background 0 - + Skru på bakgrunn 0 Enable background 1 - + Skru på bakgrunn 1 Enable background 2 - + Skru på bakgrunn 2 Enable background 3 - + Skru på bakgrunn 3 @@ -1237,12 +1238,12 @@ Nedlastningsstørrelse: %3 Enable Window 0 - + Skru på vindu 1 Enable Window 1 - + Skru på vindu 1 @@ -1311,7 +1312,7 @@ Nedlastningsstørrelse: %3 Enable mosaic - + Skru på flislegging @@ -1609,7 +1610,7 @@ Nedlastningsstørrelse: %3 Blend mode - + Blendmodus @@ -1876,49 +1877,49 @@ Nedlastningsstørrelse: %3 Enable channel 1 right - + Skru på kanal 1 høyre Enable channel 2 right - + Skru på kanal 2 høyre Enable channel 3 right - + Skru på kanal 3 høyre Enable channel 4 right - + Skru på kanal 4 høyre Enable channel 1 left - + Skru på kanal 1 venstre Enable channel 2 left - + Skru på kanal 2 venstre Enable channel 3 left - + Skru på kanal 3 venstre Enable channel 4 left - + Skru på kanal 4 venstre @@ -2211,7 +2212,7 @@ Nedlastningsstørrelse: %3 Joypad - + Kontroller @@ -2271,13 +2272,13 @@ Nedlastningsstørrelse: %3 0x9800 – 0x9BFF - + 0x9800 – 0x9BFF 0x9C00 – 0x9FFF - + 0x9C00 – 0x9FFF @@ -2287,12 +2288,12 @@ Nedlastningsstørrelse: %3 0x8800 – 0x87FF - + 0x8800 – 0x87FF 0x8000 – 0x8FFF - + 0x8000 – 0x8FFF @@ -2317,12 +2318,12 @@ Nedlastningsstørrelse: %3 0: HBlank - + 0: HBlank 1: VBlank - + 1: VBlank @@ -2517,7 +2518,7 @@ Nedlastningsstørrelse: %3 WRAM bank - + WRAM-bank @@ -2569,7 +2570,7 @@ Nedlastningsstørrelse: %3 Fixed - + Fastsatt @@ -2654,7 +2655,7 @@ Nedlastningsstørrelse: %3 IRQ - + IRQ @@ -2804,22 +2805,22 @@ Nedlastningsstørrelse: %3 SC - + SC SD - + SD SI - + SI SO - + SO @@ -2855,37 +2856,37 @@ Nedlastningsstørrelse: %3 SIO - + SIO DMA 0 - + DMA 0 DMA 1 - + DMA 1 DMA 2 - + DMA 2 DMA 3 - + DMA 3 Keypad - + Talltastatur @@ -3056,7 +3057,7 @@ Nedlastningsstørrelse: %3 No Save - + Ingen lagrefil @@ -3236,7 +3237,7 @@ Nedlastningsstørrelse: %3 Enabled Levels - + Påskrudde nivåer @@ -3266,7 +3267,7 @@ Nedlastningsstørrelse: %3 Fatal - Kritisk + Kritisk @@ -3286,7 +3287,7 @@ Nedlastningsstørrelse: %3 Max Lines - + Maks antall linjer @@ -3342,7 +3343,7 @@ Nedlastningsstørrelse: %3 Xform - + Xform @@ -3422,7 +3423,7 @@ Nedlastningsstørrelse: %3 Failed to open output file: %1 - Klarte ikke å åpne utdatafil: %1 + Klarte ikke å åpne utdatafil: %1 @@ -3445,7 +3446,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -3465,7 +3466,7 @@ Nedlastningsstørrelse: %3 Failed to open output file: %1 - Klarte ikke å åpne utdatafil: %1 + Klarte ikke å åpne utdatafil: %1 @@ -3708,7 +3709,7 @@ Nedlastningsstørrelse: %3 Load TBL - + Last inn TBL @@ -3733,7 +3734,7 @@ Nedlastningsstørrelse: %3 Load - Last inn + Last inn @@ -3937,7 +3938,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -4250,7 +4251,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -4335,7 +4336,7 @@ Nedlastningsstørrelse: %3 Generate report - + Generer rapport @@ -4363,7 +4364,7 @@ Nedlastningsstørrelse: %3 Save games and save states (%1) - + Lagrefiler og lagringstilstander @@ -4373,7 +4374,7 @@ Nedlastningsstørrelse: %3 Save games (%1) - + Lagrefiler (%1) @@ -4428,13 +4429,13 @@ Nedlastningsstørrelse: %3 Input file - + Inndatafil Browse - + Bla @@ -4484,7 +4485,7 @@ Nedlastningsstørrelse: %3 %1 SRAM - + %1 SRAM @@ -4613,7 +4614,7 @@ Nedlastningsstørrelse: %3 Fixed time - + Fastsatt tid @@ -4623,7 +4624,7 @@ Nedlastningsstørrelse: %3 Start time at - + Start tiden på @@ -4633,7 +4634,7 @@ Nedlastningsstørrelse: %3 Offset time - + Tidsavvik @@ -4664,13 +4665,13 @@ Nedlastningsstørrelse: %3 Set Y - + Sett Y Set X - + Sett X @@ -4710,7 +4711,7 @@ Nedlastningsstørrelse: %3 OpenGL (force version 1.x) - + OpenGL (tving versjon 1.x) @@ -4908,7 +4909,7 @@ Nedlastningsstørrelse: %3 Sample rate: - + Datapunktfrekvens: @@ -4957,7 +4958,7 @@ Nedlastningsstørrelse: %3 Audio in multiplayer: - + Lyd i flerspiller: @@ -4967,7 +4968,7 @@ Nedlastningsstørrelse: %3 Player 1 window only - + Kun spiller 1 sitt vindu @@ -5277,12 +5278,12 @@ Nedlastningsstørrelse: %3 Rewind history: - + Tilbakestillingshistorikk: Rewind speed: - + Tilbakespolingsfart: @@ -5420,7 +5421,7 @@ Nedlastningsstørrelse: %3 GB BIOS file: - + GB BIOS-fil: @@ -5434,12 +5435,12 @@ Nedlastningsstørrelse: %3 Browse - + Bla Use BIOS file if found - + Bruk BIOS-filen hvis den blir funnet @@ -5464,7 +5465,7 @@ Nedlastningsstørrelse: %3 Save games - + Lagrefiler @@ -5483,7 +5484,7 @@ Nedlastningsstørrelse: %3 Screenshots - + Skjermklipp @@ -5493,7 +5494,7 @@ Nedlastningsstørrelse: %3 Cheats - Juks + Juks @@ -5572,7 +5573,7 @@ Nedlastningsstørrelse: %3 Active Shader: - + Aktiv skyggelegger: @@ -5652,7 +5653,7 @@ Nedlastningsstørrelse: %3 Portable Network Graphics (*.png) - + Portable Network Graphics (*.png) @@ -5662,7 +5663,7 @@ Nedlastningsstørrelse: %3 Tiles - + Fliser @@ -5687,7 +5688,7 @@ Nedlastningsstørrelse: %3 Magnification - Forstørrelse + Forstørrelse @@ -5722,7 +5723,7 @@ Nedlastningsstørrelse: %3 Copy Selected - + Kopier valgte @@ -5745,7 +5746,7 @@ Nedlastningsstørrelse: %3 Select output file - Velg utdatafil + Velg utdatafil @@ -5872,7 +5873,7 @@ Nedlastningsstørrelse: %3 FFV1 - + FFV1 @@ -6024,7 +6025,7 @@ Nedlastningsstørrelse: %3 Crash - Krasj + Krasj @@ -6121,7 +6122,7 @@ Nedlastningsstørrelse: %3 Save games (%1) - + Lagrefiler (%1) @@ -6197,7 +6198,7 @@ Nedlastningsstørrelse: %3 ROM &info... - + ROM-&info ... @@ -6232,12 +6233,12 @@ Nedlastningsstørrelse: %3 Quick load - + Hurtiginnlasting Quick save - + Hurtiglagring @@ -6278,12 +6279,12 @@ Nedlastningsstørrelse: %3 GameShark saves (*.gsv *.sps *.xps) - + GameShark-lagrefiler (*.gsv *.sps *.xps) Reset needed - + Tilbakestilling kreves @@ -6293,7 +6294,7 @@ Nedlastningsstørrelse: %3 Save games - + Lagrefiler @@ -6318,7 +6319,7 @@ Nedlastningsstørrelse: %3 New multiplayer window - + Nytt flerspillervindu @@ -6413,7 +6414,7 @@ Nedlastningsstørrelse: %3 Re&wind - + Spol ti&lbake @@ -6463,7 +6464,7 @@ Nedlastningsstørrelse: %3 Audio/&Video - + Lyd/&Video @@ -6568,7 +6569,7 @@ Nedlastningsstørrelse: %3 Game &overrides... - + Spilloverstyringer ... @@ -6638,12 +6639,12 @@ Nedlastningsstørrelse: %3 View memory... - + Vis minne ... Search memory... - + Søk i minne ... From 3853b699f427c928ea7c170b9e739042c7864d97 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 16 Sep 2024 02:48:17 -0700 Subject: [PATCH 148/148] Qt: Fix how some languages are shown in settings --- src/platform/qt/ts/{mgba-es.ts => mgba-es_419.ts} | 0 src/platform/qt/ts/{mgba-pt.ts => mgba-pt_PT.ts} | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/platform/qt/ts/{mgba-es.ts => mgba-es_419.ts} (100%) rename src/platform/qt/ts/{mgba-pt.ts => mgba-pt_PT.ts} (99%) diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es_419.ts similarity index 100% rename from src/platform/qt/ts/mgba-es.ts rename to src/platform/qt/ts/mgba-es_419.ts diff --git a/src/platform/qt/ts/mgba-pt.ts b/src/platform/qt/ts/mgba-pt_PT.ts similarity index 99% rename from src/platform/qt/ts/mgba-pt.ts rename to src/platform/qt/ts/mgba-pt_PT.ts index cddb1dd8c..f3aa6bdc1 100644 --- a/src/platform/qt/ts/mgba-pt.ts +++ b/src/platform/qt/ts/mgba-pt_PT.ts @@ -1,6 +1,6 @@ - + QGBA