project64/Source/RSP/Main.cpp

817 lines
23 KiB
C++
Raw Normal View History

#ifdef _WIN32
2016-01-27 09:11:59 +00:00
#include <Windows.h>
#include <windowsx.h>
#include <commctrl.h>
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1910
2017-07-30 09:13:39 +00:00
#include <intrin.h>
#endif
2016-01-27 09:11:59 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2016-01-27 09:11:59 +00:00
#include <Common/StdString.h>
#include <Common/stdtypes.h>
2016-01-27 09:11:59 +00:00
#include "../Settings/Settings.h"
extern "C" {
#include "Rsp.h"
#include "Cpu.h"
2016-01-27 09:11:59 +00:00
#include "Recompiler CPU.h"
#include "RSP Command.h"
#include "RSP Registers.h"
2016-01-27 09:11:59 +00:00
#include "memory.h"
#include "breakpoint.h"
#include "Profiling.h"
2016-01-27 09:11:59 +00:00
#include "log.h"
#include "resource.h"
#include "Version.h"
2016-02-14 19:01:49 +00:00
#include "Types.h"
2016-01-27 09:11:59 +00:00
void ClearAllx86Code(void);
void ProcessMenuItem(int ID);
#ifdef _WIN32
2016-02-14 19:01:49 +00:00
Boolean CALLBACK CompilerDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
HMENU hRSPMenu = NULL;
#endif
2016-02-14 19:01:49 +00:00
Boolean GraphicsHle = TRUE, AudioHle, ConditionalMove;
Boolean DebuggingEnabled = FALSE,
Profiling,
IndvidualBlock,
ShowErrors,
BreakOnStart = FALSE,
LogRDP = FALSE,
LogX86Code = FALSE;
uint32_t CPUCore = RecompilerCPU;
2016-01-27 09:11:59 +00:00
void * hMutex = NULL;
2016-01-27 09:11:59 +00:00
DEBUG_INFO DebugInfo;
RSP_INFO RSPInfo;
void * hinstDLL;
2016-01-27 09:11:59 +00:00
extern uint8_t * pLastSecondary;
2016-01-27 09:11:59 +00:00
}
enum {
Set_BreakOnStart, Set_CPUCore, Set_LogRDP, Set_LogX86Code, Set_Profiling, Set_IndvidualBlock,
Set_ShowErrors,
// Compiler settings
2016-01-27 09:11:59 +00:00
Set_CheckDest, Set_Accum, Set_Mmx, Set_Mmx2, Set_Sse, Set_Sections,
Set_ReOrdering, Set_GPRConstants, Set_Flags, Set_AlignVector,
// Game settings
Set_JumpTableSize, Set_Mfc0Count, Set_SemaphoreExit
2016-01-27 09:11:59 +00:00
};
short Set_AudioHle = 0, Set_GraphicsHle = 0;
// DLL info
2016-01-27 09:11:59 +00:00
const char * AppName ( void )
{
static stdstr_f Name("RSP %s", VER_FILE_VERSION_STR);
return Name.c_str();
}
const char * AboutMsg ( void )
{
static stdstr_f Msg("RSP emulation plugin\nMade for Project64 (c)\nVersion %s\n\nby Jabo & Zilmar", VER_FILE_VERSION_STR);
2016-01-27 09:11:59 +00:00
return Msg.c_str();
}
// Functions
uint32_t AsciiToHex(char * HexValue)
2016-01-27 09:11:59 +00:00
{
size_t Finish, Count;
uint32_t Value = 0;
2016-01-27 09:11:59 +00:00
Finish = strlen(HexValue);
2016-01-27 09:11:59 +00:00
if (Finish > 8 ) { Finish = 8; }
for (Count = 0; Count < Finish; Count++)
2016-01-27 09:11:59 +00:00
{
Value = (Value << 4);
switch( HexValue[Count] )
{
case '0': break;
case '1': Value += 1; break;
case '2': Value += 2; break;
case '3': Value += 3; break;
case '4': Value += 4; break;
case '5': Value += 5; break;
case '6': Value += 6; break;
case '7': Value += 7; break;
case '8': Value += 8; break;
case '9': Value += 9; break;
case 'A': Value += 10; break;
case 'a': Value += 10; break;
case 'B': Value += 11; break;
case 'b': Value += 11; break;
case 'C': Value += 12; break;
case 'c': Value += 12; break;
case 'D': Value += 13; break;
case 'd': Value += 13; break;
case 'E': Value += 14; break;
case 'e': Value += 14; break;
case 'F': Value += 15; break;
case 'f': Value += 15; break;
default:
Value = (Value >> 4);
Count = Finish;
}
}
return Value;
}
void DisplayError(char* Message, ...)
2016-01-27 09:11:59 +00:00
{
char Msg[400];
va_list ap;
2016-01-27 09:11:59 +00:00
va_start( ap, Message );
vsprintf( Msg, Message, ap );
va_end( ap );
#ifdef _WIN32
MessageBox(NULL, Msg, "Error", MB_OK | MB_ICONERROR);
#else
fputs(&Msg[0], stderr);
#endif
2016-01-27 09:11:59 +00:00
}
/******************************************************************
Function: CloseDLL
Purpose: This function is called when the emulator is closing
down allowing the DLL to de-initialize.
2016-01-27 09:11:59 +00:00
input: none
output: none
*******************************************************************/
EXPORT void CloseDLL(void)
2016-01-27 09:11:59 +00:00
{
FreeMemory();
}
/******************************************************************
Function: DllAbout
Purpose: This function is optional function that is provided
to give further information about the DLL.
input: a handle to the window that calls this function
output: none
*******************************************************************/
EXPORT void DllAbout(void * hParent)
2016-01-27 09:11:59 +00:00
{
#ifdef _WIN32
MessageBoxA((HWND)hParent, AboutMsg(), "About", MB_OK | MB_ICONINFORMATION);
#else
puts(AboutMsg());
#endif
2016-01-27 09:11:59 +00:00
}
2016-02-14 19:01:49 +00:00
#ifdef _WIN32
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD /*fdwReason*/, LPVOID /*lpvReserved*/)
2016-01-27 09:11:59 +00:00
{
2016-02-14 19:01:49 +00:00
hinstDLL = hinst;
return TRUE;
}
void FixMenuState(void)
{
EnableMenuItem(hRSPMenu, ID_RSPCOMMANDS,MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_RSPREGISTERS,MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_PROFILING_RESETSTATS, MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_PROFILING_GENERATELOG, MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_DUMP_RSPCODE, MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
EnableMenuItem(hRSPMenu, ID_DUMP_DMEM, MF_BYCOMMAND | (DebuggingEnabled ? MF_ENABLED : (MF_GRAYED | MF_DISABLED)));
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_RECOMPILER, MF_BYCOMMAND | (CPUCore == RecompilerCPU ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_CPUMETHOD_INTERPT, MF_BYCOMMAND | (CPUCore == InterpreterCPU ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | (BreakOnStart ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | (LogRDP ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | (LogX86Code ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | (Profiling ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | (Profiling ? MFS_UNCHECKED : MF_CHECKED));
CheckMenuItem(hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | (IndvidualBlock ? MFS_CHECKED : MF_UNCHECKED));
CheckMenuItem(hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND | (ShowErrors ? MFS_CHECKED : MF_UNCHECKED));
2016-01-27 09:11:59 +00:00
}
2016-02-14 19:01:49 +00:00
#endif
2016-01-27 09:11:59 +00:00
/******************************************************************
Function: GetDllInfo
Purpose: This function allows the emulator to gather information
about the DLL by filling in the PluginInfo structure.
input: a pointer to a PLUGIN_INFO structure that needs to be
2016-01-27 09:11:59 +00:00
filled by the function. (see def above)
output: none
*******************************************************************/
EXPORT void GetDllInfo(PLUGIN_INFO * PluginInfo)
2016-01-27 09:11:59 +00:00
{
2016-10-02 23:57:07 +00:00
PluginInfo->Version = 0x0103;
2016-01-27 09:11:59 +00:00
PluginInfo->Type = PLUGIN_TYPE_RSP;
#ifdef _DEBUG
sprintf(PluginInfo->Name, "RSP Debug Plugin %s", VER_FILE_VERSION_STR);
#else
sprintf(PluginInfo->Name, "RSP Plugin %s", VER_FILE_VERSION_STR);
#endif
PluginInfo->NormalMemory = FALSE;
PluginInfo->MemoryBswaped = TRUE;
}
/******************************************************************
Function: GetRspDebugInfo
Purpose: This function allows the emulator to gather information
about the debug capabilities of the DLL by filling in
2016-01-27 09:11:59 +00:00
the DebugInfo structure.
input: a pointer to a RSPDEBUG_INFO structure that needs to be
2016-01-27 09:11:59 +00:00
filled by the function. (see def above)
output: none
*******************************************************************/
EXPORT void GetRspDebugInfo(RSPDEBUG_INFO * DebugInfo)
2016-01-27 09:11:59 +00:00
{
#ifdef _WIN32
2016-01-27 09:11:59 +00:00
if (hRSPMenu == NULL)
{
2016-02-14 06:03:35 +00:00
hRSPMenu = LoadMenu((HINSTANCE)hinstDLL,MAKEINTRESOURCE(RspMenu));
2016-01-27 09:11:59 +00:00
FixMenuState();
}
DebugInfo->hRSPMenu = hRSPMenu;
#endif
2016-01-27 09:11:59 +00:00
DebugInfo->ProcessMenuItem = ProcessMenuItem;
DebugInfo->UseBPoints = TRUE;
sprintf(DebugInfo->BPPanelName," RSP ");
DebugInfo->Add_BPoint = Add_BPoint;
DebugInfo->CreateBPPanel = CreateBPPanel;
DebugInfo->HideBPPanel = HideBPPanel;
DebugInfo->PaintBPPanel = PaintBPPanel;
DebugInfo->RefreshBpoints = RefreshBpoints;
DebugInfo->RemoveAllBpoint = RemoveAllBpoint;
DebugInfo->RemoveBpoint = RemoveBpoint;
DebugInfo->ShowBPPanel = ShowBPPanel;
2016-01-27 09:11:59 +00:00
DebugInfo->Enter_RSP_Commands_Window = Enter_RSP_Commands_Window;
}
/******************************************************************
Function: InitiateRSP
Purpose: This function is called when the DLL is started to give
information from the emulator that the n64 RSP
interface needs
input: Rsp_Info is passed to this function which is defined
above.
CycleCount is the number of cycles between switching
control between the RSP and r4300i core.
2016-01-27 09:11:59 +00:00
output: none
*******************************************************************/
RSP_COMPILER Compiler;
void DetectCpuSpecs(void)
{
DWORD Intel_Features = 0;
DWORD AMD_Features = 0;
#if defined(_MSC_VER)
__try {
#ifdef _M_IX86
_asm {
// Intel features
2016-01-27 09:11:59 +00:00
mov eax, 1
cpuid
mov [Intel_Features], edx
// AMD features
2016-01-27 09:11:59 +00:00
mov eax, 80000001h
cpuid
or [AMD_Features], edx
}
#else
int cpuInfo[4];
__cpuid(cpuInfo, 1);
Intel_Features = cpuInfo[3];
__cpuid(cpuInfo, 0x80000001);
AMD_Features = cpuInfo[3];
#endif
}
__except (EXCEPTION_EXECUTE_HANDLER) {
AMD_Features = Intel_Features = 0;
}
#else
2016-01-27 09:11:59 +00:00
/*
TODO: With GCC, there is <cpuid.h>, but __cpuid() there is a macro and
needs five arguments, not two. Also, GCC lacks SEH.
*/
2016-01-27 09:11:59 +00:00
AMD_Features = Intel_Features = 0;
#endif
if (Intel_Features & 0x02000000)
{
Compiler.mmx2 = TRUE;
Compiler.sse = TRUE;
}
if (Intel_Features & 0x00800000)
{
Compiler.mmx = TRUE;
}
if (AMD_Features & 0x40000000)
{
Compiler.mmx2 = TRUE;
}
if (Intel_Features & 0x00008000)
{
ConditionalMove = TRUE;
}
else
{
ConditionalMove = FALSE;
}
}
EXPORT void InitiateRSP(RSP_INFO Rsp_Info, uint32_t * CycleCount)
2016-01-27 09:11:59 +00:00
{
RSPInfo = Rsp_Info;
AudioHle = GetSystemSetting(Set_AudioHle);
GraphicsHle = GetSystemSetting(Set_GraphicsHle);
*CycleCount = 0;
AllocateMemory();
InitilizeRSPRegisters();
Build_RSP();
#ifdef GenerateLog
Start_Log();
#endif
}
/******************************************************************
Function: InitiateRSPDebugger
Purpose: This function is called when the DLL is started to give
information from the emulator that the N64 RSP
interface needs to integrate the debugger with the
2016-01-27 09:11:59 +00:00
rest of the emulator.
input: DebugInfo is passed to this function which is defined
above.
output: none
*******************************************************************/
EXPORT void InitiateRSPDebugger(DEBUG_INFO Debug_Info)
2016-01-27 09:11:59 +00:00
{
DebugInfo = Debug_Info;
}
#ifdef _WIN32
2016-01-27 09:11:59 +00:00
void ProcessMenuItem(int ID)
{
UINT uState;
switch (ID)
{
case ID_RSPCOMMANDS: Enter_RSP_Commands_Window(); break;
case ID_RSPREGISTERS: Enter_RSP_Register_Window(); break;
case ID_DUMP_RSPCODE: DumpRSPCode(); break;
case ID_DUMP_DMEM: DumpRSPData(); break;
case ID_PROFILING_ON:
case ID_PROFILING_OFF:
{
uState = GetMenuState(hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | MFS_UNCHECKED );
CheckMenuItem( hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_Profiling,FALSE);
if (DebuggingEnabled) { Profiling = FALSE; }
}
else
{
CheckMenuItem( hRSPMenu, ID_PROFILING_ON, MF_BYCOMMAND | MFS_CHECKED );
CheckMenuItem( hRSPMenu, ID_PROFILING_OFF, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_Profiling,TRUE);
if (DebuggingEnabled) { Profiling = TRUE; }
}
}
break;
case ID_PROFILING_RESETSTATS: ResetTimerList(); break;
case ID_PROFILING_GENERATELOG: GenerateTimerResults(); break;
case ID_PROFILING_LOGINDIVIDUALBLOCKS:
{
uState = GetMenuState(hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_IndvidualBlock,FALSE);
if (DebuggingEnabled) { IndvidualBlock = FALSE; }
}
else
{
CheckMenuItem( hRSPMenu, ID_PROFILING_LOGINDIVIDUALBLOCKS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_IndvidualBlock,TRUE);
if (DebuggingEnabled) { IndvidualBlock = TRUE; }
}
}
break;
case ID_SHOWCOMPILERERRORS:
{
uState = GetMenuState(hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_ShowErrors,FALSE);
if (DebuggingEnabled) { ShowErrors = FALSE; }
}
else
{
CheckMenuItem( hRSPMenu, ID_SHOWCOMPILERERRORS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_ShowErrors,TRUE);
if (DebuggingEnabled) { ShowErrors = TRUE; }
}
}
break;
case ID_COMPILER:
DialogBoxA((HINSTANCE)hinstDLL, "RSPCOMPILER", HWND_DESKTOP, (DLGPROC)CompilerDlgProc);
2016-01-27 09:11:59 +00:00
break;
case ID_BREAKONSTARTOFTASK:
{
uState = GetMenuState(hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_BreakOnStart,FALSE);
if (DebuggingEnabled) { BreakOnStart = FALSE; }
}
else
{
CheckMenuItem( hRSPMenu, ID_BREAKONSTARTOFTASK, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_BreakOnStart,TRUE);
if (DebuggingEnabled) { BreakOnStart = TRUE; }
}
}
break;
case ID_LOGRDPCOMMANDS:
{
uState = GetMenuState(hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_LogRDP,FALSE);
if (DebuggingEnabled)
{
LogRDP = FALSE;
StopRDPLog();
}
}
else
{
CheckMenuItem( hRSPMenu, ID_LOGRDPCOMMANDS, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_LogRDP,TRUE);
if (DebuggingEnabled)
{
LogRDP = TRUE;
StartRDPLog();
}
}
}
break;
case ID_SETTINGS_LOGX86CODE:
{
uState = GetMenuState(hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND);
if (uState & MFS_CHECKED)
{
CheckMenuItem( hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | MFS_UNCHECKED );
SetSetting(Set_LogX86Code,FALSE);
if (DebuggingEnabled)
{
LogX86Code = FALSE;
StopCPULog();
}
}
else
{
CheckMenuItem( hRSPMenu, ID_SETTINGS_LOGX86CODE, MF_BYCOMMAND | MFS_CHECKED );
SetSetting(Set_LogX86Code,TRUE);
if (DebuggingEnabled)
{
LogX86Code = TRUE;
StartCPULog();
}
}
}
break;
case ID_CPUMETHOD_RECOMPILER:
{
SetSetting(Set_CPUCore,RecompilerCPU);
CPUCore = RecompilerCPU;
FixMenuState();
SetCPU(RecompilerCPU);
}
break;
case ID_CPUMETHOD_INTERPT:
{
SetSetting(Set_CPUCore,InterpreterCPU);
CPUCore = InterpreterCPU;
FixMenuState();
SetCPU(InterpreterCPU);
}
break;
}
}
#endif
2016-01-27 09:11:59 +00:00
/******************************************************************
Function: RomOpen
Purpose: This function is called when a ROM is opened.
2016-01-27 09:11:59 +00:00
input: none
output: none
*******************************************************************/
EXPORT void RomOpen(void)
2016-01-27 09:11:59 +00:00
{
ClearAllx86Code();
if (DebuggingEnabled)
{
EnableDebugging(true);
}
JumpTableSize = GetSetting(Set_JumpTableSize);
Mfc0Count = GetSetting(Set_Mfc0Count);
SemaphoreExit = GetSetting(Set_SemaphoreExit);
2016-01-27 09:11:59 +00:00
}
/******************************************************************
Function: RomClosed
Purpose: This function is called when a ROM is closed.
2016-01-27 09:11:59 +00:00
input: none
output: none
*******************************************************************/
EXPORT void RomClosed(void)
{
2016-01-27 09:11:59 +00:00
if (Profiling)
{
StopTimer();
GenerateTimerResults();
}
ClearAllx86Code();
StopRDPLog();
StopCPULog();
#ifdef GenerateLog
Stop_Log();
#endif
}
2016-02-14 19:01:49 +00:00
#ifdef _WIN32
2016-01-27 09:11:59 +00:00
static BOOL GetBooleanCheck(HWND hDlg, DWORD DialogID)
{
return (IsDlgButtonChecked(hDlg, DialogID) == BST_CHECKED) ? TRUE : FALSE;
}
BOOL CALLBACK CompilerDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/)
{
char Buffer[256];
switch (uMsg)
{
case WM_INITDIALOG:
if (Compiler.bDest == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_DEST, BST_CHECKED);
if (Compiler.mmx == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_MMX, BST_CHECKED);
if (Compiler.mmx2 == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_MMX2, BST_CHECKED);
if (Compiler.sse == TRUE)
CheckDlgButton(hDlg, IDC_CHECK_SSE, BST_CHECKED);
if (Compiler.bAlignVector == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_ALIGNVEC, BST_CHECKED);
if (Compiler.bSections == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_SECTIONS, BST_CHECKED);
if (Compiler.bGPRConstants == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_GPRCONSTANTS, BST_CHECKED);
if (Compiler.bReOrdering == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_REORDER, BST_CHECKED);
if (Compiler.bFlags == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_FLAGS, BST_CHECKED);
if (Compiler.bAccum == TRUE)
CheckDlgButton(hDlg, IDC_COMPILER_ACCUM, BST_CHECKED);
SetTimer(hDlg, 1, 250, NULL);
break;
case WM_TIMER:
sprintf(Buffer, "x86: %2.2f KB / %2.2f KB", (float)(RecompPos - RecompCode) / 1024.0F,
pLastSecondary?(float)((pLastSecondary - RecompCodeSecondary) / 1024.0F):0);
SetDlgItemTextA(hDlg, IDC_COMPILER_BUFFERS, Buffer);
2016-01-27 09:11:59 +00:00
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
Compiler.bDest = GetBooleanCheck(hDlg, IDC_COMPILER_DEST);
Compiler.bAccum = GetBooleanCheck(hDlg, IDC_COMPILER_ACCUM);
Compiler.mmx = GetBooleanCheck(hDlg, IDC_CHECK_MMX);
Compiler.mmx2 = GetBooleanCheck(hDlg, IDC_CHECK_MMX2);
Compiler.sse = GetBooleanCheck(hDlg, IDC_CHECK_SSE);
Compiler.bSections = GetBooleanCheck(hDlg, IDC_COMPILER_SECTIONS);
Compiler.bReOrdering = GetBooleanCheck(hDlg, IDC_COMPILER_REORDER);
Compiler.bGPRConstants = GetBooleanCheck(hDlg, IDC_COMPILER_GPRCONSTANTS);
Compiler.bFlags = GetBooleanCheck(hDlg, IDC_COMPILER_FLAGS);
Compiler.bAlignVector = GetBooleanCheck(hDlg, IDC_COMPILER_ALIGNVEC);
SetSetting(Set_CheckDest,Compiler.bDest);
SetSetting(Set_Accum,Compiler.bAccum);
SetSetting(Set_Mmx,Compiler.mmx);
SetSetting(Set_Mmx2,Compiler.mmx2);
SetSetting(Set_Sse,Compiler.sse);
SetSetting(Set_Sections,Compiler.bSections);
SetSetting(Set_ReOrdering,Compiler.bReOrdering);
SetSetting(Set_GPRConstants,Compiler.bGPRConstants);
SetSetting(Set_Flags,Compiler.bFlags);
SetSetting(Set_AlignVector,Compiler.bAlignVector);
KillTimer(hDlg, 1);
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
KillTimer(hDlg, 1);
EndDialog(hDlg, TRUE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
BOOL CALLBACK ConfigDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM /*lParam*/)
{
HWND hWndItem;
DWORD value;
switch (uMsg)
{
case WM_INITDIALOG:
if (AudioHle == TRUE)
{
CheckDlgButton(hDlg, IDC_AUDIOHLE, BST_CHECKED);
}
if (GraphicsHle == TRUE)
{
CheckDlgButton(hDlg, IDC_GRAPHICSHLE, BST_CHECKED);
}
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
ComboBox_AddString(hWndItem, "Interpreter");
ComboBox_AddString(hWndItem, "Recompiler");
ComboBox_SetCurSel(hWndItem, CPUCore);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
hWndItem = GetDlgItem(hDlg, IDC_COMPILER_SELECT);
value = ComboBox_GetCurSel(hWndItem);
SetCPU(value);
AudioHle = GetBooleanCheck(hDlg, IDC_AUDIOHLE);
GraphicsHle = GetBooleanCheck(hDlg, IDC_GRAPHICSHLE);
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
2016-02-14 19:01:49 +00:00
#endif
2016-01-27 09:11:59 +00:00
/*EXPORT void DllConfig(HWND hWnd)
2016-01-27 09:11:59 +00:00
{
// DialogBox(hinstDLL, "RSPCONFIG", hWnd, ConfigDlgProc);
DialogBox(hinstDLL, "RSPCONFIG", GetForegroundWindow(), ConfigDlgProc);
}*/
EXPORT void EnableDebugging(Boolean Enabled)
2016-01-27 09:11:59 +00:00
{
DebuggingEnabled = Enabled;
if (DebuggingEnabled)
{
BreakOnStart = GetSetting(Set_BreakOnStart);
CPUCore = GetSetting(Set_CPUCore);
LogRDP = GetSetting(Set_LogRDP);
LogX86Code = GetSetting(Set_LogX86Code);
Profiling = GetSetting(Set_Profiling);
IndvidualBlock = GetSetting(Set_IndvidualBlock);
ShowErrors = GetSetting(Set_ShowErrors);
Compiler.bDest = GetSetting(Set_CheckDest);
Compiler.bAccum = GetSetting(Set_Accum);
Compiler.mmx = GetSetting(Set_Mmx);
Compiler.mmx2 = GetSetting(Set_Mmx2);
Compiler.sse = GetSetting(Set_Sse);
Compiler.bSections = GetSetting(Set_Sections);
Compiler.bReOrdering = GetSetting(Set_ReOrdering);
Compiler.bGPRConstants = GetSetting(Set_GPRConstants);
Compiler.bFlags = GetSetting(Set_Flags);
Compiler.bAlignVector = GetSetting(Set_AlignVector);
SetCPU(CPUCore);
}
#ifdef _WIN32
FixMenuState();
#else
fputs("FixMenuState()\n", stderr);
#endif
2016-01-27 09:11:59 +00:00
if (LogRDP)
{
StartRDPLog();
}
if (LogX86Code)
{
StartCPULog();
}
}
EXPORT void PluginLoaded(void)
2016-01-27 09:11:59 +00:00
{
BreakOnStart = false;
#ifndef _M_X64
2016-01-27 09:11:59 +00:00
CPUCore = RecompilerCPU;
#else
CPUCore = InterpreterCPU;
#endif
2016-01-27 09:11:59 +00:00
LogRDP = FALSE;
LogX86Code = FALSE;
Profiling = FALSE;
IndvidualBlock = FALSE;
ShowErrors = FALSE;
memset(&Compiler, 0, sizeof(Compiler));
Compiler.bDest = TRUE;
Compiler.bAlignVector = FALSE;
Compiler.bFlags = TRUE;
Compiler.bReOrdering = TRUE;
Compiler.bSections = TRUE;
Compiler.bAccum = TRUE;
Compiler.bGPRConstants = TRUE;
DetectCpuSpecs();
SetModuleName("RSP");
Set_GraphicsHle = FindSystemSettingId("HLE GFX");
Set_AudioHle = FindSystemSettingId("HLE Audio");
RegisterSetting(Set_BreakOnStart, Data_DWORD_General,"Break on Start", NULL,BreakOnStart,NULL);
RegisterSetting(Set_CPUCore, Data_DWORD_General,"CPU Method", NULL,CPUCore,NULL);
RegisterSetting(Set_LogRDP, Data_DWORD_General,"Log RDP", NULL,LogRDP,NULL);
RegisterSetting(Set_LogX86Code, Data_DWORD_General,"Log X86 Code", NULL,LogX86Code,NULL);
RegisterSetting(Set_Profiling, Data_DWORD_General,"Profiling", NULL,Profiling,NULL);
RegisterSetting(Set_IndvidualBlock, Data_DWORD_General,"Individual Block",NULL,IndvidualBlock,NULL);
2016-01-27 09:11:59 +00:00
RegisterSetting(Set_ShowErrors, Data_DWORD_General,"Show Errors", NULL,ShowErrors,NULL);
// Compiler settings
RegisterSetting(Set_CheckDest, Data_DWORD_General,"Check Destination Vector", NULL,Compiler.bDest,NULL);
RegisterSetting(Set_Accum, Data_DWORD_General,"Check Destination Accumulator", NULL,Compiler.bAccum,NULL);
2016-01-27 09:11:59 +00:00
RegisterSetting(Set_Mmx, Data_DWORD_General,"Use MMX", NULL,Compiler.mmx,NULL);
RegisterSetting(Set_Mmx2, Data_DWORD_General,"Use MMX2", NULL,Compiler.mmx2,NULL);
RegisterSetting(Set_Sse, Data_DWORD_General,"Use SSE", NULL,Compiler.sse,NULL);
RegisterSetting(Set_Sections, Data_DWORD_General,"Use precompiled sections", NULL,Compiler.bSections,NULL);
RegisterSetting(Set_ReOrdering, Data_DWORD_General,"Reorder opcodes", NULL,Compiler.bReOrdering,NULL);
RegisterSetting(Set_GPRConstants, Data_DWORD_General,"Detect GPR Constants", NULL,Compiler.bGPRConstants,NULL);
RegisterSetting(Set_Flags, Data_DWORD_General,"Check Flag Usage", NULL,Compiler.bFlags,NULL);
RegisterSetting(Set_AlignVector, Data_DWORD_General,"Assume Vector loads align", NULL,Compiler.bAlignVector,NULL);
RegisterSetting(Set_JumpTableSize, Data_DWORD_Game,"JumpTableSize",NULL,0x800,NULL);
RegisterSetting(Set_Mfc0Count, Data_DWORD_Game, "Mfc0Count", NULL, 0x0, NULL);
RegisterSetting(Set_SemaphoreExit, Data_DWORD_Game, "SemaphoreExit", NULL, 0x0, NULL);
2016-01-27 09:11:59 +00:00
AudioHle = Set_AudioHle != 0 ? GetSystemSetting(Set_AudioHle) : false;
GraphicsHle = Set_GraphicsHle != 0 ? GetSystemSetting(Set_GraphicsHle) : true;
#ifdef _WIN32
hMutex = (HANDLE)CreateMutex(NULL, FALSE, NULL);
#endif
2016-01-27 09:11:59 +00:00
SetCPU(CPUCore);
}
#ifdef _WIN32
void UseUnregisteredSetting(int /*SettingID*/)
2016-01-27 09:11:59 +00:00
{
DebugBreak();
2016-01-27 09:11:59 +00:00
}
#endif