From 855bcfa40c9392d939018db2308288c8f2fd34e4 Mon Sep 17 00:00:00 2001 From: skidau Date: Thu, 17 Feb 2011 09:12:36 +0000 Subject: [PATCH] Added an option for input display. This option shows the controls read by the emulator at each frame. GameCube controls in all four ports have been implemented. Wii controls are todo. The option can be found in the graphics settings. This option is usually used for tool-assisted speed-runs (TAS). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7186 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/OnFrame.cpp | 131 ++++++++++++++++-- Source/Core/Core/Src/OnFrame.h | 3 +- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 3 + Source/Core/DolphinWX/Src/VideoConfigDiag.h | 1 + Source/Core/VideoCommon/Src/VideoConfig.cpp | 4 + Source/Core/VideoCommon/Src/VideoConfig.h | 1 + .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 10 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 10 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 4 + 9 files changed, 151 insertions(+), 16 deletions(-) diff --git a/Source/Core/Core/Src/OnFrame.cpp b/Source/Core/Core/Src/OnFrame.cpp index 6a7b569d41..96e4123793 100644 --- a/Source/Core/Core/Src/OnFrame.cpp +++ b/Source/Core/Core/Src/OnFrame.cpp @@ -60,6 +60,16 @@ int g_numRerecords = 0; std::string g_recordFile = "0.dtm"; std::string g_tmpRecordFile = "1.dtm"; +std::string g_InputDisplay[4]; + +std::string GetInputDisplay() +{ + std::string inputDisplay = ""; + for (int i = 0; i < 4; ++i) + inputDisplay.append(g_InputDisplay[i]); + return inputDisplay; +} + void FrameUpdate() { g_frameCounter++; @@ -229,6 +239,75 @@ bool BeginRecordingInput(int controllers) return true; } +void SetInputDisplayString(ControllerState padState, int controllerID) +{ + char inp[70]; + sprintf(inp, "%dP:", controllerID + 1); + g_InputDisplay[controllerID] = inp; + + sprintf(inp, " X: %d Y: %d rX: %d rY: %d L: %d R: %d", + g_padState.AnalogStickX, + g_padState.AnalogStickY, + g_padState.CStickX, + g_padState.CStickY, + g_padState.TriggerL, + g_padState.TriggerR); + g_InputDisplay[controllerID].append(inp); + + if(g_padState.A) + { + g_InputDisplay[controllerID].append(" A"); + } + if(g_padState.B) + { + g_InputDisplay[controllerID].append(" B"); + } + if(g_padState.X) + { + g_InputDisplay[controllerID].append(" X"); + } + if(g_padState.Y) + { + g_InputDisplay[controllerID].append(" Y"); + } + if(g_padState.Z) + { + g_InputDisplay[controllerID].append(" Z"); + } + if(g_padState.Start) + { + g_InputDisplay[controllerID].append(" START"); + } + + if(g_padState.DPadUp) + { + g_InputDisplay[controllerID].append(" UP"); + } + if(g_padState.DPadDown) + { + g_InputDisplay[controllerID].append(" DOWN"); + } + if(g_padState.DPadLeft) + { + g_InputDisplay[controllerID].append(" LEFT"); + } + if(g_padState.DPadRight) + { + g_InputDisplay[controllerID].append(" RIGHT"); + } + + if(g_padState.L) + { + g_InputDisplay[controllerID].append(" L"); + } + if(g_padState.R) + { + g_InputDisplay[controllerID].append(" R"); + } + + g_InputDisplay[controllerID].append("\n"); +} + void RecordInput(SPADStatus *PadStatus, int controllerID) { if(!IsRecordingInput() || !IsUsingPad(controllerID)) @@ -258,6 +337,8 @@ void RecordInput(SPADStatus *PadStatus, int controllerID) g_padState.CStickY = PadStatus->substickY; fwrite(&g_padState, sizeof(ControllerState), 1, g_recordfd); + + SetInputDisplayString(g_padState, controllerID); } void RecordWiimote(int wiimote, u8 *data, s8 size) @@ -383,52 +464,76 @@ void PlayController(SPADStatus *PadStatus, int controllerID) // in the same order done during recording if(!IsPlayingInput() || !IsUsingPad(controllerID)) return; - + memset(PadStatus, 0, sizeof(SPADStatus)); fread(&g_padState, sizeof(ControllerState), 1, g_recordfd); + PadStatus->triggerLeft = g_padState.TriggerL; + PadStatus->triggerRight = g_padState.TriggerR; + + PadStatus->stickX = g_padState.AnalogStickX; + PadStatus->stickY = g_padState.AnalogStickY; + + PadStatus->substickX = g_padState.CStickX; + PadStatus->substickY = g_padState.CStickY; + PadStatus->button |= PAD_USE_ORIGIN; - if(g_padState.A) { + if(g_padState.A) + { PadStatus->button |= PAD_BUTTON_A; PadStatus->analogA = 0xFF; } - if(g_padState.B) { + if(g_padState.B) + { PadStatus->button |= PAD_BUTTON_B; PadStatus->analogB = 0xFF; } if(g_padState.X) + { PadStatus->button |= PAD_BUTTON_X; + } if(g_padState.Y) + { PadStatus->button |= PAD_BUTTON_Y; + } if(g_padState.Z) + { PadStatus->button |= PAD_TRIGGER_Z; + } if(g_padState.Start) + { PadStatus->button |= PAD_BUTTON_START; + } if(g_padState.DPadUp) + { PadStatus->button |= PAD_BUTTON_UP; + } if(g_padState.DPadDown) + { PadStatus->button |= PAD_BUTTON_DOWN; + } if(g_padState.DPadLeft) + { PadStatus->button |= PAD_BUTTON_LEFT; + } if(g_padState.DPadRight) + { PadStatus->button |= PAD_BUTTON_RIGHT; + } if(g_padState.L) + { PadStatus->button |= PAD_TRIGGER_L; + } if(g_padState.R) + { PadStatus->button |= PAD_TRIGGER_R; - - PadStatus->triggerLeft = g_padState.TriggerL; - PadStatus->triggerRight = g_padState.TriggerR; - - PadStatus->stickX = g_padState.AnalogStickX; - PadStatus->stickY = g_padState.AnalogStickY; - - PadStatus->substickX = g_padState.CStickX; - PadStatus->substickY = g_padState.CStickY; - + } + + SetInputDisplayString(g_padState, controllerID); + if(feof(g_recordfd) || g_frameCounter >= g_totalFrameCount) { Core::DisplayMessage("Movie End", 2000); diff --git a/Source/Core/Core/Src/OnFrame.h b/Source/Core/Core/Src/OnFrame.h index e5b8a169f4..be3714c27a 100644 --- a/Source/Core/Core/Src/OnFrame.h +++ b/Source/Core/Core/Src/OnFrame.h @@ -19,7 +19,7 @@ #define __FRAME_H #include "Common.h" -#include "GCPadStatus.h" +#include "../../InputCommon/Src/GCPadStatus.h" #include @@ -125,6 +125,7 @@ bool PlayWiimote(int wiimote, u8* data, s8 &size); void EndPlayInput(bool cont); void SaveRecording(const char *filename); +std::string GetInputDisplay(); }; #endif // __FRAME_H diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 33b6e37ac3..1b9f781fb9 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -109,6 +109,7 @@ wxString disable_textures_tooltip = wxTRANSLATE("Disable texturing.\nThis is onl wxString disable_fog_tooltip = wxTRANSLATE("Disable fog. Improves performance but causes glitches in games which rely on proper fog emulation."); wxString disable_alphapass_tooltip = wxTRANSLATE("Disables an alpha-setting pass.\nBreaks certain effects but might help performance."); wxString show_fps_tooltip = wxTRANSLATE("Show the number of frames rendered per second."); +wxString show_input_display_tooltip = wxTRANSLATE("Display the inputs read by the emulator."); wxString show_stats_tooltip = wxTRANSLATE("Show various statistics.\nThis is only useful for debugging purposes."); wxString proj_stats_tooltip = wxTRANSLATE("Show projection statistics.\nThis is only useful for debugging purposes."); wxString texfmt_tooltip = wxTRANSLATE("Modify textures to show the format they're using.\nThis is only useful for debugging purposes."); @@ -379,6 +380,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_info->Add(texfmt_overlay = new SettingCheckBox(page_advanced, _("Texture Format"), wxGetTranslation(texfmt_tooltip), vconfig.bTexFmtOverlayEnable)); szr_info->Add(efb_copy_regions = new SettingCheckBox(page_advanced, _("EFB Copy Regions"), wxGetTranslation(efb_copy_regions_tooltip), vconfig.bShowEFBCopyRegions)); szr_info->Add(show_shader_errors = new SettingCheckBox(page_advanced, _("Show Shader Errors"), wxT(""), vconfig.bShowShaderErrors)); + szr_info->Add(show_input_display = new SettingCheckBox(page_advanced, _("Show Input Display"), wxGetTranslation(show_input_display_tooltip), vconfig.bShowInputDisplay)); wxStaticBoxSizer* const group_info = new wxStaticBoxSizer(wxVERTICAL, page_advanced, _("Information")); szr_advanced->Add(group_info, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5); @@ -606,6 +608,7 @@ void VideoConfigDiag::SetUIValuesFromConfig() texfmt_overlay->SetValue(vconfig.bTexFmtOverlayEnable); efb_copy_regions->SetValue(vconfig.bShowEFBCopyRegions); show_shader_errors->SetValue(vconfig.bShowShaderErrors); + show_input_display->SetValue(vconfig.bShowInputDisplay); enable_xfb->SetValue(vconfig.bUseXFB); virtual_xfb->SetValue(!vconfig.bUseRealXFB); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index 183fdbcccb..081e7c69fa 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -142,6 +142,7 @@ protected: SettingCheckBox* texfmt_overlay; SettingCheckBox* efb_copy_regions; SettingCheckBox* show_shader_errors; + SettingCheckBox* show_input_display; SettingCheckBox* enable_xfb; SettingRadioButton* virtual_xfb; diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 3f8713e825..b36c0e2f08 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -67,6 +67,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples,512); iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings + iniFile.Get("Settings", "ShowInputDisplay", &bShowInputDisplay, false); iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); iniFile.Get("Settings", "OverlayProjStats", &bOverlayProjStats, false); iniFile.Get("Settings", "ShowEFBCopyRegions", &bShowEFBCopyRegions, false); @@ -143,6 +144,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Settings", "SafeTextureCacheColorSamples", &iSafeTextureCache_ColorSamples); iniFile.GetIfExists("Video_Settings", "ShowFPS", &bShowFPS); + iniFile.GetIfExists("Video_Settings", "ShowInputDisplay", &bShowInputDisplay); iniFile.GetIfExists("Video_Settings", "OverlayStats", &bOverlayStats); iniFile.GetIfExists("Video_Settings", "OverlayProjStats", &bOverlayProjStats); iniFile.GetIfExists("Video_Settings", "ShowEFBCopyRegions", &bShowEFBCopyRegions); @@ -248,6 +250,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "SafeTextureCacheColorSamples", iSafeTextureCache_ColorSamples); iniFile.Set("Settings", "ShowFPS", bShowFPS); + iniFile.Set("Settings", "ShowInputDisplay", bShowInputDisplay); iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "OverlayProjStats", bOverlayProjStats); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); @@ -326,6 +329,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Settings", "SafeTextureCacheColorSamples", iSafeTextureCache_ColorSamples); SET_IF_DIFFERS("Video_Settings", "ShowFPS", bShowFPS); + SET_IF_DIFFERS("Video_Settings", "ShowInputDisplay", bShowInputDisplay); SET_IF_DIFFERS("Video_Settings", "OverlayStats", bOverlayStats); SET_IF_DIFFERS("Video_Settings", "OverlayProjStats", bOverlayProjStats); SET_IF_DIFFERS("Video_Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 49871e93ae..9d934057f6 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -92,6 +92,7 @@ struct VideoConfig // Information bool bShowFPS; + bool bShowInputDisplay; bool bOverlayStats; bool bOverlayProjStats; bool bTexFmtOverlayEnable; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 52cc7d280c..e642527bd9 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -39,6 +39,7 @@ #include "TextureCache.h" #include "VertexShaderCache.h" #include "Core.h" +#include "OnFrame.h" namespace DX11 { @@ -1037,7 +1038,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { char fps[20]; StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); - D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, fps); + D3D::font.DrawTextScaled(0, 0, 20, 0.0f, 0xFF00FFFF, fps); + } + + if (g_ActiveConfig.bShowInputDisplay) + { + char inputDisplay[1000]; + StringCchPrintfA(inputDisplay, 1000, Frame::GetInputDisplay().c_str()); + D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, inputDisplay); } Renderer::DrawDebugText(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 571b08996a..9c1b33a46c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -51,6 +51,7 @@ #include "DLCache.h" #include "Debugger.h" #include "Core.h" +#include "OnFrame.h" namespace DX9 { @@ -1158,7 +1159,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { char fps[20]; StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); - D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, fps); + D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); + } + + if (g_ActiveConfig.bShowInputDisplay) + { + char inputDisplay[1000]; + StringCchPrintfA(inputDisplay, 1000, Frame::GetInputDisplay().c_str()); + D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); } Renderer::DrawDebugText(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 7170a8f9d3..75e950b0e1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -58,6 +58,7 @@ #include "Fifo.h" #include "Debugger.h" #include "Core.h" +#include "OnFrame.h" #include "main.h" // Local #ifdef _WIN32 @@ -536,6 +537,9 @@ void Renderer::DrawDebugInfo() if (g_ActiveConfig.bShowFPS) p+=sprintf(p, "FPS: %d\n", s_fps); + if (g_ActiveConfig.bShowInputDisplay) + p+=sprintf(p, Frame::GetInputDisplay().c_str()); + if (g_ActiveConfig.bShowEFBCopyRegions) { // Store Line Size