2013-04-18 03:43:35 +00:00
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
2010-12-05 14:15:36 +00:00
2014-02-22 22:36:30 +00:00
# include <cstddef>
# include <string>
# include <wx/button.h>
# include <wx/chartype.h>
# include <wx/choice.h>
# include <wx/defs.h>
# include <wx/event.h>
# include <wx/gdicmn.h>
# include <wx/msgdlg.h>
# include <wx/panel.h>
# include <wx/sizer.h>
# include <wx/string.h>
# include <wx/textctrl.h>
# include <wx/translation.h>
# include <wx/validate.h>
# include <wx/windowid.h>
2014-02-17 10:18:15 +00:00
# include "Common/FileUtil.h"
# include "Common/IniFile.h"
# include "Core/ConfigManager.h"
2014-02-22 22:36:30 +00:00
# include "Core/CoreParameter.h"
2014-07-25 01:46:46 +00:00
# include "DolphinWX/WxUtils.h"
2014-02-17 10:18:15 +00:00
# include "DolphinWX/Debugger/DebuggerPanel.h"
2014-02-22 22:36:30 +00:00
# include "VideoCommon/Debugger.h"
2014-02-17 10:18:15 +00:00
# include "VideoCommon/TextureCacheBase.h"
2014-02-22 22:36:30 +00:00
2010-12-05 14:15:36 +00:00
GFXDebuggerPanel : : GFXDebuggerPanel ( wxWindow * parent , wxWindowID id , const wxPoint & position ,
const wxSize & size , long style , const wxString & title )
: wxPanel ( parent , id , position , size , style , title )
{
2011-01-31 04:36:49 +00:00
g_pdebugger = this ;
2010-12-05 14:15:36 +00:00
CreateGUIControls ( ) ;
2014-11-09 00:26:20 +00:00
Bind ( wxEVT_CLOSE_WINDOW , & GFXDebuggerPanel : : OnClose , this ) ;
2010-12-05 14:15:36 +00:00
LoadSettings ( ) ;
}
GFXDebuggerPanel : : ~ GFXDebuggerPanel ( )
{
2014-03-09 20:14:26 +00:00
g_pdebugger = nullptr ;
2010-12-14 23:19:34 +00:00
GFXDebuggerPauseFlag = false ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnClose ( wxCloseEvent & event )
{
// save the window position when we hide the window
SaveSettings ( ) ;
2011-03-17 04:26:01 +00:00
event . Skip ( ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : SaveSettings ( ) const
{
IniFile file ;
file . Load ( File : : GetUserPath ( F_DEBUGGERCONFIG_IDX ) ) ;
// TODO: make this work when we close the entire program too, currently on total close we get
// weird values, perhaps because of some conflict with the rendering window
2013-04-08 05:47:51 +00:00
2010-12-05 14:15:36 +00:00
// TODO: get the screen resolution and make limits from that
2014-03-10 11:30:55 +00:00
if ( GetPosition ( ) . x < 1000 & &
GetPosition ( ) . y < 1000 & &
GetSize ( ) . GetWidth ( ) < 1000 & &
GetSize ( ) . GetHeight ( ) < 1000 )
2010-12-05 14:15:36 +00:00
{
2014-06-16 05:12:43 +00:00
IniFile : : Section * video_window = file . GetOrCreateSection ( " VideoWindow " ) ;
video_window - > Set ( " x " , GetPosition ( ) . x ) ;
video_window - > Set ( " y " , GetPosition ( ) . y ) ;
video_window - > Set ( " w " , GetSize ( ) . GetWidth ( ) ) ;
video_window - > Set ( " h " , GetSize ( ) . GetHeight ( ) ) ;
2010-12-05 14:15:36 +00:00
}
file . Save ( File : : GetUserPath ( F_DEBUGGERCONFIG_IDX ) ) ;
}
void GFXDebuggerPanel : : LoadSettings ( )
{
IniFile file ;
file . Load ( File : : GetUserPath ( F_DEBUGGERCONFIG_IDX ) ) ;
2014-06-16 05:12:43 +00:00
int x = 100 ;
int y = 100 ;
int w = 100 ;
int h = 100 ;
IniFile : : Section * video_window = file . GetOrCreateSection ( " VideoWindow " ) ;
video_window - > Get ( " x " , & x , GetPosition ( ) . x ) ;
video_window - > Get ( " y " , & y , GetPosition ( ) . y ) ;
video_window - > Get ( " w " , & w , GetSize ( ) . GetWidth ( ) ) ;
video_window - > Get ( " h " , & h , GetSize ( ) . GetHeight ( ) ) ;
2010-12-05 14:15:36 +00:00
SetSize ( x , y , w , h ) ;
}
struct PauseEventMap
{
PauseEvent event ;
const wxString ListStr ;
} ;
2013-09-23 02:48:50 +00:00
static PauseEventMap * pauseEventMap ;
2010-12-05 14:15:36 +00:00
2013-09-23 02:48:50 +00:00
void GFXDebuggerPanel : : CreateGUIControls ( )
{
static PauseEventMap map [ ] = {
2014-02-17 04:51:41 +00:00
{ NEXT_FRAME , _ ( " Frame " ) } ,
{ NEXT_FLUSH , _ ( " Flush " ) } ,
2010-12-05 14:15:36 +00:00
2014-02-17 04:51:41 +00:00
{ NEXT_PIXEL_SHADER_CHANGE , _ ( " Pixel Shader " ) } ,
{ NEXT_VERTEX_SHADER_CHANGE , _ ( " Vertex Shader " ) } ,
{ NEXT_TEXTURE_CHANGE , _ ( " Texture " ) } ,
{ NEXT_NEW_TEXTURE , _ ( " New Texture " ) } ,
2010-12-05 14:15:36 +00:00
2014-02-17 04:51:41 +00:00
{ NEXT_XFB_CMD , _ ( " XFB Cmd " ) } ,
{ NEXT_EFB_CMD , _ ( " EFB Cmd " ) } ,
2010-12-05 14:15:36 +00:00
2014-02-17 04:51:41 +00:00
{ NEXT_MATRIX_CMD , _ ( " Matrix Cmd " ) } ,
{ NEXT_VERTEX_CMD , _ ( " Vertex Cmd " ) } ,
{ NEXT_TEXTURE_CMD , _ ( " Texture Cmd " ) } ,
{ NEXT_LIGHT_CMD , _ ( " Light Cmd " ) } ,
{ NEXT_FOG_CMD , _ ( " Fog Cmd " ) } ,
2010-12-05 14:15:36 +00:00
2014-02-17 04:51:41 +00:00
{ NEXT_SET_TLUT , _ ( " TLUT Cmd " ) } ,
2013-09-23 02:48:50 +00:00
2014-02-17 04:51:41 +00:00
{ NEXT_ERROR , _ ( " Error " ) }
2013-09-23 02:48:50 +00:00
} ;
pauseEventMap = map ;
const int numPauseEventMap = sizeof ( map ) / sizeof ( PauseEventMap ) ;
2010-12-05 14:15:36 +00:00
// Basic settings
CenterOnParent ( ) ;
2014-11-09 00:26:20 +00:00
m_pButtonPause = new wxButton ( this , wxID_ANY , _ ( " Pause " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Pause " ) ) ;
m_pButtonPause - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnPauseButton , this ) ;
m_pButtonPauseAtNext = new wxButton ( this , wxID_ANY , _ ( " Pause After " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Pause At Next " ) ) ;
m_pButtonPauseAtNext - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnPauseAtNextButton , this ) ;
m_pButtonPauseAtNextFrame = new wxButton ( this , wxID_ANY , _ ( " Go to Next Frame " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Next Frame " ) ) ;
m_pButtonPauseAtNextFrame - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnPauseAtNextFrameButton , this ) ;
m_pButtonCont = new wxButton ( this , wxID_ANY , _ ( " Continue " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Continue " ) ) ;
m_pButtonCont - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnContButton , this ) ;
2010-12-05 14:15:36 +00:00
2014-11-09 00:26:20 +00:00
m_pCount = new wxTextCtrl ( this , wxID_ANY , " 1 " , wxDefaultPosition , wxSize ( 50 , 25 ) , wxTE_RIGHT , wxDefaultValidator , _ ( " Count " ) ) ;
2010-12-05 14:15:36 +00:00
2014-11-09 00:26:20 +00:00
m_pPauseAtList = new wxChoice ( this , wxID_ANY , wxDefaultPosition , wxSize ( 100 , 25 ) , 0 , nullptr , 0 , wxDefaultValidator , _ ( " PauseAtList " ) ) ;
2010-12-05 14:15:36 +00:00
for ( int i = 0 ; i < numPauseEventMap ; i + + )
{
m_pPauseAtList - > Append ( pauseEventMap [ i ] . ListStr ) ;
}
m_pPauseAtList - > SetSelection ( 0 ) ;
2014-11-09 00:26:20 +00:00
m_pButtonDump = new wxButton ( this , wxID_ANY , _ ( " Dump " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Dump " ) ) ;
m_pButtonDump - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnDumpButton , this ) ;
m_pButtonUpdateScreen = new wxButton ( this , wxID_ANY , _ ( " Update Screen " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Update Screen " ) ) ;
m_pButtonUpdateScreen - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnUpdateScreenButton , this ) ;
m_pButtonClearScreen = new wxButton ( this , wxID_ANY , _ ( " Clear Screen " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Clear Screen " ) ) ;
m_pButtonClearScreen - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnClearScreenButton , this ) ;
m_pButtonClearTextureCache = new wxButton ( this , wxID_ANY , _ ( " Clear Textures " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Clear Textures " ) ) ;
m_pButtonClearTextureCache - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnClearTextureCacheButton , this ) ;
m_pButtonClearVertexShaderCache = new wxButton ( this , wxID_ANY , _ ( " Clear V Shaders " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Clear V Shaders " ) ) ;
m_pButtonClearVertexShaderCache - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnClearVertexShaderCacheButton , this ) ;
m_pButtonClearPixelShaderCache = new wxButton ( this , wxID_ANY , _ ( " Clear P Shaders " ) , wxDefaultPosition , wxDefaultSize , 0 , wxDefaultValidator , _ ( " Clear P Shaders " ) ) ;
m_pButtonClearPixelShaderCache - > Bind ( wxEVT_BUTTON , & GFXDebuggerPanel : : OnClearPixelShaderCacheButton , this ) ;
2011-01-05 04:35:46 +00:00
2014-11-09 00:26:20 +00:00
m_pDumpList = new wxChoice ( this , wxID_ANY , wxDefaultPosition , wxSize ( 120 , 25 ) , 0 , nullptr , 0 , wxDefaultValidator , _ ( " DumpList " ) ) ;
2011-01-05 04:35:46 +00:00
m_pDumpList - > Insert ( _ ( " Pixel Shader " ) , 0 ) ;
m_pDumpList - > Append ( _ ( " Vertex Shader " ) ) ;
m_pDumpList - > Append ( _ ( " Pixel Shader Constants " ) ) ;
m_pDumpList - > Append ( _ ( " Vertex Shader Constants " ) ) ;
m_pDumpList - > Append ( _ ( " Textures " ) ) ;
m_pDumpList - > Append ( _ ( " Frame Buffer " ) ) ;
m_pDumpList - > Append ( _ ( " Geometry data " ) ) ;
m_pDumpList - > Append ( _ ( " Vertex Description " ) ) ;
m_pDumpList - > Append ( _ ( " Vertex Matrices " ) ) ;
m_pDumpList - > Append ( _ ( " Statistics " ) ) ;
2010-12-05 14:15:36 +00:00
m_pDumpList - > SetSelection ( 0 ) ;
// Layout everything on m_MainPanel
wxBoxSizer * sMain = new wxBoxSizer ( wxVERTICAL ) ;
2011-07-01 20:59:57 +00:00
wxStaticBoxSizer * const pFlowCtrlBox = new wxStaticBoxSizer ( wxVERTICAL , this , _ ( " Flow Control " ) ) ;
wxBoxSizer * const pPauseAtNextSzr = new wxBoxSizer ( wxHORIZONTAL ) ;
pFlowCtrlBox - > Add ( m_pButtonPause ) ;
pPauseAtNextSzr - > Add ( m_pButtonPauseAtNext ) ;
pPauseAtNextSzr - > Add ( m_pCount ) ;
pPauseAtNextSzr - > Add ( m_pPauseAtList ) ;
pFlowCtrlBox - > Add ( pPauseAtNextSzr ) ;
pFlowCtrlBox - > Add ( m_pButtonPauseAtNextFrame ) ;
pFlowCtrlBox - > Add ( m_pButtonCont ) ;
wxStaticBoxSizer * const pDebugBox = new wxStaticBoxSizer ( wxVERTICAL , this , _ ( " Debugging " ) ) ;
wxBoxSizer * const pDumpSzr = new wxBoxSizer ( wxHORIZONTAL ) ;
pDumpSzr - > Add ( m_pButtonDump ) ;
pDumpSzr - > Add ( m_pDumpList ) ;
pDebugBox - > Add ( pDumpSzr ) ;
wxGridSizer * const pDbgGrid = new wxGridSizer ( 2 , 5 , 5 ) ;
pDbgGrid - > Add ( m_pButtonUpdateScreen ) ;
pDbgGrid - > Add ( m_pButtonClearScreen ) ;
pDbgGrid - > Add ( m_pButtonClearTextureCache ) ;
pDbgGrid - > Add ( m_pButtonClearVertexShaderCache ) ;
pDbgGrid - > Add ( m_pButtonClearPixelShaderCache ) ;
pDebugBox - > Add ( pDbgGrid ) ;
sMain - > Add ( pFlowCtrlBox , 0 , 0 , 5 ) ;
sMain - > Add ( pDebugBox , 0 , 0 , 5 ) ;
SetSizerAndFit ( sMain ) ;
2010-12-05 14:15:36 +00:00
OnContinue ( ) ;
}
void GFXDebuggerPanel : : OnPause ( )
{
2015-02-14 21:00:15 +00:00
m_pButtonDump - > Enable ( ) ;
m_pDumpList - > Enable ( ) ;
m_pButtonUpdateScreen - > Enable ( ) ;
m_pButtonClearScreen - > Enable ( ) ;
m_pButtonClearTextureCache - > Enable ( ) ;
m_pButtonClearVertexShaderCache - > Enable ( ) ;
m_pButtonClearPixelShaderCache - > Enable ( ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnContinue ( )
{
2015-02-14 21:00:15 +00:00
m_pButtonDump - > Disable ( ) ;
m_pDumpList - > Disable ( ) ;
m_pButtonUpdateScreen - > Disable ( ) ;
m_pButtonClearScreen - > Disable ( ) ;
m_pButtonClearTextureCache - > Disable ( ) ;
m_pButtonClearVertexShaderCache - > Disable ( ) ;
m_pButtonClearPixelShaderCache - > Disable ( ) ;
2010-12-05 14:15:36 +00:00
}
// General settings
void GFXDebuggerPanel : : GeneralSettings ( wxCommandEvent & event )
{
SaveSettings ( ) ;
}
void GFXDebuggerPanel : : OnPauseButton ( wxCommandEvent & event )
{
GFXDebuggerPauseFlag = true ;
}
void GFXDebuggerPanel : : OnPauseAtNextButton ( wxCommandEvent & event )
{
GFXDebuggerPauseFlag = false ;
GFXDebuggerToPauseAtNext = pauseEventMap [ m_pPauseAtList - > GetSelection ( ) ] . event ;
wxString val = m_pCount - > GetValue ( ) ;
long value ;
if ( val . ToLong ( & value ) )
GFXDebuggerEventToPauseCount = value ;
else
GFXDebuggerEventToPauseCount = 1 ;
}
void GFXDebuggerPanel : : OnPauseAtNextFrameButton ( wxCommandEvent & event )
{
GFXDebuggerPauseFlag = false ;
GFXDebuggerToPauseAtNext = NEXT_FRAME ;
GFXDebuggerEventToPauseCount = 1 ;
}
void GFXDebuggerPanel : : OnDumpButton ( wxCommandEvent & event )
{
2011-02-28 20:40:15 +00:00
std : : string dump_path = File : : GetUserPath ( D_DUMP_IDX ) + " Debug/ " +
SConfig : : GetInstance ( ) . m_LocalCoreStartupParameter . m_strUniqueID + " / " ;
2011-03-01 03:06:14 +00:00
if ( ! File : : CreateFullPath ( dump_path ) )
2010-12-14 23:19:34 +00:00
return ;
2010-12-05 14:15:36 +00:00
switch ( m_pDumpList - > GetSelection ( ) )
{
case 0 : // Pixel Shader
2014-03-12 19:33:41 +00:00
DumpPixelShader ( dump_path ) ;
2010-12-05 14:15:36 +00:00
break ;
case 1 : // Vertex Shader
2014-03-12 19:33:41 +00:00
DumpVertexShader ( dump_path ) ;
2010-12-05 14:15:36 +00:00
break ;
case 2 : // Pixel Shader Constants
2014-03-12 19:33:41 +00:00
DumpPixelShaderConstants ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 3 : // Vertex Shader Constants
2014-03-12 19:33:41 +00:00
DumpVertexShaderConstants ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 4 : // Textures
2014-03-12 19:33:41 +00:00
DumpTextures ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 5 : // Frame Buffer
2014-03-12 19:33:41 +00:00
DumpFrameBuffer ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 6 : // Geometry
2014-03-12 19:33:41 +00:00
DumpGeometry ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 7 : // Vertex Description
2014-03-12 19:33:41 +00:00
DumpVertexDecl ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 8 : // Vertex Matrices
2014-03-12 19:33:41 +00:00
DumpMatrices ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
case 9 : // Statistics
2014-03-12 19:33:41 +00:00
DumpStats ( dump_path ) ;
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
break ;
}
}
void GFXDebuggerPanel : : OnContButton ( wxCommandEvent & event )
{
GFXDebuggerToPauseAtNext = NOT_PAUSE ;
GFXDebuggerPauseFlag = false ;
}
void GFXDebuggerPanel : : OnClearScreenButton ( wxCommandEvent & event )
{
// TODO
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnClearTextureCacheButton ( wxCommandEvent & event )
{
2012-05-28 09:37:14 +00:00
TextureCache : : Invalidate ( ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnClearVertexShaderCacheButton ( wxCommandEvent & event )
{
// TODO
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnClearPixelShaderCacheButton ( wxCommandEvent & event )
{
// TODO
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
}
void GFXDebuggerPanel : : OnUpdateScreenButton ( wxCommandEvent & event )
{
2014-07-25 01:46:46 +00:00
WxUtils : : ShowErrorDialog ( _ ( " Not implemented " ) ) ;
2010-12-05 14:15:36 +00:00
GFXDebuggerUpdateScreen ( ) ;
}