2014-08-29 00:49:26 +02:00
# include "stdafx_gui.h"
2014-08-29 20:30:21 +02:00
# include "Emu/Memory/Memory.h"
2014-06-02 19:27:24 +02:00
# include "Emu/System.h"
2012-11-15 00:39:56 +01:00
# include "rpcs3.h"
# include "Ini.h"
2014-12-26 15:06:36 +01:00
# include "Utilities/Log.h"
2014-06-02 19:27:24 +02:00
# include "Gui/ConLogFrame.h"
2014-05-02 08:30:32 +02:00
# include "Emu/GameInfo.h"
2014-02-21 17:13:57 +01:00
2014-08-26 01:55:37 +02:00
# include "Emu/Io/Keyboard.h"
2014-08-24 19:42:19 +02:00
# include "Emu/Io/Null/NullKeyboardHandler.h"
# include "Emu/Io/Windows/WindowsKeyboardHandler.h"
2014-08-26 01:55:37 +02:00
# include "Emu/Io/Mouse.h"
2014-08-24 19:42:19 +02:00
# include "Emu/Io/Null/NullMouseHandler.h"
# include "Emu/Io/Windows/WindowsMouseHandler.h"
2014-08-26 01:55:37 +02:00
# include "Emu/Io/Pad.h"
2014-08-24 19:42:19 +02:00
# include "Emu/Io/Null/NullPadHandler.h"
# include "Emu/Io/Windows/WindowsPadHandler.h"
# if defined(_WIN32)
# include "Emu/Io/XInput/XInputPadHandler.h"
# endif
2014-08-29 20:30:21 +02:00
# include "Emu/SysCalls/Modules/cellMsgDialog.h"
# include "Gui/MsgDialog.h"
2014-08-25 00:23:26 +02:00
# include "Gui/GLGSFrame.h"
2014-08-26 01:45:15 +02:00
# include <wx/stdpaths.h>
2014-08-25 00:23:26 +02:00
2014-02-21 17:13:57 +01:00
# ifdef _WIN32
2012-11-15 00:39:56 +01:00
# include <wx/msw/wrapwin.h>
2014-02-21 17:13:57 +01:00
# endif
2013-06-30 10:46:29 +02:00
2014-09-03 12:06:11 +02:00
# ifdef __unix__
2014-03-28 12:33:51 +01:00
# include <X11/Xlib.h>
# endif
2014-04-13 03:31:59 +02:00
wxDEFINE_EVENT ( wxEVT_DBG_COMMAND , wxCommandEvent ) ;
2012-11-15 00:39:56 +01:00
IMPLEMENT_APP ( Rpcs3App )
Rpcs3App * TheApp ;
2014-11-29 14:16:53 +01:00
std : : string simplify_path ( const std : : string & path , bool is_dir ) ;
2014-12-17 15:01:59 +01:00
typedef be_t < uint > CGprofile ;
typedef int CGbool ;
typedef be_t < uint > CGresource ;
typedef be_t < uint > CGenum ;
typedef be_t < uint > CGtype ;
2014-12-17 15:59:28 +01:00
typedef be_t < unsigned int > CgBinaryOffset ;
2014-12-17 15:01:59 +01:00
typedef CgBinaryOffset CgBinaryEmbeddedConstantOffset ;
typedef CgBinaryOffset CgBinaryFloatOffset ;
typedef CgBinaryOffset CgBinaryStringOffset ;
typedef CgBinaryOffset CgBinaryParameterOffset ;
// a few typedefs
typedef struct CgBinaryParameter CgBinaryParameter ;
typedef struct CgBinaryEmbeddedConstant CgBinaryEmbeddedConstant ;
typedef struct CgBinaryVertexProgram CgBinaryVertexProgram ;
typedef struct CgBinaryFragmentProgram CgBinaryFragmentProgram ;
typedef struct CgBinaryProgram CgBinaryProgram ;
// fragment programs have their constants embedded in the microcode
struct CgBinaryEmbeddedConstant
{
be_t < unsigned int > ucodeCount ; // occurances
be_t < unsigned int > ucodeOffset [ 1 ] ; // offsets that need to be patched follow
} ;
// describe a binary program parameter (CgParameter is opaque)
struct CgBinaryParameter
{
CGtype type ; // cgGetParameterType()
CGresource res ; // cgGetParameterResource()
CGenum var ; // cgGetParameterVariability()
2014-12-17 15:59:28 +01:00
be_t < int > resIndex ; // cgGetParameterResourceIndex()
2014-12-17 15:01:59 +01:00
CgBinaryStringOffset name ; // cgGetParameterName()
CgBinaryFloatOffset defaultValue ; // default constant value
CgBinaryEmbeddedConstantOffset embeddedConst ; // embedded constant information
CgBinaryStringOffset semantic ; // cgGetParameterSemantic()
CGenum direction ; // cgGetParameterDirection()
2014-12-17 15:59:28 +01:00
be_t < int > paramno ; // 0..n: cgGetParameterIndex() -1: globals
2014-12-17 15:01:59 +01:00
CGbool isReferenced ; // cgIsParameterReferenced()
CGbool isShared ; // cgIsParameterShared()
} ;
// attributes needed for vshaders
struct CgBinaryVertexProgram
{
be_t < unsigned int > instructionCount ; // #instructions
be_t < unsigned int > instructionSlot ; // load address (indexed reads!)
be_t < unsigned int > registerCount ; // R registers count
be_t < unsigned int > attributeInputMask ; // attributes vs reads from
be_t < unsigned int > attributeOutputMask ; // attributes vs writes (uses SET_VERTEX_ATTRIB_OUTPUT_MASK bits)
be_t < unsigned int > userClipMask ; // user clip plane enables (for SET_USER_CLIP_PLANE_CONTROL)
} ;
typedef enum {
CgBinaryPTTNone = 0 ,
CgBinaryPTT2x16 = 1 ,
CgBinaryPTT1x32 = 2 ,
} CgBinaryPartialTexType ;
// attributes needed for pshaders
struct CgBinaryFragmentProgram
{
be_t < unsigned int > instructionCount ; // #instructions
be_t < unsigned int > attributeInputMask ; // attributes fp reads (uses SET_VERTEX_ATTRIB_OUTPUT_MASK bits)
be_t < unsigned int > partialTexType ; // texid 0..15 use two bits each marking whether the texture format requires partial load: see CgBinaryPartialTexType
be_t < unsigned short > texCoordsInputMask ; // tex coords used by frag prog. (tex<n> is bit n)
be_t < unsigned short > texCoords2D ; // tex coords that are 2d (tex<n> is bit n)
be_t < unsigned short > texCoordsCentroid ; // tex coords that are centroid (tex<n> is bit n)
unsigned char registerCount ; // R registers count
unsigned char outputFromH0 ; // final color from R0 or H0
unsigned char depthReplace ; // fp generated z epth value
unsigned char pixelKill ; // fp uses kill operations
} ;
# include "Emu/RSX/GL/GLFragmentProgram.h"
# include "Emu/RSX/GL/GLVertexProgram.h"
// defines a binary program -- *all* address/offsets are relative to the begining of CgBinaryProgram
struct CgBinaryProgram
{
// vertex/pixel shader identification (BE/LE as well)
CGprofile profile ;
// binary revision (used to verify binary and driver structs match)
be_t < unsigned int > binaryFormatRevision ;
// total size of this struct including profile and totalSize field!
be_t < unsigned int > totalSize ;
// parameter usually queried using cgGet[First/Next]LeafParameter
be_t < unsigned int > parameterCount ;
CgBinaryParameterOffset parameterArray ;
// depending on profile points to a CgBinaryVertexProgram or CgBinaryFragmentProgram struct
CgBinaryOffset program ;
// raw ucode data
be_t < unsigned int > ucodeSize ;
CgBinaryOffset ucode ;
// variable length data follows
unsigned char data [ 1 ] ;
} ;
void compile_shader ( std : : string path )
{
ShaderVar var ( " r0.yz.x " ) ;
var . symplify ( ) ;
LOG_ERROR ( GENERAL , var . get ( ) . c_str ( ) ) ;
u32 ptr ;
{
wxFile f ( path ) ;
if ( ! f . IsOpened ( ) )
return ;
size_t size = f . Length ( ) ;
vm : : ps3 : : init ( ) ;
ptr = vm : : alloc ( size ) ;
f . Read ( vm : : get_ptr ( ptr ) , size ) ;
f . Close ( ) ;
}
CgBinaryProgram & prog = vm : : get_ref < CgBinaryProgram > ( ptr ) ;
2015-01-13 15:54:36 +01:00
LOG_ERROR ( GENERAL , " %d - 0x%x " , ( u32 ) prog . profile , ( u32 ) prog . binaryFormatRevision ) ;
2014-12-17 15:01:59 +01:00
std : : string shader ;
GLParamArray param_array ;
u32 size ;
if ( prog . profile = = 7004 )
{
CgBinaryFragmentProgram & fprog = vm : : get_ref < CgBinaryFragmentProgram > ( ptr + prog . program ) ;
u32 ctrl = ( fprog . outputFromH0 ? 0 : 0x40 ) | ( fprog . depthReplace ? 0xe : 0 ) ;
GLFragmentDecompilerThread ( shader , param_array , ptr + prog . ucode , size , ctrl ) . Task ( ) ;
}
else
{
CgBinaryVertexProgram & vprog = vm : : get_ref < CgBinaryVertexProgram > ( ptr + prog . program ) ;
std : : vector < u32 > data ;
be_t < u32 > * vdata = vm : : get_ptr < be_t < u32 > > ( ptr + prog . ucode ) ;
for ( u32 i = 0 ; i < prog . ucodeSize ; + + i , + + vdata )
{
data . push_back ( vdata [ i ] ) ;
}
GLVertexDecompilerThread ( data , shader , param_array ) . Task ( ) ;
}
LOG_ERROR ( GENERAL , shader . c_str ( ) ) ;
vm : : close ( ) ;
}
2012-11-15 00:39:56 +01:00
bool Rpcs3App : : OnInit ( )
{
2015-01-27 16:14:15 +01:00
static const wxCmdLineEntryDesc desc [ ]
{
{ wxCMD_LINE_SWITCH , " h " , " help " , " Command line options: \n h (help): Help and commands \n t (test): For directly executing a (S)ELF " , wxCMD_LINE_VAL_NONE , wxCMD_LINE_OPTION_HELP } ,
{ wxCMD_LINE_SWITCH , " t " , " test " , " Run in test mode on (S)ELF " , wxCMD_LINE_VAL_NONE } ,
{ wxCMD_LINE_PARAM , NULL , NULL , " (S)ELF " , wxCMD_LINE_VAL_STRING , wxCMD_LINE_PARAM_OPTIONAL } ,
{ wxCMD_LINE_NONE }
} ;
parser . SetDesc ( desc ) ;
parser . SetCmdLine ( argc , argv ) ;
if ( parser . Parse ( ) )
{
// help was given, terminating
this - > Exit ( ) ;
}
2014-08-24 19:42:19 +02:00
SetSendDbgCommandCallback ( [ ] ( DbgCommand id , CPUThread * t )
{
wxGetApp ( ) . SendDbgCommand ( id , t ) ;
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetCallAfterCallback ( [ ] ( std : : function < void ( ) > func )
{
wxGetApp ( ) . CallAfter ( func ) ;
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetKeyboardHandlerCountCallback ( [ ] ( )
{
return 2 ;
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetKeyboardHandlerCallback ( [ ] ( int i ) - > KeyboardHandlerBase *
{
switch ( i )
{
2014-12-19 00:18:44 +01:00
case 0 : return new NullKeyboardHandler ( ) ;
case 1 : return new WindowsKeyboardHandler ( ) ;
2014-08-24 19:42:19 +02:00
}
2014-12-19 00:18:44 +01:00
assert ( ! " Invalid keyboard handler number " ) ;
return new NullKeyboardHandler ( ) ;
2014-08-24 19:42:19 +02:00
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetMouseHandlerCountCallback ( [ ] ( )
{
return 2 ;
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetMouseHandlerCallback ( [ ] ( int i ) - > MouseHandlerBase *
{
switch ( i )
{
2014-12-19 00:18:44 +01:00
case 0 : return new NullMouseHandler ( ) ;
case 1 : return new WindowsMouseHandler ( ) ;
2014-08-24 19:42:19 +02:00
}
2014-12-19 00:18:44 +01:00
assert ( ! " Invalid mouse handler number " ) ;
return new NullMouseHandler ( ) ;
2014-08-24 19:42:19 +02:00
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetPadHandlerCountCallback ( [ ] ( )
{
# if defined(_WIN32)
return 3 ;
# else
return 2 ;
# endif
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-24 19:42:19 +02:00
SetGetPadHandlerCallback ( [ ] ( int i ) - > PadHandlerBase *
{
switch ( i )
{
2014-12-19 00:18:44 +01:00
case 0 : return new NullPadHandler ( ) ;
case 1 : return new WindowsPadHandler ( ) ;
2014-08-24 19:42:19 +02:00
# if defined(_WIN32)
2014-12-19 00:18:44 +01:00
case 2 : return new XInputPadHandler ( ) ;
2014-08-24 19:42:19 +02:00
# endif
}
2014-12-19 00:18:44 +01:00
assert ( ! " Invalid pad handler number " ) ;
return new NullPadHandler ( ) ;
2014-08-24 19:42:19 +02:00
} ) ;
2014-12-19 00:18:44 +01:00
2014-08-25 00:23:26 +02:00
SetGetGSFrameCallback ( [ ] ( ) - > GSFrameBase *
{
return new GLGSFrame ( ) ;
} ) ;
2014-12-19 00:18:44 +01:00
SetMsgDialogCallbacks ( MsgDialogCreate , MsgDialogDestroy , MsgDialogProgressBarSetMsg , MsgDialogProgressBarReset , MsgDialogProgressBarInc ) ;
2014-08-24 19:42:19 +02:00
2012-11-15 00:39:56 +01:00
TheApp = this ;
SetAppName ( _PRGNAME_ ) ;
wxInitAllImageHandlers ( ) ;
2014-08-26 01:45:15 +02:00
// RPCS3 assumes the current working directory is the folder where it is contained, so we make sure this is true
2014-11-29 14:16:53 +01:00
const wxString executablePath = wxPathOnly ( wxStandardPaths : : Get ( ) . GetExecutablePath ( ) ) ;
wxSetWorkingDirectory ( executablePath ) ;
2014-08-26 01:45:15 +02:00
2014-07-11 13:59:13 +02:00
main_thread = std : : this_thread : : get_id ( ) ;
2012-11-15 00:39:56 +01:00
Ini . Load ( ) ;
Emu . Init ( ) ;
2014-11-29 14:16:53 +01:00
Emu . SetEmulatorPath ( executablePath . ToStdString ( ) ) ;
2013-06-30 10:46:29 +02:00
2014-11-29 15:16:48 +01:00
m_MainFrame = new MainFrame ( ) ;
SetTopWindow ( m_MainFrame ) ;
2012-11-15 00:39:56 +01:00
m_MainFrame - > Show ( ) ;
2013-06-30 10:46:29 +02:00
m_MainFrame - > DoSettings ( true ) ;
2014-01-19 17:05:27 +01:00
2015-01-27 16:14:15 +01:00
OnArguments ( parser ) ;
2014-02-27 04:21:08 +01:00
2014-12-17 15:59:28 +01:00
//compile_shader("compile_shader0.spo");
//compile_shader("compile_shader1.spo");
2014-12-17 15:01:59 +01:00
2012-11-15 00:39:56 +01:00
return true ;
}
2015-01-27 16:14:15 +01:00
void Rpcs3App : : OnArguments ( const wxCmdLineParser & parser )
2014-02-27 04:21:08 +01:00
{
// Usage:
// rpcs3-*.exe Initializes RPCS3
// rpcs3-*.exe [(S)ELF] Initializes RPCS3, then loads and runs the specified (S)ELF file.
2015-01-27 16:14:15 +01:00
if ( parser . FoundSwitch ( " t " ) )
{
HLEExitOnStop = Ini . HLEExitOnStop . GetValue ( ) ;
Ini . HLEExitOnStop . SetValue ( true ) ;
if ( parser . GetParamCount ( ) ! = 1 )
{
wxLogDebug ( wxT ( " A (S)ELF file needs to be given in test mode, exiting. " ) ) ;
this - > Exit ( ) ;
}
}
if ( parser . GetParamCount ( ) > 0 )
{
Emu . SetPath ( fmt : : ToUTF8 ( parser . GetParam ( 0 ) ) ) ;
2014-02-27 04:21:08 +01:00
Emu . Load ( ) ;
Emu . Run ( ) ;
}
}
2012-11-15 00:39:56 +01:00
void Rpcs3App : : Exit ( )
{
2015-01-27 16:14:15 +01:00
if ( parser . FoundSwitch ( " t " ) )
{
Ini . HLEExitOnStop . SetValue ( HLEExitOnStop ) ;
}
2012-11-15 00:39:56 +01:00
Emu . Stop ( ) ;
Ini . Save ( ) ;
wxApp : : Exit ( ) ;
2014-11-10 00:34:28 +01:00
# ifdef _WIN32
timeEndPeriod ( 1 ) ;
# endif
2012-11-15 00:39:56 +01:00
}
2013-11-03 20:23:16 +01:00
void Rpcs3App : : SendDbgCommand ( DbgCommand id , CPUThread * thr )
2013-06-30 10:46:29 +02:00
{
wxCommandEvent event ( wxEVT_DBG_COMMAND , id ) ;
event . SetClientData ( thr ) ;
AddPendingEvent ( event ) ;
}
2014-03-28 12:33:51 +01:00
Rpcs3App : : Rpcs3App ( )
{
2014-11-10 00:34:28 +01:00
# ifdef _WIN32
timeBeginPeriod ( 1 ) ;
# endif
2014-12-17 15:01:59 +01:00
# if defined(__unix__) && !defined(__APPLE__)
2014-03-28 12:33:51 +01:00
XInitThreads ( ) ;
2014-12-17 15:01:59 +01:00
# endif
2014-03-28 12:33:51 +01:00
}
2012-11-15 00:39:56 +01:00
2014-04-13 03:31:59 +02:00
GameInfo CurGameInfo ;