diff --git a/src/core/core.h b/src/core/core.h index 45dfbcd36..23bd25c37 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -92,6 +92,7 @@ struct mCore { void (*setRTC)(struct mCore*, struct mRTCSource*); void (*setRotation)(struct mCore*, struct mRotationSource*); + void (*setRumble)(struct mCore*, struct mRumble*); }; #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 diff --git a/src/gb/core.c b/src/gb/core.c index 39f84fd25..a976b366c 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -244,6 +244,11 @@ static void _GBCoreSetRotation(struct mCore* core, struct mRotationSource* rotat gb->memory.rotation = rotation; } +static void _GBCoreSetRumble(struct mCore* core, struct mRumble* rumble) { + struct GB* gb = core->board; + gb->memory.rumble = rumble; +} + struct mCore* GBCoreCreate(void) { struct GBCore* gbcore = malloc(sizeof(*gbcore)); struct mCore* core = &gbcore->d; @@ -284,5 +289,6 @@ struct mCore* GBCoreCreate(void) { core->getGameCode = _GBCoreGetGameCode; core->setRTC = _GBCoreSetRTC; core->setRotation = _GBCoreSetRotation; + core->setRumble = _GBCoreSetRumble; return core; } diff --git a/src/gb/memory.c b/src/gb/memory.c index 1e7ccaabd..a11d982d5 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -132,11 +132,14 @@ void GBMemoryReset(struct GB* gb) { case 0x19: case 0x1A: case 0x1B: + gb->memory.mbc = _GBMBC5; + gb->memory.mbcType = GB_MBC5; + break; case 0x1C: case 0x1D: case 0x1E: gb->memory.mbc = _GBMBC5; - gb->memory.mbcType = GB_MBC5; + gb->memory.mbcType = GB_MBC5_RUMBLE; break; case 0x20: gb->memory.mbc = _GBMBC6; @@ -529,9 +532,11 @@ void _GBMBC5(struct GBMemory* memory, uint16_t address, uint8_t value) { _switchBank(memory, bank); break; case 0x2: - if (value < 0x10) { - _switchSramBank(memory, value); + if (memory->mbcType == GB_MBC5_RUMBLE) { + memory->rumble->setRumble(memory->rumble, (value >> 3) & 1); + value &= ~8; } + _switchSramBank(memory, value & 0xF); break; default: // TODO diff --git a/src/gb/memory.h b/src/gb/memory.h index 603bb2e16..aaaa8e321 100644 --- a/src/gb/memory.h +++ b/src/gb/memory.h @@ -65,6 +65,7 @@ enum GBMemoryBankControllerType { GB_MMM01 = 0x10, GB_HuC1 = 0x11, GB_HuC3 = 0x12, + GB_MBC5_RUMBLE = 0x105 }; struct GBMemory; @@ -145,6 +146,7 @@ struct GBMemory { uint8_t rtcRegs[5]; struct mRTCSource* rtc; struct mRotationSource* rotation; + struct mRumble* rumble; }; void GBMemoryInit(struct GB* gb); diff --git a/src/gba/core.c b/src/gba/core.c index 85da81a4d..cb2ff9571 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -277,6 +277,11 @@ static void _GBACoreSetRotation(struct mCore* core, struct mRotationSource* rota gba->rotationSource = rotation; } +static void _GBACoreSetRumble(struct mCore* core, struct mRumble* rumble) { + struct GBA* gba = core->board; + gba->rumble = rumble; +} + struct mCore* GBACoreCreate(void) { struct GBACore* gbacore = malloc(sizeof(*gbacore)); struct mCore* core = &gbacore->d; @@ -317,5 +322,6 @@ struct mCore* GBACoreCreate(void) { core->getGameCode = _GBACoreGetGameCode; core->setRTC = _GBACoreSetRTC; core->setRotation = _GBACoreSetRotation; + core->setRumble = _GBACoreSetRumble; return core; } diff --git a/src/platform/libretro/libretro.c b/src/platform/libretro/libretro.c index 591c6e0c0..eaa9129d3 100644 --- a/src/platform/libretro/libretro.c +++ b/src/platform/libretro/libretro.c @@ -324,12 +324,11 @@ bool retro_load_game(const struct retro_game_info* game) { blip_set_rates(core->getAudioChannel(core, 0), core->frequency(core), 32768); blip_set_rates(core->getAudioChannel(core, 1), core->frequency(core), 32768); + core->setRumble(core, &rumble); + #ifdef M_CORE_GBA if (core->platform(core) == PLATFORM_GBA) { struct GBA* gba = core->board; - if (rumbleCallback) { - gba->rumble = &rumble; - } gba->luminanceSource = &lux; const char* sysDir = 0; diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index 2702155ff..503b3e469 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -90,6 +90,7 @@ GameController::GameController(QObject* parent) mRTCGenericSourceInit(&controller->m_rtc, context->core); context->core->setRTC(context->core, &controller->m_rtc.d); context->core->setRotation(context->core, controller->m_inputController->rotationSource()); + context->core->setRumble(context->core, controller->m_inputController->rumble()); #ifdef M_CORE_GBA GBA* gba = static_cast(context->core->board); @@ -101,7 +102,6 @@ GameController::GameController(QObject* parent) #ifdef M_CORE_GBA case PLATFORM_GBA: gba->luminanceSource = &controller->m_lux; - gba->rumble = controller->m_inputController->rumble(); gba->audio.psg.forceDisableCh[0] = !controller->m_audioChannels[0]; gba->audio.psg.forceDisableCh[1] = !controller->m_audioChannels[1]; gba->audio.psg.forceDisableCh[2] = !controller->m_audioChannels[2]; diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index ff348f8d7..c99e68829 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -521,10 +521,8 @@ void _guiFinish(void) { } void _setup(struct mGUIRunner* runner) { - if (runner->core->platform(runner->core) == PLATFORM_GBA) { - ((struct GBA*) runner->core->board)->rumble = &rumble; - } runner->core->setRotation(runner->core, &rotation); + runner->core->setRumble(runner->core, &rumble); _mapKey(&runner->core->inputMap, GCN1_INPUT, PAD_BUTTON_A, GBA_KEY_A); _mapKey(&runner->core->inputMap, GCN1_INPUT, PAD_BUTTON_B, GBA_KEY_B);