From dee24e56956f16d852fc3be51628c1dc2e4477ac Mon Sep 17 00:00:00 2001 From: "baby.lueshi" Date: Mon, 6 Sep 2010 21:41:01 +0000 Subject: [PATCH] Added support for recording multiple GameCube controllers at once. Fixed recording playback to automatically enable/disable the correct controllers. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6188 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/SI.cpp | 8 ++++- Source/Core/Core/Src/OnFrame.cpp | 40 +++++++++++++++++++++--- Source/Core/Core/Src/OnFrame.h | 3 ++ Source/Core/DolphinWX/Src/FrameTools.cpp | 14 +++++++-- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/Src/HW/SI.cpp b/Source/Core/Core/Src/HW/SI.cpp index 991617f013..bf33029a6e 100644 --- a/Source/Core/Core/Src/HW/SI.cpp +++ b/Source/Core/Core/Src/HW/SI.cpp @@ -19,6 +19,7 @@ #include "ChunkFile.h" #include "../ConfigManager.h" #include "../CoreTiming.h" +#include "../OnFrame.h" #include "SystemTimers.h" #include "ProcessorInterface.h" @@ -245,7 +246,12 @@ void Init() g_Channel[i].m_InHi.Hex = 0; g_Channel[i].m_InLo.Hex = 0; - AddDevice(SConfig::GetInstance().m_SIDevice[i], i); + if (Frame::IsUsingPad(i)) + AddDevice(SI_GC_CONTROLLER, i); + else if (Frame::IsRecordingInput() || Frame::IsPlayingInput()) + AddDevice(SI_NONE, i); + else + AddDevice(SConfig::GetInstance().m_SIDevice[i], i); } g_Poll.Hex = 0; diff --git a/Source/Core/Core/Src/OnFrame.cpp b/Source/Core/Core/Src/OnFrame.cpp index 61d8db9a99..12869a8bd6 100644 --- a/Source/Core/Core/Src/OnFrame.cpp +++ b/Source/Core/Core/Src/OnFrame.cpp @@ -22,6 +22,7 @@ #include "Thread.h" #include "FileUtil.h" #include "PowerPC/PowerPC.h" +#include "HW/SI.h" Common::CriticalSection cs_frameSkip; @@ -185,10 +186,37 @@ bool IsPlayingInput() return (g_playMode == MODE_PLAYING); } +bool IsUsingPad(int controller) +{ + switch (controller) + { + case 0: + return g_numPads & 0x01; + case 1: + return g_numPads & 0x02; + case 2: + return g_numPads & 0x04; + case 3: + return g_numPads & 0x08; + default: + return false; + } +} + +void ChangePads() +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) { + SerialInterface::ChangeDevice(IsUsingPad(0) ? SI_GC_CONTROLLER : SI_NONE, 0); + SerialInterface::ChangeDevice(IsUsingPad(1) ? SI_GC_CONTROLLER : SI_NONE, 1); + SerialInterface::ChangeDevice(IsUsingPad(2) ? SI_GC_CONTROLLER : SI_NONE, 2); + SerialInterface::ChangeDevice(IsUsingPad(3) ? SI_GC_CONTROLLER : SI_NONE, 3); + } +} + // TODO: Add BeginRecordingFromSavestate bool BeginRecordingInput(int controllers) { - if(g_playMode != MODE_NONE || g_recordfd) + if(g_playMode != MODE_NONE || controllers == 0 || g_recordfd != NULL) return false; const char *filename = g_recordFile.c_str(); @@ -220,7 +248,7 @@ bool BeginRecordingInput(int controllers) void RecordInput(SPADStatus *PadStatus, int controllerID) { - if(!IsRecordingInput() || controllerID >= g_numPads || controllerID < 0) + if(!IsRecordingInput() || !IsUsingPad(controllerID)) return; g_padState.A = ((PadStatus->button & PAD_BUTTON_A) != 0); @@ -289,6 +317,8 @@ bool PlayInput(const char *filename) g_numPads = header.numControllers; g_numRerecords = header.numRerecords; + ChangePads(); + g_playMode = MODE_PLAYING; return true; @@ -306,10 +336,10 @@ void LoadInput(const char *filename) DTMHeader header; fread(&header, sizeof(DTMHeader), 1, t_record); + fclose(t_record); if(header.filetype[0] != 'D' || header.filetype[1] != 'T' || header.filetype[2] != 'M' || header.filetype[3] != 0x1A) { PanicAlert("Savestate movie %s is corrupted, movie recording stopping...", filename); - fclose(t_record); EndPlayInput(); return; } @@ -319,7 +349,7 @@ void LoadInput(const char *filename) g_numPads = header.numControllers; - fclose(t_record); + ChangePads(); if (g_recordfd) fclose(g_recordfd); @@ -341,7 +371,7 @@ void PlayController(SPADStatus *PadStatus, int controllerID) { // Correct playback is entirely dependent on the emulator polling the controllers // in the same order done during recording - if(!IsPlayingInput() || controllerID >= g_numPads || controllerID < 0) + if(!IsPlayingInput() || !IsUsingPad(controllerID)) return; memset(PadStatus, 0, sizeof(SPADStatus)); diff --git a/Source/Core/Core/Src/OnFrame.h b/Source/Core/Core/Src/OnFrame.h index c46dd6af26..5e02a9f61a 100644 --- a/Source/Core/Core/Src/OnFrame.h +++ b/Source/Core/Core/Src/OnFrame.h @@ -99,6 +99,9 @@ bool IsAutoFiring(); bool IsRecordingInput(); bool IsPlayingInput(); +bool IsUsingPad(int controller); +void ChangePads(); + void SetAutoHold(bool bEnabled, u32 keyToHold = 0); void SetAutoFire(bool bEnabled, u32 keyOne = 0, u32 keyTwo = 0); diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 4e89fecbfa..8d718ae44f 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -628,8 +628,18 @@ void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event)) void CFrame::OnRecord(wxCommandEvent& WXUNUSED (event)) { - // TODO: Take controller settings from Gamecube Configuration menu - if(Frame::BeginRecordingInput(1)) + int controllers = 0; + + if (SConfig::GetInstance().m_SIDevice[0] == SI_GC_CONTROLLER) + controllers |= 0x01; + if (SConfig::GetInstance().m_SIDevice[1] == SI_GC_CONTROLLER) + controllers |= 0x02; + if (SConfig::GetInstance().m_SIDevice[2] == SI_GC_CONTROLLER) + controllers |= 0x04; + if (SConfig::GetInstance().m_SIDevice[3] == SI_GC_CONTROLLER) + controllers |= 0x08; + + if(Frame::BeginRecordingInput(controllers)) BootGame(std::string("")); }